From 4ab3f813848c7696ee6d15383c4ed54fc7789484 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 3 Mar 2024 20:04:49 +0100 Subject: [PATCH 001/203] Extract getFactor() (#3089) * Extract getFactor() * Refactoring --- apps/api/src/app/order/order.service.ts | 4 +- .../interfaces/portfolio-order.interface.ts | 4 +- .../src/app/portfolio/portfolio-calculator.ts | 45 +++++-------------- .../src/app/portfolio/portfolio.service.ts | 3 +- apps/api/src/helper/portfolio.helper.ts | 21 +++++++++ apps/api/src/models/order.ts | 4 +- .../api/src/services/interfaces/interfaces.ts | 4 +- .../app/services/import-activities.service.ts | 18 ++++---- 8 files changed, 52 insertions(+), 51 deletions(-) create mode 100644 apps/api/src/helper/portfolio.helper.ts diff --git a/apps/api/src/app/order/order.service.ts b/apps/api/src/app/order/order.service.ts index 79738c27e..d200ee024 100644 --- a/apps/api/src/app/order/order.service.ts +++ b/apps/api/src/app/order/order.service.ts @@ -19,7 +19,7 @@ import { Order, Prisma, Tag, - Type as TypeOfOrder + Type as ActivityType } from '@prisma/client'; import Big from 'big.js'; import { endOfToday, isAfter } from 'date-fns'; @@ -229,7 +229,7 @@ export class OrderService { sortColumn?: string; sortDirection?: Prisma.SortOrder; take?: number; - types?: TypeOfOrder[]; + types?: ActivityType[]; userCurrency: string; userId: string; withExcludedAccounts?: boolean; diff --git a/apps/api/src/app/portfolio/interfaces/portfolio-order.interface.ts b/apps/api/src/app/portfolio/interfaces/portfolio-order.interface.ts index cc3a97752..161fbbecb 100644 --- a/apps/api/src/app/portfolio/interfaces/portfolio-order.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/portfolio-order.interface.ts @@ -1,4 +1,4 @@ -import { DataSource, Tag, Type as TypeOfOrder } from '@prisma/client'; +import { DataSource, Tag, Type as ActivityType } from '@prisma/client'; import Big from 'big.js'; export interface PortfolioOrder { @@ -10,6 +10,6 @@ export interface PortfolioOrder { quantity: Big; symbol: string; tags?: Tag[]; - type: TypeOfOrder; + type: ActivityType; unitPrice: Big; } diff --git a/apps/api/src/app/portfolio/portfolio-calculator.ts b/apps/api/src/app/portfolio/portfolio-calculator.ts index 9b76aa735..27a5a278b 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator.ts @@ -1,3 +1,4 @@ +import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper'; @@ -12,7 +13,6 @@ import { import { GroupBy } from '@ghostfolio/common/types'; import { Logger } from '@nestjs/common'; -import { Type as TypeOfOrder } from '@prisma/client'; import Big from 'big.js'; import { addDays, @@ -76,7 +76,7 @@ export class PortfolioCalculator { let currentTransactionPointItem: TransactionPointSymbol; const oldAccumulatedSymbol = symbols[order.symbol]; - const factor = this.getFactor(order.type); + const factor = getFactor(order.type); const unitPrice = new Big(order.unitPrice); if (oldAccumulatedSymbol) { const newQuantity = order.quantity @@ -820,25 +820,6 @@ export class PortfolioCalculator { }; } - private getFactor(type: TypeOfOrder) { - let factor: number; - - switch (type) { - case 'BUY': - case 'ITEM': - factor = 1; - break; - case 'SELL': - factor = -1; - break; - default: - factor = 0; - break; - } - - return factor; - } - private getSymbolMetrics({ end, exchangeRates, @@ -989,7 +970,7 @@ export class PortfolioCalculator { itemType: 'start', name: '', quantity: new Big(0), - type: TypeOfOrder.BUY, + type: 'BUY', unitPrice: unitPriceAtStartDate }); @@ -1003,7 +984,7 @@ export class PortfolioCalculator { itemType: 'end', name: '', quantity: new Big(0), - type: TypeOfOrder.BUY, + type: 'BUY', unitPrice: unitPriceAtEndDate }); @@ -1030,7 +1011,7 @@ export class PortfolioCalculator { feeInBaseCurrency: new Big(0), name: '', quantity: new Big(0), - type: TypeOfOrder.BUY, + type: 'BUY', unitPrice: marketSymbolMap[format(day, DATE_FORMAT)]?.[symbol] ?? lastUnitPrice @@ -1131,24 +1112,24 @@ export class PortfolioCalculator { order.type === 'BUY' ? order.quantity .mul(order.unitPriceInBaseCurrency) - .mul(this.getFactor(order.type)) + .mul(getFactor(order.type)) : totalUnits.gt(0) ? totalInvestment .div(totalUnits) .mul(order.quantity) - .mul(this.getFactor(order.type)) + .mul(getFactor(order.type)) : new Big(0); const transactionInvestmentWithCurrencyEffect = order.type === 'BUY' ? order.quantity .mul(order.unitPriceInBaseCurrencyWithCurrencyEffect) - .mul(this.getFactor(order.type)) + .mul(getFactor(order.type)) : totalUnits.gt(0) ? totalInvestmentWithCurrencyEffect .div(totalUnits) .mul(order.quantity) - .mul(this.getFactor(order.type)) + .mul(getFactor(order.type)) : new Big(0); if (PortfolioCalculator.ENABLE_LOGGING) { @@ -1203,9 +1184,7 @@ export class PortfolioCalculator { order.feeInBaseCurrencyWithCurrencyEffect ?? 0 ); - totalUnits = totalUnits.plus( - order.quantity.mul(this.getFactor(order.type)) - ); + totalUnits = totalUnits.plus(order.quantity.mul(getFactor(order.type))); const valueOfInvestment = totalUnits.mul(order.unitPriceInBaseCurrency); @@ -1214,14 +1193,14 @@ export class PortfolioCalculator { ); const grossPerformanceFromSell = - order.type === TypeOfOrder.SELL + order.type === 'SELL' ? order.unitPriceInBaseCurrency .minus(lastAveragePrice) .mul(order.quantity) : new Big(0); const grossPerformanceFromSellWithCurrencyEffect = - order.type === TypeOfOrder.SELL + order.type === 'SELL' ? order.unitPriceInBaseCurrencyWithCurrencyEffect .minus(lastAveragePriceWithCurrencyEffect) .mul(order.quantity) diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index f268349c3..d07389049 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -7,6 +7,7 @@ import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.s import { PortfolioOrder } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order.interface'; import { TransactionPoint } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point.interface'; import { UserService } from '@ghostfolio/api/app/user/user.service'; +import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; import { AccountClusterRiskCurrentInvestment } from '@ghostfolio/api/models/rules/account-cluster-risk/current-investment'; import { AccountClusterRiskSingleAccount } from '@ghostfolio/api/models/rules/account-cluster-risk/single-account'; import { CurrencyClusterRiskBaseCurrencyCurrentInvestment } from '@ghostfolio/api/models/rules/currency-cluster-risk/base-currency-current-investment'; @@ -2131,7 +2132,7 @@ export class PortfolioService { ?.marketPriceInBaseCurrency ?? 0; if (['LIABILITY', 'SELL'].includes(type)) { - currentValueOfSymbolInBaseCurrency *= -1; + currentValueOfSymbolInBaseCurrency *= getFactor(type); } if (accounts[Account?.id || UNKNOWN_KEY]?.valueInBaseCurrency) { diff --git a/apps/api/src/helper/portfolio.helper.ts b/apps/api/src/helper/portfolio.helper.ts new file mode 100644 index 000000000..01b532cbf --- /dev/null +++ b/apps/api/src/helper/portfolio.helper.ts @@ -0,0 +1,21 @@ +import { Type as ActivityType } from '@prisma/client'; + +export function getFactor(activityType: ActivityType) { + let factor: number; + + switch (activityType) { + case 'BUY': + case 'ITEM': + factor = 1; + break; + case 'LIABILITY': + case 'SELL': + factor = -1; + break; + default: + factor = 0; + break; + } + + return factor; +} diff --git a/apps/api/src/models/order.ts b/apps/api/src/models/order.ts index 214f7e56a..6e6762101 100644 --- a/apps/api/src/models/order.ts +++ b/apps/api/src/models/order.ts @@ -1,6 +1,6 @@ import { IOrder } from '@ghostfolio/api/services/interfaces/interfaces'; -import { Account, SymbolProfile, Type as TypeOfOrder } from '@prisma/client'; +import { Account, SymbolProfile, Type as ActivityType } from '@prisma/client'; import { v4 as uuidv4 } from 'uuid'; export class Order { @@ -14,7 +14,7 @@ export class Order { private symbol: string; private symbolProfile: SymbolProfile; private total: number; - private type: TypeOfOrder; + private type: ActivityType; private unitPrice: number; public constructor(data: IOrder) { diff --git a/apps/api/src/services/interfaces/interfaces.ts b/apps/api/src/services/interfaces/interfaces.ts index bfd29d991..b945d0945 100644 --- a/apps/api/src/services/interfaces/interfaces.ts +++ b/apps/api/src/services/interfaces/interfaces.ts @@ -5,7 +5,7 @@ import { Account, DataSource, SymbolProfile, - Type as TypeOfOrder + Type as ActivityType } from '@prisma/client'; export interface IOrder { @@ -18,7 +18,7 @@ export interface IOrder { quantity: number; symbol: string; symbolProfile: SymbolProfile; - type: TypeOfOrder; + type: ActivityType; unitPrice: number; } diff --git a/apps/client/src/app/services/import-activities.service.ts b/apps/client/src/app/services/import-activities.service.ts index 5375c32aa..c1b2209b3 100644 --- a/apps/client/src/app/services/import-activities.service.ts +++ b/apps/client/src/app/services/import-activities.service.ts @@ -5,7 +5,7 @@ import { parseDate as parseDateHelper } from '@ghostfolio/common/helper'; import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Account, DataSource, Type } from '@prisma/client'; +import { Account, DataSource, Type as ActivityType } from '@prisma/client'; import { isFinite } from 'lodash'; import { parse as csvToJson } from 'papaparse'; import { EMPTY } from 'rxjs'; @@ -328,26 +328,26 @@ export class ImportActivitiesService { content: any[]; index: number; item: any; - }) { + }): ActivityType { item = this.lowercaseKeys(item); for (const key of ImportActivitiesService.TYPE_KEYS) { if (item[key]) { switch (item[key].toLowerCase()) { case 'buy': - return Type.BUY; + return 'BUY'; case 'dividend': - return Type.DIVIDEND; + return 'DIVIDEND'; case 'fee': - return Type.FEE; + return 'FEE'; case 'interest': - return Type.INTEREST; + return 'INTEREST'; case 'item': - return Type.ITEM; + return 'ITEM'; case 'liability': - return Type.LIABILITY; + return 'LIABILITY'; case 'sell': - return Type.SELL; + return 'SELL'; default: break; } From c37ad9bad4af3200c3cb589afd428bfdb7983a35 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 4 Mar 2024 20:15:41 +0100 Subject: [PATCH 002/203] Bugfix/fix activities import (#3095) * Fix query parameter handling of booleans * Update changelog --- CHANGELOG.md | 4 ++++ apps/api/src/app/import/import.controller.ts | 4 +++- apps/api/src/app/portfolio/portfolio.controller.ts | 7 +++++-- apps/api/src/app/symbol/symbol.controller.ts | 4 +++- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51d86efa1..dbe4e13d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Optimized the calculation of the portfolio summary +### Fixed + +- Fixed the the activities import (query parameter handling) + ## 2.60.0 - 2024-03-02 ### Added diff --git a/apps/api/src/app/import/import.controller.ts b/apps/api/src/app/import/import.controller.ts index b7aff8634..29a06fc9f 100644 --- a/apps/api/src/app/import/import.controller.ts +++ b/apps/api/src/app/import/import.controller.ts @@ -43,8 +43,10 @@ export class ImportController { @UseInterceptors(TransformDataSourceInResponseInterceptor) public async import( @Body() importData: ImportDataDto, - @Query('dryRun') isDryRun = false + @Query('dryRun') isDryRunParam = 'false' ): Promise { + const isDryRun = isDryRunParam === 'true'; + if ( !hasPermission(this.request.user.permissions, permissions.createAccount) ) { diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 8f4acc060..e51321561 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -342,9 +342,12 @@ export class PortfolioController { @Query('assetClasses') filterByAssetClasses?: string, @Query('range') dateRange: DateRange = 'max', @Query('tags') filterByTags?: string, - @Query('withExcludedAccounts') withExcludedAccounts = false, - @Query('withItems') withItems = false + @Query('withExcludedAccounts') withExcludedAccountsParam = 'false', + @Query('withItems') withItemsParam = 'false' ): Promise { + const withExcludedAccounts = withExcludedAccountsParam === 'true'; + const withItems = withItemsParam === 'true'; + const hasReadRestrictedAccessPermission = this.userService.hasReadRestrictedAccessPermission({ impersonationId, diff --git a/apps/api/src/app/symbol/symbol.controller.ts b/apps/api/src/app/symbol/symbol.controller.ts index e41267b79..17e0056d6 100644 --- a/apps/api/src/app/symbol/symbol.controller.ts +++ b/apps/api/src/app/symbol/symbol.controller.ts @@ -39,9 +39,11 @@ export class SymbolController { @UseGuards(AuthGuard('jwt'), HasPermissionGuard) @UseInterceptors(TransformDataSourceInResponseInterceptor) public async lookupSymbol( - @Query('includeIndices') includeIndices = false, + @Query('includeIndices') includeIndicesParam = 'false', @Query('query') query = '' ): Promise<{ items: LookupItem[] }> { + const includeIndices = includeIndicesParam === 'true'; + try { return this.symbolService.lookup({ includeIndices, From 144d83195454030cc7368c64ffa61d2e49493726 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 4 Mar 2024 20:17:05 +0100 Subject: [PATCH 003/203] Release 2.61.0 (#3097) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dbe4e13d9..e19467e59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.61.0 - 2024-03-04 ### Changed diff --git a/package.json b/package.json index a23717491..cc83d588e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.60.0", + "version": "2.61.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From f1dc075c360c8aabebb271ad9be0d20e6199ae4a Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 5 Mar 2024 10:16:59 +0100 Subject: [PATCH 004/203] Update translations (#3093) --- apps/client/src/locales/messages.de.xlf | 64 ++++++++++++------------- apps/client/src/locales/messages.es.xlf | 64 ++++++++++++------------- apps/client/src/locales/messages.fr.xlf | 64 ++++++++++++------------- apps/client/src/locales/messages.it.xlf | 64 ++++++++++++------------- apps/client/src/locales/messages.nl.xlf | 64 ++++++++++++------------- apps/client/src/locales/messages.pl.xlf | 64 ++++++++++++------------- apps/client/src/locales/messages.pt.xlf | 64 ++++++++++++------------- apps/client/src/locales/messages.tr.xlf | 64 ++++++++++++------------- apps/client/src/locales/messages.xlf | 64 ++++++++++++------------- 9 files changed, 288 insertions(+), 288 deletions(-) diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index ff863284d..18f341aac 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -196,10 +196,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 263 @@ -212,6 +208,10 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 265 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 266 + libs/ui/src/lib/account-balances/account-balances.component.html 20 @@ -494,7 +494,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 411 + 412 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -534,7 +534,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 418 + 419 @@ -1468,7 +1468,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 260 + 261 @@ -1528,7 +1528,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 366 + 367 libs/ui/src/lib/assistant/assistant.html @@ -2300,7 +2300,7 @@ Zeitstrahl der Investitionen apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 294 + 298 @@ -2316,7 +2316,7 @@ Verlierer apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 214 + 216 @@ -2460,7 +2460,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 267 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2472,11 +2472,11 @@ Gebühr apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 285 + 286 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 313 + 314 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2496,7 +2496,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 322 + 323 @@ -2520,7 +2520,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 337 + 338 @@ -2884,7 +2884,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 353 + 354 @@ -3020,7 +3020,7 @@ libs/ui/src/lib/i18n.ts - 65 + 69 @@ -3032,7 +3032,7 @@ libs/ui/src/lib/i18n.ts - 66 + 70 @@ -3156,7 +3156,7 @@ Portfolio Wertentwicklung apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 264 + 268 @@ -3332,7 +3332,7 @@ Nordamerika libs/ui/src/lib/i18n.ts - 58 + 62 @@ -3340,7 +3340,7 @@ Afrika libs/ui/src/lib/i18n.ts - 55 + 59 @@ -3348,7 +3348,7 @@ Asien libs/ui/src/lib/i18n.ts - 56 + 60 @@ -3356,7 +3356,7 @@ Europa libs/ui/src/lib/i18n.ts - 57 + 61 @@ -3364,7 +3364,7 @@ Ozeanien libs/ui/src/lib/i18n.ts - 59 + 63 @@ -3372,7 +3372,7 @@ Südamerika libs/ui/src/lib/i18n.ts - 60 + 64 @@ -3464,7 +3464,7 @@ Zeitstrahl der Dividenden apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 352 + 356 @@ -4008,7 +4008,7 @@ Ups! Der historische Wechselkurs konnte nicht abgerufen werden vom apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 303 + 304 @@ -4320,7 +4320,7 @@ Aktueller Streak apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 315 + 319 @@ -4328,7 +4328,7 @@ Längster Streak apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 324 + 328 @@ -13740,7 +13740,7 @@ Extreme Angst libs/ui/src/lib/i18n.ts - 63 + 67 @@ -13748,7 +13748,7 @@ Extreme Gier libs/ui/src/lib/i18n.ts - 64 + 68 @@ -13756,7 +13756,7 @@ Neutral libs/ui/src/lib/i18n.ts - 67 + 71 diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index 6b281bd92..0ad1ae585 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -197,10 +197,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 263 @@ -213,6 +209,10 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 265 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 266 + libs/ui/src/lib/account-balances/account-balances.component.html 20 @@ -495,7 +495,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 411 + 412 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -535,7 +535,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 418 + 419 @@ -1466,7 +1466,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 260 + 261 @@ -1526,7 +1526,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 366 + 367 libs/ui/src/lib/assistant/assistant.html @@ -2298,7 +2298,7 @@ Cronología de la inversión apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 294 + 298 @@ -2314,7 +2314,7 @@ Lo peor apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 214 + 216 @@ -2458,7 +2458,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 267 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2470,11 +2470,11 @@ Comisión apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 285 + 286 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 313 + 314 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2494,7 +2494,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 322 + 323 @@ -2518,7 +2518,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 337 + 338 @@ -2870,7 +2870,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 353 + 354 @@ -3018,7 +3018,7 @@ libs/ui/src/lib/i18n.ts - 65 + 69 @@ -3030,7 +3030,7 @@ libs/ui/src/lib/i18n.ts - 66 + 70 @@ -3154,7 +3154,7 @@ Evolución cartera apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 264 + 268 @@ -3330,7 +3330,7 @@ América del Norte libs/ui/src/lib/i18n.ts - 58 + 62 @@ -3338,7 +3338,7 @@ África libs/ui/src/lib/i18n.ts - 55 + 59 @@ -3346,7 +3346,7 @@ Asia libs/ui/src/lib/i18n.ts - 56 + 60 @@ -3354,7 +3354,7 @@ Europa libs/ui/src/lib/i18n.ts - 57 + 61 @@ -3362,7 +3362,7 @@ Oceanía libs/ui/src/lib/i18n.ts - 59 + 63 @@ -3370,7 +3370,7 @@ América del Sur libs/ui/src/lib/i18n.ts - 60 + 64 @@ -3474,7 +3474,7 @@ Dividend Timeline apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 352 + 356 @@ -4006,7 +4006,7 @@ Oops! Could not get the historical exchange rate from apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 303 + 304 @@ -4318,7 +4318,7 @@ Current Streak apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 315 + 319 @@ -4326,7 +4326,7 @@ Longest Streak apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 324 + 328 @@ -13738,7 +13738,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 63 + 67 @@ -13746,7 +13746,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 64 + 68 @@ -13754,7 +13754,7 @@ Neutral libs/ui/src/lib/i18n.ts - 67 + 71 diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index bc24987e3..21a67fe36 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -252,10 +252,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 263 @@ -268,6 +264,10 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 265 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 266 + libs/ui/src/lib/account-balances/account-balances.component.html 20 @@ -550,7 +550,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 411 + 412 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -590,7 +590,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 418 + 419 @@ -622,7 +622,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 337 + 338 @@ -646,7 +646,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 353 + 354 @@ -826,7 +826,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 322 + 323 @@ -922,7 +922,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 366 + 367 libs/ui/src/lib/assistant/assistant.html @@ -1534,7 +1534,7 @@ libs/ui/src/lib/i18n.ts - 65 + 69 @@ -1546,7 +1546,7 @@ libs/ui/src/lib/i18n.ts - 66 + 70 @@ -1837,7 +1837,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 260 + 261 @@ -2665,7 +2665,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 267 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2677,11 +2677,11 @@ Frais apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 285 + 286 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 313 + 314 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2941,7 +2941,7 @@ Bas apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 214 + 216 @@ -2949,7 +2949,7 @@ Évolution du Portefeuille apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 264 + 268 @@ -2957,7 +2957,7 @@ Historique des Investissements apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 294 + 298 @@ -2965,7 +2965,7 @@ Historique des Dividendes apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 352 + 356 @@ -3489,7 +3489,7 @@ Afrique libs/ui/src/lib/i18n.ts - 55 + 59 @@ -3497,7 +3497,7 @@ Asie libs/ui/src/lib/i18n.ts - 56 + 60 @@ -3505,7 +3505,7 @@ Europe libs/ui/src/lib/i18n.ts - 57 + 61 @@ -3513,7 +3513,7 @@ Amérique du Nord libs/ui/src/lib/i18n.ts - 58 + 62 @@ -3521,7 +3521,7 @@ Océanie libs/ui/src/lib/i18n.ts - 59 + 63 @@ -3529,7 +3529,7 @@ Amérique du Sud libs/ui/src/lib/i18n.ts - 60 + 64 @@ -4005,7 +4005,7 @@ Oups ! Nous n'avons pas pu obtenir le taux de change historique à partir de apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 303 + 304 @@ -4317,7 +4317,7 @@ Série en cours apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 315 + 319 @@ -4325,7 +4325,7 @@ Série la plus longue apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 324 + 328 @@ -13737,7 +13737,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 63 + 67 @@ -13745,7 +13745,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 64 + 68 @@ -13753,7 +13753,7 @@ Neutral libs/ui/src/lib/i18n.ts - 67 + 71 diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index ea76f547d..049c7964e 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -197,10 +197,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 263 @@ -213,6 +209,10 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 265 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 266 + libs/ui/src/lib/account-balances/account-balances.component.html 20 @@ -495,7 +495,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 411 + 412 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -535,7 +535,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 418 + 419 @@ -1466,7 +1466,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 260 + 261 @@ -1526,7 +1526,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 366 + 367 libs/ui/src/lib/assistant/assistant.html @@ -2298,7 +2298,7 @@ Cronologia degli investimenti apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 294 + 298 @@ -2314,7 +2314,7 @@ In basso apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 214 + 216 @@ -2458,7 +2458,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 267 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2470,11 +2470,11 @@ Commissione apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 285 + 286 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 313 + 314 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2494,7 +2494,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 322 + 323 @@ -2518,7 +2518,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 337 + 338 @@ -2870,7 +2870,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 353 + 354 @@ -3018,7 +3018,7 @@ libs/ui/src/lib/i18n.ts - 65 + 69 @@ -3030,7 +3030,7 @@ libs/ui/src/lib/i18n.ts - 66 + 70 @@ -3154,7 +3154,7 @@ Evoluzione del portafoglio apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 264 + 268 @@ -3330,7 +3330,7 @@ Nord America libs/ui/src/lib/i18n.ts - 58 + 62 @@ -3338,7 +3338,7 @@ Africa libs/ui/src/lib/i18n.ts - 55 + 59 @@ -3346,7 +3346,7 @@ Asia libs/ui/src/lib/i18n.ts - 56 + 60 @@ -3354,7 +3354,7 @@ Europa libs/ui/src/lib/i18n.ts - 57 + 61 @@ -3362,7 +3362,7 @@ Oceania libs/ui/src/lib/i18n.ts - 59 + 63 @@ -3370,7 +3370,7 @@ Sud America libs/ui/src/lib/i18n.ts - 60 + 64 @@ -3474,7 +3474,7 @@ Cronologia dei dividendi apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 352 + 356 @@ -4006,7 +4006,7 @@ Ops! Impossibile ottenere il tasso di cambio storico da apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 303 + 304 @@ -4318,7 +4318,7 @@ Serie attuale apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 315 + 319 @@ -4326,7 +4326,7 @@ Serie più lunga apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 324 + 328 @@ -13738,7 +13738,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 63 + 67 @@ -13746,7 +13746,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 64 + 68 @@ -13754,7 +13754,7 @@ Neutral libs/ui/src/lib/i18n.ts - 67 + 71 diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index f4db03880..c70186bef 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -196,10 +196,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 263 @@ -212,6 +208,10 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 265 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 266 + libs/ui/src/lib/account-balances/account-balances.component.html 20 @@ -494,7 +494,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 411 + 412 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -534,7 +534,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 418 + 419 @@ -1465,7 +1465,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 260 + 261 @@ -1525,7 +1525,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 366 + 367 libs/ui/src/lib/assistant/assistant.html @@ -2297,7 +2297,7 @@ Tijdlijn investeringen apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 294 + 298 @@ -2313,7 +2313,7 @@ Verliezers apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 214 + 216 @@ -2457,7 +2457,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 267 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2469,11 +2469,11 @@ Transactiekosten apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 285 + 286 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 313 + 314 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2493,7 +2493,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 322 + 323 @@ -2517,7 +2517,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 337 + 338 @@ -2869,7 +2869,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 353 + 354 @@ -3017,7 +3017,7 @@ libs/ui/src/lib/i18n.ts - 65 + 69 @@ -3029,7 +3029,7 @@ libs/ui/src/lib/i18n.ts - 66 + 70 @@ -3153,7 +3153,7 @@ Waardeontwikkeling van portefeuille apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 264 + 268 @@ -3329,7 +3329,7 @@ Noord-Amerika libs/ui/src/lib/i18n.ts - 58 + 62 @@ -3337,7 +3337,7 @@ Afrika libs/ui/src/lib/i18n.ts - 55 + 59 @@ -3345,7 +3345,7 @@ Azië libs/ui/src/lib/i18n.ts - 56 + 60 @@ -3353,7 +3353,7 @@ Europa libs/ui/src/lib/i18n.ts - 57 + 61 @@ -3361,7 +3361,7 @@ Oceanië libs/ui/src/lib/i18n.ts - 59 + 63 @@ -3369,7 +3369,7 @@ Zuid-Amerika libs/ui/src/lib/i18n.ts - 60 + 64 @@ -3473,7 +3473,7 @@ Tijdlijn dividend apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 352 + 356 @@ -4005,7 +4005,7 @@ Oeps! Kon de historische wisselkoers niet krijgen van apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 303 + 304 @@ -4317,7 +4317,7 @@ Huidige reeks apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 315 + 319 @@ -4325,7 +4325,7 @@ Langste reeks apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 324 + 328 @@ -13737,7 +13737,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 63 + 67 @@ -13745,7 +13745,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 64 + 68 @@ -13753,7 +13753,7 @@ Neutral libs/ui/src/lib/i18n.ts - 67 + 71 diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf index a18db441a..e5e5d6b27 100644 --- a/apps/client/src/locales/messages.pl.xlf +++ b/apps/client/src/locales/messages.pl.xlf @@ -1760,10 +1760,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 263 @@ -1776,6 +1772,10 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 265 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 266 + libs/ui/src/lib/account-balances/account-balances.component.html 20 @@ -2058,7 +2058,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 411 + 412 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -2098,7 +2098,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 418 + 419 @@ -2162,7 +2162,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 337 + 338 @@ -2186,7 +2186,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 353 + 354 @@ -2414,7 +2414,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 322 + 323 @@ -2710,7 +2710,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 366 + 367 libs/ui/src/lib/assistant/assistant.html @@ -2998,7 +2998,7 @@ libs/ui/src/lib/i18n.ts - 65 + 69 @@ -3010,7 +3010,7 @@ libs/ui/src/lib/i18n.ts - 66 + 70 @@ -3440,7 +3440,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 260 + 261 @@ -5020,7 +5020,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 267 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5040,11 +5040,11 @@ Fee apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 285 + 286 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 313 + 314 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5056,7 +5056,7 @@ Oops! Could not get the historical exchange rate from apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 303 + 304 @@ -5412,7 +5412,7 @@ Bottom apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 214 + 216 @@ -5420,7 +5420,7 @@ Portfolio Evolution apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 264 + 268 @@ -5428,7 +5428,7 @@ Investment Timeline apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 294 + 298 @@ -5436,7 +5436,7 @@ Current Streak apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 315 + 319 @@ -5444,7 +5444,7 @@ Longest Streak apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 324 + 328 @@ -5452,7 +5452,7 @@ Dividend Timeline apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 352 + 356 @@ -13672,7 +13672,7 @@ Africa libs/ui/src/lib/i18n.ts - 55 + 59 @@ -13680,7 +13680,7 @@ Asia libs/ui/src/lib/i18n.ts - 56 + 60 @@ -13688,7 +13688,7 @@ Europe libs/ui/src/lib/i18n.ts - 57 + 61 @@ -13696,7 +13696,7 @@ North America libs/ui/src/lib/i18n.ts - 58 + 62 @@ -13704,7 +13704,7 @@ Oceania libs/ui/src/lib/i18n.ts - 59 + 63 @@ -13712,7 +13712,7 @@ South America libs/ui/src/lib/i18n.ts - 60 + 64 @@ -13720,7 +13720,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 63 + 67 @@ -13728,7 +13728,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 64 + 68 @@ -13736,7 +13736,7 @@ Neutral libs/ui/src/lib/i18n.ts - 67 + 71 diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index 52f19e666..2d3eeaa55 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -252,10 +252,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 263 @@ -268,6 +264,10 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 265 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 266 + libs/ui/src/lib/account-balances/account-balances.component.html 20 @@ -550,7 +550,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 411 + 412 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -590,7 +590,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 418 + 419 @@ -622,7 +622,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 337 + 338 @@ -646,7 +646,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 353 + 354 @@ -1402,7 +1402,7 @@ libs/ui/src/lib/i18n.ts - 65 + 69 @@ -1414,7 +1414,7 @@ libs/ui/src/lib/i18n.ts - 66 + 70 @@ -1713,7 +1713,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 260 + 261 @@ -1849,7 +1849,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 366 + 367 libs/ui/src/lib/assistant/assistant.html @@ -2573,7 +2573,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 267 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2585,11 +2585,11 @@ Comissão apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 285 + 286 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 313 + 314 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2609,7 +2609,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 322 + 323 @@ -2821,7 +2821,7 @@ Fundo apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 214 + 216 @@ -2829,7 +2829,7 @@ Evolução do Portefólio apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 264 + 268 @@ -2837,7 +2837,7 @@ Cronograma de Investimento apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 294 + 298 @@ -3341,7 +3341,7 @@ África libs/ui/src/lib/i18n.ts - 55 + 59 @@ -3349,7 +3349,7 @@ Ásia libs/ui/src/lib/i18n.ts - 56 + 60 @@ -3357,7 +3357,7 @@ Europa libs/ui/src/lib/i18n.ts - 57 + 61 @@ -3365,7 +3365,7 @@ América do Norte libs/ui/src/lib/i18n.ts - 58 + 62 @@ -3373,7 +3373,7 @@ Oceânia libs/ui/src/lib/i18n.ts - 59 + 63 @@ -3381,7 +3381,7 @@ América do Sul libs/ui/src/lib/i18n.ts - 60 + 64 @@ -3541,7 +3541,7 @@ Cronograma de Dividendos apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 352 + 356 @@ -4005,7 +4005,7 @@ Oops! Não foi possível obter a taxa de câmbio histórica de apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 303 + 304 @@ -4317,7 +4317,7 @@ Série Atual apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 315 + 319 @@ -4325,7 +4325,7 @@ Série mais Longa apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 324 + 328 @@ -13737,7 +13737,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 63 + 67 @@ -13745,7 +13745,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 64 + 68 @@ -13753,7 +13753,7 @@ Neutral libs/ui/src/lib/i18n.ts - 67 + 71 diff --git a/apps/client/src/locales/messages.tr.xlf b/apps/client/src/locales/messages.tr.xlf index 1c91aa8de..1e137c100 100644 --- a/apps/client/src/locales/messages.tr.xlf +++ b/apps/client/src/locales/messages.tr.xlf @@ -1724,10 +1724,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 263 @@ -1740,6 +1736,10 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 265 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 266 + libs/ui/src/lib/account-balances/account-balances.component.html 20 @@ -2022,7 +2022,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 411 + 412 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -2062,7 +2062,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 418 + 419 @@ -2118,7 +2118,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 337 + 338 @@ -2142,7 +2142,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 353 + 354 @@ -2338,7 +2338,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 322 + 323 @@ -2454,7 +2454,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 366 + 367 libs/ui/src/lib/assistant/assistant.html @@ -2850,7 +2850,7 @@ libs/ui/src/lib/i18n.ts - 65 + 69 @@ -2862,7 +2862,7 @@ libs/ui/src/lib/i18n.ts - 66 + 70 @@ -3265,7 +3265,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 260 + 261 @@ -4497,7 +4497,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 267 libs/ui/src/lib/activities-table/activities-table.component.html @@ -4509,7 +4509,7 @@ Hay Allah! Geçmiş döviz kuru alınamadı: apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 303 + 304 @@ -4517,11 +4517,11 @@ Komisyon apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 285 + 286 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 313 + 314 libs/ui/src/lib/activities-table/activities-table.component.html @@ -4889,7 +4889,7 @@ Alt apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 214 + 216 @@ -4897,7 +4897,7 @@ Portföyün Gelişimi apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 264 + 268 @@ -4905,7 +4905,7 @@ Yatırım Zaman Çizelgesi apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 294 + 298 @@ -4913,7 +4913,7 @@ Güncel Seri apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 315 + 319 @@ -4921,7 +4921,7 @@ En Uzun Seri apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 324 + 328 @@ -4929,7 +4929,7 @@ Temettü Zaman Çizelgesi apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 352 + 356 @@ -13077,7 +13077,7 @@ Africa libs/ui/src/lib/i18n.ts - 55 + 59 @@ -13085,7 +13085,7 @@ Asia libs/ui/src/lib/i18n.ts - 56 + 60 @@ -13093,7 +13093,7 @@ Europe libs/ui/src/lib/i18n.ts - 57 + 61 @@ -13101,7 +13101,7 @@ North America libs/ui/src/lib/i18n.ts - 58 + 62 @@ -13109,7 +13109,7 @@ Oceania libs/ui/src/lib/i18n.ts - 59 + 63 @@ -13117,7 +13117,7 @@ South America libs/ui/src/lib/i18n.ts - 60 + 64 @@ -13737,7 +13737,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 63 + 67 @@ -13745,7 +13745,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 64 + 68 @@ -13753,7 +13753,7 @@ Neutral libs/ui/src/lib/i18n.ts - 67 + 71 diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index d50ca4a31..871afeace 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -1729,10 +1729,6 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 201 - - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 262 - apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 263 @@ -1745,6 +1741,10 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html 265 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 266 + libs/ui/src/lib/account-balances/account-balances.component.html 20 @@ -2008,7 +2008,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 411 + 412 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -2047,7 +2047,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 418 + 419 @@ -2105,7 +2105,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 337 + 338 @@ -2128,7 +2128,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 353 + 354 @@ -2336,7 +2336,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 322 + 323 @@ -2607,7 +2607,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 366 + 367 libs/ui/src/lib/assistant/assistant.html @@ -2865,7 +2865,7 @@ libs/ui/src/lib/i18n.ts - 65 + 69 @@ -2876,7 +2876,7 @@ libs/ui/src/lib/i18n.ts - 66 + 70 @@ -3259,7 +3259,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 260 + 261 @@ -4673,7 +4673,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 267 libs/ui/src/lib/activities-table/activities-table.component.html @@ -4691,11 +4691,11 @@ Fee apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 285 + 286 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 313 + 314 libs/ui/src/lib/activities-table/activities-table.component.html @@ -4706,7 +4706,7 @@ Oops! Could not get the historical exchange rate from apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 303 + 304 @@ -5022,42 +5022,42 @@ Bottom apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 214 + 216 Portfolio Evolution apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 264 + 268 Investment Timeline apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 294 + 298 Current Streak apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 315 + 319 Longest Streak apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 324 + 328 Dividend Timeline apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 352 + 356 @@ -13946,63 +13946,63 @@ Africa libs/ui/src/lib/i18n.ts - 55 + 59 Asia libs/ui/src/lib/i18n.ts - 56 + 60 Europe libs/ui/src/lib/i18n.ts - 57 + 61 North America libs/ui/src/lib/i18n.ts - 58 + 62 Oceania libs/ui/src/lib/i18n.ts - 59 + 63 South America libs/ui/src/lib/i18n.ts - 60 + 64 Extreme Fear libs/ui/src/lib/i18n.ts - 63 + 67 Extreme Greed libs/ui/src/lib/i18n.ts - 64 + 68 Neutral libs/ui/src/lib/i18n.ts - 67 + 71 From f3a8822a7710f3e16616f7f224cf846e1ebf4056 Mon Sep 17 00:00:00 2001 From: Gerard Du Pre <37554513+GerardPolloRebozado@users.noreply.github.com> Date: Wed, 6 Mar 2024 11:11:10 +0100 Subject: [PATCH 005/203] Feature/remove-v-from-version-in-admin-endpoint (#3101) * Remove "v" from version in admin endpoint --- apps/api/src/environments/environment.prod.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/api/src/environments/environment.prod.ts b/apps/api/src/environments/environment.prod.ts index bc8aa65a4..81b324963 100644 --- a/apps/api/src/environments/environment.prod.ts +++ b/apps/api/src/environments/environment.prod.ts @@ -1,4 +1,4 @@ export const environment = { production: true, - version: `v${require('../../../../package.json').version}` + version: `${require('../../../../package.json').version}` }; From c54392b7bbc0a653b4fcba9d9c4c62103706011f Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Wed, 6 Mar 2024 22:06:27 +0100 Subject: [PATCH 006/203] Bugfix/fix exception in account value calculation (#3109) * Fix exception in value of account calculation caused by liabilities * Update changelog --- CHANGELOG.md | 6 + .../src/app/portfolio/portfolio.service.ts | 125 ++++++++++-------- 2 files changed, 77 insertions(+), 54 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e19467e59..0dce1cf4e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Fixed + +- Fixed an issue in the account value calculation caused by liabilities + ## 2.61.0 - 2024-03-04 ### Changed diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index d07389049..0d14e35df 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -439,15 +439,33 @@ export class PortfolioService { portfolioItemsNow[position.symbol] = position; } - for (const item of currentPositions.positions) { - if (item.quantity.lte(0)) { + for (const { + currency, + firstBuyDate, + grossPerformance, + grossPerformanceWithCurrencyEffect, + grossPerformancePercentage, + grossPerformancePercentageWithCurrencyEffect, + investment, + marketPrice, + marketPriceInBaseCurrency, + netPerformance, + netPerformancePercentage, + netPerformancePercentageWithCurrencyEffect, + netPerformanceWithCurrencyEffect, + quantity, + symbol, + tags, + transactionCount + } of currentPositions.positions) { + if (quantity.eq(0)) { // Ignore positions without any quantity continue; } - const value = item.quantity.mul(item.marketPriceInBaseCurrency ?? 0); - const symbolProfile = symbolProfileMap[item.symbol]; - const dataProviderResponse = dataProviderResponses[item.symbol]; + const value = quantity.mul(marketPriceInBaseCurrency ?? 0); + const symbolProfile = symbolProfileMap[symbol]; + const dataProviderResponse = dataProviderResponses[symbol]; const markets: PortfolioPosition['markets'] = { [UNKNOWN_KEY]: 0, @@ -519,40 +537,39 @@ export class PortfolioService { .toNumber(); } - holdings[item.symbol] = { + holdings[symbol] = { + currency, markets, marketsAdvanced, + marketPrice, + symbol, + tags, + transactionCount, allocationInPercentage: filteredValueInBaseCurrency.eq(0) ? 0 : value.div(filteredValueInBaseCurrency).toNumber(), assetClass: symbolProfile.assetClass, assetSubClass: symbolProfile.assetSubClass, countries: symbolProfile.countries, - currency: item.currency, dataSource: symbolProfile.dataSource, - dateOfFirstActivity: parseDate(item.firstBuyDate), - grossPerformance: item.grossPerformance?.toNumber() ?? 0, - grossPerformancePercent: - item.grossPerformancePercentage?.toNumber() ?? 0, + dateOfFirstActivity: parseDate(firstBuyDate), + grossPerformance: grossPerformance?.toNumber() ?? 0, + grossPerformancePercent: grossPerformancePercentage?.toNumber() ?? 0, grossPerformancePercentWithCurrencyEffect: - item.grossPerformancePercentageWithCurrencyEffect?.toNumber() ?? 0, + grossPerformancePercentageWithCurrencyEffect?.toNumber() ?? 0, grossPerformanceWithCurrencyEffect: - item.grossPerformanceWithCurrencyEffect?.toNumber() ?? 0, - investment: item.investment.toNumber(), - marketPrice: item.marketPrice, + grossPerformanceWithCurrencyEffect?.toNumber() ?? 0, + investment: investment.toNumber(), marketState: dataProviderResponse?.marketState ?? 'delayed', name: symbolProfile.name, - netPerformance: item.netPerformance?.toNumber() ?? 0, - netPerformancePercent: item.netPerformancePercentage?.toNumber() ?? 0, + netPerformance: netPerformance?.toNumber() ?? 0, + netPerformancePercent: netPerformancePercentage?.toNumber() ?? 0, netPerformancePercentWithCurrencyEffect: - item.netPerformancePercentageWithCurrencyEffect?.toNumber() ?? 0, + netPerformancePercentageWithCurrencyEffect?.toNumber() ?? 0, netPerformanceWithCurrencyEffect: - item.netPerformanceWithCurrencyEffect?.toNumber() ?? 0, - quantity: item.quantity.toNumber(), + netPerformanceWithCurrencyEffect?.toNumber() ?? 0, + quantity: quantity.toNumber(), sectors: symbolProfile.sectors, - symbol: item.symbol, - tags: item.tags, - transactionCount: item.transactionCount, url: symbolProfile.url, valueInBaseCurrency: value.toNumber() }; @@ -1770,24 +1787,33 @@ export class PortfolioService { activityType: 'INTEREST' }).toNumber(); - const items = Object.keys(holdings) - .filter((symbol) => { - return isUUID(symbol) && holdings[symbol].dataSource === 'MANUAL'; - }) - .map((symbol) => { - return holdings[symbol].valueInBaseCurrency; - }) - .reduce( - (previous, current) => new Big(previous).plus(current), - new Big(0) - ) - .toNumber(); - - const liabilities = this.getSumOfActivityType({ - activities, - userCurrency, - activityType: 'LIABILITY' - }).toNumber(); + const items = getSum( + Object.keys(holdings) + .filter((symbol) => { + return ( + isUUID(symbol) && + holdings[symbol].dataSource === 'MANUAL' && + holdings[symbol].valueInBaseCurrency > 0 + ); + }) + .map((symbol) => { + return new Big(holdings[symbol].valueInBaseCurrency).abs(); + }) + ).toNumber(); + + const liabilities = getSum( + Object.keys(holdings) + .filter((symbol) => { + return ( + isUUID(symbol) && + holdings[symbol].dataSource === 'MANUAL' && + holdings[symbol].valueInBaseCurrency < 0 + ); + }) + .map((symbol) => { + return new Big(holdings[symbol].valueInBaseCurrency).abs(); + }) + ).toNumber(); const totalBuy = this.getSumOfActivityType({ userCurrency, @@ -1941,7 +1967,7 @@ export class PortfolioService { private async getTransactionPoints({ filters, includeDrafts = false, - types = ['BUY', 'ITEM', 'SELL'], + types = ['BUY', 'ITEM', 'LIABILITY', 'SELL'], userId, withExcludedAccounts = false }: { @@ -2076,19 +2102,10 @@ export class PortfolioService { }); for (const account of currentAccounts) { - let ordersByAccount = orders.filter(({ accountId }) => { + const ordersByAccount = orders.filter(({ accountId }) => { return accountId === account.id; }); - const ordersOfTypeItemOrLiabilityByAccount = - ordersOfTypeItemOrLiability.filter(({ accountId }) => { - return accountId === account.id; - }); - - ordersByAccount = ordersByAccount.concat( - ordersOfTypeItemOrLiabilityByAccount - ); - accounts[account.id] = { balance: account.balance, currency: account.currency, @@ -2128,8 +2145,8 @@ export class PortfolioService { } of ordersByAccount) { let currentValueOfSymbolInBaseCurrency = quantity * - portfolioItemsNow[SymbolProfile.symbol] - ?.marketPriceInBaseCurrency ?? 0; + (portfolioItemsNow[SymbolProfile.symbol]?.marketPriceInBaseCurrency ?? + 0); if (['LIABILITY', 'SELL'].includes(type)) { currentValueOfSymbolInBaseCurrency *= getFactor(type); From c641c28b12d11ef0d989140e45e51373ddb24c5f Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Wed, 6 Mar 2024 22:08:00 +0100 Subject: [PATCH 007/203] Release 2.61.1 (#3110) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0dce1cf4e..1dce287c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.61.1 - 2024-03-06 ### Fixed diff --git a/package.json b/package.json index cc83d588e..8faa5ff8a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.61.0", + "version": "2.61.1", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 77358eed65ffcfb75ee0d00bd96649fa86d792ef Mon Sep 17 00:00:00 2001 From: Gerard Du Pre <37554513+GerardPolloRebozado@users.noreply.github.com> Date: Thu, 7 Mar 2024 19:38:57 +0100 Subject: [PATCH 008/203] Feature/Include user role in admin endpoint (#3107) * Include user role in admin endpoint --- apps/api/src/app/admin/admin.service.ts | 4 +++- libs/common/src/lib/interfaces/admin-data.interface.ts | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/api/src/app/admin/admin.service.ts b/apps/api/src/app/admin/admin.service.ts index 320601667..f78d1b61d 100644 --- a/apps/api/src/app/admin/admin.service.ts +++ b/apps/api/src/app/admin/admin.service.ts @@ -440,13 +440,14 @@ export class AdminService { }, createdAt: true, id: true, + role: true, Subscription: true }, take: 30 }); return usersWithAnalytics.map( - ({ _count, Analytics, createdAt, id, Subscription }) => { + ({ _count, Analytics, createdAt, id, role, Subscription }) => { const daysSinceRegistration = differenceInDays(new Date(), createdAt) + 1; const engagement = Analytics @@ -466,6 +467,7 @@ export class AdminService { createdAt, engagement, id, + role, subscription, accountCount: _count.Account || 0, country: Analytics?.country, diff --git a/libs/common/src/lib/interfaces/admin-data.interface.ts b/libs/common/src/lib/interfaces/admin-data.interface.ts index 6d51d5d52..2c6a5c501 100644 --- a/libs/common/src/lib/interfaces/admin-data.interface.ts +++ b/libs/common/src/lib/interfaces/admin-data.interface.ts @@ -1,3 +1,5 @@ +import { Role } from '@prisma/client'; + import { UniqueAsset } from './unique-asset.interface'; export interface AdminData { @@ -16,6 +18,7 @@ export interface AdminData { engagement: number; id: string; lastActivity: Date; + role: Role; transactionCount: number; }[]; version: string; From 07661d9262a6a926859b2ca7b9e75656086df126 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 7 Mar 2024 20:07:50 +0100 Subject: [PATCH 009/203] Feature/integrate dividend into transaction point concept (#3092) * Integrate dividend into transaction point concept * Update changelog --- CHANGELOG.md | 6 + apps/api/jest.config.ts | 1 - apps/api/src/app/order/order.service.ts | 2 + .../portfolio/current-rate.service.mock.ts | 9 ++ .../transaction-point-symbol.interface.ts | 2 + ...folio-calculator-baln-buy-and-sell.spec.ts | 2 + .../portfolio-calculator-baln-buy.spec.ts | 2 + ...ator-btcusd-buy-and-sell-partially.spec.ts | 2 + .../portfolio-calculator-googl-buy.spec.ts | 2 + ...-calculator-msft-buy-with-dividend.spec.ts | 118 ++++++++++++++++++ ...ulator-novn-buy-and-sell-partially.spec.ts | 2 + ...folio-calculator-novn-buy-and-sell.spec.ts | 2 + .../src/app/portfolio/portfolio-calculator.ts | 114 ++++++++++------- .../src/app/portfolio/portfolio.controller.ts | 22 +++- .../src/app/portfolio/portfolio.service.ts | 67 ++++------ .../exchange-rate-data.service.mock.ts | 7 ++ .../portfolio-summary.component.html | 2 +- .../portfolio-position.interface.ts | 1 + .../interfaces/portfolio-summary.interface.ts | 2 +- .../interfaces/symbol-metrics.interface.ts | 2 + .../interfaces/timeline-position.interface.ts | 2 + 21 files changed, 275 insertions(+), 94 deletions(-) create mode 100644 apps/api/src/app/portfolio/portfolio-calculator-msft-buy-with-dividend.spec.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 1dce287c1..5da3b143b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- Integrated dividend into the transaction point concept in the portfolio service + ## 2.61.1 - 2024-03-06 ### Fixed diff --git a/apps/api/jest.config.ts b/apps/api/jest.config.ts index 8152c3f2a..b87f91a79 100644 --- a/apps/api/jest.config.ts +++ b/apps/api/jest.config.ts @@ -13,7 +13,6 @@ export default { }, moduleFileExtensions: ['ts', 'js', 'html'], coverageDirectory: '../../coverage/apps/api', - testTimeout: 10000, testEnvironment: 'node', preset: '../../jest.preset.js' }; diff --git a/apps/api/src/app/order/order.service.ts b/apps/api/src/app/order/order.service.ts index d200ee024..c97243929 100644 --- a/apps/api/src/app/order/order.service.ts +++ b/apps/api/src/app/order/order.service.ts @@ -340,11 +340,13 @@ export class OrderService { return { ...order, value, + // TODO: Use exchange rate of date feeInBaseCurrency: this.exchangeRateDataService.toCurrency( order.fee, order.SymbolProfile.currency, userCurrency ), + // TODO: Use exchange rate of date valueInBaseCurrency: this.exchangeRateDataService.toCurrency( value, order.SymbolProfile.currency, diff --git a/apps/api/src/app/portfolio/current-rate.service.mock.ts b/apps/api/src/app/portfolio/current-rate.service.mock.ts index 76e7aae09..8f8d06112 100644 --- a/apps/api/src/app/portfolio/current-rate.service.mock.ts +++ b/apps/api/src/app/portfolio/current-rate.service.mock.ts @@ -43,6 +43,15 @@ function mockGetValue(symbol: string, date: Date) { return { marketPrice: 0 }; + case 'MSFT': + if (isSameDay(parseDate('2021-09-16'), date)) { + return { marketPrice: 89.12 }; + } else if (isSameDay(parseDate('2023-07-10'), date)) { + return { marketPrice: 331.83 }; + } + + return { marketPrice: 0 }; + case 'NOVN.SW': if (isSameDay(parseDate('2022-04-11'), date)) { return { marketPrice: 87.8 }; diff --git a/apps/api/src/app/portfolio/interfaces/transaction-point-symbol.interface.ts b/apps/api/src/app/portfolio/interfaces/transaction-point-symbol.interface.ts index 5350adccc..fb2f0a389 100644 --- a/apps/api/src/app/portfolio/interfaces/transaction-point-symbol.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/transaction-point-symbol.interface.ts @@ -2,8 +2,10 @@ import { DataSource, Tag } from '@prisma/client'; import Big from 'big.js'; export interface TransactionPointSymbol { + averagePrice: Big; currency: string; dataSource: DataSource; + dividend: Big; fee: Big; firstBuyDate: string; investment: Big; diff --git a/apps/api/src/app/portfolio/portfolio-calculator-baln-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-baln-buy-and-sell.spec.ts index d81393719..9831e5b00 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator-baln-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator-baln-buy-and-sell.spec.ts @@ -107,6 +107,8 @@ describe('PortfolioCalculator', () => { averagePrice: new Big('0'), currency: 'CHF', dataSource: 'YAHOO', + dividend: new Big('0'), + dividendInBaseCurrency: new Big('0'), fee: new Big('3.2'), firstBuyDate: '2021-11-22', grossPerformance: new Big('-12.6'), diff --git a/apps/api/src/app/portfolio/portfolio-calculator-baln-buy.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-baln-buy.spec.ts index e77335ab8..bb5986059 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator-baln-buy.spec.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator-baln-buy.spec.ts @@ -96,6 +96,8 @@ describe('PortfolioCalculator', () => { averagePrice: new Big('136.6'), currency: 'CHF', dataSource: 'YAHOO', + dividend: new Big('0'), + dividendInBaseCurrency: new Big('0'), fee: new Big('1.55'), firstBuyDate: '2021-11-30', grossPerformance: new Big('24.6'), diff --git a/apps/api/src/app/portfolio/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts index 8f5573928..6126311c3 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts @@ -120,6 +120,8 @@ describe('PortfolioCalculator', () => { averagePrice: new Big('320.43'), currency: 'USD', dataSource: 'YAHOO', + dividend: new Big('0'), + dividendInBaseCurrency: new Big('0'), fee: new Big('0'), firstBuyDate: '2015-01-01', grossPerformance: new Big('27172.74'), diff --git a/apps/api/src/app/portfolio/portfolio-calculator-googl-buy.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-googl-buy.spec.ts index 502248388..d29498292 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator-googl-buy.spec.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator-googl-buy.spec.ts @@ -109,6 +109,8 @@ describe('PortfolioCalculator', () => { averagePrice: new Big('89.12'), currency: 'USD', dataSource: 'YAHOO', + dividend: new Big('0'), + dividendInBaseCurrency: new Big('0'), fee: new Big('1'), firstBuyDate: '2023-01-03', grossPerformance: new Big('27.33'), diff --git a/apps/api/src/app/portfolio/portfolio-calculator-msft-buy-with-dividend.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-msft-buy-with-dividend.spec.ts new file mode 100644 index 000000000..de63bced1 --- /dev/null +++ b/apps/api/src/app/portfolio/portfolio-calculator-msft-buy-with-dividend.spec.ts @@ -0,0 +1,118 @@ +import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; +import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; +import { ExchangeRateDataServiceMock } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service.mock'; +import { parseDate } from '@ghostfolio/common/helper'; + +import Big from 'big.js'; + +import { CurrentRateServiceMock } from './current-rate.service.mock'; +import { PortfolioCalculator } from './portfolio-calculator'; + +jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + CurrentRateService: jest.fn().mockImplementation(() => { + return CurrentRateServiceMock; + }) + }; +}); + +jest.mock( + '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service', + () => { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + ExchangeRateDataService: jest.fn().mockImplementation(() => { + return ExchangeRateDataServiceMock; + }) + }; + } +); + +describe('PortfolioCalculator', () => { + let currentRateService: CurrentRateService; + let exchangeRateDataService: ExchangeRateDataService; + + beforeEach(() => { + currentRateService = new CurrentRateService(null, null, null, null); + + exchangeRateDataService = new ExchangeRateDataService( + null, + null, + null, + null + ); + }); + + describe('get current positions', () => { + it.only('with MSFT buy', async () => { + const portfolioCalculator = new PortfolioCalculator({ + currentRateService, + exchangeRateDataService, + currency: 'USD', + orders: [ + { + currency: 'USD', + date: '2021-09-16', + dataSource: 'YAHOO', + fee: new Big(19), + name: 'Microsoft Inc.', + quantity: new Big(1), + symbol: 'MSFT', + type: 'BUY', + unitPrice: new Big(298.58) + }, + { + currency: 'USD', + date: '2021-11-16', + dataSource: 'YAHOO', + fee: new Big(0), + name: 'Microsoft Inc.', + quantity: new Big(1), + symbol: 'MSFT', + type: 'DIVIDEND', + unitPrice: new Big(0.62) + } + ] + }); + + portfolioCalculator.computeTransactionPoints(); + + const spy = jest + .spyOn(Date, 'now') + .mockImplementation(() => parseDate('2023-07-10').getTime()); + + const currentPositions = await portfolioCalculator.getCurrentPositions( + parseDate('2023-07-10') + ); + + spy.mockRestore(); + + expect(currentPositions).toMatchObject({ + errors: [], + hasErrors: false, + positions: [ + { + averagePrice: new Big('298.58'), + currency: 'USD', + dataSource: 'YAHOO', + dividend: new Big('0.62'), + dividendInBaseCurrency: new Big('0.62'), + fee: new Big('19'), + firstBuyDate: '2021-09-16', + investment: new Big('298.58'), + investmentWithCurrencyEffect: new Big('298.58'), + marketPrice: 331.83, + marketPriceInBaseCurrency: 331.83, + quantity: new Big('1'), + symbol: 'MSFT', + tags: undefined, + transactionCount: 2 + } + ], + totalInvestment: new Big('298.58'), + totalInvestmentWithCurrencyEffect: new Big('298.58') + }); + }); + }); +}); diff --git a/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell-partially.spec.ts index c46fd54d2..afddc5423 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell-partially.spec.ts @@ -107,6 +107,8 @@ describe('PortfolioCalculator', () => { averagePrice: new Big('75.80'), currency: 'CHF', dataSource: 'YAHOO', + dividend: new Big('0'), + dividendInBaseCurrency: new Big('0'), fee: new Big('4.25'), firstBuyDate: '2022-03-07', grossPerformance: new Big('21.93'), diff --git a/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell.spec.ts index fa3ebac9b..4b7750a63 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell.spec.ts @@ -133,6 +133,8 @@ describe('PortfolioCalculator', () => { averagePrice: new Big('0'), currency: 'CHF', dataSource: 'YAHOO', + dividend: new Big('0'), + dividendInBaseCurrency: new Big('0'), fee: new Big('0'), firstBuyDate: '2022-03-07', grossPerformance: new Big('19.86'), diff --git a/apps/api/src/app/portfolio/portfolio-calculator.ts b/apps/api/src/app/portfolio/portfolio-calculator.ts index 27a5a278b..f0551f3b8 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator.ts @@ -70,6 +70,7 @@ export class PortfolioCalculator { let lastDate: string = null; let lastTransactionPoint: TransactionPoint = null; + for (const order of this.orders) { const currentDate = order.date; @@ -77,33 +78,32 @@ export class PortfolioCalculator { const oldAccumulatedSymbol = symbols[order.symbol]; const factor = getFactor(order.type); - const unitPrice = new Big(order.unitPrice); + if (oldAccumulatedSymbol) { + let investment = oldAccumulatedSymbol.investment; + const newQuantity = order.quantity .mul(factor) .plus(oldAccumulatedSymbol.quantity); - let investment = new Big(0); - - if (newQuantity.gt(0)) { - if (order.type === 'BUY') { - investment = oldAccumulatedSymbol.investment.plus( - order.quantity.mul(unitPrice) - ); - } else if (order.type === 'SELL') { - const averagePrice = oldAccumulatedSymbol.investment.div( - oldAccumulatedSymbol.quantity - ); - investment = oldAccumulatedSymbol.investment.minus( - order.quantity.mul(averagePrice) - ); - } + if (order.type === 'BUY') { + investment = oldAccumulatedSymbol.investment.plus( + order.quantity.mul(order.unitPrice) + ); + } else if (order.type === 'SELL') { + investment = oldAccumulatedSymbol.investment.minus( + order.quantity.mul(oldAccumulatedSymbol.averagePrice) + ); } currentTransactionPointItem = { investment, + averagePrice: newQuantity.gt(0) + ? investment.div(newQuantity) + : new Big(0), currency: order.currency, dataSource: order.dataSource, + dividend: new Big(0), fee: order.fee.plus(oldAccumulatedSymbol.fee), firstBuyDate: oldAccumulatedSymbol.firstBuyDate, quantity: newQuantity, @@ -113,11 +113,13 @@ export class PortfolioCalculator { }; } else { currentTransactionPointItem = { + averagePrice: order.unitPrice, currency: order.currency, dataSource: order.dataSource, + dividend: new Big(0), fee: order.fee, firstBuyDate: order.date, - investment: unitPrice.mul(order.quantity).mul(factor), + investment: order.unitPrice.mul(order.quantity).mul(factor), quantity: order.quantity.mul(factor), symbol: order.symbol, tags: order.tags, @@ -128,22 +130,28 @@ export class PortfolioCalculator { symbols[order.symbol] = currentTransactionPointItem; const items = lastTransactionPoint?.items ?? []; + const newItems = items.filter( (transactionPointItem) => transactionPointItem.symbol !== order.symbol ); + newItems.push(currentTransactionPointItem); + newItems.sort((a, b) => { return a.symbol?.localeCompare(b.symbol); }); + if (lastDate !== currentDate || lastTransactionPoint === null) { lastTransactionPoint = { date: currentDate, items: newItems }; + this.transactionPoints.push(lastTransactionPoint); } else { lastTransactionPoint.items = newItems; } + lastDate = currentDate; } } @@ -583,6 +591,8 @@ export class PortfolioCalculator { ); const { + dividend, + dividendInBaseCurrency, grossPerformance, grossPerformancePercentage, grossPerformancePercentageWithCurrencyEffect, @@ -608,11 +618,11 @@ export class PortfolioCalculator { hasAnySymbolMetricsErrors = hasAnySymbolMetricsErrors || hasErrors; positions.push({ + dividend, + dividendInBaseCurrency, timeWeightedInvestment, timeWeightedInvestmentWithCurrencyEffect, - averagePrice: item.quantity.eq(0) - ? new Big(0) - : item.investment.div(item.quantity), + averagePrice: item.averagePrice, currency: item.currency, dataSource: item.dataSource, fee: item.fee, @@ -842,6 +852,8 @@ export class PortfolioCalculator { const currentExchangeRate = exchangeRates[format(new Date(), DATE_FORMAT)]; const currentValues: { [date: string]: Big } = {}; const currentValuesWithCurrencyEffect: { [date: string]: Big } = {}; + let dividend = new Big(0); + let dividendInBaseCurrency = new Big(0); let fees = new Big(0); let feesAtStartDate = new Big(0); let feesAtStartDateWithCurrencyEffect = new Big(0); @@ -894,6 +906,8 @@ export class PortfolioCalculator { return { currentValues: {}, currentValuesWithCurrencyEffect: {}, + dividend: new Big(0), + dividendInBaseCurrency: new Big(0), grossPerformance: new Big(0), grossPerformancePercentage: new Big(0), grossPerformancePercentageWithCurrencyEffect: new Big(0), @@ -934,6 +948,8 @@ export class PortfolioCalculator { return { currentValues: {}, currentValuesWithCurrencyEffect: {}, + dividend: new Big(0), + dividendInBaseCurrency: new Big(0), grossPerformance: new Big(0), grossPerformancePercentage: new Big(0), grossPerformancePercentageWithCurrencyEffect: new Big(0), @@ -1108,29 +1124,29 @@ export class PortfolioCalculator { valueOfInvestmentBeforeTransactionWithCurrencyEffect; } - const transactionInvestment = - order.type === 'BUY' - ? order.quantity - .mul(order.unitPriceInBaseCurrency) - .mul(getFactor(order.type)) - : totalUnits.gt(0) - ? totalInvestment - .div(totalUnits) - .mul(order.quantity) - .mul(getFactor(order.type)) - : new Big(0); - - const transactionInvestmentWithCurrencyEffect = - order.type === 'BUY' - ? order.quantity - .mul(order.unitPriceInBaseCurrencyWithCurrencyEffect) - .mul(getFactor(order.type)) - : totalUnits.gt(0) - ? totalInvestmentWithCurrencyEffect - .div(totalUnits) - .mul(order.quantity) - .mul(getFactor(order.type)) - : new Big(0); + let transactionInvestment = new Big(0); + let transactionInvestmentWithCurrencyEffect = new Big(0); + + if (order.type === 'BUY') { + transactionInvestment = order.quantity + .mul(order.unitPriceInBaseCurrency) + .mul(getFactor(order.type)); + transactionInvestmentWithCurrencyEffect = order.quantity + .mul(order.unitPriceInBaseCurrencyWithCurrencyEffect) + .mul(getFactor(order.type)); + } else if (order.type === 'SELL') { + if (totalUnits.gt(0)) { + transactionInvestment = totalInvestment + .div(totalUnits) + .mul(order.quantity) + .mul(getFactor(order.type)); + transactionInvestmentWithCurrencyEffect = + totalInvestmentWithCurrencyEffect + .div(totalUnits) + .mul(order.quantity) + .mul(getFactor(order.type)); + } + } if (PortfolioCalculator.ENABLE_LOGGING) { console.log('totalInvestment', totalInvestment.toNumber()); @@ -1186,6 +1202,13 @@ export class PortfolioCalculator { totalUnits = totalUnits.plus(order.quantity.mul(getFactor(order.type))); + if (order.type === 'DIVIDEND') { + dividend = dividend.plus(order.quantity.mul(order.unitPrice)); + dividendInBaseCurrency = dividendInBaseCurrency.plus( + dividend.mul(exchangeRateAtOrderDate ?? 1) + ); + } + const valueOfInvestment = totalUnits.mul(order.unitPriceInBaseCurrency); const valueOfInvestmentWithCurrencyEffect = totalUnits.mul( @@ -1277,7 +1300,7 @@ export class PortfolioCalculator { grossPerformanceWithCurrencyEffect; } - if (i > indexOfStartOrder) { + if (i > indexOfStartOrder && ['BUY', 'SELL'].includes(order.type)) { // Only consider periods with an investment for the calculation of // the time weighted investment if (valueOfInvestmentBeforeTransaction.gt(0)) { @@ -1471,6 +1494,7 @@ export class PortfolioCalculator { Time weighted investment with currency effect: ${timeWeightedAverageInvestmentBetweenStartAndEndDateWithCurrencyEffect.toFixed( 2 )} + Total dividend: ${dividend.toFixed(2)} Gross performance: ${totalGrossPerformance.toFixed( 2 )} / ${grossPerformancePercentage.mul(100).toFixed(2)}% @@ -1495,6 +1519,8 @@ export class PortfolioCalculator { return { currentValues, currentValuesWithCurrencyEffect, + dividend, + dividendInBaseCurrency, grossPerformancePercentage, grossPerformancePercentageWithCurrencyEffect, initialValue, diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index e51321561..63e26e512 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -1,4 +1,5 @@ import { AccessService } from '@ghostfolio/api/app/access/access.service'; +import { OrderService } from '@ghostfolio/api/app/order/order.service'; import { UserService } from '@ghostfolio/api/app/user/user.service'; import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; import { @@ -11,6 +12,7 @@ import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interc import { ApiService } from '@ghostfolio/api/services/api/api.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; +import { ImpersonationService } from '@ghostfolio/api/services/impersonation/impersonation.service'; import { DEFAULT_CURRENCY, HEADER_KEY_IMPERSONATION @@ -57,6 +59,8 @@ export class PortfolioController { private readonly apiService: ApiService, private readonly configurationService: ConfigurationService, private readonly exchangeRateDataService: ExchangeRateDataService, + private readonly impersonationService: ImpersonationService, + private readonly orderService: OrderService, private readonly portfolioService: PortfolioService, @Inject(REQUEST) private readonly request: RequestWithUser, private readonly userService: UserService @@ -161,7 +165,7 @@ export class PortfolioController { 'currentNetPerformance', 'currentNetPerformanceWithCurrencyEffect', 'currentValue', - 'dividend', + 'dividendInBaseCurrency', 'emergencyFund', 'excludedAccountsAndActivities', 'fees', @@ -231,11 +235,21 @@ export class PortfolioController { filterByTags }); + const impersonationUserId = + await this.impersonationService.validateImpersonationId(impersonationId); + const userCurrency = this.request.user.Settings.settings.baseCurrency; + + const { activities } = await this.orderService.getOrders({ + filters, + userCurrency, + userId: impersonationUserId || this.request.user.id, + types: ['DIVIDEND'] + }); + let dividends = await this.portfolioService.getDividends({ + activities, dateRange, - filters, - groupBy, - impersonationId + groupBy }); if ( diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 0d14e35df..d55b3d647 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -218,27 +218,14 @@ export class PortfolioService { } public async getDividends({ - dateRange, - filters, - groupBy, - impersonationId + activities, + dateRange = 'max', + groupBy }: { - dateRange: DateRange; - filters?: Filter[]; + activities: Activity[]; + dateRange?: DateRange; groupBy?: GroupBy; - impersonationId: string; }): Promise { - const userId = await this.getUserId(impersonationId, this.request.user.id); - const user = await this.userService.user({ id: userId }); - const userCurrency = this.getUserCurrency(user); - - const { activities } = await this.orderService.getOrders({ - filters, - userCurrency, - userId, - types: ['DIVIDEND'] - }); - let dividends = activities.map(({ date, valueInBaseCurrency }) => { return { date: format(date, DATE_FORMAT), @@ -441,6 +428,7 @@ export class PortfolioService { for (const { currency, + dividend, firstBuyDate, grossPerformance, grossPerformanceWithCurrencyEffect, @@ -553,6 +541,7 @@ export class PortfolioService { countries: symbolProfile.countries, dataSource: symbolProfile.dataSource, dateOfFirstActivity: parseDate(firstBuyDate), + dividend: dividend?.toNumber() ?? 0, grossPerformance: grossPerformance?.toNumber() ?? 0, grossPerformancePercent: grossPerformancePercentage?.toNumber() ?? 0, grossPerformancePercentWithCurrencyEffect: @@ -723,7 +712,7 @@ export class PortfolioService { .filter((order) => { tags = tags.concat(order.tags); - return ['BUY', 'ITEM', 'SELL'].includes(order.type); + return ['BUY', 'DIVIDEND', 'ITEM', 'SELL'].includes(order.type); }) .map((order) => ({ currency: order.SymbolProfile.currency, @@ -764,6 +753,7 @@ export class PortfolioService { averagePrice, currency, dataSource, + dividendInBaseCurrency, fee, firstBuyDate, marketPrice, @@ -780,16 +770,6 @@ export class PortfolioService { return Account; }); - const dividendInBaseCurrency = getSum( - orders - .filter(({ type }) => { - return type === 'DIVIDEND'; - }) - .map(({ valueInBaseCurrency }) => { - return new Big(valueInBaseCurrency); - }) - ); - const historicalData = await this.dataProviderService.getHistorical( [{ dataSource, symbol: aSymbol }], 'day', @@ -823,9 +803,7 @@ export class PortfolioService { ); if (currentSymbol) { - currentAveragePrice = currentSymbol.quantity.eq(0) - ? 0 - : currentSymbol.investment.div(currentSymbol.quantity).toNumber(); + currentAveragePrice = currentSymbol.averagePrice.toNumber(); currentQuantity = currentSymbol.quantity.toNumber(); } @@ -1636,6 +1614,7 @@ export class PortfolioService { countries: [], dataSource: undefined, dateOfFirstActivity: undefined, + dividend: 0, grossPerformance: 0, grossPerformancePercent: 0, grossPerformancePercentWithCurrencyEffect: 0, @@ -1765,11 +1744,16 @@ export class PortfolioService { } } - const dividend = this.getSumOfActivityType({ - activities, - userCurrency, - activityType: 'DIVIDEND' - }).toNumber(); + const dividendInBaseCurrency = ( + await this.getDividends({ + activities: activities.filter(({ type }) => { + return type === 'DIVIDEND'; + }) + }) + ).reduce( + (previous, current) => new Big(previous).plus(current.investment), + new Big(0) + ); const emergencyFund = new Big( Math.max( @@ -1904,7 +1888,6 @@ export class PortfolioService { annualizedPerformancePercent, annualizedPerformancePercentWithCurrencyEffect, cash, - dividend, excludedAccountsAndActivities, fees, firstOrderDate, @@ -1915,6 +1898,7 @@ export class PortfolioService { totalBuy, totalSell, committedFunds: committedFunds.toNumber(), + dividendInBaseCurrency: dividendInBaseCurrency.toNumber(), emergencyFund: { assets: emergencyFundPositionsValueInBaseCurrency, cash: emergencyFund @@ -1967,7 +1951,7 @@ export class PortfolioService { private async getTransactionPoints({ filters, includeDrafts = false, - types = ['BUY', 'ITEM', 'LIABILITY', 'SELL'], + types = ['BUY', 'DIVIDEND', 'ITEM', 'LIABILITY', 'SELL'], userId, withExcludedAccounts = false }: { @@ -2144,14 +2128,11 @@ export class PortfolioService { type } of ordersByAccount) { let currentValueOfSymbolInBaseCurrency = + getFactor(type) * quantity * (portfolioItemsNow[SymbolProfile.symbol]?.marketPriceInBaseCurrency ?? 0); - if (['LIABILITY', 'SELL'].includes(type)) { - currentValueOfSymbolInBaseCurrency *= getFactor(type); - } - if (accounts[Account?.id || UNKNOWN_KEY]?.valueInBaseCurrency) { accounts[Account?.id || UNKNOWN_KEY].valueInBaseCurrency += currentValueOfSymbolInBaseCurrency; diff --git a/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.mock.ts b/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.mock.ts index e32af51d3..a25f3a356 100644 --- a/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.mock.ts +++ b/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.mock.ts @@ -22,6 +22,13 @@ export const ExchangeRateDataServiceMock = { '2023-07-10': 0.8854 } }); + } else if (targetCurrency === 'USD') { + return Promise.resolve({ + USDUSD: { + '2018-01-01': 1, + '2023-07-10': 1 + } + }); } return Promise.resolve({}); diff --git a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html index c4aea8891..096271926 100644 --- a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html +++ b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html @@ -328,7 +328,7 @@ [isCurrency]="true" [locale]="locale" [unit]="baseCurrency" - [value]="isLoading ? undefined : summary?.dividend" + [value]="isLoading ? undefined : summary?.dividendInBaseCurrency" /> diff --git a/libs/common/src/lib/interfaces/portfolio-position.interface.ts b/libs/common/src/lib/interfaces/portfolio-position.interface.ts index 87db0117d..2e5772ef7 100644 --- a/libs/common/src/lib/interfaces/portfolio-position.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-position.interface.ts @@ -14,6 +14,7 @@ export interface PortfolioPosition { currency: string; dataSource: DataSource; dateOfFirstActivity: Date; + dividend: number; exchange?: string; grossPerformance: number; grossPerformancePercent: number; diff --git a/libs/common/src/lib/interfaces/portfolio-summary.interface.ts b/libs/common/src/lib/interfaces/portfolio-summary.interface.ts index f0bb4c3b1..aaf80c0cd 100644 --- a/libs/common/src/lib/interfaces/portfolio-summary.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-summary.interface.ts @@ -5,7 +5,7 @@ export interface PortfolioSummary extends PortfolioPerformance { annualizedPerformancePercentWithCurrencyEffect: number; cash: number; committedFunds: number; - dividend: number; + dividendInBaseCurrency: number; emergencyFund: { assets: number; cash: number; diff --git a/libs/common/src/lib/interfaces/symbol-metrics.interface.ts b/libs/common/src/lib/interfaces/symbol-metrics.interface.ts index e7cbf7460..c269810d8 100644 --- a/libs/common/src/lib/interfaces/symbol-metrics.interface.ts +++ b/libs/common/src/lib/interfaces/symbol-metrics.interface.ts @@ -7,6 +7,8 @@ export interface SymbolMetrics { currentValuesWithCurrencyEffect: { [date: string]: Big; }; + dividend: Big; + dividendInBaseCurrency: Big; grossPerformance: Big; grossPerformancePercentage: Big; grossPerformancePercentageWithCurrencyEffect: Big; diff --git a/libs/common/src/lib/interfaces/timeline-position.interface.ts b/libs/common/src/lib/interfaces/timeline-position.interface.ts index 220a0aa8f..831c29b31 100644 --- a/libs/common/src/lib/interfaces/timeline-position.interface.ts +++ b/libs/common/src/lib/interfaces/timeline-position.interface.ts @@ -5,6 +5,8 @@ export interface TimelinePosition { averagePrice: Big; currency: string; dataSource: DataSource; + dividend: Big; + dividendInBaseCurrency: Big; fee: Big; firstBuyDate: string; grossPerformance: Big; From 7a3237f1ff2fa20887c351921a7eae3f27131bb9 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 8 Mar 2024 18:59:23 +0100 Subject: [PATCH 010/203] Adapt style of inactive users (#3114) --- .../components/admin-users/admin-users.html | 20 +++++++++++++------ apps/client/src/styles.scss | 4 ++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/apps/client/src/app/components/admin-users/admin-users.html b/apps/client/src/app/components/admin-users/admin-users.html index 6b83a6ab0..b8eaa28ab 100644 --- a/apps/client/src/app/components/admin-users/admin-users.html +++ b/apps/client/src/app/components/admin-users/admin-users.html @@ -35,12 +35,20 @@ mat-cell >
- {{ - element.id - }} - {{ - (element.id | slice: 0 : 5) + '...' - }} + {{ element.id }} + {{ (element.id | slice: 0 : 5) + '...' }} Date: Fri, 8 Mar 2024 19:00:21 +0100 Subject: [PATCH 011/203] Feature/remove environment variable web auth rp (#3115) * Remove environment variable WEB_AUTH_RP_ID * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/auth/web-auth.service.ts | 2 +- .../src/services/configuration/configuration.service.ts | 7 +++---- apps/api/src/services/interfaces/environment.interface.ts | 1 - 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5da3b143b..54764beb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Integrated dividend into the transaction point concept in the portfolio service +- Removed the environment variable `WEB_AUTH_RP_ID` ## 2.61.1 - 2024-03-06 diff --git a/apps/api/src/app/auth/web-auth.service.ts b/apps/api/src/app/auth/web-auth.service.ts index a6e76ffbb..961bbe9a7 100644 --- a/apps/api/src/app/auth/web-auth.service.ts +++ b/apps/api/src/app/auth/web-auth.service.ts @@ -41,7 +41,7 @@ export class WebAuthService { ) {} get rpID() { - return this.configurationService.get('WEB_AUTH_RP_ID'); + return new URL(this.configurationService.get('ROOT_URL')).hostname; } get expectedOrigin() { diff --git a/apps/api/src/services/configuration/configuration.service.ts b/apps/api/src/services/configuration/configuration.service.ts index eb82be418..507e4a375 100644 --- a/apps/api/src/services/configuration/configuration.service.ts +++ b/apps/api/src/services/configuration/configuration.service.ts @@ -3,7 +3,7 @@ import { DEFAULT_ROOT_URL } from '@ghostfolio/common/config'; import { Injectable } from '@nestjs/common'; import { DataSource } from '@prisma/client'; -import { bool, cleanEnv, host, json, num, port, str } from 'envalid'; +import { bool, cleanEnv, host, json, num, port, str, url } from 'envalid'; @Injectable() export class ConfigurationService { @@ -48,14 +48,13 @@ export class ConfigurationService { REDIS_PASSWORD: str({ default: '' }), REDIS_PORT: port({ default: 6379 }), REQUEST_TIMEOUT: num({ default: 2000 }), - ROOT_URL: str({ default: DEFAULT_ROOT_URL }), + ROOT_URL: url({ default: DEFAULT_ROOT_URL }), STRIPE_PUBLIC_KEY: str({ default: '' }), STRIPE_SECRET_KEY: str({ default: '' }), TWITTER_ACCESS_TOKEN: str({ default: 'dummyAccessToken' }), TWITTER_ACCESS_TOKEN_SECRET: str({ default: 'dummyAccessTokenSecret' }), TWITTER_API_KEY: str({ default: 'dummyApiKey' }), - TWITTER_API_SECRET: str({ default: 'dummyApiSecret' }), - WEB_AUTH_RP_ID: host({ default: 'localhost' }) + TWITTER_API_SECRET: str({ default: 'dummyApiSecret' }) }); } diff --git a/apps/api/src/services/interfaces/environment.interface.ts b/apps/api/src/services/interfaces/environment.interface.ts index 09d0b0e5d..5d3145a28 100644 --- a/apps/api/src/services/interfaces/environment.interface.ts +++ b/apps/api/src/services/interfaces/environment.interface.ts @@ -42,5 +42,4 @@ export interface Environment extends CleanedEnvAccessors { TWITTER_ACCESS_TOKEN_SECRET: string; TWITTER_API_KEY: string; TWITTER_API_SECRET: string; - WEB_AUTH_RP_ID: string; } From bc8d8309d49060ca09a61d1657553f5d172d446c Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 9 Mar 2024 11:07:01 +0100 Subject: [PATCH 012/203] Improve handling of future liabilities (#3118) * Improve handling of future liabilities * Refactor currentValue to currentValueInBaseCurrency * Update changelog --- CHANGELOG.md | 4 + .../portfolio/current-rate.service.mock.ts | 2 + .../interfaces/current-positions.interface.ts | 4 +- ...folio-calculator-baln-buy-and-sell.spec.ts | 5 +- .../portfolio-calculator-baln-buy.spec.ts | 5 +- ...ator-btcusd-buy-and-sell-partially.spec.ts | 5 +- .../portfolio-calculator-googl-buy.spec.ts | 5 +- .../portfolio-calculator-no-orders.spec.ts | 2 +- ...ulator-novn-buy-and-sell-partially.spec.ts | 5 +- ...folio-calculator-novn-buy-and-sell.spec.ts | 5 +- .../src/app/portfolio/portfolio-calculator.ts | 87 ++++++++++--------- .../src/app/portfolio/portfolio.service.ts | 25 +++--- .../exchange-rate-data.service.mock.ts | 1 + .../exchange-rate-data.service.ts | 22 ++++- .../interfaces/timeline-position.interface.ts | 1 + 15 files changed, 108 insertions(+), 70 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54764beb0..531e0de91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Integrated dividend into the transaction point concept in the portfolio service - Removed the environment variable `WEB_AUTH_RP_ID` +### Fixed + +- Fixed an issue in the calculation of the portfolio summary caused by future liabilities + ## 2.61.1 - 2024-03-06 ### Fixed diff --git a/apps/api/src/app/portfolio/current-rate.service.mock.ts b/apps/api/src/app/portfolio/current-rate.service.mock.ts index 8f8d06112..ed9229691 100644 --- a/apps/api/src/app/portfolio/current-rate.service.mock.ts +++ b/apps/api/src/app/portfolio/current-rate.service.mock.ts @@ -46,6 +46,8 @@ function mockGetValue(symbol: string, date: Date) { case 'MSFT': if (isSameDay(parseDate('2021-09-16'), date)) { return { marketPrice: 89.12 }; + } else if (isSameDay(parseDate('2021-11-16'), date)) { + return { marketPrice: 339.51 }; } else if (isSameDay(parseDate('2023-07-10'), date)) { return { marketPrice: 331.83 }; } diff --git a/apps/api/src/app/portfolio/interfaces/current-positions.interface.ts b/apps/api/src/app/portfolio/interfaces/current-positions.interface.ts index 5807d6b5e..9ad9ee822 100644 --- a/apps/api/src/app/portfolio/interfaces/current-positions.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/current-positions.interface.ts @@ -3,7 +3,7 @@ import { ResponseError, TimelinePosition } from '@ghostfolio/common/interfaces'; import Big from 'big.js'; export interface CurrentPositions extends ResponseError { - positions: TimelinePosition[]; + currentValueInBaseCurrency: Big; grossPerformance: Big; grossPerformanceWithCurrencyEffect: Big; grossPerformancePercentage: Big; @@ -14,6 +14,6 @@ export interface CurrentPositions extends ResponseError { netPerformanceWithCurrencyEffect: Big; netPerformancePercentage: Big; netPerformancePercentageWithCurrencyEffect: Big; - currentValue: Big; + positions: TimelinePosition[]; totalInvestment: Big; } diff --git a/apps/api/src/app/portfolio/portfolio-calculator-baln-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-baln-buy-and-sell.spec.ts index 9831e5b00..32320dce6 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator-baln-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator-baln-buy-and-sell.spec.ts @@ -87,7 +87,7 @@ describe('PortfolioCalculator', () => { spy.mockRestore(); expect(currentPositions).toEqual({ - currentValue: new Big('0'), + currentValueInBaseCurrency: new Big('0'), errors: [], grossPerformance: new Big('-12.6'), grossPerformancePercentage: new Big('-0.0440867739678096571'), @@ -131,7 +131,8 @@ describe('PortfolioCalculator', () => { symbol: 'BALN.SW', timeWeightedInvestment: new Big('285.8'), timeWeightedInvestmentWithCurrencyEffect: new Big('285.8'), - transactionCount: 2 + transactionCount: 2, + valueInBaseCurrency: new Big('0') } ], totalInvestment: new Big('0'), diff --git a/apps/api/src/app/portfolio/portfolio-calculator-baln-buy.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-baln-buy.spec.ts index bb5986059..f0aae5536 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator-baln-buy.spec.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator-baln-buy.spec.ts @@ -76,7 +76,7 @@ describe('PortfolioCalculator', () => { spy.mockRestore(); expect(currentPositions).toEqual({ - currentValue: new Big('297.8'), + currentValueInBaseCurrency: new Big('297.8'), errors: [], grossPerformance: new Big('24.6'), grossPerformancePercentage: new Big('0.09004392386530014641'), @@ -120,7 +120,8 @@ describe('PortfolioCalculator', () => { symbol: 'BALN.SW', timeWeightedInvestment: new Big('273.2'), timeWeightedInvestmentWithCurrencyEffect: new Big('273.2'), - transactionCount: 1 + transactionCount: 1, + valueInBaseCurrency: new Big('297.8') } ], totalInvestment: new Big('273.2'), diff --git a/apps/api/src/app/portfolio/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts index 6126311c3..d0a8aafc0 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts @@ -100,7 +100,7 @@ describe('PortfolioCalculator', () => { spy.mockRestore(); expect(currentPositions).toEqual({ - currentValue: new Big('13298.425356'), + currentValueInBaseCurrency: new Big('13298.425356'), errors: [], grossPerformance: new Big('27172.74'), grossPerformancePercentage: new Big('42.41978276196153750666'), @@ -151,7 +151,8 @@ describe('PortfolioCalculator', () => { timeWeightedInvestmentWithCurrencyEffect: new Big( '636.79469348020066587024' ), - transactionCount: 2 + transactionCount: 2, + valueInBaseCurrency: new Big('13298.425356') } ], totalInvestment: new Big('320.43'), diff --git a/apps/api/src/app/portfolio/portfolio-calculator-googl-buy.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-googl-buy.spec.ts index d29498292..c3d2eabff 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator-googl-buy.spec.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator-googl-buy.spec.ts @@ -89,7 +89,7 @@ describe('PortfolioCalculator', () => { spy.mockRestore(); expect(currentPositions).toEqual({ - currentValue: new Big('103.10483'), + currentValueInBaseCurrency: new Big('103.10483'), errors: [], grossPerformance: new Big('27.33'), grossPerformancePercentage: new Big('0.3066651705565529623'), @@ -134,7 +134,8 @@ describe('PortfolioCalculator', () => { tags: undefined, timeWeightedInvestment: new Big('89.12'), timeWeightedInvestmentWithCurrencyEffect: new Big('82.329056'), - transactionCount: 1 + transactionCount: 1, + valueInBaseCurrency: new Big('103.10483') } ], totalInvestment: new Big('89.12'), diff --git a/apps/api/src/app/portfolio/portfolio-calculator-no-orders.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-no-orders.spec.ts index ab7234822..f87075c1f 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator-no-orders.spec.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator-no-orders.spec.ts @@ -64,7 +64,7 @@ describe('PortfolioCalculator', () => { spy.mockRestore(); expect(currentPositions).toEqual({ - currentValue: new Big(0), + currentValueInBaseCurrency: new Big(0), grossPerformance: new Big(0), grossPerformancePercentage: new Big(0), grossPerformancePercentageWithCurrencyEffect: new Big(0), diff --git a/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell-partially.spec.ts index afddc5423..8aa5cf0cb 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell-partially.spec.ts @@ -87,7 +87,7 @@ describe('PortfolioCalculator', () => { spy.mockRestore(); expect(currentPositions).toEqual({ - currentValue: new Big('87.8'), + currentValueInBaseCurrency: new Big('87.8'), errors: [], grossPerformance: new Big('21.93'), grossPerformancePercentage: new Big('0.15113417083448194384'), @@ -133,7 +133,8 @@ describe('PortfolioCalculator', () => { timeWeightedInvestmentWithCurrencyEffect: new Big( '145.10285714285714285714' ), - transactionCount: 2 + transactionCount: 2, + valueInBaseCurrency: new Big('87.8') } ], totalInvestment: new Big('75.80'), diff --git a/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell.spec.ts index 4b7750a63..669013858 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator-novn-buy-and-sell.spec.ts @@ -113,7 +113,7 @@ describe('PortfolioCalculator', () => { }); expect(currentPositions).toEqual({ - currentValue: new Big('0'), + currentValueInBaseCurrency: new Big('0'), errors: [], grossPerformance: new Big('19.86'), grossPerformancePercentage: new Big('0.13100263852242744063'), @@ -157,7 +157,8 @@ describe('PortfolioCalculator', () => { symbol: 'NOVN.SW', timeWeightedInvestment: new Big('151.6'), timeWeightedInvestmentWithCurrencyEffect: new Big('151.6'), - transactionCount: 2 + transactionCount: 2, + valueInBaseCurrency: new Big('0') } ], totalInvestment: new Big('0'), diff --git a/apps/api/src/app/portfolio/portfolio-calculator.ts b/apps/api/src/app/portfolio/portfolio-calculator.ts index f0551f3b8..07016efcf 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator.ts @@ -22,6 +22,7 @@ import { format, isBefore, isSameDay, + max, subDays } from 'date-fns'; import { cloneDeep, first, isNumber, last, sortBy, uniq } from 'lodash'; @@ -449,16 +450,27 @@ export class PortfolioCalculator { public async getCurrentPositions( start: Date, - end = new Date(Date.now()) + end?: Date ): Promise { - const transactionPointsBeforeEndDate = - this.transactionPoints?.filter((transactionPoint) => { - return isBefore(parseDate(transactionPoint.date), end); - }) ?? []; + const lastTransactionPoint = last(this.transactionPoints); + + let endDate = end; + + if (!endDate) { + endDate = new Date(Date.now()); - if (!transactionPointsBeforeEndDate.length) { + if (lastTransactionPoint) { + endDate = max([endDate, parseDate(lastTransactionPoint.date)]); + } + } + + const transactionPoints = this.transactionPoints?.filter(({ date }) => { + return isBefore(parseDate(date), endDate); + }); + + if (!transactionPoints.length) { return { - currentValue: new Big(0), + currentValueInBaseCurrency: new Big(0), grossPerformance: new Big(0), grossPerformancePercentage: new Big(0), grossPerformancePercentageWithCurrencyEffect: new Big(0), @@ -473,41 +485,40 @@ export class PortfolioCalculator { }; } - const lastTransactionPoint = - transactionPointsBeforeEndDate[transactionPointsBeforeEndDate.length - 1]; - const currencies: { [symbol: string]: string } = {}; const dataGatheringItems: IDataGatheringItem[] = []; let dates: Date[] = []; - let firstIndex = transactionPointsBeforeEndDate.length; + let firstIndex = transactionPoints.length; let firstTransactionPoint: TransactionPoint = null; dates.push(resetHours(start)); - for (const item of transactionPointsBeforeEndDate[firstIndex - 1].items) { + + for (const { currency, dataSource, symbol } of transactionPoints[ + firstIndex - 1 + ].items) { dataGatheringItems.push({ - dataSource: item.dataSource, - symbol: item.symbol + dataSource, + symbol }); - currencies[item.symbol] = item.currency; + currencies[symbol] = currency; } - for (let i = 0; i < transactionPointsBeforeEndDate.length; i++) { + for (let i = 0; i < transactionPoints.length; i++) { if ( - !isBefore(parseDate(transactionPointsBeforeEndDate[i].date), start) && + !isBefore(parseDate(transactionPoints[i].date), start) && firstTransactionPoint === null ) { - firstTransactionPoint = transactionPointsBeforeEndDate[i]; + firstTransactionPoint = transactionPoints[i]; firstIndex = i; } + if (firstTransactionPoint !== null) { - dates.push( - resetHours(parseDate(transactionPointsBeforeEndDate[i].date)) - ); + dates.push(resetHours(parseDate(transactionPoints[i].date))); } } - dates.push(resetHours(end)); + dates.push(resetHours(endDate)); // Add dates of last week for fallback dates.push(subDays(resetHours(new Date()), 7)); @@ -534,7 +545,7 @@ export class PortfolioCalculator { let exchangeRatesByCurrency = await this.exchangeRateDataService.getExchangeRatesByCurrency({ currencies: uniq(Object.values(currencies)), - endDate: endOfDay(end), + endDate: endOfDay(endDate), startDate: parseDate(this.transactionPoints?.[0]?.date), targetCurrency: this.currency }); @@ -570,7 +581,7 @@ export class PortfolioCalculator { } } - const endDateString = format(end, DATE_FORMAT); + const endDateString = format(endDate, DATE_FORMAT); if (firstIndex > 0) { firstIndex--; @@ -582,9 +593,9 @@ export class PortfolioCalculator { const errors: ResponseError['errors'] = []; for (const item of lastTransactionPoint.items) { - const marketPriceInBaseCurrency = marketSymbolMap[endDateString]?.[ - item.symbol - ]?.mul( + const marketPriceInBaseCurrency = ( + marketSymbolMap[endDateString]?.[item.symbol] ?? item.averagePrice + ).mul( exchangeRatesByCurrency[`${item.currency}${this.currency}`]?.[ endDateString ] @@ -607,9 +618,9 @@ export class PortfolioCalculator { totalInvestment, totalInvestmentWithCurrencyEffect } = this.getSymbolMetrics({ - end, marketSymbolMap, start, + end: endDate, exchangeRates: exchangeRatesByCurrency[`${item.currency}${this.currency}`], symbol: item.symbol @@ -656,7 +667,10 @@ export class PortfolioCalculator { quantity: item.quantity, symbol: item.symbol, tags: item.tags, - transactionCount: item.transactionCount + transactionCount: item.transactionCount, + valueInBaseCurrency: new Big(marketPriceInBaseCurrency).mul( + item.quantity + ) }); if ( @@ -725,7 +739,7 @@ export class PortfolioCalculator { } private calculateOverallPerformance(positions: TimelinePosition[]) { - let currentValue = new Big(0); + let currentValueInBaseCurrency = new Big(0); let grossPerformance = new Big(0); let grossPerformanceWithCurrencyEffect = new Big(0); let hasErrors = false; @@ -737,14 +751,9 @@ export class PortfolioCalculator { let totalTimeWeightedInvestmentWithCurrencyEffect = new Big(0); for (const currentPosition of positions) { - if ( - currentPosition.investment && - currentPosition.marketPriceInBaseCurrency - ) { - currentValue = currentValue.plus( - new Big(currentPosition.marketPriceInBaseCurrency).mul( - currentPosition.quantity - ) + if (currentPosition.valueInBaseCurrency) { + currentValueInBaseCurrency = currentValueInBaseCurrency.plus( + currentPosition.valueInBaseCurrency ); } else { hasErrors = true; @@ -801,7 +810,7 @@ export class PortfolioCalculator { } return { - currentValue, + currentValueInBaseCurrency, grossPerformance, grossPerformanceWithCurrencyEffect, hasErrors, diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index d55b3d647..78a803e9e 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -378,9 +378,10 @@ export class PortfolioService { }); const holdings: PortfolioDetails['holdings'] = {}; - const totalValueInBaseCurrency = currentPositions.currentValue.plus( - cashDetails.balanceInBaseCurrency - ); + const totalValueInBaseCurrency = + currentPositions.currentValueInBaseCurrency.plus( + cashDetails.balanceInBaseCurrency + ); const isFilteredByAccount = filters?.some((filter) => { @@ -389,7 +390,7 @@ export class PortfolioService { let filteredValueInBaseCurrency = isFilteredByAccount ? totalValueInBaseCurrency - : currentPositions.currentValue; + : currentPositions.currentValueInBaseCurrency; if ( filters?.length === 0 || @@ -444,14 +445,14 @@ export class PortfolioService { quantity, symbol, tags, - transactionCount + transactionCount, + valueInBaseCurrency } of currentPositions.positions) { if (quantity.eq(0)) { // Ignore positions without any quantity continue; } - const value = quantity.mul(marketPriceInBaseCurrency ?? 0); const symbolProfile = symbolProfileMap[symbol]; const dataProviderResponse = dataProviderResponses[symbol]; @@ -517,11 +518,11 @@ export class PortfolioService { } } else { markets[UNKNOWN_KEY] = new Big(markets[UNKNOWN_KEY]) - .plus(value) + .plus(valueInBaseCurrency) .toNumber(); marketsAdvanced[UNKNOWN_KEY] = new Big(marketsAdvanced[UNKNOWN_KEY]) - .plus(value) + .plus(valueInBaseCurrency) .toNumber(); } @@ -535,7 +536,7 @@ export class PortfolioService { transactionCount, allocationInPercentage: filteredValueInBaseCurrency.eq(0) ? 0 - : value.div(filteredValueInBaseCurrency).toNumber(), + : valueInBaseCurrency.div(filteredValueInBaseCurrency).toNumber(), assetClass: symbolProfile.assetClass, assetSubClass: symbolProfile.assetSubClass, countries: symbolProfile.countries, @@ -560,7 +561,7 @@ export class PortfolioService { quantity: quantity.toNumber(), sectors: symbolProfile.sectors, url: symbolProfile.url, - valueInBaseCurrency: value.toNumber() + valueInBaseCurrency: valueInBaseCurrency.toNumber() }; } @@ -1175,7 +1176,7 @@ export class PortfolioService { const startDate = this.getStartDate(dateRange, portfolioStart); const { - currentValue, + currentValueInBaseCurrency, errors, grossPerformance, grossPerformancePercentage, @@ -1270,7 +1271,7 @@ export class PortfolioService { currentNetPerformancePercentWithCurrencyEffect.toNumber(), currentNetPerformanceWithCurrencyEffect: currentNetPerformanceWithCurrencyEffect.toNumber(), - currentValue: currentValue.toNumber(), + currentValue: currentValueInBaseCurrency.toNumber(), totalInvestment: totalInvestment.toNumber() } }; diff --git a/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.mock.ts b/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.mock.ts index a25f3a356..59f5144d8 100644 --- a/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.mock.ts +++ b/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.mock.ts @@ -26,6 +26,7 @@ export const ExchangeRateDataServiceMock = { return Promise.resolve({ USDUSD: { '2018-01-01': 1, + '2021-11-16': 1, '2023-07-10': 1 } }); diff --git a/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts b/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts index 148fac560..a02ddb597 100644 --- a/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts +++ b/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts @@ -73,7 +73,17 @@ export class ExchangeRateDataService { currencyTo: targetCurrency }); - let previousExchangeRate = 1; + const dateStrings = Object.keys( + exchangeRatesByCurrency[`${currency}${targetCurrency}`] + ); + const lastDateString = dateStrings.reduce((a, b) => { + return a > b ? a : b; + }); + + let previousExchangeRate = + exchangeRatesByCurrency[`${currency}${targetCurrency}`]?.[ + lastDateString + ] ?? 1; // Start from the most recent date and fill in missing exchange rates // using the latest available rate @@ -94,7 +104,7 @@ export class ExchangeRateDataService { exchangeRatesByCurrency[`${currency}${targetCurrency}`][dateString] = previousExchangeRate; - if (currency === DEFAULT_CURRENCY) { + if (currency === DEFAULT_CURRENCY && isBefore(date, new Date())) { Logger.error( `No exchange rate has been found for ${currency}${targetCurrency} at ${dateString}`, 'ExchangeRateDataService' @@ -433,13 +443,17 @@ export class ExchangeRateDataService { ]) * marketPriceBaseCurrencyToCurrency[format(date, DATE_FORMAT)]; - factors[format(date, DATE_FORMAT)] = factor; + if (isNaN(factor)) { + throw new Error('Exchange rate is not a number'); + } else { + factors[format(date, DATE_FORMAT)] = factor; + } } catch { Logger.error( `No exchange rate has been found for ${currencyFrom}${currencyTo} at ${format( date, DATE_FORMAT - )}`, + )}. Please complement market data for ${DEFAULT_CURRENCY}${currencyFrom} and ${DEFAULT_CURRENCY}${currencyTo}.`, 'ExchangeRateDataService' ); } diff --git a/libs/common/src/lib/interfaces/timeline-position.interface.ts b/libs/common/src/lib/interfaces/timeline-position.interface.ts index 831c29b31..8e5dbb8e8 100644 --- a/libs/common/src/lib/interfaces/timeline-position.interface.ts +++ b/libs/common/src/lib/interfaces/timeline-position.interface.ts @@ -27,4 +27,5 @@ export interface TimelinePosition { timeWeightedInvestment: Big; timeWeightedInvestmentWithCurrencyEffect: Big; transactionCount: number; + valueInBaseCurrency: Big; } From b642ce08e573e3c11724ef39a255ecc4d496d32d Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 9 Mar 2024 12:32:56 +0100 Subject: [PATCH 013/203] Refactor item type (#3119) --- .../portfolio-calculator.interface.ts | 2 +- .../src/app/portfolio/portfolio-calculator.ts | 22 +++++++++---------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/apps/api/src/app/portfolio/interfaces/portfolio-calculator.interface.ts b/apps/api/src/app/portfolio/interfaces/portfolio-calculator.interface.ts index 357b454fd..c5266fb33 100644 --- a/apps/api/src/app/portfolio/interfaces/portfolio-calculator.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/portfolio-calculator.interface.ts @@ -5,7 +5,7 @@ import { PortfolioOrder } from './portfolio-order.interface'; export interface PortfolioOrderItem extends PortfolioOrder { feeInBaseCurrency?: Big; feeInBaseCurrencyWithCurrencyEffect?: Big; - itemType?: '' | 'start' | 'end'; + itemType?: 'end' | 'start'; unitPriceInBaseCurrency?: Big; unitPriceInBaseCurrencyWithCurrencyEffect?: Big; } diff --git a/apps/api/src/app/portfolio/portfolio-calculator.ts b/apps/api/src/app/portfolio/portfolio-calculator.ts index 07016efcf..1521787e7 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator.ts @@ -1049,28 +1049,26 @@ export class PortfolioCalculator { } } - // Sort orders so that the start and end placeholder order are at the right + // Sort orders so that the start and end placeholder order are at the correct // position - orders = sortBy(orders, (order) => { - let sortIndex = new Date(order.date); + orders = sortBy(orders, ({ date, itemType }) => { + let sortIndex = new Date(date); - if (order.itemType === 'start') { - sortIndex = addMilliseconds(sortIndex, -1); - } - - if (order.itemType === 'end') { + if (itemType === 'end') { sortIndex = addMilliseconds(sortIndex, 1); + } else if (itemType === 'start') { + sortIndex = addMilliseconds(sortIndex, -1); } return sortIndex.getTime(); }); - const indexOfStartOrder = orders.findIndex((order) => { - return order.itemType === 'start'; + const indexOfStartOrder = orders.findIndex(({ itemType }) => { + return itemType === 'start'; }); - const indexOfEndOrder = orders.findIndex((order) => { - return order.itemType === 'end'; + const indexOfEndOrder = orders.findIndex(({ itemType }) => { + return itemType === 'end'; }); let totalInvestmentDays = 0; From d9d71e78271a1baf8c39d12f6dfab8118794abf5 Mon Sep 17 00:00:00 2001 From: Gerard Du Pre <37554513+GerardPolloRebozado@users.noreply.github.com> Date: Sat, 9 Mar 2024 15:52:05 +0100 Subject: [PATCH 014/203] Fix issue with removing account from activity (#3112) * Fix issue with removing account from activity * Update changelog --------- Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> --- CHANGELOG.md | 3 +- apps/api/src/app/order/order.service.ts | 40 +++++++------------------ 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 531e0de91..7c1e7a219 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fixed an issue in the calculation of the portfolio summary caused by future liabilities +- Fixed an issue with removing a linked account from a (wealth) item activity ## 2.61.1 - 2024-03-06 @@ -30,7 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- Fixed the the activities import (query parameter handling) +- Fixed the activities import (query parameter handling) ## 2.60.0 - 2024-03-02 diff --git a/apps/api/src/app/order/order.service.ts b/apps/api/src/app/order/order.service.ts index c97243929..1603ed530 100644 --- a/apps/api/src/app/order/order.service.ts +++ b/apps/api/src/app/order/order.service.ts @@ -70,12 +70,7 @@ export class OrderService { const updateAccountBalance = data.updateAccountBalance ?? false; const userId = data.userId; - if ( - data.type === 'FEE' || - data.type === 'INTEREST' || - data.type === 'ITEM' || - data.type === 'LIABILITY' - ) { + if (['FEE', 'INTEREST', 'ITEM', 'LIABILITY'].includes(data.type)) { const assetClass = data.assetClass; const assetSubClass = data.assetSubClass; currency = data.SymbolProfile.connectOrCreate.create.currency; @@ -130,13 +125,9 @@ export class OrderService { const orderData: Prisma.OrderCreateInput = data; - const isDraft = - data.type === 'FEE' || - data.type === 'INTEREST' || - data.type === 'ITEM' || - data.type === 'LIABILITY' - ? false - : isAfter(data.date as Date, endOfToday()); + const isDraft = ['FEE', 'INTEREST', 'ITEM', 'LIABILITY'].includes(data.type) + ? false + : isAfter(data.date as Date, endOfToday()); const order = await this.prismaService.order.create({ data: { @@ -180,12 +171,7 @@ export class OrderService { where }); - if ( - order.type === 'FEE' || - order.type === 'INTEREST' || - order.type === 'ITEM' || - order.type === 'LIABILITY' - ) { + if (['FEE', 'INTEREST', 'ITEM', 'LIABILITY'].includes(order.type)) { await this.symbolProfileService.deleteById(order.symbolProfileId); } @@ -377,13 +363,10 @@ export class OrderService { dataSource?: DataSource; symbol?: string; tags?: Tag[]; + type?: ActivityType; }; where: Prisma.OrderWhereUniqueInput; }): Promise { - if (data.Account.connect.id_userId.id === null) { - delete data.Account; - } - if (!data.comment) { data.comment = null; } @@ -392,13 +375,12 @@ export class OrderService { let isDraft = false; - if ( - data.type === 'FEE' || - data.type === 'INTEREST' || - data.type === 'ITEM' || - data.type === 'LIABILITY' - ) { + if (['FEE', 'INTEREST', 'ITEM', 'LIABILITY'].includes(data.type)) { delete data.SymbolProfile.connect; + + if (data.Account?.connect?.id_userId?.id === null) { + data.Account = { disconnect: true }; + } } else { delete data.SymbolProfile.update; From d8bfb23f208867a0d5483f97046e761465c36c4a Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 9 Mar 2024 16:53:59 +0100 Subject: [PATCH 015/203] Refactor reduce() with getSum() (#3121) --- .../src/app/portfolio/portfolio.service.ts | 85 +++++++++---------- 1 file changed, 38 insertions(+), 47 deletions(-) diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 78a803e9e..5848a78c5 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -1575,29 +1575,26 @@ export class PortfolioService { private getFees({ activities, - date = new Date(0), userCurrency }: { activities: OrderWithAccount[]; - date?: Date; userCurrency: string; }) { - return activities - .filter((activity) => { - // Filter out all activities before given date (drafts) - return isBefore(date, new Date(activity.date)); - }) - .map(({ fee, SymbolProfile }) => { - return this.exchangeRateDataService.toCurrency( - fee, - SymbolProfile.currency, - userCurrency - ); - }) - .reduce( - (previous, current) => new Big(previous).plus(current), - new Big(0) - ); + return getSum( + activities + .filter(({ isDraft }) => { + return isDraft === false; + }) + .map(({ fee, SymbolProfile }) => { + return new Big( + this.exchangeRateDataService.toCurrency( + fee, + SymbolProfile.currency, + userCurrency + ) + ); + }) + ); } private getInitialCashPosition({ @@ -1745,15 +1742,16 @@ export class PortfolioService { } } - const dividendInBaseCurrency = ( - await this.getDividends({ - activities: activities.filter(({ type }) => { - return type === 'DIVIDEND'; + const dividendInBaseCurrency = getSum( + ( + await this.getDividends({ + activities: activities.filter(({ type }) => { + return type === 'DIVIDEND'; + }) }) + ).map(({ investment }) => { + return new Big(investment); }) - ).reduce( - (previous, current) => new Big(previous).plus(current.investment), - new Big(0) ); const emergencyFund = new Big( @@ -1919,34 +1917,27 @@ export class PortfolioService { private getSumOfActivityType({ activities, activityType, - date = new Date(0), userCurrency }: { activities: OrderWithAccount[]; activityType: ActivityType; - date?: Date; userCurrency: string; }) { - return activities - .filter((activity) => { - // Filter out all activities before given date (drafts) and - // activity type - return ( - isBefore(date, new Date(activity.date)) && - activity.type === activityType - ); - }) - .map(({ quantity, SymbolProfile, unitPrice }) => { - return this.exchangeRateDataService.toCurrency( - new Big(quantity).mul(unitPrice).toNumber(), - SymbolProfile.currency, - userCurrency - ); - }) - .reduce( - (previous, current) => new Big(previous).plus(current), - new Big(0) - ); + return getSum( + activities + .filter(({ isDraft, type }) => { + return isDraft === false && type === activityType; + }) + .map(({ quantity, SymbolProfile, unitPrice }) => { + return new Big( + this.exchangeRateDataService.toCurrency( + new Big(quantity).mul(unitPrice).toNumber(), + SymbolProfile.currency, + userCurrency + ) + ); + }) + ); } private async getTransactionPoints({ From 6d2a89736655804be70a22230018abdfc8d8d01e Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 9 Mar 2024 17:17:52 +0100 Subject: [PATCH 016/203] Refactor orders with activities (#3122) --- .../src/app/portfolio/portfolio.service.ts | 37 +++++++------------ 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 5848a78c5..f03e6ec84 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -348,7 +348,7 @@ export class PortfolioService { (user.Settings?.settings as UserSettings)?.emergencyFund ?? 0 ); - const { orders, portfolioOrders, transactionPoints } = + const { activities, portfolioOrders, transactionPoints } = await this.getTransactionPoints({ filters, userId, @@ -582,8 +582,8 @@ export class PortfolioService { } const { accounts, platforms } = await this.getValueOfAccountsAndPlatforms({ + activities, filters, - orders, portfolioItemsNow, userCurrency, userId, @@ -1282,7 +1282,7 @@ export class PortfolioService { const user = await this.userService.user({ id: userId }); const userCurrency = this.getUserCurrency(user); - const { orders, portfolioOrders, transactionPoints } = + const { activities, portfolioOrders, transactionPoints } = await this.getTransactionPoints({ userId, types: ['BUY', 'SELL'] @@ -1314,7 +1314,7 @@ export class PortfolioService { } const { accounts } = await this.getValueOfAccountsAndPlatforms({ - orders, + activities, portfolioItemsNow, userCurrency, userId @@ -1324,7 +1324,7 @@ export class PortfolioService { return { rules: { - accountClusterRisk: isEmpty(orders) + accountClusterRisk: isEmpty(activities) ? undefined : await this.rulesService.evaluate( [ @@ -1339,7 +1339,7 @@ export class PortfolioService { ], userSettings ), - currencyClusterRisk: isEmpty(orders) + currencyClusterRisk: isEmpty(activities) ? undefined : await this.rulesService.evaluate( [ @@ -1368,7 +1368,7 @@ export class PortfolioService { new FeeRatioInitialInvestment( this.exchangeRateDataService, currentPositions.totalInvestment.toNumber(), - this.getFees({ userCurrency, activities: orders }).toNumber() + this.getFees({ activities, userCurrency }).toNumber() ) ], userSettings @@ -1953,8 +1953,8 @@ export class PortfolioService { userId: string; withExcludedAccounts?: boolean; }): Promise<{ + activities: Activity[]; transactionPoints: TransactionPoint[]; - orders: Activity[]; portfolioOrders: PortfolioOrder[]; }> { const userCurrency = @@ -1970,7 +1970,7 @@ export class PortfolioService { }); if (count <= 0) { - return { transactionPoints: [], orders: [], portfolioOrders: [] }; + return { activities: [], transactionPoints: [], portfolioOrders: [] }; } const portfolioOrders: PortfolioOrder[] = activities.map((order) => ({ @@ -1996,8 +1996,8 @@ export class PortfolioService { portfolioCalculator.computeTransactionPoints(); return { + activities, portfolioOrders, - orders: activities, transactionPoints: portfolioCalculator.getTransactionPoints() }; } @@ -2018,29 +2018,20 @@ export class PortfolioService { } private async getValueOfAccountsAndPlatforms({ + activities, filters = [], - orders, portfolioItemsNow, userCurrency, userId, withExcludedAccounts = false }: { + activities: Activity[]; filters?: Filter[]; - orders: Activity[]; portfolioItemsNow: { [p: string]: TimelinePosition }; userCurrency: string; userId: string; withExcludedAccounts?: boolean; }) { - const { activities: ordersOfTypeItemOrLiability } = - await this.orderService.getOrders({ - filters, - userCurrency, - userId, - withExcludedAccounts, - types: ['LIABILITY'] - }); - const accounts: PortfolioDetails['accounts'] = {}; const platforms: PortfolioDetails['platforms'] = {}; @@ -2058,7 +2049,7 @@ export class PortfolioService { }); } else { const accountIds = uniq( - orders + activities .filter(({ accountId }) => { return accountId; }) @@ -2078,7 +2069,7 @@ export class PortfolioService { }); for (const account of currentAccounts) { - const ordersByAccount = orders.filter(({ accountId }) => { + const ordersByAccount = activities.filter(({ accountId }) => { return accountId === account.id; }); From eb75be8535f2b40e6f2a2ab57031840f866bce41 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 9 Mar 2024 19:56:26 +0100 Subject: [PATCH 017/203] Optimize details endpoint (#3123) * Make summary optional * Introduce dedicated holdings endpoint * Update changelog --- CHANGELOG.md | 2 + .../src/app/portfolio/portfolio.controller.ts | 62 +++++++++++------ .../src/app/portfolio/portfolio.service.ts | 69 ++++++++++++------- .../redact-values-in-response.interceptor.ts | 2 - .../account-detail-dialog.component.ts | 8 +-- .../portfolio-summary.component.html | 2 +- .../allocations/allocations-page.component.ts | 1 - .../allocations/allocations-page.html | 9 +-- .../holdings/holdings-page.component.ts | 30 ++------ apps/client/src/app/services/data.service.ts | 41 +++++++++++ libs/common/src/lib/helper.ts | 6 +- libs/common/src/lib/interfaces/index.ts | 2 + .../interfaces/portfolio-details.interface.ts | 5 +- .../interfaces/portfolio-summary.interface.ts | 4 +- .../portfolio-holdings-response.interface.ts | 5 ++ 15 files changed, 159 insertions(+), 89 deletions(-) create mode 100644 libs/common/src/lib/interfaces/responses/portfolio-holdings-response.interface.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c1e7a219..9918a4420 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Optimized the calculation of the accounts table +- Optimized the calculation of the portfolio holdings - Integrated dividend into the transaction point concept in the portfolio service - Removed the environment variable `WEB_AUTH_RP_ID` diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 63e26e512..748850204 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -20,6 +20,7 @@ import { import { PortfolioDetails, PortfolioDividends, + PortfolioHoldingsResponse, PortfolioInvestments, PortfolioPerformanceResponse, PortfolioPublicDetails, @@ -95,21 +96,15 @@ export class PortfolioController { filterByTags }); - const { - accounts, - filteredValueInBaseCurrency, - filteredValueInPercentage, - hasErrors, - holdings, - platforms, - summary, - totalValueInBaseCurrency - } = await this.portfolioService.getDetails({ - dateRange, - filters, - impersonationId, - userId: this.request.user.id - }); + const { accounts, hasErrors, holdings, platforms, summary } = + await this.portfolioService.getDetails({ + dateRange, + filters, + impersonationId, + userId: this.request.user.id, + withLiabilities: true, + withSummary: true + }); if (hasErrors || hasNotDefinedValuesInObject(holdings)) { hasError = true; @@ -164,19 +159,21 @@ export class PortfolioController { 'currentGrossPerformanceWithCurrencyEffect', 'currentNetPerformance', 'currentNetPerformanceWithCurrencyEffect', + 'currentNetWorth', 'currentValue', 'dividendInBaseCurrency', 'emergencyFund', 'excludedAccountsAndActivities', 'fees', + 'filteredValueInBaseCurrency', 'fireWealth', 'interest', 'items', 'liabilities', - 'netWorth', 'totalBuy', 'totalInvestment', - 'totalSell' + 'totalSell', + 'totalValueInBaseCurrency' ]); } @@ -203,12 +200,9 @@ export class PortfolioController { return { accounts, - filteredValueInBaseCurrency, - filteredValueInPercentage, hasError, holdings, platforms, - totalValueInBaseCurrency, summary: portfolioSummary }; } @@ -279,6 +273,33 @@ export class PortfolioController { return { dividends }; } + @Get('holdings') + @UseGuards(AuthGuard('jwt'), HasPermissionGuard) + @UseInterceptors(RedactValuesInResponseInterceptor) + @UseInterceptors(TransformDataSourceInResponseInterceptor) + public async getHoldings( + @Headers(HEADER_KEY_IMPERSONATION.toLowerCase()) impersonationId: string, + @Query('accounts') filterByAccounts?: string, + @Query('assetClasses') filterByAssetClasses?: string, + @Query('query') filterBySearchQuery?: string, + @Query('tags') filterByTags?: string + ): Promise { + const filters = this.apiService.buildFiltersFromQueryParams({ + filterByAccounts, + filterByAssetClasses, + filterBySearchQuery, + filterByTags + }); + + const { holdings } = await this.portfolioService.getDetails({ + filters, + impersonationId, + userId: this.request.user.id + }); + + return { holdings: Object.values(holdings) }; + } + @Get('investments') @UseGuards(AuthGuard('jwt'), HasPermissionGuard) public async getInvestments( @@ -502,7 +523,6 @@ export class PortfolioController { } const { holdings } = await this.portfolioService.getDetails({ - dateRange: 'max', filters: [{ id: 'EQUITY', type: 'ASSET_CLASS' }], impersonationId: access.userId, userId: user.id diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index f03e6ec84..9880abcc4 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -24,7 +24,12 @@ import { MAX_CHART_ITEMS, UNKNOWN_KEY } from '@ghostfolio/common/config'; -import { DATE_FORMAT, getSum, parseDate } from '@ghostfolio/common/helper'; +import { + DATE_FORMAT, + getAllActivityTypes, + getSum, + parseDate +} from '@ghostfolio/common/helper'; import { Accounts, EnhancedSymbolProfile, @@ -141,7 +146,8 @@ export class PortfolioService { filters, withExcludedAccounts, impersonationId: userId, - userId: this.request.user.id + userId: this.request.user.id, + withLiabilities: true }) ]); @@ -332,13 +338,17 @@ export class PortfolioService { filters, impersonationId, userId, - withExcludedAccounts = false + withExcludedAccounts = false, + withLiabilities = false, + withSummary = false }: { dateRange?: DateRange; filters?: Filter[]; impersonationId: string; userId: string; withExcludedAccounts?: boolean; + withLiabilities?: boolean; + withSummary?: boolean; }): Promise { userId = await this.getUserId(impersonationId, userId); const user = await this.userService.user({ id: userId }); @@ -352,7 +362,12 @@ export class PortfolioService { await this.getTransactionPoints({ filters, userId, - withExcludedAccounts + withExcludedAccounts, + types: withLiabilities + ? undefined + : getAllActivityTypes().filter((activityType) => { + return activityType !== 'LIABILITY'; + }) }); const portfolioCalculator = new PortfolioCalculator({ @@ -625,29 +640,29 @@ export class PortfolioService { }; } - const summary = await this.getSummary({ - holdings, - impersonationId, - userCurrency, - userId, - balanceInBaseCurrency: cashDetails.balanceInBaseCurrency, - emergencyFundPositionsValueInBaseCurrency: - this.getEmergencyFundPositionsValueInBaseCurrency({ - holdings - }) - }); + let summary: PortfolioSummary; + + if (withSummary) { + summary = await this.getSummary({ + filteredValueInBaseCurrency, + holdings, + impersonationId, + userCurrency, + userId, + balanceInBaseCurrency: cashDetails.balanceInBaseCurrency, + emergencyFundPositionsValueInBaseCurrency: + this.getEmergencyFundPositionsValueInBaseCurrency({ + holdings + }) + }); + } return { accounts, holdings, platforms, summary, - filteredValueInBaseCurrency: filteredValueInBaseCurrency.toNumber(), - filteredValueInPercentage: summary.netWorth - ? filteredValueInBaseCurrency.div(summary.netWorth).toNumber() - : 0, - hasErrors: currentPositions.hasErrors, - totalValueInBaseCurrency: summary.netWorth + hasErrors: currentPositions.hasErrors }; } @@ -1705,6 +1720,7 @@ export class PortfolioService { private async getSummary({ balanceInBaseCurrency, emergencyFundPositionsValueInBaseCurrency, + filteredValueInBaseCurrency, holdings, impersonationId, userCurrency, @@ -1712,6 +1728,7 @@ export class PortfolioService { }: { balanceInBaseCurrency: number; emergencyFundPositionsValueInBaseCurrency: number; + filteredValueInBaseCurrency: Big; holdings: PortfolioDetails['holdings']; impersonationId: string; userCurrency: string; @@ -1893,7 +1910,6 @@ export class PortfolioService { interest, items, liabilities, - netWorth, totalBuy, totalSell, committedFunds: committedFunds.toNumber(), @@ -1905,12 +1921,17 @@ export class PortfolioService { .toNumber(), total: emergencyFund.toNumber() }, + filteredValueInBaseCurrency: filteredValueInBaseCurrency.toNumber(), + filteredValueInPercentage: netWorth + ? filteredValueInBaseCurrency.div(netWorth).toNumber() + : undefined, fireWealth: new Big(performanceInformation.performance.currentValue) .minus(emergencyFundPositionsValueInBaseCurrency) .toNumber(), ordersCount: activities.filter(({ type }) => { return type === 'BUY' || type === 'SELL'; - }).length + }).length, + totalValueInBaseCurrency: netWorth }; } @@ -1943,7 +1964,7 @@ export class PortfolioService { private async getTransactionPoints({ filters, includeDrafts = false, - types = ['BUY', 'DIVIDEND', 'ITEM', 'LIABILITY', 'SELL'], + types = getAllActivityTypes(), userId, withExcludedAccounts = false }: { diff --git a/apps/api/src/interceptors/redact-values-in-response.interceptor.ts b/apps/api/src/interceptors/redact-values-in-response.interceptor.ts index b1889cf9d..78ae918d2 100644 --- a/apps/api/src/interceptors/redact-values-in-response.interceptor.ts +++ b/apps/api/src/interceptors/redact-values-in-response.interceptor.ts @@ -49,7 +49,6 @@ export class RedactValuesInResponseInterceptor 'dividendInBaseCurrency', 'fee', 'feeInBaseCurrency', - 'filteredValueInBaseCurrency', 'grossPerformance', 'grossPerformanceWithCurrencyEffect', 'investment', @@ -58,7 +57,6 @@ export class RedactValuesInResponseInterceptor 'quantity', 'symbolMapping', 'totalBalanceInBaseCurrency', - 'totalValueInBaseCurrency', 'unitPrice', 'value', 'valueInBaseCurrency' diff --git a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts index 2cd48a561..760f8081b 100644 --- a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts +++ b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts @@ -115,7 +115,7 @@ export class AccountDetailDialog implements OnDestroy, OnInit { ); this.dataService - .fetchPortfolioDetails({ + .fetchPortfolioHoldings({ filters: [ { type: 'ACCOUNT', @@ -125,11 +125,7 @@ export class AccountDetailDialog implements OnDestroy, OnInit { }) .pipe(takeUntil(this.unsubscribeSubject)) .subscribe(({ holdings }) => { - this.holdings = []; - - for (const [symbol, holding] of Object.entries(holdings)) { - this.holdings.push(holding); - } + this.holdings = holdings; this.changeDetectorRef.markForCheck(); }); diff --git a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html index 096271926..347767011 100644 --- a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html +++ b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html @@ -282,7 +282,7 @@ [isCurrency]="true" [locale]="locale" [unit]="baseCurrency" - [value]="isLoading ? undefined : summary?.netWorth" + [value]="isLoading ? undefined : summary?.totalValueInBaseCurrency" />
diff --git a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts index 330ae4227..67ad82316 100644 --- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts +++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts @@ -281,7 +281,6 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { this.platforms = {}; this.portfolioDetails = { accounts: {}, - filteredValueInPercentage: 0, holdings: {}, platforms: {}, summary: undefined diff --git a/apps/client/src/app/pages/portfolio/allocations/allocations-page.html b/apps/client/src/app/pages/portfolio/allocations/allocations-page.html index 312061775..04bf96f39 100644 --- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.html +++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.html @@ -18,7 +18,7 @@ [value]=" isLoading ? undefined - : portfolioDetails?.filteredValueInPercentage + : portfolioDetails?.summary?.filteredValueInPercentage " /> @@ -26,10 +26,11 @@ diff --git a/apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts b/apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts index 6c4a058b7..6635393f5 100644 --- a/apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts +++ b/apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts @@ -3,11 +3,7 @@ import { PositionDetailDialog } from '@ghostfolio/client/components/position/pos import { DataService } from '@ghostfolio/client/services/data.service'; import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; -import { - PortfolioDetails, - PortfolioPosition, - User -} from '@ghostfolio/common/interfaces'; +import { PortfolioPosition, User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; @@ -28,8 +24,6 @@ export class HoldingsPageComponent implements OnDestroy, OnInit { public hasImpersonationId: boolean; public hasPermissionToCreateOrder: boolean; public holdings: PortfolioPosition[]; - public isLoading = false; - public portfolioDetails: PortfolioDetails; public user: User; private unsubscribeSubject = new Subject(); @@ -83,12 +77,10 @@ export class HoldingsPageComponent implements OnDestroy, OnInit { this.holdings = undefined; - this.fetchPortfolioDetails() + this.fetchHoldings() .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((portfolioDetails) => { - this.portfolioDetails = portfolioDetails; - - this.initialize(); + .subscribe(({ holdings }) => { + this.holdings = holdings; this.changeDetectorRef.markForCheck(); }); @@ -103,22 +95,12 @@ export class HoldingsPageComponent implements OnDestroy, OnInit { this.unsubscribeSubject.complete(); } - private fetchPortfolioDetails() { - return this.dataService.fetchPortfolioDetails({ + private fetchHoldings() { + return this.dataService.fetchPortfolioHoldings({ filters: this.userService.getFilters() }); } - private initialize() { - this.holdings = []; - - for (const [symbol, holding] of Object.entries( - this.portfolioDetails.holdings - )) { - this.holdings.push(holding); - } - } - private openPositionDialog({ dataSource, symbol diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts index 6555a964d..7741fd601 100644 --- a/apps/client/src/app/services/data.service.ts +++ b/apps/client/src/app/services/data.service.ts @@ -27,6 +27,7 @@ import { OAuthResponse, PortfolioDetails, PortfolioDividends, + PortfolioHoldingsResponse, PortfolioInvestments, PortfolioPerformanceResponse, PortfolioPublicDetails, @@ -434,6 +435,46 @@ export class DataService { ); } + public fetchPortfolioHoldings({ + filters + }: { + filters?: Filter[]; + } = {}) { + return this.http + .get('/api/v1/portfolio/holdings', { + params: this.buildFiltersAsQueryParams({ filters }) + }) + .pipe( + map((response) => { + if (response.holdings) { + for (const symbol of Object.keys(response.holdings)) { + response.holdings[symbol].assetClassLabel = translate( + response.holdings[symbol].assetClass + ); + + response.holdings[symbol].assetSubClassLabel = translate( + response.holdings[symbol].assetSubClass + ); + + response.holdings[symbol].dateOfFirstActivity = response.holdings[ + symbol + ].dateOfFirstActivity + ? parseISO(response.holdings[symbol].dateOfFirstActivity) + : undefined; + + response.holdings[symbol].value = isNumber( + response.holdings[symbol].value + ) + ? response.holdings[symbol].value + : response.holdings[symbol].valueInPercentage; + } + } + + return response; + }) + ); + } + public fetchPortfolioPerformance({ filters, range, diff --git a/libs/common/src/lib/helper.ts b/libs/common/src/lib/helper.ts index e55800628..c52ec9ca5 100644 --- a/libs/common/src/lib/helper.ts +++ b/libs/common/src/lib/helper.ts @@ -1,6 +1,6 @@ import * as currencies from '@dinero.js/currencies'; import { NumberParser } from '@internationalized/number'; -import { DataSource, MarketData } from '@prisma/client'; +import { DataSource, MarketData, Type as ActivityType } from '@prisma/client'; import Big from 'big.js'; import { getDate, @@ -138,6 +138,10 @@ export function extractNumberFromString({ } } +export function getAllActivityTypes(): ActivityType[] { + return ['BUY', 'DIVIDEND', 'FEE', 'ITEM', 'LIABILITY', 'SELL']; +} + export function getAssetProfileIdentifier({ dataSource, symbol }: UniqueAsset) { return `${dataSource}-${symbol}`; } diff --git a/libs/common/src/lib/interfaces/index.ts b/libs/common/src/lib/interfaces/index.ts index 7d77826d0..dba1ac79a 100644 --- a/libs/common/src/lib/interfaces/index.ts +++ b/libs/common/src/lib/interfaces/index.ts @@ -40,6 +40,7 @@ import type { BenchmarkResponse } from './responses/benchmark-response.interface import type { ResponseError } from './responses/errors.interface'; import type { ImportResponse } from './responses/import-response.interface'; import type { OAuthResponse } from './responses/oauth-response.interface'; +import type { PortfolioHoldingsResponse } from './responses/portfolio-holdings-response.interface'; import type { PortfolioPerformanceResponse } from './responses/portfolio-performance-response.interface'; import type { ScraperConfiguration } from './scraper-configuration.interface'; import type { Statistics } from './statistics.interface'; @@ -81,6 +82,7 @@ export { PortfolioChart, PortfolioDetails, PortfolioDividends, + PortfolioHoldingsResponse, PortfolioInvestments, PortfolioItem, PortfolioOverview, diff --git a/libs/common/src/lib/interfaces/portfolio-details.interface.ts b/libs/common/src/lib/interfaces/portfolio-details.interface.ts index 565c17c7d..611ed8056 100644 --- a/libs/common/src/lib/interfaces/portfolio-details.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-details.interface.ts @@ -13,8 +13,6 @@ export interface PortfolioDetails { valueInPercentage?: number; }; }; - filteredValueInBaseCurrency?: number; - filteredValueInPercentage: number; holdings: { [symbol: string]: PortfolioPosition }; platforms: { [id: string]: { @@ -25,6 +23,5 @@ export interface PortfolioDetails { valueInPercentage?: number; }; }; - summary: PortfolioSummary; - totalValueInBaseCurrency?: number; + summary?: PortfolioSummary; } diff --git a/libs/common/src/lib/interfaces/portfolio-summary.interface.ts b/libs/common/src/lib/interfaces/portfolio-summary.interface.ts index aaf80c0cd..de04dc24c 100644 --- a/libs/common/src/lib/interfaces/portfolio-summary.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-summary.interface.ts @@ -13,13 +13,15 @@ export interface PortfolioSummary extends PortfolioPerformance { }; excludedAccountsAndActivities: number; fees: number; + filteredValueInBaseCurrency?: number; + filteredValueInPercentage?: number; fireWealth: number; firstOrderDate: Date; interest: number; items: number; liabilities: number; - netWorth: number; ordersCount: number; totalBuy: number; totalSell: number; + totalValueInBaseCurrency?: number; } diff --git a/libs/common/src/lib/interfaces/responses/portfolio-holdings-response.interface.ts b/libs/common/src/lib/interfaces/responses/portfolio-holdings-response.interface.ts new file mode 100644 index 000000000..d2cf38f55 --- /dev/null +++ b/libs/common/src/lib/interfaces/responses/portfolio-holdings-response.interface.ts @@ -0,0 +1,5 @@ +import { PortfolioPosition } from '@ghostfolio/common/interfaces'; + +export interface PortfolioHoldingsResponse { + holdings: PortfolioPosition[]; +} From ba73f6de2e3019c1803d9e5fa45fca66d80bb618 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 9 Mar 2024 19:57:56 +0100 Subject: [PATCH 018/203] Release 2.62.0 (#3124) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9918a4420..e4f689445 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.62.0 - 2024-03-09 ### Changed diff --git a/package.json b/package.json index 8faa5ff8a..ddd5de1cf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.61.1", + "version": "2.62.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 0bca8897d69e8b88966195955f08a00d4e6c8c32 Mon Sep 17 00:00:00 2001 From: gizmodus Date: Sun, 10 Mar 2024 09:35:47 +0100 Subject: [PATCH 019/203] Fix average price calculation by only considering BUY transactions (#3125) * Fix average price calculation by only considering buy transactions * Update changelog --- CHANGELOG.md | 6 + ...aln-buy-and-sell-in-two-activities.spec.ts | 166 ++++++++++++++++++ .../src/app/portfolio/portfolio-calculator.ts | 60 +++---- 3 files changed, 199 insertions(+), 33 deletions(-) create mode 100644 apps/api/src/app/portfolio/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index e4f689445..33baa68c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Fixed + +- Fixed an issue in the performance calculation caused by multiple `SELL` activities on the same day + ## 2.62.0 - 2024-03-09 ### Changed diff --git a/apps/api/src/app/portfolio/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts new file mode 100644 index 000000000..703931846 --- /dev/null +++ b/apps/api/src/app/portfolio/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts @@ -0,0 +1,166 @@ +import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; +import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; +import { parseDate } from '@ghostfolio/common/helper'; + +import Big from 'big.js'; + +import { CurrentRateServiceMock } from './current-rate.service.mock'; +import { PortfolioCalculator } from './portfolio-calculator'; + +jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + CurrentRateService: jest.fn().mockImplementation(() => { + return CurrentRateServiceMock; + }) + }; +}); + +describe('PortfolioCalculator', () => { + let currentRateService: CurrentRateService; + let exchangeRateDataService: ExchangeRateDataService; + + beforeEach(() => { + currentRateService = new CurrentRateService(null, null, null, null); + + exchangeRateDataService = new ExchangeRateDataService( + null, + null, + null, + null + ); + }); + + describe('get current positions', () => { + it.only('with BALN.SW buy and sell in two activities', async () => { + const portfolioCalculator = new PortfolioCalculator({ + currentRateService, + exchangeRateDataService, + currency: 'CHF', + orders: [ + { + currency: 'CHF', + date: '2021-11-22', + dataSource: 'YAHOO', + fee: new Big(1.55), + name: 'Bâloise Holding AG', + quantity: new Big(2), + symbol: 'BALN.SW', + type: 'BUY', + unitPrice: new Big(142.9) + }, + { + currency: 'CHF', + date: '2021-11-30', + dataSource: 'YAHOO', + fee: new Big(1.65), + name: 'Bâloise Holding AG', + quantity: new Big(1), + symbol: 'BALN.SW', + type: 'SELL', + unitPrice: new Big(136.6) + }, + { + currency: 'CHF', + date: '2021-11-30', + dataSource: 'YAHOO', + fee: new Big(0), + name: 'Bâloise Holding AG', + quantity: new Big(1), + symbol: 'BALN.SW', + type: 'SELL', + unitPrice: new Big(136.6) + } + ] + }); + + portfolioCalculator.computeTransactionPoints(); + + const spy = jest + .spyOn(Date, 'now') + .mockImplementation(() => parseDate('2021-12-18').getTime()); + + const chartData = await portfolioCalculator.getChartData({ + start: parseDate('2021-11-22') + }); + + const currentPositions = await portfolioCalculator.getCurrentPositions( + parseDate('2021-11-22') + ); + + const investments = portfolioCalculator.getInvestments(); + + const investmentsByMonth = portfolioCalculator.getInvestmentsByGroup({ + data: chartData, + groupBy: 'month' + }); + + spy.mockRestore(); + + expect(currentPositions).toEqual({ + currentValueInBaseCurrency: new Big('0'), + errors: [], + grossPerformance: new Big('-12.6'), + grossPerformancePercentage: new Big('-0.04408677396780965649'), + grossPerformancePercentageWithCurrencyEffect: new Big( + '-0.04408677396780965649' + ), + grossPerformanceWithCurrencyEffect: new Big('-12.6'), + hasErrors: false, + netPerformance: new Big('-15.8'), + netPerformancePercentage: new Big('-0.05528341497550734703'), + netPerformancePercentageWithCurrencyEffect: new Big( + '-0.05528341497550734703' + ), + netPerformanceWithCurrencyEffect: new Big('-15.8'), + positions: [ + { + averagePrice: new Big('0'), + currency: 'CHF', + dataSource: 'YAHOO', + dividend: new Big('0'), + dividendInBaseCurrency: new Big('0'), + fee: new Big('3.2'), + firstBuyDate: '2021-11-22', + grossPerformance: new Big('-12.6'), + grossPerformancePercentage: new Big('-0.04408677396780965649'), + grossPerformancePercentageWithCurrencyEffect: new Big( + '-0.04408677396780965649' + ), + grossPerformanceWithCurrencyEffect: new Big('-12.6'), + investment: new Big('0'), + investmentWithCurrencyEffect: new Big('0'), + netPerformance: new Big('-15.8'), + netPerformancePercentage: new Big('-0.05528341497550734703'), + netPerformancePercentageWithCurrencyEffect: new Big( + '-0.05528341497550734703' + ), + netPerformanceWithCurrencyEffect: new Big('-15.8'), + marketPrice: 148.9, + marketPriceInBaseCurrency: 148.9, + quantity: new Big('0'), + symbol: 'BALN.SW', + timeWeightedInvestment: new Big('285.80000000000000396627'), + timeWeightedInvestmentWithCurrencyEffect: new Big( + '285.80000000000000396627' + ), + transactionCount: 3, + valueInBaseCurrency: new Big('0') + } + ], + totalInvestment: new Big('0'), + totalInvestmentWithCurrencyEffect: new Big('0') + }); + + expect(investments).toEqual([ + { date: '2021-11-22', investment: new Big('285.8') }, + { date: '2021-11-30', investment: new Big('0') } + ]); + + expect(investmentsByMonth).toEqual([ + { date: '2021-11-01', investment: 0 }, + { date: '2021-12-01', investment: 0 } + ]); + }); + }); +}); diff --git a/apps/api/src/app/portfolio/portfolio-calculator.ts b/apps/api/src/app/portfolio/portfolio-calculator.ts index 1521787e7..faf954bbd 100644 --- a/apps/api/src/app/portfolio/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/portfolio-calculator.ts @@ -893,13 +893,10 @@ export class PortfolioCalculator { } = {}; let totalInvestment = new Big(0); + let totalInvestmentFromBuyTransactions = new Big(0); + let totalInvestmentFromBuyTransactionsWithCurrencyEffect = new Big(0); let totalInvestmentWithCurrencyEffect = new Big(0); - let totalInvestmentWithGrossPerformanceFromSell = new Big(0); - - let totalInvestmentWithGrossPerformanceFromSellWithCurrencyEffect = new Big( - 0 - ); - + let totalQuantityFromBuyTransactions = new Big(0); let totalUnits = new Big(0); let valueAtStartDate: Big; let valueAtStartDateWithCurrencyEffect: Big; @@ -1138,9 +1135,21 @@ export class PortfolioCalculator { transactionInvestment = order.quantity .mul(order.unitPriceInBaseCurrency) .mul(getFactor(order.type)); + transactionInvestmentWithCurrencyEffect = order.quantity .mul(order.unitPriceInBaseCurrencyWithCurrencyEffect) .mul(getFactor(order.type)); + + totalQuantityFromBuyTransactions = + totalQuantityFromBuyTransactions.plus(order.quantity); + + totalInvestmentFromBuyTransactions = + totalInvestmentFromBuyTransactions.plus(transactionInvestment); + + totalInvestmentFromBuyTransactionsWithCurrencyEffect = + totalInvestmentFromBuyTransactionsWithCurrencyEffect.plus( + transactionInvestmentWithCurrencyEffect + ); } else if (order.type === 'SELL') { if (totalUnits.gt(0)) { transactionInvestment = totalInvestment @@ -1245,35 +1254,21 @@ export class PortfolioCalculator { grossPerformanceFromSellWithCurrencyEffect ); - totalInvestmentWithGrossPerformanceFromSell = - totalInvestmentWithGrossPerformanceFromSell - .plus(transactionInvestment) - .plus(grossPerformanceFromSell); - - totalInvestmentWithGrossPerformanceFromSellWithCurrencyEffect = - totalInvestmentWithGrossPerformanceFromSellWithCurrencyEffect - .plus(transactionInvestmentWithCurrencyEffect) - .plus(grossPerformanceFromSellWithCurrencyEffect); - - lastAveragePrice = totalUnits.eq(0) + lastAveragePrice = totalQuantityFromBuyTransactions.eq(0) ? new Big(0) - : totalInvestmentWithGrossPerformanceFromSell.div(totalUnits); + : totalInvestmentFromBuyTransactions.div( + totalQuantityFromBuyTransactions + ); - lastAveragePriceWithCurrencyEffect = totalUnits.eq(0) + lastAveragePriceWithCurrencyEffect = totalQuantityFromBuyTransactions.eq( + 0 + ) ? new Big(0) - : totalInvestmentWithGrossPerformanceFromSellWithCurrencyEffect.div( - totalUnits + : totalInvestmentFromBuyTransactionsWithCurrencyEffect.div( + totalQuantityFromBuyTransactions ); if (PortfolioCalculator.ENABLE_LOGGING) { - console.log( - 'totalInvestmentWithGrossPerformanceFromSell', - totalInvestmentWithGrossPerformanceFromSell.toNumber() - ); - console.log( - 'totalInvestmentWithGrossPerformanceFromSellWithCurrencyEffect', - totalInvestmentWithGrossPerformanceFromSellWithCurrencyEffect.toNumber() - ); console.log( 'grossPerformanceFromSells', grossPerformanceFromSells.toNumber() @@ -1319,11 +1314,10 @@ export class PortfolioCalculator { orderDate, previousOrderDate ); - - // Set to at least 1 day, otherwise the transactions on the same day - // would not be considered in the time weighted calculation if (daysSinceLastOrder <= 0) { - daysSinceLastOrder = 1; + // The time between two activities on the same day is unknown + // -> Set it to the smallest floating point number greater than 0 + daysSinceLastOrder = Number.EPSILON; } // Sum up the total investment days since the start date to calculate From bb86f852033ff6b8f85ab8af48706c48d4279176 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 10 Mar 2024 09:50:43 +0100 Subject: [PATCH 020/203] Feature/add available home server systems to faq (#3126) * Add available home server systems * Update changelog * Add CasaOS to README.md --- CHANGELOG.md | 4 ++++ README.md | 2 +- .../faq/self-hosting/self-hosting-page.html | 19 +++++++++++++++++++ .../resources/resources-page.component.ts | 1 + .../app/pages/resources/resources-page.html | 17 +++++++++++++++++ 5 files changed, 42 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 33baa68c4..44b641f7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Extended the content of the _Self-Hosting_ section by available home server systems on the Frequently Asked Questions (FAQ) page + ### Fixed - Fixed an issue in the performance calculation caused by multiple `SELL` activities on the same day diff --git a/README.md b/README.md index c82ad50c3..eb302936e 100644 --- a/README.md +++ b/README.md @@ -144,7 +144,7 @@ docker compose --env-file ./.env -f docker/docker-compose.build.yml up -d ### Home Server Systems (Community) -Ghostfolio is available for various home server systems, including [Runtipi](https://www.runtipi.io/docs/apps-available), [TrueCharts](https://truecharts.org/charts/stable/ghostfolio), [Umbrel](https://apps.umbrel.com/app/ghostfolio), and [Unraid](https://unraid.net/community/apps?q=ghostfolio). +Ghostfolio is available for various home server systems, including [CasaOS](https://github.com/bigbeartechworld/big-bear-casaos), [Runtipi](https://www.runtipi.io/docs/apps-available), [TrueCharts](https://truecharts.org/charts/stable/ghostfolio), [Umbrel](https://apps.umbrel.com/app/ghostfolio), and [Unraid](https://unraid.net/community/apps?q=ghostfolio). ## Development diff --git a/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html b/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html index 5dcaa0cf7..1f95abef3 100644 --- a/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html +++ b/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html @@ -18,6 +18,25 @@ GitHub. + + + Which home server systems is Ghostfolio available + on? + + + The community has made Ghostfolio available on various home server + systems, including + CasaOS, Runtipi, + TrueCharts, Umbrel, and + Unraid. + + How do I add a new currency? diff --git a/apps/client/src/app/pages/resources/resources-page.component.ts b/apps/client/src/app/pages/resources/resources-page.component.ts index 5c9e690b9..23c5bf5eb 100644 --- a/apps/client/src/app/pages/resources/resources-page.component.ts +++ b/apps/client/src/app/pages/resources/resources-page.component.ts @@ -14,6 +14,7 @@ import { Subject } from 'rxjs'; export class ResourcesPageComponent implements OnInit { public hasPermissionForSubscription: boolean; public info: InfoItem; + public routerLinkFaq = ['/' + $localize`faq`]; public routerLinkResourcesPersonalFinanceTools = [ '/' + $localize`resources`, 'personal-finance-tools' diff --git a/apps/client/src/app/pages/resources/resources-page.html b/apps/client/src/app/pages/resources/resources-page.html index da57cc908..800c674cf 100644 --- a/apps/client/src/app/pages/resources/resources-page.html +++ b/apps/client/src/app/pages/resources/resources-page.html @@ -2,6 +2,23 @@

Resources

+

Ghostfolio

+
+
+
+

Frequently Asked Questions (FAQ)

+
+ Find quick answers to commonly asked questions about Ghostfolio in + our Frequently Asked Questions (FAQ) section. +
+ +
+
+

Guides

From d32dd5e8605ad4a8bdb1833d9348a7b464460921 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 11 Mar 2024 19:16:20 +0100 Subject: [PATCH 021/203] Feature/upgrade countries list to version 3.1.0 (#3131) * Upgrade countries-list to version 3.1.0 * Update changelog --- CHANGELOG.md | 4 ++++ .../data-enhancer/trackinsight/trackinsight.service.ts | 9 ++++----- .../services/symbol-profile/symbol-profile.service.ts | 5 ++--- package.json | 2 +- yarn.lock | 8 ++++---- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44b641f7f..f7ca1dc34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Extended the content of the _Self-Hosting_ section by available home server systems on the Frequently Asked Questions (FAQ) page +### Changed + +- Upgraded `countries-list` from version `2.6.1` to `3.1.0` + ### Fixed - Fixed an issue in the performance calculation caused by multiple `SELL` activities on the same day diff --git a/apps/api/src/services/data-provider/data-enhancer/trackinsight/trackinsight.service.ts b/apps/api/src/services/data-provider/data-enhancer/trackinsight/trackinsight.service.ts index 63d785253..ddc3d79f8 100644 --- a/apps/api/src/services/data-provider/data-enhancer/trackinsight/trackinsight.service.ts +++ b/apps/api/src/services/data-provider/data-enhancer/trackinsight/trackinsight.service.ts @@ -5,12 +5,12 @@ import { Sector } from '@ghostfolio/common/interfaces/sector.interface'; import { Injectable } from '@nestjs/common'; import { SymbolProfile } from '@prisma/client'; +import { countries } from 'countries-list'; import got from 'got'; @Injectable() export class TrackinsightDataEnhancerService implements DataEnhancerInterface { private static baseUrl = 'https://www.trackinsight.com/data-api'; - private static countries = require('countries-list/dist/countries.json'); private static countriesMapping = { 'Russian Federation': 'Russia' }; @@ -131,20 +131,19 @@ export class TrackinsightDataEnhancerService implements DataEnhancerInterface { (response.countries as unknown as Country[]).length === 0 ) { response.countries = []; + for (const [name, value] of Object.entries( holdings?.countries ?? {} )) { let countryCode: string; - for (const [key, country] of Object.entries( - TrackinsightDataEnhancerService.countries - )) { + for (const [code, country] of Object.entries(countries)) { if ( country.name === name || country.name === TrackinsightDataEnhancerService.countriesMapping[name] ) { - countryCode = key; + countryCode = code; break; } } diff --git a/apps/api/src/services/symbol-profile/symbol-profile.service.ts b/apps/api/src/services/symbol-profile/symbol-profile.service.ts index a87b00d95..751feda22 100644 --- a/apps/api/src/services/symbol-profile/symbol-profile.service.ts +++ b/apps/api/src/services/symbol-profile/symbol-profile.service.ts @@ -189,9 +189,8 @@ export class SymbolProfileService { return { code, weight, - continent: - continents[countries[code as string]?.continent] ?? UNKNOWN_KEY, - name: countries[code as string]?.name ?? UNKNOWN_KEY + continent: continents[countries[code]?.continent] ?? UNKNOWN_KEY, + name: countries[code]?.name ?? UNKNOWN_KEY }; }); } diff --git a/package.json b/package.json index ddd5de1cf..5b92172e4 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "class-validator": "0.14.0", "color": "4.2.3", "countries-and-timezones": "3.4.1", - "countries-list": "2.6.1", + "countries-list": "3.1.0", "countup.js": "2.3.2", "date-fns": "2.29.3", "envalid": "7.3.1", diff --git a/yarn.lock b/yarn.lock index f71e7ad80..ba7e811ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9739,10 +9739,10 @@ countries-and-timezones@3.4.1: resolved "https://registry.yarnpkg.com/countries-and-timezones/-/countries-and-timezones-3.4.1.tgz#0ec2540f57e42f0f740eb2acaede786043347fe1" integrity sha512-INeHGCony4XUUR8iGL/lmt9s1Oi+n+gFHeJAMfbV5hJfYeDOB8JG1oxz5xFQu5oBZoRCJe/87k1Vzue9DoIauA== -countries-list@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/countries-list/-/countries-list-2.6.1.tgz#d479757ac873b1e596ccea0a925962d20396c0cb" - integrity sha512-jXM1Nv3U56dPQ1DsUSsEaGmLHburo4fnB7m+1yhWDUVvx5gXCd1ok/y3gXCjXzhqyawG+igcPYcAl4qjkvopaQ== +countries-list@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/countries-list/-/countries-list-3.1.0.tgz#1cbe32f58659c7d6a1e744917689f24c84333ea8" + integrity sha512-HpTBLZba1VPTZSjUnUwR7SykxV7Z/7/+ZM5x5wi5tO99Qvom6bE2SC+AQ18016ujg3jSlYBbMITrHNnPAHSM9Q== countup.js@2.3.2: version "2.3.2" From e792924606dd98849008855c9320ff3f7eacf35d Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 11 Mar 2024 20:15:32 +0100 Subject: [PATCH 022/203] Update OSS friends (#3132) --- apps/client/src/assets/oss-friends.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/client/src/assets/oss-friends.json b/apps/client/src/assets/oss-friends.json index 73674e8dd..cbbbd5987 100644 --- a/apps/client/src/assets/oss-friends.json +++ b/apps/client/src/assets/oss-friends.json @@ -1,5 +1,5 @@ { - "createdAt": "2024-02-29T00:00:00.000Z", + "createdAt": "2024-03-11T00:00:00.000Z", "data": [ { "name": "Aptabase", @@ -8,7 +8,7 @@ }, { "name": "Argos", - "description": "Argos provides the developer tools to debug tests and detect visual regressions..", + "description": "Argos provides the developer tools to debug tests and detect visual regressions.", "href": "https://argos-ci.com" }, { From 59c064e3c8ccfcbe0b6f2b9cbbcd28586f40c904 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 11 Mar 2024 20:15:55 +0100 Subject: [PATCH 023/203] Feature/upgrade yahoo finance2 to version 2.10.0 (#3127) * Upgrade yahoo-finance2 to version 2.10.0 * Update changelog --- CHANGELOG.md | 1 + package.json | 2 +- yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7ca1dc34..242dd9dfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Upgraded `countries-list` from version `2.6.1` to `3.1.0` +- Upgraded `yahoo-finance2` from version `2.9.1` to `2.10.0` ### Fixed diff --git a/package.json b/package.json index 5b92172e4..bdac1e9b1 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,7 @@ "svgmap": "2.6.0", "twitter-api-v2": "1.14.2", "uuid": "9.0.1", - "yahoo-finance2": "2.9.1", + "yahoo-finance2": "2.10.0", "zone.js": "0.14.3" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index ba7e811ef..8cf31c64b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19242,10 +19242,10 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yahoo-finance2@2.9.1: - version "2.9.1" - resolved "https://registry.yarnpkg.com/yahoo-finance2/-/yahoo-finance2-2.9.1.tgz#43e22465403f48c688ff8e762f3894aac8014d70" - integrity sha512-s+i5arE6+zUwHRJnze4EsU5aCTmsMFKFeBc9sMzSceDOjH+BSeEZG9twMYtWlSCjKbWLCmUEUCxtH1fvcq+f6Q== +yahoo-finance2@2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/yahoo-finance2/-/yahoo-finance2-2.10.0.tgz#90a9d7984e3b35a11fff9850c55d1cd322ddbee3" + integrity sha512-yKHjMEnFVkgIvgyxjsNAMLf4xGCKM+HzThorCNuCoE71yoie75lR+WTd0HshdCnb8tpsCclFaP045I+p6Mu6aA== dependencies: "@types/tough-cookie" "^4.0.2" ajv "8.10.0" From 7a364472c83662f770f9c319e1040590146dea2f Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 11 Mar 2024 20:16:56 +0100 Subject: [PATCH 024/203] Bugfix/fix liability issue in allocations (#3133) * Remove liabilities from allocations calculation * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/portfolio/portfolio.controller.ts | 7 +++++-- apps/api/src/app/portfolio/portfolio.service.ts | 4 ++-- .../home-summary/home-summary.component.ts | 2 +- apps/client/src/app/services/data.service.ts | 12 ++++++++++-- 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 242dd9dfe..2fddca32c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fixed an issue in the performance calculation caused by multiple `SELL` activities on the same day +- Fixed an issue in the calculation on the allocations page caused by liabilities ## 2.62.0 - 2024-03-09 diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 748850204..557e8a5f5 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -76,8 +76,11 @@ export class PortfolioController { @Query('accounts') filterByAccounts?: string, @Query('assetClasses') filterByAssetClasses?: string, @Query('range') dateRange: DateRange = 'max', - @Query('tags') filterByTags?: string + @Query('tags') filterByTags?: string, + @Query('withLiabilities') withLiabilitiesParam = 'false' ): Promise { + const withLiabilities = withLiabilitiesParam === 'true'; + let hasDetails = true; let hasError = false; const hasReadRestrictedAccessPermission = @@ -101,8 +104,8 @@ export class PortfolioController { dateRange, filters, impersonationId, + withLiabilities, userId: this.request.user.id, - withLiabilities: true, withSummary: true }); diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 9880abcc4..74d7b382a 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -146,8 +146,7 @@ export class PortfolioService { filters, withExcludedAccounts, impersonationId: userId, - userId: this.request.user.id, - withLiabilities: true + userId: this.request.user.id }) ]); @@ -393,6 +392,7 @@ export class PortfolioService { }); const holdings: PortfolioDetails['holdings'] = {}; + const totalValueInBaseCurrency = currentPositions.currentValueInBaseCurrency.plus( cashDetails.balanceInBaseCurrency diff --git a/apps/client/src/app/components/home-summary/home-summary.component.ts b/apps/client/src/app/components/home-summary/home-summary.component.ts index b67b67ce5..bb68a4627 100644 --- a/apps/client/src/app/components/home-summary/home-summary.component.ts +++ b/apps/client/src/app/components/home-summary/home-summary.component.ts @@ -102,7 +102,7 @@ export class HomeSummaryComponent implements OnDestroy, OnInit { this.isLoading = true; this.dataService - .fetchPortfolioDetails() + .fetchPortfolioDetails({ withLiabilities: true }) .pipe(takeUntil(this.unsubscribeSubject)) .subscribe(({ summary }) => { this.summary = summary; diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts index 7741fd601..0c8781eb1 100644 --- a/apps/client/src/app/services/data.service.ts +++ b/apps/client/src/app/services/data.service.ts @@ -390,13 +390,21 @@ export class DataService { } public fetchPortfolioDetails({ - filters + filters, + withLiabilities = false }: { filters?: Filter[]; + withLiabilities?: boolean; } = {}): Observable { + let params = this.buildFiltersAsQueryParams({ filters }); + + if (withLiabilities) { + params = params.append('withLiabilities', withLiabilities); + } + return this.http .get('/api/v1/portfolio/details', { - params: this.buildFiltersAsQueryParams({ filters }) + params }) .pipe( map((response) => { From d23cb5f1902f3b5aca249e5b08e671253d117f38 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 11 Mar 2024 20:17:47 +0100 Subject: [PATCH 025/203] Feature/upgrade simplewebauthn dependencies to version 9.0 (#3130) * Upgrade @simplewebauthn/browser and @simplewebauthn/server to version 9.0 * Update changelog --- CHANGELOG.md | 1 + package.json | 6 +-- yarn.lock | 116 +++++++++++++-------------------------------------- 3 files changed, 34 insertions(+), 89 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fddca32c..18c2f4fcf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Upgraded `@simplewebauthn/browser` and `@simplewebauthn/server` from version `8.3` to `9.0` - Upgraded `countries-list` from version `2.6.1` to `3.1.0` - Upgraded `yahoo-finance2` from version `2.9.1` to `2.10.0` diff --git a/package.json b/package.json index bdac1e9b1..c8d2cbdba 100644 --- a/package.json +++ b/package.json @@ -83,8 +83,8 @@ "@nestjs/schedule": "3.0.2", "@nestjs/serve-static": "4.0.0", "@prisma/client": "5.10.2", - "@simplewebauthn/browser": "8.3.1", - "@simplewebauthn/server": "8.3.2", + "@simplewebauthn/browser": "9.0.1", + "@simplewebauthn/server": "9.0.3", "@stripe/stripe-js": "1.47.0", "alphavantage": "2.2.0", "big.js": "6.2.1", @@ -159,7 +159,7 @@ "@nx/web": "18.0.4", "@nx/workspace": "18.0.4", "@schematics/angular": "17.1.3", - "@simplewebauthn/typescript-types": "8.0.0", + "@simplewebauthn/types": "9.0.1", "@storybook/addon-essentials": "7.6.5", "@storybook/angular": "7.6.5", "@storybook/core-server": "7.6.5", diff --git a/yarn.lock b/yarn.lock index 8cf31c64b..7092b4b93 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2744,36 +2744,6 @@ resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz#923ca57e173c6b232bbbb07347b1be982f03e783" integrity sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A== -"@cbor-extract/cbor-extract-darwin-arm64@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.1.1.tgz#5721f6dd3feae0b96d23122853ce977e0671b7a6" - integrity sha512-blVBy5MXz6m36Vx0DfLd7PChOQKEs8lK2bD1WJn/vVgG4FXZiZmZb2GECHFvVPA5T7OnODd9xZiL3nMCv6QUhA== - -"@cbor-extract/cbor-extract-darwin-x64@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-darwin-x64/-/cbor-extract-darwin-x64-2.1.1.tgz#c25e7d0133950d87d101d7b3afafea8d50d83f5f" - integrity sha512-h6KFOzqk8jXTvkOftyRIWGrd7sKQzQv2jVdTL9nKSf3D2drCvQB/LHUxAOpPXo3pv2clDtKs3xnHalpEh3rDsw== - -"@cbor-extract/cbor-extract-linux-arm64@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-linux-arm64/-/cbor-extract-linux-arm64-2.1.1.tgz#48f78e7d8f0fcc84ed074b6bfa6d15dd83187c63" - integrity sha512-SxAaRcYf8S0QHaMc7gvRSiTSr7nUYMqbUdErBEu+HYA4Q6UNydx1VwFE68hGcp1qvxcy9yT5U7gA+a5XikfwSQ== - -"@cbor-extract/cbor-extract-linux-arm@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-linux-arm/-/cbor-extract-linux-arm-2.1.1.tgz#7507d346389cb682e44fab8fae9534edd52e2e41" - integrity sha512-ds0uikdcIGUjPyraV4oJqyVE5gl/qYBpa/Wnh6l6xLE2lj/hwnjT2XcZCChdXwW/YFZ1LUHs6waoYN8PmK0nKQ== - -"@cbor-extract/cbor-extract-linux-x64@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-linux-x64/-/cbor-extract-linux-x64-2.1.1.tgz#b7c1d2be61c58ec18d58afbad52411ded63cd4cd" - integrity sha512-GVK+8fNIE9lJQHAlhOROYiI0Yd4bAZ4u++C2ZjlkS3YmO6hi+FUxe6Dqm+OKWTcMpL/l71N6CQAmaRcb4zyJuA== - -"@cbor-extract/cbor-extract-win32-x64@2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.1.1.tgz#21b11a1a3f18c3e7d62fd5f87438b7ed2c64c1f7" - integrity sha512-2Niq1C41dCRIDeD8LddiH+mxGlO7HJ612Ll3D/E73ZWBmycued+8ghTr/Ho3CMOWPUEr08XtyBMVXAjqF+TcKw== - "@codewithdan/observable-store@2.2.15": version "2.2.15" resolved "https://registry.yarnpkg.com/@codewithdan/observable-store/-/observable-store-2.2.15.tgz#6d27e0988e182853def59a714b712f4389e558d2" @@ -3839,6 +3809,11 @@ resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== +"@levischuck/tiny-cbor@^0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@levischuck/tiny-cbor/-/tiny-cbor-0.2.2.tgz#84239ce80e1107b810f1fe9f66546d4f79f31aea" + integrity sha512-f5CnPw997Y2GQ8FAvtuVVC19FX8mwNNC+1XJcIi16n/LTJifKO6QBgGLgN3YEmqtGMk17SKSuoWES3imJVxAVw== + "@ljharb/through@^2.3.11": version "2.3.12" resolved "https://registry.yarnpkg.com/@ljharb/through/-/through-2.3.12.tgz#c418c43060eee193adce48b15c2206096a28e9ea" @@ -5214,7 +5189,7 @@ tslib "^2.3.0" yargs-parser "21.1.1" -"@peculiar/asn1-android@^2.3.6": +"@peculiar/asn1-android@^2.3.10": version "2.3.10" resolved "https://registry.yarnpkg.com/@peculiar/asn1-android/-/asn1-android-2.3.10.tgz#a2dde6227fa1ddea33d8ae7835768674e7a0baa6" integrity sha512-z9Rx9cFJv7UUablZISe7uksNbFJCq13hO0yEAOoIpAymALTLlvUOSLnGiQS7okPaM5dP42oTLhezH6XDXRXjGw== @@ -5223,7 +5198,7 @@ asn1js "^3.0.5" tslib "^2.6.2" -"@peculiar/asn1-ecc@^2.3.6": +"@peculiar/asn1-ecc@^2.3.8": version "2.3.8" resolved "https://registry.yarnpkg.com/@peculiar/asn1-ecc/-/asn1-ecc-2.3.8.tgz#6b1a18f64f221ae862c1038bb125fbf4342918a0" integrity sha512-Ah/Q15y3A/CtxbPibiLM/LKcMbnLTdUdLHUgdpB5f60sSvGkXzxJCu5ezGTFHogZXWNX3KSmYqilCrfdmBc6pQ== @@ -5233,7 +5208,7 @@ asn1js "^3.0.5" tslib "^2.6.2" -"@peculiar/asn1-rsa@^2.3.6": +"@peculiar/asn1-rsa@^2.3.8": version "2.3.8" resolved "https://registry.yarnpkg.com/@peculiar/asn1-rsa/-/asn1-rsa-2.3.8.tgz#6a6a0eaafc0aded9a44b679b522cc2417b09a3ba" integrity sha512-ES/RVEHu8VMYXgrg3gjb1m/XG0KJWnV4qyZZ7mAg7rrF3VTmRbLxO8mk+uy0Hme7geSMebp+Wvi2U6RLLEs12Q== @@ -5243,7 +5218,7 @@ asn1js "^3.0.5" tslib "^2.6.2" -"@peculiar/asn1-schema@^2.3.6", "@peculiar/asn1-schema@^2.3.8": +"@peculiar/asn1-schema@^2.3.8": version "2.3.8" resolved "https://registry.yarnpkg.com/@peculiar/asn1-schema/-/asn1-schema-2.3.8.tgz#04b38832a814e25731232dd5be883460a156da3b" integrity sha512-ULB1XqHKx1WBU/tTFIA+uARuRoBVZ4pNdOA878RDrRbBfBGcSzi5HBkdScC6ZbHn8z7L8gmKCgPC1LHRrP46tA== @@ -5252,7 +5227,7 @@ pvtsutils "^1.3.5" tslib "^2.6.2" -"@peculiar/asn1-x509@^2.3.6", "@peculiar/asn1-x509@^2.3.8": +"@peculiar/asn1-x509@^2.3.8": version "2.3.8" resolved "https://registry.yarnpkg.com/@peculiar/asn1-x509/-/asn1-x509-2.3.8.tgz#865896e2b849cc3c55497ca685040ef889d357a3" integrity sha512-voKxGfDU1c6r9mKiN5ZUsZWh3Dy1BABvTM3cimf0tztNwyMJPhiXY94eRTgsMQe6ViLfT6EoXxkWVzcm3mFAFw== @@ -5725,37 +5700,32 @@ "@sigstore/protobuf-specs" "^0.2.1" tuf-js "^2.1.0" -"@simplewebauthn/browser@8.3.1": - version "8.3.1" - resolved "https://registry.yarnpkg.com/@simplewebauthn/browser/-/browser-8.3.1.tgz#f5c1aed6313d61944a9e13f16ae4495750bddf93" - integrity sha512-bMW7oOkxX4ydRAkkPtJ1do2k9yOoIGc/hZYebcuEOVdJoC6wwVpu97mYY7Mz8B9hLlcaR5WFgBsLl5tSJVzm8A== +"@simplewebauthn/browser@9.0.1": + version "9.0.1" + resolved "https://registry.yarnpkg.com/@simplewebauthn/browser/-/browser-9.0.1.tgz#46a12c2bcefcb199f7fcb6a7e883531cd6efde17" + integrity sha512-wD2WpbkaEP4170s13/HUxPcAV5y4ZXaKo1TfNklS5zDefPinIgXOpgz1kpEvobAsaLPa2KeH7AKKX/od1mrBJw== dependencies: - "@simplewebauthn/typescript-types" "^8.0.0" + "@simplewebauthn/types" "^9.0.1" -"@simplewebauthn/server@8.3.2": - version "8.3.2" - resolved "https://registry.yarnpkg.com/@simplewebauthn/server/-/server-8.3.2.tgz#dfdbe7af4c1258e786c4a0b1c83c54743ba7568c" - integrity sha512-ceo8t5gdO5W/JOePQWPDH+rAd8tO6QNalLU56rc9ItdzaTjk+qcYwQg/BKXDDg6117P3HKrRBkZwBrMJl4dOdA== +"@simplewebauthn/server@9.0.3": + version "9.0.3" + resolved "https://registry.yarnpkg.com/@simplewebauthn/server/-/server-9.0.3.tgz#5f73c19ff2420be94cc71a49085879c111d7872d" + integrity sha512-FMZieoBosrVLFxCnxPFD9Enhd1U7D8nidVDT4MsHc6l4fdVcjoeHjDueeXCloO1k5O/fZg1fsSXXPKbY2XTzDA== dependencies: "@hexagon/base64" "^1.1.27" - "@peculiar/asn1-android" "^2.3.6" - "@peculiar/asn1-ecc" "^2.3.6" - "@peculiar/asn1-rsa" "^2.3.6" - "@peculiar/asn1-schema" "^2.3.6" - "@peculiar/asn1-x509" "^2.3.6" - "@simplewebauthn/typescript-types" "^8.0.0" - cbor-x "^1.5.2" + "@levischuck/tiny-cbor" "^0.2.2" + "@peculiar/asn1-android" "^2.3.10" + "@peculiar/asn1-ecc" "^2.3.8" + "@peculiar/asn1-rsa" "^2.3.8" + "@peculiar/asn1-schema" "^2.3.8" + "@peculiar/asn1-x509" "^2.3.8" + "@simplewebauthn/types" "^9.0.1" cross-fetch "^4.0.0" -"@simplewebauthn/typescript-types@8.0.0": - version "8.0.0" - resolved "https://registry.yarnpkg.com/@simplewebauthn/typescript-types/-/typescript-types-8.0.0.tgz#1698a7228aba880c5c1deba1f13a4f9fd8851cb3" - integrity sha512-d7Izb2H+LZJteXMkS8DmpAarD6mZdpIOu/av/yH4/u/3Pd6DKFLyBM3j8BMmUvUqpzvJvHARNrRfQYto58mtTQ== - -"@simplewebauthn/typescript-types@^8.0.0": - version "8.3.3" - resolved "https://registry.yarnpkg.com/@simplewebauthn/typescript-types/-/typescript-types-8.3.3.tgz#4292656f4fae6c9e9c25e5b94a60fa038a7d11cc" - integrity sha512-YLfmT+HzzUuRtBPp93XgKzQPrFJ1F6f1vl7ltfmm6R9d2SZfr8E15B5CC7hkCwSTioJDCaEw4p3NZt3+nubaxA== +"@simplewebauthn/types@9.0.1", "@simplewebauthn/types@^9.0.1": + version "9.0.1" + resolved "https://registry.yarnpkg.com/@simplewebauthn/types/-/types-9.0.1.tgz#3a68d50e63d8821cf2067de3324c68d5e8120d0c" + integrity sha512-tGSRP1QvsAvsJmnOlRQyw/mvK9gnPtjEc5fg2+m8n+QUa+D7rvrKkOYyfpy42GTs90X3RDOnqJgfHt+qO67/+w== "@sinclair/typebox@^0.27.8": version "0.27.8" @@ -9078,27 +9048,6 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== -cbor-extract@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/cbor-extract/-/cbor-extract-2.1.1.tgz#f154b31529fdb6b7c70fb3ca448f44eda96a1b42" - integrity sha512-1UX977+L+zOJHsp0mWFG13GLwO6ucKgSmSW6JTl8B9GUvACvHeIVpFqhU92299Z6PfD09aTXDell5p+lp1rUFA== - dependencies: - node-gyp-build-optional-packages "5.0.3" - optionalDependencies: - "@cbor-extract/cbor-extract-darwin-arm64" "2.1.1" - "@cbor-extract/cbor-extract-darwin-x64" "2.1.1" - "@cbor-extract/cbor-extract-linux-arm" "2.1.1" - "@cbor-extract/cbor-extract-linux-arm64" "2.1.1" - "@cbor-extract/cbor-extract-linux-x64" "2.1.1" - "@cbor-extract/cbor-extract-win32-x64" "2.1.1" - -cbor-x@^1.5.2: - version "1.5.4" - resolved "https://registry.yarnpkg.com/cbor-x/-/cbor-x-1.5.4.tgz#8f0754fa8589cbd7339b613b2b5717d133508e98" - integrity sha512-PVKILDn+Rf6MRhhcyzGXi5eizn1i0i3F8Fe6UMMxXBnWkalq9+C5+VTmlIjAYM4iF2IYF2N+zToqAfYOp+3rfw== - optionalDependencies: - cbor-extract "^2.1.1" - chalk@^1.0.0, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -15213,11 +15162,6 @@ node-forge@^1, node-forge@^1.3.1: resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== -node-gyp-build-optional-packages@5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.3.tgz#92a89d400352c44ad3975010368072b41ad66c17" - integrity sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA== - node-gyp-build-optional-packages@5.0.7: version "5.0.7" resolved "https://registry.yarnpkg.com/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.0.7.tgz#5d2632bbde0ab2f6e22f1bbac2199b07244ae0b3" From 9a3db919827cd2d1a0e05810ec4d33c2a4c49067 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 11 Mar 2024 20:19:23 +0100 Subject: [PATCH 026/203] Release 2.63.0 (#3134) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18c2f4fcf..425aa20cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.63.0 - 2024-03-11 ### Added diff --git a/package.json b/package.json index c8d2cbdba..b5f7d9c3d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.62.0", + "version": "2.63.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 473136e9aa4c9144cafacc56d6a7cd0f0b939cf9 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 11 Mar 2024 21:35:43 +0100 Subject: [PATCH 027/203] Release 2.63.1 (#3135) * Release 2.63.1 --- CHANGELOG.md | 4 ++- .../src/assets/cryptocurrencies/custom.json | 1 + .../eod-historical-data.service.ts | 31 +++++++------------ package.json | 2 +- 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 425aa20cb..0877bcf74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,11 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 2.63.0 - 2024-03-11 +## 2.63.1 - 2024-03-11 ### Added - Extended the content of the _Self-Hosting_ section by available home server systems on the Frequently Asked Questions (FAQ) page +- Added support for the cryptocurrency _Real Smurf Cat_ (`SMURFCAT-USD`) ### Changed @@ -21,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed an issue in the performance calculation caused by multiple `SELL` activities on the same day - Fixed an issue in the calculation on the allocations page caused by liabilities +- Fixed an issue with the currency in the request to get quotes from _EOD Historical Data_ ## 2.62.0 - 2024-03-09 diff --git a/apps/api/src/assets/cryptocurrencies/custom.json b/apps/api/src/assets/cryptocurrencies/custom.json index ffda9c526..ef08ca449 100644 --- a/apps/api/src/assets/cryptocurrencies/custom.json +++ b/apps/api/src/assets/cryptocurrencies/custom.json @@ -4,6 +4,7 @@ "LUNA1": "Terra", "LUNA2": "Terra", "SGB1": "Songbird", + "SMURFCAT": "Real Smurf Cat", "UNI1": "Uniswap", "UNI7083": "Uniswap", "UST": "TerraUSD" diff --git a/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts b/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts index af67d62e9..d8e7a2e0b 100644 --- a/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts +++ b/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts @@ -11,7 +11,6 @@ import { IDataProviderHistoricalResponse, IDataProviderResponse } from '@ghostfolio/api/services/interfaces/interfaces'; -import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; import { DEFAULT_CURRENCY, REPLACE_NAME_PARTS @@ -36,8 +35,7 @@ export class EodHistoricalDataService implements DataProviderInterface { private readonly URL = 'https://eodhistoricaldata.com/api'; public constructor( - private readonly configurationService: ConfigurationService, - private readonly symbolProfileService: SymbolProfileService + private readonly configurationService: ConfigurationService ) { this.apiKey = this.configurationService.get('API_KEY_EOD_HISTORICAL_DATA'); } @@ -232,29 +230,24 @@ export class EodHistoricalDataService implements DataProviderInterface { ? [realTimeResponse] : realTimeResponse; - const symbolProfiles = await this.symbolProfileService.getSymbolProfiles( - symbols.map((symbol) => { - return { - symbol, - dataSource: this.getName() - }; - }) - ); - response = quotes.reduce( - ( + async ( result: { [symbol: string]: IDataProviderResponse }, { close, code, timestamp } ) => { - const currency = symbolProfiles.find(({ symbol }) => { - return symbol === code; - })?.currency; + let currency: string; + + if (symbols.length === 1) { + const { items } = await this.search({ query: symbols[0] }); + + if (items.length === 1) { + currency = items[0].currency; + } + } if (isNumber(close)) { result[this.convertFromEodSymbol(code)] = { - currency: - currency ?? - this.convertFromEodSymbol(code)?.replace(DEFAULT_CURRENCY, ''), + currency, dataSource: this.getName(), marketPrice: close, marketState: isToday(new Date(timestamp * 1000)) diff --git a/package.json b/package.json index b5f7d9c3d..579c4151e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.63.0", + "version": "2.63.1", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 671e4e316b3db329b2ba53ecd2d25acf35acdcd7 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 12 Mar 2024 20:50:32 +0100 Subject: [PATCH 028/203] Release 2.63.2 (#3138) --- CHANGELOG.md | 2 +- .../eod-historical-data.service.ts | 76 +++++++++++-------- package.json | 2 +- 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0877bcf74..6f1c07500 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 2.63.1 - 2024-03-11 +## 2.63.2 - 2024-03-12 ### Added diff --git a/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts b/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts index d8e7a2e0b..99104a78d 100644 --- a/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts +++ b/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts @@ -11,6 +11,7 @@ import { IDataProviderHistoricalResponse, IDataProviderResponse } from '@ghostfolio/api/services/interfaces/interfaces'; +import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; import { DEFAULT_CURRENCY, REPLACE_NAME_PARTS @@ -35,7 +36,8 @@ export class EodHistoricalDataService implements DataProviderInterface { private readonly URL = 'https://eodhistoricaldata.com/api'; public constructor( - private readonly configurationService: ConfigurationService + private readonly configurationService: ConfigurationService, + private readonly symbolProfileService: SymbolProfileService ) { this.apiKey = this.configurationService.get('API_KEY_EOD_HISTORICAL_DATA'); } @@ -230,41 +232,53 @@ export class EodHistoricalDataService implements DataProviderInterface { ? [realTimeResponse] : realTimeResponse; - response = quotes.reduce( - async ( - result: { [symbol: string]: IDataProviderResponse }, - { close, code, timestamp } - ) => { - let currency: string; + const symbolProfiles = await this.symbolProfileService.getSymbolProfiles( + symbols.map((symbol) => { + return { + symbol, + dataSource: this.getName() + }; + }) + ); - if (symbols.length === 1) { - const { items } = await this.search({ query: symbols[0] }); + for (const { close, code, timestamp } of quotes) { + let currency: string; - if (items.length === 1) { - currency = items[0].currency; - } - } + if (code.endsWith('.FOREX')) { + currency = this.convertFromEodSymbol(code)?.replace( + DEFAULT_CURRENCY, + '' + ); + } - if (isNumber(close)) { - result[this.convertFromEodSymbol(code)] = { - currency, - dataSource: this.getName(), - marketPrice: close, - marketState: isToday(new Date(timestamp * 1000)) - ? 'open' - : 'closed' - }; - } else { - Logger.error( - `Could not get quote for ${this.convertFromEodSymbol(code)} (${this.getName()})`, - 'EodHistoricalDataService' - ); + if (!currency) { + currency = symbolProfiles.find(({ symbol }) => { + return symbol === code; + })?.currency; + } + + if (!currency) { + const { items } = await this.search({ query: code }); + + if (items.length === 1) { + currency = items[0].currency; } + } - return result; - }, - {} - ); + if (isNumber(close)) { + response[this.convertFromEodSymbol(code)] = { + currency, + dataSource: this.getName(), + marketPrice: close, + marketState: isToday(new Date(timestamp * 1000)) ? 'open' : 'closed' + }; + } else { + Logger.error( + `Could not get quote for ${this.convertFromEodSymbol(code)} (${this.getName()})`, + 'EodHistoricalDataService' + ); + } + } return response; } catch (error) { diff --git a/package.json b/package.json index 579c4151e..c32114cf4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.63.1", + "version": "2.63.2", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 40d93066ff3f3f9c883670b60bd98408f59d2de9 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Wed, 13 Mar 2024 20:21:54 +0100 Subject: [PATCH 029/203] Introduce .env.dev (#3120) --- .env.dev | 25 +++++++++++++++++++++++++ .env.example | 3 ++- README.md | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 .env.dev diff --git a/.env.dev b/.env.dev new file mode 100644 index 000000000..c4c8a0d35 --- /dev/null +++ b/.env.dev @@ -0,0 +1,25 @@ +COMPOSE_PROJECT_NAME=ghostfolio-development + +# CACHE +REDIS_HOST=localhost +REDIS_PORT=6379 +REDIS_PASSWORD= + +# POSTGRES +POSTGRES_DB=ghostfolio-db +POSTGRES_USER=user +POSTGRES_PASSWORD= + +# VARIOUS +ACCESS_TOKEN_SALT= +DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}?connect_timeout=300&sslmode=prefer +JWT_SECRET_KEY= + +# DEVELOPMENT + +# Nx 18 enables using plugins to infer targets by default +# This is disabled for existing workspaces to maintain compatibility +# For more info, see: https://nx.dev/concepts/inferred-tasks +NX_ADD_PLUGINS=false + +NX_NATIVE_COMMAND_RUNNER=false diff --git a/.env.example b/.env.example index 8df547e37..766894992 100644 --- a/.env.example +++ b/.env.example @@ -1,4 +1,4 @@ -COMPOSE_PROJECT_NAME=ghostfolio-development +COMPOSE_PROJECT_NAME=ghostfolio # CACHE REDIS_HOST=localhost @@ -10,6 +10,7 @@ POSTGRES_DB=ghostfolio-db POSTGRES_USER=user POSTGRES_PASSWORD= +# VARIOUS ACCESS_TOKEN_SALT= DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}?connect_timeout=300&sslmode=prefer JWT_SECRET_KEY= diff --git a/README.md b/README.md index eb302936e..9602d88c9 100644 --- a/README.md +++ b/README.md @@ -154,7 +154,7 @@ Ghostfolio is available for various home server systems, including [CasaOS](http - [Node.js](https://nodejs.org/en/download) (version 18+) - [Yarn](https://yarnpkg.com/en/docs/install) - Create a local copy of this Git repository (clone) -- Copy the file `.env.example` to `.env` and populate it with your data (`cp .env.example .env`) +- Copy the file `.env.dev` to `.env` and populate it with your data (`cp .env.dev .env`) ### Setup From a0ddd1f9b99187acde7302a334cc1c22234d8921 Mon Sep 17 00:00:00 2001 From: helgehatt Date: Wed, 13 Mar 2024 20:44:33 +0100 Subject: [PATCH 030/203] Fix date conversion in import of historical market data (#3117) * Fix date conversion in import of historical market data * Update changelog --- CHANGELOG.md | 6 ++++++ .../admin-market-data-detail.component.ts | 3 +-- .../market-data-detail-dialog/interfaces/interfaces.ts | 2 +- .../market-data-detail-dialog.component.ts | 4 ++-- .../market-data-detail-dialog.html | 2 +- .../asset-profile-dialog.component.ts | 7 +++---- apps/client/src/app/services/admin.service.ts | 9 +++------ 7 files changed, 17 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f1c07500..f60fcdf26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Fixed + +- Fixed the date conversion of the import of historical market data in the admin control panel + ## 2.63.2 - 2024-03-12 ### Added diff --git a/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.ts b/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.ts index 5a2ec5265..26da886e7 100644 --- a/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.ts +++ b/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.ts @@ -155,15 +155,14 @@ export class AdminMarketDataDetailComponent implements OnChanges, OnInit { day: string; yearMonth: string; }) { - const date = parseISO(`${yearMonth}-${day}`); const marketPrice = this.marketDataByMonth[yearMonth]?.[day]?.marketPrice; const dialogRef = this.dialog.open(MarketDataDetailDialog, { data: { - date, marketPrice, currency: this.currency, dataSource: this.dataSource, + dateString: `${yearMonth}-${day}`, symbol: this.symbol, user: this.user }, diff --git a/apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/interfaces/interfaces.ts b/apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/interfaces/interfaces.ts index 8f5447f9c..81188cd1f 100644 --- a/apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/interfaces/interfaces.ts +++ b/apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/interfaces/interfaces.ts @@ -5,7 +5,7 @@ import { DataSource } from '@prisma/client'; export interface MarketDataDetailDialogParams { currency: string; dataSource: DataSource; - date: Date; + dateString: string; marketPrice: number; symbol: string; user: User; diff --git a/apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.component.ts b/apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.component.ts index df8ac6067..6a44d0dfb 100644 --- a/apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.component.ts +++ b/apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.component.ts @@ -45,7 +45,7 @@ export class MarketDataDetailDialog implements OnDestroy { this.adminService .fetchSymbolForDate({ dataSource: this.data.dataSource, - date: this.data.date, + dateString: this.data.dateString, symbol: this.data.symbol }) .pipe(takeUntil(this.unsubscribeSubject)) @@ -63,7 +63,7 @@ export class MarketDataDetailDialog implements OnDestroy { marketData: { marketData: [ { - date: this.data.date.toISOString(), + date: this.data.dateString, marketPrice: this.data.marketPrice } ] diff --git a/apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html b/apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html index 5e16fc702..8e7e30649 100644 --- a/apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html +++ b/apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html @@ -9,7 +9,7 @@ matInput name="date" [matDatepicker]="date" - [(ngModel)]="data.date" + [(ngModel)]="data.dateString" /> { - return { marketPrice, date: parseDate(date).toISOString() }; - }) + marketData }, symbol: this.data.symbol }) diff --git a/apps/client/src/app/services/admin.service.ts b/apps/client/src/app/services/admin.service.ts index 7d204c607..c850527a8 100644 --- a/apps/client/src/app/services/admin.service.ts +++ b/apps/client/src/app/services/admin.service.ts @@ -188,17 +188,14 @@ export class AdminService { public fetchSymbolForDate({ dataSource, - date, + dateString, symbol }: { dataSource: DataSource; - date: Date; + dateString: string; symbol: string; }) { - const url = `/api/v1/symbol/${dataSource}/${symbol}/${format( - date, - DATE_FORMAT - )}`; + const url = `/api/v1/symbol/${dataSource}/${symbol}/${dateString}`; return this.http.get(url); } From 8420cb830c678734e1096192cd806d203c0e0a28 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 14 Mar 2024 14:09:20 +0100 Subject: [PATCH 031/203] Feature/add product roadmap to faq (#3143) * Add product roadmap * Update changelog --- CHANGELOG.md | 4 ++ .../pages/faq/overview/faq-overview-page.html | 37 ++++++++++--------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f60fcdf26..77c556152 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Extended the content of the _General_ section by the product roadmap on the Frequently Asked Questions (FAQ) page + ### Fixed - Fixed the date conversion of the import of historical market data in the admin control panel diff --git a/apps/client/src/app/pages/faq/overview/faq-overview-page.html b/apps/client/src/app/pages/faq/overview/faq-overview-page.html index 97c2067d0..925871a60 100644 --- a/apps/client/src/app/pages/faq/overview/faq-overview-page.html +++ b/apps/client/src/app/pages/faq/overview/faq-overview-page.html @@ -33,10 +33,8 @@ - What else is included in Ghostfolio? + What else is included in Ghostfolio? + Please find a feature overview to manage your wealth here. @@ -44,10 +42,8 @@ - Can I use Ghostfolio anonymously? + Can I use Ghostfolio anonymously? + Yes, the authentication system via security token enables you to sign in securely and anonymously to Ghostfolio. There is no need for an @@ -56,10 +52,8 @@ - How can Ghostfolio be free? + How can Ghostfolio be free? + This project is driven by the efforts of contributors from around the world. The @@ -75,8 +69,8 @@ Do you monetize or sell my financial data? + > + No, we value your privacy. We do not sell or share your financial data with any third parties. - What is your business model? + What is your business model? + By offering Ghostfolio Premium, a @@ -96,6 +88,15 @@ users. + + + What is your product roadmap? + + At this time, we do not have a public roadmap + available. + Date: Fri, 15 Mar 2024 08:37:41 +0100 Subject: [PATCH 032/203] Feature/improve usability of platform and tag management (#3144) * Improve usability * Update changelog --- CHANGELOG.md | 5 +++++ .../components/admin-platform/admin-platform.component.html | 6 +++++- .../src/app/components/admin-tag/admin-tag.component.html | 6 +++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77c556152..bcf2ad4f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Extended the content of the _General_ section by the product roadmap on the Frequently Asked Questions (FAQ) page +### Changed + +- Improved the usability of the platform management in the admin control panel +- Improved the usability of the tag management in the admin control panel + ### Fixed - Fixed the date conversion of the import of historical market data in the admin control panel diff --git a/apps/client/src/app/components/admin-platform/admin-platform.component.html b/apps/client/src/app/components/admin-platform/admin-platform.component.html index bd7e82560..ecf3304cf 100644 --- a/apps/client/src/app/components/admin-platform/admin-platform.component.html +++ b/apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -91,7 +91,11 @@ Edit - - +
diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts index 372608279..846b5e599 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts @@ -1,4 +1,5 @@ import { GfAdminMarketDataDetailModule } from '@ghostfolio/client/components/admin-market-data-detail/admin-market-data-detail.module'; +import { AdminMarketDataService } from '@ghostfolio/client/components/admin-market-data/admin-market-data.service'; import { GfCurrencySelectorModule } from '@ghostfolio/ui/currency-selector/currency-selector.module'; import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart/portfolio-proportion-chart.module'; import { GfValueModule } from '@ghostfolio/ui/value'; @@ -36,6 +37,7 @@ import { AssetProfileDialog } from './asset-profile-dialog.component'; ReactiveFormsModule, TextFieldModule ], + providers: [AdminMarketDataService], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class GfAssetProfileDialogModule {} From 61ecd15f1d5812a3a929780ca62e95cab66bcf7d Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 19 Mar 2024 19:55:08 +0100 Subject: [PATCH 047/203] Feature/change edit button to a in admin market data page (#3164) * Change edit button to a * Update changelog --- CHANGELOG.md | 1 + .../admin-market-data/admin-market-data.html | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 440784758..2dc8cc0ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Moved the support to grant private access with permissions from experimental to general availability +- Improved the usability to edit market data in the admin control panel ## 2.64.0 - 2024-03-16 diff --git a/apps/client/src/app/components/admin-market-data/admin-market-data.html b/apps/client/src/app/components/admin-market-data/admin-market-data.html index a91b05bcc..83e7f7533 100644 --- a/apps/client/src/app/components/admin-market-data/admin-market-data.html +++ b/apps/client/src/app/components/admin-market-data/admin-market-data.html @@ -161,20 +161,20 @@ - +
diff --git a/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts b/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts index f176c0847..c6d7f8e89 100644 --- a/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts +++ b/apps/client/src/app/components/user-account-settings/user-account-settings.component.ts @@ -48,7 +48,8 @@ export class UserAccountSettingsComponent implements OnDestroy, OnInit { 'nl', 'pl', 'pt', - 'tr' + 'tr', + 'zh' ]; public user: User; diff --git a/apps/client/src/app/components/user-account-settings/user-account-settings.html b/apps/client/src/app/components/user-account-settings/user-account-settings.html index df423ba16..1ad24e22e 100644 --- a/apps/client/src/app/components/user-account-settings/user-account-settings.html +++ b/apps/client/src/app/components/user-account-settings/user-account-settings.html @@ -76,6 +76,12 @@ Deutsch English + @if (user?.settings?.isExperimentalFeatures) { + Chinese (Community) + } Español (Community)Nederlands (Community) - Polski (Community) + @if (user?.settings?.isExperimentalFeatures) { + Polski (Community) + } Português (Community)

Multi-Language

- Use Ghostfolio in multiple languages: English, Dutch, French, - German, Italian, + Use Ghostfolio in multiple languages: English, + Dutch, French, German, Italian, Portuguese, Spanish and Turkish are currently supported.

diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf new file mode 100644 index 000000000..f1e528dd0 --- /dev/null +++ b/apps/client/src/locales/messages.zh.xlf @@ -0,0 +1,6 @@ + + + + + + diff --git a/libs/common/src/lib/config.ts b/libs/common/src/lib/config.ts index 3bbe0ff8c..293f77488 100644 --- a/libs/common/src/lib/config.ts +++ b/libs/common/src/lib/config.ts @@ -137,7 +137,8 @@ export const SUPPORTED_LANGUAGE_CODES = [ 'nl', 'pl', 'pt', - 'tr' + 'tr', + 'zh' ]; export const UNKNOWN_KEY = 'UNKNOWN'; diff --git a/libs/common/src/lib/helper.ts b/libs/common/src/lib/helper.ts index b49589aab..e03ea1a1f 100644 --- a/libs/common/src/lib/helper.ts +++ b/libs/common/src/lib/helper.ts @@ -11,7 +11,7 @@ import { parseISO, subDays } from 'date-fns'; -import { de, es, fr, it, nl, pl, pt, tr } from 'date-fns/locale'; +import { de, es, fr, it, nl, pl, pt, tr, zhCN } from 'date-fns/locale'; import { ghostfolioScraperApiSymbolPrefix, locale } from './config'; import { Benchmark, UniqueAsset } from './interfaces'; @@ -178,6 +178,8 @@ export function getDateFnsLocale(aLanguageCode: string) { return pt; } else if (aLanguageCode === 'tr') { return tr; + } else if (aLanguageCode === 'zh') { + return zhCN; } return undefined; From af47889d6544001864069f9faabd8ae962eb0d25 Mon Sep 17 00:00:00 2001 From: qiaoy Date: Sun, 31 Mar 2024 17:24:32 +0800 Subject: [PATCH 082/203] Add Chinese translations (#3215) * Add Chinese translations --- apps/client/src/locales/messages.zh.xlf | 14997 +++++++++++++++++++++- 1 file changed, 14996 insertions(+), 1 deletion(-) diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index f1e528dd0..2887d5724 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -1,6 +1,15001 @@ + - + + + about + 关于 + + apps/client/src/app/app-routing.module.ts + 9 + + + apps/client/src/app/app.component.ts + 47 + + + apps/client/src/app/app.component.ts + 48 + + + apps/client/src/app/app.component.ts + 49 + + + apps/client/src/app/app.component.ts + 51 + + + apps/client/src/app/components/header/header.component.ts + 76 + + + apps/client/src/app/components/header/header.component.ts + 81 + + + apps/client/src/app/pages/about/about-page.component.ts + 45 + + + apps/client/src/app/pages/about/about-page.component.ts + 50 + + + apps/client/src/app/pages/about/about-page.component.ts + 55 + + + apps/client/src/app/pages/about/about-page.component.ts + 63 + + + apps/client/src/app/pages/about/about-page.component.ts + 74 + + + apps/client/src/app/pages/blog/2023/08/ghostfolio-joins-oss-friends/ghostfolio-joins-oss-friends-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts + 14 + + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2023/11/hacktoberfest-2023-debriefing/hacktoberfest-2023-debriefing-page.component.ts + 13 + + + apps/client/src/app/pages/landing/landing-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.component.ts + 22 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/allinvestview-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/allvue-systems-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/basil-finance-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/beanvest-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/capitally-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/compound-planning-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/de.fi-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/delta-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/divvydiary-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/eightfigures-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/empower-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/exirio-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/fina-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/finary-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/finwise-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/folishare-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/getquin-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/gospatz-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/intuit-mint-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/justetf-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/kubera-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/magnifi-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/markets.sh-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/maybe-finance-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/monarch-money-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/monse-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/parqet-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/plannix-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/portfolio-dividend-tracker-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/portseido-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/projectionlab-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/rocket-money-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/seeking-alpha-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/sharesight-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/simple-portfolio-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockle-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/tiller-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/utluna-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/vyzer-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/wealthfolio-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/wealthica-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/whal-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/yeekatee-page.component.ts + 26 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/ynab-page.component.ts + 26 + + + + faq + 常见问题 + + apps/client/src/app/app-routing.module.ts + 10 + + + apps/client/src/app/app.component.ts + 54 + + + apps/client/src/app/pages/about/overview/about-overview-page.component.ts + 19 + + + apps/client/src/app/pages/faq/faq-page.component.ts + 37 + + + apps/client/src/app/pages/faq/faq-page.component.ts + 42 + + + apps/client/src/app/pages/faq/faq-page.component.ts + 48 + + + apps/client/src/app/pages/resources/resources-page.component.ts + 17 + + + + features + 功能 + + apps/client/src/app/app-routing.module.ts + 11 + + + apps/client/src/app/app.component.ts + 55 + + + apps/client/src/app/components/header/header.component.ts + 77 + + + apps/client/src/app/components/header/header.component.ts + 82 + + + apps/client/src/app/pages/about/overview/about-overview-page.component.ts + 20 + + + apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.component.ts + 15 + + + apps/client/src/app/pages/blog/2023/03/1000-stars-on-github/1000-stars-on-github-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2023/05/unlock-your-financial-potential-with-ghostfolio/unlock-your-financial-potential-with-ghostfolio-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2023/07/exploring-the-path-to-fire/exploring-the-path-to-fire-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts + 15 + + + apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts + 15 + + + apps/client/src/app/pages/blog/2023/11/hacktoberfest-2023-debriefing/hacktoberfest-2023-debriefing-page.component.ts + 14 + + + apps/client/src/app/pages/faq/overview/faq-overview-page.component.ts + 14 + + + apps/client/src/app/pages/pricing/pricing-page.component.ts + 35 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/allinvestview-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/allvue-systems-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/basil-finance-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/beanvest-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/capitally-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/compound-planning-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/de.fi-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/delta-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/divvydiary-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/eightfigures-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/empower-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/exirio-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/fina-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/finary-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/finwise-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/folishare-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/getquin-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/gospatz-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/intuit-mint-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/justetf-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/kubera-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/magnifi-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/markets.sh-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/maybe-finance-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/monarch-money-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/monse-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/parqet-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/plannix-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/portfolio-dividend-tracker-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/portseido-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/projectionlab-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/rocket-money-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/seeking-alpha-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/sharesight-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/simple-portfolio-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockle-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/tiller-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/utluna-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/vyzer-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/wealthfolio-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/wealthica-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/whal-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/yeekatee-page.component.ts + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/ynab-page.component.ts + 27 + + + + license + 许可 + + apps/client/src/app/app-routing.module.ts + 12 + + + apps/client/src/app/app.component.ts + 49 + + + apps/client/src/app/pages/about/about-page.component.ts + 55 + + + + markets + 市场 + + apps/client/src/app/app-routing.module.ts + 13 + + + apps/client/src/app/app.component.ts + 56 + + + apps/client/src/app/components/header/header.component.ts + 78 + + + apps/client/src/app/components/header/header.component.ts + 83 + + + apps/client/src/app/pages/blog/2022/08/500-stars-on-github/500-stars-on-github-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.component.ts + 16 + + + apps/client/src/app/pages/faq/saas/saas-page.component.ts + 14 + + + + pricing + 价钱 + + apps/client/src/app/app-routing.module.ts + 14 + + + apps/client/src/app/app.component.ts + 57 + + + apps/client/src/app/components/header/header.component.ts + 79 + + + apps/client/src/app/components/header/header.component.ts + 84 + + + apps/client/src/app/components/home-summary/home-summary.component.ts + 125 + + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.component.ts + 14 + + + apps/client/src/app/components/user-account-membership/user-account-membership.component.ts + 38 + + + apps/client/src/app/core/http-response.interceptor.ts + 81 + + + apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2021/07/hello-ghostfolio/hello-ghostfolio-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2022/01/first-months-in-open-source/first-months-in-open-source-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2022/08/500-stars-on-github/500-stars-on-github-page.component.ts + 14 + + + apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.component.ts + 16 + + + apps/client/src/app/pages/blog/2023/03/1000-stars-on-github/1000-stars-on-github-page.component.ts + 14 + + + apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts + 16 + + + apps/client/src/app/pages/faq/saas/saas-page.component.ts + 15 + + + libs/ui/src/lib/membership-card/membership-card.component.ts + 13 + + + + privacy-policy + 隐私政策 + + apps/client/src/app/app-routing.module.ts + 15 + + + apps/client/src/app/app.component.ts + 52 + + + apps/client/src/app/pages/about/about-page.component.ts + 63 + + + + register + 注册 + + apps/client/src/app/app-routing.module.ts + 16 + + + apps/client/src/app/app.component.ts + 58 + + + apps/client/src/app/components/header/header.component.ts + 85 + + + apps/client/src/app/core/auth.guard.ts + 54 + + + apps/client/src/app/pages/faq/saas/saas-page.component.ts + 16 + + + apps/client/src/app/pages/features/features-page.component.ts + 18 + + + apps/client/src/app/pages/landing/landing-page.component.ts + 27 + + + apps/client/src/app/pages/pricing/pricing-page.component.ts + 36 + + + + resources + 资源 + + apps/client/src/app/app-routing.module.ts + 17 + + + apps/client/src/app/app.component.ts + 59 + + + apps/client/src/app/components/header/header.component.ts + 80 + + + apps/client/src/app/components/header/header.component.ts + 86 + + + apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts + 14 + + + apps/client/src/app/pages/blog/2021/07/hello-ghostfolio/hello-ghostfolio-page.component.ts + 14 + + + apps/client/src/app/pages/blog/2022/07/how-do-i-get-my-finances-in-order/how-do-i-get-my-finances-in-order-page.component.ts + 13 + + + apps/client/src/app/pages/blog/2023/05/unlock-your-financial-potential-with-ghostfolio/unlock-your-financial-potential-with-ghostfolio-page.component.ts + 14 + + + apps/client/src/app/pages/features/features-page.component.ts + 19 + + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.component.ts + 14 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/allinvestview-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/allvue-systems-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/altoo-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/basil-finance-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/beanvest-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/capitally-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/capmon-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/compound-planning-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/copilot-money-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/de.fi-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/delta-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/divvydiary-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/eightfigures-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/empower-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/exirio-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/fina-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/finary-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/finwise-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/folishare-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/getquin-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/gospatz-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/intuit-mint-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/justetf-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/kubera-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/magnifi-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/markets.sh-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/maybe-finance-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/monarch-money-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/monse-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/parqet-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/plannix-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/portfolio-dividend-tracker-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/portseido-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/projectionlab-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/rocket-money-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/seeking-alpha-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/sharesight-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/simple-portfolio-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/snowball-analytics-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockle-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/stockmarketeye-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/sumio-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/tiller-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/utluna-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/vyzer-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/wealthfolio-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/wealthica-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/whal-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/yeekatee-page.component.ts + 29 + + + apps/client/src/app/pages/resources/personal-finance-tools/products/ynab-page.component.ts + 29 + + + apps/client/src/app/pages/resources/resources-page.component.ts + 19 + + + + You are using the Live Demo. + 您正在使用现场演示。 + + apps/client/src/app/app.component.html + 17 + + + + Create Account + 创建账户 + + apps/client/src/app/app.component.html + 18 + + + apps/client/src/app/pages/register/register-page.html + 26 + + + apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html + 2 + + + + Personal Finance + 个人财务 + + apps/client/src/app/app.component.html + 55 + + + + Markets + 市场 + + apps/client/src/app/app.component.html + 58 + + + apps/client/src/app/components/header/header.component.html + 381 + + + apps/client/src/app/components/home-market/home-market.html + 2 + + + apps/client/src/app/pages/resources/resources-page.html + 56 + + + + Resources + 资源 + + apps/client/src/app/app.component.html + 60 + + + apps/client/src/app/components/header/header.component.html + 80 + + + apps/client/src/app/components/header/header.component.html + 284 + + + apps/client/src/app/pages/resources/resources-page.html + 4 + + + + About + 关于 + + apps/client/src/app/app.component.html + 66 + + + apps/client/src/app/components/header/header.component.html + 111 + + + apps/client/src/app/components/header/header.component.html + 352 + + + + Blog + 博客 + + apps/client/src/app/app.component.html + 68 + + + apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.html + 204 + + + apps/client/src/app/pages/blog/2021/07/hello-ghostfolio/hello-ghostfolio-page.html + 183 + + + apps/client/src/app/pages/blog/2022/01/first-months-in-open-source/first-months-in-open-source-page.html + 183 + + + apps/client/src/app/pages/blog/2022/07/ghostfolio-meets-internet-identity/ghostfolio-meets-internet-identity-page.html + 183 + + + apps/client/src/app/pages/blog/2022/07/how-do-i-get-my-finances-in-order/how-do-i-get-my-finances-in-order-page.html + 209 + + + apps/client/src/app/pages/blog/2022/08/500-stars-on-github/500-stars-on-github-page.html + 195 + + + apps/client/src/app/pages/blog/2022/10/hacktoberfest-2022/hacktoberfest-2022-page.html + 181 + + + apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.html + 141 + + + apps/client/src/app/pages/blog/2022/12/the-importance-of-tracking-your-personal-finances/the-importance-of-tracking-your-personal-finances-page.html + 168 + + + apps/client/src/app/pages/blog/2023/01/ghostfolio-auf-sackgeld-vorgestellt/ghostfolio-auf-sackgeld-vorgestellt-page.html + 178 + + + apps/client/src/app/pages/blog/2023/02/ghostfolio-meets-umbrel/ghostfolio-meets-umbrel-page.html + 202 + + + apps/client/src/app/pages/blog/2023/03/1000-stars-on-github/1000-stars-on-github-page.html + 252 + + + apps/client/src/app/pages/blog/2023/05/unlock-your-financial-potential-with-ghostfolio/unlock-your-financial-potential-with-ghostfolio-page.html + 233 + + + apps/client/src/app/pages/blog/2023/07/exploring-the-path-to-fire/exploring-the-path-to-fire-page.html + 243 + + + apps/client/src/app/pages/blog/2023/08/ghostfolio-joins-oss-friends/ghostfolio-joins-oss-friends-page.html + 154 + + + apps/client/src/app/pages/blog/2023/09/ghostfolio-2/ghostfolio-2-page.html + 273 + + + apps/client/src/app/pages/blog/2023/09/hacktoberfest-2023/hacktoberfest-2023-page.html + 181 + + + apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.html + 148 + + + apps/client/src/app/pages/blog/2023/11/hacktoberfest-2023-debriefing/hacktoberfest-2023-debriefing-page.html + 270 + + + apps/client/src/app/pages/blog/blog-page.html + 5 + + + + Changelog + 变更日志 + + apps/client/src/app/app.component.html + 71 + + + apps/client/src/app/pages/about/changelog/changelog-page.html + 4 + + + + Features + 功能 + + apps/client/src/app/app.component.html + 73 + + + apps/client/src/app/components/header/header.component.html + 339 + + + apps/client/src/app/pages/features/features-page.html + 5 + + + + Frequently Asked Questions (FAQ) + 常见问题 (FAQ) + + apps/client/src/app/app.component.html + 76 + + + apps/client/src/app/pages/about/overview/about-overview-page.html + 146 + + + + License + 许可 + + apps/client/src/app/app.component.html + 80 + + + apps/client/src/app/pages/about/license/license-page.html + 4 + + + + Pricing + 价钱 + + apps/client/src/app/app.component.html + 86 + + + apps/client/src/app/components/header/header.component.html + 98 + + + apps/client/src/app/components/header/header.component.html + 296 + + + apps/client/src/app/components/header/header.component.html + 365 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 188 + + + + Privacy Policy + 隐私政策 + + apps/client/src/app/app.component.html + 90 + + + apps/client/src/app/pages/about/privacy-policy/privacy-policy-page.html + 4 + + + + Community + 社区 + + apps/client/src/app/app.component.html + 105 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 80 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 84 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 88 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 92 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 96 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 100 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 104 + + + apps/client/src/app/pages/features/features-page.html + 256 + + + + The risk of loss in trading can be substantial. It is not advisable to invest money you may need in the short term. + 交易损失的风险可能很大。不建议将短期内可能需要的资金进行投资。 + + apps/client/src/app/app.component.html + 179 + + + + Alias + 别名 + + apps/client/src/app/components/access-table/access-table.component.html + 3 + + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 11 + + + + Grantee + 受赠者 + + apps/client/src/app/components/access-table/access-table.component.html + 10 + + + + Type + 类型 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 28 + + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 22 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 12 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 159 + + + + Details + 细节 + + apps/client/src/app/components/access-table/access-table.component.html + 32 + + + + Revoke + 撤销 + + apps/client/src/app/components/access-table/access-table.component.html + 59 + + + + Do you really want to revoke this granted access? + 您真的要撤销此授予的访问权限吗? + + apps/client/src/app/components/access-table/access-table.component.ts + 50 + + + + Cash Balance + 现金余额 + + apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html + 45 + + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 117 + + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 34 + + + + Equity + 公平 + + apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html + 56 + + + + Activities + 活动 + + apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html + 61 + + + apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html + 90 + + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 100 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 122 + + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 44 + + + apps/client/src/app/components/admin-users/admin-users.html + 134 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 178 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 287 + + + apps/client/src/app/pages/portfolio/activities/activities-page.html + 4 + + + + Platform + 平台 + + apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html + 65 + + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 72 + + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 48 + + + + Cash Balances + 现金余额 + + apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html + 114 + + + + Transfer Cash Balance + 转移现金余额 + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 9 + + + apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.html + 7 + + + + Name + 名称 + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 34 + + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 38 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 197 + + + apps/client/src/app/components/admin-platform/admin-platform.component.html + 30 + + + apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html + 7 + + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 30 + + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 7 + + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 15 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 138 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 136 + + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 28 + + + + Total + 全部的 + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 45 + + + + Currency + 货币 + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 55 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 103 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 203 + + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 25 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 144 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 274 + + + + Value + 价值 + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 152 + + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 187 + + + apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.html + 45 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 198 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 199 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 201 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 263 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 264 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 265 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 266 + + + libs/ui/src/lib/account-balances/account-balances.component.html + 20 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 255 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 291 + + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 74 + + + + Edit + 编辑 + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 254 + + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 175 + + + apps/client/src/app/components/admin-overview/admin-overview.html + 80 + + + apps/client/src/app/components/admin-platform/admin-platform.component.html + 91 + + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 71 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 428 + + + + Delete + 删除 + + apps/client/src/app/components/accounts-table/accounts-table.component.html + 264 + + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 190 + + + apps/client/src/app/components/admin-overview/admin-overview.html + 90 + + + apps/client/src/app/components/admin-overview/admin-overview.html + 199 + + + apps/client/src/app/components/admin-platform/admin-platform.component.html + 101 + + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 81 + + + libs/ui/src/lib/account-balances/account-balances.component.html + 51 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 450 + + + + Do you really want to delete this account? + 您真的要删除该帐户吗? + + apps/client/src/app/components/accounts-table/accounts-table.component.ts + 101 + + + + Asset Profile + 资产概况 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 31 + + + + Historical Market Data + 历史市场数据 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 37 + + + + Symbol + 符号 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 45 + + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 24 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 98 + + + apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html + 34 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 257 + + + + Data Source + 数据源 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 54 + + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 51 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 154 + + + + Attempts + 尝试 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 63 + + + + Created + 创建 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 72 + + + + Finished + 完成的 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 81 + + + + Status + 状况 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 90 + + + + Delete Jobs + 删除作业 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 126 + + + + View Data + 查看数据 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 141 + + + + View Stacktrace + 查看堆栈跟踪 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 148 + + + + Delete Job + 删除作业 + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 151 + + + + Details for + 详细信息 + + apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html + 2 + + + + Date + 日期 + + apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html + 6 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 160 + + + libs/ui/src/lib/account-balances/account-balances.component.html + 11 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 168 + + + + Market Price + 市场价 + + apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html + 26 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 81 + + + + Cancel + 取消 + + apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html + 46 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 330 + + + apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html + 40 + + + apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html + 19 + + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 13 + + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 60 + + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 103 + + + apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.html + 57 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 412 + + + apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html + 38 + + + + Save + 保存 + + apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html + 48 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 337 + + + apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html + 47 + + + apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html + 26 + + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 20 + + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 67 + + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 110 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 419 + + + + Currencies + 货币 + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 67 + + + + ETFs without Countries + 没有国家的 ETF + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 72 + + + + ETFs without Sectors + 无行业类别的 ETF + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 77 + + + + Do you really want to delete this asset profile? + 您确实要删除此资产配置文件吗? + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 185 + + + + Filter by... + 过滤... + + apps/client/src/app/components/admin-market-data/admin-market-data.component.ts + 282 + + + + Asset Class + 资产类别 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 60 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 131 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 212 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 184 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 338 + + + + Asset Sub Class + 资产子类别 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 69 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 140 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 225 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 193 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 354 + + + + First Activity + 第一个活动 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 78 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 113 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 166 + + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 50 + + + + Activities Count + 活动计数 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 87 + + + + Historical Data + 历史数据 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 96 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 65 + + + + Sectors Count + 行业数 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 105 + + + + Countries Count + 国家数 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 114 + + + + Gather Recent Data + 收集最近的数据 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 144 + + + + Gather All Data + 收集所有数据 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 147 + + + + Gather Profile Data + 收集个人资料数据 + + apps/client/src/app/components/admin-market-data/admin-market-data.html + 150 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 45 + + + + Oops! Could not parse historical data. + 哎呀!无法解析历史数据。 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts + 223 + + + + Refresh + 刷新 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 22 + + + + Gather Historical Data + 收集历史数据 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 32 + + + + Import + 导入 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 91 + + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 154 + + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 189 + + + + Sector + 行业 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 159 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 210 + + + + Country + 国家 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 168 + + + apps/client/src/app/components/admin-users/admin-users.html + 77 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 220 + + + + Sectors + 行业 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 173 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 295 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 226 + + + apps/client/src/app/pages/public/public-page.html + 45 + + + + Countries + 国家 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 183 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 306 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 238 + + + + Benchmark + 基准 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 253 + + + + Symbol Mapping + 符号映射 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 259 + + + + Scraper Configuration + 刮削配置 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 270 + + + + Note + 笔记 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 317 + + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 78 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 323 + + + + Add Asset Profile + 添加资产概况 + + apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html + 7 + + + + Search + 搜索 + + apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html + 16 + + + + Add Manually + 手动添加 + + apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html + 19 + + + + Name, symbol or ISIN + 名称、符号或 ISIN + + apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html + 25 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 122 + + + + Please add a currency: + 请添加货币: + + apps/client/src/app/components/admin-overview/admin-overview.component.ts + 122 + + + + is an invalid currency! + 是无效的货币! + + apps/client/src/app/components/admin-overview/admin-overview.component.ts + 129 + + + + Do you really want to delete this coupon? + 您确实要删除此优惠券吗? + + apps/client/src/app/components/admin-overview/admin-overview.component.ts + 140 + + + + Do you really want to delete this currency? + 您真的要删除该货币吗? + + apps/client/src/app/components/admin-overview/admin-overview.component.ts + 153 + + + + Do you really want to delete this system message? + 您真的要删除这条系统消息吗? + + apps/client/src/app/components/admin-overview/admin-overview.component.ts + 166 + + + + Do you really want to flush the cache? + 您真的要刷新缓存吗? + + apps/client/src/app/components/admin-overview/admin-overview.component.ts + 183 + + + + Please set your system message: + 请设置您的系统消息: + + apps/client/src/app/components/admin-overview/admin-overview.component.ts + 214 + + + + Version + 版本 + + apps/client/src/app/components/admin-overview/admin-overview.html + 7 + + + + User Count + 用户数 + + apps/client/src/app/components/admin-overview/admin-overview.html + 13 + + + + Activity Count + 活动计数 + + apps/client/src/app/components/admin-overview/admin-overview.html + 23 + + + + per User + 每位用户 + + apps/client/src/app/components/admin-overview/admin-overview.html + 32 + + + + Exchange Rates + 汇率 + + apps/client/src/app/components/admin-overview/admin-overview.html + 37 + + + + Add Currency + 添加货币 + + apps/client/src/app/components/admin-overview/admin-overview.html + 104 + + + + User Signup + 用户注册 + + apps/client/src/app/components/admin-overview/admin-overview.html + 110 + + + + Read-only Mode + 只读模式 + + apps/client/src/app/components/admin-overview/admin-overview.html + 123 + + + + System Message + 系统信息 + + apps/client/src/app/components/admin-overview/admin-overview.html + 145 + + + + Set Message + 设置留言 + + apps/client/src/app/components/admin-overview/admin-overview.html + 165 + + + + Coupons + 优惠券 + + apps/client/src/app/components/admin-overview/admin-overview.html + 173 + + + + Add + 添加 + + apps/client/src/app/components/admin-overview/admin-overview.html + 231 + + + + Housekeeping + 家政 + + apps/client/src/app/components/admin-overview/admin-overview.html + 238 + + + + Flush Cache + 刷新缓存 + + apps/client/src/app/components/admin-overview/admin-overview.html + 242 + + + + Add Platform + 添加平台 + + apps/client/src/app/components/admin-platform/admin-platform.component.html + 11 + + + + Url + 网址 + + apps/client/src/app/components/admin-platform/admin-platform.component.html + 50 + + + apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html + 13 + + + + Accounts + 帐户 + + apps/client/src/app/components/admin-platform/admin-platform.component.html + 64 + + + apps/client/src/app/components/admin-users/admin-users.html + 113 + + + apps/client/src/app/components/header/header.component.html + 54 + + + apps/client/src/app/components/header/header.component.html + 257 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 312 + + + apps/client/src/app/pages/accounts/accounts-page.html + 4 + + + libs/ui/src/lib/assistant/assistant.html + 107 + + + + Do you really want to delete this platform? + 您真的要删除这个平台吗? + + apps/client/src/app/components/admin-platform/admin-platform.component.ts + 79 + + + + Update platform + 更新平台 + + apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html + 2 + + + + Add platform + 添加平台 + + apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html + 3 + + + + Platforms + 平台 + + apps/client/src/app/components/admin-settings/admin-settings.component.html + 4 + + + + Tags + 标签 + + apps/client/src/app/components/admin-settings/admin-settings.component.html + 10 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 332 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 367 + + + libs/ui/src/lib/assistant/assistant.html + 127 + + + + Add Tag + 添加标签 + + apps/client/src/app/components/admin-tag/admin-tag.component.html + 11 + + + + Do you really want to delete this tag? + 您真的要删除此标签吗? + + apps/client/src/app/components/admin-tag/admin-tag.component.ts + 79 + + + + Update tag + 更新标签 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 2 + + + + Add tag + 添加标签 + + apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html + 3 + + + + Do you really want to delete this user? + 您真的要删除该用户吗? + + apps/client/src/app/components/admin-users/admin-users.component.ts + 113 + + + + User + 用户 + + apps/client/src/app/components/admin-users/admin-users.html + 29 + + + + Registration + 注册 + + apps/client/src/app/components/admin-users/admin-users.html + 96 + + + + Engagement per Day + 每天的参与度 + + apps/client/src/app/components/admin-users/admin-users.html + 158 + + + + Last Request + 最后请求 + + apps/client/src/app/components/admin-users/admin-users.html + 183 + + + + Impersonate User + 模拟用户 + + apps/client/src/app/components/admin-users/admin-users.html + 222 + + + + Delete User + 删除用户 + + apps/client/src/app/components/admin-users/admin-users.html + 232 + + + + Performance + 表现 + + apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html + 6 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 59 + + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 119 + + + + Compare with... + 与之比较... + + apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html + 19 + + + + Manage Benchmarks + 管理基准 + + apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.html + 38 + + + + Portfolio + 文件夹 + + apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts + 110 + + + apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts + 48 + + + + Benchmark + 基准 + + apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts + 119 + + + + Current Market Mood + 当前市场情绪 + + apps/client/src/app/components/fear-and-greed-index/fear-and-greed-index.component.html + 12 + + + + Overview + 概述 + + apps/client/src/app/components/header/header.component.html + 28 + + + apps/client/src/app/components/header/header.component.html + 239 + + + + Portfolio + 文件夹 + + apps/client/src/app/components/header/header.component.html + 41 + + + apps/client/src/app/components/header/header.component.html + 249 + + + + Admin Control + 管理控制 + + apps/client/src/app/components/header/header.component.html + 67 + + + apps/client/src/app/components/header/header.component.html + 273 + + + + Me + + + apps/client/src/app/components/header/header.component.html + 206 + + + + User + 用户 + + apps/client/src/app/components/header/header.component.html + 225 + + + + My Ghostfolio + 我的 Ghostfolio + + apps/client/src/app/components/header/header.component.html + 264 + + + + About Ghostfolio + 关于 Ghostfolio + + apps/client/src/app/components/header/header.component.html + 304 + + + apps/client/src/app/pages/about/overview/about-overview-page.html + 5 + + + + Sign in + 登入 + + apps/client/src/app/components/header/header.component.html + 394 + + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 71 + + + + Get started + 开始使用 + + apps/client/src/app/components/header/header.component.html + 406 + + + + Sign in + 登入 + + apps/client/src/app/components/header/header.component.ts + 226 + + + apps/client/src/app/pages/webauthn/webauthn-page-routing.module.ts + 7 + + + + Oops! Incorrect Security Token. + 哎呀!安全令牌不正确。 + + apps/client/src/app/components/header/header.component.ts + 240 + + + + Manage Activities + 管理活动 + + apps/client/src/app/components/home-holdings/home-holdings.html + 22 + + + apps/client/src/app/pages/portfolio/holdings/holdings-page.html + 32 + + + + Fear + 恐惧 + + apps/client/src/app/components/home-market/home-market.component.ts + 25 + + + libs/ui/src/lib/i18n.ts + 69 + + + + Greed + 贪婪 + + apps/client/src/app/components/home-market/home-market.component.ts + 26 + + + libs/ui/src/lib/i18n.ts + 70 + + + + Last Days + 最后的 + + apps/client/src/app/components/home-market/home-market.html + 6 + + + + Welcome to Ghostfolio + 欢迎来到Ghostfolio + + apps/client/src/app/components/home-overview/home-overview.html + 7 + + + + Ready to take control of your personal finances? + 准备好掌控您的个人财务了吗? + + apps/client/src/app/components/home-overview/home-overview.html + 8 + + + + Setup your accounts + 设置您的帐户 + + apps/client/src/app/components/home-overview/home-overview.html + 15 + + + + Get a comprehensive financial overview by adding your bank and brokerage accounts. + 通过添加您的银行和经纪账户来获取全面的财务概览。 + + apps/client/src/app/components/home-overview/home-overview.html + 17 + + + + Capture your activities + 记录你的活动 + + apps/client/src/app/components/home-overview/home-overview.html + 24 + + + + Record your investment activities to keep your portfolio up to date. + 记录您的投资活动以使您的投资组合保持最新状态。 + + apps/client/src/app/components/home-overview/home-overview.html + 26 + + + + Monitor and analyze your portfolio + 监控和分析您的投资组合 + + apps/client/src/app/components/home-overview/home-overview.html + 33 + + + + Track your progress in real-time with comprehensive analysis and insights. + 通过全面的分析和见解实时跟踪您的进度。 + + apps/client/src/app/components/home-overview/home-overview.html + 35 + + + + Setup accounts + 设置帐户 + + apps/client/src/app/components/home-overview/home-overview.html + 48 + + + + Add activity + 添加活动 + + apps/client/src/app/components/home-overview/home-overview.html + 56 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 8 + + + + This feature requires a subscription. + 此功能需要订阅。 + + apps/client/src/app/components/home-summary/home-summary.component.ts + 113 + + + apps/client/src/app/core/http-response.interceptor.ts + 68 + + + + Upgrade Plan + 升级计划 + + apps/client/src/app/components/home-summary/home-summary.component.ts + 115 + + + apps/client/src/app/core/http-response.interceptor.ts + 70 + + + + Summary + 概括 + + apps/client/src/app/components/home-summary/home-summary.html + 2 + + + + Total Amount + 总金额 + + apps/client/src/app/components/investment-chart/investment-chart.component.ts + 191 + + + + Savings Rate + 储蓄率 + + apps/client/src/app/components/investment-chart/investment-chart.component.ts + 263 + + + + Security Token + 安全令牌 + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 11 + + + apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html + 10 + + + + or + + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 31 + + + apps/client/src/app/pages/landing/landing-page.html + 429 + + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 99 + + + apps/client/src/app/pages/register/register-page.html + 29 + + + apps/client/src/app/pages/webauthn/webauthn-page.html + 29 + + + + Sign in with Internet Identity + 使用互联网身份登录 + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 42 + + + + Sign in with Google + 使用 Google 登录 + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 52 + + + + Stay signed in + 保持登录 + + apps/client/src/app/components/login-with-access-token-dialog/login-with-access-token-dialog.html + 61 + + + + Time in Market + 上市时间 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 3 + + + + + + + + + + + + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 12 + + + + {VAR_PLURAL, plural, =1 {transaction} other {transactions}} + {VAR_PLURAL,复数,=1 {交易} 其他{交易}} + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 14 + + + + Buy + + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 21 + + + + Sell + + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 33 + + + + Investment + 投资 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 48 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 134 + + + + Absolute Gross Performance + 绝对总业绩 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 60 + + + + Gross Performance + 总表现 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 77 + + + + Fees + 费用 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 100 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 156 + + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 161 + + + + Absolute Net Performance + 绝对净绩效 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 116 + + + + Net Performance + 净绩效 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 133 + + + + Total Assets + 总资产 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 159 + + + + Valuables + 贵重物品 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 172 + + + + Emergency Fund + 应急基金 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 184 + + + apps/client/src/app/pages/features/features-page.html + 89 + + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 122 + + + + Cash + 现金 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 205 + + + + Assets + 资产 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 218 + + + + Buying Power + 购买力 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 231 + + + + Excluded from Analysis + 从分析中排除 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 243 + + + + Liabilities + 负债 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 258 + + + apps/client/src/app/pages/features/features-page.html + 102 + + + + Net Worth + 净值 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 278 + + + + Annualized Performance + 年化业绩 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 290 + + + + Interest + 利息 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 312 + + + + Dividend + 股息 + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 324 + + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 145 + + + apps/client/src/app/pages/features/features-page.html + 63 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 196 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 261 + + + + Please enter the amount of your emergency fund: + 请输入您的应急基金金额: + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts + 53 + + + + Change + 修改 + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 48 + + + + Average Unit Price + 平均单价 + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 70 + + + + Minimum Price + 最低价格 + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 97 + + + + Maximum Price + 最高价格 + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 113 + + + + Quantity + 数量 + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 123 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 183 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 184 + + + + Report Data Glitch + 报告数据故障 + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 350 + + + + Are you an ambitious investor who needs the full picture? + 您是一位雄心勃勃、需要全面了解的投资者吗? + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 12 + + + + Upgrade to Ghostfolio Premium today and gain access to exclusive features to enhance your investment experience: + 立即升级至 Ghostfolio Premium 并获得独家功能,以增强您的投资体验: + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 15 + + + + Portfolio Summary + 投资组合摘要 + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 22 + + + apps/client/src/app/pages/pricing/pricing-page.html + 55 + + + apps/client/src/app/pages/pricing/pricing-page.html + 199 + + + + Portfolio Allocations + 投资组合分配 + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 26 + + + apps/client/src/app/pages/features/features-page.html + 160 + + + apps/client/src/app/pages/pricing/pricing-page.html + 59 + + + apps/client/src/app/pages/pricing/pricing-page.html + 203 + + + + Performance Benchmarks + 性能基准 + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 30 + + + apps/client/src/app/pages/pricing/pricing-page.html + 63 + + + apps/client/src/app/pages/pricing/pricing-page.html + 207 + + + + FIRE Calculator + 财务自由计算器 + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 34 + + + apps/client/src/app/pages/pricing/pricing-page.html + 67 + + + apps/client/src/app/pages/pricing/pricing-page.html + 211 + + + + Professional Data Provider + 专业数据提供商 + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 38 + + + apps/client/src/app/pages/pricing/pricing-page.html + 226 + + + + and more Features... + 以及更多功能... + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 42 + + + apps/client/src/app/pages/pricing/pricing-page.html + 83 + + + apps/client/src/app/pages/pricing/pricing-page.html + 231 + + + + Get the tools to effectively manage your finances and refine your personal investment strategy. + 获取有效管理财务和完善个人投资策略的工具。 + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 45 + + + + Skip + 跳过 + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 52 + + + + Upgrade Plan + 升级计划 + + apps/client/src/app/components/header/header.component.html + 177 + + + apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.html + 59 + + + apps/client/src/app/components/user-account-membership/user-account-membership.html + 20 + + + apps/client/src/app/pages/pricing/pricing-page.html + 268 + + + + Today + 今天 + + apps/client/src/app/components/toggle/toggle.component.ts + 22 + + + libs/ui/src/lib/assistant/assistant.component.ts + 99 + + + + YTD + 年初至今 + + apps/client/src/app/components/toggle/toggle.component.ts + 23 + + + libs/ui/src/lib/assistant/assistant.component.ts + 109 + + + + 1Y + 1年 + + apps/client/src/app/components/toggle/toggle.component.ts + 24 + + + libs/ui/src/lib/assistant/assistant.component.ts + 112 + + + + 5Y + 5年 + + apps/client/src/app/components/toggle/toggle.component.ts + 25 + + + libs/ui/src/lib/assistant/assistant.component.ts + 114 + + + + Max + 最大限度 + + apps/client/src/app/components/toggle/toggle.component.ts + 26 + + + libs/ui/src/lib/assistant/assistant.component.ts + 117 + + + + Grant access + 授予访问权限 + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 7 + + + + Public + 公开 + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 25 + + + + Granted Access + 授予访问权限 + + apps/client/src/app/components/user-account-access/user-account-access.html + 5 + + + + Please enter your coupon code: + 请输入您的优惠券代码: + + apps/client/src/app/components/user-account-membership/user-account-membership.component.ts + 111 + + + + Could not redeem coupon code + 无法兑换优惠券代码 + + apps/client/src/app/components/user-account-membership/user-account-membership.component.ts + 121 + + + + Coupon code has been redeemed + 优惠券代码已兑换 + + apps/client/src/app/components/user-account-membership/user-account-membership.component.ts + 133 + + + + Reload + 重新加载 + + apps/client/src/app/components/user-account-membership/user-account-membership.component.ts + 134 + + + + per year + 每年 + + apps/client/src/app/components/user-account-membership/user-account-membership.html + 41 + + + apps/client/src/app/pages/pricing/pricing-page.html + 254 + + + + Try Premium + 尝试高级版 + + apps/client/src/app/components/user-account-membership/user-account-membership.html + 50 + + + + Redeem Coupon + 兑换优惠券 + + apps/client/src/app/components/user-account-membership/user-account-membership.html + 63 + + + + Auto + 自动 + + apps/client/src/app/components/user-account-settings/user-account-settings.component.ts + 33 + + + + Do you really want to remove this sign in method? + 您确实要删除此登录方法吗? + + apps/client/src/app/components/user-account-settings/user-account-settings.component.ts + 188 + + + + Settings + 设置 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 2 + + + + Presenter View + 演示者视图 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 7 + + + + Protection for sensitive information like absolute performances and quantity values + 保护绝对性能和数量值等敏感信息 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 8 + + + + Base Currency + 基础货币 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 27 + + + + Language + 语言 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 50 + + + + Locale + 语言环境 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 113 + + + + Date and number format + 日期和数字格式 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 115 + + + + Appearance + 外貌 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 138 + + + + Auto + 自动 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 152 + + + + Light + 明亮 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 153 + + + + Dark + 黑暗 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 154 + + + + Zen Mode + 极简模式 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 163 + + + apps/client/src/app/pages/features/features-page.html + 190 + + + + Distraction-free experience for turbulent times + 动荡时期的无干扰体验 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 164 + + + + Biometric Authentication + 生物识别认证 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 180 + + + + Sign in with fingerprint + 使用指纹登录 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 181 + + + + Experimental Features + 实验性功能 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 198 + + + + Sneak peek at upcoming functionality + 预览即将推出的功能 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 199 + + + + User ID + 用户身份 + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 47 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 215 + + + + Export Data + 导出数据 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 223 + + + + This feature is currently unavailable. + 此功能目前无法使用。 + + apps/client/src/app/core/http-response.interceptor.ts + 60 + + + + Please try again later. + 请稍后再试。 + + apps/client/src/app/core/http-response.interceptor.ts + 62 + + + apps/client/src/app/core/http-response.interceptor.ts + 89 + + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts + 138 + + + + Oops! Something went wrong. + 哎呀!出了些问题。 + + apps/client/src/app/core/http-response.interceptor.ts + 87 + + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts + 136 + + + + Okay + 好的 + + apps/client/src/app/core/http-response.interceptor.ts + 90 + + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts + 139 + + + + About + 关于 + + apps/client/src/app/pages/about/about-page-routing.module.ts + 51 + + + apps/client/src/app/pages/about/about-page.component.ts + 44 + + + apps/client/src/app/pages/about/overview/about-overview-page-routing.module.ts + 13 + + + + Changelog + 更新日志 + + apps/client/src/app/pages/about/about-page.component.ts + 49 + + + apps/client/src/app/pages/about/changelog/changelog-page-routing.module.ts + 13 + + + + License + 许可 + + apps/client/src/app/pages/about/about-page.component.ts + 54 + + + apps/client/src/app/pages/about/license/license-page-routing.module.ts + 13 + + + + Privacy Policy + 隐私政策 + + apps/client/src/app/pages/about/about-page.component.ts + 62 + + + apps/client/src/app/pages/about/privacy-policy/privacy-policy-page-routing.module.ts + 13 + + + + Our + 我们的 + + apps/client/src/app/pages/about/oss-friends/oss-friends-page.html + 6 + + + + Discover other exciting Open Source Software projects + 发现其他令人兴奋的开源软件项目 + + apps/client/src/app/pages/about/oss-friends/oss-friends-page.html + 9 + + + + Visit + 访问 + + apps/client/src/app/pages/about/oss-friends/oss-friends-page.html + 28 + + + + Accounts + 账户 + + apps/client/src/app/pages/accounts/accounts-page-routing.module.ts + 13 + + + + Oops, cash balance transfer has failed. + 糟糕,现金余额转账失败。 + + apps/client/src/app/pages/accounts/accounts-page.component.ts + 306 + + + + Update account + 更新账户 + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 8 + + + + Add account + 新增帐户 + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 10 + + + + Account ID + 帐户ID + + apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html + 96 + + + + From + + + apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.html + 11 + + + + To + + + apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.html + 28 + + + + Transfer + 转移 + + apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.html + 64 + + + + Admin Control + 管理控制 + + apps/client/src/app/pages/admin/admin-page-routing.module.ts + 20 + + + + Market Data + 市场数据 + + apps/client/src/app/pages/admin/admin-page-routing.module.ts + 30 + + + apps/client/src/app/pages/admin/admin-page.component.ts + 37 + + + + Settings + 设置 + + apps/client/src/app/pages/admin/admin-page-routing.module.ts + 35 + + + apps/client/src/app/pages/admin/admin-page.component.ts + 32 + + + apps/client/src/app/pages/user-account/user-account-page-routing.module.ts + 18 + + + apps/client/src/app/pages/user-account/user-account-page.component.ts + 35 + + + + Users + 用户 + + apps/client/src/app/pages/admin/admin-page-routing.module.ts + 40 + + + apps/client/src/app/pages/admin/admin-page.component.ts + 47 + + + + Overview + 概述 + + apps/client/src/app/pages/admin/admin-page.component.ts + 27 + + + apps/client/src/app/pages/home/home-page.component.ts + 34 + + + apps/client/src/app/pages/zen/zen-page-routing.module.ts + 19 + + + apps/client/src/app/pages/zen/zen-page.component.ts + 34 + + + + Blog + 博客 + + apps/client/src/app/pages/blog/blog-page-routing.module.ts + 13 + + + + Discover the latest Ghostfolio updates and insights on personal finance + 了解最新的 Ghostfolio 更新和个人理财见解 + + apps/client/src/app/pages/blog/blog-page.html + 7 + + + + As you are already logged in, you cannot access the demo account. + 由于您已经登录,因此无法访问模拟帐户。 + + apps/client/src/app/pages/demo/demo-page.component.ts + 32 + + + + Frequently Asked Questions (FAQ) + 常见问题 (FAQ) + + apps/client/src/app/pages/faq/faq-page-routing.module.ts + 34 + + + apps/client/src/app/pages/faq/overview/faq-overview-page-routing.module.ts + 13 + + + + Frequently Asked Questions (FAQ) + 常见问题 (FAQ) + + apps/client/src/app/pages/faq/overview/faq-overview-page.html + 4 + + + apps/client/src/app/pages/faq/saas/saas-page.html + 4 + + + apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html + 4 + + + + Features + 功能 + + apps/client/src/app/pages/features/features-page-routing.module.ts + 13 + + + + Check out the numerous features of Ghostfolio to manage your wealth + 查看 Ghostfolio 的众多功能来管理您的财富 + + apps/client/src/app/pages/features/features-page.html + 6 + + + + Stocks + 股票 + + apps/client/src/app/pages/features/features-page.html + 15 + + + + ETFs + ETF + + apps/client/src/app/pages/features/features-page.html + 25 + + + + Bonds + 债券 + + apps/client/src/app/pages/features/features-page.html + 38 + + + + Cryptocurrencies + 加密货币 + + apps/client/src/app/pages/features/features-page.html + 51 + + + + Wealth Items + 财富项目 + + apps/client/src/app/pages/features/features-page.html + 76 + + + + Import and Export + 导入和导出 + + apps/client/src/app/pages/features/features-page.html + 115 + + + + Multi-Accounts + 多账户 + + apps/client/src/app/pages/features/features-page.html + 127 + + + + Portfolio Calculations + 投资组合计算 + + apps/client/src/app/pages/features/features-page.html + 141 + + + + Dark Mode + 深色模式 + + apps/client/src/app/pages/features/features-page.html + 177 + + + + Market Mood + 市场情绪 + + apps/client/src/app/pages/features/features-page.html + 205 + + + + Static Analysis + 静态分析 + + apps/client/src/app/pages/features/features-page.html + 224 + + + + Multi-Language + 多语言 + + apps/client/src/app/pages/features/features-page.html + 241 + + + + Open Source Software + 开源软件 + + apps/client/src/app/pages/features/features-page.html + 275 + + + + Get Started + 立即开始 + + apps/client/src/app/pages/features/features-page.html + 300 + + + apps/client/src/app/pages/public/public-page.html + 153 + + + + Holdings + 控股 + + apps/client/src/app/pages/home/home-page-routing.module.ts + 23 + + + apps/client/src/app/pages/home/home-page.component.ts + 39 + + + apps/client/src/app/pages/portfolio/holdings/holdings-page-routing.module.ts + 13 + + + apps/client/src/app/pages/portfolio/portfolio-page.component.ts + 39 + + + apps/client/src/app/pages/zen/zen-page.component.ts + 39 + + + + Summary + 概括 + + apps/client/src/app/pages/home/home-page-routing.module.ts + 28 + + + apps/client/src/app/pages/home/home-page.component.ts + 44 + + + + Markets + 市场 + + apps/client/src/app/pages/home/home-page-routing.module.ts + 33 + + + apps/client/src/app/pages/home/home-page.component.ts + 49 + + + apps/client/src/app/pages/markets/markets-page-routing.module.ts + 13 + + + + Ghostfolio is a personal finance dashboard to keep track of your net worth including cash, stocks, ETFs and cryptocurrencies across multiple platforms. + Ghostfolio 是一个个人财务仪表板,用于跨多个平台跟踪您的净资产,包括现金、股票、ETF 和加密货币。 + + apps/client/src/app/pages/i18n/i18n-page.html + 4 + + + + app, asset, cryptocurrency, dashboard, etf, finance, management, performance, portfolio, software, stock, trading, wealth, web3 + 应用程序、资产、加密货币、仪表板、etf、财务、管理、绩效、投资组合、软件、股票、交易、财富、web3 + + apps/client/src/app/pages/i18n/i18n-page.html + 9 + + + + Open Source Wealth Management Software + 开源财富管理软件 + + apps/client/src/app/pages/i18n/i18n-page.html + 14 + + + + New + 新的 + + apps/client/src/app/pages/landing/landing-page.html + 7 + + + + Manage your wealth like a boss + 像老板一样管理您的财富 + + apps/client/src/app/pages/landing/landing-page.html + 11 + + + + Ghostfolio is a privacy-first, open source dashboard for your personal finances. Break down your asset allocation, know your net worth and make solid, data-driven investment decisions. + Ghostfolio 是一个隐私优先、开源的个人财务仪表板。分解您的资产配置,了解您的净资产并做出可靠的、数据驱动的投资决策。 + + apps/client/src/app/pages/landing/landing-page.html + 15 + + + + Get Started + 开始使用 + + apps/client/src/app/pages/landing/landing-page.html + 47 + + + apps/client/src/app/pages/landing/landing-page.html + 425 + + + + or + + + apps/client/src/app/pages/landing/landing-page.html + 52 + + + + Live Demo + 现场演示 + + apps/client/src/app/pages/landing/landing-page.html + 55 + + + apps/client/src/app/pages/landing/landing-page.html + 430 + + + + Monthly Active Users + 每月活跃用户数 + + apps/client/src/app/pages/landing/landing-page.html + 75 + + + + Stars on GitHub + GitHub 上的星星 + + apps/client/src/app/pages/landing/landing-page.html + 93 + + + apps/client/src/app/pages/open/open-page.html + 103 + + + + Pulls on Docker Hub + 拉动 Docker Hub + + apps/client/src/app/pages/landing/landing-page.html + 111 + + + apps/client/src/app/pages/open/open-page.html + 117 + + + + As seen in + 如图所示 + + apps/client/src/app/pages/landing/landing-page.html + 119 + + + + Protect your assets. Refine your personal investment strategy. + 保护你的资产。完善你的个人投资策略 + + apps/client/src/app/pages/landing/landing-page.html + 221 + + + + Ghostfolio empowers busy people to keep track of stocks, ETFs or cryptocurrencies without being tracked. + Ghostfolio 使忙碌的人们能够在不被追踪的情况下跟踪股票、ETF 或加密货币。 + + apps/client/src/app/pages/landing/landing-page.html + 225 + + + + 360° View + 360° 视角 + + apps/client/src/app/pages/landing/landing-page.html + 236 + + + + Get the full picture of your personal finances across multiple platforms. + 跨多个平台全面了解您的个人财务状况。 + + apps/client/src/app/pages/landing/landing-page.html + 238 + + + + Web3 Ready + Web3 就绪 + + apps/client/src/app/pages/landing/landing-page.html + 247 + + + + Use Ghostfolio anonymously and own your financial data. + 匿名使用 Ghostfolio 并拥有您的财务数据。 + + apps/client/src/app/pages/landing/landing-page.html + 249 + + + + Open Source + 开源 + + apps/client/src/app/pages/landing/landing-page.html + 257 + + + + Benefit from continuous improvements through a strong community. + 通过强大的社区不断改进,从中受益。 + + apps/client/src/app/pages/landing/landing-page.html + 259 + + + + Why Ghostfolio? + 为什么使用Ghostfolio + + apps/client/src/app/pages/landing/landing-page.html + 268 + + + + Ghostfolio is for you if you are... + 如果您符合以下条件,那么 Ghostfolio 适合您... + + apps/client/src/app/pages/landing/landing-page.html + 269 + + + + trading stocks, ETFs or cryptocurrencies on multiple platforms + 在多个平台上交易股票、ETF 或加密货币 + + apps/client/src/app/pages/landing/landing-page.html + 276 + + + + pursuing a buy & hold strategy + 采取买入并持有策略 + + apps/client/src/app/pages/landing/landing-page.html + 282 + + + + interested in getting insights of your portfolio composition + 有兴趣深入了解您的投资组合构成 + + apps/client/src/app/pages/landing/landing-page.html + 287 + + + + valuing privacy and data ownership + 重视隐私和数据所有权 + + apps/client/src/app/pages/landing/landing-page.html + 292 + + + + into minimalism + 进入极简主义 + + apps/client/src/app/pages/landing/landing-page.html + 295 + + + + caring about diversifying your financial resources + 关心您的财务资源多元化 + + apps/client/src/app/pages/landing/landing-page.html + 299 + + + + interested in financial independence + 对财务独立感兴趣 + + apps/client/src/app/pages/landing/landing-page.html + 303 + + + + saying no to spreadsheets in + 对电子表格说不 + + apps/client/src/app/pages/landing/landing-page.html + 307 + + + + still reading this list + 仍在阅读此列表 + + apps/client/src/app/pages/landing/landing-page.html + 310 + + + + Learn more about Ghostfolio + 了解有关 Ghostfolio 的更多信息 + + apps/client/src/app/pages/landing/landing-page.html + 315 + + + + What our users are saying + 我们的什么用户正在说 + + apps/client/src/app/pages/landing/landing-page.html + 323 + + + + Members from around the globe are using Ghostfolio Premium + 来自世界各地的会员正在使用Ghostfolio 高级版 + + apps/client/src/app/pages/landing/landing-page.html + 355 + + + + How does Ghostfolio work? + 如何幽灵作品集工作? + + apps/client/src/app/pages/landing/landing-page.html + 367 + + + + Get started in only 3 steps + 只需 3 步即可开始 + + apps/client/src/app/pages/landing/landing-page.html + 370 + + + + Sign up anonymously* + 匿名注册* + + apps/client/src/app/pages/landing/landing-page.html + 376 + + + + * no e-mail address nor credit card required + * 无需电子邮件地址或信用卡 + + apps/client/src/app/pages/landing/landing-page.html + 378 + + + + Add any of your historical transactions + 添加您的任何历史交易 + + apps/client/src/app/pages/landing/landing-page.html + 389 + + + + Get valuable insights of your portfolio composition + 获取有关您的投资组合构成的宝贵见解 + + apps/client/src/app/pages/landing/landing-page.html + 401 + + + + Are you ready? + 准备好? + + apps/client/src/app/pages/landing/landing-page.html + 413 + + + + Join now or check out the example account + 立即加入或查看示例帐户 + + apps/client/src/app/pages/landing/landing-page.html + 414 + + + + At Ghostfolio, transparency is at the core of our values. We publish the source code as open source software (OSS) under the AGPL-3.0 license and we openly share aggregated key metrics of the platform’s operational status. + 在 Ghostfolio,透明度是我们价值观的核心。我们将源代码发布为开源软件(OSS)下AGPL-3.0许可证我们公开分享平台运营状态的汇总关键指标。 + + apps/client/src/app/pages/open/open-page.html + 6 + + + + (Last 24 hours) + (最近 24 小时) + + apps/client/src/app/pages/open/open-page.html + 37 + + + + Active Users + 活跃用户 + + apps/client/src/app/pages/open/open-page.html + 40 + + + apps/client/src/app/pages/open/open-page.html + 62 + + + + (Last 30 days) + (最近 30 天) + + apps/client/src/app/pages/open/open-page.html + 48 + + + apps/client/src/app/pages/open/open-page.html + 59 + + + + New Users + 新用户 + + apps/client/src/app/pages/open/open-page.html + 51 + + + + Users in Slack community + Slack 社区的用户 + + apps/client/src/app/pages/open/open-page.html + 75 + + + + Contributors on GitHub + GitHub 上的贡献者 + + apps/client/src/app/pages/open/open-page.html + 89 + + + + (Last 90 days) + (过去 90 天) + + apps/client/src/app/pages/open/open-page.html + 127 + + + + Uptime + 正常运行时间 + + apps/client/src/app/pages/open/open-page.html + 132 + + + + Activities + 活动 + + apps/client/src/app/pages/portfolio/activities/activities-page-routing.module.ts + 13 + + + apps/client/src/app/pages/portfolio/portfolio-page.component.ts + 44 + + + + Do you really want to delete all your activities? + 您真的要删除所有活动吗? + + apps/client/src/app/pages/portfolio/activities/activities-page.component.ts + 168 + + + + Update activity + 更新活动 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 7 + + + + Stocks, ETFs, bonds, cryptocurrencies, commodities + 股票、ETF、债券、加密货币、大宗商品 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 22 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 62 + + + + One-time fee, annual account fees + 一次性费用、年度账户费用 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 30 + + + + Distribution of corporate earnings + 企业盈利分配 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 38 + + + + Revenue for lending out money + 放贷收入 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 46 + + + + Mortgages, personal loans, credit cards + 抵押贷款、个人贷款、信用卡 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 54 + + + + Luxury items, real estate, private companies + 奢侈品、房地产、私营公司 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 70 + + + + Account + 帐户 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 82 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 306 + + + + Update Cash Balance + 更新现金余额 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 110 + + + + Unit Price + 单价 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 203 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 267 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 208 + + + + Oops! Could not get the historical exchange rate from + 哎呀!无法从以下来源获取历史汇率 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 232 + + + + Fee + 费用 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 286 + + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 314 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 232 + + + + Oops! Could not get the historical exchange rate from + 哎呀!无法获取历史汇率 + + apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html + 304 + + + + Import Activities + 导入活动 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts + 44 + + + + Import Dividends + 导入股息 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts + 86 + + + + Importing data... + 正在导入数据... + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts + 120 + + + + Import has been completed + 导入已完成 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts + 128 + + + + Validating data... + 验证数据... + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts + 233 + + + + Select Holding + 选择控股 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 20 + + + + Select File + 选择文件 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 23 + + + + Holding + 保持 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 33 + + + + Load Dividends + 加载股息 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 70 + + + + Choose or drop a file here + 在此处选择或放置文件 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 86 + + + + The following file formats are supported: + 支持以下文件格式: + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 92 + + + + Select Dividends + 选择股息 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 115 + + + + Select Activities + 选择活动 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 118 + + + + Back + 后退 + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 145 + + + apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html + 181 + + + + Allocations + 分配 + + apps/client/src/app/pages/portfolio/allocations/allocations-page-routing.module.ts + 13 + + + apps/client/src/app/pages/portfolio/portfolio-page.component.ts + 49 + + + + Allocations + 分配 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 4 + + + + Proportion of Net Worth + 占净资产的比例 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 12 + + + + By Platform + 按平台 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 44 + + + + By Currency + 按货币 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 63 + + + + By Asset Class + 按资产类别 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 86 + + + + By Holding + 通过持有 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 109 + + + + By Sector + 按部门 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 132 + + + + By Continent + 按大陆 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 156 + + + + By Market + 按市场 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 179 + + + + Regions + 区域 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 203 + + + apps/client/src/app/pages/public/public-page.html + 76 + + + + Developed Markets + 发达市场 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 228 + + + apps/client/src/app/pages/public/public-page.html + 93 + + + + Emerging Markets + 新兴市场 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 237 + + + apps/client/src/app/pages/public/public-page.html + 102 + + + + Other Markets + 其他市场 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 246 + + + apps/client/src/app/pages/public/public-page.html + 111 + + + + No data available + 无可用数据 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 258 + + + apps/client/src/app/pages/public/public-page.html + 123 + + + + By Account + 按帐户 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 270 + + + + By ETF Provider + 按 ETF 提供商 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 290 + + + + By Country + 按国家/地区 + + apps/client/src/app/pages/portfolio/allocations/allocations-page.html + 313 + + + + Analysis + 分析 + + apps/client/src/app/pages/portfolio/analysis/analysis-page-routing.module.ts + 13 + + + apps/client/src/app/pages/portfolio/portfolio-page.component.ts + 34 + + + + Dividend + 股息 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts + 42 + + + libs/ui/src/lib/i18n.ts + 31 + + + + Deposit + 订金 + + libs/ui/src/lib/fire-calculator/fire-calculator.component.ts + 332 + + + + Monthly + 每月 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts + 54 + + + + Yearly + 每年 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts + 55 + + + + Analysis + 分析 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 2 + + + + Top + 顶部 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 168 + + + + Bottom + 底部 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 216 + + + + Portfolio Evolution + 投资组合演变 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 268 + + + + Investment Timeline + 投资时间表 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 298 + + + + Current Streak + 当前连胜 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 319 + + + + Longest Streak + 最长连续纪录 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 328 + + + + Dividend Timeline + 股息时间表 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 356 + + + + FIRE + 财务独立 + + apps/client/src/app/pages/portfolio/fire/fire-page-routing.module.ts + 13 + + + + FIRE + 财务独立 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 4 + + + + Calculator + 计算器 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 7 + + + + 4% Rule + 4%规则 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 41 + + + + Ghostfolio X-ray uses static analysis to identify potential issues and risks in your portfolio. + Ghostfolio X-ray 使用静态分析来识别您的投资组合中的潜在问题和风险。 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 111 + + + + Currency Cluster Risks + 货币集群风险 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 135 + + + + Account Cluster Risks + 账户集群风险 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 148 + + + + Holdings + 控股 + + apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html + 77 + + + apps/client/src/app/pages/portfolio/holdings/holdings-page.html + 4 + + + apps/client/src/app/pages/public/public-page.html + 14 + + + libs/ui/src/lib/assistant/assistant.html + 46 + + + + Pricing + 价钱 + + apps/client/src/app/pages/pricing/pricing-page-routing.module.ts + 13 + + + + Pricing Plans + 定价计划 + + apps/client/src/app/pages/pricing/pricing-page.html + 4 + + + + Our official Ghostfolio Premium cloud offering is the easiest way to get started. Due to the time it saves, this will be the best option for most people. Revenue is used to cover the costs of the hosting infrastructure and to fund ongoing development. + 我们的官方 Ghostfolio Premium 云产品是最简单的入门方法。由于它节省了时间,这对于大多数人来说将是最佳选择。收入用于支付托管基础设施的成本和资助持续开发。 + + apps/client/src/app/pages/pricing/pricing-page.html + 6 + + + + If you prefer to run Ghostfolio on your own infrastructure, please find the source code and further instructions on GitHub. + 如果你希望在自己的基础设施上运行 Ghostfolio,请查看源代码和进一步的说明GitHub + + apps/client/src/app/pages/pricing/pricing-page.html + 24 + + + + For tech-savvy investors who prefer to run Ghostfolio on their own infrastructure. + 适合喜欢在自己的基础设施上运行 Ghostfolio 的精通技术的投资者。 + + apps/client/src/app/pages/pricing/pricing-page.html + 36 + + + + Unlimited Transactions + 无限交易 + + apps/client/src/app/pages/pricing/pricing-page.html + 43 + + + apps/client/src/app/pages/pricing/pricing-page.html + 126 + + + apps/client/src/app/pages/pricing/pricing-page.html + 187 + + + + Unlimited Accounts + 无限账户 + + apps/client/src/app/pages/pricing/pricing-page.html + 47 + + + apps/client/src/app/pages/pricing/pricing-page.html + 130 + + + apps/client/src/app/pages/pricing/pricing-page.html + 191 + + + + Portfolio Performance + 投资组合表现 + + apps/client/src/app/pages/pricing/pricing-page.html + 51 + + + apps/client/src/app/pages/pricing/pricing-page.html + 134 + + + apps/client/src/app/pages/pricing/pricing-page.html + 195 + + + + Data Import and Export + 数据导入与导出 + + apps/client/src/app/pages/pricing/pricing-page.html + 71 + + + apps/client/src/app/pages/pricing/pricing-page.html + 138 + + + apps/client/src/app/pages/pricing/pricing-page.html + 215 + + + + Community Support + 社区支持 + + apps/client/src/app/pages/pricing/pricing-page.html + 88 + + + + Self-hosted, update manually. + 自托管,手动更新。 + + apps/client/src/app/pages/pricing/pricing-page.html + 92 + + + + Free + 自由的 + + apps/client/src/app/pages/pricing/pricing-page.html + 93 + + + apps/client/src/app/pages/pricing/pricing-page.html + 150 + + + + For new investors who are just getting started with trading. + 适合刚开始交易的新投资者。 + + apps/client/src/app/pages/pricing/pricing-page.html + 120 + + + + Fully managed Ghostfolio cloud offering. + 完全托管的 Ghostfolio 云产品。 + + apps/client/src/app/pages/pricing/pricing-page.html + 149 + + + apps/client/src/app/pages/pricing/pricing-page.html + 240 + + + + For ambitious investors who need the full picture of their financial assets. + 适合需要全面了解其金融资产的雄心勃勃的投资者。 + + apps/client/src/app/pages/pricing/pricing-page.html + 180 + + + + Email and Chat Support + 电子邮件和聊天支持 + + apps/client/src/app/pages/pricing/pricing-page.html + 236 + + + + Renew Plan + 更新计划 + + apps/client/src/app/components/header/header.component.html + 185 + + + apps/client/src/app/components/user-account-membership/user-account-membership.html + 28 + + + apps/client/src/app/pages/pricing/pricing-page.html + 276 + + + + One-time payment, no auto-renewal. + 一次性付款,无自动续订。 + + apps/client/src/app/pages/pricing/pricing-page.html + 280 + + + + Get Started + 开始使用 + + apps/client/src/app/pages/pricing/pricing-page.html + 291 + + + + It’s free. + 免费。 + + apps/client/src/app/pages/pricing/pricing-page.html + 294 + + + + Hello, has shared a Portfolio with you! + 你好,分享了一个文件夹与你! + + apps/client/src/app/pages/public/public-page.html + 4 + + + + Currencies + 货币 + + apps/client/src/app/pages/public/public-page.html + 30 + + + + Continents + 大陆 + + apps/client/src/app/pages/public/public-page.html + 60 + + + + Ghostfolio empowers you to keep track of your wealth. + Ghostfolio 使您能够跟踪您的财富。 + + apps/client/src/app/pages/public/public-page.html + 148 + + + + Registration + 注册 + + apps/client/src/app/pages/register/register-page-routing.module.ts + 13 + + + + Continue with Internet Identity + 继续互联网身份 + + apps/client/src/app/pages/register/register-page.html + 41 + + + + Continue with Google + 继续使用谷歌 + + apps/client/src/app/pages/register/register-page.html + 51 + + + + Copy to clipboard + 复制到剪贴板 + + apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html + 26 + + + + I agree to have stored my Security Token from above in a secure place. If I lose it, I cannot get my account back. + 我同意存储我的保安编码器从上面看,在一个安全的地方。如果我丢失了它,我将无法找回我的帐户。 + + apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html + 32 + + + + Agree and continue + 同意并继续 + + apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html + 45 + + + + Personal Finance Tools + 个人理财工具 + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page-routing.module.ts + 14 + + + + open-source-alternative-to + 开源替代方案 + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page-routing.module.ts + 23 + + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.component.ts + 13 + + + + Open Source Alternative to + 开源替代方案 + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page-routing.module.ts + 26 + + + + Discover Open Source Alternatives for Personal Finance Tools + 发现个人理财工具的开源替代品 + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html + 4 + + + + This overview page features a curated collection of personal finance tools compared to the open source alternative Ghostfolio. If you value transparency, data privacy, and community collaboration, Ghostfolio provides an excellent opportunity to take control of your financial management. + 此概述页面包含与开源替代方案相比的精选个人理财工具集合Ghostfolio。如果您重视透明度、数据隐私和社区协作,Ghostfolio 提供了一个绝佳的机会来控制您的财务管理。 + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html + 8 + + + + Explore the links below to compare a variety of personal finance tools with Ghostfolio. + 浏览下面的链接,将各种个人理财工具与 Ghostfolio 进行比较。 + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html + 16 + + + + Open Source Alternative to + 开源替代方案 + + apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html + 38 + + + + The Open Source Alternative to + 开源替代方案 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 8 + + + + Are you looking for an open source alternative to ? Ghostfolio is a powerful portfolio management tool that provides individuals with a comprehensive platform to track, analyze, and optimize their investments. Whether you are an experienced investor or just starting out, Ghostfolio offers an intuitive user interface and a wide range of functionalities to help you make informed decisions and take control of your financial future. + 您是否正在寻找开源替代方案幽灵作品集是一个强大的投资组合管理工具,为个人提供一个全面的平台来跟踪、分析和优化他们的投资。无论您是经验丰富的投资者还是刚刚起步的投资者,Ghostfolio 都提供直观的用户界面和广泛的功能帮助您做出明智的决定并掌控您的财务未来。 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 13 + + + + Ghostfolio is an open source software (OSS), providing a cost-effective alternative to making it particularly suitable for individuals on a tight budget, such as those pursuing Financial Independence, Retire Early (FIRE). By leveraging the collective efforts of a community of developers and personal finance enthusiasts, Ghostfolio continuously enhances its capabilities, security, and user experience. + Ghostfolio 是一款开源软件 (OSS),提供了一种经济高效的替代方案使其特别适合预算紧张的个人,例如追求财务独立,提前退休(FIRE) 。通过利用开发者社区和个人理财爱好者的集体努力,Ghostfolio 不断增强其功能、安全性和用户体验。 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 27 + + + + Let’s dive deeper into the detailed Ghostfolio vs comparison table below to gain a thorough understanding of how Ghostfolio positions itself relative to . We will explore various aspects such as features, data privacy, pricing, and more, allowing you to make a well-informed choice for your personal requirements. + 让我们更深入地了解 Ghostfolio 与下面的比较表可帮助您全面了解 Ghostfolio 相对于其他产品的定位。我们将探讨功能、数据隐私、定价等各个方面,让您根据个人需求做出明智的选择。 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 38 + + + + Ghostfolio vs comparison table + Ghostfolio vs比较表 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 49 + + + + Founded + 成立 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 72 + + + + Origin + 来源 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 77 + + + + Region + 地区 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 82 + + + + Available in + 可用于 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 87 + + + + ✅ Yes + ✅ 是的 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 109 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 116 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 130 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 141 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 155 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 162 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 174 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 181 + + + + ❌ No + ❌ 没有 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 111 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 134 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 145 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 157 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 164 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 176 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 183 + + + + ❌ No + ❌ 没有 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 118 + + + + Self-Hosting + 自托管 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 123 + + + + Use anonymously + 匿名使用 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 150 + + + + Free Plan + 免费计划 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 169 + + + + Starting from + 从...开始 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 195 + + + + year + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 191 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 197 + + + + Notes + 笔记 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 202 + + + + Please note that the information provided in the Ghostfolio vs comparison table is based on our independent research and analysis. This website is not affiliated with or any other product mentioned in the comparison. As the landscape of personal finance tools evolves, it is essential to verify any specific details or changes directly from the respective product page. Data needs a refresh? Help us maintain accurate data on GitHub. + 请注意,Ghostfolio 与 Ghostfolio 中提供的信息比较表基于我们的独立研究和分析。该网站不隶属于或比较中提到的任何其他产品。随着个人理财工具格局的不断发展,直接从相应的产品页面验证任何具体的细节或变化至关重要。数据需要刷新吗?帮助我们维护准确的数据GitHub + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 210 + + + + Ready to take your investments to the next level? + 准备好带走你的投资下一级 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 223 + + + + Effortlessly track, analyze, and visualize your wealth with Ghostfolio. + 使用 Ghostfolio 轻松跟踪、分析和可视化您的财富。 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 227 + + + + Get Started + 开始使用 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 232 + + + + Personal Finance Tools + 个人理财工具 + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html + 308 + + + + Switzerland + 瑞士 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 72 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 102 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 530 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 580 + + + + Global + 全球的 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 73 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 341 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 462 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 581 + + + + United States + 美国 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 93 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 149 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 159 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 201 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 210 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 220 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 232 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 242 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 294 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 316 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 327 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 352 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 354 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 364 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 429 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 439 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 449 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 518 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 541 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 569 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 591 + + + + France + 法国 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 121 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 482 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 498 + + + + Poland + 波兰 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 131 + + + + Germany + 德国 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 140 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 190 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 274 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 284 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 305 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 339 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 385 + + + + Belgium + 比利时 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 179 + + + + South Africa + 南非 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 251 + + + + Austria + 奥地利 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 262 + + + + Italy + 意大利 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 396 + + + + Netherlands + 荷兰 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 406 + + + + Thailand + 泰国 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 418 + + + + New Zealand + 新西兰 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 460 + + + + Czech Republic + 捷克共和国 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 471 + + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 508 + + + + Finland + 芬兰 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 490 + + + + Canada + 加拿大 + + apps/client/src/app/pages/resources/personal-finance-tools/products.ts + 561 + + + + Resources + 资源 + + apps/client/src/app/pages/resources/resources-page-routing.module.ts + 13 + + + + Guides + 指南 + + apps/client/src/app/pages/resources/resources-page.html + 22 + + + + Glossary + 词汇表 + + apps/client/src/app/pages/resources/resources-page.html + 92 + + + + Membership + 会员资格 + + apps/client/src/app/pages/user-account/user-account-page-routing.module.ts + 23 + + + apps/client/src/app/pages/user-account/user-account-page.component.ts + 40 + + + + Access + 使用权 + + apps/client/src/app/pages/user-account/user-account-page-routing.module.ts + 28 + + + apps/client/src/app/pages/user-account/user-account-page.component.ts + 46 + + + + My Ghostfolio + 我的 Ghostfolio + + apps/client/src/app/pages/user-account/user-account-page-routing.module.ts + 33 + + + + Oops, authentication has failed. + 糟糕,身份验证失败。 + + apps/client/src/app/pages/webauthn/webauthn-page.html + 19 + + + + Try again + 再试一次 + + apps/client/src/app/pages/webauthn/webauthn-page.html + 27 + + + + Go back to Home Page + 返回首页 + + apps/client/src/app/pages/webauthn/webauthn-page.html + 31 + + + + Do you really want to delete this account balance? + 您确实要删除该帐户余额吗? + + libs/ui/src/lib/account-balances/account-balances.component.ts + 58 + + + + Import Activities + 进口活动 + + libs/ui/src/lib/activities-table/activities-table.component.html + 9 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 369 + + + + Import Dividends + 导入股息 + + libs/ui/src/lib/activities-table/activities-table.component.html + 29 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 381 + + + + Export Activities + 出口活动 + + libs/ui/src/lib/activities-table/activities-table.component.html + 41 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 394 + + + + Export Drafts as ICS + 将汇票导出为 ICS + + libs/ui/src/lib/activities-table/activities-table.component.html + 54 + + + libs/ui/src/lib/activities-table/activities-table.component.html + 407 + + + + Delete all Activities + 删除所有活动 + + libs/ui/src/lib/activities-table/activities-table.component.html + 65 + + + + Draft + 草稿 + + libs/ui/src/lib/activities-table/activities-table.component.html + 143 + + + + Clone + 克隆 + + libs/ui/src/lib/activities-table/activities-table.component.html + 434 + + + + Export Draft as ICS + 将汇票导出为 ICS + + libs/ui/src/lib/activities-table/activities-table.component.html + 444 + + + + Do you really want to delete this activity? + 您确实要删除此活动吗? + + libs/ui/src/lib/activities-table/activities-table.component.ts + 175 + + + + Find holding... + 查找持有... + + libs/ui/src/lib/assistant/assistant.component.ts + 126 + + + + No entries... + 没有条目... + + libs/ui/src/lib/assistant/assistant.html + 63 + + + libs/ui/src/lib/assistant/assistant.html + 84 + + + + Asset Profiles + 资产概况 + + libs/ui/src/lib/assistant/assistant.html + 67 + + + + Index + 指数 + + libs/ui/src/lib/benchmark/benchmark.component.html + 3 + + + + 50-Day Trend + 50 天趋势 + + libs/ui/src/lib/benchmark/benchmark.component.html + 15 + + + + 200-Day Trend + 200天趋势 + + libs/ui/src/lib/benchmark/benchmark.component.html + 40 + + + + Last All Time High + 上次历史最高纪录 + + libs/ui/src/lib/benchmark/benchmark.component.html + 65 + + + + Change from All Time High + 从历史最高点开始变化 + + libs/ui/src/lib/benchmark/benchmark.component.html + 81 + + + + from ATH + 来自 ATH + + libs/ui/src/lib/benchmark/benchmark.component.html + 83 + + + + Market data provided by + 市场数据提供者 + + libs/ui/src/lib/data-provider-credits/data-provider-credits.component.html + 2 + + + + Savings Rate per Month + 每月储蓄率 + + libs/ui/src/lib/fire-calculator/fire-calculator.component.html + 10 + + + + Annual Interest Rate + 年利率 + + libs/ui/src/lib/fire-calculator/fire-calculator.component.html + 21 + + + + Retirement Date + 退休日期 + + libs/ui/src/lib/fire-calculator/fire-calculator.component.html + 32 + + + + Projected Total Amount + 预计总额 + + libs/ui/src/lib/fire-calculator/fire-calculator.component.html + 60 + + + + Interest + 利息 + + libs/ui/src/lib/fire-calculator/fire-calculator.component.ts + 342 + + + libs/ui/src/lib/i18n.ts + 33 + + + + Savings + 储蓄 + + libs/ui/src/lib/fire-calculator/fire-calculator.component.ts + 352 + + + + Allocation + 分配 + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 98 + + + + Show all + 显示所有 + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 174 + + + + Account + 帐户 + + libs/ui/src/lib/i18n.ts + 4 + + + + Asia-Pacific + 亚太 + + libs/ui/src/lib/i18n.ts + 5 + + + + Asset Class + 资产类别 + + libs/ui/src/lib/i18n.ts + 6 + + + + Asset Sub Class + 资产子类别 + + libs/ui/src/lib/i18n.ts + 7 + + + + Core + 核心 + + libs/ui/src/lib/i18n.ts + 8 + + + + Switch to Ghostfolio Premium or Ghostfolio Open Source easily + 轻松切换到 Ghostfolio Premium 或 Ghostfolio Open Source + + libs/ui/src/lib/i18n.ts + 9 + + + + Switch to Ghostfolio Premium easily + 轻松切换到 Ghostfolio Premium + + libs/ui/src/lib/i18n.ts + 10 + + + + Switch to Ghostfolio Open Source or Ghostfolio Basic easily + 轻松切换到 Ghostfolio Open Source 或 Ghostfolio Basic + + libs/ui/src/lib/i18n.ts + 11 + + + + Emergency Fund + 应急基金 + + libs/ui/src/lib/i18n.ts + 12 + + + + Grant + 授予 + + libs/ui/src/lib/i18n.ts + 13 + + + + Higher Risk + 风险较高 + + libs/ui/src/lib/i18n.ts + 14 + + + + This activity already exists. + 这项活动已经存在。 + + libs/ui/src/lib/i18n.ts + 15 + + + + Japan + 日本 + + libs/ui/src/lib/i18n.ts + 16 + + + + Lower Risk + 降低风险 + + libs/ui/src/lib/i18n.ts + 17 + + + + Month + + + libs/ui/src/lib/i18n.ts + 18 + + + + Months + 几个月 + + libs/ui/src/lib/i18n.ts + 19 + + + + Other + 其他 + + libs/ui/src/lib/i18n.ts + 20 + + + libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts + 385 + + + + Preset + 预设 + + libs/ui/src/lib/i18n.ts + 21 + + + + Retirement Provision + 退休金 + + libs/ui/src/lib/i18n.ts + 22 + + + + Satellite + 卫星 + + libs/ui/src/lib/i18n.ts + 23 + + + + Symbol + 符号 + + libs/ui/src/lib/i18n.ts + 24 + + + + Tag + 标签 + + libs/ui/src/lib/i18n.ts + 25 + + + + Year + + + libs/ui/src/lib/i18n.ts + 26 + + + + Years + + + libs/ui/src/lib/i18n.ts + 27 + + + + Buy + + + libs/ui/src/lib/i18n.ts + 30 + + + + Fee + 费用 + + libs/ui/src/lib/i18n.ts + 32 + + + + Valuable + 有价值的 + + libs/ui/src/lib/i18n.ts + 34 + + + + Liability + 责任 + + libs/ui/src/lib/i18n.ts + 35 + + + + Sell + + + libs/ui/src/lib/i18n.ts + 36 + + + + Cash + 现金 + + libs/ui/src/lib/i18n.ts + 39 + + + + Commodity + 商品 + + libs/ui/src/lib/i18n.ts + 40 + + + + Equity + 公平 + + libs/ui/src/lib/i18n.ts + 41 + + + + Fixed Income + 固定收入 + + libs/ui/src/lib/i18n.ts + 42 + + + + Real Estate + 房地产 + + libs/ui/src/lib/i18n.ts + 43 + + + + Bond + 纽带 + + libs/ui/src/lib/i18n.ts + 46 + + + + Cryptocurrency + 加密货币 + + libs/ui/src/lib/i18n.ts + 47 + + + + ETF + 交易所交易基金 + + libs/ui/src/lib/i18n.ts + 48 + + + + Mutual Fund + 共同基金 + + libs/ui/src/lib/i18n.ts + 49 + + + + Precious Metal + 贵金属 + + libs/ui/src/lib/i18n.ts + 50 + + + + Private Equity + 私人产权 + + libs/ui/src/lib/i18n.ts + 51 + + + + Stock + 库存 + + libs/ui/src/lib/i18n.ts + 52 + + + + Africa + 非洲 + + libs/ui/src/lib/i18n.ts + 59 + + + + Asia + 亚洲 + + libs/ui/src/lib/i18n.ts + 60 + + + + Europe + 欧洲 + + libs/ui/src/lib/i18n.ts + 61 + + + + North America + 北美 + + libs/ui/src/lib/i18n.ts + 62 + + + + Oceania + 大洋洲 + + libs/ui/src/lib/i18n.ts + 63 + + + + South America + 南美洲 + + libs/ui/src/lib/i18n.ts + 64 + + + + Extreme Fear + 极度恐惧 + + libs/ui/src/lib/i18n.ts + 67 + + + + Extreme Greed + 极度贪婪 + + libs/ui/src/lib/i18n.ts + 68 + + + + Neutral + 中性的 + + libs/ui/src/lib/i18n.ts + 71 + + + + Membership + 会员资格 + + libs/ui/src/lib/membership-card/membership-card.component.html + 18 + + + + Valid until + 有效期至 + + libs/ui/src/lib/membership-card/membership-card.component.html + 23 + + + + Time to add your first activity. + 是时候添加您的第一个活动了。 + + libs/ui/src/lib/no-transactions-info/no-transactions-info.component.html + 12 + + + + No data available + 无可用数据 + + libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts + 387 + + + libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts + 400 + + + + If a translation is missing, kindly support us in extending it here. + 如果翻译缺失,请支持我们进行扩展这里 + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 55 + + + + Date Range + 日期范围 + + libs/ui/src/lib/assistant/assistant.html + 93 + + + + The current market price is + 当前市场价格为 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts + 317 + + + + Test + 测试 + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 288 + + + + Oops! Could not grant access. + 哎呀!无法授予访问权限。 + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts + 80 + + + + Restricted view + 视野受限 + + apps/client/src/app/components/access-table/access-table.component.html + 25 + + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 36 + + + + Permission + 允许 + + apps/client/src/app/components/access-table/access-table.component.html + 17 + + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 33 + + + + Private + 私人的 + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 24 + + + + Job Queue + 作业队列 + + apps/client/src/app/pages/admin/admin-page-routing.module.ts + 25 + + + apps/client/src/app/pages/admin/admin-page.component.ts + 42 + + + + Market data is delayed for + 市场数据延迟 + + apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts + 82 + + + + Absolute Currency Performance + 绝对货币表现 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 73 + + + + Absolute Net Performance + 绝对净性能 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 121 + + + + Absolute Asset Performance + 绝对资产绩效 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 29 + + + + Investment + 投资 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts + 46 + + + apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts + 60 + + + + Asset Performance + 资产绩效 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 51 + + + + Net Performance + 净绩效 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 140 + + + + Currency Performance + 货币表现 + + apps/client/src/app/pages/portfolio/analysis/analysis-page.html + 98 + + + + Year to date + 今年迄今为止 + + libs/ui/src/lib/assistant/assistant.component.ts + 109 + + + + Week to date + 本周至今 + + libs/ui/src/lib/assistant/assistant.component.ts + 101 + + + + Month to date + 本月至今 + + libs/ui/src/lib/assistant/assistant.component.ts + 105 + + + + MTD + 最大输运量 + + libs/ui/src/lib/assistant/assistant.component.ts + 105 + + + + WTD + 世界贸易组织 + + libs/ui/src/lib/assistant/assistant.component.ts + 101 + + + + Oops! A data provider is experiencing the hiccups. + 哎呀!数据提供商遇到了问题。 + + apps/client/src/app/components/portfolio-performance/portfolio-performance.component.html + 8 + + + + View + 看法 + + apps/client/src/app/components/access-table/access-table.component.html + 22 + + + apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html + 39 + + + + Reset Filters + 重置过滤器 + + libs/ui/src/lib/assistant/assistant.html + 155 + + + + If you retire today, you would be able to withdraw per year or per month, based on your total assets of and a withdrawal rate of 4%. + 如果你今天退休,你可以领取每年或者每月,根据您的总资产提款率为4%。 + + apps/client/src/app/pages/portfolio/fire/fire-page.html + 68 + + + + year + + + libs/ui/src/lib/assistant/assistant.component.ts + 112 + + + + years + + + libs/ui/src/lib/assistant/assistant.component.ts + 114 + + + + Apply Filters + 应用过滤器 + + libs/ui/src/lib/assistant/assistant.html + 165 + + + + Asset Classes + 资产类别 + + libs/ui/src/lib/assistant/assistant.html + 138 + + + + self-hosting + 自托管 + + apps/client/src/app/pages/faq/faq-page.component.ts + 48 + + + + FAQ + 常见问题 + + apps/client/src/app/pages/faq/saas/saas-page-routing.module.ts + 13 + + + apps/client/src/app/pages/faq/self-hosting/self-hosting-page-routing.module.ts + 13 + + + + Self-Hosting + 自托管 + + apps/client/src/app/pages/faq/faq-page.component.ts + 47 + + + apps/client/src/app/pages/faq/self-hosting/self-hosting-page-routing.module.ts + 13 + + + + Data Gathering + 数据收集 + + apps/client/src/app/components/admin-overview/admin-overview.html + 134 + + + + General + 一般的 + + apps/client/src/app/pages/faq/faq-page.component.ts + 36 + + + + Cloud + + + apps/client/src/app/pages/faq/faq-page.component.ts + 41 + + + apps/client/src/app/pages/faq/saas/saas-page-routing.module.ts + 13 + + + + Oops! It looks like you’re making too many requests. Please slow down a bit. + 哎呀!看来您提出了太多要求。请慢一点。 + + apps/client/src/app/core/http-response.interceptor.ts + 105 + + + + My Account + 我的账户 + + apps/client/src/app/pages/i18n/i18n-page.html + 13 + + + + Closed + 关闭 + + apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + 31 + + + + Active + 积极的 + + apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + 30 + + + + Activity + 活动 + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 176 + + From 084467ee9adce35f2099d4e8ea1119e55ff40cb7 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 31 Mar 2024 11:24:50 +0200 Subject: [PATCH 083/203] Feature/reverse order of specific years in date range selector of assistant (#3221) * Reverse order * Update changelog --- CHANGELOG.md | 6 +++++- libs/ui/src/lib/assistant/assistant.component.ts | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 39cefd95f..ce6ec2a7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,12 +11,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Set up the language localization for Chinese (`zh`) +### Changed + +- Improved the usability of the date range support by specific years (`2023`, `2022`, `2021`, etc.) in the assistant (experimental) + ## 2.69.0 - 2024-03-30 ### Added - Added the date range support in the activities table on the portfolio activities page (experimental) -- Extended the date range support by specific years (`2023`, `2022`, `2021`, etc.) in the assistant (experimental) +- Extended the date range support by specific years (`2021`, `2022`, `2023`, etc.) in the assistant (experimental) - Set up `Tini` to avoid zombie processes and perform signal forwarding in docker image ### Changed diff --git a/libs/ui/src/lib/assistant/assistant.component.ts b/libs/ui/src/lib/assistant/assistant.component.ts index bd8355125..310bede05 100644 --- a/libs/ui/src/lib/assistant/assistant.component.ts +++ b/libs/ui/src/lib/assistant/assistant.component.ts @@ -219,6 +219,7 @@ export class AssistantComponent implements OnChanges, OnDestroy, OnInit { return { label: format(date, 'yyyy'), value: format(date, 'yyyy') }; }) .slice(0, -1) + .reverse() ); } From 34997f91db6faac15821d6176a799c65360638f9 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 31 Mar 2024 11:38:09 +0200 Subject: [PATCH 084/203] Feature/setup webpack bundle analyzer (#3222) * Set up Webpack Bundle Analyzer * Update changelog --- CHANGELOG.md | 1 + package.json | 4 ++- yarn.lock | 78 +++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 78 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce6ec2a7d..1ce4ef296 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Set up the language localization for Chinese (`zh`) +- Set up _Webpack Bundle Analyzer_ ### Changed diff --git a/package.json b/package.json index aa9bf0fd0..05ffd3e49 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "affected:libs": "nx affected:libs", "affected:lint": "nx affected:lint", "affected:test": "nx affected:test", + "analyze:client": "nx run client:build:production --stats-json && webpack-bundle-analyzer -p 1234 dist/apps/client/en/stats.json", "angular": "node --max_old_space_size=32768 ./node_modules/@angular/cli/bin/ng", "build:production": "nx run api:copy-assets && nx run api:build:production && nx run client:copy-assets && nx run client:build:production && yarn replace-placeholders-in-build", "build:storybook": "nx run ui:build-storybook", @@ -197,7 +198,8 @@ "ts-jest": "29.1.0", "ts-node": "10.9.1", "tslib": "2.6.0", - "typescript": "5.3.3" + "typescript": "5.3.3", + "webpack-bundle-analyzer": "4.10.1" }, "engines": { "node": ">=18" diff --git a/yarn.lock b/yarn.lock index 03e4cca81..ee83c3606 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5352,6 +5352,11 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@polka/url@^1.0.0-next.24": + version "1.0.0-next.25" + resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.25.tgz#f077fdc0b5d0078d30893396ff4827a13f99e817" + integrity sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ== + "@prisma/client@5.11.0": version "5.11.0" resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.11.0.tgz#d8e55fab85163415b2245fb408b9106f83c8106d" @@ -8039,11 +8044,21 @@ acorn-jsx@^5.3.2: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== +acorn-walk@^8.0.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" + integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== + acorn-walk@^8.0.2, acorn-walk@^8.1.1: version "8.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== +acorn@^8.0.4: + version "8.11.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== + acorn@^8.1.0, acorn@^8.10.0, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.1, acorn@^8.8.2, acorn@^8.9.0: version "8.10.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" @@ -10474,6 +10489,11 @@ dayjs@^1.11.7: resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ== +debounce@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" + integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== + debug@2.6.9, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -10849,7 +10869,7 @@ dotenv@^16.0.0, dotenv@~16.3.1: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== -duplexer@^0.1.1: +duplexer@^0.1.1, duplexer@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== @@ -12455,6 +12475,13 @@ gunzip-maybe@^1.4.2: pumpify "^1.3.3" through2 "^2.0.3" +gzip-size@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462" + integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q== + dependencies: + duplexer "^0.1.2" + handle-thing@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" @@ -12596,7 +12623,7 @@ html-entities@^2.1.0, html-entities@^2.3.2: resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.4.0.tgz#edd0cee70402584c8c76cc2c0556db09d1f45061" integrity sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ== -html-escaper@^2.0.0: +html-escaper@^2.0.0, html-escaper@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== @@ -13207,6 +13234,11 @@ is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + is-potential-custom-element-name@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" @@ -15122,7 +15154,7 @@ mri@^1.1.0, mri@^1.2.0: resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== -mrmime@2.0.0: +mrmime@2.0.0, mrmime@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-2.0.0.tgz#151082a6e06e59a9a39b46b3e14d5cfe92b3abb4" integrity sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw== @@ -15693,7 +15725,7 @@ open@^7.0.3: is-docker "^2.0.0" is-wsl "^2.1.1" -opener@^1.5.1: +opener@^1.5.1, opener@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== @@ -17649,6 +17681,15 @@ simple-update-notifier@^2.0.0: dependencies: semver "^7.5.3" +sirv@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-2.0.4.tgz#5dd9a725c578e34e449f332703eb2a74e46a29b0" + integrity sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ== + dependencies: + "@polka/url" "^1.0.0-next.24" + mrmime "^2.0.0" + totalist "^3.0.0" + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" @@ -18377,6 +18418,11 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== +totalist@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/totalist/-/totalist-3.0.1.tgz#ba3a3d600c915b1a97872348f79c127475f6acf8" + integrity sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ== + tough-cookie-file-store@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/tough-cookie-file-store/-/tough-cookie-file-store-2.0.3.tgz#788f7a6fe5cd8f61a1afb71b2f0b964ebf914b80" @@ -19080,6 +19126,25 @@ webidl-conversions@^7.0.0: resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== +webpack-bundle-analyzer@4.10.1: + version "4.10.1" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.1.tgz#84b7473b630a7b8c21c741f81d8fe4593208b454" + integrity sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ== + dependencies: + "@discoveryjs/json-ext" "0.5.7" + acorn "^8.0.4" + acorn-walk "^8.0.0" + commander "^7.2.0" + debounce "^1.2.1" + escape-string-regexp "^4.0.0" + gzip-size "^6.0.0" + html-escaper "^2.0.2" + is-plain-object "^5.0.0" + opener "^1.5.2" + picocolors "^1.0.0" + sirv "^2.0.3" + ws "^7.3.1" + webpack-dev-middleware@6.1.1, webpack-dev-middleware@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-6.1.1.tgz#6bbc257ec83ae15522de7a62f995630efde7cc3d" @@ -19409,6 +19474,11 @@ ws@^6.1.0: dependencies: async-limiter "~1.0.0" +ws@^7.3.1: + version "7.5.9" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" + integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== + ws@^8.11.0, ws@^8.13.0, ws@^8.2.3: version "8.14.2" resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" From 0c684748025d26e0b22182ea71f98288d67ae668 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 31 Mar 2024 11:41:44 +0200 Subject: [PATCH 085/203] Extract locales (#3223) --- apps/client/src/locales/messages.de.xlf | 200 ++++++++------- apps/client/src/locales/messages.es.xlf | 200 ++++++++------- apps/client/src/locales/messages.fr.xlf | 200 ++++++++------- apps/client/src/locales/messages.it.xlf | 200 ++++++++------- apps/client/src/locales/messages.nl.xlf | 200 ++++++++------- apps/client/src/locales/messages.pl.xlf | 200 ++++++++------- apps/client/src/locales/messages.pt.xlf | 200 ++++++++------- apps/client/src/locales/messages.tr.xlf | 200 ++++++++------- apps/client/src/locales/messages.xlf | 200 ++++++++------- apps/client/src/locales/messages.zh.xlf | 318 ++++++++++++------------ 10 files changed, 1099 insertions(+), 1019 deletions(-) diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index bbe0d1edd..58b55bc01 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -22,7 +22,7 @@ Das Ausfallrisiko beim Börsenhandel kann erheblich sein. Es ist nicht ratsam, Geld zu investieren, welches du kurzfristig benötigst. apps/client/src/app/app.component.html - 179 + 184 @@ -94,7 +94,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -130,7 +130,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -270,7 +270,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -326,7 +330,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -474,7 +478,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -490,7 +494,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -518,7 +522,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -534,7 +538,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -554,7 +558,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -582,7 +586,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -1492,11 +1496,11 @@ Sektoren apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1512,11 +1516,11 @@ Länder apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1592,7 +1596,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -1604,7 +1608,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -1616,7 +1620,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -1628,7 +1632,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -1640,7 +1644,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -1876,7 +1880,7 @@ Möchtest du diese Anmeldemethode wirklich löschen? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -1948,7 +1952,7 @@ Lokalität apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 @@ -1956,7 +1960,7 @@ Datums- und Zahlenformat apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 @@ -1964,7 +1968,7 @@ Zen Modus apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -1976,7 +1980,7 @@ Einloggen mit Fingerabdruck apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 @@ -1984,11 +1988,11 @@ Benutzer ID apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 @@ -2056,11 +2060,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2496,7 +2500,7 @@ Kommentar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2516,11 +2520,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2572,7 +2576,7 @@ Portfolio apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -2880,11 +2884,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2900,7 +2904,7 @@ Sektor apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2912,7 +2916,7 @@ Land apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -2972,7 +2976,7 @@ Monatlich apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 @@ -3048,7 +3052,7 @@ Filtern nach... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -3076,7 +3080,7 @@ Experimentelle Funktionen apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 @@ -3092,7 +3096,7 @@ Benchmark apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -3124,7 +3128,7 @@ Aussehen apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 @@ -3132,7 +3136,7 @@ Automatisch apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -3140,7 +3144,7 @@ Hell apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 @@ -3148,7 +3152,7 @@ Dunkel apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 @@ -3156,7 +3160,7 @@ Gesamtbetrag apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 @@ -3172,7 +3176,7 @@ Sparrate apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -3412,31 +3416,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -3464,7 +3472,7 @@ Symbol Zuordnung apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 @@ -3480,7 +3488,7 @@ Dividenden apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -3516,7 +3524,7 @@ Importieren apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -3584,7 +3592,7 @@ Jährlich apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -3664,7 +3672,7 @@ Unbeschwertes Erlebnis für turbulente Zeiten apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 @@ -3672,7 +3680,7 @@ Vorschau auf kommende Funktionalität apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 @@ -4100,7 +4108,7 @@ Möchtest du wirklich alle Aktivitäten löschen? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -4524,7 +4532,7 @@ Scraper Konfiguration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 @@ -9868,7 +9876,7 @@ ETFs ohne Länder apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 @@ -9876,7 +9884,7 @@ ETFs ohne Sektoren apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 @@ -10008,7 +10016,7 @@ Biometrische Authentifizierung apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 @@ -10092,7 +10100,7 @@ Daten exportieren apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -10100,7 +10108,7 @@ Währungen apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 @@ -10480,7 +10488,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -10512,7 +10520,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -10772,19 +10780,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -11052,7 +11060,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -11068,7 +11076,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -11084,7 +11092,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -11116,7 +11124,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -11188,7 +11196,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -11224,7 +11232,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -13344,7 +13352,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 @@ -13424,7 +13432,7 @@ Finde Position... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -13451,8 +13459,8 @@ Do you really want to delete this asset profile? Möchtest du dieses Anlageprofil wirklich löschen? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 @@ -13776,7 +13784,7 @@ Ups! Die historischen Daten konnten nicht geparsed werden. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -14648,7 +14656,7 @@ Der aktuelle Marktpreis ist apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 @@ -14656,7 +14664,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14732,11 +14740,11 @@ Einlage apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14792,7 +14800,7 @@ Seit Wochenbeginn libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14800,7 +14808,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14808,7 +14816,7 @@ Seit Monatsbeginn libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14816,7 +14824,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14824,7 +14832,7 @@ Seit Jahresbeginn libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -14836,7 +14844,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14868,7 +14876,7 @@ Jahr libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -14876,7 +14884,7 @@ Jahre libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index 6535d4034..6f4bd17fc 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -23,7 +23,7 @@ El riesgo de pérdida en trading puede ser importante. No es aconsejable invertir dinero que puedas necesitar a corto plazo. apps/client/src/app/app.component.html - 179 + 184 @@ -95,7 +95,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -131,7 +131,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -271,7 +271,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -327,7 +331,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -475,7 +479,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -491,7 +495,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -519,7 +523,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -535,7 +539,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -555,7 +559,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -583,7 +587,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -1490,11 +1494,11 @@ Sectores apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1510,11 +1514,11 @@ Países apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1590,7 +1594,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -1602,7 +1606,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -1614,7 +1618,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -1626,7 +1630,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -1638,7 +1642,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -1874,7 +1878,7 @@ ¿Estás seguro de eliminar este método de acceso? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -1946,7 +1950,7 @@ Ubicación apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 @@ -1954,7 +1958,7 @@ Formato de fecha y número apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 @@ -1962,7 +1966,7 @@ Modo Zen apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -1974,7 +1978,7 @@ Accede con huella digital apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 @@ -1982,11 +1986,11 @@ ID usuario apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 @@ -2054,11 +2058,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2494,7 +2498,7 @@ Nota apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2514,11 +2518,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2570,7 +2574,7 @@ Cartera apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -2866,11 +2870,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2926,7 +2930,7 @@ Sector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2938,7 +2942,7 @@ País apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -2998,7 +3002,7 @@ Mensual apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 @@ -3046,7 +3050,7 @@ Filtrar por... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -3074,7 +3078,7 @@ Funcionalidades experimentales apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 @@ -3082,7 +3086,7 @@ Benchmark apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -3122,7 +3126,7 @@ Apariencia apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 @@ -3130,7 +3134,7 @@ Automático apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -3138,7 +3142,7 @@ Claro apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 @@ -3146,7 +3150,7 @@ Oscuro apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 @@ -3154,7 +3158,7 @@ Importe total apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 @@ -3170,7 +3174,7 @@ Tasa de ahorro apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -3410,31 +3414,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -3462,7 +3470,7 @@ Mapeo de símbolos apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 @@ -3470,7 +3478,7 @@ Dividend apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -3514,7 +3522,7 @@ Import apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -3582,7 +3590,7 @@ Yearly apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -3662,7 +3670,7 @@ Distraction-free experience for turbulent times apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 @@ -3670,7 +3678,7 @@ Sneak peek at upcoming functionality apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 @@ -4098,7 +4106,7 @@ Do you really want to delete all your activities? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -4522,7 +4530,7 @@ Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 @@ -9866,7 +9874,7 @@ ETFs without Countries apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 @@ -9874,7 +9882,7 @@ ETFs without Sectors apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 @@ -10006,7 +10014,7 @@ Biometric Authentication apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 @@ -10090,7 +10098,7 @@ Export Data apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -10098,7 +10106,7 @@ Currencies apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 @@ -10478,7 +10486,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -10510,7 +10518,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -10770,19 +10778,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -11050,7 +11058,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -11066,7 +11074,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -11082,7 +11090,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -11114,7 +11122,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -11186,7 +11194,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -11222,7 +11230,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -13342,7 +13350,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 @@ -13422,7 +13430,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -13449,8 +13457,8 @@ Do you really want to delete this asset profile? Do you really want to delete this asset profile? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 @@ -13774,7 +13782,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -14646,7 +14654,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 @@ -14654,7 +14662,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14730,11 +14738,11 @@ Investment apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14790,7 +14798,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14798,7 +14806,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14806,7 +14814,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14814,7 +14822,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14822,7 +14830,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -14834,7 +14842,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14866,7 +14874,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -14874,7 +14882,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index 9faea802b..fd2fdae57 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -6,7 +6,7 @@ Le risque de perte en investissant peut être important. Il est déconseillé d'investir de l'argent dont vous pourriez avoir besoin à court terme. apps/client/src/app/app.component.html - 179 + 184 @@ -106,7 +106,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -142,7 +142,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -194,11 +194,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -326,7 +326,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -374,7 +378,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -530,7 +534,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -546,7 +550,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -574,7 +578,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -590,7 +594,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -606,7 +610,7 @@ Filtrer par... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -618,11 +622,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -642,11 +646,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -666,7 +670,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -694,7 +698,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -754,7 +758,7 @@ Secteur apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -766,7 +770,7 @@ Pays apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -782,11 +786,11 @@ Secteurs apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -802,11 +806,11 @@ Pays apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -818,7 +822,7 @@ Équivalence de Symboles apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 @@ -826,7 +830,7 @@ Note apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1102,7 +1106,7 @@ Portefeuille apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -1114,7 +1118,7 @@ Référence apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -1602,7 +1606,7 @@ Montant Total apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 @@ -1610,7 +1614,7 @@ Taux d'Épargne apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -1921,7 +1925,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -1933,7 +1937,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -1945,7 +1949,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -1957,7 +1961,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -1969,7 +1973,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -2137,7 +2141,7 @@ Voulez-vous vraiment supprimer cette méthode de connexion ? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -2221,31 +2225,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -2257,7 +2265,7 @@ Paramètres régionaux apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 @@ -2265,7 +2273,7 @@ Format de date et d'heure apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 @@ -2273,7 +2281,7 @@ Apparence apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 @@ -2281,7 +2289,7 @@ Auto apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -2289,7 +2297,7 @@ Clair apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 @@ -2297,7 +2305,7 @@ Sombre apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 @@ -2305,7 +2313,7 @@ Mode Zen apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -2317,7 +2325,7 @@ Se connecter avec empreinte apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 @@ -2325,7 +2333,7 @@ Fonctionnalités expérimentales apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 @@ -2333,11 +2341,11 @@ ID d'utilisateur apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 @@ -2745,7 +2753,7 @@ Importer apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -2905,7 +2913,7 @@ Dividende apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -2925,7 +2933,7 @@ Mensuel apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 @@ -3581,7 +3589,7 @@ Annuel apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -3661,7 +3669,7 @@ Expérience sans distraction pour les périodes tumultueuses apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 @@ -3669,7 +3677,7 @@ Avant-première de fonctionnalités futures apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 @@ -4097,7 +4105,7 @@ Voulez-vous vraiment supprimer toutes vos activités ? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -4521,7 +4529,7 @@ Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 @@ -9865,7 +9873,7 @@ ETFs without Countries apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 @@ -9873,7 +9881,7 @@ ETFs without Sectors apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 @@ -10005,7 +10013,7 @@ Biometric Authentication apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 @@ -10089,7 +10097,7 @@ Export Data apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -10097,7 +10105,7 @@ Currencies apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 @@ -10477,7 +10485,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -10509,7 +10517,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -10769,19 +10777,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -11049,7 +11057,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -11065,7 +11073,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -11081,7 +11089,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -11113,7 +11121,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -11185,7 +11193,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -11221,7 +11229,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -13341,7 +13349,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 @@ -13421,7 +13429,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -13448,8 +13456,8 @@ Do you really want to delete this asset profile? Do you really want to delete this asset profile? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 @@ -13773,7 +13781,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -14645,7 +14653,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 @@ -14653,7 +14661,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14729,11 +14737,11 @@ Investment apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14789,7 +14797,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14797,7 +14805,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14805,7 +14813,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14813,7 +14821,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14821,7 +14829,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -14833,7 +14841,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14865,7 +14873,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -14873,7 +14881,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index 581bdc55c..283dcd868 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -23,7 +23,7 @@ Il rischio di perdita nel trading può essere notevole. Non è consigliabile investire denaro di cui potresti avere bisogno a breve termine. apps/client/src/app/app.component.html - 179 + 184 @@ -95,7 +95,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -131,7 +131,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -271,7 +271,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -327,7 +331,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -475,7 +479,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -491,7 +495,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -519,7 +523,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -535,7 +539,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -555,7 +559,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -583,7 +587,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -1490,11 +1494,11 @@ Settori apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1510,11 +1514,11 @@ Paesi apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1590,7 +1594,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -1602,7 +1606,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -1614,7 +1618,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -1626,7 +1630,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -1638,7 +1642,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -1874,7 +1878,7 @@ Vuoi davvero rimuovere questo metodo di accesso? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -1946,7 +1950,7 @@ Locale apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 @@ -1954,7 +1958,7 @@ Formato data e numero apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 @@ -1962,7 +1966,7 @@ Modalità Zen apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -1974,7 +1978,7 @@ Accesso con impronta digitale apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 @@ -1982,11 +1986,11 @@ ID utente apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 @@ -2054,11 +2058,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2494,7 +2498,7 @@ Nota apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2514,11 +2518,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2570,7 +2574,7 @@ Portafoglio apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -2866,11 +2870,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2926,7 +2930,7 @@ Settore apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2938,7 +2942,7 @@ Paese apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -2998,7 +3002,7 @@ Mensile apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 @@ -3046,7 +3050,7 @@ Filtra per... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -3074,7 +3078,7 @@ Funzionalità sperimentali apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 @@ -3082,7 +3086,7 @@ Benchmark apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -3122,7 +3126,7 @@ Aspetto apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 @@ -3130,7 +3134,7 @@ Auto apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -3138,7 +3142,7 @@ Chiaro apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 @@ -3146,7 +3150,7 @@ Scuro apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 @@ -3154,7 +3158,7 @@ Importo totale apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 @@ -3170,7 +3174,7 @@ Tasso di risparmio apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -3410,31 +3414,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -3462,7 +3470,7 @@ Mappatura dei simboli apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 @@ -3470,7 +3478,7 @@ Dividendi apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -3514,7 +3522,7 @@ Importa apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -3582,7 +3590,7 @@ Annuale apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -3662,7 +3670,7 @@ Esperienza priva di distrazioni per i periodi più turbolenti apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 @@ -3670,7 +3678,7 @@ Un'anteprima delle funzionalità in arrivo apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 @@ -4098,7 +4106,7 @@ Vuoi davvero eliminare tutte le tue attività? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -4522,7 +4530,7 @@ Configurazione dello scraper apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 @@ -9866,7 +9874,7 @@ ETF senza paesi apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 @@ -9874,7 +9882,7 @@ ETF senza settori apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 @@ -10006,7 +10014,7 @@ Autenticazione biometrica apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 @@ -10090,7 +10098,7 @@ Esporta dati apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -10098,7 +10106,7 @@ Valute apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 @@ -10478,7 +10486,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -10510,7 +10518,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -10770,19 +10778,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -11050,7 +11058,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -11066,7 +11074,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -11082,7 +11090,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -11114,7 +11122,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -11186,7 +11194,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -11222,7 +11230,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -13342,7 +13350,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 @@ -13422,7 +13430,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -13449,8 +13457,8 @@ Do you really want to delete this asset profile? Do you really want to delete this asset profile? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 @@ -13774,7 +13782,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -14646,7 +14654,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 @@ -14654,7 +14662,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14730,11 +14738,11 @@ Investment apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14790,7 +14798,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14798,7 +14806,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14806,7 +14814,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14814,7 +14822,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14822,7 +14830,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -14834,7 +14842,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14866,7 +14874,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -14874,7 +14882,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index 39d0d9532..4a2874300 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -22,7 +22,7 @@ Het risico op verlies bij handelen kan aanzienlijk zijn. Het is niet aan te raden om geld te investeren dat je misschien op korte termijn nodig heeft. apps/client/src/app/app.component.html - 179 + 184 @@ -94,7 +94,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -130,7 +130,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -270,7 +270,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -326,7 +330,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -474,7 +478,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -490,7 +494,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -518,7 +522,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -534,7 +538,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -554,7 +558,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -582,7 +586,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -1489,11 +1493,11 @@ Sectoren apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1509,11 +1513,11 @@ Landen apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1589,7 +1593,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -1601,7 +1605,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -1613,7 +1617,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -1625,7 +1629,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -1637,7 +1641,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -1873,7 +1877,7 @@ Wil je deze aanmeldingsmethode echt verwijderen? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -1945,7 +1949,7 @@ Locatie apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 @@ -1953,7 +1957,7 @@ Datum- en getalnotatie apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 @@ -1961,7 +1965,7 @@ Zen-modus apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -1973,7 +1977,7 @@ Aanmelden met vingerafdruk apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 @@ -1981,11 +1985,11 @@ Gebruikers-ID apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 @@ -2053,11 +2057,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2493,7 +2497,7 @@ Opmerking apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2513,11 +2517,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2569,7 +2573,7 @@ Portefeuille apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -2865,11 +2869,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2925,7 +2929,7 @@ Sector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2937,7 +2941,7 @@ Land apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -2997,7 +3001,7 @@ Maandelijks apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 @@ -3045,7 +3049,7 @@ Filter op... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -3073,7 +3077,7 @@ Experimentele functies apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 @@ -3081,7 +3085,7 @@ Benchmark apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -3121,7 +3125,7 @@ Weergave apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 @@ -3129,7 +3133,7 @@ Automatisch apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -3137,7 +3141,7 @@ Licht apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 @@ -3145,7 +3149,7 @@ Donker apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 @@ -3153,7 +3157,7 @@ Totaalbedrag apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 @@ -3169,7 +3173,7 @@ Spaarrente apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -3409,31 +3413,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -3461,7 +3469,7 @@ Symbool toewijzen apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 @@ -3469,7 +3477,7 @@ Dividend apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -3513,7 +3521,7 @@ Importeren apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -3581,7 +3589,7 @@ Jaarlijks apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -3661,7 +3669,7 @@ Afleidingsvrije ervaring voor roerige tijden apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 @@ -3669,7 +3677,7 @@ Voorproefje van nieuwe functionaliteit apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 @@ -4097,7 +4105,7 @@ Wil je echt al je activiteiten verwijderen? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -4521,7 +4529,7 @@ Scraper instellingen apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 @@ -9865,7 +9873,7 @@ ETF's zonder Landen apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 @@ -9873,7 +9881,7 @@ ETF's zonder Sectoren apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 @@ -10005,7 +10013,7 @@ Biometrische authenticatie apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 @@ -10089,7 +10097,7 @@ Exporteer Data apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -10097,7 +10105,7 @@ Valuta apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 @@ -10477,7 +10485,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -10509,7 +10517,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -10769,19 +10777,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -11049,7 +11057,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -11065,7 +11073,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -11081,7 +11089,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -11113,7 +11121,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -11185,7 +11193,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -11221,7 +11229,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -13341,7 +13349,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 @@ -13421,7 +13429,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -13448,8 +13456,8 @@ Do you really want to delete this asset profile? Do you really want to delete this asset profile? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 @@ -13773,7 +13781,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -14645,7 +14653,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 @@ -14653,7 +14661,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14729,11 +14737,11 @@ Investment apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14789,7 +14797,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14797,7 +14805,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14805,7 +14813,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14813,7 +14821,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14821,7 +14829,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -14833,7 +14841,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14865,7 +14873,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -14873,7 +14881,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf index f59f2652a..5a1611384 100644 --- a/apps/client/src/locales/messages.pl.xlf +++ b/apps/client/src/locales/messages.pl.xlf @@ -10,19 +10,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -290,7 +290,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -322,7 +322,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -582,7 +582,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -598,7 +598,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -630,7 +630,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -702,7 +702,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -718,7 +718,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -754,7 +754,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -1462,31 +1462,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -1498,7 +1502,7 @@ The risk of loss in trading can be substantial. It is not advisable to invest money you may need in the short term. apps/client/src/app/app.component.html - 179 + 184 @@ -1606,7 +1610,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -1670,7 +1674,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1722,11 +1726,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1838,7 +1842,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -1902,7 +1910,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2042,7 +2050,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2058,7 +2066,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2086,7 +2094,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2102,7 +2110,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2118,7 +2126,7 @@ Currencies apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 @@ -2126,7 +2134,7 @@ ETFs without Countries apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 @@ -2134,15 +2142,15 @@ ETFs without Sectors apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 Do you really want to delete this asset profile? Do you really want to delete this asset profile? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 @@ -2150,7 +2158,7 @@ Filter by... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -2162,11 +2170,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2186,11 +2194,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2210,7 +2218,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2238,7 +2246,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -2290,7 +2298,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -2314,7 +2322,7 @@ Import apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -2330,7 +2338,7 @@ Sector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2342,7 +2350,7 @@ Country apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -2358,11 +2366,11 @@ Sectors apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2378,11 +2386,11 @@ Countries apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2394,7 +2402,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 @@ -2402,7 +2410,7 @@ Symbol Mapping apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 @@ -2410,7 +2418,7 @@ Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 @@ -2418,7 +2426,7 @@ Note apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2854,7 +2862,7 @@ Portfolio apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -2866,7 +2874,7 @@ Benchmark apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -3154,7 +3162,7 @@ Total Amount apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 @@ -3162,7 +3170,7 @@ Savings Rate apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -3676,7 +3684,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -3688,7 +3696,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -3700,7 +3708,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -3712,7 +3720,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -3724,7 +3732,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -3824,7 +3832,7 @@ Do you really want to remove this sign in method? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -3872,7 +3880,7 @@ Locale apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 @@ -3880,7 +3888,7 @@ Date and number format apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 @@ -3888,7 +3896,7 @@ Appearance apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 @@ -3896,7 +3904,7 @@ Auto apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -3904,7 +3912,7 @@ Light apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 @@ -3912,7 +3920,7 @@ Dark apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 @@ -3920,7 +3928,7 @@ Zen Mode apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -3932,7 +3940,7 @@ Distraction-free experience for turbulent times apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 @@ -3940,7 +3948,7 @@ Biometric Authentication apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 @@ -3948,7 +3956,7 @@ Sign in with fingerprint apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 @@ -3956,7 +3964,7 @@ Experimental Features apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 @@ -3964,7 +3972,7 @@ Sneak peek at upcoming functionality apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 @@ -3972,11 +3980,11 @@ User ID apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 @@ -3984,7 +3992,7 @@ Export Data apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -4940,7 +4948,7 @@ Do you really want to delete all your activities? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -5372,7 +5380,7 @@ Dividend apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -5392,7 +5400,7 @@ Monthly apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 @@ -5400,7 +5408,7 @@ Yearly apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -13216,7 +13224,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -14648,7 +14656,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 @@ -14656,7 +14664,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14732,11 +14740,11 @@ Investment apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14792,7 +14800,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14800,7 +14808,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14808,7 +14816,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14816,7 +14824,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14824,7 +14832,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -14836,7 +14844,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14868,7 +14876,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -14876,7 +14884,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index 60d8a37cf..3970b11aa 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -6,7 +6,7 @@ O risco de perda em investimentos pode ser substancial. Não é aconselhável investir dinheiro que possa vir a precisar a curto prazo. apps/client/src/app/app.component.html - 179 + 184 @@ -106,7 +106,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -142,7 +142,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -194,11 +194,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -326,7 +326,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -374,7 +378,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -530,7 +534,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -546,7 +550,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -574,7 +578,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -590,7 +594,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -606,7 +610,7 @@ Filtrar por... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -618,11 +622,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -642,11 +646,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -666,7 +670,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -694,7 +698,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -970,7 +974,7 @@ Portefólio apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -982,7 +986,7 @@ Referência apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -1478,7 +1482,7 @@ Valor Total apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 @@ -1486,7 +1490,7 @@ Taxa de Poupança apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -1785,7 +1789,7 @@ Setor apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1797,7 +1801,7 @@ País apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -1813,11 +1817,11 @@ Setores apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1833,11 +1837,11 @@ Países apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -1897,7 +1901,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -1909,7 +1913,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -1921,7 +1925,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -1933,7 +1937,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -1945,7 +1949,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -2113,7 +2117,7 @@ Deseja realmente remover este método de início de sessão? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -2205,7 +2209,7 @@ Localidade apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 @@ -2213,7 +2217,7 @@ Formato de números e datas apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 @@ -2221,7 +2225,7 @@ Modo Zen apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -2233,7 +2237,7 @@ Aparência apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 @@ -2241,7 +2245,7 @@ Auto apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -2249,7 +2253,7 @@ Claro apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 @@ -2257,7 +2261,7 @@ Escuro apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 @@ -2265,7 +2269,7 @@ Iniciar sessão com impressão digital apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 @@ -2273,7 +2277,7 @@ Funcionalidades Experimentais apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 @@ -2281,11 +2285,11 @@ ID do Utilizador apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 @@ -2609,7 +2613,7 @@ Nota apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2805,7 +2809,7 @@ Mensalmente apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 @@ -3433,7 +3437,7 @@ Mapeamento de Símbolo apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 @@ -3453,31 +3457,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -3521,7 +3529,7 @@ Importar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -3537,7 +3545,7 @@ Dividendos apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -3581,7 +3589,7 @@ Anualmente apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -3661,7 +3669,7 @@ Experiência sem distrações para tempos turbulentos apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 @@ -3669,7 +3677,7 @@ Acesso antecipado a funcionalidades futuras apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 @@ -4097,7 +4105,7 @@ Deseja mesmo eliminar todas as suas atividades? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -4521,7 +4529,7 @@ Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 @@ -9865,7 +9873,7 @@ ETFs without Countries apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 @@ -9873,7 +9881,7 @@ ETFs without Sectors apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 @@ -10005,7 +10013,7 @@ Biometric Authentication apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 @@ -10089,7 +10097,7 @@ Export Data apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -10097,7 +10105,7 @@ Currencies apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 @@ -10477,7 +10485,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -10509,7 +10517,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -10769,19 +10777,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -11049,7 +11057,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -11065,7 +11073,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -11081,7 +11089,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -11113,7 +11121,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -11185,7 +11193,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -11221,7 +11229,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -13341,7 +13349,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 @@ -13421,7 +13429,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -13448,8 +13456,8 @@ Do you really want to delete this asset profile? Do you really want to delete this asset profile? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 @@ -13773,7 +13781,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -14645,7 +14653,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 @@ -14653,7 +14661,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14729,11 +14737,11 @@ Investment apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14789,7 +14797,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14797,7 +14805,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14805,7 +14813,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14813,7 +14821,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14821,7 +14829,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -14833,7 +14841,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14865,7 +14873,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -14873,7 +14881,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 diff --git a/apps/client/src/locales/messages.tr.xlf b/apps/client/src/locales/messages.tr.xlf index ae9ae985c..2052e6667 100644 --- a/apps/client/src/locales/messages.tr.xlf +++ b/apps/client/src/locales/messages.tr.xlf @@ -10,19 +10,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -290,7 +290,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -322,7 +322,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -582,7 +582,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -598,7 +598,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -630,7 +630,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -702,7 +702,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -718,7 +718,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -754,7 +754,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -1438,31 +1438,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -1474,7 +1478,7 @@ Alım satımda kayıp riski büyük boyutta olabilir. Kısa vadede ihtiyaç duyabileceğiniz parayla yatırım yapmak tavsiye edilmez. apps/client/src/app/app.component.html - 179 + 184 @@ -1598,7 +1602,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -1634,7 +1638,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1686,11 +1690,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1802,7 +1806,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -1850,7 +1858,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2006,7 +2014,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2022,7 +2030,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2050,7 +2058,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2066,7 +2074,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2082,7 +2090,7 @@ Para Birimleri apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 @@ -2090,7 +2098,7 @@ Ülkesi Olmayan ETF'ler apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 @@ -2098,7 +2106,7 @@ Sektörü Olmayan ETF'ler apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 @@ -2106,7 +2114,7 @@ Filtrele... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -2118,11 +2126,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2142,11 +2150,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2166,7 +2174,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2194,7 +2202,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -2262,7 +2270,7 @@ Sektör apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2274,7 +2282,7 @@ Ülke apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -2290,11 +2298,11 @@ Sektörler apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2310,11 +2318,11 @@ Ülkeler apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2326,7 +2334,7 @@ Sembol Eşleştirme apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 @@ -2334,7 +2342,7 @@ Veri Toplayıcı Yapılandırması apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 @@ -2342,7 +2350,7 @@ Not apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2714,7 +2722,7 @@ Portföy apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -2726,7 +2734,7 @@ Karşılaştırma Ölçütü apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -3006,7 +3014,7 @@ Toplam Tutar apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 @@ -3014,7 +3022,7 @@ Tasarruf Oranı apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -3517,7 +3525,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -3529,7 +3537,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -3541,7 +3549,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -3553,7 +3561,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -3565,7 +3573,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -3941,7 +3949,7 @@ Zen Modu apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -4441,7 +4449,7 @@ Tüm işlemlerinizi silmeyi gerçekten istiyor musunuz? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -4653,7 +4661,7 @@ İçe Aktar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -4849,7 +4857,7 @@ Temettü apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -4869,7 +4877,7 @@ Aylık apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 @@ -4877,7 +4885,7 @@ Yıllık apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -12353,7 +12361,7 @@ Bu giriş yöntemini kaldırmayı gerçekten istiyor musunuz? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -12437,7 +12445,7 @@ Yerel Ayarlar apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 @@ -12445,7 +12453,7 @@ Tarih ve Sayı Formatları apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 @@ -12453,7 +12461,7 @@ Görünüm apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 @@ -12461,7 +12469,7 @@ Otomatik apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -12469,7 +12477,7 @@ Açık apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 @@ -12477,7 +12485,7 @@ Koyu apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 @@ -12485,7 +12493,7 @@ Çalkantılı zamanlar için dikkat dağıtmayan bir deneyim apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 @@ -12493,7 +12501,7 @@ Biyometrik Kimlik Doğrulama apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 @@ -12501,7 +12509,7 @@ Parmak iziyle oturum aç apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 @@ -12509,7 +12517,7 @@ Deneysel Özellikler apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 @@ -12517,7 +12525,7 @@ Gelecek özelliklere göz atın apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 @@ -12525,11 +12533,11 @@ Kullanıcı Kimliği apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 @@ -12537,7 +12545,7 @@ Verileri Dışa Aktar apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -13341,7 +13349,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 @@ -13421,7 +13429,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -13448,8 +13456,8 @@ Do you really want to delete this asset profile? Do you really want to delete this asset profile? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 @@ -13773,7 +13781,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -14645,7 +14653,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 @@ -14653,7 +14661,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14729,11 +14737,11 @@ Investment apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14789,7 +14797,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14797,7 +14805,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14805,7 +14813,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14813,7 +14821,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14821,7 +14829,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -14833,7 +14841,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14865,7 +14873,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -14873,7 +14881,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index b5fca055a..1cb9af6dd 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -10,19 +10,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -289,7 +289,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -320,7 +320,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -579,7 +579,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -594,7 +594,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -625,7 +625,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -696,7 +696,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -711,7 +711,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -746,7 +746,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -1440,31 +1440,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -1475,7 +1479,7 @@ The risk of loss in trading can be substantial. It is not advisable to invest money you may need in the short term. apps/client/src/app/app.component.html - 179 + 184 @@ -1574,7 +1578,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -1642,7 +1646,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1692,11 +1696,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1805,7 +1809,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -1865,7 +1873,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -1992,7 +2000,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2008,7 +2016,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2035,7 +2043,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2051,7 +2059,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2066,35 +2074,35 @@ Currencies apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 ETFs without Countries apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 ETFs without Sectors apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 Do you really want to delete this asset profile? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 Filter by... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -2105,11 +2113,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2128,11 +2136,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2151,7 +2159,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2177,7 +2185,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -2223,7 +2231,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -2244,7 +2252,7 @@ Import apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -2259,7 +2267,7 @@ Sector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2270,7 +2278,7 @@ Country apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -2285,11 +2293,11 @@ Sectors apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2304,11 +2312,11 @@ Countries apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2319,28 +2327,28 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 Symbol Mapping apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 Note apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2736,7 +2744,7 @@ Portfolio apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -2747,7 +2755,7 @@ Benchmark apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -3005,14 +3013,14 @@ Total Amount apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 Savings Rate apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -3476,7 +3484,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -3487,7 +3495,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -3498,7 +3506,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -3509,7 +3517,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -3520,7 +3528,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -3608,7 +3616,7 @@ Do you really want to remove this sign in method? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -3650,49 +3658,49 @@ Locale apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 Date and number format apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 Appearance apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 Auto apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 Light apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 Dark apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 Zen Mode apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -3703,53 +3711,53 @@ Distraction-free experience for turbulent times apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 Biometric Authentication apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 Sign in with fingerprint apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 Experimental Features apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 Sneak peek at upcoming functionality apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 User ID apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 Export Data apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -4603,7 +4611,7 @@ Do you really want to delete all your activities? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -4988,7 +4996,7 @@ Dividend apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -5006,14 +5014,14 @@ Monthly apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 Yearly apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -13533,7 +13541,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -14067,14 +14075,14 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14156,11 +14164,11 @@ Investment apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14188,35 +14196,35 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 Week to date libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 Month to date libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 MTD libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 WTD libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14234,7 +14242,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14255,14 +14263,14 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 years libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index 2887d5724..7ff1ce5bb 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -1,6 +1,6 @@ - + about @@ -11,19 +11,19 @@ apps/client/src/app/app.component.ts - 47 + 48 apps/client/src/app/app.component.ts - 48 + 49 apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/app.component.ts - 51 + 52 apps/client/src/app/components/header/header.component.ts @@ -291,7 +291,7 @@ apps/client/src/app/app.component.ts - 54 + 55 apps/client/src/app/pages/about/overview/about-overview-page.component.ts @@ -323,7 +323,7 @@ apps/client/src/app/app.component.ts - 55 + 56 apps/client/src/app/components/header/header.component.ts @@ -583,7 +583,7 @@ apps/client/src/app/app.component.ts - 49 + 50 apps/client/src/app/pages/about/about-page.component.ts @@ -599,7 +599,7 @@ apps/client/src/app/app.component.ts - 56 + 57 apps/client/src/app/components/header/header.component.ts @@ -631,7 +631,7 @@ apps/client/src/app/app.component.ts - 57 + 58 apps/client/src/app/components/header/header.component.ts @@ -703,7 +703,7 @@ apps/client/src/app/app.component.ts - 52 + 53 apps/client/src/app/pages/about/about-page.component.ts @@ -719,7 +719,7 @@ apps/client/src/app/app.component.ts - 58 + 59 apps/client/src/app/components/header/header.component.ts @@ -755,7 +755,7 @@ apps/client/src/app/app.component.ts - 59 + 60 apps/client/src/app/components/header/header.component.ts @@ -1463,31 +1463,35 @@ apps/client/src/app/components/user-account-settings/user-account-settings.html - 80 + 81 apps/client/src/app/components/user-account-settings/user-account-settings.html - 84 + 86 apps/client/src/app/components/user-account-settings/user-account-settings.html - 88 + 90 apps/client/src/app/components/user-account-settings/user-account-settings.html - 92 + 94 apps/client/src/app/components/user-account-settings/user-account-settings.html - 96 + 98 apps/client/src/app/components/user-account-settings/user-account-settings.html - 100 + 103 apps/client/src/app/components/user-account-settings/user-account-settings.html - 104 + 108 + + + apps/client/src/app/components/user-account-settings/user-account-settings.html + 112 apps/client/src/app/pages/features/features-page.html @@ -1499,7 +1503,7 @@ 交易损失的风险可能很大。不建议将短期内可能需要的资金进行投资。 apps/client/src/app/app.component.html - 179 + 184 @@ -1607,7 +1611,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 122 + 139 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -1679,7 +1683,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 197 + 214 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1731,11 +1735,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 103 + 120 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 203 + 220 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1847,7 +1851,11 @@ apps/client/src/app/components/admin-market-data/admin-market-data.html - 190 + 194 + + + apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html + 62 apps/client/src/app/components/admin-overview/admin-overview.html @@ -1911,7 +1919,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 98 + 115 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2003,8 +2011,8 @@ - Details for - 详细信息 + Details for + 详细信息 apps/client/src/app/components/admin-market-data-detail/market-data-detail-dialog/market-data-detail-dialog.html 2 @@ -2051,7 +2059,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 330 + 347 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2067,7 +2075,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 60 + 58 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2095,7 +2103,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 337 + 354 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2111,7 +2119,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 67 + 65 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2127,7 +2135,7 @@ 货币 apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 67 + 72 @@ -2135,7 +2143,7 @@ 没有国家的 ETF apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 72 + 77 @@ -2143,15 +2151,15 @@ 无行业类别的 ETF apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 77 + 82 Do you really want to delete this asset profile? 您确实要删除此资产配置文件吗? - apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 185 + apps/client/src/app/components/admin-market-data/admin-market-data.service.ts + 13 @@ -2159,7 +2167,7 @@ 过滤... apps/client/src/app/components/admin-market-data/admin-market-data.component.ts - 282 + 281 @@ -2171,11 +2179,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 131 + 148 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 212 + 229 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2195,11 +2203,11 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 140 + 157 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 225 + 242 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2219,7 +2227,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 113 + 130 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2247,7 +2255,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 65 + 82 @@ -2299,7 +2307,7 @@ 哎呀!无法解析历史数据。 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 223 + 233 @@ -2323,7 +2331,7 @@ 导入 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 91 + 108 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -2339,7 +2347,7 @@ 行业 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 159 + 176 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2351,7 +2359,7 @@ 国家 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 168 + 185 apps/client/src/app/components/admin-users/admin-users.html @@ -2367,11 +2375,11 @@ 行业 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 173 + 190 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 295 + 312 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2387,11 +2395,11 @@ 国家 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 183 + 200 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 306 + 323 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -2403,7 +2411,7 @@ 基准 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 253 + 270 @@ -2411,7 +2419,7 @@ 符号映射 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 259 + 276 @@ -2419,7 +2427,7 @@ 刮削配置 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 287 @@ -2427,7 +2435,7 @@ 笔记 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 317 + 334 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2483,8 +2491,8 @@ - is an invalid currency! - 是无效的货币! + is an invalid currency! + 是无效的货币! apps/client/src/app/components/admin-overview/admin-overview.component.ts 129 @@ -2871,7 +2879,7 @@ 文件夹 apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 110 + 116 apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -2883,7 +2891,7 @@ 基准 apps/client/src/app/components/benchmark-comparator/benchmark-comparator.component.ts - 119 + 128 @@ -3043,8 +3051,8 @@ - Last Days - 最后的 + Last Days + 最后的 apps/client/src/app/components/home-market/home-market.html 6 @@ -3171,7 +3179,7 @@ 总金额 apps/client/src/app/components/investment-chart/investment-chart.component.ts - 191 + 142 @@ -3179,7 +3187,7 @@ 储蓄率 apps/client/src/app/components/investment-chart/investment-chart.component.ts - 263 + 214 @@ -3252,12 +3260,12 @@ - - + + - - + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html @@ -3693,7 +3701,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 99 + 188 @@ -3705,7 +3713,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -3717,7 +3725,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -3729,7 +3737,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 @@ -3741,7 +3749,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 117 + 209 @@ -3841,7 +3849,7 @@ 您确实要删除此登录方法吗? apps/client/src/app/components/user-account-settings/user-account-settings.component.ts - 188 + 189 @@ -3889,7 +3897,7 @@ 语言环境 apps/client/src/app/components/user-account-settings/user-account-settings.html - 113 + 121 @@ -3897,7 +3905,7 @@ 日期和数字格式 apps/client/src/app/components/user-account-settings/user-account-settings.html - 115 + 123 @@ -3905,7 +3913,7 @@ 外貌 apps/client/src/app/components/user-account-settings/user-account-settings.html - 138 + 146 @@ -3913,7 +3921,7 @@ 自动 apps/client/src/app/components/user-account-settings/user-account-settings.html - 152 + 160 @@ -3921,7 +3929,7 @@ 明亮 apps/client/src/app/components/user-account-settings/user-account-settings.html - 153 + 161 @@ -3929,7 +3937,7 @@ 黑暗 apps/client/src/app/components/user-account-settings/user-account-settings.html - 154 + 162 @@ -3937,7 +3945,7 @@ 极简模式 apps/client/src/app/components/user-account-settings/user-account-settings.html - 163 + 171 apps/client/src/app/pages/features/features-page.html @@ -3949,7 +3957,7 @@ 动荡时期的无干扰体验 apps/client/src/app/components/user-account-settings/user-account-settings.html - 164 + 172 @@ -3957,7 +3965,7 @@ 生物识别认证 apps/client/src/app/components/user-account-settings/user-account-settings.html - 180 + 188 @@ -3965,7 +3973,7 @@ 使用指纹登录 apps/client/src/app/components/user-account-settings/user-account-settings.html - 181 + 189 @@ -3973,7 +3981,7 @@ 实验性功能 apps/client/src/app/components/user-account-settings/user-account-settings.html - 198 + 206 @@ -3981,7 +3989,7 @@ 预览即将推出的功能 apps/client/src/app/components/user-account-settings/user-account-settings.html - 199 + 207 @@ -3989,11 +3997,11 @@ 用户身份 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 47 + 45 apps/client/src/app/components/user-account-settings/user-account-settings.html - 215 + 223 @@ -4001,7 +4009,7 @@ 导出数据 apps/client/src/app/components/user-account-settings/user-account-settings.html - 223 + 231 @@ -4621,8 +4629,8 @@ - Protect your assets. Refine your personal investment strategy. - 保护你的资产。完善你的个人投资策略 + Protect your assets. Refine your personal investment strategy. + 保护你的资产。完善你的个人投资策略 apps/client/src/app/pages/landing/landing-page.html 221 @@ -4685,8 +4693,8 @@ - Why Ghostfolio? - 为什么使用Ghostfolio + Why Ghostfolio? + 为什么使用Ghostfolio apps/client/src/app/pages/landing/landing-page.html 268 @@ -4757,8 +4765,8 @@ - saying no to spreadsheets in - 对电子表格说不 + saying no to spreadsheets in + 对电子表格说不 apps/client/src/app/pages/landing/landing-page.html 307 @@ -4781,24 +4789,24 @@ - What our users are saying - 我们的什么用户正在说 + What our users are saying + 我们的什么用户正在说 apps/client/src/app/pages/landing/landing-page.html 323 - Members from around the globe are using Ghostfolio Premium - 来自世界各地的会员正在使用Ghostfolio 高级版 + Members from around the globe are using Ghostfolio Premium + 来自世界各地的会员正在使用Ghostfolio 高级版 apps/client/src/app/pages/landing/landing-page.html 355 - How does Ghostfolio work? - 如何幽灵作品集工作? + How does Ghostfolio work? + 如何幽灵作品集工作? apps/client/src/app/pages/landing/landing-page.html 367 @@ -4821,8 +4829,8 @@ - * no e-mail address nor credit card required - * 无需电子邮件地址或信用卡 + * no e-mail address nor credit card required + * 无需电子邮件地址或信用卡 apps/client/src/app/pages/landing/landing-page.html 378 @@ -4845,24 +4853,24 @@ - Are you ready? - 准备好? + Are you ready? + 准备好? apps/client/src/app/pages/landing/landing-page.html 413 - Join now or check out the example account - 立即加入或查看示例帐户 + Join now or check out the example account + 立即加入或查看示例帐户 apps/client/src/app/pages/landing/landing-page.html 414 - At Ghostfolio, transparency is at the core of our values. We publish the source code as open source software (OSS) under the AGPL-3.0 license and we openly share aggregated key metrics of the platform’s operational status. - 在 Ghostfolio,透明度是我们价值观的核心。我们将源代码发布为开源软件(OSS)下AGPL-3.0许可证我们公开分享平台运营状态的汇总关键指标。 + At Ghostfolio, transparency is at the core of our values. We publish the source code as open source software (OSS) under the AGPL-3.0 license and we openly share aggregated key metrics of the platform’s operational status. + 在 Ghostfolio,透明度是我们价值观的核心。我们将源代码发布为开源软件(OSS)下AGPL-3.0许可证我们公开分享平台运营状态的汇总关键指标。 apps/client/src/app/pages/open/open-page.html 6 @@ -4957,7 +4965,7 @@ 您真的要删除所有活动吗? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 168 + 171 @@ -5389,7 +5397,7 @@ 股息 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 42 + 43 libs/ui/src/lib/i18n.ts @@ -5409,7 +5417,7 @@ 每月 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 54 + 55 @@ -5417,7 +5425,7 @@ 每年 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 55 + 56 @@ -5585,8 +5593,8 @@ - If you prefer to run Ghostfolio on your own infrastructure, please find the source code and further instructions on GitHub. - 如果你希望在自己的基础设施上运行 Ghostfolio,请查看源代码和进一步的说明GitHub + If you prefer to run Ghostfolio on your own infrastructure, please find the source code and further instructions on GitHub. + 如果你希望在自己的基础设施上运行 Ghostfolio,请查看源代码和进一步的说明GitHub apps/client/src/app/pages/pricing/pricing-page.html 24 @@ -5769,8 +5777,8 @@ - Hello, has shared a Portfolio with you! - 你好,分享了一个文件夹与你! + Hello, has shared a Portfolio with you! + 你好,分享了一个文件夹与你! apps/client/src/app/pages/public/public-page.html 4 @@ -5833,8 +5841,8 @@ - I agree to have stored my Security Token from above in a secure place. If I lose it, I cannot get my account back. - 我同意存储我的保安编码器从上面看,在一个安全的地方。如果我丢失了它,我将无法找回我的帐户。 + I agree to have stored my Security Token from above in a secure place. If I lose it, I cannot get my account back. + 我同意存储我的保安编码器从上面看,在一个安全的地方。如果我丢失了它,我将无法找回我的帐户。 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html 32 @@ -5869,8 +5877,8 @@ - Open Source Alternative to - 开源替代方案 + Open Source Alternative to + 开源替代方案 apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page-routing.module.ts 26 @@ -5885,8 +5893,8 @@ - This overview page features a curated collection of personal finance tools compared to the open source alternative Ghostfolio. If you value transparency, data privacy, and community collaboration, Ghostfolio provides an excellent opportunity to take control of your financial management. - 此概述页面包含与开源替代方案相比的精选个人理财工具集合Ghostfolio。如果您重视透明度、数据隐私和社区协作,Ghostfolio 提供了一个绝佳的机会来控制您的财务管理。 + This overview page features a curated collection of personal finance tools compared to the open source alternative Ghostfolio. If you value transparency, data privacy, and community collaboration, Ghostfolio provides an excellent opportunity to take control of your financial management. + 此概述页面包含与开源替代方案相比的精选个人理财工具集合Ghostfolio。如果您重视透明度、数据隐私和社区协作,Ghostfolio 提供了一个绝佳的机会来控制您的财务管理。 apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html 8 @@ -5901,8 +5909,8 @@ - Open Source Alternative to - 开源替代方案 + Open Source Alternative to + 开源替代方案 apps/client/src/app/pages/resources/personal-finance-tools/personal-finance-tools-page.html 38 @@ -6113,8 +6121,8 @@ - Are you looking for an open source alternative to ? Ghostfolio is a powerful portfolio management tool that provides individuals with a comprehensive platform to track, analyze, and optimize their investments. Whether you are an experienced investor or just starting out, Ghostfolio offers an intuitive user interface and a wide range of functionalities to help you make informed decisions and take control of your financial future. - 您是否正在寻找开源替代方案幽灵作品集是一个强大的投资组合管理工具,为个人提供一个全面的平台来跟踪、分析和优化他们的投资。无论您是经验丰富的投资者还是刚刚起步的投资者,Ghostfolio 都提供直观的用户界面和广泛的功能帮助您做出明智的决定并掌控您的财务未来。 + Are you looking for an open source alternative to ? Ghostfolio is a powerful portfolio management tool that provides individuals with a comprehensive platform to track, analyze, and optimize their investments. Whether you are an experienced investor or just starting out, Ghostfolio offers an intuitive user interface and a wide range of functionalities to help you make informed decisions and take control of your financial future. + 您是否正在寻找开源替代方案幽灵作品集是一个强大的投资组合管理工具,为个人提供一个全面的平台来跟踪、分析和优化他们的投资。无论您是经验丰富的投资者还是刚刚起步的投资者,Ghostfolio 都提供直观的用户界面和广泛的功能帮助您做出明智的决定并掌控您的财务未来。 apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 13 @@ -6317,8 +6325,8 @@ - Ghostfolio is an open source software (OSS), providing a cost-effective alternative to making it particularly suitable for individuals on a tight budget, such as those pursuing Financial Independence, Retire Early (FIRE). By leveraging the collective efforts of a community of developers and personal finance enthusiasts, Ghostfolio continuously enhances its capabilities, security, and user experience. - Ghostfolio 是一款开源软件 (OSS),提供了一种经济高效的替代方案使其特别适合预算紧张的个人,例如追求财务独立,提前退休(FIRE) 。通过利用开发者社区和个人理财爱好者的集体努力,Ghostfolio 不断增强其功能、安全性和用户体验。 + Ghostfolio is an open source software (OSS), providing a cost-effective alternative to making it particularly suitable for individuals on a tight budget, such as those pursuing Financial Independence, Retire Early (FIRE). By leveraging the collective efforts of a community of developers and personal finance enthusiasts, Ghostfolio continuously enhances its capabilities, security, and user experience. + Ghostfolio 是一款开源软件 (OSS),提供了一种经济高效的替代方案使其特别适合预算紧张的个人,例如追求财务独立,提前退休(FIRE) 。通过利用开发者社区和个人理财爱好者的集体努力,Ghostfolio 不断增强其功能、安全性和用户体验。 apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 27 @@ -6521,8 +6529,8 @@ - Let’s dive deeper into the detailed Ghostfolio vs comparison table below to gain a thorough understanding of how Ghostfolio positions itself relative to . We will explore various aspects such as features, data privacy, pricing, and more, allowing you to make a well-informed choice for your personal requirements. - 让我们更深入地了解 Ghostfolio 与下面的比较表可帮助您全面了解 Ghostfolio 相对于其他产品的定位。我们将探讨功能、数据隐私、定价等各个方面,让您根据个人需求做出明智的选择。 + Let’s dive deeper into the detailed Ghostfolio vs comparison table below to gain a thorough understanding of how Ghostfolio positions itself relative to . We will explore various aspects such as features, data privacy, pricing, and more, allowing you to make a well-informed choice for your personal requirements. + 让我们更深入地了解 Ghostfolio 与下面的比较表可帮助您全面了解 Ghostfolio 相对于其他产品的定位。我们将探讨功能、数据隐私、定价等各个方面,让您根据个人需求做出明智的选择。 apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 38 @@ -6725,8 +6733,8 @@ - Ghostfolio vs comparison table - Ghostfolio vs比较表 + Ghostfolio vs comparison table + Ghostfolio vs比较表 apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 49 @@ -12581,8 +12589,8 @@ - Please note that the information provided in the Ghostfolio vs comparison table is based on our independent research and analysis. This website is not affiliated with or any other product mentioned in the comparison. As the landscape of personal finance tools evolves, it is essential to verify any specific details or changes directly from the respective product page. Data needs a refresh? Help us maintain accurate data on GitHub. - 请注意,Ghostfolio 与 Ghostfolio 中提供的信息比较表基于我们的独立研究和分析。该网站不隶属于或比较中提到的任何其他产品。随着个人理财工具格局的不断发展,直接从相应的产品页面验证任何具体的细节或变化至关重要。数据需要刷新吗?帮助我们维护准确的数据GitHub + Please note that the information provided in the Ghostfolio vs comparison table is based on our independent research and analysis. This website is not affiliated with or any other product mentioned in the comparison. As the landscape of personal finance tools evolves, it is essential to verify any specific details or changes directly from the respective product page. Data needs a refresh? Help us maintain accurate data on GitHub. + 请注意,Ghostfolio 与 Ghostfolio 中提供的信息比较表基于我们的独立研究和分析。该网站不隶属于或比较中提到的任何其他产品。随着个人理财工具格局的不断发展,直接从相应的产品页面验证任何具体的细节或变化至关重要。数据需要刷新吗?帮助我们维护准确的数据GitHub apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 210 @@ -12785,8 +12793,8 @@ - Ready to take your investments to the next level? - 准备好带走你的投资下一级 + Ready to take your investments to the next level? + 准备好带走你的投资下一级 apps/client/src/app/pages/resources/personal-finance-tools/product-page-template.html 223 @@ -14049,7 +14057,7 @@ 查找持有... libs/ui/src/lib/assistant/assistant.component.ts - 126 + 111 @@ -14637,8 +14645,8 @@ - If a translation is missing, kindly support us in extending it here. - 如果翻译缺失,请支持我们进行扩展这里 + If a translation is missing, kindly support us in extending it here. + 如果翻译缺失,请支持我们进行扩展这里 apps/client/src/app/components/user-account-settings/user-account-settings.html 55 @@ -14657,7 +14665,7 @@ 当前市场价格为 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 317 + 327 @@ -14665,7 +14673,7 @@ 测试 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 288 + 305 @@ -14757,11 +14765,11 @@ 投资 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 46 + 47 apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts - 60 + 61 @@ -14793,7 +14801,7 @@ 今年迄今为止 libs/ui/src/lib/assistant/assistant.component.ts - 109 + 198 @@ -14801,7 +14809,7 @@ 本周至今 libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14809,7 +14817,7 @@ 本月至今 libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14817,7 +14825,7 @@ 最大输运量 libs/ui/src/lib/assistant/assistant.component.ts - 105 + 194 @@ -14825,7 +14833,7 @@ 世界贸易组织 libs/ui/src/lib/assistant/assistant.component.ts - 101 + 190 @@ -14845,7 +14853,7 @@ apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html - 39 + 38 @@ -14857,8 +14865,8 @@ - If you retire today, you would be able to withdraw per year or per month, based on your total assets of and a withdrawal rate of 4%. - 如果你今天退休,你可以领取每年或者每月,根据您的总资产提款率为4%。 + If you retire today, you would be able to withdraw per year or per month, based on your total assets of and a withdrawal rate of 4%. + 如果你今天退休,你可以领取每年或者每月,根据您的总资产提款率为4%。 apps/client/src/app/pages/portfolio/fire/fire-page.html 68 @@ -14869,7 +14877,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 112 + 202 @@ -14877,7 +14885,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 114 + 206 From 8cd6c34ed83071cb93124a34b17cff1bc740294d Mon Sep 17 00:00:00 2001 From: Francisco Silva Date: Sun, 31 Mar 2024 20:07:58 +0200 Subject: [PATCH 086/203] Feature/introduce portfolio calculator factory (#3214) * Introduce portfolio calculator factory * Update changelog --- CHANGELOG.md | 1 + .../calculator/mwr/portfolio-calculator.ts | 37 + .../portfolio-calculator-test-utils.ts | 25 + .../portfolio-calculator.factory.ts | 51 ++ .../calculator/portfolio-calculator.ts | 788 ++++++++++++++++++ ...aln-buy-and-sell-in-two-activities.spec.ts | 107 ++- ...folio-calculator-baln-buy-and-sell.spec.ts | 81 +- .../twr/portfolio-calculator-baln-buy.spec.ts | 55 +- ...ator-btcusd-buy-and-sell-partially.spec.ts | 81 +- .../portfolio-calculator-googl-buy.spec.ts | 55 +- ...-calculator-msft-buy-with-dividend.spec.ts | 81 +- .../portfolio-calculator-no-orders.spec.ts | 20 +- ...ulator-novn-buy-and-sell-partially.spec.ts | 82 +- ...folio-calculator-novn-buy-and-sell.spec.ts | 81 +- .../twr/portfolio-calculator.spec.ts | 25 +- .../calculator/twr/portfolio-calculator.ts | 765 +---------------- .../interfaces/current-positions.interface.ts | 1 + ...e.ts => portfolio-order-item.interface.ts} | 0 .../api/src/app/portfolio/portfolio.module.ts | 2 + .../src/app/portfolio/portfolio.service.ts | 75 +- 20 files changed, 1361 insertions(+), 1052 deletions(-) create mode 100644 apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts create mode 100644 apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts create mode 100644 apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts create mode 100644 apps/api/src/app/portfolio/calculator/portfolio-calculator.ts rename apps/api/src/app/portfolio/interfaces/{portfolio-calculator.interface.ts => portfolio-order-item.interface.ts} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ce4ef296..7a0b55060 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Improved the usability of the date range support by specific years (`2023`, `2022`, `2021`, etc.) in the assistant (experimental) +- Introduced a factory for the portfolio calculations to support different algorithms in future ## 2.69.0 - 2024-03-30 diff --git a/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts new file mode 100644 index 000000000..ec744f624 --- /dev/null +++ b/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts @@ -0,0 +1,37 @@ +import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; +import { CurrentPositions } from '@ghostfolio/api/app/portfolio/interfaces/current-positions.interface'; +import { + SymbolMetrics, + TimelinePosition, + UniqueAsset +} from '@ghostfolio/common/interfaces'; + +export class MWRPortfolioCalculator extends PortfolioCalculator { + protected calculateOverallPerformance( + positions: TimelinePosition[] + ): CurrentPositions { + throw new Error('Method not implemented.'); + } + + protected getSymbolMetrics({ + dataSource, + end, + exchangeRates, + isChartMode = false, + marketSymbolMap, + start, + step = 1, + symbol + }: { + end: Date; + exchangeRates: { [dateString: string]: number }; + isChartMode?: boolean; + marketSymbolMap: { + [date: string]: { [symbol: string]: Big }; + }; + start: Date; + step?: number; + } & UniqueAsset): SymbolMetrics { + throw new Error('Method not implemented.'); + } +} diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts new file mode 100644 index 000000000..6d1939fcd --- /dev/null +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts @@ -0,0 +1,25 @@ +export const activityDummyData = { + accountId: undefined, + accountUserId: undefined, + comment: undefined, + createdAt: new Date(), + feeInBaseCurrency: undefined, + id: undefined, + isDraft: false, + symbolProfileId: undefined, + updatedAt: new Date(), + userId: undefined, + value: undefined, + valueInBaseCurrency: undefined +}; + +export const symbolProfileDummyData = { + activitiesCount: undefined, + assetClass: undefined, + assetSubClass: undefined, + countries: [], + createdAt: undefined, + id: undefined, + sectors: [], + updatedAt: undefined +}; diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts new file mode 100644 index 000000000..cf1fe9324 --- /dev/null +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts @@ -0,0 +1,51 @@ +import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; +import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; + +import { Injectable } from '@nestjs/common'; + +import { MWRPortfolioCalculator } from './mwr/portfolio-calculator'; +import { PortfolioCalculator } from './portfolio-calculator'; +import { TWRPortfolioCalculator } from './twr/portfolio-calculator'; + +export enum PerformanceCalculationType { + MWR = 'MWR', // Money-Weighted Rate of Return + TWR = 'TWR' // Time-Weighted Rate of Return +} + +@Injectable() +export class PortfolioCalculatorFactory { + public constructor( + private readonly currentRateService: CurrentRateService, + private readonly exchangeRateDataService: ExchangeRateDataService + ) {} + + public createCalculator({ + activities, + calculationType, + currency + }: { + activities: Activity[]; + calculationType: PerformanceCalculationType; + currency: string; + }): PortfolioCalculator { + switch (calculationType) { + case PerformanceCalculationType.MWR: + return new MWRPortfolioCalculator({ + activities, + currency, + currentRateService: this.currentRateService, + exchangeRateDataService: this.exchangeRateDataService + }); + case PerformanceCalculationType.TWR: + return new TWRPortfolioCalculator({ + activities, + currency, + currentRateService: this.currentRateService, + exchangeRateDataService: this.exchangeRateDataService + }); + default: + throw new Error('Invalid calculation type'); + } + } +} diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts new file mode 100644 index 000000000..c3edc86d9 --- /dev/null +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -0,0 +1,788 @@ +import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; +import { CurrentPositions } from '@ghostfolio/api/app/portfolio/interfaces/current-positions.interface'; +import { PortfolioOrder } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order.interface'; +import { TransactionPointSymbol } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point-symbol.interface'; +import { TransactionPoint } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point.interface'; +import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; +import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; +import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; +import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper'; +import { + DataProviderInfo, + HistoricalDataItem, + InvestmentItem, + ResponseError, + SymbolMetrics, + TimelinePosition, + UniqueAsset +} from '@ghostfolio/common/interfaces'; +import { GroupBy } from '@ghostfolio/common/types'; + +import { Big } from 'big.js'; +import { + eachDayOfInterval, + endOfDay, + format, + isBefore, + isSameDay, + max, + subDays +} from 'date-fns'; +import { isNumber, last, uniq } from 'lodash'; + +export abstract class PortfolioCalculator { + protected static readonly ENABLE_LOGGING = false; + + protected orders: PortfolioOrder[]; + + private currency: string; + private currentRateService: CurrentRateService; + private dataProviderInfos: DataProviderInfo[]; + private exchangeRateDataService: ExchangeRateDataService; + private transactionPoints: TransactionPoint[]; + + public constructor({ + activities, + currency, + currentRateService, + exchangeRateDataService + }: { + activities: Activity[]; + currency: string; + currentRateService: CurrentRateService; + exchangeRateDataService: ExchangeRateDataService; + }) { + this.currency = currency; + this.currentRateService = currentRateService; + this.exchangeRateDataService = exchangeRateDataService; + this.orders = activities.map( + ({ date, fee, quantity, SymbolProfile, type, unitPrice }) => { + return { + SymbolProfile, + type, + date: format(date, DATE_FORMAT), + fee: new Big(fee), + quantity: new Big(quantity), + unitPrice: new Big(unitPrice) + }; + } + ); + + this.orders.sort((a, b) => { + return a.date?.localeCompare(b.date); + }); + + this.computeTransactionPoints(); + } + + protected abstract calculateOverallPerformance( + positions: TimelinePosition[] + ): CurrentPositions; + + public getAnnualizedPerformancePercent({ + daysInMarket, + netPerformancePercent + }: { + daysInMarket: number; + netPerformancePercent: Big; + }): Big { + if (isNumber(daysInMarket) && daysInMarket > 0) { + const exponent = new Big(365).div(daysInMarket).toNumber(); + return new Big( + Math.pow(netPerformancePercent.plus(1).toNumber(), exponent) + ).minus(1); + } + + return new Big(0); + } + + public async getChartData({ + end = new Date(Date.now()), + start, + step = 1 + }: { + end?: Date; + start: Date; + step?: number; + }): Promise { + const symbols: { [symbol: string]: boolean } = {}; + + const transactionPointsBeforeEndDate = + this.transactionPoints?.filter((transactionPoint) => { + return isBefore(parseDate(transactionPoint.date), end); + }) ?? []; + + const currencies: { [symbol: string]: string } = {}; + const dataGatheringItems: IDataGatheringItem[] = []; + const firstIndex = transactionPointsBeforeEndDate.length; + + let dates = eachDayOfInterval({ start, end }, { step }).map((date) => { + return resetHours(date); + }); + + const includesEndDate = isSameDay(last(dates), end); + + if (!includesEndDate) { + dates.push(resetHours(end)); + } + + if (transactionPointsBeforeEndDate.length > 0) { + for (const { + currency, + dataSource, + symbol + } of transactionPointsBeforeEndDate[firstIndex - 1].items) { + dataGatheringItems.push({ + dataSource, + symbol + }); + currencies[symbol] = currency; + symbols[symbol] = true; + } + } + + const { dataProviderInfos, values: marketSymbols } = + await this.currentRateService.getValues({ + dataGatheringItems, + dateQuery: { + in: dates + } + }); + + this.dataProviderInfos = dataProviderInfos; + + const marketSymbolMap: { + [date: string]: { [symbol: string]: Big }; + } = {}; + + let exchangeRatesByCurrency = + await this.exchangeRateDataService.getExchangeRatesByCurrency({ + currencies: uniq(Object.values(currencies)), + endDate: endOfDay(end), + startDate: this.getStartDate(), + targetCurrency: this.currency + }); + + for (const marketSymbol of marketSymbols) { + const dateString = format(marketSymbol.date, DATE_FORMAT); + if (!marketSymbolMap[dateString]) { + marketSymbolMap[dateString] = {}; + } + if (marketSymbol.marketPrice) { + marketSymbolMap[dateString][marketSymbol.symbol] = new Big( + marketSymbol.marketPrice + ); + } + } + + const accumulatedValuesByDate: { + [date: string]: { + investmentValueWithCurrencyEffect: Big; + totalCurrentValue: Big; + totalCurrentValueWithCurrencyEffect: Big; + totalInvestmentValue: Big; + totalInvestmentValueWithCurrencyEffect: Big; + totalNetPerformanceValue: Big; + totalNetPerformanceValueWithCurrencyEffect: Big; + totalTimeWeightedInvestmentValue: Big; + totalTimeWeightedInvestmentValueWithCurrencyEffect: Big; + }; + } = {}; + + const valuesBySymbol: { + [symbol: string]: { + currentValues: { [date: string]: Big }; + currentValuesWithCurrencyEffect: { [date: string]: Big }; + investmentValuesAccumulated: { [date: string]: Big }; + investmentValuesAccumulatedWithCurrencyEffect: { [date: string]: Big }; + investmentValuesWithCurrencyEffect: { [date: string]: Big }; + netPerformanceValues: { [date: string]: Big }; + netPerformanceValuesWithCurrencyEffect: { [date: string]: Big }; + timeWeightedInvestmentValues: { [date: string]: Big }; + timeWeightedInvestmentValuesWithCurrencyEffect: { [date: string]: Big }; + }; + } = {}; + + for (const symbol of Object.keys(symbols)) { + const { + currentValues, + currentValuesWithCurrencyEffect, + investmentValuesAccumulated, + investmentValuesAccumulatedWithCurrencyEffect, + investmentValuesWithCurrencyEffect, + netPerformanceValues, + netPerformanceValuesWithCurrencyEffect, + timeWeightedInvestmentValues, + timeWeightedInvestmentValuesWithCurrencyEffect + } = this.getSymbolMetrics({ + end, + marketSymbolMap, + start, + step, + symbol, + dataSource: null, + exchangeRates: + exchangeRatesByCurrency[`${currencies[symbol]}${this.currency}`], + isChartMode: true + }); + + valuesBySymbol[symbol] = { + currentValues, + currentValuesWithCurrencyEffect, + investmentValuesAccumulated, + investmentValuesAccumulatedWithCurrencyEffect, + investmentValuesWithCurrencyEffect, + netPerformanceValues, + netPerformanceValuesWithCurrencyEffect, + timeWeightedInvestmentValues, + timeWeightedInvestmentValuesWithCurrencyEffect + }; + } + + for (const currentDate of dates) { + const dateString = format(currentDate, DATE_FORMAT); + + for (const symbol of Object.keys(valuesBySymbol)) { + const symbolValues = valuesBySymbol[symbol]; + + const currentValue = + symbolValues.currentValues?.[dateString] ?? new Big(0); + + const currentValueWithCurrencyEffect = + symbolValues.currentValuesWithCurrencyEffect?.[dateString] ?? + new Big(0); + + const investmentValueAccumulated = + symbolValues.investmentValuesAccumulated?.[dateString] ?? new Big(0); + + const investmentValueAccumulatedWithCurrencyEffect = + symbolValues.investmentValuesAccumulatedWithCurrencyEffect?.[ + dateString + ] ?? new Big(0); + + const investmentValueWithCurrencyEffect = + symbolValues.investmentValuesWithCurrencyEffect?.[dateString] ?? + new Big(0); + + const netPerformanceValue = + symbolValues.netPerformanceValues?.[dateString] ?? new Big(0); + + const netPerformanceValueWithCurrencyEffect = + symbolValues.netPerformanceValuesWithCurrencyEffect?.[dateString] ?? + new Big(0); + + const timeWeightedInvestmentValue = + symbolValues.timeWeightedInvestmentValues?.[dateString] ?? new Big(0); + + const timeWeightedInvestmentValueWithCurrencyEffect = + symbolValues.timeWeightedInvestmentValuesWithCurrencyEffect?.[ + dateString + ] ?? new Big(0); + + accumulatedValuesByDate[dateString] = { + investmentValueWithCurrencyEffect: ( + accumulatedValuesByDate[dateString] + ?.investmentValueWithCurrencyEffect ?? new Big(0) + ).add(investmentValueWithCurrencyEffect), + totalCurrentValue: ( + accumulatedValuesByDate[dateString]?.totalCurrentValue ?? new Big(0) + ).add(currentValue), + totalCurrentValueWithCurrencyEffect: ( + accumulatedValuesByDate[dateString] + ?.totalCurrentValueWithCurrencyEffect ?? new Big(0) + ).add(currentValueWithCurrencyEffect), + totalInvestmentValue: ( + accumulatedValuesByDate[dateString]?.totalInvestmentValue ?? + new Big(0) + ).add(investmentValueAccumulated), + totalInvestmentValueWithCurrencyEffect: ( + accumulatedValuesByDate[dateString] + ?.totalInvestmentValueWithCurrencyEffect ?? new Big(0) + ).add(investmentValueAccumulatedWithCurrencyEffect), + totalNetPerformanceValue: ( + accumulatedValuesByDate[dateString]?.totalNetPerformanceValue ?? + new Big(0) + ).add(netPerformanceValue), + totalNetPerformanceValueWithCurrencyEffect: ( + accumulatedValuesByDate[dateString] + ?.totalNetPerformanceValueWithCurrencyEffect ?? new Big(0) + ).add(netPerformanceValueWithCurrencyEffect), + totalTimeWeightedInvestmentValue: ( + accumulatedValuesByDate[dateString] + ?.totalTimeWeightedInvestmentValue ?? new Big(0) + ).add(timeWeightedInvestmentValue), + totalTimeWeightedInvestmentValueWithCurrencyEffect: ( + accumulatedValuesByDate[dateString] + ?.totalTimeWeightedInvestmentValueWithCurrencyEffect ?? new Big(0) + ).add(timeWeightedInvestmentValueWithCurrencyEffect) + }; + } + } + + return Object.entries(accumulatedValuesByDate).map(([date, values]) => { + const { + investmentValueWithCurrencyEffect, + totalCurrentValue, + totalCurrentValueWithCurrencyEffect, + totalInvestmentValue, + totalInvestmentValueWithCurrencyEffect, + totalNetPerformanceValue, + totalNetPerformanceValueWithCurrencyEffect, + totalTimeWeightedInvestmentValue, + totalTimeWeightedInvestmentValueWithCurrencyEffect + } = values; + + const netPerformanceInPercentage = totalTimeWeightedInvestmentValue.eq(0) + ? 0 + : totalNetPerformanceValue + .div(totalTimeWeightedInvestmentValue) + .mul(100) + .toNumber(); + + const netPerformanceInPercentageWithCurrencyEffect = + totalTimeWeightedInvestmentValueWithCurrencyEffect.eq(0) + ? 0 + : totalNetPerformanceValueWithCurrencyEffect + .div(totalTimeWeightedInvestmentValueWithCurrencyEffect) + .mul(100) + .toNumber(); + + return { + date, + netPerformanceInPercentage, + netPerformanceInPercentageWithCurrencyEffect, + investmentValueWithCurrencyEffect: + investmentValueWithCurrencyEffect.toNumber(), + netPerformance: totalNetPerformanceValue.toNumber(), + netPerformanceWithCurrencyEffect: + totalNetPerformanceValueWithCurrencyEffect.toNumber(), + totalInvestment: totalInvestmentValue.toNumber(), + totalInvestmentValueWithCurrencyEffect: + totalInvestmentValueWithCurrencyEffect.toNumber(), + value: totalCurrentValue.toNumber(), + valueWithCurrencyEffect: totalCurrentValueWithCurrencyEffect.toNumber() + }; + }); + } + + public async getCurrentPositions( + start: Date, + end?: Date + ): Promise { + const lastTransactionPoint = last(this.transactionPoints); + + let endDate = end; + + if (!endDate) { + endDate = new Date(Date.now()); + + if (lastTransactionPoint) { + endDate = max([endDate, parseDate(lastTransactionPoint.date)]); + } + } + + const transactionPoints = this.transactionPoints?.filter(({ date }) => { + return isBefore(parseDate(date), endDate); + }); + + if (!transactionPoints.length) { + return { + currentValueInBaseCurrency: new Big(0), + grossPerformance: new Big(0), + grossPerformancePercentage: new Big(0), + grossPerformancePercentageWithCurrencyEffect: new Big(0), + grossPerformanceWithCurrencyEffect: new Big(0), + hasErrors: false, + netPerformance: new Big(0), + netPerformancePercentage: new Big(0), + netPerformancePercentageWithCurrencyEffect: new Big(0), + netPerformanceWithCurrencyEffect: new Big(0), + positions: [], + totalInvestment: new Big(0), + totalInvestmentWithCurrencyEffect: new Big(0) + }; + } + + const currencies: { [symbol: string]: string } = {}; + const dataGatheringItems: IDataGatheringItem[] = []; + let dates: Date[] = []; + let firstIndex = transactionPoints.length; + let firstTransactionPoint: TransactionPoint = null; + + dates.push(resetHours(start)); + + for (const { currency, dataSource, symbol } of transactionPoints[ + firstIndex - 1 + ].items) { + dataGatheringItems.push({ + dataSource, + symbol + }); + + currencies[symbol] = currency; + } + + for (let i = 0; i < transactionPoints.length; i++) { + if ( + !isBefore(parseDate(transactionPoints[i].date), start) && + firstTransactionPoint === null + ) { + firstTransactionPoint = transactionPoints[i]; + firstIndex = i; + } + + if (firstTransactionPoint !== null) { + dates.push(resetHours(parseDate(transactionPoints[i].date))); + } + } + + dates.push(resetHours(endDate)); + + // Add dates of last week for fallback + dates.push(subDays(resetHours(new Date()), 7)); + dates.push(subDays(resetHours(new Date()), 6)); + dates.push(subDays(resetHours(new Date()), 5)); + dates.push(subDays(resetHours(new Date()), 4)); + dates.push(subDays(resetHours(new Date()), 3)); + dates.push(subDays(resetHours(new Date()), 2)); + dates.push(subDays(resetHours(new Date()), 1)); + dates.push(resetHours(new Date())); + + dates = uniq( + dates.map((date) => { + return date.getTime(); + }) + ) + .map((timestamp) => { + return new Date(timestamp); + }) + .sort((a, b) => { + return a.getTime() - b.getTime(); + }); + + let exchangeRatesByCurrency = + await this.exchangeRateDataService.getExchangeRatesByCurrency({ + currencies: uniq(Object.values(currencies)), + endDate: endOfDay(endDate), + startDate: this.getStartDate(), + targetCurrency: this.currency + }); + + const { + dataProviderInfos, + errors: currentRateErrors, + values: marketSymbols + } = await this.currentRateService.getValues({ + dataGatheringItems, + dateQuery: { + in: dates + } + }); + + this.dataProviderInfos = dataProviderInfos; + + const marketSymbolMap: { + [date: string]: { [symbol: string]: Big }; + } = {}; + + for (const marketSymbol of marketSymbols) { + const date = format(marketSymbol.date, DATE_FORMAT); + + if (!marketSymbolMap[date]) { + marketSymbolMap[date] = {}; + } + + if (marketSymbol.marketPrice) { + marketSymbolMap[date][marketSymbol.symbol] = new Big( + marketSymbol.marketPrice + ); + } + } + + const endDateString = format(endDate, DATE_FORMAT); + + if (firstIndex > 0) { + firstIndex--; + } + + const positions: TimelinePosition[] = []; + let hasAnySymbolMetricsErrors = false; + + const errors: ResponseError['errors'] = []; + + for (const item of lastTransactionPoint.items) { + const marketPriceInBaseCurrency = ( + marketSymbolMap[endDateString]?.[item.symbol] ?? item.averagePrice + ).mul( + exchangeRatesByCurrency[`${item.currency}${this.currency}`]?.[ + endDateString + ] + ); + + const { + grossPerformance, + grossPerformancePercentage, + grossPerformancePercentageWithCurrencyEffect, + grossPerformanceWithCurrencyEffect, + hasErrors, + netPerformance, + netPerformancePercentage, + netPerformancePercentageWithCurrencyEffect, + netPerformanceWithCurrencyEffect, + timeWeightedInvestment, + timeWeightedInvestmentWithCurrencyEffect, + totalDividend, + totalDividendInBaseCurrency, + totalInvestment, + totalInvestmentWithCurrencyEffect + } = this.getSymbolMetrics({ + marketSymbolMap, + start, + dataSource: item.dataSource, + end: endDate, + exchangeRates: + exchangeRatesByCurrency[`${item.currency}${this.currency}`], + symbol: item.symbol + }); + + hasAnySymbolMetricsErrors = hasAnySymbolMetricsErrors || hasErrors; + + positions.push({ + dividend: totalDividend, + dividendInBaseCurrency: totalDividendInBaseCurrency, + timeWeightedInvestment, + timeWeightedInvestmentWithCurrencyEffect, + averagePrice: item.averagePrice, + currency: item.currency, + dataSource: item.dataSource, + fee: item.fee, + firstBuyDate: item.firstBuyDate, + grossPerformance: !hasErrors ? grossPerformance ?? null : null, + grossPerformancePercentage: !hasErrors + ? grossPerformancePercentage ?? null + : null, + grossPerformancePercentageWithCurrencyEffect: !hasErrors + ? grossPerformancePercentageWithCurrencyEffect ?? null + : null, + grossPerformanceWithCurrencyEffect: !hasErrors + ? grossPerformanceWithCurrencyEffect ?? null + : null, + investment: totalInvestment, + investmentWithCurrencyEffect: totalInvestmentWithCurrencyEffect, + marketPrice: + marketSymbolMap[endDateString]?.[item.symbol]?.toNumber() ?? null, + marketPriceInBaseCurrency: + marketPriceInBaseCurrency?.toNumber() ?? null, + netPerformance: !hasErrors ? netPerformance ?? null : null, + netPerformancePercentage: !hasErrors + ? netPerformancePercentage ?? null + : null, + netPerformancePercentageWithCurrencyEffect: !hasErrors + ? netPerformancePercentageWithCurrencyEffect ?? null + : null, + netPerformanceWithCurrencyEffect: !hasErrors + ? netPerformanceWithCurrencyEffect ?? null + : null, + quantity: item.quantity, + symbol: item.symbol, + tags: item.tags, + transactionCount: item.transactionCount, + valueInBaseCurrency: new Big(marketPriceInBaseCurrency).mul( + item.quantity + ) + }); + + if ( + (hasErrors || + currentRateErrors.find(({ dataSource, symbol }) => { + return dataSource === item.dataSource && symbol === item.symbol; + })) && + item.investment.gt(0) + ) { + errors.push({ dataSource: item.dataSource, symbol: item.symbol }); + } + } + + const overall = this.calculateOverallPerformance(positions); + + return { + ...overall, + errors, + positions, + hasErrors: hasAnySymbolMetricsErrors || overall.hasErrors + }; + } + + public getDataProviderInfos() { + return this.dataProviderInfos; + } + + public getInvestments(): { date: string; investment: Big }[] { + if (this.transactionPoints.length === 0) { + return []; + } + + return this.transactionPoints.map((transactionPoint) => { + return { + date: transactionPoint.date, + investment: transactionPoint.items.reduce( + (investment, transactionPointSymbol) => + investment.plus(transactionPointSymbol.investment), + new Big(0) + ) + }; + }); + } + + public getInvestmentsByGroup({ + data, + groupBy + }: { + data: HistoricalDataItem[]; + groupBy: GroupBy; + }): InvestmentItem[] { + const groupedData: { [dateGroup: string]: Big } = {}; + + for (const { date, investmentValueWithCurrencyEffect } of data) { + const dateGroup = + groupBy === 'month' ? date.substring(0, 7) : date.substring(0, 4); + groupedData[dateGroup] = (groupedData[dateGroup] ?? new Big(0)).plus( + investmentValueWithCurrencyEffect + ); + } + + return Object.keys(groupedData).map((dateGroup) => ({ + date: groupBy === 'month' ? `${dateGroup}-01` : `${dateGroup}-01-01`, + investment: groupedData[dateGroup].toNumber() + })); + } + + public getStartDate() { + return this.transactionPoints.length > 0 + ? parseDate(this.transactionPoints[0].date) + : new Date(); + } + + protected abstract getSymbolMetrics({ + dataSource, + end, + exchangeRates, + isChartMode, + marketSymbolMap, + start, + step, + symbol + }: { + end: Date; + exchangeRates: { [dateString: string]: number }; + isChartMode?: boolean; + marketSymbolMap: { + [date: string]: { [symbol: string]: Big }; + }; + start: Date; + step?: number; + } & UniqueAsset): SymbolMetrics; + + public getTransactionPoints() { + return this.transactionPoints; + } + + private computeTransactionPoints() { + this.transactionPoints = []; + const symbols: { [symbol: string]: TransactionPointSymbol } = {}; + + let lastDate: string = null; + let lastTransactionPoint: TransactionPoint = null; + + for (const { + fee, + date, + quantity, + SymbolProfile, + tags, + type, + unitPrice + } of this.orders) { + let currentTransactionPointItem: TransactionPointSymbol; + const oldAccumulatedSymbol = symbols[SymbolProfile.symbol]; + + const factor = getFactor(type); + + if (oldAccumulatedSymbol) { + let investment = oldAccumulatedSymbol.investment; + + const newQuantity = quantity + .mul(factor) + .plus(oldAccumulatedSymbol.quantity); + + if (type === 'BUY') { + investment = oldAccumulatedSymbol.investment.plus( + quantity.mul(unitPrice) + ); + } else if (type === 'SELL') { + investment = oldAccumulatedSymbol.investment.minus( + quantity.mul(oldAccumulatedSymbol.averagePrice) + ); + } + + currentTransactionPointItem = { + investment, + tags, + averagePrice: newQuantity.gt(0) + ? investment.div(newQuantity) + : new Big(0), + currency: SymbolProfile.currency, + dataSource: SymbolProfile.dataSource, + dividend: new Big(0), + fee: fee.plus(oldAccumulatedSymbol.fee), + firstBuyDate: oldAccumulatedSymbol.firstBuyDate, + quantity: newQuantity, + symbol: SymbolProfile.symbol, + transactionCount: oldAccumulatedSymbol.transactionCount + 1 + }; + } else { + currentTransactionPointItem = { + fee, + tags, + averagePrice: unitPrice, + currency: SymbolProfile.currency, + dataSource: SymbolProfile.dataSource, + dividend: new Big(0), + firstBuyDate: date, + investment: unitPrice.mul(quantity).mul(factor), + quantity: quantity.mul(factor), + symbol: SymbolProfile.symbol, + transactionCount: 1 + }; + } + + symbols[SymbolProfile.symbol] = currentTransactionPointItem; + + const items = lastTransactionPoint?.items ?? []; + + const newItems = items.filter(({ symbol }) => { + return symbol !== SymbolProfile.symbol; + }); + + newItems.push(currentTransactionPointItem); + + newItems.sort((a, b) => { + return a.symbol?.localeCompare(b.symbol); + }); + + if (lastDate !== date || lastTransactionPoint === null) { + lastTransactionPoint = { + date, + items: newItems + }; + + this.transactionPoints.push(lastTransactionPoint); + } else { + lastTransactionPoint.items = newItems; + } + + lastDate = date; + } + } +} diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts index e08de8e22..ee71a1fb3 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts @@ -1,4 +1,12 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PortfolioCalculatorFactory, + PerformanceCalculationType +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -6,8 +14,6 @@ import { parseDate } from '@ghostfolio/common/helper'; import { Big } from 'big.js'; -import { PortfolioCalculator } from './portfolio-calculator'; - jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { return { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -20,6 +26,7 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -30,54 +37,66 @@ describe('PortfolioCalculator', () => { null, null ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); }); describe('get current positions', () => { it.only('with BALN.SW buy and sell in two activities', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, - activities: [ - { - date: new Date('2021-11-22'), - fee: 1.55, - quantity: 2, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Bâloise Holding AG', - symbol: 'BALN.SW' - }, - type: 'BUY', - unitPrice: 142.9 + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2021-11-22'), + fee: 1.55, + quantity: 2, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Bâloise Holding AG', + symbol: 'BALN.SW' }, - { - date: new Date('2021-11-30'), - fee: 1.65, - quantity: 1, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Bâloise Holding AG', - symbol: 'BALN.SW' - }, - type: 'SELL', - unitPrice: 136.6 + type: 'BUY', + unitPrice: 142.9 + }, + { + ...activityDummyData, + date: new Date('2021-11-30'), + fee: 1.65, + quantity: 1, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Bâloise Holding AG', + symbol: 'BALN.SW' }, - { - date: new Date('2021-11-30'), - fee: 0, - quantity: 1, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Bâloise Holding AG', - symbol: 'BALN.SW' - }, - type: 'SELL', - unitPrice: 136.6 - } - ], + type: 'SELL', + unitPrice: 136.6 + }, + { + ...activityDummyData, + date: new Date('2021-11-30'), + fee: 0, + quantity: 1, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Bâloise Holding AG', + symbol: 'BALN.SW' + }, + type: 'SELL', + unitPrice: 136.6 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, currency: 'CHF' }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts index 411c5e4db..69078be7c 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts @@ -1,4 +1,12 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PerformanceCalculationType, + PortfolioCalculatorFactory +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -6,8 +14,6 @@ import { parseDate } from '@ghostfolio/common/helper'; import { Big } from 'big.js'; -import { PortfolioCalculator } from './portfolio-calculator'; - jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { return { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -20,6 +26,7 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -30,41 +37,51 @@ describe('PortfolioCalculator', () => { null, null ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); }); describe('get current positions', () => { it.only('with BALN.SW buy and sell', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, - activities: [ - { - date: new Date('2021-11-22'), - fee: 1.55, - quantity: 2, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Bâloise Holding AG', - symbol: 'BALN.SW' - }, - type: 'BUY', - unitPrice: 142.9 + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2021-11-22'), + fee: 1.55, + quantity: 2, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Bâloise Holding AG', + symbol: 'BALN.SW' }, - { - date: new Date('2021-11-30'), - fee: 1.65, - quantity: 2, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Bâloise Holding AG', - symbol: 'BALN.SW' - }, - type: 'SELL', - unitPrice: 136.6 - } - ], + type: 'BUY', + unitPrice: 142.9 + }, + { + ...activityDummyData, + date: new Date('2021-11-30'), + fee: 1.65, + quantity: 2, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Bâloise Holding AG', + symbol: 'BALN.SW' + }, + type: 'SELL', + unitPrice: 136.6 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, currency: 'CHF' }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts index 32f582647..b52aac68d 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts @@ -1,4 +1,12 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PortfolioCalculatorFactory, + PerformanceCalculationType +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -6,8 +14,6 @@ import { parseDate } from '@ghostfolio/common/helper'; import { Big } from 'big.js'; -import { PortfolioCalculator } from './portfolio-calculator'; - jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { return { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -20,6 +26,7 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -30,28 +37,36 @@ describe('PortfolioCalculator', () => { null, null ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); }); describe('get current positions', () => { it.only('with BALN.SW buy', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, - activities: [ - { - date: new Date('2021-11-30'), - fee: 1.55, - quantity: 2, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Bâloise Holding AG', - symbol: 'BALN.SW' - }, - type: 'BUY', - unitPrice: 136.6 - } - ], + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2021-11-30'), + fee: 1.55, + quantity: 2, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Bâloise Holding AG', + symbol: 'BALN.SW' + }, + type: 'BUY', + unitPrice: 136.6 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, currency: 'CHF' }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts index f5687f810..420ba48f1 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts @@ -1,4 +1,12 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PortfolioCalculatorFactory, + PerformanceCalculationType +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -7,8 +15,6 @@ import { parseDate } from '@ghostfolio/common/helper'; import { Big } from 'big.js'; -import { PortfolioCalculator } from './portfolio-calculator'; - jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { return { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -33,6 +39,7 @@ jest.mock( describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -43,41 +50,51 @@ describe('PortfolioCalculator', () => { null, null ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); }); describe('get current positions', () => { it.only('with BTCUSD buy and sell partially', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, - activities: [ - { - date: new Date('2015-01-01'), - fee: 0, - quantity: 2, - SymbolProfile: { - currency: 'USD', - dataSource: 'YAHOO', - name: 'Bitcoin USD', - symbol: 'BTCUSD' - }, - type: 'BUY', - unitPrice: 320.43 + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2015-01-01'), + fee: 0, + quantity: 2, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'USD', + dataSource: 'YAHOO', + name: 'Bitcoin USD', + symbol: 'BTCUSD' }, - { - date: new Date('2017-12-31'), - fee: 0, - quantity: 1, - SymbolProfile: { - currency: 'USD', - dataSource: 'YAHOO', - name: 'Bitcoin USD', - symbol: 'BTCUSD' - }, - type: 'SELL', - unitPrice: 14156.4 - } - ], + type: 'BUY', + unitPrice: 320.43 + }, + { + ...activityDummyData, + date: new Date('2017-12-31'), + fee: 0, + quantity: 1, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'USD', + dataSource: 'YAHOO', + name: 'Bitcoin USD', + symbol: 'BTCUSD' + }, + type: 'SELL', + unitPrice: 14156.4 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, currency: 'CHF' }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts index 743733733..5f33d771b 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts @@ -1,4 +1,12 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PortfolioCalculatorFactory, + PerformanceCalculationType +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -7,8 +15,6 @@ import { parseDate } from '@ghostfolio/common/helper'; import { Big } from 'big.js'; -import { PortfolioCalculator } from './portfolio-calculator'; - jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { return { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -33,6 +39,7 @@ jest.mock( describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -43,28 +50,36 @@ describe('PortfolioCalculator', () => { null, null ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); }); describe('get current positions', () => { it.only('with GOOGL buy', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, - activities: [ - { - date: new Date('2023-01-03'), - fee: 1, - quantity: 1, - SymbolProfile: { - currency: 'USD', - dataSource: 'YAHOO', - name: 'Alphabet Inc.', - symbol: 'GOOGL' - }, - type: 'BUY', - unitPrice: 89.12 - } - ], + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2023-01-03'), + fee: 1, + quantity: 1, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'USD', + dataSource: 'YAHOO', + name: 'Alphabet Inc.', + symbol: 'GOOGL' + }, + type: 'BUY', + unitPrice: 89.12 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, currency: 'CHF' }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts index afd5e9ff2..a2c106784 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts @@ -1,4 +1,12 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PerformanceCalculationType, + PortfolioCalculatorFactory +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -7,8 +15,6 @@ import { parseDate } from '@ghostfolio/common/helper'; import { Big } from 'big.js'; -import { PortfolioCalculator } from './portfolio-calculator'; - jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { return { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -33,6 +39,7 @@ jest.mock( describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -43,41 +50,51 @@ describe('PortfolioCalculator', () => { null, null ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); }); describe('get current positions', () => { it.only('with MSFT buy', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, - activities: [ - { - date: new Date('2021-09-16'), - fee: 19, - quantity: 1, - SymbolProfile: { - currency: 'USD', - dataSource: 'YAHOO', - name: 'Microsoft Inc.', - symbol: 'MSFT' - }, - type: 'BUY', - unitPrice: 298.58 + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2021-09-16'), + fee: 19, + quantity: 1, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'USD', + dataSource: 'YAHOO', + name: 'Microsoft Inc.', + symbol: 'MSFT' }, - { - date: new Date('2021-11-16'), - fee: 0, - quantity: 1, - SymbolProfile: { - currency: 'USD', - dataSource: 'YAHOO', - name: 'Microsoft Inc.', - symbol: 'MSFT' - }, - type: 'DIVIDEND', - unitPrice: 0.62 - } - ], + type: 'BUY', + unitPrice: 298.58 + }, + { + ...activityDummyData, + date: new Date('2021-11-16'), + fee: 0, + quantity: 1, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'USD', + dataSource: 'YAHOO', + name: 'Microsoft Inc.', + symbol: 'MSFT' + }, + type: 'DIVIDEND', + unitPrice: 0.62 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, currency: 'USD' }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts index 39a563b85..905747519 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts @@ -1,3 +1,7 @@ +import { + PerformanceCalculationType, + PortfolioCalculatorFactory +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -6,8 +10,6 @@ import { parseDate } from '@ghostfolio/common/helper'; import { Big } from 'big.js'; import { subDays } from 'date-fns'; -import { PortfolioCalculator } from './portfolio-calculator'; - jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { return { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -20,6 +22,7 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -30,14 +33,18 @@ describe('PortfolioCalculator', () => { null, null ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); }); describe('get current positions', () => { it('with no orders', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, + const portfolioCalculator = factory.createCalculator({ activities: [], + calculationType: PerformanceCalculationType.TWR, currency: 'CHF' }); @@ -73,7 +80,8 @@ describe('PortfolioCalculator', () => { netPerformancePercentageWithCurrencyEffect: new Big(0), netPerformanceWithCurrencyEffect: new Big(0), positions: [], - totalInvestment: new Big(0) + totalInvestment: new Big(0), + totalInvestmentWithCurrencyEffect: new Big(0) }); expect(investments).toEqual([]); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts index d7e7c6eab..21e0bb499 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts @@ -1,4 +1,12 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PerformanceCalculationType, + PortfolioCalculatorFactory +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -6,8 +14,6 @@ import { parseDate } from '@ghostfolio/common/helper'; import { Big } from 'big.js'; -import { PortfolioCalculator } from './portfolio-calculator'; - jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { return { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -20,6 +26,7 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -30,44 +37,53 @@ describe('PortfolioCalculator', () => { null, null ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); }); describe('get current positions', () => { it.only('with NOVN.SW buy and sell partially', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, - activities: [ - { - date: new Date('2022-03-07'), - fee: 1.3, - quantity: 2, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Novartis AG', - symbol: 'NOVN.SW' - }, - type: 'BUY', - unitPrice: 75.8 + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2022-03-07'), + fee: 1.3, + quantity: 2, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Novartis AG', + symbol: 'NOVN.SW' }, - { - date: new Date('2022-04-08'), - fee: 2.95, - quantity: 1, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Novartis AG', - symbol: 'NOVN.SW' - }, - type: 'SELL', - unitPrice: 85.73 - } - ], + type: 'BUY', + unitPrice: 75.8 + }, + { + ...activityDummyData, + date: new Date('2022-04-08'), + fee: 2.95, + quantity: 1, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Novartis AG', + symbol: 'NOVN.SW' + }, + type: 'SELL', + unitPrice: 85.73 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, currency: 'CHF' }); - const spy = jest .spyOn(Date, 'now') .mockImplementation(() => parseDate('2022-04-11').getTime()); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts index 68eecea22..28920ece7 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts @@ -1,4 +1,12 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PerformanceCalculationType, + PortfolioCalculatorFactory +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; @@ -6,8 +14,6 @@ import { parseDate } from '@ghostfolio/common/helper'; import { Big } from 'big.js'; -import { PortfolioCalculator } from './portfolio-calculator'; - jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { return { // eslint-disable-next-line @typescript-eslint/naming-convention @@ -20,6 +26,7 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -30,41 +37,51 @@ describe('PortfolioCalculator', () => { null, null ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); }); describe('get current positions', () => { it.only('with NOVN.SW buy and sell', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, - activities: [ - { - date: new Date('2022-03-07'), - fee: 0, - quantity: 2, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Novartis AG', - symbol: 'NOVN.SW' - }, - type: 'BUY', - unitPrice: 75.8 + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2022-03-07'), + fee: 0, + quantity: 2, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Novartis AG', + symbol: 'NOVN.SW' }, - { - date: new Date('2022-04-08'), - fee: 0, - quantity: 2, - SymbolProfile: { - currency: 'CHF', - dataSource: 'YAHOO', - name: 'Novartis AG', - symbol: 'NOVN.SW' - }, - type: 'SELL', - unitPrice: 85.73 - } - ], + type: 'BUY', + unitPrice: 75.8 + }, + { + ...activityDummyData, + date: new Date('2022-04-08'), + fee: 0, + quantity: 2, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'CHF', + dataSource: 'YAHOO', + name: 'Novartis AG', + symbol: 'NOVN.SW' + }, + type: 'SELL', + unitPrice: 85.73 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, currency: 'CHF' }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts index de011d813..b68f4358d 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts @@ -1,13 +1,16 @@ +import { + PerformanceCalculationType, + PortfolioCalculatorFactory +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { Big } from 'big.js'; -import { PortfolioCalculator } from './portfolio-calculator'; - describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; beforeEach(() => { currentRateService = new CurrentRateService(null, null, null, null); @@ -18,17 +21,21 @@ describe('PortfolioCalculator', () => { null, null ); - }); - describe('annualized performance percentage', () => { - const portfolioCalculator = new PortfolioCalculator({ - activities: [], + factory = new PortfolioCalculatorFactory( currentRateService, - exchangeRateDataService, - currency: 'USD' - }); + exchangeRateDataService + ); + }); + describe('annualized performance percentage', () => { it('Get annualized performance', async () => { + const portfolioCalculator = factory.createCalculator({ + activities: [], + calculationType: PerformanceCalculationType.TWR, + currency: 'CHF' + }); + expect( portfolioCalculator .getAnnualizedPerformancePercent({ diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index 6ea93a670..0fee9c5c7 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -1,24 +1,13 @@ -import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; -import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; +import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; import { CurrentPositions } from '@ghostfolio/api/app/portfolio/interfaces/current-positions.interface'; -import { PortfolioOrderItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-calculator.interface'; -import { PortfolioOrder } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order.interface'; -import { TransactionPointSymbol } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point-symbol.interface'; -import { TransactionPoint } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point.interface'; +import { PortfolioOrderItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order-item.interface'; import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; -import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; -import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; -import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper'; +import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { - DataProviderInfo, - HistoricalDataItem, - InvestmentItem, - ResponseError, SymbolMetrics, TimelinePosition, UniqueAsset } from '@ghostfolio/common/interfaces'; -import { GroupBy } from '@ghostfolio/common/types'; import { Logger } from '@nestjs/common'; import { Big } from 'big.js'; @@ -26,638 +15,15 @@ import { addDays, addMilliseconds, differenceInDays, - eachDayOfInterval, - endOfDay, format, - isBefore, - isSameDay, - max, - subDays + isBefore } from 'date-fns'; -import { cloneDeep, first, isNumber, last, sortBy, uniq } from 'lodash'; - -export class PortfolioCalculator { - private static readonly ENABLE_LOGGING = false; - - private currency: string; - private currentRateService: CurrentRateService; - private dataProviderInfos: DataProviderInfo[]; - private exchangeRateDataService: ExchangeRateDataService; - private orders: PortfolioOrder[]; - private transactionPoints: TransactionPoint[]; - - public constructor({ - activities, - currency, - currentRateService, - exchangeRateDataService - }: { - activities: Activity[]; - currency: string; - currentRateService: CurrentRateService; - exchangeRateDataService: ExchangeRateDataService; - }) { - this.currency = currency; - this.currentRateService = currentRateService; - this.exchangeRateDataService = exchangeRateDataService; - this.orders = activities.map( - ({ date, fee, quantity, SymbolProfile, type, unitPrice }) => { - return { - SymbolProfile, - type, - date: format(date, DATE_FORMAT), - fee: new Big(fee), - quantity: new Big(quantity), - unitPrice: new Big(unitPrice) - }; - } - ); - - this.orders.sort((a, b) => { - return a.date?.localeCompare(b.date); - }); - - this.computeTransactionPoints(); - } - - public getAnnualizedPerformancePercent({ - daysInMarket, - netPerformancePercent - }: { - daysInMarket: number; - netPerformancePercent: Big; - }): Big { - if (isNumber(daysInMarket) && daysInMarket > 0) { - const exponent = new Big(365).div(daysInMarket).toNumber(); - return new Big( - Math.pow(netPerformancePercent.plus(1).toNumber(), exponent) - ).minus(1); - } - - return new Big(0); - } - - public async getChartData({ - end = new Date(Date.now()), - start, - step = 1 - }: { - end?: Date; - start: Date; - step?: number; - }): Promise { - const symbols: { [symbol: string]: boolean } = {}; - - const transactionPointsBeforeEndDate = - this.transactionPoints?.filter((transactionPoint) => { - return isBefore(parseDate(transactionPoint.date), end); - }) ?? []; - - const currencies: { [symbol: string]: string } = {}; - const dataGatheringItems: IDataGatheringItem[] = []; - const firstIndex = transactionPointsBeforeEndDate.length; - - let dates = eachDayOfInterval({ start, end }, { step }).map((date) => { - return resetHours(date); - }); - - const includesEndDate = isSameDay(last(dates), end); - - if (!includesEndDate) { - dates.push(resetHours(end)); - } - - if (transactionPointsBeforeEndDate.length > 0) { - for (const { - currency, - dataSource, - symbol - } of transactionPointsBeforeEndDate[firstIndex - 1].items) { - dataGatheringItems.push({ - dataSource, - symbol - }); - currencies[symbol] = currency; - symbols[symbol] = true; - } - } - - const { dataProviderInfos, values: marketSymbols } = - await this.currentRateService.getValues({ - dataGatheringItems, - dateQuery: { - in: dates - } - }); - - this.dataProviderInfos = dataProviderInfos; - - const marketSymbolMap: { - [date: string]: { [symbol: string]: Big }; - } = {}; - - let exchangeRatesByCurrency = - await this.exchangeRateDataService.getExchangeRatesByCurrency({ - currencies: uniq(Object.values(currencies)), - endDate: endOfDay(end), - startDate: this.getStartDate(), - targetCurrency: this.currency - }); - - for (const marketSymbol of marketSymbols) { - const dateString = format(marketSymbol.date, DATE_FORMAT); - if (!marketSymbolMap[dateString]) { - marketSymbolMap[dateString] = {}; - } - if (marketSymbol.marketPrice) { - marketSymbolMap[dateString][marketSymbol.symbol] = new Big( - marketSymbol.marketPrice - ); - } - } - - const accumulatedValuesByDate: { - [date: string]: { - investmentValueWithCurrencyEffect: Big; - totalCurrentValue: Big; - totalCurrentValueWithCurrencyEffect: Big; - totalInvestmentValue: Big; - totalInvestmentValueWithCurrencyEffect: Big; - totalNetPerformanceValue: Big; - totalNetPerformanceValueWithCurrencyEffect: Big; - totalTimeWeightedInvestmentValue: Big; - totalTimeWeightedInvestmentValueWithCurrencyEffect: Big; - }; - } = {}; - - const valuesBySymbol: { - [symbol: string]: { - currentValues: { [date: string]: Big }; - currentValuesWithCurrencyEffect: { [date: string]: Big }; - investmentValuesAccumulated: { [date: string]: Big }; - investmentValuesAccumulatedWithCurrencyEffect: { [date: string]: Big }; - investmentValuesWithCurrencyEffect: { [date: string]: Big }; - netPerformanceValues: { [date: string]: Big }; - netPerformanceValuesWithCurrencyEffect: { [date: string]: Big }; - timeWeightedInvestmentValues: { [date: string]: Big }; - timeWeightedInvestmentValuesWithCurrencyEffect: { [date: string]: Big }; - }; - } = {}; - - for (const symbol of Object.keys(symbols)) { - const { - currentValues, - currentValuesWithCurrencyEffect, - investmentValuesAccumulated, - investmentValuesAccumulatedWithCurrencyEffect, - investmentValuesWithCurrencyEffect, - netPerformanceValues, - netPerformanceValuesWithCurrencyEffect, - timeWeightedInvestmentValues, - timeWeightedInvestmentValuesWithCurrencyEffect - } = this.getSymbolMetrics({ - end, - marketSymbolMap, - start, - step, - symbol, - dataSource: null, - exchangeRates: - exchangeRatesByCurrency[`${currencies[symbol]}${this.currency}`], - isChartMode: true - }); - - valuesBySymbol[symbol] = { - currentValues, - currentValuesWithCurrencyEffect, - investmentValuesAccumulated, - investmentValuesAccumulatedWithCurrencyEffect, - investmentValuesWithCurrencyEffect, - netPerformanceValues, - netPerformanceValuesWithCurrencyEffect, - timeWeightedInvestmentValues, - timeWeightedInvestmentValuesWithCurrencyEffect - }; - } - - for (const currentDate of dates) { - const dateString = format(currentDate, DATE_FORMAT); - - for (const symbol of Object.keys(valuesBySymbol)) { - const symbolValues = valuesBySymbol[symbol]; - - const currentValue = - symbolValues.currentValues?.[dateString] ?? new Big(0); - - const currentValueWithCurrencyEffect = - symbolValues.currentValuesWithCurrencyEffect?.[dateString] ?? - new Big(0); - - const investmentValueAccumulated = - symbolValues.investmentValuesAccumulated?.[dateString] ?? new Big(0); - - const investmentValueAccumulatedWithCurrencyEffect = - symbolValues.investmentValuesAccumulatedWithCurrencyEffect?.[ - dateString - ] ?? new Big(0); - - const investmentValueWithCurrencyEffect = - symbolValues.investmentValuesWithCurrencyEffect?.[dateString] ?? - new Big(0); - - const netPerformanceValue = - symbolValues.netPerformanceValues?.[dateString] ?? new Big(0); - - const netPerformanceValueWithCurrencyEffect = - symbolValues.netPerformanceValuesWithCurrencyEffect?.[dateString] ?? - new Big(0); - - const timeWeightedInvestmentValue = - symbolValues.timeWeightedInvestmentValues?.[dateString] ?? new Big(0); - - const timeWeightedInvestmentValueWithCurrencyEffect = - symbolValues.timeWeightedInvestmentValuesWithCurrencyEffect?.[ - dateString - ] ?? new Big(0); - - accumulatedValuesByDate[dateString] = { - investmentValueWithCurrencyEffect: ( - accumulatedValuesByDate[dateString] - ?.investmentValueWithCurrencyEffect ?? new Big(0) - ).add(investmentValueWithCurrencyEffect), - totalCurrentValue: ( - accumulatedValuesByDate[dateString]?.totalCurrentValue ?? new Big(0) - ).add(currentValue), - totalCurrentValueWithCurrencyEffect: ( - accumulatedValuesByDate[dateString] - ?.totalCurrentValueWithCurrencyEffect ?? new Big(0) - ).add(currentValueWithCurrencyEffect), - totalInvestmentValue: ( - accumulatedValuesByDate[dateString]?.totalInvestmentValue ?? - new Big(0) - ).add(investmentValueAccumulated), - totalInvestmentValueWithCurrencyEffect: ( - accumulatedValuesByDate[dateString] - ?.totalInvestmentValueWithCurrencyEffect ?? new Big(0) - ).add(investmentValueAccumulatedWithCurrencyEffect), - totalNetPerformanceValue: ( - accumulatedValuesByDate[dateString]?.totalNetPerformanceValue ?? - new Big(0) - ).add(netPerformanceValue), - totalNetPerformanceValueWithCurrencyEffect: ( - accumulatedValuesByDate[dateString] - ?.totalNetPerformanceValueWithCurrencyEffect ?? new Big(0) - ).add(netPerformanceValueWithCurrencyEffect), - totalTimeWeightedInvestmentValue: ( - accumulatedValuesByDate[dateString] - ?.totalTimeWeightedInvestmentValue ?? new Big(0) - ).add(timeWeightedInvestmentValue), - totalTimeWeightedInvestmentValueWithCurrencyEffect: ( - accumulatedValuesByDate[dateString] - ?.totalTimeWeightedInvestmentValueWithCurrencyEffect ?? new Big(0) - ).add(timeWeightedInvestmentValueWithCurrencyEffect) - }; - } - } - - return Object.entries(accumulatedValuesByDate).map(([date, values]) => { - const { - investmentValueWithCurrencyEffect, - totalCurrentValue, - totalCurrentValueWithCurrencyEffect, - totalInvestmentValue, - totalInvestmentValueWithCurrencyEffect, - totalNetPerformanceValue, - totalNetPerformanceValueWithCurrencyEffect, - totalTimeWeightedInvestmentValue, - totalTimeWeightedInvestmentValueWithCurrencyEffect - } = values; - - const netPerformanceInPercentage = totalTimeWeightedInvestmentValue.eq(0) - ? 0 - : totalNetPerformanceValue - .div(totalTimeWeightedInvestmentValue) - .mul(100) - .toNumber(); - - const netPerformanceInPercentageWithCurrencyEffect = - totalTimeWeightedInvestmentValueWithCurrencyEffect.eq(0) - ? 0 - : totalNetPerformanceValueWithCurrencyEffect - .div(totalTimeWeightedInvestmentValueWithCurrencyEffect) - .mul(100) - .toNumber(); - - return { - date, - netPerformanceInPercentage, - netPerformanceInPercentageWithCurrencyEffect, - investmentValueWithCurrencyEffect: - investmentValueWithCurrencyEffect.toNumber(), - netPerformance: totalNetPerformanceValue.toNumber(), - netPerformanceWithCurrencyEffect: - totalNetPerformanceValueWithCurrencyEffect.toNumber(), - totalInvestment: totalInvestmentValue.toNumber(), - totalInvestmentValueWithCurrencyEffect: - totalInvestmentValueWithCurrencyEffect.toNumber(), - value: totalCurrentValue.toNumber(), - valueWithCurrencyEffect: totalCurrentValueWithCurrencyEffect.toNumber() - }; - }); - } - - public async getCurrentPositions( - start: Date, - end?: Date - ): Promise { - const lastTransactionPoint = last(this.transactionPoints); - - let endDate = end; - - if (!endDate) { - endDate = new Date(Date.now()); - - if (lastTransactionPoint) { - endDate = max([endDate, parseDate(lastTransactionPoint.date)]); - } - } - - const transactionPoints = this.transactionPoints?.filter(({ date }) => { - return isBefore(parseDate(date), endDate); - }); - - if (!transactionPoints.length) { - return { - currentValueInBaseCurrency: new Big(0), - grossPerformance: new Big(0), - grossPerformancePercentage: new Big(0), - grossPerformancePercentageWithCurrencyEffect: new Big(0), - grossPerformanceWithCurrencyEffect: new Big(0), - hasErrors: false, - netPerformance: new Big(0), - netPerformancePercentage: new Big(0), - netPerformancePercentageWithCurrencyEffect: new Big(0), - netPerformanceWithCurrencyEffect: new Big(0), - positions: [], - totalInvestment: new Big(0) - }; - } - - const currencies: { [symbol: string]: string } = {}; - const dataGatheringItems: IDataGatheringItem[] = []; - let dates: Date[] = []; - let firstIndex = transactionPoints.length; - let firstTransactionPoint: TransactionPoint = null; +import { cloneDeep, first, last, sortBy } from 'lodash'; - dates.push(resetHours(start)); - - for (const { currency, dataSource, symbol } of transactionPoints[ - firstIndex - 1 - ].items) { - dataGatheringItems.push({ - dataSource, - symbol - }); - - currencies[symbol] = currency; - } - - for (let i = 0; i < transactionPoints.length; i++) { - if ( - !isBefore(parseDate(transactionPoints[i].date), start) && - firstTransactionPoint === null - ) { - firstTransactionPoint = transactionPoints[i]; - firstIndex = i; - } - - if (firstTransactionPoint !== null) { - dates.push(resetHours(parseDate(transactionPoints[i].date))); - } - } - - dates.push(resetHours(endDate)); - - // Add dates of last week for fallback - dates.push(subDays(resetHours(new Date()), 7)); - dates.push(subDays(resetHours(new Date()), 6)); - dates.push(subDays(resetHours(new Date()), 5)); - dates.push(subDays(resetHours(new Date()), 4)); - dates.push(subDays(resetHours(new Date()), 3)); - dates.push(subDays(resetHours(new Date()), 2)); - dates.push(subDays(resetHours(new Date()), 1)); - dates.push(resetHours(new Date())); - - dates = uniq( - dates.map((date) => { - return date.getTime(); - }) - ) - .map((timestamp) => { - return new Date(timestamp); - }) - .sort((a, b) => { - return a.getTime() - b.getTime(); - }); - - let exchangeRatesByCurrency = - await this.exchangeRateDataService.getExchangeRatesByCurrency({ - currencies: uniq(Object.values(currencies)), - endDate: endOfDay(endDate), - startDate: this.getStartDate(), - targetCurrency: this.currency - }); - - const { - dataProviderInfos, - errors: currentRateErrors, - values: marketSymbols - } = await this.currentRateService.getValues({ - dataGatheringItems, - dateQuery: { - in: dates - } - }); - - this.dataProviderInfos = dataProviderInfos; - - const marketSymbolMap: { - [date: string]: { [symbol: string]: Big }; - } = {}; - - for (const marketSymbol of marketSymbols) { - const date = format(marketSymbol.date, DATE_FORMAT); - - if (!marketSymbolMap[date]) { - marketSymbolMap[date] = {}; - } - - if (marketSymbol.marketPrice) { - marketSymbolMap[date][marketSymbol.symbol] = new Big( - marketSymbol.marketPrice - ); - } - } - - const endDateString = format(endDate, DATE_FORMAT); - - if (firstIndex > 0) { - firstIndex--; - } - - const positions: TimelinePosition[] = []; - let hasAnySymbolMetricsErrors = false; - - const errors: ResponseError['errors'] = []; - - for (const item of lastTransactionPoint.items) { - const marketPriceInBaseCurrency = ( - marketSymbolMap[endDateString]?.[item.symbol] ?? item.averagePrice - ).mul( - exchangeRatesByCurrency[`${item.currency}${this.currency}`]?.[ - endDateString - ] - ); - - const { - grossPerformance, - grossPerformancePercentage, - grossPerformancePercentageWithCurrencyEffect, - grossPerformanceWithCurrencyEffect, - hasErrors, - netPerformance, - netPerformancePercentage, - netPerformancePercentageWithCurrencyEffect, - netPerformanceWithCurrencyEffect, - timeWeightedInvestment, - timeWeightedInvestmentWithCurrencyEffect, - totalDividend, - totalDividendInBaseCurrency, - totalInvestment, - totalInvestmentWithCurrencyEffect - } = this.getSymbolMetrics({ - marketSymbolMap, - start, - dataSource: item.dataSource, - end: endDate, - exchangeRates: - exchangeRatesByCurrency[`${item.currency}${this.currency}`], - symbol: item.symbol - }); - - hasAnySymbolMetricsErrors = hasAnySymbolMetricsErrors || hasErrors; - - positions.push({ - dividend: totalDividend, - dividendInBaseCurrency: totalDividendInBaseCurrency, - timeWeightedInvestment, - timeWeightedInvestmentWithCurrencyEffect, - averagePrice: item.averagePrice, - currency: item.currency, - dataSource: item.dataSource, - fee: item.fee, - firstBuyDate: item.firstBuyDate, - grossPerformance: !hasErrors ? grossPerformance ?? null : null, - grossPerformancePercentage: !hasErrors - ? grossPerformancePercentage ?? null - : null, - grossPerformancePercentageWithCurrencyEffect: !hasErrors - ? grossPerformancePercentageWithCurrencyEffect ?? null - : null, - grossPerformanceWithCurrencyEffect: !hasErrors - ? grossPerformanceWithCurrencyEffect ?? null - : null, - investment: totalInvestment, - investmentWithCurrencyEffect: totalInvestmentWithCurrencyEffect, - marketPrice: - marketSymbolMap[endDateString]?.[item.symbol]?.toNumber() ?? null, - marketPriceInBaseCurrency: - marketPriceInBaseCurrency?.toNumber() ?? null, - netPerformance: !hasErrors ? netPerformance ?? null : null, - netPerformancePercentage: !hasErrors - ? netPerformancePercentage ?? null - : null, - netPerformancePercentageWithCurrencyEffect: !hasErrors - ? netPerformancePercentageWithCurrencyEffect ?? null - : null, - netPerformanceWithCurrencyEffect: !hasErrors - ? netPerformanceWithCurrencyEffect ?? null - : null, - quantity: item.quantity, - symbol: item.symbol, - tags: item.tags, - transactionCount: item.transactionCount, - valueInBaseCurrency: new Big(marketPriceInBaseCurrency).mul( - item.quantity - ) - }); - - if ( - (hasErrors || - currentRateErrors.find(({ dataSource, symbol }) => { - return dataSource === item.dataSource && symbol === item.symbol; - })) && - item.investment.gt(0) - ) { - errors.push({ dataSource: item.dataSource, symbol: item.symbol }); - } - } - - const overall = this.calculateOverallPerformance(positions); - - return { - ...overall, - errors, - positions, - hasErrors: hasAnySymbolMetricsErrors || overall.hasErrors - }; - } - - public getDataProviderInfos() { - return this.dataProviderInfos; - } - - public getInvestments(): { date: string; investment: Big }[] { - if (this.transactionPoints.length === 0) { - return []; - } - - return this.transactionPoints.map((transactionPoint) => { - return { - date: transactionPoint.date, - investment: transactionPoint.items.reduce( - (investment, transactionPointSymbol) => - investment.plus(transactionPointSymbol.investment), - new Big(0) - ) - }; - }); - } - - public getInvestmentsByGroup({ - data, - groupBy - }: { - data: HistoricalDataItem[]; - groupBy: GroupBy; - }): InvestmentItem[] { - const groupedData: { [dateGroup: string]: Big } = {}; - - for (const { date, investmentValueWithCurrencyEffect } of data) { - const dateGroup = - groupBy === 'month' ? date.substring(0, 7) : date.substring(0, 4); - groupedData[dateGroup] = (groupedData[dateGroup] ?? new Big(0)).plus( - investmentValueWithCurrencyEffect - ); - } - - return Object.keys(groupedData).map((dateGroup) => ({ - date: groupBy === 'month' ? `${dateGroup}-01` : `${dateGroup}-01-01`, - investment: groupedData[dateGroup].toNumber() - })); - } - - private calculateOverallPerformance(positions: TimelinePosition[]) { +export class TWRPortfolioCalculator extends PortfolioCalculator { + protected calculateOverallPerformance( + positions: TimelinePosition[] + ): CurrentPositions { let currentValueInBaseCurrency = new Big(0); let grossPerformance = new Big(0); let grossPerformanceWithCurrencyEffect = new Big(0); @@ -754,119 +120,12 @@ export class PortfolioCalculator { ? new Big(0) : grossPerformanceWithCurrencyEffect.div( totalTimeWeightedInvestmentWithCurrencyEffect - ) + ), + positions }; } - public getStartDate() { - return this.transactionPoints.length > 0 - ? parseDate(this.transactionPoints[0].date) - : new Date(); - } - - public getTransactionPoints() { - return this.transactionPoints; - } - - private computeTransactionPoints() { - this.transactionPoints = []; - const symbols: { [symbol: string]: TransactionPointSymbol } = {}; - - let lastDate: string = null; - let lastTransactionPoint: TransactionPoint = null; - - for (const { - fee, - date, - quantity, - SymbolProfile, - tags, - type, - unitPrice - } of this.orders) { - let currentTransactionPointItem: TransactionPointSymbol; - const oldAccumulatedSymbol = symbols[SymbolProfile.symbol]; - - const factor = getFactor(type); - - if (oldAccumulatedSymbol) { - let investment = oldAccumulatedSymbol.investment; - - const newQuantity = quantity - .mul(factor) - .plus(oldAccumulatedSymbol.quantity); - - if (type === 'BUY') { - investment = oldAccumulatedSymbol.investment.plus( - quantity.mul(unitPrice) - ); - } else if (type === 'SELL') { - investment = oldAccumulatedSymbol.investment.minus( - quantity.mul(oldAccumulatedSymbol.averagePrice) - ); - } - - currentTransactionPointItem = { - investment, - tags, - averagePrice: newQuantity.gt(0) - ? investment.div(newQuantity) - : new Big(0), - currency: SymbolProfile.currency, - dataSource: SymbolProfile.dataSource, - dividend: new Big(0), - fee: fee.plus(oldAccumulatedSymbol.fee), - firstBuyDate: oldAccumulatedSymbol.firstBuyDate, - quantity: newQuantity, - symbol: SymbolProfile.symbol, - transactionCount: oldAccumulatedSymbol.transactionCount + 1 - }; - } else { - currentTransactionPointItem = { - fee, - tags, - averagePrice: unitPrice, - currency: SymbolProfile.currency, - dataSource: SymbolProfile.dataSource, - dividend: new Big(0), - firstBuyDate: date, - investment: unitPrice.mul(quantity).mul(factor), - quantity: quantity.mul(factor), - symbol: SymbolProfile.symbol, - transactionCount: 1 - }; - } - - symbols[SymbolProfile.symbol] = currentTransactionPointItem; - - const items = lastTransactionPoint?.items ?? []; - - const newItems = items.filter(({ symbol }) => { - return symbol !== SymbolProfile.symbol; - }); - - newItems.push(currentTransactionPointItem); - - newItems.sort((a, b) => { - return a.symbol?.localeCompare(b.symbol); - }); - - if (lastDate !== date || lastTransactionPoint === null) { - lastTransactionPoint = { - date, - items: newItems - }; - - this.transactionPoints.push(lastTransactionPoint); - } else { - lastTransactionPoint.items = newItems; - } - - lastDate = date; - } - } - - private getSymbolMetrics({ + protected getSymbolMetrics({ dataSource, end, exchangeRates, diff --git a/apps/api/src/app/portfolio/interfaces/current-positions.interface.ts b/apps/api/src/app/portfolio/interfaces/current-positions.interface.ts index cf759b7ac..308cc4037 100644 --- a/apps/api/src/app/portfolio/interfaces/current-positions.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/current-positions.interface.ts @@ -16,4 +16,5 @@ export interface CurrentPositions extends ResponseError { netPerformancePercentageWithCurrencyEffect: Big; positions: TimelinePosition[]; totalInvestment: Big; + totalInvestmentWithCurrencyEffect: Big; } diff --git a/apps/api/src/app/portfolio/interfaces/portfolio-calculator.interface.ts b/apps/api/src/app/portfolio/interfaces/portfolio-order-item.interface.ts similarity index 100% rename from apps/api/src/app/portfolio/interfaces/portfolio-calculator.interface.ts rename to apps/api/src/app/portfolio/interfaces/portfolio-order-item.interface.ts diff --git a/apps/api/src/app/portfolio/portfolio.module.ts b/apps/api/src/app/portfolio/portfolio.module.ts index 4b5034979..6b06bf02d 100644 --- a/apps/api/src/app/portfolio/portfolio.module.ts +++ b/apps/api/src/app/portfolio/portfolio.module.ts @@ -15,6 +15,7 @@ import { SymbolProfileModule } from '@ghostfolio/api/services/symbol-profile/sym import { Module } from '@nestjs/common'; +import { PortfolioCalculatorFactory } from './calculator/portfolio-calculator.factory'; import { CurrentRateService } from './current-rate.service'; import { PortfolioController } from './portfolio.controller'; import { PortfolioService } from './portfolio.service'; @@ -41,6 +42,7 @@ import { RulesService } from './rules.service'; AccountBalanceService, AccountService, CurrentRateService, + PortfolioCalculatorFactory, PortfolioService, RulesService ] diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 8384427c3..566ad4049 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -3,7 +3,6 @@ import { AccountService } from '@ghostfolio/api/app/account/account.service'; import { CashDetails } from '@ghostfolio/api/app/account/interfaces/cash-details.interface'; import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { OrderService } from '@ghostfolio/api/app/order/order.service'; -import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { UserService } from '@ghostfolio/api/app/user/user.service'; import { getFactor, @@ -81,7 +80,11 @@ import { } from 'date-fns'; import { isEmpty, last, uniq, uniqBy } from 'lodash'; -import { PortfolioCalculator } from './calculator/twr/portfolio-calculator'; +import { PortfolioCalculator } from './calculator/portfolio-calculator'; +import { + PerformanceCalculationType, + PortfolioCalculatorFactory +} from './calculator/portfolio-calculator.factory'; import { HistoricalDataContainer, PortfolioPositionDetail @@ -98,7 +101,7 @@ export class PortfolioService { public constructor( private readonly accountBalanceService: AccountBalanceService, private readonly accountService: AccountService, - private readonly currentRateService: CurrentRateService, + private readonly calculatorFactory: PortfolioCalculatorFactory, private readonly dataProviderService: DataProviderService, private readonly exchangeRateDataService: ExchangeRateDataService, private readonly impersonationService: ImpersonationService, @@ -265,11 +268,10 @@ export class PortfolioService { }; } - const portfolioCalculator = new PortfolioCalculator({ + const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, - currency: this.request.user.Settings.settings.baseCurrency, - currentRateService: this.currentRateService, - exchangeRateDataService: this.exchangeRateDataService + calculationType: PerformanceCalculationType.TWR, + currency: this.request.user.Settings.settings.baseCurrency }); const { items } = await this.getChart({ @@ -354,11 +356,10 @@ export class PortfolioService { withExcludedAccounts }); - const portfolioCalculator = new PortfolioCalculator({ + const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, - currency: userCurrency, - currentRateService: this.currentRateService, - exchangeRateDataService: this.exchangeRateDataService + calculationType: PerformanceCalculationType.TWR, + currency: userCurrency }); const { startDate } = getInterval( @@ -720,15 +721,14 @@ export class PortfolioService { tags = uniqBy(tags, 'id'); - const portfolioCalculator = new PortfolioCalculator({ + const portfolioCalculator = this.calculatorFactory.createCalculator({ activities: orders.filter((order) => { tags = tags.concat(order.tags); return ['BUY', 'DIVIDEND', 'ITEM', 'SELL'].includes(order.type); }), - currency: userCurrency, - currentRateService: this.currentRateService, - exchangeRateDataService: this.exchangeRateDataService + calculationType: PerformanceCalculationType.TWR, + currency: userCurrency }); const portfolioStart = portfolioCalculator.getStartDate(); @@ -963,11 +963,10 @@ export class PortfolioService { }; } - const portfolioCalculator = new PortfolioCalculator({ + const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, - currency: this.request.user.Settings.settings.baseCurrency, - currentRateService: this.currentRateService, - exchangeRateDataService: this.exchangeRateDataService + calculationType: PerformanceCalculationType.TWR, + currency: this.request.user.Settings.settings.baseCurrency }); const currentPositions = await portfolioCalculator.getCurrentPositions( @@ -1152,11 +1151,10 @@ export class PortfolioService { }; } - const portfolioCalculator = new PortfolioCalculator({ + const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, - currency: userCurrency, - currentRateService: this.currentRateService, - exchangeRateDataService: this.exchangeRateDataService + calculationType: PerformanceCalculationType.TWR, + currency: userCurrency }); const { @@ -1270,11 +1268,10 @@ export class PortfolioService { types: ['BUY', 'SELL'] }); - const portfolioCalculator = new PortfolioCalculator({ + const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, - currency: userCurrency, - currentRateService: this.currentRateService, - exchangeRateDataService: this.exchangeRateDataService + calculationType: PerformanceCalculationType.TWR, + currency: this.request.user.Settings.settings.baseCurrency }); const currentPositions = await portfolioCalculator.getCurrentPositions( @@ -1772,12 +1769,12 @@ export class PortfolioService { const daysInMarket = differenceInDays(new Date(), firstOrderDate); - const annualizedPerformancePercent = new PortfolioCalculator({ - activities: [], - currency: userCurrency, - currentRateService: this.currentRateService, - exchangeRateDataService: this.exchangeRateDataService - }) + const annualizedPerformancePercent = this.calculatorFactory + .createCalculator({ + activities: [], + calculationType: PerformanceCalculationType.TWR, + currency: userCurrency + }) .getAnnualizedPerformancePercent({ daysInMarket, netPerformancePercent: new Big( @@ -1787,12 +1784,12 @@ export class PortfolioService { ?.toNumber(); const annualizedPerformancePercentWithCurrencyEffect = - new PortfolioCalculator({ - activities: [], - currency: userCurrency, - currentRateService: this.currentRateService, - exchangeRateDataService: this.exchangeRateDataService - }) + this.calculatorFactory + .createCalculator({ + activities: [], + calculationType: PerformanceCalculationType.TWR, + currency: userCurrency + }) .getAnnualizedPerformancePercent({ daysInMarket, netPerformancePercent: new Big( From 1b81409b35117321cceed0177b7f30786ff2b095 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 1 Apr 2024 09:02:10 +0200 Subject: [PATCH 087/203] Add OpenAlternative logo (#3225) --- .../src/app/pages/landing/landing-page.html | 6 +++--- .../src/app/pages/landing/landing-page.scss | 9 +++------ .../src/assets/images/logo-openalternative.svg | 11 +++++++++++ .../src/assets/images/logo-openstartup.png | Bin 57189 -> 0 bytes 4 files changed, 17 insertions(+), 9 deletions(-) create mode 100644 apps/client/src/assets/images/logo-openalternative.svg delete mode 100644 apps/client/src/assets/images/logo-openstartup.png diff --git a/apps/client/src/app/pages/landing/landing-page.html b/apps/client/src/app/pages/landing/landing-page.html index e48b5e6ed..579b35702 100644 --- a/apps/client/src/app/pages/landing/landing-page.html +++ b/apps/client/src/app/pages/landing/landing-page.html @@ -152,10 +152,10 @@
diff --git a/apps/client/src/app/pages/landing/landing-page.scss b/apps/client/src/app/pages/landing/landing-page.scss index 6d5578ffb..6a8dd8ec5 100644 --- a/apps/client/src/app/pages/landing/landing-page.scss +++ b/apps/client/src/app/pages/landing/landing-page.scss @@ -57,12 +57,8 @@ mask-image: url('/assets/images/logo-hacker-news.svg'); } - &.logo-openstartup { - background-image: url('/assets/images/logo-openstartup.png'); - background-position: center; - background-repeat: no-repeat; - background-size: contain; - filter: grayscale(1); + &.logo-openalternative { + mask-image: url('/assets/images/logo-openalternative.svg'); } &.logo-privacy-tools { @@ -133,6 +129,7 @@ &.logo-alternative-to, &.logo-dev-community, &.logo-hacker-news, + &.logo-openalternative, &.logo-privacy-tools, &.logo-reddit, &.logo-sackgeld, diff --git a/apps/client/src/assets/images/logo-openalternative.svg b/apps/client/src/assets/images/logo-openalternative.svg new file mode 100644 index 000000000..b8488e9ac --- /dev/null +++ b/apps/client/src/assets/images/logo-openalternative.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/apps/client/src/assets/images/logo-openstartup.png b/apps/client/src/assets/images/logo-openstartup.png deleted file mode 100644 index 1eaa2c43017fddd6cdfb32408bea9040870423c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 57189 zcmc$_Ral(e(gjG6V8PwpEx5ZAT!Xv22X}XOcL)&N-QC@xad(I5oH^h3pNqL4Zu)_K zrFQMARkc=a!sKPe;b5>~KtMp?Bqc-?K|ny=KtR4=Kz#-NWrjcz9ryw6C?u&21^n@Z zG71F&Aq0^W5mf%AbEXaHiLyY@i0gj1=m7)?q|R zIO{LUW}Lj!FDj^PHivHi>Y57*YMs#b`Kax1OeT}=EID_xd8lNT;BooB`Pi}Ub(;}r z7)8{Ls0Z~O924~0mtYX#+<77asg3Yu|Ns8(``@oQ#BP>}{^vShB6%1jJ<@7a8){8t z;eW3BdlT?Ntp6V`l!x$hXRxvq<=C+&c6bcsNvT8%M3A#Sx=*7Hs1y93Rb62NO>Ga3 zbe1QUKMXo&g<@pb<*W*DN)=J?e&zC3cWpg+p2_SX{67CbH$l;ZMgkx(E)`id-@j-Q zkb`~_nP~?~pC9=VLx{vwJ$l+;-3+&=Y*Z(g57Z6(>s7*jpsyJE*(sF=BHV0-&W(Fz z_;*2)_J4nqE30xO^q`QdzPuJGtqK|$_-8ZxWZS8++0hK@5QpKn7qpg=A(%m2EJY?|MGX*1 zpMP14G4wz?yhL=h|Uk=tZ>)-8?7eWL^D7aOk$QAfR6XLz9XgG4jXT}0gc+{J4!9M=T&)H*x z@5#!h-5zDB6pK>Xzx%87Ow!IqOthdp?(Q@pd9V%xDlgv%I zpYFC+`V}qRgh++sTub2rzkJK}2P<*xr4d>_95e)RZT&CvzO)Hw z25=2>HokuoEF26NwBcaR39kM*FdHW=gylf@HsdDqbln{I3N9X4GAV&cJ?)Pe^t2fb@-fv+$h9$46NHbw1U z!M;uY!TPTQ373Iu!m#S^$YgN1t7^C+!66i{;fm*N83lje!k&3iS-g?G@5mf18M8!K zUBp7Q;6Aq+i7>?ytEcc-V&N(CF_BrK%^|~~My@vAK`diY*o+_x zA6+|4Fv0ZY0CQfBy`Q`n?kuZTgL1t_{`P)Rah}<9|;5lk8!vhYwIMa&$ z-`EHLyJh}hEYE(=|M+6*{%1|NTRSE75Hvd&R^ zH%)hfGSd&=blwfQ@5_SIe4O_~+T#RAlI00zHG#Y*ny|+y}3bNmE_3SLW)%}7J3OD`_T=*FX`Np*y zfNo}(TSjiaQ?Z>W49!!q)vD?Bb{Mp3wTuo#$pq}i98O?^dRbT6Q0*Y01;P=!LN^k( z&K6D%XAcBMG*WmeRm1xwM@3Ej`_x?l;8S-6HpVy$1}`H~r9IKveylQJ7|8*~3l$!2 z;7dAiJNtDv|7M*;4SD1zYvo#t$Tbcz4PL?Ia9 zwh38qhoh5Q%wJgf*~RHGN7(Hf_ePNSUW?aZGB(+Q&~;IyaCq9ySy8vN0uJCR{J z9naVx=Z4?>bJ=zcI>ah60Ec2{`AxSyT5mW**7oSSo!bA;|5YKx{J$xdkF!UqI)B9b zu3zGXB8X{PhwfUcCe*L0Jt4Fc4^WUdd^^2tb)Ax7|E*UrZRmzVmqe%Hn~< zLov_Oz(~}Wz;}lIZ^$Kz{KrLY=$tMHm6%9DJWd^T7%mdjL-~{#S zdwlZhPGfH)xHgG@dEeBI@qU+|wK`9OobuPW2e1-4b-?M%a{$IL|ue|}PT+DhzKV<=_zsI++5cCViuJJo|yEvikH z)M$Nb~zTsp#dt0UNdZ950z)&RrGPM%gzY*7&=Yiof%xIAEZ)gpy%^(boay+Q#E;^a~2^oRiWr{r9W0i_gVni32gB8jtWIVnq z?7~YJe&8k%H9IF1-jAA)%0Az$`W`p{_fnD>n6qWrPRYjAkZ0;n_}y%o8_N&RsDY<( z0YFQ3r{sMlaM#L|j}eNeXZRnS_shTm8lrW^&+<$Ans)QxiEX?-Ipu6*(?@@2|ANod z%w6St50%%O0k2L=ow0p)1)}m($>U8Pvsz;d&UiGrvKbSNMyGbv@yqHQ5mrSTK1`zL zy^e$%jQLMK@HHvnK${;8hh>kr()Gl)jFsG;jIkrxStc>51#|3=BdVJ4Z212T>-BbE z>KviyUK@?e?i5(OTN5Cq_vC&LSna?2Y^!(KHE^8=<|aYwS3s*)_gLZ$^6`&<@~ zAecQbn@^N!5j&m_w~ly-Fo_q>b8aXe&RvLjJ{zmIB;GV9I8XVT_O&B7v^7w8se?jw zzPuJ(20YPmXC-nd%3v-3{BPS}=Sb2mk)7}!!*o{NpV88FmAv@Sh{9ZXms)Hj$J7;P zJ*ZwYE393K&Z~dP_w+WP|D@)4(BPq6X)kPy`@W5b(&J0&!|MCgFnlc>S;6IlO8bo6 z{zU&qH{t{?9LZPLxrTgyfF>DmxH-}Di?Av=z>rGV^j$$(S+5tZ3uMGYgcoaB;vZY; z{$mRYqM^h>+63v`gI#j9z33gO5AU_v;_10YsdMfL;Wn`vBE!rzxB^NNFMo1;@U+!e zFoJhAFTfuZY(khum|vHoiO4^ubXJ}Vnf(fayOsntU*k4rrOn3b0UGr+pqDI1LR_Wtdo zfr&(6DliLxUe_fgj3=)~l#m_9*KudCG_hiDh*rMq_fm9*9RCQix6vB5_?0hqh7H3x zq`$F%NU7iC`F0Nxx@D<8)>b%bdlX`oLyXL{5q_#WoewwlbHO}9quGsFc7rct^cKmO zzDEl?+HBMP7(ZF;)+kzR%C-Z9PTP4!`ZV!urSIPOb1Td5>L>(-vtXcDv-uKuDp4Vz2ep~F=T^vwPufV^u{VPt2ZOoHuH*h3Fpe0 zZSOJ5lWFgBwr=RBkRqNp!^OYMB+$^j?a6yB1JH(er(Eoa8Zmn_pQH`yepgRk$37WV#E zm60LwXOc;-bPN)oLJ4N%nZ<);uC1SlFsa}FX)tr02)kL_M9&IrR=+5VA}ZkZ2x%RW zU~#Tn$$X75ljx8ZUaPafgH~Q%j!Ij-mB_cu#QUse*xTgiDzd_|Uhb%`4!-I#ojkQ0 zNU_hnFJp8-IO&2(4Ad|SPlDjaCl{{`=?XETzq|{!aLA<=_ZyqyZ(4NqS3VrD z*3}EZF{}>B^r~yKxLLT&n8k3i3HUuyx3ibK(sz1&oZ)_<1dG82|8E&Iy6BCi3_p@t z;YUj^Su)y)h?@I3tb;%QoxxZpW-S*zG@f6t>WKjqgOWR9H2YY)Tl7B6R=kD#-#okM7jhvw{_eiJi)p058?o+KIv2+GsvzAtRE&ruD^w2FZBM*IV7Tg zf*bjTOoQc;n4FXsw4{3(+i|45ixwDyXd?Zb%rZ9|xk*4#3~{>B4v9F2capszcaGOo zI%c$`&)egTEuppSn4fxqG3@h~pAGJiQDa<<_a-uUWT1CVdN)$wx?? z6W5O@e?0`(TVD9e!-a}K@~i_09nYgR){Uu_)4hpTIGyF$pQyiL6>m6@AT-i1T!%e5 z7`EEqPK}&zZ{0{R+LHep(o*c8<61ZduQ>M(C+dj4T+_Inshn*an%UtY0#O5mIt8?M zlRB3_V+$rsEM+G(rtu5=UR4eIv&%EZ-gFixIdOWDpfRdV4`@#@_uhXW`LWQo@}Fc6 z?BeIYC($H+3~saCe)saDz?-T(`&QRvS~=-!J%X8!A*TK^(OQKZ{XblS6o{NUQ0F@H zi2(>mb6XkVoWc$ZS{R?SFXqqJ6N+LtJ}#< z<|i%O0zYNFCs6)&+-P;RDbBNQ+!P%;>`p`I<75lvXdDrs|Y0`lTtYFidUk zMBG`+@Juqzfd#cGL(IheSAQ|ErNDR1kBc9%b^h@N3JGOQ&fyNyI8-Pt2tZpr7c-uZ z8eV!X7tq{3Xol|5e&(GgBn*onFj>DmMA1)qaOq|VUcMucHp5WZ+3R+#ICqu2FFXIs zi=jk;ohWRcc35`%B@V|ff8mUsGqXv**Lj#(T!P{nAM;B^57@yo^Dw+vamQ>f(G|Jvej<$IUj*7XtX4y7!<>(qBw>jN z)juZi1DV4BRhbJ}=J(J|m5aIOeSTyz0$w*6tlHUjYku1Qs$71E|8dU>?t4W@If?cv zgaT@<0zTcUQcb>&WEMnm5DU$;2^Cg~Gl;1uk=k8#@g$fGPE1Zptx4nkvYITr`4;F? zd=%aHtX2w-+AjR%#pq18^VTO&K|nLFB9l>=Jk@Yfe9y}BY1n%GSrJ~5gUKe_##I)- zfaaqwUYHYQ-a+X?-7#I*GKr({5~|$cZ&tfC8zBh~K|;Ez>eKiGbAA`R|1$&bKW2zK zRbP})@r+tF7}I1kvlMlC%$E`nNG!6r*JK?lH_mWH=Fgw`#a51GWAINGgyGWXce?qg zwI2#cK2my(sWvV41pe6CgKpyUPzd?x92b7|1 zy-jDxR~uVulCE1tBmMuz9ZNkR6ox? zj1k75O+4!-F)dZ7QT5|sEjJ9r2=w*Sfn6<_Te~ZQw#lJ?x_pQJtC$cV>ajBr2q?Av zm`{A?MuJ{NGU>%&E@`^wV9zEMZ$g!Ea(W(ns?4li6(PzOuXY~hi2u>N=AAlsVe7Mm z!s_{%Wsph*pICvE&)J)6^NIm^x;Luk!)<4Ap6lr|6oXsSMg>Y7&1rF-I4WiO;a>VD zF1e;$>4)thKJa4HP@hUk&ay zdMWi+VJ$h&CqY<1Smu)PxEVjVuG5fMCk?|u+}X&R>`hJ`*Tl|a&0x!QM7Y~Cz8nFo zCx+)fher8?33hRannv`32yI8nuN(?b?L>uJN-1?JiE}@05{RhSDE%(s{YY$l*b#bK z6)5@mkmb9gk_6-ndKFm12z{W)Y=ixmm@0;H}##M(ADbN2# z(QiCiKlOX9pcxU;jqk>Wv1sZ1PhVLqjDKU7K48rmKE9B^`+wH~j}y*julmgstym$h z3zo(c{FzSFoU1Rby0Pk_E_nR#JY)ytGXvgAasx0kgkKn(w2qEr)yx34o^DTCw=iF4QkJfEZj5(Rqd0(D4n8#^R=v zXd1f;RaBA8!^JA^NO5DVtb|eAD|@Vi#L(ri>n)2x{@pTic_s5u68k=CRDISw(E&ew zaNnVSqcS&Xox%=#Bgpt#{bLk~)kv*9nEA3Miex`hRpffqDCUD9)HHX-a{Ds#w~rYy z&>FJ~*o1Ikn{b8ehy3HlVv-xz8ogOZPaN(ViXM{q9uL12GK!&T_4xS)%(JMc`*ftB zOQ@52RvNj^@yA0av#jlDQ=QKp&8vPR8l>?=c!XVp6e2ISI*v&uo*HnqPb{8yrFg9R z3&jic4<-!9ln~k+jT*v=)By9oYLJCS&M_|BJ9A>ol60`9EyKll-J_h*a;(`cnA(y| zFa}#8yWk}i;kUTD(#}w)=u)S92Y<7J*yNBlFw<>DDlsv25icy z1WVbUq)se5;h;+lmSSsBAHy+#QIEWLcMeOF%&}ns?3IfBTQj3eQN)guk8zC9PFAr? zbV2#aLs}c%v4y9^`B2i!uM!_unMHW2Pb4AUN0Tzka8v|2#t|@3Ej(4swL>V1rx_|) zQ?JZT*j}fPUQHyEI0M^!5f?KTzu&_$gMfVde);#H7JDCNBw*uP+xQ|d?>3+kIpRxl zTmigRk{A(vUOfjtkpZj2N_;yl$yg{F9lDuoB{}w2EF$H)h;Q<#XH@J0f)A6u>@hDH z&+7s=W=WxzgK0G}Xsi-^O)0E6DJ#JT+2y1!9+c!bzrtzwYVWS(fO4 z^u;r^Sj~vx{QK(Cv0?B_tN|&&)K?_kA6v^~xr3QSUf;xSq+a3c?is2A5K3DDbac$nFN{?&`$5#)T zf=()DaGk=!O|cLP1PzR_Gp_ zcP^@H3^^kFhrWr>QH)jwY`0OgD{~dWzcM6|q}HTC^P*AMmp&A`>5$h-8$$u{MCa$3 zI|!r+Fe<54sQ_Ayi{-o zwJ{_<8rCjbA4j2ul@j(~aDdt=9n_Won|q$oa^wB5NQ~yMmvj6*PvMh;;{l1yiMl1L zqHlh);R0bqZc&S#ST6TBTU~o@?h$vn&idVszq-#yGnZ?X?5**~8!(8b0!E)JAt+F9 zxbK(7_D2sk(l}?DTFVx`4UGk6RO^P2o2J^EtV_u)5xkFf9t*g@oE*8Zb>b7;fg}&t zcwqRVMg_IkaKf$;Tq)b6T0ZU&vip)FbeeTG9PO;_iNtN064?iZWxut?e^L!+L-(I~ z+_jw0xJh;Qxn|FzmyQSr;Y2~gHC&YAEP+Zg{NuS~|8eWig0H$pel z?@a*B!}_Y0ppb}_HMHXR*9Yz!KtQvtSAvmH-ymmW1M)rYr-gpMp4hxrTWtDOuF z{Tfp~&#J)~{LWhrX3w?uf6fB%A<7ii6)n?@eA5J936N}XJ2;uFkCzb8Xz0WlO{CIo z@eEv178?f>oX^bfvtPH0-Xfi3NA;S6TET)lium zT2;n==HBC-p86;^zec~x!dYZqR;)7yd&z}@elk*+Sr|=Py=O7(`5w)9FVxn4%sH&J z_Az0msyfehYLZCzk|8Ep4?B$9%+|e2*&?X`iZ98Mw$4uGRIgDY-2lo`$qNb zZft>Ls=?%r$6}ddRCRV!SmFr2+Zqg}_&{_ni;K7RFd!a30kJ}|-U^&)fBhEGv!x}h8Uu5YZp#k z(&zJmUa%KrhR~=t=;mCKlagYW+(Pj_-H!9jo<}G-L|&3$nt;Gj6|gUQ4cBF^mSI;k z@H=bjx4W+|T;g}b+A-lg+dVkkpKDh8jFNnZ@FDj~t#m+V+M{NP3k9{w22L2dSzN^JDj3whg24&%RN?$(jl$KoDGwDowpcZn592II@vhy-FZ>!)3x?6VuxM0mPxUz3%SEZ7s=U4V;w(e-c_az6h$pwXTx^tZ!2L zX+9{gGi?{X)^&uJV-VQlL6_yuaLEM}HXL=GA#}(~F;qXi)PU9V9lZ{M30#U7lq?#c zu*Eayd@IZ2ra9b3!dZwxD)b>oXe58oj4qki=<$*k($zJq}@oVQujmZ3>q zGoz`BX_r)K8BxI=rt^z!23XXl$Wjm1ZhH0R$+aTk0ezGqFl(?~lPbfA>>P>YcO|mh zd0QdGUkSNtAU~=g@1-E7Nzyg;<>Kb%S)wgpOet**QTpu9ZFdev_ielOYxz4}s}@Uh zT=b~o0lXG0^;EU1K_!^SIzxuKPIH$D&}@unWDQwz?m(68{m>y3hcM2r?QT`=D8 zVjf~}+d@{=FaWe>mkK%pwg-iAO*wa%uXXgtNmuJ5<$Btx5*&-2gZMz!b6oi=QKx5X1xhL1Rh)P z#%gh$1ACxC3T)&RWprH|1HHjVA?eGH9>N%&roD$LcIV<%@kLMIY?y~Yz)%}VoBd*i zasdfEG?}fU=C8Rk!a|xh@{7&rmclUmgs>=v9Cn}w3j|DX);UU!7Jz9@=!6?Y-1LJq zW<%@f*SG|DvFrXf7Ad}dkk2(e`nM#gwgI|;Wi}m=w=jACJUXtB@vwrFexR@&TZCmIyUb^$wDu(#%iU>R--lW9m_ zp#ujrL;NC^qXF1120E+FD+B&lo2jU)t1L-OPCrudqYf4H^)QC4c;Q_s>DN(wKdQuB?5-<41fqmmjJI z42oJ=eMXvFBS09yKOIJaP6kmsOl#37IwFyLL%ARs{6%pf4s@9w8BTVvAmUhKmm*UD(GKg#S?H(vc%kk2#{2f9GTocNd zOJsX1tn!#eA! zTy(^w_I0BElBxSmMK|@zoo)D;S_Y{Bn{Osbuj*a|>(Nho@t-A7t zUVo!iUMN>Nu00)gRs)7de8O+bG}>HY0wdQM7Jk5v*rzkpy?IpsF^|oro#7U|9Kqq5 zRZOQ1EHhSj&MZ`oH%a;~@%^(eugoA}3vI^Hx_2WQ23vbUr^}{yGkQCDtoC3CvXCpJ z`eqR`RZ$%WN$mF9N#ee3Ry=R7mm#@vwupJ-Sm)%>OWEI{`HB9Bn89Dc0MbuU^d>*~ zJZ3tzxB81zHgkrhQS@V{jpg_oN!l#fN-IItEDATw;8q&3_D$t^{v{e0hp73z8RWog`-l?(GNIC3lSSoVAuqx$=t{;=LOTDr z`D2p>*ehqOO@EclG}L2Uh&^qb36-cS2>i!pa!YNU9INL$YLc_7KyG1dyEqEF+9+B2 zs>D}se$c6l9wzD?kr}`St`=#PP~Urn#M2gs!Z2S}<`eIl8Ia{}9|!{7%hPK8A}T(2 zHE$Jd)D0F{kkNHKp?Y#afaS}j$`X@77cJoaHXDvT`L(t)+y329rZllB-0gfD1geeH z&?4hz^Y=!A<-OA5+}p3PXpw=cYDjXe#7vxcUhW4txr4hq?2V(2M`(S(4`pt1XMLOX zrR)b-fU`oMs~GXFCbd#Y=`e8?ouHo*QDyduQCDwKiv z?|drnlkK6tSznGAk+*MNt~pY&>j(G{E)YN^RX!ex(wS7Q32+3m-W^L3gFAscx32m! zeojtQR$H~J#4jZ5T3w4?m9(dhsz5)C-^u$pmO5=wu*T_c=jT1xlNRgv^I)E>9yGLE zhW)-(;Q>N&P9EsZ0z4WakJH@r#!|b&Inv87(6qfRTHe%DJ%@U%wl&5}e@j=7VD5Yz4~*vgZb5y28az+`o-*~zvv@{W z`>**6zcb)WpMI}j*H-NyFu6Pd-8Nd_d};22DQ$pSV&)p2#du%f#%c5J5umYA50k62Nm3YTD(P1e|#51aSAif8du=*4)@!} zzW7VBbp5O!wO$Vl^Hb3k_sylkS_zZ9ivXF7AylSuw@EWd(V)(!goz-Ls!gcha%cnGH+IiRZ>V%&8iBu5K*@ zyh?)^`zk|TsG;UfpH?g~w>D|Eq*(#8G3%A=j=NZAf>>!ooL{dwEbdWFuC^}Q_L5&^ zG1JrMV}qi0a6t0}{>GTxz~O!avFa7cCbz$%?ASMxRF(sRzR^vMSg4Q7Q+=U8`KZuh zNGNgqplSycPpupWUi=YRxf8T=9E0B&{|!Oa_$B1R!|(W2K#;YOC3v&ZjN%lh4hf0- z(VTZPNgEkWuH`0>cBQ^mLiK~M2kz0g6iE(qsA1BMyCw!>KHd4sT%^@Tx2uSdKa`;~++=p{KxC7xsLm+WvhB>8&Iv^5x`WqeefS0B|$ z(z~PYy~xP#3!^zy(i76VNbQB_Bb8ls!@G+?36~|@+WOw9gkKE3NVak#_%63fdpFTB zueG|rW89%o*+=@`!0i5HE$$53f8rKeE4Vuyu-OK5V&6+eBe^jl89q9Pqwh2p+sYml z;m2E%0{1?*8S(GluLkcK6MvxPPUHh9&Ngoga-J7Ze9evM@uw$_8;~XKXETB2z}XM| z52#JMwm@*UAUo%gpM?P*DAIH6;S<7$^Tdeb*Uz!aV-tdt9@uqN@oU-x{;>+SXISaU z2t@l+g>nqDvuq)zqpG9T1iLqFCk_s?u7GRTZBvSm;G1bbHBKV;cwCqpV_vHgza3g^ z{fLRYI6tQZfnZ4(TjT^LlOZhLm5QU3M}ok{+J>lksXkP}2a#)Aoj(49<0sJ(c`v|4 z+tc?CXan?|!9qE(+d&vk??5dI`QCGFKl$FFm9(Nt82u7K9td(R8zzZOS~)wtC2)AZ zT~ar=SF6eqX#Y8CN)C#>ZT_a|tt9rNjv`(@W)_Z8hdhrkN_fG$%5tQukI}K0zuCV@ zB2O)eAM{0`QCy!IC=CvnMjC2(9znCTik3R{5Ow$_(NaN+>}2Fl1ipF=J|!9E@wgkZG?x;%KA^ZOq1OFmG?+3 za*_I<9OFE?Y;@EG!bO(rX?74d_1E`}1d>a{#Hu-;W*C6`f+XP+4aQbqL3l@=9E;4& zujHk@X)w+SO6-0EtB2WjFlG@t&eLb=2rp<+Vio-S6;a}ax?JKctP!e_$l!`7`8?39 z3}jBOyOnltscwRAU&uCRyWL$kG+S;Yi^3WfV-sQAc6R2KZ5Rt^(xo3V_w`Y202>ba z){nXAA9(wQK8{*7@$LP9x@E9*?17#2tD2Gocf}@X6^)KV#f!OgnO8gfQ*QWD#)NWR zt8>wbp8w3f$x!_if86A!;Gc&KR1Qs?F8q$0(0z3Bxr>ONt~DzSpynRbbZ?zLgPvAi z7{Ooawcb#8Uyq>2_<~lhqQ%%PFL|nsySBn&KGvI0Rwk zTP+EE_>J}z%r8s6qZ-MP2Z9~|$4N~+`^`%5i^46@hIci5ZS_I@?6u6Ez}&dYXE&s&_A(RHpc6#Q z7QkvyB}9^8{J>+0!DSQe=BKzm)hD(SXTIg*lzg|jt3#OT@wh6gVUhYx3&RDQXRnsk zH`?Z6pp~w(Z%%{49kY4bJHETN32t@-2e~EcLuDQ58JY-~Yn%kFZDMhBr;S3sD;>au zS4J7{C5+9+m=WxSU_M8MV1y|wiw*7r7VzQ~Fq;X7g9h$Rv+WdpHJf*c^dFsM<3kfQ zkkjNE;K5&SiEl#i2HwPPAU@_U(FeUQJS4V7_GpikH zy&s@ZF-H2@uZYkHl%xWtmOZ}DxWLZiFI=`1VOJw{(eQL$ag60*P|mM3fAi}mk+%TC zfo#(qC7Ii!SYXiB!+mT?2emU=-H{m$Vg#e!_j&P{Vxm|H)aF4f#O|%D!-T;aI_k0( z(YRX#l^K|HQ<0f(v*PL9T~pZm!PcP10mtewpSDUi=>@8C$#ZF15Wx1!ToAB@%u<|q zre^SYPe?K5I?BQ5i$TuC9e(WRL>{TblzfyY}Fogr`FL~avD&$B-PAuvK%I;ALbz)Sr_t?`z9jK~|Lu8X6{3^1J0)O!j3x6D>{C7 zazzZJlHTXH1pQ4hK#PWc;f{RLcb&87vJBxdbT~KaokN86?yh2_$wzx6DvKh}Ft>XF zlvK|c&3gAmQEsGhg#z=rZfcq4z;=Z02cmAH9D5hf?)==cUkU}Tedn>Sl$MeqB?PH| zUN^6J6cG>*V^wxs4bVF$bv6fz%z5l6BBFqY$94(b;7}UdqwB821FTNx5|HOB5%-L) z5guh))-r7!?$jno_GvcVEv$Jep)XWC+BKzC*8jXs0tLMwhJbn@NavnzSG6WM@0NAJ zY?Sye>67=GwFVSH#q=_TK)@$$u$>yw5%I;JvOu%NoYi&ajUlQm7t3Xuma5X7 zZA-eM#7?ctagmzM)RMQG7QOi(FspvNm(h%1XEw-Ex)tcI~yBI8LH zuov$9NO6%l@`CKGXxd0e%VqL0OAp%nWj2GqZF`h zvcLWs5W2|(*Alp0kgzt`v9R6A5WhWVZSasltePvEfNpE&M1Vty|4LjG`^D?xx>z^Q z68e#k8c9Yq;mmKnp{E1Kd$lkxrnWL>cn+Ssr4l&qs#gjt$rANBp9YJfR)z4A!y_&&EcmhDNA*?kl*uUWlWBT za5T2r4saUa$WJ>#aNfwTw?(v8r!lmGmFvuUX{bNq6yLpyvexYhZXx%$kZ#5-*?1nY zR(wY;#pF5#p4o=5%&5x5-s*)_PNO%9k5}L0ErL!t40?^K9#V4j7SIGN^XBI7j>5un ze}g>|p+?Yg+s}7XDNmBs*Oan@5YFV9?gfaZq`d^|GJ@gLApaeWP#Ep z7;#9Ta06N+1}zy7hoqO(XKJ-_T-YC%4G*^dusgRnId{t20$+Z0C}%5Mc&zhgL0FT( zD3JFJjPKivj8S&u2OD^R+g#I3cgKFSWy;Vlim0X1S`yElNhWcXcF?WCErpu7G@CTE z7-1=Jl95iLGU0E6JpU+hV}9*e#~Swrg!PxVZF1)MexKFQTl9{uv zQ9h>`k1c_ZFR)Inw%V4@;_*PPb(3P3)HaoH^wa0+OHToG>FYkNm95X>I~Gf~SKPzC z4RcAFzxfMT9n=b0H`n~9mUe$*9m#N+J9l5o~SYB0oguV<1MRZ+KU53anxa5z-3scF zKf!<-Wdt+Oie_o2mW#e2a$01Y@aNJqRq=J{A{p3tSU3{IC^4~0tZTuxhqT+Ox#!%fPt*@@S5|kx!CXKRJmjjF#}lii#>d z9mA$05XX=#qF7e)Br}1xrp?7af=?n%t{I>(WygW|)z zd*ANhta;Hpbhpv+@42+z4ExOi9Zpy-aMJT2O``U8UyI9ejT>FgkdAFzBSst4h<|nv+;w1JGR1hMP!ou?#bgzI`-xp^BvjQWF^AUpzLjk z5L*n1r;2*R07^1d2b!jadB{U}{=qzcJh>9OB35qSlWGNME|OFgE?_}<@gKiYu_nL& zS|`){K;Id8z-DLB<+3=yzFT)-7=oSJj_}mIb99+%hT4@JDHESiv<~FHv}2_Gxw{0# zBd9L3gSz>e4hS)B>us~ikx}U#PdB}$1&Je3y!jA{vf~vPSK>hq*H$h^f}&+q5Wu(} z42$WZ$&PK1bU{EGLdcdNH-a~3(uD)ukHtI=M(yB5-nZEQsuN$poU{M-p3m}=qge*4 zK$C|c^m?Dsa+31~oo|_KODHk#kBsSx1p9}3GpM#IwywEKzI2F`w6oH~+TksA_*u&@ zgvFuG!Ikq(cz}**%-Sp1V9c-vq8v?dVrVfz?H-(f*o1_l27a3ftJ_#QFURk$kMons z>g3R%XG)_#k~)2XfJYEdjG|^JzF$%@J}j>C@{ajWTWIBJwT`ye{S1Eudz01dV_fU| z-y&J>u3X@NCEPkRGi@YRcr?X)32F%){2;fjVfd2$q=r>-9wx{i*)Dl&3}wJimx97Q z(e2A&9?C^-BFBp5LufNdryWaP+uCCDBe%QY{4%6F5urZzyEa>GBo{WlP~Rr@`%F{8Y$w65Qv( zJZfyE<nAy8UXmHN#%jx8IlYbI#pSYPbpXDxi%%LygVgTAM46q znEdN{AzOATY&#f{gxYB_{t>t}9$mHSbojI+I@?ZsS8XqUb-t=oO`Y*6`I!g)F(%t? z=F*tfG?7^u#@mX&MsT9tErCWl_K_-AG?StxXH}MJOe#&b=E8e9|820tR&D~2zR3B7 zY+xv4ZdvrmCVc5?5L#fnqHF9sp6GZ$ZP1N!r;zF4-P|-yw$lc}=<>xF-`vr9`*#!> z^&-coW?inVM1cw@w|RkVx`miC?3I-4d790FFQ^zq12SHP&79}Uawx?ehY?X5$A=}u z2a$j;YwW(~h^}7R9b1%)&u;6W?C9>gs5m7Q6p9msmh6n6Jw$F5a_wJrL(7swLPW*4 zsr{-|a!=jbkF#L|G|ClMC7X6BZ8Qp_Debgt#aPymLf;qZ_}n3|^Ka;|_3&-6blga!W|(^_@yplt4{xyUp@An$SiOe)}1L z-<2X&%V6o}cCxHdl2)os7@55UprKM^Pc0zMI3?i{pp3(xMZ14OdTwq02nbb0R5`Gjw1=r2Eg# zw?GDJz+#(REHBG}J!al9y%{)W{DGm+*&}C|eZ_gUg>eQpBMv;QhQawPYgjfra~*r8 z-7}Jr$y&E@BQQ)FgT<@AC3e<*yRxOdG|Ob=m-%C&rXctN_uE8)wsKKq1xtCGlm-h(6TfG`^G?cC2@Xbg4Dy8Gh*%2;eWYU~>p?^L{G>=)i`@ z4`7Y-iO*kZw9ykA_8u&X3p)4!Nn3Ec4HnHwdKdKW71KrZ{SG$Tc;H;~O$C{c>a5u@eFIs__)h4?oR9 z$$Yz!NltzSBvG_qy#1Ks;sSZCS7}We%IP(_TLVlD>dS0wVtS^7XXRs*^vDI)PhxNI zY&V}A<`q_K$SmJLW-SZlqxoTp@L={hYEMP0Rfh*uW0oy2tj22OU<{Mf)>a!&X+Qb%!syt%-g}LY&IZR#+jq znA~0V;8{FwCXNi?a?LitTje^hR0mF5j6eIw6^*}HzQP=qcyG&n%OFZbg5to+i>R)- z5aBn=JPWTP>Cz&q6|YWuyN7!8I_M@}Scn9P(s7#)wJj(e79iI@xr89rf;oJWn}oA2 zFPBre+by_L_=PFLpf{7z`W)iZukpbG%mWtCM`FTLU(U;dCn^??E}_^BN|gE@j+%+X zJWr_iI69LPzeRt_>HdmReoHq2Y8H736k)aVydrpuELBI?(-uS) zyGQ3gdq~}49;7;Hat=$$<#y&7ic2WS*ltv9e5!2|Qv*S8sbVr}C&2XoEKIntiRVh- zXTh%WoQPZL25142d&iG!@m)G}Mi9(@O){#?6aDVH1oQ#paXX`ZphIwGz4#Y2>PVdd zVEYHvhwtreZr7pTJ;MqVco1Nt?O@EocvuCy+~!bCkfOv$ZZbswb_t~g@ViF_dBMN& zARNW(`-HTSQ>6xQT67nZqSx!8HVwdW_}b(mEp#$>_fj;(*uikp1w1UNmwbJ zD)MeQ46(Ehyxt79ztm{L|N3<}(adHVyYOwdZw9r4-r47aaru4mZn>aYYd5C{K6TZ2 z&3AFJ&0yy&9nD-By@^-2I~dMYe&OizO{Z^v;2pWwhOz@Iftb0caa2-Z442>@$R}>_M|)JjoUEFJaWmkPt77}U?8oB+C71$ zEudic*XWWFl;|Q;W-u>~FT&!19ndbENP2MLn3ZIeTjrd6UJFQTJ);+kwgymtV|U*7+(c(Vazm+SLrVH=B;spm4NZXyyNKl!Gso zP+GWXYUOqKV5B=Scp|=Y`Sp!WHenj9m3|~+>=o6DB2sQJ{Y3k?s6ednlJHLEocRd& zuF#>j2PG}l(%*?Dbtc^+xEGY7ii%2Skm&s%UVj=C??hWu!_wDtYS~|Oi=~_kqeeoH zHW7S9wFlJ8fi9KY@Kpa@W--t@;E;rR-zf(7N8!=>d@vBv`?Ck)HN4D(({Pysl}=9M zfkB0bHO)i9@)xW%Z(;HiV|!4@1(s8&N7{sOk6XH6fTbzIrHQM1(xw#ra=7iPt3N5~ zN0Lok{|cX7H`8<0J5KN<3jVw7l)wCCi7A#k+ z!B2N9Zh;ZF9i>R`uXGeyx?(@RCoZZ4pGuGYF>Jnh+w>lTQ@hXjGCr>AsMOKaj6d$S zkb%qs)<7&tmE>*b&^3_nP5aaKNm8}_BbNxYodw0^4`0!4V(9*6QRt=*vK<&0e8j{r zTq$SUK)umvR6;wf#|uRfm&Mn{st|wU}*?R_#gwY9H;ODysa$9hQ zo9imE3x-xW=dqi9l)Gh41f?*pS!AIcJ%e21!dcOLaX)DbNUf%wYdJ=C5%%VbKE!ui z&4t`3chiTPjMCLw)Vq;*IzpSCBJ>P~;dXy8=j@%BH&XbF>5OjaKYORDk55i~2Y3|d zqb0>neHRNI6(9`ur3yFRbu>8S!x;dp6&SQXP}e@wrNPF63_P$%7f7X#BcBFd2fIhZ z>ZhzJRu%Rea+gbu)1i*R8SDiEDRLXq z-$b`sNq|>%u0<&G2_M8uhuo{9>cloH)$kU1_j~Yi6@ppY<>;D4lS{GL+669jUL_Ei zLQ>2~nxdb@QL$L~kl29PtkL9CZ+E`ME0(B58f!W*=Hu)td=ftOXyO?tf14*P`cJz+ z4vaB_eGR&MZQ;XQabN8W_qm=swcAy`8i~3Q5Oi=2ULw@hl6Fu3!>*2h@gE@uQ!3pS*s}@*0x~PaB`*U48tRO z(>A9k_+>kU1M16}67PqecQ}a?laoP;FvM&0@F)_Q=@C2Fi+wf|j z5uL5S+k;#_RQ)T70GDEU^v|DryPr$vs!snLHI~0| zlZj0O=bsQ>KE1&#UayP8>pQ~0-cQN{5hF=dsa8=O(TrCDBgScoCgAf&qoav)?pUL= zizCWt8gq&GA2F7p3GM_xNMiZOm4#J*6q{$D+@neL0>XQOjF``_p~jS%_KNlUkU-X5 zXKCwu^^o(gz%2fH^T9R9B{9X-FS6bbdQXok7Sc&$;R1c>V!Q0&dh_9O(VF&Ri-L;O zz;g8@xp!3IW_b6yIDT_V-K==oCygri<^Sx`!|(=JnBhWo(u4)tmW1u2t|BB#-(Q&4 z0ZnRCv|?e)a-D5st8O`OwN%^@{`-!UTdLqr+)Z{utPyW;e;N*VWKXGt_j^bR4D@}M z^!pZaaNm~I-y5mM{}H!OzBHSZy1{LjBI zrR)_SP0;K}>fK&E#GR%Yp|;tEwzjzJLeBo%WTOLEG_!hSawFPFkj`@Es7%jz06QO4 zVdF=Cd(tP0+u61cQgo?=BhpvwA;{gn2I;QsC3v^PL_nJK1FMebuOHZcc2H*IwXJbI zz$5zqYylaC2$23Q7-kHOBcx%3HJjc(7Ak78eL|T448l;3Y2(fZ*}2yN@>j}kf+3t? zjs{u{w2{4v|75%A$VOF+k#f<4AI1MP(0#zIU(t(y*K_-Gl5X#8gU!AVIGcgOmY%fi zuS5EGAee4h1vs4bX_Zl`L|CXL@M~v_TBZHK+2=$>6V#F(?9`&AaHmw@3%ntUd&986 zWoATqGsiW$n2R2iJ*MY1-B0r?yXt50JlADs5_4pV4#Z<%G8sDI1qi(hl5` zo+g=nU3X0cO0j{<+Q{#RV^L~Lj)!QB9-BhO_&>`}=m!yn9+A$s6d}ZryYY^attZ_i35q z&wJ(RCwk6m30^Uc5Tx&v1%tyTNcg{xlqtB9rD|trPQ7bAhOOu-hSr*L=?TM3TL(Z( z;fF~B?mJ|6YfFF7waT!E4N==hMD06gwZt3Rw|#{@!du8&k5VcCdrT_vF@kiVwP%+Su@Do^~qSACQ|!|$q4ZTTkbKhOq-)Qwi^w# zVSYyw#HqK$Em$xe-ZBPQamv1Ut-vR$)FPhhG>K{DZ>CwE`P1E|$)ixV3$(Dk04H-= zVbT!v=K_pli*q{>b?%=zmFi2!DHX|8PE94+&M~U&mVZBHCj0R1D*dpf?D zFmlIfuUet&f%itat)3K#)kc+Zl@~X6wavfNWBeXtGrD^~Yry;V?3&`l4SdAVuJw7+MxSvW1Kwz>sB-e}{`z}N+oUhpx z{=h}_zn*>Z8D|5*u(g5RN4Aq*viGVl+g{BSbbki7Kb2ag&UUCXNVYU-367j zPeD1)n5KNK(Py6I<;7E;I)1zw;@!No57EaU%_SfssQ>_=D^z1h8DJQHd*aFSR@pcp zWC%v*dmd)H3P#zWkvtbFDS*#PDv3to?MixPC=uX!AO_ao`eoOG03H%OkGqbKrY7$D z0^NZbe%O!2C9ZV{((SiwPMn>0Ig=fxXC6Qm|PP)ob z+d5U4aaIM%Rd{pz;M%`4bP52V`(u}CI}Mk}?-=Q5hELC4Y89E)Sc`H?tDKl%GSxC! zNi}Rv;yKszHQ;eoU*8MVf?t<6@&TUONIJ&x(QvaVB_P#)(2Pi=$-R{~)b|&%{a-ow zUe6fIWi0Yvp*|&mCqbdq2qI!%>+F@(zs-Aq-)in;U+h%yyq;T{iJnxmu%gl+T4tGvJ$!kqsTHg#mS%+1lnie=b!?1s(&t#Cx;R4 z9ugC6k6TS2jk-7KD|U=eq?g_dcK%z}Fp8v`FV1yDo~_20$}u&GsFYJR4bHjGp!&^% zYxL`Nr&kp(nK9xK6boC3(!+I+=8#4cNy{W_*0l<7c6XRzRp`2fikUBdp>1>*Tc1TR z-U8vF?cnNa!R@^574M6ScpxQ7*5#ctpP)eX=kU1qYV!VEn^;Mgyw-7=9swd+>a1Xm z{T%3PQKMR}a?ZsOMls254zF3?ef0-3R*#4(0eaO!8z)0=s3sV8W3wiJVIMwwsaD*D z!a^cY8&)(WG@j4Z8kPgBIAmYEhF>_4q9`NNg2+nj53AMAniY&hE&mo+L>z|!v&%J8 zXEL%_aKyVK$=6y33~?(y%+ABO;%~I@I8wpPWM`_;oH?-*O&CHS>qHhwHpbiaik5mw zM!q@73~`wdit1GPJMqDwD938m>WrOgn;hNRT;MT%T?^Lvwd#xkNtp8uS4ky|kq@NUy9!fh z_R!0PK+>|h@mx+QF#ddy^m4%GkkruS>6-_6bPoV@3~__~6~8TG8@YMp7f4qlpm5gU z7*FjIo7+L-;+*Drq^E(-ZUAP*^LZ((=P8Fw1DQ}9bs~tVs*Zs3`pe&9{=g?CRU=6(%a8KL%ZHd3_~6nkI3?$uD~TYgRg6h zwfpP%iroAf#Z?bej5Ea&2w%NLVR3hLttIZ;dJA)-Wn0EE7Az-_nO$DmZioOxuIWm|xss?LmcS zTBG#a4*~zQCQ#uD7^^4%o@k2rX{{7W$rX1_i|wWJW{>q+%9`KEXf_{_x-|ZxpPmat zBDTfe$&e}s9Ie%$QhSooP41SCMt}G2`IY#Q@qG4irpp!nLg4@)(`Kvix;RZ=IdKQqrd6#3X5@|D>Vwh)j zUQ%n_@q?V0pSsI`JAEwhMr1WI59ga^Sq-o#USQ@zLPOSl869ksDp};Q|5k{ZfgF!0 z0x7|GQ?@L_cae%c^N|vso{KqNyVc(u>^S1z_?(LZW88^!`Yv2_EM5vAerm*;aiXIA z-cJ_th>VN4n|zTEm=+8*A->04pVp%k=n33et&;}doAN6#G%kdV+jgzflfylD z08RvZ^R-EI)IJb_^=#*x>q^;I^SwI`%qsKej#wzh?u}aHGw*GvD0;p|Qz_@2jK;Eq zdxPZMb837{F8;Xe-A$O_R%;Vr;TQ2qZO11j94AYk z*&Y0NCF$3R^4kiy!S3mNlHqD>4$ReI9mYdOS&Xf$W8ZCm&m(oiuu^rSYd(DkCbTi{ zuDw5qY5$^rzl>U?|Ab>gCq#6MN|i$V4fZTg^E&7t>Ym7OIu-^gXFEMnoj5}B6s3d!p!@Bw_8qkl3d zy5^GvWS0qF?K5kB!${PvfNpWF`FBRnC&$cyu#)s}m~r19c5G5LDPVSA)FqsE*m24qU4(p%v6J~JqmP+Ni5xLyvdV#4!J|ME(~Qw|4G<;$B6rPTV0 zx~R6xsAd}+(0KRq&K4NpNXd|mMhLeS7;WXMDI_ZjFd-jo|412v~gX3Sq?_@waQ;wOC49De3qQb>8ZZ^_n< z2(_<2dJ2u-P~W^NmgjVy#Zrr^dX?5(fmeqj&0tI!^@zq!J|_wX6`irq7M$8=qZzL? z;4rx}f{0as?EW}q_)3k=yw{dDc5s})TfS45e3Ui~_t5NyeCdvU|BX<)&TAv8-+-{B z2JPWS8%;x58Egz*7cEWPdyETY@>nA3tJ50YqDI~cP9LL3)OMYg$#k!oUeyn37jXn9 z+~?L!{Mj zY!QajBml306p$6z2v`5Kne2o?^lCYQMz|bbOs!c*R2eZ=dsN;-X#eku|JyRUZhzYc zm8pIehFrwP{p(~y^DLn1<$|t6cPT=QSXGJ;qyFbrHG(jgh4+EE>NZCb^gwD->U^Rn zP_1Y6CnAz`j^e+8p5HxXlk$8Gf3^h$5DYGY{4h;^`YG0qA^7{m>yrc8qb8B2f-;of!Ugw7bALcJe7+ zk%g^TVNAul=yf3ku#k3Ji8^r=@QH{G5owTQbi7|4*ex|@`==)T#>4GkBsK36-K=C1kHqf*7|jUbc&kTiq^m6H?0=ao6h_BY@`y3B*R30 zV}}^mc{Nj*u`nKvloQOfLKWiT5R5Q)8*yUw?3?V1gYG-ou?kFrGgZx z?6`woF$5xsMnfk99|3mJ9YP`+InoMrNeI1xpW=GoJ31({4ECM-o$C<#-sE{(2;Hp@ z(n#l(7nblXKqpbb*Cg9-OQiq00msCq5s--KBLAPBdyOIX2r(5!L@u|(kfR{uAXRa3 zMOWo3ElRxqeNN#C9K({DjBZjoZCiZ%o+Cdpl(!S(Y|7F-q2DEjMAWTN=T~4)f{vxf z>tD`hd*C3=t5^~3IcApso~D#Mh<&ob3RbG0=T^;5!oMUv^K`F$d|PG}2f+PFBs!rH6ITQ!r~l@TwMs& zy(sncR_~uuIh;L6L}hPvOSwu~Mf1TxM?Fc4kaI9KbUIb(oIO-a8uYBL_A=lvgyB28 z7yz-d5%BaXWE$3Mr&SOV#m9`#jhR&At~z5-fjW}axw`izHcR^S1+ps!m6n zT8eYXyaP_k0LSZCE)Huyu?I%^384xhHx4dYfUjxkiLsfG2t3f=KCRFi3~A^vZkKt( z=So7KnhG)($$^p?>+3UEFpf=sV(1NrDk>NtHI(m?J(4L_g#zkUAJF#c5 zd}}LH)JD17>G{Q&i)?I3V4W1Oj_y#~?*3(V(w1Gji-0k1S#p}Y5nKO7vMs_j`6vaP zL`kE?dT8ACyXiuEzs=aqH%b-hlXyJ-)xC3Q^D+4vk$k>eo5U9*2bHN01-7zO|Fj{) zu+6sq?7{ai`lC(V+Us=lMJ#W2tf@Mg_4RPV`pIk|?weFQ}zHygR&lP@LtWaQ6E#X(U< z#5wY%-pL)@?$=2=#Tq((Q})`SDuEj=Kv*vN8iaBk^;nX9JFU6bnTRE(SGH)i53@6py}$Gl=7}{^E`ja;dI7l8AcJIXQtxR*phIy0 zP0HfdC7D16?mC=9cUm|5evB`~SSCrI4<}w~3bD!2awIsz_wki(;S}d_?;rmJxIHD# z->i0vwzx=V<>lmu49_e{noMA6OrC97loh-G5rxO|T|MSC#_?ULPu7^h1aW|oNZyux z5fIkc`yKQ717cAG+|hi1yXl+x5XO_7G0Plxx*82qIY-<#41Q^dr0p|Yt)mL&PNy0~ zXMQeKy&iD9vb+?Y`}I_505e2;JrijLx3peWUU)HSt7lf~+HE`7U6qd6B5INyR$#_3ts)a!{E zzOJ7Z`H>yPs!E0f#anc8*KSXuRKpDC0J7w_F9?A$&*E~{kXQ*E8K+vbr$KX$*ASQF z@A?ih`||O-(<(>jdAAfyiHz$S_b~ zB;vQ1z_$-!CZNn9R5xy>&&AvMUEg;@&RwuXa225nJ`bubZ-G-QJhbSQW2rvG^d#+Y zrGGEI8e!^ezGtX7@YJMm)QH?2{o=JXnAP`byPuq zB~1_R#PE&haUO~p3Y6HBj*}TvI6J;0ZR6XSeM5$X>79jo!AMyt6GH{ovy>+{PtzB(^5HZyo28l_dk_5V0}Ww zCQ@5nc!HY2(8mVj1%FM6-E+vlen+BI^ToSazjWrdd*%pEI?mu)Zz~3EFWE35%cRAH zCCZHx9_zfOtkG`!_KHnNS&HNY4Ba|LX+W9W7+bsw1R^+D|7S*Z?Vv(ph?8r=6&Nm| zDiSa;yY$&hJ5=}>ER&F@4f2J6z8FeLqNqpG_pd-{6J9rovO018<5;}%`eNxKOiJC? zA^Or@II4=16fp4#%?fC4e(r*-6QAb0|B+SIA)FGDb_o0a#Xq%=wbBq99JbNI0&vZn zI@e=gNRHmIPrY@`y%Je=K4Gd!5zJaxGgP~$(N z<=YmT)+rT)j)(G`;)ksXRCC)u1PfozOKf}{0$MDCI~}o&Nnh{WdwXJO@CxgpIMnE~ z1kDy$c|M_J9j)uPt@kPHP_RBJvGNKlIl$3F22y| zzIR&!e1}JH#Yt7bM!gDpE`t(@&px_6G338#TTlymfHf-~sOgUsBlCoB`rXG6la^7@ zSgBS~VcLY<$K;VB3xQFmUay_O7sW$JfqIe&IkntQIj4{bHG9DA5LUYv!;D0TP(!?7F*m8Y&U)VT9BqDmS25g^U_P zVUL{RTf#KiCa=5S&wuyR9_18%%XiMmW$6WWbAr~xZcu{aF4o;*nXYpYMu9#Ep#R3K zdmI0k%%YvHNM@ZMhIAJ_%WgoRu}c z#Sg@1h<%sMwAtu`k7Y8w4Iv&_Y768~2?lk8ZqXmR0)2~1m{<$GlYGAG(}}3Tk%O5| zoAtHt3NP9DFV?l+mK2LKQ|L!c*W=MqM~+3~*aIynDJD!(^dSS?q_BZuh6+39%cl9g z(3zcl0cx0(PH1BZ!t8V@XVMDof)qkOG?+;8H4fgEHx&D6%e8`$WyC@M7#loL^>r?| zIBMiVq3NH&@DEO3@6ZXSo(LW3;tL5;&<4&g^)Q$h=T{cInZ|*?0KR9~-V5=ex>wQ1 zSdS{xXU%c<2I6z3ZjpG2&48ezRmnaOE-M(&)YLPs%i;k` z(a689AnvSrH8swIjwGNM3+r^wzBdIZ5z4CKf(cu>M?hS^PI$=GV>gzNPQ1?60hY#t zuLSpiD-8PX(SK?iG7(U>d^%F!3v`IFx_QWdXvgoAxb_HYkHRcx9~}KRMh)oM-wT*~ zv1@t!^c6ny&A} zaN!*6+!*!#qc38po#dB0)bafZtTyM;ypOm3b{)_Nn8(4#2hkKJb{;*qi+D(I#134t z*S}riK@QNu(~>XnP}`KDm~Ac)aZjv5gg5jfXear4lNj%-q0Cq`)rDSP_?F9rLBFqv zR;+z!fo7*AJ7DKGW|aBQK+}93Bf^(!mYgTakROz@k91o6xfE@J5ZYDN9(fjy5!Xh` zxc{eC;{SiG7#+N)zGhAij7~v>QN_&vp`ZW3s~o}`qRO^lTzObbOP3+R^ABVjS%t79 z=$nc%^cko%cTagi-ep?K%}Q7)i~sV5x^1>w6#rN#Mwe?TI?KO1Nbi1mLU>-osV&qK zOoKR43?Vy4J(B^_lxbE!dOSbS)jaV=9wMw<*dY|^Z}p(k=<$LufI@Mw*CngQn}o2k zYV;*86_d$aVX;W`k=rINavRhBJB(IsPc6Ej9;s{&=qwaS+UG9hz76*d)HG_xQ@%Q@ z3k~dZ+84q)FrOoyOnGoo{(P6TN34=l$zdnH-Q9HOCKidar(P-a9aviAX-tOc?^NsL zGHuQ{n^E<)B%WrSvi^SfST?aEvOz(sLIQ=)oFsN8wkf)*#LE#TS4C<;%TLjL&DEk~ zWmS1*^A=Z;K(@MU@H7xt8o;{HvK7wKRS&35JJUrMI+T`CA1HtU(VI9SL(L5yHK;HF zDvZ0Kurs~WVVLL;y;hr3j!8ImS>^r%wSKr;)AcUJnncz(Y5RR%H+dE4BlHK9CqIvOrBx( z8kt>{zGp3^FgpR28q~CY1o!t(NYYE7RIdXxEu(2pBqSBIfkXN!%0B<|{`K*@UCs;O zejg#E5C_qoC+rSdN1XQZf`ou7)FJDkKbD3_+&Te;j6?Z!JP=sM*<>XS0o)nf2pIM< zPdtj*DFZx`3bCTN8zL2-;^&<452`~A*s(P2tQrzg8A=Tfbl975-Tvt{*O*Q?jx#Ps z-iu+-=Ic+eZ->PC@6vN$j#+)i)`ls8GTMc~xmg@yKFN6~`W|xSISSDumciYEEggCJ zAzmSeJ2wuXF`A$p!=^$F>-$>S1jO~Ot)td`=RsellDM2oL`8jxjV9&Q{65~`a7-am z7oh(6QwrJsq$Gi_tb;W2NzjU&RTkIB^OCIfP4IA=+_R~|!?_vLT%QiIcQ1I&VkKi5WadgH_!_Bz&5{I4OvgjEVg?xfHgR z)5oavm{3Veqa=Oc9%O+s`jnDJf+WJTqKhF(6PZ64a^BD_-<@x;GZaj|wJt_Ra$(?h z8)I)Jtqn;3oWD+aPOs#DA=t*t7J3K+Z;Jxlnvhz4gg+W!#gSDsu98H9cTV^`mS~IHQDX#W?|nE zf=lnV(bK7VMJShNFk=aw28*4uMWsLAwEFILA!kq@-7o__dQrQ+ZQYSUQkwyayqaU-Vl)Tl6kXK+T>HcBMf#{GoR%J!15R zAUUeK$abN=ia(F4-Xf$uflo$dB2z2W5pO+!2rWjDCN2GU9f?P|SnZ@>kc@h59M5!^ z^3PJdA-J5sS9Hq!vM3;VXn6oH^Jg0(bplCj1|6$VfSoD4@5Ns$7uSS1Jv5dogIO4HH#g3c zbe12BAu$?9ptg{o3Pm3H!xBe=SLCI&_$8c$Jh&s)5|R1w1&%^{ej4~n82gY6Zx#IO ze_qiU0u=6*Q7QP8$MB0hDnV~4f#PjNKT}=OQL?l&_J4PJDD$&5%9K>0hJ&{vq{e5& zbkLgLSF6iJ0xkwp%`f_@aexz8#8(#+AFW@uyL3#;mXhWGI1)Kr8g!D~9#UE|TrTtA&hluBWb}UcF;NblArI9|=#@tH(RN|)4_3u2agTqC@g=Ryf+WlVqv8Z##Dt7w)clvXz zxgHBVAqptrO^CV(z}~K8V}u9eMj%(Eopn9RP#^(A3_wq6&dvsvA`ffE4Kwu^W@=&! zL0h@H$Y&6FlPvlmjKq)6eVH)x5?p#qN2?YbViKhfWMS?KKbzek1z;1c=ixx{EM|PH z6%iP*h~~+!@#5f*O9Ow1@Z&a!K^uz$xE)aQg*GbkWgKycq?~lp7Y`-;>uueh9fpy$ z#XxwEOHZt*c)QFP60g;F51Nr+!+EA@Ubn4wT`x}8kAFO;MQTOK)Ua=UAon4uHs&F} z#v3-b?`6Pfi6(ogcg+ZcTe5!l2P%2(BO z0HuoAf#hlU)$@LT&S+7KB^XHl1m`B4*rhc%1Oe>IU2~?L{$sh4qv3B4_~WXGCBVGU z?8B^h@fL?H^>|F!tRRuJvN}0QDlDjUea|E=91hCCXk|y5@R1A(z12(}>mSx~RyUHa@TR$9_#(DD#0P`*rf3XvOJL<@=*94TMwUrbmj84?}2QICb z%Za3iICCus>n(QV+kLlNF6w(1WJZDyKmQ1Sy-)Ke`#zzi+|iWF9L5g>LF@#{r>n+Y zFJYKlu~47e9nJ8WpgE3qL^8{lvX(Y6<&XwF7ogI-Sd2)gW@}~5?3OEa8<1*ayZq<1 z0B8WC#@aHh$c!IPNaN*%tvt8LIIDOu*;fiRn=WnzPF>#Bc3p1h24pw1E<7G~eGJN zGT=fp$RR%e*q2^iHMKSy=8(g423iT4NYycdo<)h~%M>v@UR*mz?5*mI4bvv(LDr1s zM6LVqy>@^a)K(LVo22hOL;C~UmKEirT+%6Jix?c#)ZwzEa{9NIm2ALH=Jx=AVOn)x zX>+1iJxl~{XGkGEdwrXpG&hz?CN~{q9o-@0coEycQsXuVk4Ca|8eQh7Xf-EU(V8EO zS*c=Ok^BrlYw`Vf5;tV=w1wY?A(0T#i*&70kB^?_pMv9I8avghyCJ2E!b5RWG#8G7 z&P}*B=ON*tInx{|PEYt7xcU_!K?>iLlTK%`%JAKl80o#%xP_8rJ@5BU5j-aL zE=KSBp`pq#>&cjG&EFI*-gobXY(KdM&yA5#jU@8Sf7$Jlfp^86V1JzFRBB2*k%MGV z3^OR|89ltF-VzZ!SC)2$Nw1@US?ZLT+O~nQWXIO#^Zg>rRU-#_Ma(aBPZDzYvAuP|HD7WrkZZeaCOReP3$|uG5 z{G!1vgW%gPdw${%KRcRj(IOz%idqkOb(;j`E1h#%9pw|VT3^OE-`k%YvS{g#W zv*RQ(0WYZ^=SQ}`b3)pr#p)M2!Y=PT9dX~~PWK7tOV|;0*I>Pfz2fD`C&e)MecK<{Z`rG(7kwK* zfkH0%Cv6Q590~&)7kc$3*8x05T`CD1+qOQII3E^jY>17xh+R*|CFV zv%Cgb-m@b9gdfOImYeBRv{zj&82(84jh-f1EX_7^#M7PP+vX%uFrSy3e?@d`YIcua z2Pbj90IuvHfXt6oq^VP9Yb~4?2h4N-3jwOLh9eyG~-a3!tcCUQ`x{`H7~#|aNT%CzbIuI9W~8c~!`aP#vjtP$rC zBYr_eqxxu;rH&K?8jK>QafbJeImz%{;%%;c3W7m$%y!l~Cv+TEH?Lba`<`^Gh~7t7 zb{3@kV21H%NG<;bE$K%?J0$cnjk38;d#5*KoD9S9yvb;5aAtOx+pu1$C(`9&+7a`odJg|cHO zUKn=Hb(ZnG2Pb*nA_N6~dbA)QOmMz4Ifo`)L)4axXqy!}VQaZs_IXt>i@ThKzWArH zIER?AiqG}}F_N;s?TS!K+(J>s2eG+uk=cZeGcw04Zp81bOPLIf6mogbg1+Aj08 z>LOdJp3>55rr#5aXH@oN)2Gy(f_%o=7_dKMZ7IQ`b100l<1UTER^!h*F!M2N>2Uf) zQ}D8?jj33n6|I>zb&Cw`%)>YmWUj!3d7+-D%y|EA!fRarum}3@8LNLQc%} zE0Uu$oUjv#Au!J<%P^eIjNOUC9kqq*EA22q{geV052pm1gZWNTA>yrdIpUn|oxt9{ zmU0#Bx82f;8D<^17OIFsszPK-7lk`3J&85=*Hf;AEP+lCSn>_q%Hb$n)VbY6Sqn=K z=%fQkod8))pPt>fHcJS}>&jtwUx|~+jLuhYd(Z>`ssP}wNc>MtBwTU7N)5P1s(~L%Odbo^e-9-4Cl8trc%dNCpv{#EJRQm}yF8 z#hPV-d~jOJIHV`4UL0nW0IDMydWb69B(Z z#}h3zxRNq#(XUaa8I90O2(KgLOTJtyvT^`+cRSQP#UM9+$H_gK?}*41^za7o#B0q> zpH(_oieYB}(qMxd83|7Ia%jBVkFjK);u+T^OD|RQp7y1&};nph|Yx& z_Fw$UPk-YyuS*eRmO;gAt*RVkP^<_M$`a2S^AAIEfG-`${hfdW`~WF=z%br3q4=X=-qv+SVG(>|m2yxnpDjKZ ziIEu4)h-A6_@RPP1340w+t8Du5Pe2^`rcItPlqDzt?S@cKw~J0%!H%Y zi5ZIHSx)#S>|&b>6yVqM1fYg{UVl3P??N_cm2-!o zfM^5vWH^5qlcPj+v)PSH%$cfWK6}z@?7(7nWP{pf-#M^cn%L00p1AHDD$1vbUQ{JU z!h(z*xBLUFrd{NlMq=!sW>{At6uIEVNBYtDql)-piJ82UYPG=v{99N_I%7GtCRT(> z%qWR4iW_E9TvBz8{8+zJzr#}2OR%Y19pas$u}MYI^zS0f&1EdFIY(Y1G2j+DB!Bld z^y3?g%Zt|f62^=s0HOZnFzchJxjCt3{Hg*g(?Bmw+ko<}71m%*i!Ky~L$qJv5Knn2 zQLKQyJI-S7k9$PMi!8k|3fX{qZZq3yY6cO&IG@+1NmQ1auJ6v;QtPhp-m>)wu*JGt z^H1K{BOha&^$3{H41~K>OG#ySy7@$z;U{5}`Q-@N{TDX|1i3Gg`c#h5%bm%k&Z3#( zu$*7?`n3)mqPY*(J5-fKI&_{7K5Ekja75Oh0k$t*bo6@{cnKJ$?jt#D|CjlX4-uc? z0^pVE$m2@;-7xF?c@%a+g!wk>GT5o<8DAYdgq zg=;feusduAo?Dm!XKd;pbg5Oh;H!xbMm9Ole~IwW`?D`@-%}QO$#*1wEyLD(l(sbI?1A_ppE5 z1JiF#6H7C0Dt?_a*=-Fd1?J^RzFd%7wDOmNq6j&Us~#)c3zwylMMM9bUKfRO@EL%b zlHfo>ma3ZyT4RB*sE-^QZQH_E{f(qDqdf=nFjcxgZ9}=mBbQJH z!BE4SDCLSMmSS!i?o$!24*piR@1D(xlz-GDVjO@IYXbK=9QUJgRdT@^C-xuxh`>0E zAtKh4e7i`rV}ah5Akqi?6kqfA9Q59XbOtS7UzA3-A^qyt^KqOP`>}Fm?AEjwF0A5M zbegfgjNsM}05Q>}cGIi<#RnVY$iS`w#kg`g6QKr2<8QHfD|)uLqrlDojvgkpY=-0j zzM#J^JDN_uvKEXGdWdJ48WGzb|Ar6aeKs}pUp^d9b<-DbD2WmTbq;B>z*Epuu*gRm zYDl6>p$}~eQki~W#yZ;GFO%73NCLGMR}rT?Q91*so!PWHdZ>a?t=kjMf3h=V#}mk)N7kwR;71le0w#IKr3|F%|lxx9hHU)FB%?9gC3#0Z8R&WbzF zO{-SBop1Y^PIUcDmc`WEc{C#fVj^z)x_?hwud1CraHsDRcX{uYNUyv9_V`_c%PRjv z40B!*%1K7!Uoz7(TsjdL%*GFgJ}8PYP8gRQ{+LP19N^&Cngd(LrWMw4!!@2nIo9e; z_C~pQ5Zm)XIq&OmcYjHOsJ-pv*%M!=KZgdn(ZhVi`~Y1UNb~KZb(gxS5|bt#D%mx; z$Abn0)?m0Ovz^%oaiUKVBvoRnG1s2=WSg(p#(adwFvhI%*jVZI{ZQ1F0`|QN^C$BR zm$BC#mp+vQ^wO)>wcp`yb2QP>-(+cj=u>^LeHWwx-%__4P8X&xddNBB@?<--rvGII zN_cqkw{FH`_;H(E*oRbcRDm?}2Tkf;D>vV6v7uU(8)koRe_WjL*XtkmR<{yRl#>$& z?T*&(Kh(VuU!qwU{SQ}f*%nvRb?xFV!Ge2$1b1yL5ZqlG4ekVK+zG)UxVyW%TX1)G zXx#nn>)yxnW&eV%)vH!j%{j(6t5t+#9sT1SRhX3l?;nf%XG$7M;cK&N?c?!I;Sb9( zk&weGW36-gbgVgqln{}en(-A>+?uf_Rx%&p2{dVJCjLZnN+m$jDwzKFkhr^e$2QWq zIF;#QP2yxvqjut7ZHxglO(DVQ6yC~euVQO|iOUVKq!WSe zr74G$6n$x$1+r2-xdPyMEb@CoqiiO;@K#0@iK2Q}7E2H6$>3LRG8Ir8OG;Zp7(GG6 zbAx+TD+Wz|)=gUZ9$B%n>gblQ+ zq2Z9utvZ*KZGSEJ@M?xY;1f4ZQH)EwbV|P4Wi-RXHw(1K=z< zy#~Fye@oeM74X$x88bbu zLwwOV@H^f=OYtIXKNW3+;Ld?mgoZde%D)tR&?^$Plo5CCD#2A9;)p0RP89m)*^v`^ zZ(=yS=V)OL-W|JBgpOD&I^gw21fMM+XyS>v5f5#XxN(jqBYH4mK%t;?BSuzPW%>Kl zQcJxlq8aGu+w z5~*x|-|1bWMm|vt-h@OGGn=o{)L<`eTmdJCV!gDNRzEKJ{MS zSU8`rU@c;eGi&nKf*TJ#z-*dKDZ?O$I4i!;k-Gg@gCsQX3IHNWPd0DP`8o1t0~)6s zSoR;friI5TwO)ZLhRG%gg#8<`U4xfS>TF1Db~v?*&ICoySy-5X^J!v8c}T@rkUwjB zvg}AQ#`GIAV;VyC?cW`rFQktsdz8aZ^1OMLe_?Z)JsP=U4vo1yD%D7eCiAJ%FN(2;sJw4N%}WXv5ZOcZpZs(wl*tzT$$ENz^FL zM3?wPov4_-S3c>i=RXLh?F7GDF7OMSn0qpj#%PYmE%eE*o>9n&^1lMJ%3AJx>^5=X zro9NnBv5qm#$w?{g#v`}_gP5VkFO6OBreSo0|Lpikum08Gh()u^N~7t^sO(NEJc81 zPCaoWDjPfCB@_WB%R>CDnhlg|ixZI+KEd@FD*Qc41%iXI(hS6hm$<5DgVFq&%AmVD zOG&%)>U)1&wCUG8Agq4kWfPff*ozhkg^l@!0-*iG6wxS!Z8+PHq+~+&u@bOUhJ!dl zB!GI{z-Yvei|aREz-t2T_1hY_nV9+eem4e8M;FUL_YwAH#x%!I_+6^C1j{vVg95&u zES)Z?5+N%71KmAR2bA`y-kL5#ncju<)tTCPy@zKd<_wXmXq4 zAg-4GP&Yx3E~^pE_l7IyrXq$L$qy|YAC!gkNB<~vXX1Uzq(gI)954;kC*f&0&U*{) zO8PO6#K3Cj7p$m($1DW5lovOFskM*}1W-%6=I)0aMR+irZvI|Q3gUIXWex6#L<(dw z353A16nGlh(nWKDf|p+wXyxk%a2yK-H|ocv=;!+$Hs@1Qg5ux<)zl008{7>-i8$Jb zMjb+jC851^HZaP8)4f%X8S8(%g$U|*zf)zgmizd;=fR>9?{wXJ_mNm&$26@XNi(+1 z#_~)3E$p$AbfoVMF|&mSaXP*fpwB1Vbm+w(A`jt$jm&TIa(uFT%_tq|e77I0tfoS6 zVQj0Pz9Hq6+Pal?0*b#`enruyaX8dGTdh5u;8Y{5*MQ+88v==dT*&IR{Jvn=zJ6d! zJ!E}TIJS>J56AZud;9l9Hum8xZ7D7-1GxWFyCWMzCspzGn%Uj?%TgxKA3%7zXd;H;ZQY_9 z)2QWZ!>xgFcA9UqclC$uD%|wfg>u3cL<2MfHX#tJ{pMvs1lIsO#h&JxC1j)LZ)|sI zd^|Yt28vKlbiXatt(5N%2ez+N(&KJ)}wcJE-s5jM1dn5`&uQMf#$hnoPZVxQ1#8dAw)pPKhfgfdW zTBTZn0pjfuk4Cj-sJQu_Fn3UCTSG23BBUl!o^k9}-TJh}i_Un*;ePW_fkK99zIVQ+ z)EnFA-jlac&nrS%MXSdXVp4aRG(G}zYq||cp6DLxjn&BX!00yFjk7zG={jH4bl`T- zbST+?cVLhyQs^uHi8{*m5;k%%I+JGqD`7|eh#ef??%U_@PwSX<XoElg^pfV)QW(!}7ytr>&ZTG=g;%Uu+;Ps05v5;n~zvHq={eW2kD zlvR;JI@vUf4iOpjz_IRh-fvNIIHEE%9-VL?bV1bK%!Tj8oMVMs=*uRCqYXefMyjbi zw_ML^^K)f3?wa;(EI=7n^`JWgvt8-;ynG}dyt^K291r6`%`J*NiMd2D`GmM>Vss?$^8x-inTVJ#r&Sox2@2R2RG6J-WFPbi zL1iQ}$n=D;pzKL^aRQ&LY?|dY`iI8lNTez&1K z{B^GzkrC=(t5Q?^xS7Pq?bY4~r$;mO&?ovOkJW7`!+36nWo$^FInzkH_S4~j_u*vq zXh%!Fm>ZGm)P{EZq;L#qpb$?_#)C36+FeZ@mN8Pk-QBM@OR0-(! z{SuX0Vywp~jlOT}IygF|4~pJ?Eu;I}qul|^BGxp#-Bkur(^Y#r1}(x_q5PFw)R&+d zdA=M6%PS`mS3hvtJY}k-joDc{ZNW^O_l%zD_117qe{_k8AwiKg%)l1!b(*-06<%M3 zOtw}1liNZ{LY~Yy-jBx)O7Do&>F&Dp10y(XW;`WDPc1;z= zWPX1FnhBCPpu3IvuHS30LOM>y7Q9(HF+yyhEylE^)^L|4U^$f~!=5vXFdT>V#uo^O zVI9VVxO062PQ31wS@#Z5uA%l2VTV`Km4oUcsxirBk3Zs?+JBU{gl7M%pes;6DbM!@ z*lXs;uE5*<>qIz#r<}~2OYwV`Cq-K;akyG8lFy?wp4Ep6rJ)GN>bpB?vfP_L z)y>?5Gb&MHS;)&$V+@gtsOsPzro|aDy+^Tc|pMr17Sh+a&IN!PdeaOCU|EfgG13U9~x@R zrBd>I&|Tq?D37app264|oKZ;3#S&FPUABd}N=NG?lYaIA3n@zn=jACO`l>KUb~AXP z@|!5xzROr>mVw4>p=+Lin9E4&mSFI@JZ#y5M%`+MvRkX}W+L2m`u@j&YCZNw0eVR8 zj7a87kzSaaZ81(vXx$mIdz5hAo{b}OOFmYpi+4Mh^^{0v9G+!RBj-M$-Jtx=83T;q z=zvy{z~7MZV%6<9L3NYe(6S$9TPq~bh3k1vUV4a%FW?4dI;f4b1gP>VO*!^r9Mxe} zs`NQbU%DHV#C^M|n%6GqB@d|ZpsmmlJqvU68&SMg^GmV3?4<4MZv*JJOml24PaHU- zY80Xg%((`_P$pJpT0LuDgcSuM+^OHFyeov;twu(lFws&kEIrNdEVEjjeTu4CR>L+` zv+2&YAg(I34>7m%Xgjs_as(zFawIukvso#Jk2`ywi1UrVuSlCe)1x>d2H(Im@ljbd z=GYks<(%{s95wv8mK?h{mrs)r=aZ(2(k`|c&Rj#@d^Uqc zq12O!V{qcfNFGazjE&>WKj*ND^(>1Q*9DH@<4BEbACSU@tN&#xr15VDw!N?F4kbrR zxv^(bYu6w^%7XVN`zVMbi%sqJ_aVKz)+&nM8v_#8O*Rjm&hYuzIms1{AE|Ler$M?g zgs&2P7tDy^nr_e?b%V}ln?7GtC=wpxx92wlW|D^-w`FRn-R}LV3%`i|ZPIhJSoDsM zrG=Fk#_$l6F%Cz@H}l4;{K*DMCMgK~2JQ@< zSZQwotTc_M#f`-~HEi%FR;$la_^YpF@|y48)nIw(V(9c|i!(w45$ zx|Q<=qtnir4@=s-XX8YG!xLg`B%`Y!a)D9I6Pr%R+1%HI6LP{RiV}dL7IMhm$Rh}| z%1j$CsggiMpB8Wu$fy$SxA|@XwSn|Hr6uF5K8=jV%4Fo{5>nucHp0RGWXu`(P68!(hwj&L;52GO za5pGwb#~tcQCTb1_ydmyUcM7%RKjIDx^K7V3(CBNgFu@uQhEyLVP}6Bs?Fg&UZ1$1 zNBulNKkD?vAJ7u9T-3tQm$qakvJvk3=dM-5Os1O z1shB51f)g9SLWcO6ZzUnS^n|w+;UeVBHmLT*&pF}F1wQO;ahw3G`^q=WwH#+zWZG= zsIdzY0rS8AP1*Ia@IBa}hICJxQoc#4+wOefidnoRWbyhLFS)q%1Fe%@syfh%QvCX8 z+j8gMKj`0xI7bbFJXpwP#h#vi<6NpUWc_>dM{o9(&1VRy6uOSkQ>#I%B;SDLl&a-| ztt#6))?)h>usa3c7&(Jvo2PBehSz3ycMLR_(x%#9R?^)snNbnfyc2NHf#Lr1*#$HY zSPi$`3Q`?$0*!pL+oy!z=B>uyX8@_4N5U}&pj5f_Ao4N0t_8u#+|q00pJE1zN!hh$>3EaQC;Z3T0mc$cFCJH`v% z66#3I&Y4Ceou#GT?T;FyxUmVwX5p}qQDr?U{EJQ08-L0P{#qV8inJSYGC9@0Z_Kfi z;ERe~_cSKe4zEs^MYDkv3}1=F&8$+HOsRpOm*POkW|hxaO0JalEa zykA^a0+q0UO@s_UWB^U%oN^+KkW&B8?YCSlYTP*DrDq0gJi>J2;8bMTp5G16NKFG>u&xm*7ZA0bHE z4FuyLV%$`-Fq+b2@6VUXzXaOV`+0>rMGnmI+7bR1?4M@tc)`pSFGOajpjL zh5!^crVHx#Qm-JcF33ci&-^BJOEy?{NztugPB%x^7yKyE(+8^_e=-PYi(aX3{!8&^ zvXUl_x31Q3I|e~arFe9I@T{UB006n1?A8K>vxvK>`Y=tOzZc5H1vIcofr*{Vw4_mT zT^y@EnyCGIVc`p?LRVjQk>KS`_H|aXRe-nmKK|fSVuQ1eHqAWq7dJ2D7bxi_ZPy}; z7g`UrKO&P0jS8ijN{Lnuq-X2lKaN^@+>xtHa74xIIZ&&IIOt+sPYvh4UbF-CV?Q+u z6=C0$RS*!<@vQkv)*<_ROcl^}9BaB?*Z|zl*UB5;ZS8XrmY_<9Cqx2z%=Z#a6>owh z-&M^#brUzC6*bju8UR%FvGflM>VE)}&UPNaV=1Pia! zlMZvA+FBj%{XQAQd`9wHu4#QEOol0kno>m24IuWXjFwU8-ZeoEwH+yW_tFa8m=*0=l2%Seyaq9wsaY*p5I)@S=pgWS zoq&M5vB*EpeOj&YZISD^5D92d&Z?6^uSlbou}U>ve^DQfMUl*axr6SxdYl#S_I`V6 zzV?;}wO(Zo?bet+y(HcH4g*!df~lSv?RytR!h9C*?MXyM!M5?%2-VtX&?~%87m)8; zPgB^qH7EiQANXyoxjDI6!g4F*d4!F6;>-}EMpT!TA#H;DN z#%gDygt#BQX?D2}8!Mpql;1-xCNliZ`lWa*IpjUKf7OOnL&i9@VjlJkcL#wJe%!>}T8%H(WEBs*D4LwL?L37sxm#4zYm0ew zT^Yp=;R_ z^e*0;!(7gMA=wI|-;IWgZtgEP+BRq8p{U=mq%e2+ZBTkh4$_Kt0Y_D!z}yz^}b}y~Vp`xtKJeJ~<|o zM@O1$lEd04c)ehgmxNrrHY1Wws8$JtULou)L&de1kFD46SVy>x-g8 z^?CO$9@`j$@;1}++Ptz5aG7X9oS>?${6khDI^c|f$a~%Xc9l@G2RtP-k%Vd)k6QiU z@-7(WI@n@0OLC)w(0fqr{Aw*v>YH2@mDK!qaD(ONlt^jF31$Dw7x-@wDiYoGgw%@pRM&|+T%hJ6#0Mtj_tAqqRa z;RF!wPq6`0gLHpEJ!boaHKXM9VR>&-eW!2$M+m0G}fKG^8fP!l(mZsc4hHP(g+CUsg;@=Rb;5y zd%l~9oq%@ei*lcCr&2|L#qnO1?hJY=?7bplk(^pyu-Dg#MqQM@o%Off5B}_=8J|Jv z1orc(HBX5GkC=Bepj^JUi|Ag7Se-^~=Cqwu5uRWEr(nQ)0-J2z4l%y3D;BsoEC3uC z`4$u!Hk5=XIx$x>+ysKiR!KSqB9aI+je^<<3x70PlEfe`1ldm>D-tj-PWOD@ON9f! z6;_o*GT-Lx2Bb3JHBTo8ybH0h9kzXNt~6n@=SvHOjcOpN=zdT&eyMFLu&IL~qr3O` zF`T;1tW}x{R&HQ%Pj%&Sj>tgi+CWHzzE%1u+ankz)SwvQb+=_pBHNh8_r9{jce2-z zz|LXjh>)MMN6+|33dv}x{7q5=H$BKAR_=q|t(7&cAJ|175^WV@g>SjOygH=vZ>h}7 z=Ng+=Anyei9b!-e;_cinIKbb(I3(Tm9^&rRj44R1+g&H_D^)4q`03J|m91(lx(dXl zK1Mfr&$u!X?rmeOqUwsLqW?SHkuwgN(15!9djC9>S|Mg&au#M1FB|v5L*O=76xW^s zvd&p2IP9*UPrmt5MYt?O#7#7u_xk6R)$J2nTh^dN=QQC`pYFO@=B%)a>#6TQ9XMa3 zb>jLFEm>QAdI{ps&v6Imr_Rq?OpEs+490{*;aX8Bi(^MrKB-F|$t=frKQ^~VYw5aA zJsPt4e?d7zqIfhB)d}mqv>mlGdx(K|WZnh93L>H9(>0}^g z+RY)R8VvzEDa-SdH!MM-CrZ~KKfEVnU1SLjCLTa2U+s*KtLa?_XE^X})!E&~#&sH| zN;?ildV`tI%Z+kGc8G@myMm{=ON<&>AyWWPxmM}hnA}4^n#sp~qvA>>O&}m93ptZM z?p^YnJtT#2;mV8UN0*Vzqs%JI-n5e1{r0#PcBHr3lG0`;3}~T4dXoBOsU|2zI}W={ z#^E{SU?IKBUJYVvqw;FI(m+cOh+HCeyVKTFGvMGq51i3`@t#gk*_YDYqTT(h7gUmv zH$QH(9f7#MKpbzR8~Ru8UIp-N2`59d7!d6ty`t9K3$i;_*K+8^C`&b6T8(p;w~X}S zai$cBr&z(a?Qe(k44OXqF zV!69xdJA1MDuN~&*K$4~V(#T9ewyF0ao z+ntx^RzEA`4S#(JbA!R$)<%lB&-;G8v+dZ3CR9te@{gVydDt2qfcBpkpRD^Q6!C-R zI^IKR)#03p3$R(*ocVKgYT$Z?TJcYo+cvsB! z9!r+u0Ss}rvM8B5>bH^TrD1#yfLmJJ=#pbfuN&djSatNWw?eXDjMEgIcN~K7Zomb787y5w`idLdSX%XTEeH6a{^OD~lCLtmXg0gz@=s-nj%qZz-5PO1HBQ3@pwU;sYXA%mJuFQt;7y2lSz{y*)HtrX7Gy4+J|_vUhGOjXU0YU%3*G@Z|b zl2v&uobA5#n(FDeB;_y@)abzS-_DxY+8J<+P7WADIDeFaX?~VRY<_;jjXT(2qaj`J zorOQ@&oVXO~1@WUL+q5jy(Ylb0K#p<2Wm;?cWa=gLOfp z*t-lW*>n@ypO@lUk-CH`568&KIz6)$H*dcK$J>{(c6|}^l3q>PR0732jGI| zE}yq2DIKfGrtnWsGJ_tibnc0YUpsvr8k^oM&eEN;uS9_x5`cn$6H-slSaQ`H52HV| z*(XS#*xwyKQ;s2zV74V6K{~fHCgiQVeO_VkgaE+b8!NT1Y$+a!mxFD#>2zA6nOH`( zeet9j3X}$YO~h$!p%xPw)`!DQPQkJgg-CB|>Cke{$Wif2ynG0HY$#B0uSHOC zWYIw_`1IR6#5=){g3m3)p=EUd@IW?)ik&bs$#)A=Kb~=q_w`+|{j^D~ms|ykiCO}0 zxK_J(SxxJzB7XoK!6Xq(jub)hK|+RMH9UfgDE+0oG3$ zih5~$D!6Ad>2cF%NfcZ`lw>HrQjboc`6)8I*9!|A*65+)M>Atw)JwDX^#B*fa2jLt zqZiv1o$@txHhw3EKF%OO^#Xi_~B$!P700+>hB#)K~hbX(E{*ig4>j0jf?gJ?kB{ zpwV->>Zjg-^V&nBdoTv$r-itmogxbR(*w?XvO*>s;$IVP##k(Ta<}~bJNBG4%D#od zMxtLsV zdBo0cu(R`@w&dk^5(EBT5f-Uvlzcwj>P3}PE-El{vY*Y6Gq5)`7Ef>JwmY+v#C!~? zeJMiBtMQ|S2x$gjx<(P7F*{;I8KgVk`D~E#pL0@a2i*Zb_{N6F!fUEVI305JFwX$j z*E2htn9%l)-=Gm2SN0F;t@Sp*sMlnT83*t+5P4`Pf@*GhpR4#6<(-QGmC#7b=ffz5 zZ)I3-T@^g>>k~F2MvF@Wa?Rq2=4M+qPUlFy>>miE23+Eyj~%EnbUqOG5kn9H`Qp*i z*mcg^NpLXAhUd{tqnWV?N}FT$u`B+rhW<>4ZB^CFJzgei1#fhQr|1ohX`LfB_ms>x z_gpkbW>V^bL*5%M;n81D7j<{l9~TE%_J&~?HN!~WF9kVr{Il(>T&1 z_II(vN%5&HGOn!Da3kVuZ?$}}3Op*ocjBxeVyvyk0XeLOw)eK~d1-$FwHy|Q9@Q#Z zNkjjIWYPA&ZQ0?#mH$f(@!5!n0hn_;+;Y%s=Y2qQ#LQDq<5bUig(^Jlu=JEZqRSXl z_VwvTgb%y!uG6S-sbMsOOhN3b+(xk)j5QsC=@=AzMBTfV#=Y8F>3a~X8VDl&qL)9~*2o{9VD3ZjW?U-?l%%I_1!&T`cxRiMCcqKY%Nq&g%l z=K?wr77yt`wt7^Kr}v3RGM;V%LMI zsVVoEFCl-Uj(peDJ7UJh8rKMgOVJ(8+cDd??l}OGKi!?mJ=24Ok&b_xHwXZ^1$J|C zSuC-b2cNLwNQ?XyYkW)s0Um}uPXT6!)emScLs}5;nQcZnzM0fE8Fcho$-bq-oAG56 z$)OYzR1vvFE(USZZYT;&`e)Wn6E1653Ppa51jD3lL?VtxqGvji4;xGddD8Xj1AJi7 zi`#PbXY7o;oKVSv3ohx*pxB(WNX;9Pn+$b9t2z^$O4HL0Fw(se&rSbVu@0V$2}lF~ zDPtRPcRMGf6qz@Mxu7FksFeawiP0x~vQwP>C9k1jEp~QyzeFKm!CV;1@V-{fm~KXP z<*4oe|SAuH!shOYH zv1W<%bEek!6i&E%@$Asg4HT@;kM)l#v1i*CdoC4s9GkGAe`=13P@nTM(+gs>Yy$N+ zH+EHbV^J46gF2G#_)hd#-s%-<4`IN|4tUoc6C@N2o7T58V5N}VJjd)i=;98n@>UX@ z^8m+K$DoSfe9R>Locphc{7?FSZ|=}Sn}+H+nNMn)ou)ohK*W0JJ)mQwS5~jwp|79MkJAB zImuDOd^33rysJa~lBcaq1}WpF4oXM6OZvC$kmEka##J+z4e`yG%J|!#JqUkE5k#{B!w)d}fi}%b>a2boU&3u% zd)}mx(VM2MhWABO{Q$9zQyGJ0lx4Xh(L$kT`!nF&4Qr&NS|z*YzafLUNnBt*O_L7< zZnY%JgW|Zq?ud$-hZU@ci)`lGda5~7_$QiMB?6oAoyF)zy7y~@q1;21$Y@vjH6b?J&`(bvuO$uzxA{%Vryzm;0 znM@x0Ruklx#>rq7)Q9~Fub=jane&eJ*%Z)L*f0U0$&mzr@ma|> zzjVF{*zNI~Jh!e5~{Obr;iGnhv-jjt240nJJp~ zu(hB=TIeKj!xD{?lLurS2r>^R@nc#nG~szDGk?zcwf>dBsxLDwoEqu?=g#KCB2|)z zgok*`sgrICn{DzLCPFT-$*Y#}leRsT4c22l=9vML%>CN8sMNXi(@SEQBc~)kUp2+z zq3|6{DD`NDeQmKb>Y3TqPfpV$B=Bl+r^)d|v~BsHh_WwuC)$TsAMJD6B6l6Qqk4pL zbJV~SwD`Bvfn+R|ra0~DM#9J5jtJL=xgtMtPXK!@dZdSQsyUZ#TNo~fx?-SI3 z53Je7^^-VJ@8BCnh6%oGe*lAlhwV5S)Zsj=3irHzTOx4^45BE%`5RUS`6Z#C*1^rY ztrG*0vK~o0<)H`1Bp@s>u{6j9;ul5pc=#UCtQMKL_^k)5h3U^R25{T{Mjd~mEKmE6oI=EE)a6}Te zKJcaSxKaE`jji}?nG!iA<+--b$2*7ApWFWw_Sh9FLTW{fD}dm+cNbQd>A)>rv}?OJ z6oklUdvN=NUJ{ZpHJ5BlJtK^IAm2cltVzrZ{a%isSa7R4X;z$B8JaZa0@c4xdH+{t zrg*jwIq_0h1oQ5$Mt28GOB)o6^SxlT)0=c<-u2IX4M2W*3CGQrE_w8Ft7mfwaSlMc z2_Eu24Wp}c`lsuPNi>Wjx`EizwB7BH3af^4pI#ykZIzfo^0OGlXw` z_3t&qX(0%+{KU zgvP~q2;zpbu$O?>zEf)s^3oHc5lv0jW3#P?xWsSi>w{Z*VD|G(gOXU1k# zvXDq-V8nc|TJ&{-4?LHr(N#M1J+#XD6n4X2cLgUIW$9~`1#l(-Wq2V~h8HsNZ3Qey zl%gT=HPz^(%v*@@ilK>W!PhmmBr1S`gCp(ZjqXPiLU*?prXir&jzd zW2fIg<4Gtk4?nCbm}U7ezZ?opyY(d9Al9hm;p+R8mnYZhu0>aYitEcXV$2JE*8y@epm(qmWZ|MeN z|LKpwD7_%CxHRQ(p_s)k!Dq04ik^dVn=c*_y2*WFSDbo{&*_hJs>v$$b zh`eJ??^`Z-Vu{%3=z;{AyC)T)a`G56rm3%LkR*qbEQ|VSec}8x+hj%A&4m&t2uUkH zyTHg(@SyEq*wte3I1w)pEwu8wBd+91Fm={Lyd!}SHBCHk*Gu1DFmbnvIhkw9b`ZH;O&AV$VG^J18D@dtB2>3ae`3YMa554l ziFz#(LY~Pg8?Vc}FrV!95d4isSc_v;CLdV#PBAXqaOsH zM(%VR;qm4dBa*rM)c*fg_L%6Qb$Z-@AgbYnl5a=-jk@WQ(7_1n2;~ZXp z!C8=q*0Do@9nE?Z#pq%EdMlYa>V)NKH^3lIny0NbChC0oHP;2c@scA4TxGwBya-5nn3|^{LaZ>-*)KGZK(Y zlj~bfW@M@gzh}kpav<9ZX%==?c70Xiijc$d#69VRTQ(^6?Un@DKlJ=6kw57`qzUrF zee@Qb^`HO0nWX{?lJ9fNiXy82Mu)Fb@%pa~FsXSORh`{1=%|EP`Q!T#onmAp4!Z`@ z$@a~G02Tu)21Oaq7wI$Y-gjj3nTyylkBbuI8YqLr8CzQgT7Wk8EhDi$TaSpdZmEVx z`S7#CQ1#GgVgF{iP7zaeUU31U8>|s#=!q9bt=XeE*9Oe;4&DeP9Q(&shdL5g0kYb) z7cLY0-yf45xt!I_9A44P5OtuaUI1q^90lt>8lt~0fVaD223q}AYxat1%TmSX_P(=e zj;6v?^Xu{tSSB_3b?}FBBfC^fc4@s-4F0p@d7V~)WCj-ILw^-0gxq&0v6*_@ zmd4X|v@?WeP0ExOij{^G>essjQ8kN}MpFl8!zRAf^s2Y&`7TsfiMksh?jail!_*Y- zOZ?6<<%(M}Q>#J`rp&_(NshYLW4-8hR5cTvTPSOI`8cd!$UD8|3X(h{()t}*bDah+XUlk5dR~j zIoU6a+D7iG;w{!T`&c%sBJ`~c5<|dJHErjxvJldf(rZkYiX<&SXn;u? zfHE(rT3PxSC5CQL0HSNLh5%N^4z^?Jpq~$!MC3ej(nJ5lcFaCyeD|ehDD1aapTW0X zHThwe9mV4dW4YuK2WQu4S29NcNHGBDKWWKW;;l+{C4dk&;?DAy6#U5Ks7A_n_@pn2 zx$LaZ|8M)VBxz>loyrvjx>o1^T46BQ66D>%T42dfsSm_?2D6=s-QY$ z*2n)gLvY@GCGdi-BEvz#at`J0(Zw!&uR* z82Y`WIrQ?iTonhW9f8dMLhSoLw$1D+A3Rm;_p+b~AcJ$|{@AO}t$+8x0$$xgy32Jn zK$~4q)Ir4ZANG}m8S4-m9TTV4Lt@|OI*`z=Ge@5R5MXXt7ypZg1~VhF0)m8Vq#_dh z4+-b~&;K*T@#eO7-V0~TZPY7hHeN}Q(QK+>B4ZbJCtc3V7g31aegn3r^TTUZPVd(J z;`;f>P*%f!6Q^^MH`9vXOOdapOF+{>KkUj+_8?Rtkfu!mk2k#S@G=^|BsM9)NV4P< znW2ErLElxl80&`h0t8WofHxrv=M0vez-#{~4)`QRsnW|r%oSRjl$s*xA@ZWKpzKBN z_B{wJuV=ev#u9lFBv43nX1oEYM)pKiF+AQyi{b|*ed;DNO5B?yy!0b7X*v*s?C`0Y znrUf+{-}YlObC1WO<;yDgSMG-%M%w9~wLtC@Oj0 z5sBZCK8Npx)6Wnic$P0$t=6Qx8C5NE!duQl*+^56#FoSH0!Z(&BE8`sFbGyS=Ni+M zAx=!E1(`gx|2S-iBo=HGEdTMEa3+&bTTE?}9M<#K0t96nh+dTt1Guw0P+@wM#w&JP=FCY+it#iew7%RW9x@OrA z+CuI_Vwfl>kXi#{{&MZ`CF7R=gn!dPp9}Q85VI`T+R0fV`Z`4Z!!BW;5^VQU(@*E; zdlL=d!71Hn+Wy2|W-OP!NUz3cB7F*1Ildg!B`MkqvfYQ9ylz4$pU{C>^0MFWcNbP1 z!aEfsS{jH}8ba|@^?No{ydGYfYX%3z9bd`sQX&+^Cug;7?T5Am%>eO(bk=NliWXRy zaD*Zt7%unGGSq?$glp!%2@3}$kdB#C_JCiz-OIhpk$Y#~Wb?oZGQ~(MZEi*E9z9NH z>=HOdS@O^ZnF&AljpxqxWz7fESpb^z9r~EWxbx}|>hp*HGggn^lP?rN<;ok;5;OOg z6hYcVAM#S);l9%H{iW-w%SP;K$-4G6es886Qx}74@S2a|C=ZPI84Ryij#K?MR?FF3 zDSkEgq4VX(GXy%jbtoNHw0BQjJ=mPF4-(tYcc;7w;VD@B!{}#qFXpI!vg)Oi@8OaK z!HF%c7tHR)cMxhi5;HoDt!mE!Yt!mkmi%-c8Us-@-IcUVwmZU*fE9RdB#;C^qwxQL zg~$I*foOJqaQxb&$R+x1Zb1^;{HQdZS`@vW-iYPdq`~W}!B`gQ>f@p->**^$EA5QN zP>R5ooekn>SvX&az5T)Ry%IjKpS@kUHAp<@^mpd=$v7~=chxv1>ga_k;zt2Z#-#wf z9ruQ4hgDwa%<-_Axu0k`U8zIGAJI`Csy(kXZkr^CUQelgTM1{+{atE=@w-*s(EhE6 zdi!sVM^cM*6+T)8JQf4KUH%1REo%Tgg_q^eRn@b-QXs6xp;wd-znXl+jSfFvJJl&L z%4jp&nhr+LDDn#nw4GY>W}-rP*FxG;=``(g#u(a?AuZqizD#K-eykhnxpaET;8H~k zCL|GXFh74#=(yDjVaUROwzKx+gS?Cr(519{5*YC8&Oqn2*K2vA0h8b_=vkZdOW`t8Fq1`SCDv8-fH zyFH$=({Kj~aub(P>aVG=(YwZ_KOx$%tE4~a&wuUXayoe_RoJSnT8Vd^S4!YePuSgs z*^hvY(fs4_1O)ysoS?casxK(Q? z6{>Jc-;XmZO4?ZSZQ+qqE|VX=2ke>C#3q(CR5rtSQWbY|3bS-@+)L2>g4&y2tHz^~ zB*b375A5-<8F|A{QP$u88n_t8N>k6@c-GiMP{qO(Fcq5N`f1CMUP^U6d&5@=UW_s~9Q-VA@x94Bvedohq4bQH-v?JLH=ZW^ze3|*B z>P%3upp0g5Q3NOp6pVEJ?;%KPB*V9)wkE1pnv5pS{PeNdvF5^<#JAw2mq6~-3PKw} zIjZ6k5;i=QL7cX6b3RJ{Of?OoXAGQ*L}Ro(bUkd@&UtWXYrXzb_Un@?ostF9*^PxM zJC37Vy6L7Zst+YA2Hr!;NO?CtL@AB7j5E6cJCAoooL$RC#46d#f9b}4*ABXfOF+)Q zGJ@4~(0=umQAYM(Gl+_G2C?nwKHc1l200m>*?xog)q2|#gasTSinoEq8R!3N?5g9U zh`RRDA`*gxbgIAt3X;--beBskNOvwQu%wjK(v2Y9AT6y(hrrUH^h$U4yQuH?{`<{u z{+zjU=G^B#&pBuIo{ffPm3`qejKnC5!Wi5zJ`HSHbbdQ|2i4>=bF_QsB}7MFqlau+{^&)qZSFUQ zNJWDo5&qS!eA+MO@W>*?NDft@{F&`{nfwIeJ{+H~UMG+&6>cc|^FG7L00}O})?UpsE~j;md*N)(7X}RU&3jSnWeArL3@Dp0AGP)5Zp)AjV_=k9d$@zcnHZYt4&uRl6cG+ykuCNtGC zMZB?XGYjOc5a8weX0Ef!VIWabr7dy6JMwrqXH#Yp->3r9BtJcwx*!kdFmYtC8Kq3A z=jc`|R@B1+!}ND02m0`_BETmo@7D>Y=(S%FnRPWfMfb^l;cQJJZsD;b?R6A5jL#NI zv=^9u+kB>1P!KF;8qg;BE{yBj->nRfut7ldGX`oe8*SaAs$K(>4TI%f{jn^jLxwAF zuI;r#7in1pVOC<%Yh_(xBvO+`=hl282U2|pN>ZG8J199mwJsUGRwqlyzX(jriSVJs>uvBB=At^1XX z^EA|FFO1s2ImG|BV}jv=J8>5leI(`UYWJyn7mO3t+m+C{|_{O8C|bcnZk*(~ou511E3KK3)^BzLVHXOs`b6_<^y|NVb2Si=;C} zKko?~b1vwnkdKc*E=s`o` z=IP~CL_AYl$B}gBnFgBzweq_**+GB&^ooIjN5gjsDn^OkrRi+r>nmU>AY-mFl`c zw*2l#IgNL|cI4SzQ&@3Y)O0?LQW32ny?D2CTMy;jQ`3Udwyi2N7M}f1!Q_t1UFa^? zd&rTPl9pUXrrCoRNHk|~U08x;NH-b9(Zo6Ni?Gbnu4q$6jIF06mze?c?YzIo@K|1y z>t=b`6P`e3zdCCUOD!MDP;iRr?#EN+w#)r*10t)px0$200C-TUtSst+^qL9F(Kd8#(QP88VmW`&#+iZZllgVqh zyaT1C&&mx0!yk#GjpT)jD6L6zEg~)peud|S99@ zL*p1cXl~^kEo*Y~O3&n1Pzi31-@^U2Z5`Gjo!Fl66gM*gpud@}gxn>u7bA{({FFuz zEe$Zm+c{T6D?Iz{NX)wZ-kR z(yuYHO#QyrDnL0ujlQ~7WZZ3h@Fhfn2!KW;n+%Wwx8IAi_>|ju{s8xZ+4<4a9o<=7 zk;H=f+9acmJ)ECNP48AG-@ij6Jc)4V0N$K z$cQ)FldunnT4B4I^G>m9LxpukpS&@RleTlZkH#uideD|5=o|0*Q7)B^jjusfG!wAr89x$!es@teRo#e8B%v=NL5B< zjR1@_7yU`~xdC1o&QY+%^zs$H(y&2JJmKybL!#sCEAmc;x*j*DoJ}g`YB(mMI`E{; zDugE3pdI=C@C@NB=aAOkPrB_qkbfOUbA!}%Ce9F&wlR@v!dgTVa+G))bu5BaF~c7V z>I>~oRVj@p+b9WArw5?lozX2QOhZnT*!syQ6rs(> z%zS*Ro^g{udF%9!v^ABpsuT`x0|F-_D-%^-8%J&L>Y5sSnzV;BwCBUKg)>jT@OhK7 z2Za{jUTHA}k=tyPN8Jk5W`Bfx#H%S5`<_8O6)PDt^=w_(>cz@Caz?0<88>?WJDA5Z7)7m$!KbU!G<|RCv2c ze8o=jvlwL75LXlVOvZC#E^UxY&N5M+e9^sTyj)u~sU*oK!a;Hib_=-aM@SpkM!#?D zhuilCAqDCOW@ag%hrf)!^yCihs{Tkm_GV{$z~Y`!Gwwu^_rxpC_=<@|B_mqaYs3|= zp0;>J|EHu~=5Ir=_9;m*axSaw#n0*M?T%RKr##>(^uO;ShMgaM^`xVNGT~ z_PzN}Q=4@BzXy=JgCAi}K;PScE@|$>e^jcL-xPM$CQk0ktTLbE_o`B5<59ldQy!9> zZF&<6BwQUqtW8Ok`97!Lt&zEYIY4YbN3m;`G1E5`S#R!$FTFKV&yxaFCd0bHGFkG4 z@=wi0b@LgdO#tyq6E7gky`-d3T_#N0A6YAeDojM@eX+44g{;S@WZOID9us@|;$`Hu;yKJ|oZ1Zg7>humWklH`Yq4M!>Zz!YqUE^OrK?Z(zfo zKWk$bZ5m=pI*r)-e1yAJcB5MjD9`!4d|W$|=eD4$wI;@$((}}oW!{QAjPB7e_pdnE)rsJi>tFSEsA18+C0afqv0)qYhWCb| zX^R6eQRf?ev=7Y`*M>8mxr$`xAu$MhfvnZr(CfOUK2MFRV2%CO?__bd8|qsghY@sN zW#3TeDRJtiCS1eNt+b0r*{fhbUF-OB>{Mp$>QklmwSOSnvSK0Kz+HwHYX_-6W`F7N zr*$~HiAv8B8Y)#s?5aV0vp~(^ab$VUsdai+$!{JQbiSEJ<5l8sp4!~fGXN*nP#E32 zGfdoQjKr@eoaF!vRa(JlXT2RVKc<%`oQgKC7&I^oPactnK-7d1pjK6@p7)o)@{Ls&d=Qrsxf!(zRrk)&T&<57oEhy1Exm>iUw=t+;@s(GI z?MLp{Z;f}eNPcL%Z{oYA#u?hMx;%acpFb`y|02{B${=*dLI8h#MnDX|ltaQ6l&#v5 zjKeCduAMJ_ip1=O%U~R_+`HxFQsP328^BSM{v||eZo9WeB)-hJ5l=^Rw>^*B*Noc` z;o4LqM$(V$F!+)|P&#yl$aE8vn$X~{c|VCaneGQe1c)H5K_5$hfK z;0iA@5B7iAN^VWf#+0yPTGV5tXtOs>=yd$oI+m|&Q) z<&IZ3Z6iC4MYt5$k#V8NDZe$M#)>8SO9pQnvFYf%EYVI zqSelZEjT7`ydmXDz)l_sp$+Q)aXI8pN2V;a*_a2bB^9B zMX%*gnh1uaz+=b8*5y1%oR{R_JxvgkPxMn40j1g9XAiw24$3MCMaC!Adu!~h+}O}h zJSZ_)!VG58PH3QIb}roBra2tQqobtEs8z;QlnbM zc6BN})v++V`Krn7Z}%4jM?`)-qu-{h=Fd+V$#>`oDG)<;``h|2?bjne#&^)sh}7*#T=Of%8~zbq>y$zNf|-mJ(u)oB1)5WxJv*^)YX_%g7aMx~w!xZiuFkWx9?>S8Q2v?M6c z+47;gd9pTNHr zN$NfejI8*65C32Zjp#!hN+!}5xYf#X$Iq!^k&~9tEJSHWY;b^i{#1B(aoLTq4VIk@ zmq3(n1E{y8AaVBT{Z^D#u)!@De=D8?Eg_0IV>~L{T?uKDU6@P5u{zaB@JR)zDI4Dz z)}MF-;159oRsjcz>HVzTF2b=qfOr#omk)p72bO6#+sPcU;QSjNty}rs`|F!L+$0k; zB~>l)pDxo&z+;xTLUEv1l?~#!K6~^!Un{$o74ldFCj~Gc{F^}`T=A84%!FQJ$Y!Uu z5NQ)P^V{}v4GrI-`z_+{4f+;kQoz_>z+n zaai1bYHGcr<9Ybh>;1ntxfnHQUaI5!6S;*!`tcKq9>q`nW3Tw%8{#B63eNs6ue`uo zwDcNiqT$kLnhYFtM3fQ7KnX(dFHpZm7xn#FvD0X8^s-7aP2#V#@u8#*xNGQ=whWR# zujKpk5y-qbX4dl=B!Z+NuXEF$)wb}cRwted>^gBGzvm$zyKz>YpMw099IjI-4RDK%q?hBR{7n(x+ljeNyaG0Su2x0%U6 zm`_S&4w#2!3(s{2wO$>z2^@@+)n_Q^0akjdX0k%Zae>GX0o(4s-2nj(ny5D@0T(U)$(BIg(24@h>*E8@U}TWqFjr8pI_jC=pkL*=7gfV~MWS_o zF7e99IZT5bp?@)pDGkb3rJJ!mezGgP2!44=qBaPwZ!i(eV291dN+?wev6Z}IGQgs~ z(|XT0=G{&E_I6xgXSjC}yr{IOrDwB0T$YrC;UwGqI6f*HSh@*jyA~L){Pvfu0QYj! zP*`sar8=?@T`10{W`!}8;4__2%&vfqyr(`4VK`_=@(!Ovf))V^tK z(oVIQlA|Uah=k{8+G)FwM-SuOGn1xfuVh1o9{r;iiSTmj_fAIAq<`s|ni&w2gz-@u z@%zFL(iH%er(T707WO;aUJgqR;Z%1q3{j;3}+PwvapTCsW# z9E4XmWx8_|Eh#+9-4P~nahm{%DYF9w{zd@+{|6{$=?5IeEFcg|UI9|S2X*y~@tLJp zS$SX^EGxZvC;JyD20YHC)BDBXW!3Y0x@Vhh|1GTiBKgAI-{#$t{ zj8U)vVl3h*`u-vAu3|uN=U#th$q)a#( Date: Mon, 1 Apr 2024 09:22:35 +0200 Subject: [PATCH 088/203] Bugfix/fix duplicated tags in position detail dialog (#3224) * Fix duplicated tags * Update changelog --- CHANGELOG.md | 4 ++++ apps/api/src/app/portfolio/portfolio.service.ts | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a0b55060..7da7e2f93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Improved the usability of the date range support by specific years (`2023`, `2022`, `2021`, etc.) in the assistant (experimental) - Introduced a factory for the portfolio calculations to support different algorithms in future +### Fixed + +- Fixed the duplicated tags in the position detail dialog + ## 2.69.0 - 2024-03-30 ### Added diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 566ad4049..0bdafec48 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -719,8 +719,6 @@ export class PortfolioService { { dataSource: aDataSource, symbol: aSymbol } ]); - tags = uniqBy(tags, 'id'); - const portfolioCalculator = this.calculatorFactory.createCalculator({ activities: orders.filter((order) => { tags = tags.concat(order.tags); @@ -731,6 +729,8 @@ export class PortfolioService { currency: userCurrency }); + tags = uniqBy(tags, 'id'); + const portfolioStart = portfolioCalculator.getStartDate(); const transactionPoints = portfolioCalculator.getTransactionPoints(); From d7b579e3e86bf9bf7973b60322c821a69bd15559 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 1 Apr 2024 10:42:15 +0200 Subject: [PATCH 089/203] Feature/refactor getAnnualizedPerformancePercent to portfolio calculator (#3226) * Move getAnnualizedPerformancePercent() to portfolio calculator --- .../calculator/portfolio-calculator.ts | 19 +---- .../twr/portfolio-calculator.spec.ts | 68 +--------------- .../app/portfolio/portfolio.service.spec.ts | 78 +++++++++++++++++++ .../src/app/portfolio/portfolio.service.ts | 56 ++++++------- 4 files changed, 111 insertions(+), 110 deletions(-) create mode 100644 apps/api/src/app/portfolio/portfolio.service.spec.ts diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index c3edc86d9..48fcaf343 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -29,7 +29,7 @@ import { max, subDays } from 'date-fns'; -import { isNumber, last, uniq } from 'lodash'; +import { last, uniq } from 'lodash'; export abstract class PortfolioCalculator { protected static readonly ENABLE_LOGGING = false; @@ -80,23 +80,6 @@ export abstract class PortfolioCalculator { positions: TimelinePosition[] ): CurrentPositions; - public getAnnualizedPerformancePercent({ - daysInMarket, - netPerformancePercent - }: { - daysInMarket: number; - netPerformancePercent: Big; - }): Big { - if (isNumber(daysInMarket) && daysInMarket > 0) { - const exponent = new Big(365).div(daysInMarket).toNumber(); - return new Big( - Math.pow(netPerformancePercent.plus(1).toNumber(), exponent) - ).minus(1); - } - - return new Big(0); - } - public async getChartData({ end = new Date(Date.now()), start, diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts index b68f4358d..365593846 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts @@ -1,12 +1,7 @@ -import { - PerformanceCalculationType, - PortfolioCalculatorFactory -} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; -import { Big } from 'big.js'; - describe('PortfolioCalculator', () => { let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; @@ -28,64 +23,5 @@ describe('PortfolioCalculator', () => { ); }); - describe('annualized performance percentage', () => { - it('Get annualized performance', async () => { - const portfolioCalculator = factory.createCalculator({ - activities: [], - calculationType: PerformanceCalculationType.TWR, - currency: 'CHF' - }); - - expect( - portfolioCalculator - .getAnnualizedPerformancePercent({ - daysInMarket: NaN, // differenceInDays of date-fns returns NaN for the same day - netPerformancePercent: new Big(0) - }) - .toNumber() - ).toEqual(0); - - expect( - portfolioCalculator - .getAnnualizedPerformancePercent({ - daysInMarket: 0, - netPerformancePercent: new Big(0) - }) - .toNumber() - ).toEqual(0); - - /** - * Source: https://www.readyratios.com/reference/analysis/annualized_rate.html - */ - expect( - portfolioCalculator - .getAnnualizedPerformancePercent({ - daysInMarket: 65, // < 1 year - netPerformancePercent: new Big(0.1025) - }) - .toNumber() - ).toBeCloseTo(0.729705); - - expect( - portfolioCalculator - .getAnnualizedPerformancePercent({ - daysInMarket: 365, // 1 year - netPerformancePercent: new Big(0.05) - }) - .toNumber() - ).toBeCloseTo(0.05); - - /** - * Source: https://www.investopedia.com/terms/a/annualized-total-return.asp#annualized-return-formula-and-calculation - */ - expect( - portfolioCalculator - .getAnnualizedPerformancePercent({ - daysInMarket: 575, // > 1 year - netPerformancePercent: new Big(0.2374) - }) - .toNumber() - ).toBeCloseTo(0.145); - }); - }); + test.skip('Skip empty test', () => 1); }); diff --git a/apps/api/src/app/portfolio/portfolio.service.spec.ts b/apps/api/src/app/portfolio/portfolio.service.spec.ts new file mode 100644 index 000000000..7654b7df3 --- /dev/null +++ b/apps/api/src/app/portfolio/portfolio.service.spec.ts @@ -0,0 +1,78 @@ +import { Big } from 'big.js'; + +import { PortfolioService } from './portfolio.service'; + +describe('PortfolioService', () => { + let portfolioService: PortfolioService; + + beforeAll(async () => { + portfolioService = new PortfolioService( + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, + null + ); + }); + + describe('annualized performance percentage', () => { + it('Get annualized performance', async () => { + expect( + portfolioService + .getAnnualizedPerformancePercent({ + daysInMarket: NaN, // differenceInDays of date-fns returns NaN for the same day + netPerformancePercent: new Big(0) + }) + .toNumber() + ).toEqual(0); + + expect( + portfolioService + .getAnnualizedPerformancePercent({ + daysInMarket: 0, + netPerformancePercent: new Big(0) + }) + .toNumber() + ).toEqual(0); + + /** + * Source: https://www.readyratios.com/reference/analysis/annualized_rate.html + */ + expect( + portfolioService + .getAnnualizedPerformancePercent({ + daysInMarket: 65, // < 1 year + netPerformancePercent: new Big(0.1025) + }) + .toNumber() + ).toBeCloseTo(0.729705); + + expect( + portfolioService + .getAnnualizedPerformancePercent({ + daysInMarket: 365, // 1 year + netPerformancePercent: new Big(0.05) + }) + .toNumber() + ).toBeCloseTo(0.05); + + /** + * Source: https://www.investopedia.com/terms/a/annualized-total-return.asp#annualized-return-formula-and-calculation + */ + expect( + portfolioService + .getAnnualizedPerformancePercent({ + daysInMarket: 575, // > 1 year + netPerformancePercent: new Big(0.2374) + }) + .toNumber() + ).toBeCloseTo(0.145); + }); + }); +}); diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 0bdafec48..17a1ea4a0 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -78,7 +78,7 @@ import { parseISO, set } from 'date-fns'; -import { isEmpty, last, uniq, uniqBy } from 'lodash'; +import { isEmpty, isNumber, last, uniq, uniqBy } from 'lodash'; import { PortfolioCalculator } from './calculator/portfolio-calculator'; import { @@ -217,6 +217,24 @@ export class PortfolioService { }; } + public getAnnualizedPerformancePercent({ + daysInMarket, + netPerformancePercent + }: { + daysInMarket: number; + netPerformancePercent: Big; + }): Big { + if (isNumber(daysInMarket) && daysInMarket > 0) { + const exponent = new Big(365).div(daysInMarket).toNumber(); + + return new Big( + Math.pow(netPerformancePercent.plus(1).toNumber(), exponent) + ).minus(1); + } + + return new Big(0); + } + public async getDividends({ activities, groupBy @@ -1769,34 +1787,20 @@ export class PortfolioService { const daysInMarket = differenceInDays(new Date(), firstOrderDate); - const annualizedPerformancePercent = this.calculatorFactory - .createCalculator({ - activities: [], - calculationType: PerformanceCalculationType.TWR, - currency: userCurrency - }) - .getAnnualizedPerformancePercent({ + const annualizedPerformancePercent = this.getAnnualizedPerformancePercent({ + daysInMarket, + netPerformancePercent: new Big( + performanceInformation.performance.currentNetPerformancePercent + ) + })?.toNumber(); + + const annualizedPerformancePercentWithCurrencyEffect = + this.getAnnualizedPerformancePercent({ daysInMarket, netPerformancePercent: new Big( - performanceInformation.performance.currentNetPerformancePercent + performanceInformation.performance.currentNetPerformancePercentWithCurrencyEffect ) - }) - ?.toNumber(); - - const annualizedPerformancePercentWithCurrencyEffect = - this.calculatorFactory - .createCalculator({ - activities: [], - calculationType: PerformanceCalculationType.TWR, - currency: userCurrency - }) - .getAnnualizedPerformancePercent({ - daysInMarket, - netPerformancePercent: new Big( - performanceInformation.performance.currentNetPerformancePercentWithCurrencyEffect - ) - }) - ?.toNumber(); + })?.toNumber(); return { ...performanceInformation.performance, From efdc9b387fa89310e135a315654a7ec8fabb0d2b Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 1 Apr 2024 13:24:00 +0200 Subject: [PATCH 090/203] Eliminate ghostfolio-style.scss (#3228) --- apps/client/src/app/app.component.scss | 2 -- .../app/components/access-table/access-table.component.scss | 2 -- .../components/accounts-table/accounts-table.component.scss | 2 -- apps/client/src/app/components/admin-jobs/admin-jobs.scss | 2 -- .../admin-market-data-detail.component.scss | 2 -- .../app/components/admin-market-data/admin-market-data.scss | 2 -- .../src/app/components/admin-overview/admin-overview.scss | 2 -- .../components/admin-platform/admin-platform.component.scss | 2 -- .../components/admin-settings/admin-settings.component.scss | 2 -- .../src/app/components/admin-tag/admin-tag.component.scss | 2 -- apps/client/src/app/components/admin-users/admin-users.scss | 2 -- apps/client/src/app/components/header/header.component.scss | 2 -- .../src/app/components/home-holdings/home-holdings.scss | 2 -- apps/client/src/app/components/home-market/home-market.scss | 2 -- .../src/app/components/home-overview/home-overview.scss | 2 -- .../src/app/components/home-summary/home-summary.scss | 2 -- .../src/app/components/positions/positions.component.scss | 6 ++---- apps/client/src/app/pages/about/about-page.scss | 2 -- apps/client/src/app/pages/admin/admin-page.scss | 2 -- apps/client/src/app/pages/home/home-page.scss | 2 -- apps/client/src/app/pages/landing/landing-page.scss | 2 -- apps/client/src/app/pages/portfolio/portfolio-page.scss | 2 -- .../src/app/pages/user-account/user-account-page.scss | 2 -- apps/client/src/app/pages/zen/zen-page.scss | 2 -- apps/client/src/styles/ghostfolio-style.scss | 4 ---- apps/client/src/styles/theme.scss | 3 +++ .../lib/account-balances/account-balances.component.scss | 2 -- .../lib/activities-filter/activities-filter.component.scss | 2 -- .../lib/activities-table/activities-table.component.scss | 2 -- .../ui/src/lib/holdings-table/holdings-table.component.scss | 2 -- 30 files changed, 5 insertions(+), 62 deletions(-) delete mode 100644 apps/client/src/styles/ghostfolio-style.scss diff --git a/apps/client/src/app/app.component.scss b/apps/client/src/app/app.component.scss index 21d33e3c9..a23e94fbb 100644 --- a/apps/client/src/app/app.component.scss +++ b/apps/client/src/app/app.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; min-height: 100svh; diff --git a/apps/client/src/app/components/access-table/access-table.component.scss b/apps/client/src/app/components/access-table/access-table.component.scss index f506edfc6..22a5d6732 100644 --- a/apps/client/src/app/components/access-table/access-table.component.scss +++ b/apps/client/src/app/components/access-table/access-table.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; diff --git a/apps/client/src/app/components/accounts-table/accounts-table.component.scss b/apps/client/src/app/components/accounts-table/accounts-table.component.scss index 39e455dca..e934483db 100644 --- a/apps/client/src/app/components/accounts-table/accounts-table.component.scss +++ b/apps/client/src/app/components/accounts-table/accounts-table.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; diff --git a/apps/client/src/app/components/admin-jobs/admin-jobs.scss b/apps/client/src/app/components/admin-jobs/admin-jobs.scss index b5b58f67e..5d4e87f30 100644 --- a/apps/client/src/app/components/admin-jobs/admin-jobs.scss +++ b/apps/client/src/app/components/admin-jobs/admin-jobs.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; } diff --git a/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.scss b/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.scss index 8121fc119..a03533589 100644 --- a/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.scss +++ b/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; font-size: 0.9rem; diff --git a/apps/client/src/app/components/admin-market-data/admin-market-data.scss b/apps/client/src/app/components/admin-market-data/admin-market-data.scss index b5b58f67e..5d4e87f30 100644 --- a/apps/client/src/app/components/admin-market-data/admin-market-data.scss +++ b/apps/client/src/app/components/admin-market-data/admin-market-data.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; } diff --git a/apps/client/src/app/components/admin-overview/admin-overview.scss b/apps/client/src/app/components/admin-overview/admin-overview.scss index 25209ac97..a4ae1edd2 100644 --- a/apps/client/src/app/components/admin-overview/admin-overview.scss +++ b/apps/client/src/app/components/admin-overview/admin-overview.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; diff --git a/apps/client/src/app/components/admin-platform/admin-platform.component.scss b/apps/client/src/app/components/admin-platform/admin-platform.component.scss index b5b58f67e..5d4e87f30 100644 --- a/apps/client/src/app/components/admin-platform/admin-platform.component.scss +++ b/apps/client/src/app/components/admin-platform/admin-platform.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; } diff --git a/apps/client/src/app/components/admin-settings/admin-settings.component.scss b/apps/client/src/app/components/admin-settings/admin-settings.component.scss index b5b58f67e..5d4e87f30 100644 --- a/apps/client/src/app/components/admin-settings/admin-settings.component.scss +++ b/apps/client/src/app/components/admin-settings/admin-settings.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; } diff --git a/apps/client/src/app/components/admin-tag/admin-tag.component.scss b/apps/client/src/app/components/admin-tag/admin-tag.component.scss index b5b58f67e..5d4e87f30 100644 --- a/apps/client/src/app/components/admin-tag/admin-tag.component.scss +++ b/apps/client/src/app/components/admin-tag/admin-tag.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; } diff --git a/apps/client/src/app/components/admin-users/admin-users.scss b/apps/client/src/app/components/admin-users/admin-users.scss index f06a9d825..e4990bf59 100644 --- a/apps/client/src/app/components/admin-users/admin-users.scss +++ b/apps/client/src/app/components/admin-users/admin-users.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; diff --git a/apps/client/src/app/components/header/header.component.scss b/apps/client/src/app/components/header/header.component.scss index 0c6557ddd..04d634d3b 100644 --- a/apps/client/src/app/components/header/header.component.scss +++ b/apps/client/src/app/components/header/header.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; z-index: 999; diff --git a/apps/client/src/app/components/home-holdings/home-holdings.scss b/apps/client/src/app/components/home-holdings/home-holdings.scss index b5b58f67e..5d4e87f30 100644 --- a/apps/client/src/app/components/home-holdings/home-holdings.scss +++ b/apps/client/src/app/components/home-holdings/home-holdings.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; } diff --git a/apps/client/src/app/components/home-market/home-market.scss b/apps/client/src/app/components/home-market/home-market.scss index f9e5e6275..5b523160d 100644 --- a/apps/client/src/app/components/home-market/home-market.scss +++ b/apps/client/src/app/components/home-market/home-market.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; diff --git a/apps/client/src/app/components/home-overview/home-overview.scss b/apps/client/src/app/components/home-overview/home-overview.scss index 9f8a1ce49..3a692b28d 100644 --- a/apps/client/src/app/components/home-overview/home-overview.scss +++ b/apps/client/src/app/components/home-overview/home-overview.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; height: 100%; diff --git a/apps/client/src/app/components/home-summary/home-summary.scss b/apps/client/src/app/components/home-summary/home-summary.scss index b5b58f67e..5d4e87f30 100644 --- a/apps/client/src/app/components/home-summary/home-summary.scss +++ b/apps/client/src/app/components/home-summary/home-summary.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; } diff --git a/apps/client/src/app/components/positions/positions.component.scss b/apps/client/src/app/components/positions/positions.component.scss index 90eff65ea..d3e8995a1 100644 --- a/apps/client/src/app/components/positions/positions.component.scss +++ b/apps/client/src/app/components/positions/positions.component.scss @@ -1,11 +1,9 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; gf-position { &:nth-child(even) { - background-color: rgba(0, 0, 0, $alpha-hover); + background-color: rgba(0, 0, 0, var(--gf-theme-alpha-hover)); } } } @@ -13,7 +11,7 @@ :host-context(.is-dark-theme) { gf-position { &:nth-child(even) { - background-color: rgba(255, 255, 255, $alpha-hover); + background-color: rgba(255, 255, 255, var(--gf-theme-alpha-hover)); } } } diff --git a/apps/client/src/app/pages/about/about-page.scss b/apps/client/src/app/pages/about/about-page.scss index 6a0b74854..e87d9a05b 100644 --- a/apps/client/src/app/pages/about/about-page.scss +++ b/apps/client/src/app/pages/about/about-page.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { color: rgb(var(--dark-primary-text)); } diff --git a/apps/client/src/app/pages/admin/admin-page.scss b/apps/client/src/app/pages/admin/admin-page.scss index 6a0b74854..e87d9a05b 100644 --- a/apps/client/src/app/pages/admin/admin-page.scss +++ b/apps/client/src/app/pages/admin/admin-page.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { color: rgb(var(--dark-primary-text)); } diff --git a/apps/client/src/app/pages/home/home-page.scss b/apps/client/src/app/pages/home/home-page.scss index 6a0b74854..e87d9a05b 100644 --- a/apps/client/src/app/pages/home/home-page.scss +++ b/apps/client/src/app/pages/home/home-page.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { color: rgb(var(--dark-primary-text)); } diff --git a/apps/client/src/app/pages/landing/landing-page.scss b/apps/client/src/app/pages/landing/landing-page.scss index 6a8dd8ec5..0b8736819 100644 --- a/apps/client/src/app/pages/landing/landing-page.scss +++ b/apps/client/src/app/pages/landing/landing-page.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; diff --git a/apps/client/src/app/pages/portfolio/portfolio-page.scss b/apps/client/src/app/pages/portfolio/portfolio-page.scss index 6a0b74854..e87d9a05b 100644 --- a/apps/client/src/app/pages/portfolio/portfolio-page.scss +++ b/apps/client/src/app/pages/portfolio/portfolio-page.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { color: rgb(var(--dark-primary-text)); } diff --git a/apps/client/src/app/pages/user-account/user-account-page.scss b/apps/client/src/app/pages/user-account/user-account-page.scss index 6a0b74854..e87d9a05b 100644 --- a/apps/client/src/app/pages/user-account/user-account-page.scss +++ b/apps/client/src/app/pages/user-account/user-account-page.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { color: rgb(var(--dark-primary-text)); } diff --git a/apps/client/src/app/pages/zen/zen-page.scss b/apps/client/src/app/pages/zen/zen-page.scss index 6a0b74854..e87d9a05b 100644 --- a/apps/client/src/app/pages/zen/zen-page.scss +++ b/apps/client/src/app/pages/zen/zen-page.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { color: rgb(var(--dark-primary-text)); } diff --git a/apps/client/src/styles/ghostfolio-style.scss b/apps/client/src/styles/ghostfolio-style.scss deleted file mode 100644 index 103f4cf14..000000000 --- a/apps/client/src/styles/ghostfolio-style.scss +++ /dev/null @@ -1,4 +0,0 @@ -$mat-css-dark-theme-selector: '.is-dark-theme'; - -$alpha-disabled-text: 0.38; -$alpha-hover: 0.04; diff --git a/apps/client/src/styles/theme.scss b/apps/client/src/styles/theme.scss index 8114402d5..cc9b164e6 100644 --- a/apps/client/src/styles/theme.scss +++ b/apps/client/src/styles/theme.scss @@ -3,6 +3,8 @@ $dark-primary-text: rgba(black, 0.87); $light-primary-text: white; +$mat-css-dark-theme-selector: '.is-dark-theme'; + $gf-primary: ( 50: var(--gf-theme-primary-50), 100: var(--gf-theme-primary-100), @@ -106,6 +108,7 @@ $gf-theme-dark: mat.define-dark-theme( } :root { + --gf-theme-alpha-hover: 0.04; --gf-theme-primary-500: #36cfcc; --gf-theme-primary-500-rgb: 0, 187, 255; --gf-theme-secondary-500: #3686cf; diff --git a/libs/ui/src/lib/account-balances/account-balances.component.scss b/libs/ui/src/lib/account-balances/account-balances.component.scss index b5b58f67e..5d4e87f30 100644 --- a/libs/ui/src/lib/account-balances/account-balances.component.scss +++ b/libs/ui/src/lib/account-balances/account-balances.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; } diff --git a/libs/ui/src/lib/activities-filter/activities-filter.component.scss b/libs/ui/src/lib/activities-filter/activities-filter.component.scss index 7d0649bfc..07964fdfa 100644 --- a/libs/ui/src/lib/activities-filter/activities-filter.component.scss +++ b/libs/ui/src/lib/activities-filter/activities-filter.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; diff --git a/libs/ui/src/lib/activities-table/activities-table.component.scss b/libs/ui/src/lib/activities-table/activities-table.component.scss index 003303f95..bb5e11691 100644 --- a/libs/ui/src/lib/activities-table/activities-table.component.scss +++ b/libs/ui/src/lib/activities-table/activities-table.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; diff --git a/libs/ui/src/lib/holdings-table/holdings-table.component.scss b/libs/ui/src/lib/holdings-table/holdings-table.component.scss index a33b78aff..8e321bcf1 100644 --- a/libs/ui/src/lib/holdings-table/holdings-table.component.scss +++ b/libs/ui/src/lib/holdings-table/holdings-table.component.scss @@ -1,5 +1,3 @@ -@import 'apps/client/src/styles/ghostfolio-style'; - :host { display: block; From 6f3cce1c5f2cb5bb59d2051f912db8e7d5bc95bb Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 2 Apr 2024 20:17:16 +0200 Subject: [PATCH 091/203] Feature/disable option to update cash balance if date is not today (#3229) * Disable option to update cash balance if date is not today * Update changelog --- CHANGELOG.md | 1 + .../create-or-update-activity-dialog.component.ts | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7da7e2f93..0e0559738 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Disabled the option to update the cash balance of an account if date is not today - Improved the usability of the date range support by specific years (`2023`, `2022`, `2021`, etc.) in the assistant (experimental) - Introduced a factory for the portfolio calculations to support different algorithms in future diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts index b628aba46..4fb8e9d81 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts @@ -275,6 +275,17 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { } ); + this.activityForm.controls['date'].valueChanges.subscribe(() => { + if (isToday(this.activityForm.controls['date'].value)) { + this.activityForm.controls['updateAccountBalance'].enable(); + } else { + this.activityForm.controls['updateAccountBalance'].disable(); + this.activityForm.controls['updateAccountBalance'].setValue(false); + } + + this.changeDetectorRef.markForCheck(); + }); + this.activityForm.controls['searchSymbol'].valueChanges.subscribe(() => { if (this.activityForm.controls['searchSymbol'].invalid) { this.data.activity.SymbolProfile = null; From ca7717f9c56a70dc5f6fb2ab1ddaa8f1707d36d5 Mon Sep 17 00:00:00 2001 From: Bastien Jeannelle <48835068+Sonlis@users.noreply.github.com> Date: Tue, 2 Apr 2024 21:26:14 +0300 Subject: [PATCH 092/203] Bugfix/Enable tini in docker compose files instead of adding it to the Dockerfile (#3232) * Enable tini in docker compose files instead of adding it to the Dockerfile * Update changelog --- CHANGELOG.md | 2 ++ Dockerfile | 7 ------- docker/docker-compose.build.yml | 1 + docker/docker-compose.yml | 1 + 4 files changed, 4 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e0559738..c0446ee8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Set up the language localization for Chinese (`zh`) +- Added `init: true` to the `docker-compose` files (`docker-compose.yml` and `docker-compose.build.yml`) to avoid zombie processes - Set up _Webpack Bundle Analyzer_ ### Changed @@ -21,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fixed the duplicated tags in the position detail dialog +- Removed `Tini` from the docker image ## 2.69.0 - 2024-03-30 diff --git a/Dockerfile b/Dockerfile index aa578e235..f9396d0e7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -56,13 +56,6 @@ RUN apt update && apt install -y \ openssl \ && rm -rf /var/lib/apt/lists/* -# Add tini, which is an init process that handles signaling within the container -# and with the host. See https://github.com/krallin/tini -ENV TINI_VERSION v0.19.0 -ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini -RUN chmod +x /tini -ENTRYPOINT ["/tini", "--"] - COPY --from=builder /ghostfolio/dist/apps /ghostfolio/apps COPY ./docker/entrypoint.sh /ghostfolio/entrypoint.sh WORKDIR /ghostfolio/apps/api diff --git a/docker/docker-compose.build.yml b/docker/docker-compose.build.yml index 2ac90b7c1..7ad52be7d 100644 --- a/docker/docker-compose.build.yml +++ b/docker/docker-compose.build.yml @@ -2,6 +2,7 @@ version: '3.9' services: ghostfolio: build: ../ + init: true env_file: - ../.env environment: diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 007a46883..d2dbb8112 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -2,6 +2,7 @@ version: '3.9' services: ghostfolio: image: ghostfolio/ghostfolio:latest + init: true env_file: - ../.env environment: From 26b9660e110f67bbdb49975eadf4e5fdf94d56d6 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 2 Apr 2024 20:29:47 +0200 Subject: [PATCH 093/203] Release 2.70.0 (#3234) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0446ee8f..2c36c692d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.70.0 - 2024-04-02 ### Added diff --git a/package.json b/package.json index 05ffd3e49..5db51af5d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.69.0", + "version": "2.70.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 371c999fbc8a94ac6ee2b610da148d011bec457f Mon Sep 17 00:00:00 2001 From: Arshad Jamal Date: Wed, 3 Apr 2024 23:17:53 +0530 Subject: [PATCH 094/203] Feature/Add dividend yield to position detail dialog (#2636) * Add dividend yield to position detail dialog * Update changelog --------- Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> --- CHANGELOG.md | 6 +++ .../portfolio-position-detail.interface.ts | 2 + .../src/app/portfolio/portfolio.service.ts | 24 ++++++++++++ .../position-detail-dialog.component.ts | 4 ++ .../position-detail-dialog.html | 39 +++++++++++++------ 5 files changed, 63 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2c36c692d..a6513785b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Added + +- Added the dividend yield to the position detail dialog (experimental) + ## 2.70.0 - 2024-04-02 ### Added diff --git a/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts b/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts index 2925ca9bc..c058a0249 100644 --- a/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts @@ -12,6 +12,8 @@ export interface PortfolioPositionDetail { averagePrice: number; dataProviderInfo: DataProviderInfo; dividendInBaseCurrency: number; + dividendYieldPercent: number; + dividendYieldPercentWithCurrencyEffect: number; feeInBaseCurrency: number; firstBuyDate: string; grossPerformance: number; diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 17a1ea4a0..3b8a42d89 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -710,6 +710,8 @@ export class PortfolioService { averagePrice: undefined, dataProviderInfo: undefined, dividendInBaseCurrency: undefined, + dividendYieldPercent: undefined, + dividendYieldPercentWithCurrencyEffect: undefined, feeInBaseCurrency: undefined, firstBuyDate: undefined, grossPerformance: undefined, @@ -769,6 +771,8 @@ export class PortfolioService { firstBuyDate, marketPrice, quantity, + timeWeightedInvestment, + timeWeightedInvestmentWithCurrencyEffect, transactionCount } = position; @@ -781,6 +785,21 @@ export class PortfolioService { return Account; }); + const dividendYieldPercent = this.getAnnualizedPerformancePercent({ + daysInMarket: differenceInDays(new Date(), parseDate(firstBuyDate)), + netPerformancePercent: dividendInBaseCurrency.div( + timeWeightedInvestment + ) + }); + + const dividendYieldPercentWithCurrencyEffect = + this.getAnnualizedPerformancePercent({ + daysInMarket: differenceInDays(new Date(), parseDate(firstBuyDate)), + netPerformancePercent: dividendInBaseCurrency.div( + timeWeightedInvestmentWithCurrencyEffect + ) + }); + const historicalData = await this.dataProviderService.getHistorical( [{ dataSource, symbol: aSymbol }], 'day', @@ -854,6 +873,9 @@ export class PortfolioService { averagePrice: averagePrice.toNumber(), dataProviderInfo: portfolioCalculator.getDataProviderInfos()?.[0], dividendInBaseCurrency: dividendInBaseCurrency.toNumber(), + dividendYieldPercent: dividendYieldPercent.toNumber(), + dividendYieldPercentWithCurrencyEffect: + dividendYieldPercentWithCurrencyEffect.toNumber(), feeInBaseCurrency: this.exchangeRateDataService.toCurrency( fee.toNumber(), SymbolProfile.currency, @@ -930,6 +952,8 @@ export class PortfolioService { averagePrice: 0, dataProviderInfo: undefined, dividendInBaseCurrency: 0, + dividendYieldPercent: 0, + dividendYieldPercentWithCurrencyEffect: 0, feeInBaseCurrency: 0, firstBuyDate: undefined, grossPerformance: undefined, diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts index 6ada2eeb1..bb37b9ed5 100644 --- a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts +++ b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts @@ -48,6 +48,7 @@ export class PositionDetailDialog implements OnDestroy, OnInit { public dataProviderInfo: DataProviderInfo; public dataSource: MatTableDataSource; public dividendInBaseCurrency: number; + public dividendYieldPercentWithCurrencyEffect: number; public feeInBaseCurrency: number; public firstBuyDate: string; public historicalDataItems: LineChartItem[]; @@ -95,6 +96,7 @@ export class PositionDetailDialog implements OnDestroy, OnInit { averagePrice, dataProviderInfo, dividendInBaseCurrency, + dividendYieldPercentWithCurrencyEffect, feeInBaseCurrency, firstBuyDate, historicalData, @@ -119,6 +121,8 @@ export class PositionDetailDialog implements OnDestroy, OnInit { this.dataProviderInfo = dataProviderInfo; this.dataSource = new MatTableDataSource(orders.reverse()); this.dividendInBaseCurrency = dividendInBaseCurrency; + this.dividendYieldPercentWithCurrencyEffect = + dividendYieldPercentWithCurrencyEffect; this.feeInBaseCurrency = feeInBaseCurrency; this.firstBuyDate = firstBuyDate; this.historicalDataItems = historicalData.map( diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html index 3a8694c83..3680f5701 100644 --- a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html +++ b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -134,17 +134,29 @@ >Investment
-
- Dividend -
+ @if (dividendInBaseCurrency && user?.settings?.isExperimentalFeatures) { +
+ Dividend +
+
+ Dividend Yield +
+ }
+ @if (user?.settings?.isExperimentalFeatures) { +
+ }
Asset Class Date: Wed, 3 Apr 2024 19:24:38 +0100 Subject: [PATCH 095/203] Feature/add support to override asset (sub) class and url in admin control panel (#3218) * Add support to override asset (sub) class and url in admin control panel * Update changelog --- CHANGELOG.md | 3 +++ apps/api/src/app/admin/admin.service.ts | 23 +++++++++++-------- .../src/app/admin/update-asset-profile.dto.ts | 10 +++++++- .../symbol-profile/symbol-profile.service.ts | 6 +++-- .../asset-profile-dialog.component.ts | 9 +++++--- .../asset-profile-dialog.html | 10 ++++++-- apps/client/src/app/services/admin.service.ts | 6 +++-- 7 files changed, 47 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6513785b..f2b8c35b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added the dividend yield to the position detail dialog (experimental) +- Added support to override the asset class of an asset profile in the asset profile details dialog of the admin control +- Added support to override the asset sub class of an asset profile in the asset profile details dialog of the admin control +- Added support to override the url of an asset profile in the asset profile details dialog of the admin control ## 2.70.0 - 2024-04-02 diff --git a/apps/api/src/app/admin/admin.service.ts b/apps/api/src/app/admin/admin.service.ts index e8a2432e8..2aac43a18 100644 --- a/apps/api/src/app/admin/admin.service.ts +++ b/apps/api/src/app/admin/admin.service.ts @@ -25,6 +25,7 @@ import { MarketDataPreset } from '@ghostfolio/common/types'; import { BadRequestException, Injectable } from '@nestjs/common'; import { + AssetClass, AssetSubClass, DataSource, Prisma, @@ -332,12 +333,18 @@ export class AdminService { scraperConfiguration, sectors, symbol, - symbolMapping + symbolMapping, + url }: Prisma.SymbolProfileUpdateInput & UniqueAsset) { + const symbolProfileOverrides = { + assetClass: assetClass as AssetClass, + assetSubClass: assetSubClass as AssetSubClass, + name: name as string, + url: url as string + }; + const updatedSymbolProfile: Prisma.SymbolProfileUpdateInput & UniqueAsset = { - assetClass, - assetSubClass, comment, countries, currency, @@ -347,16 +354,12 @@ export class AdminService { symbol, symbolMapping, ...(dataSource === 'MANUAL' - ? { name } + ? { assetClass, assetSubClass, name, url } : { SymbolProfileOverrides: { upsert: { - create: { - name: name as string - }, - update: { - name: name as string - } + create: symbolProfileOverrides, + update: symbolProfileOverrides } } }) diff --git a/apps/api/src/app/admin/update-asset-profile.dto.ts b/apps/api/src/app/admin/update-asset-profile.dto.ts index 4a0457194..e3de3cab1 100644 --- a/apps/api/src/app/admin/update-asset-profile.dto.ts +++ b/apps/api/src/app/admin/update-asset-profile.dto.ts @@ -5,7 +5,8 @@ import { IsISO4217CurrencyCode, IsObject, IsOptional, - IsString + IsString, + IsUrl } from 'class-validator'; export class UpdateAssetProfileDto { @@ -46,4 +47,11 @@ export class UpdateAssetProfileDto { symbolMapping?: { [dataProvider: string]: string; }; + + @IsOptional() + @IsUrl({ + protocols: ['https'], + require_protocol: true + }) + url?: string; } diff --git a/apps/api/src/services/symbol-profile/symbol-profile.service.ts b/apps/api/src/services/symbol-profile/symbol-profile.service.ts index 656b7b7e4..915b2f716 100644 --- a/apps/api/src/services/symbol-profile/symbol-profile.service.ts +++ b/apps/api/src/services/symbol-profile/symbol-profile.service.ts @@ -98,7 +98,8 @@ export class SymbolProfileService { sectors, symbol, symbolMapping, - SymbolProfileOverrides + SymbolProfileOverrides, + url }: Prisma.SymbolProfileUpdateInput & UniqueAsset) { return this.prismaService.symbolProfile.update({ data: { @@ -111,7 +112,8 @@ export class SymbolProfileService { scraperConfiguration, sectors, symbolMapping, - SymbolProfileOverrides + SymbolProfileOverrides, + url }, where: { dataSource_symbol: { dataSource, symbol } } }); diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts index 352e709bd..2f0c2546b 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts @@ -64,7 +64,8 @@ export class AssetProfileDialog implements OnDestroy, OnInit { name: ['', Validators.required], scraperConfiguration: '', sectors: '', - symbolMapping: '' + symbolMapping: '', + url: '' }); public assetProfileSubClass: string; public benchmarks: Partial[]; @@ -163,7 +164,8 @@ export class AssetProfileDialog implements OnDestroy, OnInit { this.assetProfile?.scraperConfiguration ?? {} ), sectors: JSON.stringify(this.assetProfile?.sectors ?? []), - symbolMapping: JSON.stringify(this.assetProfile?.symbolMapping ?? {}) + symbolMapping: JSON.stringify(this.assetProfile?.symbolMapping ?? {}), + url: this.assetProfile?.url ?? '' }); this.assetProfileForm.markAsPristine(); @@ -293,7 +295,8 @@ export class AssetProfileDialog implements OnDestroy, OnInit { currency: (( (this.assetProfileForm.controls['currency'].value) ))?.value, - name: this.assetProfileForm.controls['name'].value + name: this.assetProfileForm.controls['name'].value, + url: this.assetProfileForm.controls['url'].value }; this.adminService diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html index 93240ba3a..bc6327f0e 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -224,7 +224,7 @@ />
-
+
Asset Class @@ -237,7 +237,7 @@
-
+
Asset Sub Class @@ -330,6 +330,12 @@
+ + Url + + +
+
Note
-
- - Scraper Configuration -
+ @if (assetProfile?.dataSource === 'MANUAL') { +
+ + Scraper Configuration +
+ + +
+
+
+
+ + Sectors - -
- -
-
- - Sectors - - -
-
- - Countries - - -
+
+
+
+ + Countries + + +
+ }
Url + @if (assetProfileForm.controls['url'].value) { + + }
diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts index 846b5e599..76266205f 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts @@ -1,5 +1,6 @@ import { GfAdminMarketDataDetailModule } from '@ghostfolio/client/components/admin-market-data-detail/admin-market-data-detail.module'; import { AdminMarketDataService } from '@ghostfolio/client/components/admin-market-data/admin-market-data.service'; +import { GfSymbolIconModule } from '@ghostfolio/client/components/symbol-icon/symbol-icon.module'; import { GfCurrencySelectorModule } from '@ghostfolio/ui/currency-selector/currency-selector.module'; import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart/portfolio-proportion-chart.module'; import { GfValueModule } from '@ghostfolio/ui/value'; @@ -26,6 +27,7 @@ import { AssetProfileDialog } from './asset-profile-dialog.component'; GfAdminMarketDataDetailModule, GfCurrencySelectorModule, GfPortfolioProportionChartModule, + GfSymbolIconModule, GfValueModule, MatButtonModule, MatCheckboxModule, diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/interfaces/interfaces.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/interfaces/interfaces.ts index c230a39ee..6a966b427 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/interfaces/interfaces.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/interfaces/interfaces.ts @@ -1,6 +1,9 @@ +import { ColorScheme } from '@ghostfolio/common/types'; + import { DataSource } from '@prisma/client'; export interface AssetProfileDialogParams { + colorScheme: ColorScheme; dataSource: DataSource; deviceType: string; locale: string; From c6641fde36bc9f7809bbaff8059e1496fd229aae Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 6 Apr 2024 09:11:15 +0200 Subject: [PATCH 100/203] Feature/add icon to create or update platform dialog (#3241) * Add platform icon * Update changelog --- CHANGELOG.md | 1 + .../create-or-update-platform-dialog.html | 3 +++ .../create-or-update-platform-dialog.module.ts | 3 +++ 3 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c536d4106..c20da8462 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added support to override the asset sub class of an asset profile in the asset profile details dialog of the admin control - Added support to override the url of an asset profile in the asset profile details dialog of the admin control - Added the asset profile icon to the asset profile details dialog of the admin control +- Added the platform icon to the create or update platform dialog of the admin control - Extended the content of the _Self-Hosting_ section by the data providers on the Frequently Asked Questions (FAQ) page ### Changed diff --git a/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html b/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html index 06f6ab72e..780308130 100644 --- a/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html +++ b/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html @@ -12,6 +12,9 @@ Url + @if (data.platform.url) { + + }
diff --git a/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.module.ts b/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.module.ts index bf576480a..1b7c0bd8f 100644 --- a/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.module.ts +++ b/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.module.ts @@ -1,3 +1,5 @@ +import { GfSymbolIconModule } from '@ghostfolio/client/components/symbol-icon/symbol-icon.module'; + import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; @@ -12,6 +14,7 @@ import { CreateOrUpdatePlatformDialog } from './create-or-update-platform-dialog declarations: [CreateOrUpdatePlatformDialog], imports: [ CommonModule, + GfSymbolIconModule, FormsModule, MatButtonModule, MatDialogModule, From 6152ff4b4474f26bb7f4c2b032a17989ff6414c6 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 6 Apr 2024 12:50:35 +0200 Subject: [PATCH 101/203] Remove condition (#3242) --- .../position-detail-dialog/position-detail-dialog.html | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html index 3680f5701..537fe104d 100644 --- a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html +++ b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -191,9 +191,7 @@ }
- @if (user?.settings?.isExperimentalFeatures) { -
- } +
Asset Class Date: Sat, 6 Apr 2024 20:00:56 +0200 Subject: [PATCH 102/203] Feature/add quotes in README.md for API auth documentation (#3246) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 36a4eb818..234e2c941 100644 --- a/README.md +++ b/README.md @@ -206,7 +206,7 @@ Set the header for each request as follows: "Authorization": "Bearer eyJh..." ``` -You can get the _Bearer Token_ via `POST http://localhost:3333/api/v1/auth/anonymous` (Body: `{ accessToken: }`) +You can get the _Bearer Token_ via `POST http://localhost:3333/api/v1/auth/anonymous` (Body: `{ "accessToken": "" }`) Deprecated: `GET http://localhost:3333/api/v1/auth/anonymous/` or `curl -s http://localhost:3333/api/v1/auth/anonymous/`. From ca2e748c56581f4d2bd3fb0588b0d5554506c50e Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 6 Apr 2024 20:03:16 +0200 Subject: [PATCH 103/203] Bugfix/add missing tags in portfolio calculator (#3243) * Add missing tags * Update changelog --- CHANGELOG.md | 4 ++++ .../portfolio/calculator/portfolio-calculator.ts | 14 ++++++++++---- ...tor-baln-buy-and-sell-in-two-activities.spec.ts | 1 + .../portfolio-calculator-baln-buy-and-sell.spec.ts | 1 + .../twr/portfolio-calculator-baln-buy.spec.ts | 1 + ...alculator-btcusd-buy-and-sell-partially.spec.ts | 2 +- .../twr/portfolio-calculator-googl-buy.spec.ts | 2 +- ...folio-calculator-msft-buy-with-dividend.spec.ts | 2 +- ...-calculator-novn-buy-and-sell-partially.spec.ts | 1 + .../portfolio-calculator-novn-buy-and-sell.spec.ts | 1 + apps/api/src/app/portfolio/portfolio.service.ts | 14 ++++---------- 11 files changed, 26 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c20da8462..bf0eeb0fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Improved the url validation in the create and update platform endpoint - Improved the language localization for German (`de`) +### Fixed + +- Fixed the missing tags in the portfolio calculations + ## 2.70.0 - 2024-04-02 ### Added diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index 48fcaf343..488f9ce99 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -29,7 +29,7 @@ import { max, subDays } from 'date-fns'; -import { last, uniq } from 'lodash'; +import { last, uniq, uniqBy } from 'lodash'; export abstract class PortfolioCalculator { protected static readonly ENABLE_LOGGING = false; @@ -57,9 +57,10 @@ export abstract class PortfolioCalculator { this.currentRateService = currentRateService; this.exchangeRateDataService = exchangeRateDataService; this.orders = activities.map( - ({ date, fee, quantity, SymbolProfile, type, unitPrice }) => { + ({ date, fee, quantity, SymbolProfile, tags = [], type, unitPrice }) => { return { SymbolProfile, + tags, type, date: format(date, DATE_FORMAT), fee: new Big(fee), @@ -711,17 +712,17 @@ export abstract class PortfolioCalculator { currentTransactionPointItem = { investment, - tags, averagePrice: newQuantity.gt(0) ? investment.div(newQuantity) : new Big(0), currency: SymbolProfile.currency, dataSource: SymbolProfile.dataSource, dividend: new Big(0), - fee: fee.plus(oldAccumulatedSymbol.fee), + fee: oldAccumulatedSymbol.fee.plus(fee), firstBuyDate: oldAccumulatedSymbol.firstBuyDate, quantity: newQuantity, symbol: SymbolProfile.symbol, + tags: oldAccumulatedSymbol.tags.concat(tags), transactionCount: oldAccumulatedSymbol.transactionCount + 1 }; } else { @@ -740,6 +741,11 @@ export abstract class PortfolioCalculator { }; } + currentTransactionPointItem.tags = uniqBy( + currentTransactionPointItem.tags, + 'id' + ); + symbols[SymbolProfile.symbol] = currentTransactionPointItem; const items = lastTransactionPoint?.items ?? []; diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts index ee71a1fb3..b936d21a9 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts @@ -164,6 +164,7 @@ describe('PortfolioCalculator', () => { marketPriceInBaseCurrency: 148.9, quantity: new Big('0'), symbol: 'BALN.SW', + tags: [], timeWeightedInvestment: new Big('285.80000000000000396627'), timeWeightedInvestmentWithCurrencyEffect: new Big( '285.80000000000000396627' diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts index 69078be7c..d1557bc12 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts @@ -149,6 +149,7 @@ describe('PortfolioCalculator', () => { marketPriceInBaseCurrency: 148.9, quantity: new Big('0'), symbol: 'BALN.SW', + tags: [], timeWeightedInvestment: new Big('285.8'), timeWeightedInvestmentWithCurrencyEffect: new Big('285.8'), transactionCount: 2, diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts index b52aac68d..593503493 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts @@ -134,6 +134,7 @@ describe('PortfolioCalculator', () => { marketPriceInBaseCurrency: 148.9, quantity: new Big('2'), symbol: 'BALN.SW', + tags: [], timeWeightedInvestment: new Big('273.2'), timeWeightedInvestmentWithCurrencyEffect: new Big('273.2'), transactionCount: 1, diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts index 420ba48f1..e3f351b28 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts @@ -166,7 +166,7 @@ describe('PortfolioCalculator', () => { ), quantity: new Big('1'), symbol: 'BTCUSD', - tags: undefined, + tags: [], timeWeightedInvestment: new Big('640.56763686131386861314'), timeWeightedInvestmentWithCurrencyEffect: new Big( '636.79469348020066587024' diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts index 5f33d771b..e7796b4d3 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts @@ -147,7 +147,7 @@ describe('PortfolioCalculator', () => { marketPriceInBaseCurrency: 103.10483, quantity: new Big('1'), symbol: 'GOOGL', - tags: undefined, + tags: [], timeWeightedInvestment: new Big('89.12'), timeWeightedInvestmentWithCurrencyEffect: new Big('82.329056'), transactionCount: 1, diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts index a2c106784..49a07e73f 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts @@ -126,7 +126,7 @@ describe('PortfolioCalculator', () => { marketPriceInBaseCurrency: 331.83, quantity: new Big('1'), symbol: 'MSFT', - tags: undefined, + tags: [], transactionCount: 2 } ], diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts index 21e0bb499..2bfd6d865 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts @@ -148,6 +148,7 @@ describe('PortfolioCalculator', () => { marketPriceInBaseCurrency: 87.8, quantity: new Big('1'), symbol: 'NOVN.SW', + tags: [], timeWeightedInvestment: new Big('145.10285714285714285714'), timeWeightedInvestmentWithCurrencyEffect: new Big( '145.10285714285714285714' diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts index 28920ece7..be3f75dc2 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts @@ -175,6 +175,7 @@ describe('PortfolioCalculator', () => { marketPriceInBaseCurrency: 87.8, quantity: new Big('0'), symbol: 'NOVN.SW', + tags: [], timeWeightedInvestment: new Big('151.6'), timeWeightedInvestmentWithCurrencyEffect: new Big('151.6'), transactionCount: 2, diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 3b8a42d89..fc13ea8e6 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -63,8 +63,7 @@ import { DataSource, Order, Platform, - Prisma, - Tag + Prisma } from '@prisma/client'; import { Big } from 'big.js'; import { isUUID } from 'class-validator'; @@ -701,11 +700,8 @@ export class PortfolioService { ); }); - let tags: Tag[] = []; - if (orders.length <= 0) { return { - tags, accounts: [], averagePrice: undefined, dataProviderInfo: undefined, @@ -730,6 +726,7 @@ export class PortfolioService { orders: [], quantity: undefined, SymbolProfile: undefined, + tags: [], transactionCount: undefined, value: undefined }; @@ -741,16 +738,12 @@ export class PortfolioService { const portfolioCalculator = this.calculatorFactory.createCalculator({ activities: orders.filter((order) => { - tags = tags.concat(order.tags); - return ['BUY', 'DIVIDEND', 'ITEM', 'SELL'].includes(order.type); }), calculationType: PerformanceCalculationType.TWR, currency: userCurrency }); - tags = uniqBy(tags, 'id'); - const portfolioStart = portfolioCalculator.getStartDate(); const transactionPoints = portfolioCalculator.getTransactionPoints(); @@ -771,6 +764,7 @@ export class PortfolioService { firstBuyDate, marketPrice, quantity, + tags, timeWeightedInvestment, timeWeightedInvestmentWithCurrencyEffect, transactionCount @@ -947,7 +941,6 @@ export class PortfolioService { minPrice, orders, SymbolProfile, - tags, accounts: [], averagePrice: 0, dataProviderInfo: undefined, @@ -967,6 +960,7 @@ export class PortfolioService { netPerformancePercentWithCurrencyEffect: undefined, netPerformanceWithCurrencyEffect: undefined, quantity: 0, + tags: [], transactionCount: undefined, value: 0 }; From 50dbbf056953222c10c9f733b3e2ee746ade51bb Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 6 Apr 2024 21:15:19 +0200 Subject: [PATCH 104/203] Feature/refactor symbol icon module to asset profile icon component (#3245) * Refactor symbol icon module to asset profile icon component (standalone) --- .../accounts-table/accounts-table.component.html | 4 ++-- .../accounts-table/accounts-table.module.ts | 4 ++-- .../asset-profile-dialog/asset-profile-dialog.html | 2 +- .../asset-profile-dialog.module.ts | 4 ++-- .../admin-platform/admin-platform.component.html | 2 +- .../admin-platform/admin-platform.module.ts | 4 ++-- .../create-or-update-platform-dialog.html | 6 +++++- .../create-or-update-platform-dialog.module.ts | 4 ++-- .../asset-profile-icon.component.html | 8 ++++++++ .../asset-profile-icon.component.scss} | 0 .../asset-profile-icon.component.ts} | 13 +++++++++---- .../symbol-icon/symbol-icon.component.html | 7 ------- .../components/symbol-icon/symbol-icon.module.ts | 12 ------------ .../create-or-update-account-dialog.html | 2 +- .../create-or-update-account-dialog.module.ts | 4 ++-- .../transfer-balance/transfer-balance-dialog.html | 4 ++-- .../transfer-balance-dialog.module.ts | 4 ++-- .../create-or-update-activity-dialog.html | 2 +- .../create-or-update-activity-dialog.module.ts | 4 ++-- .../activities-table.component.html | 4 ++-- .../lib/activities-table/activities-table.module.ts | 4 ++-- libs/ui/src/lib/assistant/assistant.html | 2 +- libs/ui/src/lib/assistant/assistant.module.ts | 4 ++-- .../holdings-table/holdings-table.component.html | 2 +- .../src/lib/holdings-table/holdings-table.module.ts | 4 ++-- 25 files changed, 54 insertions(+), 56 deletions(-) create mode 100644 apps/client/src/app/components/asset-profile-icon/asset-profile-icon.component.html rename apps/client/src/app/components/{symbol-icon/symbol-icon.component.scss => asset-profile-icon/asset-profile-icon.component.scss} (100%) rename apps/client/src/app/components/{symbol-icon/symbol-icon.component.ts => asset-profile-icon/asset-profile-icon.component.ts} (63%) delete mode 100644 apps/client/src/app/components/symbol-icon/symbol-icon.component.html delete mode 100644 apps/client/src/app/components/symbol-icon/symbol-icon.module.ts diff --git a/apps/client/src/app/components/accounts-table/accounts-table.component.html b/apps/client/src/app/components/accounts-table/accounts-table.component.html index cd4f139c4..241b5d90a 100644 --- a/apps/client/src/app/components/accounts-table/accounts-table.component.html +++ b/apps/client/src/app/components/accounts-table/accounts-table.component.html @@ -34,7 +34,7 @@ Name -
- Url @if (assetProfileForm.controls['url'].value) { - Name - Url @if (data.platform.url) { - + }
diff --git a/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.module.ts b/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.module.ts index 1b7c0bd8f..ac97e57cf 100644 --- a/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.module.ts +++ b/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.module.ts @@ -1,4 +1,4 @@ -import { GfSymbolIconModule } from '@ghostfolio/client/components/symbol-icon/symbol-icon.module'; +import { GfAssetProfileIconComponent } from '@ghostfolio/client/components/asset-profile-icon/asset-profile-icon.component'; import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; @@ -14,7 +14,7 @@ import { CreateOrUpdatePlatformDialog } from './create-or-update-platform-dialog declarations: [CreateOrUpdatePlatformDialog], imports: [ CommonModule, - GfSymbolIconModule, + GfAssetProfileIconComponent, FormsModule, MatButtonModule, MatDialogModule, diff --git a/apps/client/src/app/components/asset-profile-icon/asset-profile-icon.component.html b/apps/client/src/app/components/asset-profile-icon/asset-profile-icon.component.html new file mode 100644 index 000000000..f0abad285 --- /dev/null +++ b/apps/client/src/app/components/asset-profile-icon/asset-profile-icon.component.html @@ -0,0 +1,8 @@ +@if (src) { + +} diff --git a/apps/client/src/app/components/symbol-icon/symbol-icon.component.scss b/apps/client/src/app/components/asset-profile-icon/asset-profile-icon.component.scss similarity index 100% rename from apps/client/src/app/components/symbol-icon/symbol-icon.component.scss rename to apps/client/src/app/components/asset-profile-icon/asset-profile-icon.component.scss diff --git a/apps/client/src/app/components/symbol-icon/symbol-icon.component.ts b/apps/client/src/app/components/asset-profile-icon/asset-profile-icon.component.ts similarity index 63% rename from apps/client/src/app/components/symbol-icon/symbol-icon.component.ts rename to apps/client/src/app/components/asset-profile-icon/asset-profile-icon.component.ts index a6fa0901a..4d96ef83f 100644 --- a/apps/client/src/app/components/symbol-icon/symbol-icon.component.ts +++ b/apps/client/src/app/components/asset-profile-icon/asset-profile-icon.component.ts @@ -1,4 +1,6 @@ +import { CommonModule } from '@angular/common'; import { + CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, Input, @@ -7,12 +9,15 @@ import { import { DataSource } from '@prisma/client'; @Component({ - selector: 'gf-symbol-icon', changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './symbol-icon.component.html', - styleUrls: ['./symbol-icon.component.scss'] + imports: [CommonModule], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + selector: 'gf-asset-profile-icon', + standalone: true, + styleUrls: ['./asset-profile-icon.component.scss'], + templateUrl: './asset-profile-icon.component.html' }) -export class SymbolIconComponent implements OnChanges { +export class GfAssetProfileIconComponent implements OnChanges { @Input() dataSource: DataSource; @Input() size: 'large'; @Input() symbol: string; diff --git a/apps/client/src/app/components/symbol-icon/symbol-icon.component.html b/apps/client/src/app/components/symbol-icon/symbol-icon.component.html deleted file mode 100644 index 0aebd0e5b..000000000 --- a/apps/client/src/app/components/symbol-icon/symbol-icon.component.html +++ /dev/null @@ -1,7 +0,0 @@ - diff --git a/apps/client/src/app/components/symbol-icon/symbol-icon.module.ts b/apps/client/src/app/components/symbol-icon/symbol-icon.module.ts deleted file mode 100644 index 8eee9ef0c..000000000 --- a/apps/client/src/app/components/symbol-icon/symbol-icon.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; - -import { SymbolIconComponent } from './symbol-icon.component'; - -@NgModule({ - declarations: [SymbolIconComponent], - exports: [SymbolIconComponent], - imports: [CommonModule], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfSymbolIconModule {} diff --git a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html index 9ff61d0c2..e2981462f 100644 --- a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html +++ b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -61,7 +61,7 @@ ) { -
-
-
- -
@if (element.Account?.Platform?.url) { -
- - Date: Sun, 7 Apr 2024 09:25:14 +0200 Subject: [PATCH 105/203] Feature/add key to x ray rule (#3248) * Add key * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/portfolio/rules.service.ts | 12 ++++++++++-- apps/api/src/models/rule.ts | 8 ++++++++ .../rules/account-cluster-risk/current-investment.ts | 1 + .../rules/account-cluster-risk/single-account.ts | 1 + .../base-currency-current-investment.ts | 1 + .../currency-cluster-risk/current-investment.ts | 1 + .../rules/emergency-fund/emergency-fund-setup.ts | 1 + .../rules/fees/fee-ratio-initial-investment.ts | 1 + 9 files changed, 25 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf0eeb0fd..932206f90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added support to override the url of an asset profile in the asset profile details dialog of the admin control - Added the asset profile icon to the asset profile details dialog of the admin control - Added the platform icon to the create or update platform dialog of the admin control +- Extended the rules in the _X-ray_ section by a `key` - Extended the content of the _Self-Hosting_ section by the data providers on the Frequently Asked Questions (FAQ) page ### Changed diff --git a/apps/api/src/app/portfolio/rules.service.ts b/apps/api/src/app/portfolio/rules.service.ts index 7dfcee56a..85f7ed55b 100644 --- a/apps/api/src/app/portfolio/rules.service.ts +++ b/apps/api/src/app/portfolio/rules.service.ts @@ -17,8 +17,16 @@ export class RulesService { return rule.getSettings(aUserSettings)?.isActive; }) .map((rule) => { - const evaluationResult = rule.evaluate(rule.getSettings(aUserSettings)); - return { ...evaluationResult, name: rule.getName() }; + const { evaluation, value } = rule.evaluate( + rule.getSettings(aUserSettings) + ); + + return { + evaluation, + value, + key: rule.getKey(), + name: rule.getName() + }; }); } } diff --git a/apps/api/src/models/rule.ts b/apps/api/src/models/rule.ts index 171da810d..ba37f4e94 100644 --- a/apps/api/src/models/rule.ts +++ b/apps/api/src/models/rule.ts @@ -7,19 +7,27 @@ import { EvaluationResult } from './interfaces/evaluation-result.interface'; import { RuleInterface } from './interfaces/rule.interface'; export abstract class Rule implements RuleInterface { + private key: string; private name: string; public constructor( protected exchangeRateDataService: ExchangeRateDataService, { + key, name }: { + key: string; name: string; } ) { + this.key = key; this.name = name; } + public getKey() { + return this.key; + } + public getName() { return this.name; } diff --git a/apps/api/src/models/rules/account-cluster-risk/current-investment.ts b/apps/api/src/models/rules/account-cluster-risk/current-investment.ts index 52f20a218..a9a60f912 100644 --- a/apps/api/src/models/rules/account-cluster-risk/current-investment.ts +++ b/apps/api/src/models/rules/account-cluster-risk/current-investment.ts @@ -15,6 +15,7 @@ export class AccountClusterRiskCurrentInvestment extends Rule { accounts: PortfolioDetails['accounts'] ) { super(exchangeRateDataService, { + key: AccountClusterRiskCurrentInvestment.name, name: 'Investment' }); diff --git a/apps/api/src/models/rules/account-cluster-risk/single-account.ts b/apps/api/src/models/rules/account-cluster-risk/single-account.ts index b5028228a..a47895c13 100644 --- a/apps/api/src/models/rules/account-cluster-risk/single-account.ts +++ b/apps/api/src/models/rules/account-cluster-risk/single-account.ts @@ -11,6 +11,7 @@ export class AccountClusterRiskSingleAccount extends Rule { accounts: PortfolioDetails['accounts'] ) { super(exchangeRateDataService, { + key: AccountClusterRiskSingleAccount.name, name: 'Single Account' }); diff --git a/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts b/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts index a2bd44f44..39406e6c2 100644 --- a/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts +++ b/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts @@ -11,6 +11,7 @@ export class CurrencyClusterRiskBaseCurrencyCurrentInvestment extends Rule { positions: TimelinePosition[] ) { super(exchangeRateDataService, { + key: CurrencyClusterRiskCurrentInvestment.name, name: 'Investment' }); diff --git a/apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts b/apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts index b6248ab51..20e9502bf 100644 --- a/apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts +++ b/apps/api/src/models/rules/emergency-fund/emergency-fund-setup.ts @@ -11,6 +11,7 @@ export class EmergencyFundSetup extends Rule { emergencyFund: number ) { super(exchangeRateDataService, { + key: EmergencyFundSetup.name, name: 'Emergency Fund: Set up' }); diff --git a/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts b/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts index 0ba70d23c..69db9634d 100644 --- a/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts +++ b/apps/api/src/models/rules/fees/fee-ratio-initial-investment.ts @@ -13,6 +13,7 @@ export class FeeRatioInitialInvestment extends Rule { fees: number ) { super(exchangeRateDataService, { + key: FeeRatioInitialInvestment.name, name: 'Fee Ratio' }); From 719bbe156e081b04d12cc85fce47152d13ca52b2 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 7 Apr 2024 09:26:30 +0200 Subject: [PATCH 106/203] Feature/optimize calculation of allocations by market (#3249) * Optimize calculation of allocations by market * Update changelog --- CHANGELOG.md | 1 + .../src/app/portfolio/portfolio.controller.ts | 5 +- .../src/app/portfolio/portfolio.service.ts | 175 ++++++++++-------- .../allocations/allocations-page.component.ts | 3 +- apps/client/src/app/services/data.service.ts | 8 +- 5 files changed, 113 insertions(+), 79 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 932206f90..19140a7cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Optimized the calculation of allocations by market - Improved the url validation in the create and update platform endpoint - Improved the language localization for German (`de`) diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 6047b7abd..0ae596d84 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -78,9 +78,11 @@ export class PortfolioController { @Query('assetClasses') filterByAssetClasses?: string, @Query('range') dateRange: DateRange = 'max', @Query('tags') filterByTags?: string, - @Query('withLiabilities') withLiabilitiesParam = 'false' + @Query('withLiabilities') withLiabilitiesParam = 'false', + @Query('withMarkets') withMarketsParam = 'false' ): Promise { const withLiabilities = withLiabilitiesParam === 'true'; + const withMarkets = withMarketsParam === 'true'; let hasDetails = true; let hasError = false; @@ -106,6 +108,7 @@ export class PortfolioController { filters, impersonationId, withLiabilities, + withMarkets, userId: this.request.user.id, withSummary: true }); diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index fc13ea8e6..99fb47e2c 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -63,7 +63,8 @@ import { DataSource, Order, Platform, - Prisma + Prisma, + SymbolProfile } from '@prisma/client'; import { Big } from 'big.js'; import { isUUID } from 'class-validator'; @@ -337,6 +338,7 @@ export class PortfolioService { userId, withExcludedAccounts = false, withLiabilities = false, + withMarkets = false, withSummary = false }: { dateRange?: DateRange; @@ -345,6 +347,7 @@ export class PortfolioService { userId: string; withExcludedAccounts?: boolean; withLiabilities?: boolean; + withMarkets?: boolean; withSummary?: boolean; }): Promise { userId = await this.getUserId(impersonationId, userId); @@ -484,77 +487,17 @@ export class PortfolioService { } } - const symbolProfile = symbolProfileMap[symbol]; + const assetProfile = symbolProfileMap[symbol]; const dataProviderResponse = dataProviderResponses[symbol]; - const markets: PortfolioPosition['markets'] = { - [UNKNOWN_KEY]: 0, - developedMarkets: 0, - emergingMarkets: 0, - otherMarkets: 0 - }; - const marketsAdvanced: PortfolioPosition['marketsAdvanced'] = { - [UNKNOWN_KEY]: 0, - asiaPacific: 0, - emergingMarkets: 0, - europe: 0, - japan: 0, - northAmerica: 0, - otherMarkets: 0 - }; - - if (symbolProfile.countries.length > 0) { - for (const country of symbolProfile.countries) { - if (developedMarkets.includes(country.code)) { - markets.developedMarkets = new Big(markets.developedMarkets) - .plus(country.weight) - .toNumber(); - } else if (emergingMarkets.includes(country.code)) { - markets.emergingMarkets = new Big(markets.emergingMarkets) - .plus(country.weight) - .toNumber(); - } else { - markets.otherMarkets = new Big(markets.otherMarkets) - .plus(country.weight) - .toNumber(); - } + let markets: PortfolioPosition['markets']; + let marketsAdvanced: PortfolioPosition['marketsAdvanced']; - if (country.code === 'JP') { - marketsAdvanced.japan = new Big(marketsAdvanced.japan) - .plus(country.weight) - .toNumber(); - } else if (country.code === 'CA' || country.code === 'US') { - marketsAdvanced.northAmerica = new Big(marketsAdvanced.northAmerica) - .plus(country.weight) - .toNumber(); - } else if (asiaPacificMarkets.includes(country.code)) { - marketsAdvanced.asiaPacific = new Big(marketsAdvanced.asiaPacific) - .plus(country.weight) - .toNumber(); - } else if (emergingMarkets.includes(country.code)) { - marketsAdvanced.emergingMarkets = new Big( - marketsAdvanced.emergingMarkets - ) - .plus(country.weight) - .toNumber(); - } else if (europeMarkets.includes(country.code)) { - marketsAdvanced.europe = new Big(marketsAdvanced.europe) - .plus(country.weight) - .toNumber(); - } else { - marketsAdvanced.otherMarkets = new Big(marketsAdvanced.otherMarkets) - .plus(country.weight) - .toNumber(); - } - } - } else { - markets[UNKNOWN_KEY] = new Big(markets[UNKNOWN_KEY]) - .plus(valueInBaseCurrency) - .toNumber(); - - marketsAdvanced[UNKNOWN_KEY] = new Big(marketsAdvanced[UNKNOWN_KEY]) - .plus(valueInBaseCurrency) - .toNumber(); + if (withMarkets) { + ({ markets, marketsAdvanced } = this.getMarkets({ + assetProfile, + valueInBaseCurrency + })); } holdings[symbol] = { @@ -568,10 +511,10 @@ export class PortfolioService { allocationInPercentage: filteredValueInBaseCurrency.eq(0) ? 0 : valueInBaseCurrency.div(filteredValueInBaseCurrency).toNumber(), - assetClass: symbolProfile.assetClass, - assetSubClass: symbolProfile.assetSubClass, - countries: symbolProfile.countries, - dataSource: symbolProfile.dataSource, + assetClass: assetProfile.assetClass, + assetSubClass: assetProfile.assetSubClass, + countries: assetProfile.countries, + dataSource: assetProfile.dataSource, dateOfFirstActivity: parseDate(firstBuyDate), dividend: dividend?.toNumber() ?? 0, grossPerformance: grossPerformance?.toNumber() ?? 0, @@ -582,7 +525,7 @@ export class PortfolioService { grossPerformanceWithCurrencyEffect?.toNumber() ?? 0, investment: investment.toNumber(), marketState: dataProviderResponse?.marketState ?? 'delayed', - name: symbolProfile.name, + name: assetProfile.name, netPerformance: netPerformance?.toNumber() ?? 0, netPerformancePercent: netPerformancePercentage?.toNumber() ?? 0, netPerformancePercentWithCurrencyEffect: @@ -590,8 +533,8 @@ export class PortfolioService { netPerformanceWithCurrencyEffect: netPerformanceWithCurrencyEffect?.toNumber() ?? 0, quantity: quantity.toNumber(), - sectors: symbolProfile.sectors, - url: symbolProfile.url, + sectors: assetProfile.sectors, + url: assetProfile.url, valueInBaseCurrency: valueInBaseCurrency.toNumber() }; } @@ -1630,6 +1573,86 @@ export class PortfolioService { }; } + private getMarkets({ + assetProfile, + valueInBaseCurrency + }: { + assetProfile: EnhancedSymbolProfile; + valueInBaseCurrency: Big; + }) { + const markets = { + [UNKNOWN_KEY]: 0, + developedMarkets: 0, + emergingMarkets: 0, + otherMarkets: 0 + }; + const marketsAdvanced = { + [UNKNOWN_KEY]: 0, + asiaPacific: 0, + emergingMarkets: 0, + europe: 0, + japan: 0, + northAmerica: 0, + otherMarkets: 0 + }; + + if (assetProfile.countries.length > 0) { + for (const country of assetProfile.countries) { + if (developedMarkets.includes(country.code)) { + markets.developedMarkets = new Big(markets.developedMarkets) + .plus(country.weight) + .toNumber(); + } else if (emergingMarkets.includes(country.code)) { + markets.emergingMarkets = new Big(markets.emergingMarkets) + .plus(country.weight) + .toNumber(); + } else { + markets.otherMarkets = new Big(markets.otherMarkets) + .plus(country.weight) + .toNumber(); + } + + if (country.code === 'JP') { + marketsAdvanced.japan = new Big(marketsAdvanced.japan) + .plus(country.weight) + .toNumber(); + } else if (country.code === 'CA' || country.code === 'US') { + marketsAdvanced.northAmerica = new Big(marketsAdvanced.northAmerica) + .plus(country.weight) + .toNumber(); + } else if (asiaPacificMarkets.includes(country.code)) { + marketsAdvanced.asiaPacific = new Big(marketsAdvanced.asiaPacific) + .plus(country.weight) + .toNumber(); + } else if (emergingMarkets.includes(country.code)) { + marketsAdvanced.emergingMarkets = new Big( + marketsAdvanced.emergingMarkets + ) + .plus(country.weight) + .toNumber(); + } else if (europeMarkets.includes(country.code)) { + marketsAdvanced.europe = new Big(marketsAdvanced.europe) + .plus(country.weight) + .toNumber(); + } else { + marketsAdvanced.otherMarkets = new Big(marketsAdvanced.otherMarkets) + .plus(country.weight) + .toNumber(); + } + } + } else { + markets[UNKNOWN_KEY] = new Big(markets[UNKNOWN_KEY]) + .plus(valueInBaseCurrency) + .toNumber(); + + marketsAdvanced[UNKNOWN_KEY] = new Big(marketsAdvanced[UNKNOWN_KEY]) + .plus(valueInBaseCurrency) + .toNumber(); + } + + return { markets, marketsAdvanced }; + } + private getStreaks({ investments, savingsRate diff --git a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts index 67ad82316..0dba81d1e 100644 --- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts +++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts @@ -205,7 +205,8 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { private fetchPortfolioDetails() { return this.dataService.fetchPortfolioDetails({ - filters: this.userService.getFilters() + filters: this.userService.getFilters(), + withMarkets: true }); } diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts index 088512cec..aeeb2f07b 100644 --- a/apps/client/src/app/services/data.service.ts +++ b/apps/client/src/app/services/data.service.ts @@ -411,10 +411,12 @@ export class DataService { public fetchPortfolioDetails({ filters, - withLiabilities = false + withLiabilities = false, + withMarkets = false }: { filters?: Filter[]; withLiabilities?: boolean; + withMarkets?: boolean; } = {}): Observable { let params = this.buildFiltersAsQueryParams({ filters }); @@ -422,6 +424,10 @@ export class DataService { params = params.append('withLiabilities', withLiabilities); } + if (withMarkets) { + params = params.append('withMarkets', withMarkets); + } + return this.http .get('/api/v1/portfolio/details', { params From 07c0e5a612fe569ab0124880eb51e21219f9156e Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 7 Apr 2024 11:30:32 +0200 Subject: [PATCH 107/203] Feature/add currency to order database schema (#3251) * Add currency to Order database schema * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/import/import.service.ts | 14 +++--- apps/api/src/app/order/create-order.dto.ts | 4 ++ apps/api/src/app/order/order.controller.ts | 19 +++++++- apps/api/src/app/order/order.service.ts | 8 +--- apps/api/src/app/order/update-order.dto.ts | 4 ++ .../portfolio-calculator-test-utils.ts | 1 + ...ate-or-update-activity-dialog.component.ts | 46 ++++--------------- .../create-or-update-activity-dialog.html | 6 +-- .../migration.sql | 2 + prisma/schema.prisma | 1 + 11 files changed, 51 insertions(+), 55 deletions(-) create mode 100644 prisma/migrations/20240407073037_added_currency_to_order/migration.sql diff --git a/CHANGELOG.md b/CHANGELOG.md index 19140a7cc..7b2f531a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added the asset profile icon to the asset profile details dialog of the admin control - Added the platform icon to the create or update platform dialog of the admin control - Extended the rules in the _X-ray_ section by a `key` +- Added `currency` to the `Order` database schema as a preparation to set a custom currency - Extended the content of the _Self-Hosting_ section by the data providers on the Frequently Asked Questions (FAQ) page ### Changed diff --git a/apps/api/src/app/import/import.service.ts b/apps/api/src/app/import/import.service.ts index f45512318..cbdff87c0 100644 --- a/apps/api/src/app/import/import.service.ts +++ b/apps/api/src/app/import/import.service.ts @@ -112,6 +112,7 @@ export class ImportService { accountId: Account?.id, accountUserId: undefined, comment: undefined, + currency: undefined, createdAt: undefined, fee: 0, feeInBaseCurrency: 0, @@ -261,6 +262,7 @@ export class ImportService { { accountId, comment, + currency, date, error, fee, @@ -285,7 +287,6 @@ export class ImportService { assetSubClass, countries, createdAt, - currency, dataSource, figi, figiComposite, @@ -342,6 +343,7 @@ export class ImportService { if (isDryRun) { order = { comment, + currency, date, fee, quantity, @@ -357,7 +359,6 @@ export class ImportService { assetSubClass, countries, createdAt, - currency, dataSource, figi, figiComposite, @@ -371,6 +372,7 @@ export class ImportService { symbolMapping, updatedAt, url, + currency: assetProfile.currency, comment: assetProfile.comment }, Account: validatedAccount, @@ -394,9 +396,9 @@ export class ImportService { SymbolProfile: { connectOrCreate: { create: { - currency, dataSource, - symbol + symbol, + currency: assetProfile.currency }, where: { dataSource_symbol: { @@ -420,14 +422,14 @@ export class ImportService { value, feeInBaseCurrency: this.exchangeRateDataService.toCurrency( fee, - currency, + assetProfile.currency, userCurrency ), // @ts-ignore SymbolProfile: assetProfile, valueInBaseCurrency: this.exchangeRateDataService.toCurrency( value, - currency, + assetProfile.currency, userCurrency ) }); diff --git a/apps/api/src/app/order/create-order.dto.ts b/apps/api/src/app/order/create-order.dto.ts index aecec842a..6d36f036a 100644 --- a/apps/api/src/app/order/create-order.dto.ts +++ b/apps/api/src/app/order/create-order.dto.ts @@ -42,6 +42,10 @@ export class CreateOrderDto { @IsISO4217CurrencyCode() currency: string; + @IsISO4217CurrencyCode() + @IsOptional() + customCurrency?: string; + @IsOptional() @IsEnum(DataSource, { each: true }) dataSource?: DataSource; diff --git a/apps/api/src/app/order/order.controller.ts b/apps/api/src/app/order/order.controller.ts index 2f9825d6b..c7fec0dac 100644 --- a/apps/api/src/app/order/order.controller.ts +++ b/apps/api/src/app/order/order.controller.ts @@ -126,13 +126,22 @@ export class OrderController { @UseGuards(AuthGuard('jwt'), HasPermissionGuard) @UseInterceptors(TransformDataSourceInRequestInterceptor) public async createOrder(@Body() data: CreateOrderDto): Promise { + const currency = data.currency; + const customCurrency = data.customCurrency; + + if (customCurrency) { + data.currency = customCurrency; + + delete data.customCurrency; + } + const order = await this.orderService.createOrder({ ...data, date: parseISO(data.date), SymbolProfile: { connectOrCreate: { create: { - currency: data.currency, + currency, dataSource: data.dataSource, symbol: data.symbol }, @@ -182,8 +191,16 @@ export class OrderController { const date = parseISO(data.date); const accountId = data.accountId; + const customCurrency = data.customCurrency; + delete data.accountId; + if (customCurrency) { + data.currency = customCurrency; + + delete data.customCurrency; + } + return this.orderService.updateOrder({ data: { ...data, diff --git a/apps/api/src/app/order/order.service.ts b/apps/api/src/app/order/order.service.ts index 126b04a07..20b2d5f15 100644 --- a/apps/api/src/app/order/order.service.ts +++ b/apps/api/src/app/order/order.service.ts @@ -26,6 +26,7 @@ import { endOfToday, isAfter } from 'date-fns'; import { groupBy, uniqBy } from 'lodash'; import { v4 as uuidv4 } from 'uuid'; +import { CreateOrderDto } from './create-order.dto'; import { Activities } from './interfaces/activities.interface'; @Injectable() @@ -65,7 +66,6 @@ export class OrderService { } const accountId = data.accountId; - let currency = data.currency; const tags = data.tags ?? []; const updateAccountBalance = data.updateAccountBalance ?? false; const userId = data.userId; @@ -73,7 +73,6 @@ export class OrderService { if (['FEE', 'INTEREST', 'ITEM', 'LIABILITY'].includes(data.type)) { const assetClass = data.assetClass; const assetSubClass = data.assetSubClass; - currency = data.SymbolProfile.connectOrCreate.create.currency; const dataSource: DataSource = 'MANUAL'; const id = uuidv4(); const name = data.SymbolProfile.connectOrCreate.create.symbol; @@ -81,7 +80,6 @@ export class OrderService { data.id = id; data.SymbolProfile.connectOrCreate.create.assetClass = assetClass; data.SymbolProfile.connectOrCreate.create.assetSubClass = assetSubClass; - data.SymbolProfile.connectOrCreate.create.currency = currency; data.SymbolProfile.connectOrCreate.create.dataSource = dataSource; data.SymbolProfile.connectOrCreate.create.name = name; data.SymbolProfile.connectOrCreate.create.symbol = id; @@ -116,7 +114,6 @@ export class OrderService { delete data.comment; } - delete data.currency; delete data.dataSource; delete data.symbol; delete data.tags; @@ -155,8 +152,8 @@ export class OrderService { await this.accountService.updateAccountBalance({ accountId, amount, - currency, userId, + currency: data.SymbolProfile.connectOrCreate.create.currency, date: data.date as Date }); } @@ -442,7 +439,6 @@ export class OrderService { delete data.assetClass; delete data.assetSubClass; - delete data.currency; delete data.dataSource; delete data.symbol; delete data.tags; diff --git a/apps/api/src/app/order/update-order.dto.ts b/apps/api/src/app/order/update-order.dto.ts index c0a400c57..be3c2b6e5 100644 --- a/apps/api/src/app/order/update-order.dto.ts +++ b/apps/api/src/app/order/update-order.dto.ts @@ -41,6 +41,10 @@ export class UpdateOrderDto { @IsISO4217CurrencyCode() currency: string; + @IsISO4217CurrencyCode() + @IsOptional() + customCurrency?: string; + @IsString() dataSource: DataSource; diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts index 6d1939fcd..504b5b171 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts @@ -3,6 +3,7 @@ export const activityDummyData = { accountUserId: undefined, comment: undefined, createdAt: new Date(), + currency: undefined, feeInBaseCurrency: undefined, id: undefined, isDraft: false, diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts index 4fb8e9d81..21a2ca920 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts @@ -98,10 +98,6 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { this.data.activity?.SymbolProfile?.currency, Validators.required ], - currencyOfFee: [ - this.data.activity?.SymbolProfile?.currency, - Validators.required - ], currencyOfUnitPrice: [ this.data.activity?.SymbolProfile?.currency, Validators.required @@ -149,45 +145,16 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { takeUntil(this.unsubscribeSubject) ) .subscribe(async () => { - let exchangeRateOfFee = 1; let exchangeRateOfUnitPrice = 1; this.activityForm.controls['feeInCustomCurrency'].setErrors(null); this.activityForm.controls['unitPriceInCustomCurrency'].setErrors(null); const currency = this.activityForm.controls['currency'].value; - const currencyOfFee = this.activityForm.controls['currencyOfFee'].value; const currencyOfUnitPrice = this.activityForm.controls['currencyOfUnitPrice'].value; const date = this.activityForm.controls['date'].value; - if (currency && currencyOfFee && currency !== currencyOfFee && date) { - try { - const { marketPrice } = await lastValueFrom( - this.dataService - .fetchExchangeRateForDate({ - date, - symbol: `${currencyOfFee}-${currency}` - }) - .pipe(takeUntil(this.unsubscribeSubject)) - ); - - exchangeRateOfFee = marketPrice; - } catch { - this.activityForm.controls['feeInCustomCurrency'].setErrors({ - invalid: true - }); - } - } - - const feeInCustomCurrency = - this.activityForm.controls['feeInCustomCurrency'].value * - exchangeRateOfFee; - - this.activityForm.controls['fee'].setValue(feeInCustomCurrency, { - emitEvent: false - }); - if ( currency && currencyOfUnitPrice && @@ -212,10 +179,18 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { } } + const feeInCustomCurrency = + this.activityForm.controls['feeInCustomCurrency'].value * + exchangeRateOfUnitPrice; + const unitPriceInCustomCurrency = this.activityForm.controls['unitPriceInCustomCurrency'].value * exchangeRateOfUnitPrice; + this.activityForm.controls['fee'].setValue(feeInCustomCurrency, { + emitEvent: false + }); + this.activityForm.controls['unitPrice'].setValue( unitPriceInCustomCurrency, { @@ -258,7 +233,6 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { })?.currency ?? this.data.user.settings.baseCurrency; this.activityForm.controls['currency'].setValue(currency); - this.activityForm.controls['currencyOfFee'].setValue(currency); this.activityForm.controls['currencyOfUnitPrice'].setValue(currency); if (['FEE', 'INTEREST'].includes(type)) { @@ -328,7 +302,6 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { })?.currency ?? this.data.user.settings.baseCurrency; this.activityForm.controls['currency'].setValue(currency); - this.activityForm.controls['currencyOfFee'].setValue(currency); this.activityForm.controls['currencyOfUnitPrice'].setValue(currency); this.activityForm.controls['dataSource'].removeValidators( @@ -361,7 +334,6 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { })?.currency ?? this.data.user.settings.baseCurrency; this.activityForm.controls['currency'].setValue(currency); - this.activityForm.controls['currencyOfFee'].setValue(currency); this.activityForm.controls['currencyOfUnitPrice'].setValue(currency); this.activityForm.controls['dataSource'].removeValidators( @@ -486,6 +458,7 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { assetSubClass: this.activityForm.controls['assetSubClass'].value, comment: this.activityForm.controls['comment'].value, currency: this.activityForm.controls['currency'].value, + customCurrency: this.activityForm.controls['currencyOfUnitPrice'].value, date: this.activityForm.controls['date'].value, dataSource: this.activityForm.controls['dataSource'].value, fee: this.activityForm.controls['fee'].value, @@ -549,7 +522,6 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { ) .subscribe(({ currency, dataSource, marketPrice }) => { this.activityForm.controls['currency'].setValue(currency); - this.activityForm.controls['currencyOfFee'].setValue(currency); this.activityForm.controls['currencyOfUnitPrice'].setValue(currency); this.activityForm.controls['dataSource'].setValue(dataSource); diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html index 9491a440e..79ea7647a 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html @@ -290,11 +290,7 @@ matTextSuffix [ngClass]="{ 'd-none': !activityForm.controls['currency']?.value }" > - - - {{ currency }} - - + {{ activityForm.controls['currencyOfUnitPrice'].value }}
Date: Sun, 7 Apr 2024 11:32:55 +0200 Subject: [PATCH 108/203] Release 2.71.0 (#3252) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b2f531a3..2e1ab7f1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.71.0 - 2024-04-07 ### Added diff --git a/package.json b/package.json index 5db51af5d..fbb811928 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.70.0", + "version": "2.71.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 71892e67b2aea4db49f69b49aeef186f337c109c Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 7 Apr 2024 20:27:38 +0200 Subject: [PATCH 109/203] Feature/upgrade prisma to version 5.12.1 (#3253) * Upgrade prisma to version 5.12.1 * Update changelog --- CHANGELOG.md | 6 ++++ package.json | 4 +-- yarn.lock | 90 ++++++++++++++++++++++++++-------------------------- 3 files changed, 53 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e1ab7f1d..59c3fe4d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- Upgraded `prisma` from version `5.11.0` to `5.12.1` + ## 2.71.0 - 2024-04-07 ### Added diff --git a/package.json b/package.json index fbb811928..752218436 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "@nestjs/platform-express": "10.1.3", "@nestjs/schedule": "3.0.2", "@nestjs/serve-static": "4.0.0", - "@prisma/client": "5.11.0", + "@prisma/client": "5.12.1", "@simplewebauthn/browser": "9.0.1", "@simplewebauthn/server": "9.0.3", "@stripe/stripe-js": "1.47.0", @@ -125,7 +125,7 @@ "passport": "0.6.0", "passport-google-oauth20": "2.0.0", "passport-jwt": "4.0.0", - "prisma": "5.11.0", + "prisma": "5.12.1", "reflect-metadata": "0.1.13", "rxjs": "7.5.6", "stripe": "11.12.0", diff --git a/yarn.lock b/yarn.lock index ee83c3606..d505b65d0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5357,46 +5357,46 @@ resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.25.tgz#f077fdc0b5d0078d30893396ff4827a13f99e817" integrity sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ== -"@prisma/client@5.11.0": - version "5.11.0" - resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.11.0.tgz#d8e55fab85163415b2245fb408b9106f83c8106d" - integrity sha512-SWshvS5FDXvgJKM/a0y9nDC1rqd7KG0Q6ZVzd+U7ZXK5soe73DJxJJgbNBt2GNXOa+ysWB4suTpdK5zfFPhwiw== - -"@prisma/debug@5.11.0": - version "5.11.0" - resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-5.11.0.tgz#80e3f9d5a8f678c67a8783f7fcdda3cbbb8dd091" - integrity sha512-N6yYr3AbQqaiUg+OgjkdPp3KPW1vMTAgtKX6+BiB/qB2i1TjLYCrweKcUjzOoRM5BriA4idrkTej9A9QqTfl3A== - -"@prisma/engines-version@5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102": - version "5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102" - resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102.tgz#a7aa218b1ebf1077798c931632461aae8ce6a8f7" - integrity sha512-WXCuyoymvrS4zLz4wQagSsc3/nE6CHy8znyiMv8RKazKymOMd5o9FP5RGwGHAtgoxd+aB/BWqxuP/Ckfu7/3MA== - -"@prisma/engines@5.11.0": - version "5.11.0" - resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.11.0.tgz#96e941c5c81ce68f3a8b4c481007d397564c5d4b" - integrity sha512-gbrpQoBTYWXDRqD+iTYMirDlF9MMlQdxskQXbhARhG6A/uFQjB7DZMYocMQLoiZXO/IskfDOZpPoZE8TBQKtEw== - dependencies: - "@prisma/debug" "5.11.0" - "@prisma/engines-version" "5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102" - "@prisma/fetch-engine" "5.11.0" - "@prisma/get-platform" "5.11.0" - -"@prisma/fetch-engine@5.11.0": - version "5.11.0" - resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-5.11.0.tgz#cd7a2fa5b5d89f1da0689e329c56fa69223fba7d" - integrity sha512-994viazmHTJ1ymzvWugXod7dZ42T2ROeFuH6zHPcUfp/69+6cl5r9u3NFb6bW8lLdNjwLYEVPeu3hWzxpZeC0w== - dependencies: - "@prisma/debug" "5.11.0" - "@prisma/engines-version" "5.11.0-15.efd2449663b3d73d637ea1fd226bafbcf45b3102" - "@prisma/get-platform" "5.11.0" - -"@prisma/get-platform@5.11.0": - version "5.11.0" - resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-5.11.0.tgz#19a768127b1712c27f5dec8a0a79a4c9675829eb" - integrity sha512-rxtHpMLxNTHxqWuGOLzR2QOyQi79rK1u1XYAVLZxDGTLz/A+uoDnjz9veBFlicrpWjwuieM4N6jcnjj/DDoidw== - dependencies: - "@prisma/debug" "5.11.0" +"@prisma/client@5.12.1": + version "5.12.1" + resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.12.1.tgz#c26a674fea76754b3a9e8b90a11e617f90212f76" + integrity sha512-6/JnizEdlSBxDIdiLbrBdMW5NqDxOmhXAJaNXiPpgzAPr/nLZResT6MMpbOHLo5yAbQ1Vv5UU8PTPRzb0WIxdA== + +"@prisma/debug@5.12.1": + version "5.12.1" + resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-5.12.1.tgz#007c8ad2e466d565bcd0671b8846c27f8700c722" + integrity sha512-kd/wNsR0klrv79o1ITsbWxYyh4QWuBidvxsXSParPsYSu0ircUmNk3q4ojsgNc3/81b0ozg76iastOG43tbf8A== + +"@prisma/engines-version@5.12.0-21.473ed3124229e22d881cb7addf559799debae1ab": + version "5.12.0-21.473ed3124229e22d881cb7addf559799debae1ab" + resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.12.0-21.473ed3124229e22d881cb7addf559799debae1ab.tgz#c78d099a3fe86d446db7442e64e56987e39e7f32" + integrity sha512-6yvO8s80Tym61aB4QNtYZfWVmE3pwqe807jEtzm8C5VDe7nw8O1FGX3TXUaXmWV0fQTIAfRbeL2Gwrndabp/0g== + +"@prisma/engines@5.12.1": + version "5.12.1" + resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.12.1.tgz#a50649427d627a9af962a188a84c65d61c6e2b3f" + integrity sha512-HQDdglLw2bZR/TXD2Y+YfDMvi5Q8H+acbswqOsWyq9pPjBLYJ6gzM+ptlTU/AV6tl0XSZLU1/7F4qaWa8bqpJA== + dependencies: + "@prisma/debug" "5.12.1" + "@prisma/engines-version" "5.12.0-21.473ed3124229e22d881cb7addf559799debae1ab" + "@prisma/fetch-engine" "5.12.1" + "@prisma/get-platform" "5.12.1" + +"@prisma/fetch-engine@5.12.1": + version "5.12.1" + resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-5.12.1.tgz#c38e9fa17fdc535b4c83cbb7645569ad0a511fa9" + integrity sha512-qSs3KcX1HKcea1A+hlJVK/ljj0PNIUHDxAayGMvgJBqmaN32P9tCidlKz1EGv6WoRFICYnk3Dd/YFLBwnFIozA== + dependencies: + "@prisma/debug" "5.12.1" + "@prisma/engines-version" "5.12.0-21.473ed3124229e22d881cb7addf559799debae1ab" + "@prisma/get-platform" "5.12.1" + +"@prisma/get-platform@5.12.1": + version "5.12.1" + resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-5.12.1.tgz#33f427f6d744dee62a9e06858889691d78b50804" + integrity sha512-pgIR+pSvhYHiUcqXVEZS31NrFOTENC9yFUdEAcx7cdQBoZPmHVjtjN4Ss6NzVDMYPrKJJ51U14EhEoeuBlMioQ== + dependencies: + "@prisma/debug" "5.12.1" "@radix-ui/number@1.0.1": version "1.0.1" @@ -16574,12 +16574,12 @@ pretty-hrtime@^1.0.3: resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A== -prisma@5.11.0: - version "5.11.0" - resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.11.0.tgz#ef3891f79921a2deec6f540eba13a3cc8525f6d2" - integrity sha512-KCLiug2cs0Je7kGkQBN9jDWoZ90ogE/kvZTUTgz2h94FEo8pczCkPH7fPNXkD1sGU7Yh65risGGD1HQ5DF3r3g== +prisma@5.12.1: + version "5.12.1" + resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.12.1.tgz#db4596253bb066afc9f08744642f200a398d8d51" + integrity sha512-SkMnb6wyIxTv9ACqiHBI2u9gD6y98qXRoCoLEnZsF6yee5Qg828G+ARrESN+lQHdw4maSZFFSBPPDpvSiVTo0Q== dependencies: - "@prisma/engines" "5.11.0" + "@prisma/engines" "5.12.1" prismjs@^1.28.0: version "1.29.0" From 3bf7ac76a0dd6589d80859aa4ce7a6669bcea966 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 8 Apr 2024 08:07:00 +0200 Subject: [PATCH 110/203] Feature/upgrade nx to version 18.2.3 (#3256) * Upgrade Nx to version 17.3.3 * Update changelog --- CHANGELOG.md | 2 + package.json | 70 +-- yarn.lock | 1547 +++++++++++++++++++++++++++----------------------- 3 files changed, 865 insertions(+), 754 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59c3fe4d1..9aacb00de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Upgraded `angular` from version `17.2.4` to `17.3.3` +- Upgraded `Nx` from version `18.1.2` to `18.2.3` - Upgraded `prisma` from version `5.11.0` to `5.12.1` ## 2.71.0 - 2024-04-07 diff --git a/package.json b/package.json index 752218436..1f2e7520a 100644 --- a/package.json +++ b/package.json @@ -54,17 +54,17 @@ "workspace-generator": "nx workspace-generator" }, "dependencies": { - "@angular/animations": "17.2.4", - "@angular/cdk": "17.2.2", - "@angular/common": "17.2.4", - "@angular/compiler": "17.2.4", - "@angular/core": "17.2.4", - "@angular/forms": "17.2.4", - "@angular/material": "17.2.2", - "@angular/platform-browser": "17.2.4", - "@angular/platform-browser-dynamic": "17.2.4", - "@angular/router": "17.2.4", - "@angular/service-worker": "17.2.4", + "@angular/animations": "17.3.3", + "@angular/cdk": "17.3.3", + "@angular/common": "17.3.3", + "@angular/compiler": "17.3.3", + "@angular/core": "17.3.3", + "@angular/forms": "17.3.3", + "@angular/material": "17.3.3", + "@angular/platform-browser": "17.3.3", + "@angular/platform-browser-dynamic": "17.3.3", + "@angular/router": "17.3.3", + "@angular/service-worker": "17.3.3", "@codewithdan/observable-store": "2.2.15", "@dfinity/agent": "0.15.7", "@dfinity/auth-client": "0.15.7", @@ -136,30 +136,30 @@ "zone.js": "0.14.4" }, "devDependencies": { - "@angular-devkit/build-angular": "17.2.3", - "@angular-devkit/core": "17.2.3", - "@angular-devkit/schematics": "17.2.3", - "@angular-eslint/eslint-plugin": "17.2.1", - "@angular-eslint/eslint-plugin-template": "17.2.1", - "@angular-eslint/template-parser": "17.2.1", - "@angular/cli": "17.2.3", - "@angular/compiler-cli": "17.2.4", - "@angular/language-service": "17.2.4", - "@angular/localize": "17.2.4", - "@angular/pwa": "17.2.3", + "@angular-devkit/build-angular": "17.3.3", + "@angular-devkit/core": "17.3.3", + "@angular-devkit/schematics": "17.3.3", + "@angular-eslint/eslint-plugin": "17.3.0", + "@angular-eslint/eslint-plugin-template": "17.3.0", + "@angular-eslint/template-parser": "17.3.0", + "@angular/cli": "17.3.3", + "@angular/compiler-cli": "17.3.3", + "@angular/language-service": "17.3.3", + "@angular/localize": "17.3.3", + "@angular/pwa": "17.3.3", "@nestjs/schematics": "10.0.1", "@nestjs/testing": "10.1.3", - "@nx/angular": "18.1.2", - "@nx/cypress": "18.1.2", - "@nx/eslint-plugin": "18.1.2", - "@nx/jest": "18.1.2", - "@nx/js": "18.1.2", - "@nx/nest": "18.1.2", - "@nx/node": "18.1.2", - "@nx/storybook": "18.1.2", - "@nx/web": "18.1.2", - "@nx/workspace": "18.1.2", - "@schematics/angular": "17.2.3", + "@nx/angular": "18.2.3", + "@nx/cypress": "18.2.3", + "@nx/eslint-plugin": "18.2.3", + "@nx/jest": "18.2.3", + "@nx/js": "18.2.3", + "@nx/nest": "18.2.3", + "@nx/node": "18.2.3", + "@nx/storybook": "18.2.3", + "@nx/web": "18.2.3", + "@nx/workspace": "18.2.3", + "@schematics/angular": "17.3.3", "@simplewebauthn/types": "9.0.1", "@storybook/addon-essentials": "7.6.5", "@storybook/angular": "7.6.5", @@ -187,7 +187,7 @@ "jest": "29.4.3", "jest-environment-jsdom": "29.4.3", "jest-preset-angular": "14.0.3", - "nx": "18.1.2", + "nx": "18.2.3", "prettier": "3.2.5", "prettier-plugin-organize-attributes": "1.0.0", "react": "18.2.0", @@ -198,7 +198,7 @@ "ts-jest": "29.1.0", "ts-node": "10.9.1", "tslib": "2.6.0", - "typescript": "5.3.3", + "typescript": "5.4.4", "webpack-bundle-analyzer": "4.10.1" }, "engines": { diff --git a/yarn.lock b/yarn.lock index d505b65d0..9c77b9917 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12,7 +12,15 @@ resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.1.tgz#abfccb8ca78075a2b6187345c26243c1a0842f28" integrity sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg== -"@ampproject/remapping@2.2.1", "@ampproject/remapping@^2.2.0": +"@ampproject/remapping@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" + integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + +"@ampproject/remapping@^2.2.0": version "2.2.1" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== @@ -20,12 +28,12 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@angular-devkit/architect@0.1702.3": - version "0.1702.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1702.3.tgz#4bdd844f55c94dc6b3153bb693b6b1c5621d3ae2" - integrity sha512-4jeBgtBIZxAeJyiwSdbRE4+rWu34j0UMCKia8s7473rKj0Tn4+dXlHmA/kuFYIp6K/9pE/hBoeUFxLNA/DZuRQ== +"@angular-devkit/architect@0.1703.3": + version "0.1703.3" + resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1703.3.tgz#d60cdc2d2ad3b204d8b353124a8defa92c40db69" + integrity sha512-BKbdigCjmspqxOxSIQuWgPZzpyuKqZoTBDh0jDeLcAmvPsuxCgIWbsExI4OQ0CyusnQ+XT0IT39q8B9rvF56cg== dependencies: - "@angular-devkit/core" "17.2.3" + "@angular-devkit/core" "17.3.3" rxjs "7.8.1" "@angular-devkit/architect@^0.1301.0 || ^0.1401.0 || ^0.1501.0 || ^0.1601.0 || ^0.1700.0": @@ -36,83 +44,83 @@ "@angular-devkit/core" "17.0.0" rxjs "7.8.1" -"@angular-devkit/build-angular@17.2.3": - version "17.2.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-17.2.3.tgz#0ff93a434fc1f31d065943688b5c9559bdfc1593" - integrity sha512-AZsEHZj+k2Lxb7uQUwfEpSE6TvQhCoIgP6XLKgKxZHUOiTUVXDj84WhNcbup5SsSG1cafmoVN7APxxuSwHcoeg== +"@angular-devkit/build-angular@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-17.3.3.tgz#94b610596300a8acba22f5c30dcb03220cbd96da" + integrity sha512-E/6Z1MIMhEB1I2sN+Pw4/zinwAFj4vLDh6dEuj856WWEPndgPiUB6fGX4EbCTsyIUzboXI5ysdNyt2Eq56bllA== dependencies: - "@ampproject/remapping" "2.2.1" - "@angular-devkit/architect" "0.1702.3" - "@angular-devkit/build-webpack" "0.1702.3" - "@angular-devkit/core" "17.2.3" - "@babel/core" "7.23.9" + "@ampproject/remapping" "2.3.0" + "@angular-devkit/architect" "0.1703.3" + "@angular-devkit/build-webpack" "0.1703.3" + "@angular-devkit/core" "17.3.3" + "@babel/core" "7.24.0" "@babel/generator" "7.23.6" "@babel/helper-annotate-as-pure" "7.22.5" "@babel/helper-split-export-declaration" "7.22.6" "@babel/plugin-transform-async-generator-functions" "7.23.9" "@babel/plugin-transform-async-to-generator" "7.23.3" - "@babel/plugin-transform-runtime" "7.23.9" - "@babel/preset-env" "7.23.9" - "@babel/runtime" "7.23.9" + "@babel/plugin-transform-runtime" "7.24.0" + "@babel/preset-env" "7.24.0" + "@babel/runtime" "7.24.0" "@discoveryjs/json-ext" "0.5.7" - "@ngtools/webpack" "17.2.3" + "@ngtools/webpack" "17.3.3" "@vitejs/plugin-basic-ssl" "1.1.0" ansi-colors "4.1.3" - autoprefixer "10.4.17" + autoprefixer "10.4.18" babel-loader "9.1.3" babel-plugin-istanbul "6.1.1" browserslist "^4.21.5" copy-webpack-plugin "11.0.0" - critters "0.0.20" + critters "0.0.22" css-loader "6.10.0" - esbuild-wasm "0.20.0" + esbuild-wasm "0.20.1" fast-glob "3.3.2" http-proxy-middleware "2.0.6" - https-proxy-agent "7.0.2" - inquirer "9.2.14" + https-proxy-agent "7.0.4" + inquirer "9.2.15" jsonc-parser "3.2.1" karma-source-map-support "1.4.0" less "4.2.0" less-loader "11.1.0" license-webpack-plugin "4.0.2" loader-utils "3.2.1" - magic-string "0.30.7" - mini-css-extract-plugin "2.8.0" + magic-string "0.30.8" + mini-css-extract-plugin "2.8.1" mrmime "2.0.0" open "8.4.2" ora "5.4.1" parse5-html-rewriting-stream "7.0.0" picomatch "4.0.1" - piscina "4.3.1" + piscina "4.4.0" postcss "8.4.35" - postcss-loader "8.1.0" + postcss-loader "8.1.1" resolve-url-loader "5.0.0" rxjs "7.8.1" - sass "1.70.0" - sass-loader "14.1.0" + sass "1.71.1" + sass-loader "14.1.1" semver "7.6.0" source-map-loader "5.0.0" source-map-support "0.5.21" - terser "5.27.0" + terser "5.29.1" tree-kill "1.2.2" tslib "2.6.2" - undici "6.6.2" - vite "5.0.12" + undici "6.7.1" + vite "5.1.5" watchpack "2.4.0" - webpack "5.90.1" - webpack-dev-middleware "6.1.1" + webpack "5.90.3" + webpack-dev-middleware "6.1.2" webpack-dev-server "4.15.1" webpack-merge "5.10.0" webpack-subresource-integrity "5.1.0" optionalDependencies: - esbuild "0.20.0" + esbuild "0.20.1" -"@angular-devkit/build-webpack@0.1702.3": - version "0.1702.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1702.3.tgz#9054793a57e494f4f80d541611a7c1c63377a24c" - integrity sha512-G9F2Ori8WxJtMvOQGxTdg7d+5aAO1IPeEtMiZwFPrw65Ey6Gvfm0h2+3FnQdzeKrZmGaTk5E6gffHXJJQfCnmQ== +"@angular-devkit/build-webpack@0.1703.3": + version "0.1703.3" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1703.3.tgz#b7fcc2fa2c0c6ba4cc1dcdd8d108c8f536d03a60" + integrity sha512-d0JjE8MaGVNphlJfeP1OZKhNT4wCXkEZKdSdwE0+W+vDHNUuZiUBB1czO48sb7T4xBrdjRWlV/9CzMNJ7n3ydA== dependencies: - "@angular-devkit/architect" "0.1702.3" + "@angular-devkit/architect" "0.1703.3" rxjs "7.8.1" "@angular-devkit/core@16.0.1": @@ -149,10 +157,10 @@ rxjs "7.8.1" source-map "0.7.4" -"@angular-devkit/core@17.2.3": - version "17.2.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-17.2.3.tgz#9e38dc4242212a6b00bf03e518add0f9b75b6e7f" - integrity sha512-A7WWl1/VsZw6utFFPBib1wSbAB5OeBgAgQmVpVe9wW8u9UZa6CLc7b3InWtRRyBXTo9Sa5GNZDFfwlXhy3iW3w== +"@angular-devkit/core@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-17.3.3.tgz#dce2f615355b2ef59c19927d90620670a6c890d0" + integrity sha512-J22Sh3M7rj8Ar3iEs20ko5wgC3DE7vWfYZNdimt2IJiS4J7BEX8R3Awf+TRt+6AN3NFm3/xe1Sz4yvDh3FvNFg== dependencies: ajv "8.12.0" ajv-formats "2.1.1" @@ -194,87 +202,87 @@ ora "5.4.1" rxjs "7.8.1" -"@angular-devkit/schematics@17.2.3": - version "17.2.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-17.2.3.tgz#1e9f803deccdfdd1eeeff36c702d6dadae91227f" - integrity sha512-JZCzHHheotv+iJ4p6qLc3pEi2M8NO12Slo6uiCg2T9B01glAcJB7DA1nwqjwD1cElf24Pt0C+HI0r+Lng48IsQ== +"@angular-devkit/schematics@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-17.3.3.tgz#223d8ffd27e6daaf63a3161dbe8c849860541bf1" + integrity sha512-SABqTtj2im4PJhQjNaAsSypbNkpZFW8YozJ3P748tlh5a9XoHpgiqXv5JhRbyKElLDAyk5i9fe2++JmSudPG/Q== dependencies: - "@angular-devkit/core" "17.2.3" + "@angular-devkit/core" "17.3.3" jsonc-parser "3.2.1" - magic-string "0.30.7" + magic-string "0.30.8" ora "5.4.1" rxjs "7.8.1" -"@angular-eslint/bundled-angular-compiler@17.2.1": - version "17.2.1" - resolved "https://registry.yarnpkg.com/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-17.2.1.tgz#d849b0845371b41856b9f598af81ce5bf799bca0" - integrity sha512-puC0itsZv2QlrDOCcWtq1KZH+DvfrpV+mV78HHhi6+h25R5iIhr8ARKcl3EQxFjvrFq34jhG8pSupxKvFbHVfA== +"@angular-eslint/bundled-angular-compiler@17.3.0": + version "17.3.0" + resolved "https://registry.yarnpkg.com/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-17.3.0.tgz#08b8b1bebbb677a1f208b56516fc9177a289d212" + integrity sha512-ejfNzRuBeHUV8m2fkgs+M809rj5STuCuQo4fdfc6ccQpzXDI6Ha7BKpTznWfg5g529q/wrkoGSGgFxU9Yc2/dQ== -"@angular-eslint/eslint-plugin-template@17.2.1": - version "17.2.1" - resolved "https://registry.yarnpkg.com/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-17.2.1.tgz#226a623219375a2344112c1c896fefef0dae4df6" - integrity sha512-hl1hcHtcm90wyVL1OQGTz16oA0KHon+FFb3Qg0fLXObaXxA495Ecefd9ub5Xxg4JEOPRDi29bF1Y3YKpwflgeg== +"@angular-eslint/eslint-plugin-template@17.3.0": + version "17.3.0" + resolved "https://registry.yarnpkg.com/@angular-eslint/eslint-plugin-template/-/eslint-plugin-template-17.3.0.tgz#712a99503b4ef12e9f37979375539c3ace44375b" + integrity sha512-9l/aRfpE9MCRVDWRb+rSB9Zei0paep1vqV6M/87VUnzBnzqeMRnVuPvQowilh2zweVSGKBF25Vp4HkwOL6ExDQ== dependencies: - "@angular-eslint/bundled-angular-compiler" "17.2.1" - "@angular-eslint/utils" "17.2.1" - "@typescript-eslint/type-utils" "6.19.0" - "@typescript-eslint/utils" "6.19.0" + "@angular-eslint/bundled-angular-compiler" "17.3.0" + "@angular-eslint/utils" "17.3.0" + "@typescript-eslint/type-utils" "7.2.0" + "@typescript-eslint/utils" "7.2.0" aria-query "5.3.0" axobject-query "4.0.0" -"@angular-eslint/eslint-plugin@17.2.1": - version "17.2.1" - resolved "https://registry.yarnpkg.com/@angular-eslint/eslint-plugin/-/eslint-plugin-17.2.1.tgz#2be51ead1785950feb8351001e0683eae42f4c29" - integrity sha512-9yA81BHpsaCUKRBtHGN3ieAy8HpIoffzPQMu34lYqZFT4yGHGhYmhQjNSQGBRbV2LD9dVv2U35rMHNmUcozXpw== +"@angular-eslint/eslint-plugin@17.3.0": + version "17.3.0" + resolved "https://registry.yarnpkg.com/@angular-eslint/eslint-plugin/-/eslint-plugin-17.3.0.tgz#b5037877cdc64d407649247e5ca09851c8674b4e" + integrity sha512-81cQbOEPoQupFX8WmpqZn+y8VA7JdVRGBtt+uJNKBXcJknTpPWdLBZRFlgVakmC24iEZ0Fint/N3NBBQI3mz2A== dependencies: - "@angular-eslint/utils" "17.2.1" - "@typescript-eslint/utils" "6.19.0" + "@angular-eslint/utils" "17.3.0" + "@typescript-eslint/utils" "7.2.0" -"@angular-eslint/template-parser@17.2.1": - version "17.2.1" - resolved "https://registry.yarnpkg.com/@angular-eslint/template-parser/-/template-parser-17.2.1.tgz#005f997346eb17c6dbca5fffc41da51b7e755013" - integrity sha512-WPQYFvRju0tCDXQ/pwrzC911pE07JvpeDgcN2elhzV6lxDHJEZpA5O9pnW9qgNA6J6XM9Q7dBkJ22ztAzC4WFw== +"@angular-eslint/template-parser@17.3.0": + version "17.3.0" + resolved "https://registry.yarnpkg.com/@angular-eslint/template-parser/-/template-parser-17.3.0.tgz#580a703cbaa4967d36a953a00f5c347987c14171" + integrity sha512-m+UzAnWgtjeS0x6skSmR0eXltD/p7HZA+c8pPyAkiHQzkxE7ohhfyZc03yWGuYJvWQUqQAKKdO/nQop14TP0bg== dependencies: - "@angular-eslint/bundled-angular-compiler" "17.2.1" + "@angular-eslint/bundled-angular-compiler" "17.3.0" eslint-scope "^8.0.0" -"@angular-eslint/utils@17.2.1": - version "17.2.1" - resolved "https://registry.yarnpkg.com/@angular-eslint/utils/-/utils-17.2.1.tgz#3d4217775d86479348fdd0e1ad83014c9d8339f2" - integrity sha512-qQYTBXy90dWM7fhhpa5i9lTtqqhJisvRa+naCrQx9kBgR458JScLdkVIdcZ9D/rPiDCmKiVUfgcDISnjUeqTqg== +"@angular-eslint/utils@17.3.0": + version "17.3.0" + resolved "https://registry.yarnpkg.com/@angular-eslint/utils/-/utils-17.3.0.tgz#85915e864c7b7f33df1fdf15f74cc99fd5895e1e" + integrity sha512-PJT9pxWqpvI9OXO+7L5SIVhvMW+RFjeafC7PYjtvSbNFpz+kF644BiAcfMJ0YqBnkrw3JXt+RAX25CT4mXIoXw== dependencies: - "@angular-eslint/bundled-angular-compiler" "17.2.1" - "@typescript-eslint/utils" "6.19.0" + "@angular-eslint/bundled-angular-compiler" "17.3.0" + "@typescript-eslint/utils" "7.2.0" -"@angular/animations@17.2.4": - version "17.2.4" - resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-17.2.4.tgz#d1c7d74b1bc360ba853c299a8db70d1a9517bf1c" - integrity sha512-eTjD8XeioL1Xj+W6iQayOh2JBCfjkg+MG3wzyEW0jhetE/N+wm2xbI1aub2pYplKsu96hOih3lfowYt7qIKGfw== +"@angular/animations@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-17.3.3.tgz#b6487fbaa970cfd1f998d72a61e74c7e3deb14be" + integrity sha512-poLW3FHe5wkxmTIsQ3em2vq4obgQHyZJz6biF+4hCqQSNMbMBS0e5ZycAiJLkUD/WLc88lQZ20muRO7qjVuMLA== dependencies: tslib "^2.3.0" -"@angular/cdk@17.2.2": - version "17.2.2" - resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-17.2.2.tgz#c3f3335209a2099cbc124c2b1e9b1b8d20488647" - integrity sha512-no3FownDI+05SvCGOxduramTJw+V5p/rKebz4msZbsAXXLnOScZPN2rDgMKShl2dQokc6gjsKXsy8fAYpx7NSQ== +"@angular/cdk@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-17.3.3.tgz#a266eb76a91ee2ce8f1e2df4bdc9a40b8dab29eb" + integrity sha512-hfS9pwaNE6CTZqP3FBh9tZPbuf//bDqZ5IpMzscfDFrwX8ycxBiI3znH/rFSf9l1rL0OQGoqWWNVfJCT+RrukA== dependencies: tslib "^2.3.0" optionalDependencies: parse5 "^7.1.2" -"@angular/cli@17.2.3": - version "17.2.3" - resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-17.2.3.tgz#c5e70fcb8f1e4cc15ef5fba04533fbe414e875c1" - integrity sha512-GIF9NF4t8PiHS4wt6baw1hECfmMOmNHvDAuT12/xoAueOairxIQ+AX13WaEHMJriWujm31TjqbwXmhPxMSEQpw== +"@angular/cli@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-17.3.3.tgz#66880fb12b0d4e536222ec7a256431795fe344c9" + integrity sha512-veIGK2sRm0SfiLHeftx0W0xC3N8uxoqxXiSG57V6W2wIFN/fKm3aRq3sa8phz7vxUzoKGqyZh6hsT7ybkjgkGA== dependencies: - "@angular-devkit/architect" "0.1702.3" - "@angular-devkit/core" "17.2.3" - "@angular-devkit/schematics" "17.2.3" - "@schematics/angular" "17.2.3" + "@angular-devkit/architect" "0.1703.3" + "@angular-devkit/core" "17.3.3" + "@angular-devkit/schematics" "17.3.3" + "@schematics/angular" "17.3.3" "@yarnpkg/lockfile" "1.1.0" ansi-colors "4.1.3" - ini "4.1.1" - inquirer "9.2.14" + ini "4.1.2" + inquirer "9.2.15" jsonc-parser "3.2.1" npm-package-arg "11.0.1" npm-pick-manifest "9.0.0" @@ -286,17 +294,17 @@ symbol-observable "4.0.0" yargs "17.7.2" -"@angular/common@17.2.4": - version "17.2.4" - resolved "https://registry.yarnpkg.com/@angular/common/-/common-17.2.4.tgz#d56054b499fc9bbc9350df668111b1680c09b1fa" - integrity sha512-ymzDHZPQWpBKVQ7lPZucU+vBSb70Re6y5TKzkOX7oYE8Z1+tiNGLvfmzGsO2/N0lvwyZWXjkdXYEDON2hIlZ1Q== +"@angular/common@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-17.3.3.tgz#6bbd0c033446010ada04511b6955d048259cf9d7" + integrity sha512-GwlKetNpfWKiG2j4S6bYTi6PA2iT4+eln7o8owo44xZWdQnWQjfxnH39vQuCyhi6OOQL1dozmae+fVXgQsV6jQ== dependencies: tslib "^2.3.0" -"@angular/compiler-cli@17.2.4": - version "17.2.4" - resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-17.2.4.tgz#2aa9366974723a428530fdfd29ecfa5cdfad1839" - integrity sha512-VGQx1YoYuifQZNj2/nGMEyYVYvXSWrt1ZXK43dgxPDH3jCWNncOBUYtmyCmYvxKvDz0aDO3KL8cro8c4+N0pPw== +"@angular/compiler-cli@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-17.3.3.tgz#e2505b95b0d56118ea0950eae18bb0fa2c2e7515" + integrity sha512-vM0lqwuXQZ912HbLnIuvUblvIz2WEUsU7a5Z2ieNey6famH4zxPH12vCbVwXgicB6GLHorhOfcWC5443wD2mJw== dependencies: "@babel/core" "7.23.9" "@jridgewell/sourcemap-codec" "^1.4.14" @@ -307,10 +315,10 @@ tslib "^2.3.0" yargs "^17.2.1" -"@angular/compiler@17.2.4": - version "17.2.4" - resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-17.2.4.tgz#82fb29e80096b1fb3f6fd4d4f2c22fdbc0bb9a9b" - integrity sha512-McSsBcoHhMkaQpHM5/wTosAKTzJY5uE6ji3z+ec5GrIJhV7jrVfa67+RUoUzHe+rlD/7oQbX1L/OaHKDP8+/mA== +"@angular/compiler@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-17.3.3.tgz#ac6aefbb01f031b5834477aff46aa267719f7156" + integrity sha512-ZNMRfagMxMjk1KW5H3ssCg5QL0J6ZW1JAZ1mrTXixqS7gbdwl60bTGE+EfuEwbjvovEYaj4l9cga47eMaxZTbQ== dependencies: tslib "^2.3.0" @@ -319,10 +327,10 @@ resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-9.0.0.tgz#87e0bef4c369b6cadae07e3a4295778fc93799d5" integrity sha512-ctjwuntPfZZT2mNj2NDIVu51t9cvbhl/16epc5xEwyzyDt76pX9UgwvY+MbXrf/C/FWwdtmNtfP698BKI+9leQ== -"@angular/core@17.2.4": - version "17.2.4" - resolved "https://registry.yarnpkg.com/@angular/core/-/core-17.2.4.tgz#46600cbc399e150ed6332db48d8c4b644789169f" - integrity sha512-5Bko+vk7H1Ce57MHuRcpZtq2Srq5euufSvwg0piPozp0yYmCqNoYN7c128kgi6PbiPQeAnKRzRbEuYd1YCU4Tw== +"@angular/core@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-17.3.3.tgz#e0fd86eccd0106a5b8602c56eb4449cbb4538219" + integrity sha512-O/jr3aFJMCxF6Jmymjx4jIigRHJfqM/ALIi60y2LVznBVFkk9xyMTsAjgWQIEHX+2muEIzgfKuXzpL0y30y+wA== dependencies: tslib "^2.3.0" @@ -331,32 +339,32 @@ resolved "https://registry.yarnpkg.com/@angular/core/-/core-9.0.0.tgz#227dc53e1ac81824f998c6e76000b7efc522641e" integrity sha512-6Pxgsrf0qF9iFFqmIcWmjJGkkCaCm6V5QNnxMy2KloO3SDq6QuMVRbN9RtC8Urmo25LP+eZ6ZgYqFYpdD8Hd9w== -"@angular/forms@17.2.4": - version "17.2.4" - resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-17.2.4.tgz#0ec0d0e5e53659162397b631240786c681438234" - integrity sha512-flubCxK6Rc1YmAu23+o+NwqaIWbJ4MIYij05b1GlpRKB5GRX6M0fOl7uRHZmA6dC4xZGt/MUklRqb71T7dJ5JQ== +"@angular/forms@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-17.3.3.tgz#ff00da4f7ab1f6fefda7b3c323ddb07c2a4b23ac" + integrity sha512-wqn+eAggbOZY91hr7oDjv5qdflszVOC9SZMcWJUoZTGn+8eoV6v6728GDFuDDwYkKQ9G9eQbX4IZmYoVw3TVjQ== dependencies: tslib "^2.3.0" -"@angular/language-service@17.2.4": - version "17.2.4" - resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-17.2.4.tgz#1c216681c6ea2a246ff6c09f0f9d05be4889b8ab" - integrity sha512-4F32tJtl9Z8QKe1djkPRj/WY45NKv1bn9aL9Bi9z3T5ZkBCVsdnnXcm4hXnD9gXgWL5RozV2NTbuhGlGx5R0Pg== +"@angular/language-service@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-17.3.3.tgz#99b26aabc10b210e1cedf4b8cca1cac64ccf4183" + integrity sha512-OtdWNY0Syg4UvA8j2IhQJeq/UjWHYbRiyUcZjGKPRzuqIPjUhsmMyuW3zpi7Pwx2CpBzZXcik1Ra2WZ0gbwigg== -"@angular/localize@17.2.4": - version "17.2.4" - resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-17.2.4.tgz#adb03882d1dc0d1bf54c3c04d5be9bc4ddd511a3" - integrity sha512-l6qZzP7f0fH6bCufyrhlUD6n7ggfTEaerIZW/jw0mnXFqVsHVfXX2jWHKljaZJWT3vhDp312i8xAukoAPM0uSQ== +"@angular/localize@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-17.3.3.tgz#3f9c3c66eb02648edc9c8d348124d7170bab1946" + integrity sha512-gahGKy0VBZ+KP6MUULGQMoi5SN3REwslaPvtomizzz9fdmqHfR8PPd1vOJSNm2IEVlvm1hv1dDRjPcR4DJwvaQ== dependencies: "@babel/core" "7.23.9" "@types/babel__core" "7.20.5" fast-glob "3.3.2" yargs "^17.2.1" -"@angular/material@17.2.2": - version "17.2.2" - resolved "https://registry.yarnpkg.com/@angular/material/-/material-17.2.2.tgz#33e3e11183030d9f4c713b56be3cf49fd1df1f0a" - integrity sha512-ToUp8gARTvdze9L7jhEuKqdos221jUCMRD6qzhl07XZRlxVbf/5VXUq2Nn7ei9uN11Ii1UY5pC0GS2XtlyHp4A== +"@angular/material@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular/material/-/material-17.3.3.tgz#33f7ca38d3c0ff909bde4e8ae490ea2da49ecd3f" + integrity sha512-cb3PYY+Lf3FvXxXIRmOBcTn5QS9Ghr5Eq0aiJiiYV6YVohr0YGWsndMCZ/5a2j8fxpboDo9THeTnOuuAOJv7AA== dependencies: "@material/animation" "15.0.0-canary.7f224ddd4.0" "@material/auto-init" "15.0.0-canary.7f224ddd4.0" @@ -407,40 +415,40 @@ "@material/typography" "15.0.0-canary.7f224ddd4.0" tslib "^2.3.0" -"@angular/platform-browser-dynamic@17.2.4": - version "17.2.4" - resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-17.2.4.tgz#c28d405c812d39ce885a4cd65909457741ac062d" - integrity sha512-tNS6WexBbdks4uiB0JfPjUG2/rJ/5wuWr9C11CIgsMo+Onbw49imwDQQTxsx1A3misVb72mUufRza9DcxfSBxg== +"@angular/platform-browser-dynamic@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-17.3.3.tgz#0e747cecb51ebaec53c11ebfef289972b793484d" + integrity sha512-jSgSNHRTXCIat20I+4tLm/e8qOvrIE3Zv7S/DtYZEiAth84uoznvo1kXnN+KREse2vP/WoNgSDKQ2JLzkwYXSQ== dependencies: tslib "^2.3.0" -"@angular/platform-browser@17.2.4": - version "17.2.4" - resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-17.2.4.tgz#06733dbbd49c3b28f77be142dc6b0dbb7be07638" - integrity sha512-A1jkx4ApIx76VDxm8UZLKEq+gwpKZb4qjzCTBDfjOpXB0MJQ5IaYdCrV0E/vPCKZhIfjbEHK+9H1vHRYDCcXtA== +"@angular/platform-browser@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-17.3.3.tgz#b00a68526e2f39e9797ad4696f9dd8b42451f268" + integrity sha512-XFWjquD+Pr9VszRzrDlT6uaf57TsY9XhL9iHCNok6Op5DpVQpIAuw1vFt2t5ZoQ0gv+lY8mVWnxgqe3CgTdYxw== dependencies: tslib "^2.3.0" -"@angular/pwa@17.2.3": - version "17.2.3" - resolved "https://registry.yarnpkg.com/@angular/pwa/-/pwa-17.2.3.tgz#008059b28ae6a7849ad2236259a513ccca155904" - integrity sha512-4fcJgE3Y3g/FQ1czT+HTMYNjXuzTJYGJ1tGP0+++aWdk/IKj+RSGhc31ZjVgjJGk8Rk6inAthNOI8rvByepR5Q== +"@angular/pwa@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular/pwa/-/pwa-17.3.3.tgz#28851976b5763b2e6608dafc6fdd86af1416d42a" + integrity sha512-my2EHZ+ld9L+r2BUfL1Mq9ozUvE+1BY3bav5o4ZkwwtQOZ3XTqYIK2v3Z5O/Mot3XAIAeUR9rksoHGtCZcagMg== dependencies: - "@angular-devkit/schematics" "17.2.3" - "@schematics/angular" "17.2.3" + "@angular-devkit/schematics" "17.3.3" + "@schematics/angular" "17.3.3" parse5-html-rewriting-stream "7.0.0" -"@angular/router@17.2.4": - version "17.2.4" - resolved "https://registry.yarnpkg.com/@angular/router/-/router-17.2.4.tgz#b376d14d2022cdea86172f2013884af5ee7a8f54" - integrity sha512-HnEq6OtyXVJx24Vps0N2GsdvynQ8Mv6twjGmhBlo3x/19ay0WEHdHdsayOSKFvxXg9LCLPnSDYlmpk074IsgqA== +"@angular/router@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-17.3.3.tgz#29859efaeaf9e70ff098011679d1407b68de5997" + integrity sha512-kj42+TtwvET7MFqxB3pkKyob0VNmspASlv8Y29vSpzzaOHn8J1fDf6H+8opoIC+Gmvo5NqXUDwq7nxI5aQ0mUQ== dependencies: tslib "^2.3.0" -"@angular/service-worker@17.2.4": - version "17.2.4" - resolved "https://registry.yarnpkg.com/@angular/service-worker/-/service-worker-17.2.4.tgz#4a247029a5c5390da69d26e421814f83546553aa" - integrity sha512-D9itcdOz8Y4r/WncfmPZlaHHe2kPjMEuSkky36OSvFFP8RXhvuu4iCPYwYvhJYILxKZq++usKZSkPtuETlyKhQ== +"@angular/service-worker@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@angular/service-worker/-/service-worker-17.3.3.tgz#cd8c83793771e93e0a98192428d956d92e9cb487" + integrity sha512-ZS7MPNPdvIoNKuPfK2pukKiyn+OXVMUALBjSH6k2ayiKxhMiNBCybA4KkQf6DZ9NIlKiGoBc46wf7FZybWAYbQ== dependencies: tslib "^2.3.0" @@ -513,6 +521,27 @@ json5 "^2.2.3" semver "^6.3.1" +"@babel/core@7.24.0": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.0.tgz#56cbda6b185ae9d9bed369816a8f4423c5f2ff1b" + integrity sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.24.0" + "@babel/parser" "^7.24.0" + "@babel/template" "^7.24.0" + "@babel/traverse" "^7.24.0" + "@babel/types" "^7.24.0" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.13.16", "@babel/core@^7.20.2": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.2.tgz#ed10df0d580fff67c5f3ee70fd22e2e4c90a9f94" @@ -916,6 +945,15 @@ "@babel/traverse" "^7.24.1" "@babel/types" "^7.24.0" +"@babel/helpers@^7.24.0": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.4.tgz#dc00907fd0d95da74563c142ef4cd21f2cb856b6" + integrity sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw== + dependencies: + "@babel/template" "^7.24.0" + "@babel/traverse" "^7.24.1" + "@babel/types" "^7.24.0" + "@babel/highlight@^7.22.13": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" @@ -1910,6 +1948,16 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-transform-parameters" "^7.23.3" +"@babel/plugin-transform-object-rest-spread@^7.24.0": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz#5a3ce73caf0e7871a02e1c31e8b473093af241ff" + integrity sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA== + dependencies: + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.24.1" + "@babel/plugin-transform-object-super@^7.18.6", "@babel/plugin-transform-object-super@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz#794a8d2fcb5d0835af722173c1a9d704f44e218c" @@ -1974,6 +2022,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" +"@babel/plugin-transform-parameters@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz#983c15d114da190506c75b616ceb0f817afcc510" + integrity sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg== + dependencies: + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-transform-private-methods@^7.22.5": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz#21c8af791f76674420a147ae62e9935d790f8722" @@ -2054,7 +2109,19 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-runtime@7.23.9", "@babel/plugin-transform-runtime@^7.23.2": +"@babel/plugin-transform-runtime@7.24.0": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.0.tgz#e308fe27d08b74027d42547081eefaf4f2ffbcc9" + integrity sha512-zc0GA5IitLKJrSfXlXmp8KDqLrnGECK7YRfQBmEKg1NmBOQ7e+KuclBEKJgzifQeUYLdNiAw4B4bjyvzWVLiSA== + dependencies: + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-plugin-utils" "^7.24.0" + babel-plugin-polyfill-corejs2 "^0.4.8" + babel-plugin-polyfill-corejs3 "^0.9.0" + babel-plugin-polyfill-regenerator "^0.5.5" + semver "^6.3.1" + +"@babel/plugin-transform-runtime@^7.23.2": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.9.tgz#2c64d0680fc8e09e1dfe8fd5c646fe72abd82004" integrity sha512-A7clW3a0aSjm3ONU9o2HAILSegJCYlEZmOhmBRReVtIpY/Z/p7yIZ+wR41Z+UipwdGuqwtID/V/dOdZXjwi9gQ== @@ -2220,14 +2287,14 @@ "@babel/helper-create-regexp-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/preset-env@7.23.9": - version "7.23.9" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.23.9.tgz#beace3b7994560ed6bf78e4ae2073dff45387669" - integrity sha512-3kBGTNBBk9DQiPoXYS0g0BYlwTQYUTifqgKTjxUwEUkduRT2QOa0FPGBJ+NROQhGyYO5BuTJwGvBnqKDykac6A== +"@babel/preset-env@7.24.0": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.24.0.tgz#11536a7f4b977294f0bdfad780f01a8ac8e183fc" + integrity sha512-ZxPEzV9IgvGn73iK0E6VB9/95Nd7aMFpbE0l8KQFDG70cOV9IxRP7Y2FUPmlK0v6ImlLqYX50iuZ3ZTVhOF2lA== dependencies: "@babel/compat-data" "^7.23.5" "@babel/helper-compilation-targets" "^7.23.6" - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/helper-validator-option" "^7.23.5" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.23.3" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.23.3" @@ -2280,7 +2347,7 @@ "@babel/plugin-transform-new-target" "^7.23.3" "@babel/plugin-transform-nullish-coalescing-operator" "^7.23.4" "@babel/plugin-transform-numeric-separator" "^7.23.4" - "@babel/plugin-transform-object-rest-spread" "^7.23.4" + "@babel/plugin-transform-object-rest-spread" "^7.24.0" "@babel/plugin-transform-object-super" "^7.23.3" "@babel/plugin-transform-optional-catch-binding" "^7.23.4" "@babel/plugin-transform-optional-chaining" "^7.23.4" @@ -2636,10 +2703,10 @@ resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@7.23.9": - version "7.23.9" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7" - integrity sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw== +"@babel/runtime@7.24.0": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.0.tgz#584c450063ffda59697021430cb47101b085951e" + integrity sha512-Chk32uHMg6TnQdvw2e9IlqPpFX/6NLuK0Ys2PqLb7/gL5uFn9mXvK715FGLlOLQrcO4qIkNHkvPGktzzXexsFw== dependencies: regenerator-runtime "^0.14.0" @@ -2725,7 +2792,7 @@ debug "^4.3.1" globals "^11.1.0" -"@babel/traverse@^7.24.1": +"@babel/traverse@^7.24.0", "@babel/traverse@^7.24.1": version "7.24.1" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.1.tgz#d65c36ac9dd17282175d1e4a3c49d5b7988f530c" integrity sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ== @@ -2942,10 +3009,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz#d1bc06aedb6936b3b6d313bf809a5a40387d2b7f" integrity sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA== -"@esbuild/aix-ppc64@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.0.tgz#509621cca4e67caf0d18561a0c56f8b70237472f" - integrity sha512-fGFDEctNh0CcSwsiRPxiaqX0P5rq+AqE0SRhYGZ4PX46Lg1FNR6oCxJghf8YgY0WQEgQuh3lErUFE4KxLeRmmw== +"@esbuild/aix-ppc64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.1.tgz#eafa8775019b3650a77e8310ba4dbd17ca7af6d5" + integrity sha512-m55cpeupQ2DbuRGQMMZDzbv9J9PgVelPjlcmM5kxHnrBdBx6REaEd7LamYV7Dm8N7rCyR/XwU6rVP8ploKtIkA== "@esbuild/aix-ppc64@0.20.2": version "0.20.2" @@ -2967,10 +3034,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz#7ad65a36cfdb7e0d429c353e00f680d737c2aed4" integrity sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA== -"@esbuild/android-arm64@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.0.tgz#109a6fdc4a2783fc26193d2687827045d8fef5ab" - integrity sha512-aVpnM4lURNkp0D3qPoAzSG92VXStYmoVPOgXveAUoQBWRSuQzt51yvSju29J6AHPmwY1BjH49uR29oyfH1ra8Q== +"@esbuild/android-arm64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.1.tgz#68791afa389550736f682c15b963a4f37ec2f5f6" + integrity sha512-hCnXNF0HM6AjowP+Zou0ZJMWWa1VkD77BXe959zERgGJBBxB+sV+J9f/rcjeg2c5bsukD/n17RKWXGFCO5dD5A== "@esbuild/android-arm64@0.20.2": version "0.20.2" @@ -2992,10 +3059,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.12.tgz#b0c26536f37776162ca8bde25e42040c203f2824" integrity sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w== -"@esbuild/android-arm@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.0.tgz#1397a2c54c476c4799f9b9073550ede496c94ba5" - integrity sha512-3bMAfInvByLHfJwYPJRlpTeaQA75n8C/QKpEaiS4HrFWFiJlNI0vzq/zCjBrhAYcPyVPG7Eo9dMrcQXuqmNk5g== +"@esbuild/android-arm@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.1.tgz#38c91d8ee8d5196f7fbbdf4f0061415dde3a473a" + integrity sha512-4j0+G27/2ZXGWR5okcJi7pQYhmkVgb4D7UKwxcqrjhvp5TKWx3cUjgB1CGj1mfdmJBQ9VnUGgUhign+FPF2Zgw== "@esbuild/android-arm@0.20.2": version "0.20.2" @@ -3017,10 +3084,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.12.tgz#cb13e2211282012194d89bf3bfe7721273473b3d" integrity sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew== -"@esbuild/android-x64@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.0.tgz#2b615abefb50dc0a70ac313971102f4ce2fdb3ca" - integrity sha512-uK7wAnlRvjkCPzh8jJ+QejFyrP8ObKuR5cBIsQZ+qbMunwR8sbd8krmMbxTLSrDhiPZaJYKQAU5Y3iMDcZPhyQ== +"@esbuild/android-x64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.1.tgz#93f6190ce997b313669c20edbf3645fc6c8d8f22" + integrity sha512-MSfZMBoAsnhpS+2yMFYIQUPs8Z19ajwfuaSZx+tSl09xrHZCjbeXXMsUF/0oq7ojxYEpsSo4c0SfjxOYXRbpaA== "@esbuild/android-x64@0.20.2": version "0.20.2" @@ -3042,10 +3109,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz#cbee41e988020d4b516e9d9e44dd29200996275e" integrity sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g== -"@esbuild/darwin-arm64@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.0.tgz#5c122ed799eb0c35b9d571097f77254964c276a2" - integrity sha512-AjEcivGAlPs3UAcJedMa9qYg9eSfU6FnGHJjT8s346HSKkrcWlYezGE8VaO2xKfvvlZkgAhyvl06OJOxiMgOYQ== +"@esbuild/darwin-arm64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.1.tgz#0d391f2e81fda833fe609182cc2fbb65e03a3c46" + integrity sha512-Ylk6rzgMD8klUklGPzS414UQLa5NPXZD5tf8JmQU8GQrj6BrFA/Ic9tb2zRe1kOZyCbGl+e8VMbDRazCEBqPvA== "@esbuild/darwin-arm64@0.20.2": version "0.20.2" @@ -3067,10 +3134,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz#e37d9633246d52aecf491ee916ece709f9d5f4cd" integrity sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A== -"@esbuild/darwin-x64@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.0.tgz#9561d277002ba8caf1524f209de2b22e93d170c1" - integrity sha512-bsgTPoyYDnPv8ER0HqnJggXK6RyFy4PH4rtsId0V7Efa90u2+EifxytE9pZnsDgExgkARy24WUQGv9irVbTvIw== +"@esbuild/darwin-x64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.1.tgz#92504077424584684862f483a2242cfde4055ba2" + integrity sha512-pFIfj7U2w5sMp52wTY1XVOdoxw+GDwy9FsK3OFz4BpMAjvZVs0dT1VXs8aQm22nhwoIWUmIRaE+4xow8xfIDZA== "@esbuild/darwin-x64@0.20.2": version "0.20.2" @@ -3092,10 +3159,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz#1ee4d8b682ed363b08af74d1ea2b2b4dbba76487" integrity sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA== -"@esbuild/freebsd-arm64@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.0.tgz#84178986a3138e8500d17cc380044868176dd821" - integrity sha512-kQ7jYdlKS335mpGbMW5tEe3IrQFIok9r84EM3PXB8qBFJPSc6dpWfrtsC/y1pyrz82xfUIn5ZrnSHQQsd6jebQ== +"@esbuild/freebsd-arm64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.1.tgz#a1646fa6ba87029c67ac8a102bb34384b9290774" + integrity sha512-UyW1WZvHDuM4xDz0jWun4qtQFauNdXjXOtIy7SYdf7pbxSWWVlqhnR/T2TpX6LX5NI62spt0a3ldIIEkPM6RHw== "@esbuild/freebsd-arm64@0.20.2": version "0.20.2" @@ -3117,10 +3184,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz#37a693553d42ff77cd7126764b535fb6cc28a11c" integrity sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg== -"@esbuild/freebsd-x64@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.0.tgz#3f9ce53344af2f08d178551cd475629147324a83" - integrity sha512-uG8B0WSepMRsBNVXAQcHf9+Ko/Tr+XqmK7Ptel9HVmnykupXdS4J7ovSQUIi0tQGIndhbqWLaIL/qO/cWhXKyQ== +"@esbuild/freebsd-x64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.1.tgz#41c9243ab2b3254ea7fb512f71ffdb341562e951" + integrity sha512-itPwCw5C+Jh/c624vcDd9kRCCZVpzpQn8dtwoYIt2TJF3S9xJLiRohnnNrKwREvcZYx0n8sCSbvGH349XkcQeg== "@esbuild/freebsd-x64@0.20.2": version "0.20.2" @@ -3142,10 +3209,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz#be9b145985ec6c57470e0e051d887b09dddb2d4b" integrity sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA== -"@esbuild/linux-arm64@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.0.tgz#24efa685515689df4ecbc13031fa0a9dda910a11" - integrity sha512-uTtyYAP5veqi2z9b6Gr0NUoNv9F/rOzI8tOD5jKcCvRUn7T60Bb+42NDBCWNhMjkQzI0qqwXkQGo1SY41G52nw== +"@esbuild/linux-arm64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.1.tgz#f3c1e1269fbc9eedd9591a5bdd32bf707a883156" + integrity sha512-cX8WdlF6Cnvw/DO9/X7XLH2J6CkBnz7Twjpk56cshk9sjYVcuh4sXQBy5bmTwzBjNVZze2yaV1vtcJS04LbN8w== "@esbuild/linux-arm64@0.20.2": version "0.20.2" @@ -3167,10 +3234,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz#207ecd982a8db95f7b5279207d0ff2331acf5eef" integrity sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w== -"@esbuild/linux-arm@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.0.tgz#6b586a488e02e9b073a75a957f2952b3b6e87b4c" - integrity sha512-2ezuhdiZw8vuHf1HKSf4TIk80naTbP9At7sOqZmdVwvvMyuoDiZB49YZKLsLOfKIr77+I40dWpHVeY5JHpIEIg== +"@esbuild/linux-arm@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.1.tgz#4503ca7001a8ee99589c072801ce9d7540717a21" + integrity sha512-LojC28v3+IhIbfQ+Vu4Ut5n3wKcgTu6POKIHN9Wpt0HnfgUGlBuyDDQR4jWZUZFyYLiz4RBBBmfU6sNfn6RhLw== "@esbuild/linux-arm@0.20.2": version "0.20.2" @@ -3192,10 +3259,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz#d0d86b5ca1562523dc284a6723293a52d5860601" integrity sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA== -"@esbuild/linux-ia32@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.0.tgz#84ce7864f762708dcebc1b123898a397dea13624" - integrity sha512-c88wwtfs8tTffPaoJ+SQn3y+lKtgTzyjkD8NgsyCtCmtoIC8RDL7PrJU05an/e9VuAke6eJqGkoMhJK1RY6z4w== +"@esbuild/linux-ia32@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.1.tgz#98c474e3e0cbb5bcbdd8561a6e65d18f5767ce48" + integrity sha512-4H/sQCy1mnnGkUt/xszaLlYJVTz3W9ep52xEefGtd6yXDQbz/5fZE5dFLUgsPdbUOQANcVUa5iO6g3nyy5BJiw== "@esbuild/linux-ia32@0.20.2": version "0.20.2" @@ -3217,10 +3284,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz#9a37f87fec4b8408e682b528391fa22afd952299" integrity sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA== -"@esbuild/linux-loong64@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.0.tgz#1922f571f4cae1958e3ad29439c563f7d4fd9037" - integrity sha512-lR2rr/128/6svngnVta6JN4gxSXle/yZEZL3o4XZ6esOqhyR4wsKyfu6qXAL04S4S5CgGfG+GYZnjFd4YiG3Aw== +"@esbuild/linux-loong64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.1.tgz#a8097d28d14b9165c725fe58fc438f80decd2f33" + integrity sha512-c0jgtB+sRHCciVXlyjDcWb2FUuzlGVRwGXgI+3WqKOIuoo8AmZAddzeOHeYLtD+dmtHw3B4Xo9wAUdjlfW5yYA== "@esbuild/linux-loong64@0.20.2": version "0.20.2" @@ -3242,10 +3309,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz#4ddebd4e6eeba20b509d8e74c8e30d8ace0b89ec" integrity sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w== -"@esbuild/linux-mips64el@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.0.tgz#7ca1bd9df3f874d18dbf46af009aebdb881188fe" - integrity sha512-9Sycc+1uUsDnJCelDf6ZNqgZQoK1mJvFtqf2MUz4ujTxGhvCWw+4chYfDLPepMEvVL9PDwn6HrXad5yOrNzIsQ== +"@esbuild/linux-mips64el@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.1.tgz#c44f6f0d7d017c41ad3bb15bfdb69b690656b5ea" + integrity sha512-TgFyCfIxSujyuqdZKDZ3yTwWiGv+KnlOeXXitCQ+trDODJ+ZtGOzLkSWngynP0HZnTsDyBbPy7GWVXWaEl6lhA== "@esbuild/linux-mips64el@0.20.2": version "0.20.2" @@ -3267,10 +3334,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz#adb67dadb73656849f63cd522f5ecb351dd8dee8" integrity sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg== -"@esbuild/linux-ppc64@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.0.tgz#8f95baf05f9486343bceeb683703875d698708a4" - integrity sha512-CoWSaaAXOZd+CjbUTdXIJE/t7Oz+4g90A3VBCHLbfuc5yUQU/nFDLOzQsN0cdxgXd97lYW/psIIBdjzQIwTBGw== +"@esbuild/linux-ppc64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.1.tgz#0765a55389a99237b3c84227948c6e47eba96f0d" + integrity sha512-b+yuD1IUeL+Y93PmFZDZFIElwbmFfIKLKlYI8M6tRyzE6u7oEP7onGk0vZRh8wfVGC2dZoy0EqX1V8qok4qHaw== "@esbuild/linux-ppc64@0.20.2": version "0.20.2" @@ -3292,10 +3359,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz#11bc0698bf0a2abf8727f1c7ace2112612c15adf" integrity sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg== -"@esbuild/linux-riscv64@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.0.tgz#ca63b921d5fe315e28610deb0c195e79b1a262ca" - integrity sha512-mlb1hg/eYRJUpv8h/x+4ShgoNLL8wgZ64SUr26KwglTYnwAWjkhR2GpoKftDbPOCnodA9t4Y/b68H4J9XmmPzA== +"@esbuild/linux-riscv64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.1.tgz#e4153b032288e3095ddf4c8be07893781b309a7e" + integrity sha512-wpDlpE0oRKZwX+GfomcALcouqjjV8MIX8DyTrxfyCfXxoKQSDm45CZr9fanJ4F6ckD4yDEPT98SrjvLwIqUCgg== "@esbuild/linux-riscv64@0.20.2": version "0.20.2" @@ -3317,10 +3384,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz#e86fb8ffba7c5c92ba91fc3b27ed5a70196c3cc8" integrity sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg== -"@esbuild/linux-s390x@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.0.tgz#cb3d069f47dc202f785c997175f2307531371ef8" - integrity sha512-fgf9ubb53xSnOBqyvWEY6ukBNRl1mVX1srPNu06B6mNsNK20JfH6xV6jECzrQ69/VMiTLvHMicQR/PgTOgqJUQ== +"@esbuild/linux-s390x@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.1.tgz#b9ab8af6e4b73b26d63c1c426d7669a5d53eb5a7" + integrity sha512-5BepC2Au80EohQ2dBpyTquqGCES7++p7G+7lXe1bAIvMdXm4YYcEfZtQrP4gaoZ96Wv1Ute61CEHFU7h4FMueQ== "@esbuild/linux-s390x@0.20.2": version "0.20.2" @@ -3342,10 +3409,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz#5f37cfdc705aea687dfe5dfbec086a05acfe9c78" integrity sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg== -"@esbuild/linux-x64@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.0.tgz#ac617e0dc14e9758d3d7efd70288c14122557dc7" - integrity sha512-H9Eu6MGse++204XZcYsse1yFHmRXEWgadk2N58O/xd50P9EvFMLJTQLg+lB4E1cF2xhLZU5luSWtGTb0l9UeSg== +"@esbuild/linux-x64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.1.tgz#0b25da17ac38c3e11cdd06ca3691d4d6bef2755f" + integrity sha512-5gRPk7pKuaIB+tmH+yKd2aQTRpqlf1E4f/mC+tawIm/CGJemZcHZpp2ic8oD83nKgUPMEd0fNanrnFljiruuyA== "@esbuild/linux-x64@0.20.2": version "0.20.2" @@ -3367,10 +3434,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz#29da566a75324e0d0dd7e47519ba2f7ef168657b" integrity sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA== -"@esbuild/netbsd-x64@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.0.tgz#6cc778567f1513da6e08060e0aeb41f82eb0f53c" - integrity sha512-lCT675rTN1v8Fo+RGrE5KjSnfY0x9Og4RN7t7lVrN3vMSjy34/+3na0q7RIfWDAj0e0rCh0OL+P88lu3Rt21MQ== +"@esbuild/netbsd-x64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.1.tgz#3148e48406cd0d4f7ba1e0bf3f4d77d548c98407" + integrity sha512-4fL68JdrLV2nVW2AaWZBv3XEm3Ae3NZn/7qy2KGAt3dexAgSVT+Hc97JKSZnqezgMlv9x6KV0ZkZY7UO5cNLCg== "@esbuild/netbsd-x64@0.20.2": version "0.20.2" @@ -3392,10 +3459,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz#306c0acbdb5a99c95be98bdd1d47c916e7dc3ff0" integrity sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw== -"@esbuild/openbsd-x64@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.0.tgz#76848bcf76b4372574fb4d06cd0ed1fb29ec0fbe" - integrity sha512-HKoUGXz/TOVXKQ+67NhxyHv+aDSZf44QpWLa3I1lLvAwGq8x1k0T+e2HHSRvxWhfJrFxaaqre1+YyzQ99KixoA== +"@esbuild/openbsd-x64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.1.tgz#7b73e852986a9750192626d377ac96ac2b749b76" + integrity sha512-GhRuXlvRE+twf2ES+8REbeCb/zeikNqwD3+6S5y5/x+DYbAQUNl0HNBs4RQJqrechS4v4MruEr8ZtAin/hK5iw== "@esbuild/openbsd-x64@0.20.2": version "0.20.2" @@ -3417,10 +3484,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz#0933eaab9af8b9b2c930236f62aae3fc593faf30" integrity sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA== -"@esbuild/sunos-x64@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.0.tgz#ea4cd0639bf294ad51bc08ffbb2dac297e9b4706" - integrity sha512-GDwAqgHQm1mVoPppGsoq4WJwT3vhnz/2N62CzhvApFD1eJyTroob30FPpOZabN+FgCjhG+AgcZyOPIkR8dfD7g== +"@esbuild/sunos-x64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.1.tgz#402a441cdac2eee98d8be378c7bc23e00c1861c5" + integrity sha512-ZnWEyCM0G1Ex6JtsygvC3KUUrlDXqOihw8RicRuQAzw+c4f1D66YlPNNV3rkjVW90zXVsHwZYWbJh3v+oQFM9Q== "@esbuild/sunos-x64@0.20.2": version "0.20.2" @@ -3442,10 +3509,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz#773bdbaa1971b36db2f6560088639ccd1e6773ae" integrity sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A== -"@esbuild/win32-arm64@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.0.tgz#a5c171e4a7f7e4e8be0e9947a65812c1535a7cf0" - integrity sha512-0vYsP8aC4TvMlOQYozoksiaxjlvUcQrac+muDqj1Fxy6jh9l9CZJzj7zmh8JGfiV49cYLTorFLxg7593pGldwQ== +"@esbuild/win32-arm64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.1.tgz#36c4e311085806a6a0c5fc54d1ac4d7b27e94d7b" + integrity sha512-QZ6gXue0vVQY2Oon9WyLFCdSuYbXSoxaZrPuJ4c20j6ICedfsDilNPYfHLlMH7vGfU5DQR0czHLmJvH4Nzis/A== "@esbuild/win32-arm64@0.20.2": version "0.20.2" @@ -3467,10 +3534,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz#000516cad06354cc84a73f0943a4aa690ef6fd67" integrity sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ== -"@esbuild/win32-ia32@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.0.tgz#f8ac5650c412d33ea62d7551e0caf82da52b7f85" - integrity sha512-p98u4rIgfh4gdpV00IqknBD5pC84LCub+4a3MO+zjqvU5MVXOc3hqR2UgT2jI2nh3h8s9EQxmOsVI3tyzv1iFg== +"@esbuild/win32-ia32@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.1.tgz#0cf933be3fb9dc58b45d149559fe03e9e22b54fe" + integrity sha512-HzcJa1NcSWTAU0MJIxOho8JftNp9YALui3o+Ny7hCh0v5f90nprly1U3Sj1Ldj/CvKKdvvFsCRvDkpsEMp4DNw== "@esbuild/win32-ia32@0.20.2": version "0.20.2" @@ -3492,10 +3559,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz#c57c8afbb4054a3ab8317591a0b7320360b444ae" integrity sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA== -"@esbuild/win32-x64@0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.0.tgz#2efddf82828aac85e64cef62482af61c29561bee" - integrity sha512-NgJnesu1RtWihtTtXGFMU5YSE6JyyHPMxCwBZK7a6/8d31GuSo9l0Ss7w1Jw5QnKUawG6UEehs883kcXf5fYwg== +"@esbuild/win32-x64@0.20.1": + version "0.20.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.1.tgz#77583b6ea54cee7c1410ebbd54051b6a3fcbd8ba" + integrity sha512-0MBh53o6XtI6ctDnRMeQ+xoCN8kD2qI1rY1KgF/xdWQwoFeKou7puvDfV8/Wv4Ctx2rRpET/gGdz3YlNtNACSA== "@esbuild/win32-x64@0.20.2": version "0.20.2" @@ -3539,11 +3606,6 @@ resolved "https://registry.yarnpkg.com/@fal-works/esbuild-plugin-global-externals/-/esbuild-plugin-global-externals-2.1.2.tgz#c05ed35ad82df8e6ac616c68b92c2282bd083ba4" integrity sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ== -"@fastify/busboy@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.0.0.tgz#f22824caff3ae506b18207bad4126dbc6ccdb6b8" - integrity sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ== - "@floating-ui/core@^1.4.2": version "1.5.0" resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.0.tgz#5c05c60d5ae2d05101c3021c1a2a350ddc027f8c" @@ -4796,10 +4858,10 @@ dependencies: tslib "2.6.1" -"@ngtools/webpack@17.2.3": - version "17.2.3" - resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-17.2.3.tgz#d1e06039407487dfcca1f136ca036c1f4c6eba40" - integrity sha512-+d5Q7/ctDHePYZXcg0GFwL/AbyEkPMHoCiT7pmLI0B0n87D/mYKK/qmVN1VANBrFLTuIe8RtcL0aJ9pw8HAxWA== +"@ngtools/webpack@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-17.3.3.tgz#da62af790e2d7280fe8b03f5dbff343580ffc0f0" + integrity sha512-053KMbg1Tb+Mmg4Htsv8yTpI7ABghguoxhwosQXKB0CjO6M0oexuvdaxbRDQ1vd5xYNOW9LcOfxOMPIwyU4BBA== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -4885,98 +4947,98 @@ read-package-json-fast "^3.0.0" which "^4.0.0" -"@nrwl/angular@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nrwl/angular/-/angular-18.1.2.tgz#8c46b9040e62505d939e57cbd378f060a53fe1f1" - integrity sha512-qgzWh4ku3bV+v2ZVFbNmGpFe9xGCxYPKDPE7YKpGKjBYb+5rrFjITkbR4TD0B3mgI7iOYX6ZdkYrPjpmCsI1kA== +"@nrwl/angular@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nrwl/angular/-/angular-18.2.3.tgz#eb65c229726c50f00d78e679d5696b0494548a24" + integrity sha512-F0RtvSIH/Qs0ju7VcdfBpDeBZvwio2g4KdNpRog9ZBlgJjEmRWu7aA733A2xng96IkJkIrO0DiJaFbNdm8Yelw== dependencies: - "@nx/angular" "18.1.2" + "@nx/angular" "18.2.3" tslib "^2.3.0" -"@nrwl/cypress@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nrwl/cypress/-/cypress-18.1.2.tgz#04be1190e423ded1c9d5175632e83bbf1171d1f1" - integrity sha512-RphBWkdY32h97oQ/9FPw4vbLOld9MY65osrb47OKnpBGiqPKSWZOkhxLlgWN0FZV2hGRfvHUKHCC1ZmKHi6fCA== +"@nrwl/cypress@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nrwl/cypress/-/cypress-18.2.3.tgz#934f7615f347ece85025a925de2e132a9a924164" + integrity sha512-P44e3hmhXWK6jALoHK8bAVUvIqGP8SCX/GM/e6jVAZIjvAC+L69WTkAXVLgZkiD8WpZegSho47AtaL1D256a/g== dependencies: - "@nx/cypress" "18.1.2" + "@nx/cypress" "18.2.3" -"@nrwl/devkit@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-18.1.2.tgz#6ab2b3a85f8af181db48ef1351298633da2b0126" - integrity sha512-x+6UJNeWoDtke1FhEAP6ptDLUPJC/xOJ+Wri6RFTi+/ekw7qD3Bj73XHU9C47HBxMxN2voUVMfIX3mC65/CXiQ== +"@nrwl/devkit@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-18.2.3.tgz#4de5589b99c6e5a15da334630079d027a59fdd4c" + integrity sha512-BJQdPmXFze7g4zsHhwSTssAcm/hvl0rXbIzZYQxncsVU4d+Fx0GS3JYBZ+9EcfnCeAEb10jGvn7Rfk+0okMmOw== dependencies: - "@nx/devkit" "18.1.2" + "@nx/devkit" "18.2.3" -"@nrwl/eslint-plugin-nx@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nrwl/eslint-plugin-nx/-/eslint-plugin-nx-18.1.2.tgz#d1cd83547cb6d825a6661ded008f0bef0f09bdd1" - integrity sha512-cmTMpG09avCHbbrpHE2rld4o+GEUX6Q7URh51QvKbeIeBvT77uEbin7EzptWJNjN4Ht9hKEAiQkZPideualWeA== +"@nrwl/eslint-plugin-nx@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nrwl/eslint-plugin-nx/-/eslint-plugin-nx-18.2.3.tgz#f66513f8a2bbb63f3555129f8d8236a0936d7573" + integrity sha512-hwIqxp2A0G250tFzEDmVbhwhtldoB7858848AME99Nt9Ij27ThzYaLIG+TYicmb+Rq2FqG9G/6wS89eg1aAg2Q== dependencies: - "@nx/eslint-plugin" "18.1.2" + "@nx/eslint-plugin" "18.2.3" -"@nrwl/jest@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nrwl/jest/-/jest-18.1.2.tgz#f2e0a4ac17cc042075986aa9fe92ea4bab7ef864" - integrity sha512-G+Zr/MDS3k1Bg0Pmv2YWlqBhpaZq38W7GdSci4DEkdQMBZtHhoObTrAfnRXwwP5Zsh5FAXltfTdAkWn8e6lQtg== +"@nrwl/jest@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nrwl/jest/-/jest-18.2.3.tgz#f603d310729b216788d00d70ad0c00193f8bc430" + integrity sha512-64Ebl6GYOQ8AWp/MpPx8qXwKla3x0wnVGjJK4gUGOJ9ShMQnzd4hgYLpVuB4Des7QSxXoict3YVOVocY0joNow== dependencies: - "@nx/jest" "18.1.2" + "@nx/jest" "18.2.3" -"@nrwl/js@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nrwl/js/-/js-18.1.2.tgz#3b4d0db7d964c2bf76569e6521bb313bace58bbd" - integrity sha512-BTxmaF73TB9Ym8MyXUfFjeS3kyw/elORrSrEu6b4ei1Q/DszEpZHhvavN1nUebqJe3RifW9IKL2TFblSoIWCTg== +"@nrwl/js@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nrwl/js/-/js-18.2.3.tgz#f7aa58ae957403215ca2507c6740245796a27d3e" + integrity sha512-fOpKQg7CvzOmcow9fbBc5l96Pbv8gTe9qba4jiw3Z+EH776qraNBL9pRpff653V+obVh//gkq84BUeoJgk8vzQ== dependencies: - "@nx/js" "18.1.2" + "@nx/js" "18.2.3" -"@nrwl/nest@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nrwl/nest/-/nest-18.1.2.tgz#1bd2a8637f3b56b2074b54246669817c7512b310" - integrity sha512-UD1j1r2hpH3O78Yad1dAcInYpvX7NPGnrwXvJqojyOqT5A/GqXxKKnpTsE5IZsNwdFfIQXRGY4QjacEsBuZf5Q== +"@nrwl/nest@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nrwl/nest/-/nest-18.2.3.tgz#c4544725ab375f1189e719b50410d38c36bcec95" + integrity sha512-hQqh3kGZ6Ky7zHzyRDNnzZ57Egn7w96IEfABsT2nnpej0LPWebryPefGSAI4Afgy2q8jSUFj9Bgjf6j93Ogiqg== dependencies: - "@nx/nest" "18.1.2" + "@nx/nest" "18.2.3" -"@nrwl/node@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nrwl/node/-/node-18.1.2.tgz#112b9653447d69eef041a79f6302e869a2b3c320" - integrity sha512-1Z9ZMOdzw8v7sOaOUaQnJr3Aclqchpg1Thj9mqslu/FZeXlp7pngeT4hPvt3FqFbLvxZIH5u3uxQjFNW4QKNxQ== +"@nrwl/node@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nrwl/node/-/node-18.2.3.tgz#fff8c16005c41c8c7d3fe6b7ee4a1b4446e44461" + integrity sha512-cQWAAtG+AexiWsU+5DRfEvbHhU0vkcvhdD3yUG8HjcMjc7eHS82PPxWUk/EzEI/3+3fYcHhSw5F/WyqaVkYJaw== dependencies: - "@nx/node" "18.1.2" + "@nx/node" "18.2.3" -"@nrwl/storybook@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nrwl/storybook/-/storybook-18.1.2.tgz#f9cc07ca9ec2a89cb1729f8b2bf50fbc01f18882" - integrity sha512-inItJAeJUw0DnOkH/cp7JuASp0ndO+4xvJVAD26fEWzYB3pVdM77FIow4BSYXV0P10h7c9K7R9X8KdGXdEbSkg== +"@nrwl/storybook@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nrwl/storybook/-/storybook-18.2.3.tgz#340b10b845dfa373c0513fba40213631e6d0bf51" + integrity sha512-+kZYFSKtZp4+qDav2Z9+xGtRoCiYFE7toKSWNO+7qBmuEm+noCppgxyJ4dv92gc2DR8FSWPrHKp5x+Km0dwJYQ== dependencies: - "@nx/storybook" "18.1.2" + "@nx/storybook" "18.2.3" -"@nrwl/tao@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-18.1.2.tgz#5a05befc9260cae8c7f38ec83669f4ffbfd83f3b" - integrity sha512-IA+osZ5TlKMwJmcP7TECW7TO0JdNNQud9Dgkh1ZfJ4GWnT7WEkE9b2Yf1IFeeB81kCTXXq8jfISa8ZY21MjRaQ== +"@nrwl/tao@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-18.2.3.tgz#c29abf614c23b404d30340326fb52d33822815c0" + integrity sha512-vmteqzGcKPbexaAVPb/7VfXI5dXxzZwSm3rem3z20QlDOmNh1545VLO9YEfT5xzmZT2CC7F0etR4KcrJLtoT5g== dependencies: - nx "18.1.2" + nx "18.2.3" tslib "^2.3.0" -"@nrwl/web@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nrwl/web/-/web-18.1.2.tgz#58cefe472c638f368207c29cf57e6e5db6cb1ad5" - integrity sha512-mu8OW+wFMYgLB2R4X8gzdxLhREXJ5CIRvkS1xFmf91/pMru2kiBpiGrX3+6lvM4RcMFaY4YZiKpVp09JOeCQwQ== +"@nrwl/web@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nrwl/web/-/web-18.2.3.tgz#15e43dd727ba06df111edf16c7f74f915600e41d" + integrity sha512-nlucIDaMUOAG5xOJTCzvKHhCAxergYUrfi2XgPYjg4mu+ApqJxI7HO6FVXZazdivEwNy++BLErjmOjMb52iaVw== dependencies: - "@nx/web" "18.1.2" + "@nx/web" "18.2.3" -"@nrwl/webpack@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nrwl/webpack/-/webpack-18.1.2.tgz#f5152df6b9311afb90cc559414f15d5f363c096a" - integrity sha512-ivFdNTnvLAHwWvF/83hPlBhuSvVXEblS4l4OkPRVw8kG7DjEAfvY5Zb1GsqsThTMAgtXPEVdqzofAskFr+xKPw== +"@nrwl/webpack@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nrwl/webpack/-/webpack-18.2.3.tgz#d3443ed4478e87defb5be209a335d71b91ccce27" + integrity sha512-ygkYzE+ihhFBuMmOuOkGse0Aas0CSbJ8uLth8UumnapU1euBTP5blhp+y6HRCRT8SzfGzc0qJ+M8YLb6E/DvMQ== dependencies: - "@nx/webpack" "18.1.2" + "@nx/webpack" "18.2.3" -"@nrwl/workspace@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nrwl/workspace/-/workspace-18.1.2.tgz#bae0bc66b4f1a071e77d158e5fded72da41a67ec" - integrity sha512-8nI5KxGAr30QBwXlQpMiIr+MdmGNdYxBU0HikqQP3RPk97+y6g/O6He2cOGZFFN5hDbeuQ/R15hyGtPLYS9jLg== +"@nrwl/workspace@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nrwl/workspace/-/workspace-18.2.3.tgz#811b3778b3222be835248eb366de0b9a98f3843e" + integrity sha512-5tVtui/iy+VZTk3x/eFj21Zm0ICPUre9CfB5jlJ2MwH8w+96+186Yt2XGJATkFfnVnjqnszOcjk5BLlra8fdLA== dependencies: - "@nx/workspace" "18.1.2" + "@nx/workspace" "18.2.3" "@nuxtjs/opencollective@0.3.2": version "0.3.2" @@ -4987,51 +5049,51 @@ consola "^2.15.0" node-fetch "^2.6.1" -"@nx/angular@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/angular/-/angular-18.1.2.tgz#75e7c3c24510b0f7727a137bb0bc4d8e572dc7d9" - integrity sha512-ES9GtbIPmnz5W6Q9fZ+CkwyIRVjGkRd8Ee5eSwi0nRZDeCPSar+k9+52bpzW8VV5LbCQZKEGS8NjRhV0l+/9jw== - dependencies: - "@nrwl/angular" "18.1.2" - "@nx/devkit" "18.1.2" - "@nx/eslint" "18.1.2" - "@nx/js" "18.1.2" - "@nx/web" "18.1.2" - "@nx/webpack" "18.1.2" - "@nx/workspace" "18.1.2" +"@nx/angular@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/angular/-/angular-18.2.3.tgz#564c304c253a268c87d2cb751655691f471e98f7" + integrity sha512-oSp4cNlyCUd03SNoa+x5zjrnqBjxANInB0+vsGD5VlOewpfkVNWPb7TIRa+JyOFXWSWblF0LNEiLxWnxY+27gw== + dependencies: + "@nrwl/angular" "18.2.3" + "@nx/devkit" "18.2.3" + "@nx/eslint" "18.2.3" + "@nx/js" "18.2.3" + "@nx/web" "18.2.3" + "@nx/webpack" "18.2.3" + "@nx/workspace" "18.2.3" "@phenomnomnominal/tsquery" "~5.0.1" - "@typescript-eslint/type-utils" "^6.9.1" + "@typescript-eslint/type-utils" "^7.3.0" chalk "^4.1.0" find-cache-dir "^3.3.2" ignore "^5.0.4" magic-string "~0.30.2" minimatch "9.0.3" - piscina "^4.2.1" + piscina "^4.4.0" semver "^7.5.3" tslib "^2.3.0" webpack "^5.80.0" webpack-merge "^5.8.0" -"@nx/cypress@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/cypress/-/cypress-18.1.2.tgz#9cef040c511eeb16fa8109bcc4e6c38bc8492e5d" - integrity sha512-JMdpGHWhL0Iv+Eod1tIT1LVSTZfQmp40sWpH7Jri7WCoEw3vh4F4//1Az84Irs+QKDXUPX/eV1avbJY+2HIZqQ== +"@nx/cypress@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/cypress/-/cypress-18.2.3.tgz#fe32cbb21d592fbe0c62f1ee47abc5ffc232bd23" + integrity sha512-TY5LC4cXFAMq3hrIQDTKYwGgNVDWCTF6i22gaaMlTayowfSWcEug5FHfBGXzpvYR4Q5Snci988krI1yN/6Fbfw== dependencies: - "@nrwl/cypress" "18.1.2" - "@nx/devkit" "18.1.2" - "@nx/eslint" "18.1.2" - "@nx/js" "18.1.2" + "@nrwl/cypress" "18.2.3" + "@nx/devkit" "18.2.3" + "@nx/eslint" "18.2.3" + "@nx/js" "18.2.3" "@phenomnomnominal/tsquery" "~5.0.1" detect-port "^1.5.1" semver "^7.5.3" tslib "^2.3.0" -"@nx/devkit@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/devkit/-/devkit-18.1.2.tgz#5d1d83bd10caedb0797ee940d61e03d546221405" - integrity sha512-xgiPqKdJ6GVrqXsAyHD/yxqCDW1LekkWgazkuBI8MKA5J2IwZ4Ex5pMsOVMuWz2sTRejuPRqajBclFRMbhfCig== +"@nx/devkit@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/devkit/-/devkit-18.2.3.tgz#81788e9d018772414ddad0f1aba7ce007da570a3" + integrity sha512-dugw9Jm3Og28uwGee94P3KYkqiUV7J8RgibOQjQG4J2Vt3DPBNEGSgBD72qKkzpioEo+XSVUkn9h3GrdmnRU+Q== dependencies: - "@nrwl/devkit" "18.1.2" + "@nrwl/devkit" "18.2.3" ejs "^3.1.7" enquirer "~2.3.6" ignore "^5.0.4" @@ -5040,44 +5102,44 @@ tslib "^2.3.0" yargs-parser "21.1.1" -"@nx/eslint-plugin@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/eslint-plugin/-/eslint-plugin-18.1.2.tgz#4fec9bcd36900007048dacecb33ae418a0ee7e8e" - integrity sha512-enlPiKl/TdW/YTxNmlBvMt4Z6hm/Ozp5R+G9d7w+e82ZwBBaJnsTZYlNGuhFmWP9ZVMCVjivJHe9da0Ea4e7yQ== +"@nx/eslint-plugin@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/eslint-plugin/-/eslint-plugin-18.2.3.tgz#99e7e46d8bc32966bdb9c0be7783b7e7bc84a795" + integrity sha512-vOHkzHNpDLLd5RMrL/8/sAdqBqMcf2FrSJWug6W4cC0x8hzUpNwnfEn+i4ZCV/QxduQH4/UP96AbOm7rzwoAdg== dependencies: - "@nrwl/eslint-plugin-nx" "18.1.2" - "@nx/devkit" "18.1.2" - "@nx/js" "18.1.2" - "@typescript-eslint/type-utils" "^6.13.2" - "@typescript-eslint/utils" "^6.13.2" + "@nrwl/eslint-plugin-nx" "18.2.3" + "@nx/devkit" "18.2.3" + "@nx/js" "18.2.3" + "@typescript-eslint/type-utils" "^7.3.0" + "@typescript-eslint/utils" "^7.3.0" chalk "^4.1.0" confusing-browser-globals "^1.0.9" jsonc-eslint-parser "^2.1.0" semver "^7.5.3" tslib "^2.3.0" -"@nx/eslint@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/eslint/-/eslint-18.1.2.tgz#f4f0830c890c71f098938129a3f35c215c205166" - integrity sha512-cNCbCg5/qYCXrcBuJaJjy6+aLTDcU9LfxEvuBrA3RdAVqpSj0EjxocrmXwbSZTQt6JDhgraoZqtFRxGZ+44Oww== +"@nx/eslint@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/eslint/-/eslint-18.2.3.tgz#714106ffb0e9a7dd35e3248640a073e811eb9c66" + integrity sha512-qr1A3on5tPR3Rxsrg1wlPLVB/L6iFDp+II1xBb/3PBAsddKvPCzPASsogAm0Q3RdqK2JkJrwo/rX3YxwrjZ5cQ== dependencies: - "@nx/devkit" "18.1.2" - "@nx/js" "18.1.2" - "@nx/linter" "18.1.2" + "@nx/devkit" "18.2.3" + "@nx/js" "18.2.3" + "@nx/linter" "18.2.3" eslint "^8.0.0" tslib "^2.3.0" - typescript "~5.3.2" + typescript "~5.4.2" -"@nx/jest@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/jest/-/jest-18.1.2.tgz#4ff73bee42c459f22a262355bc249ff93f9a8ab8" - integrity sha512-lCWVAzeN+U5xppqU6kuJaHCdudiSxnVdoYcaW0yf5bx3XYaKIIN+2NTPxRGy/QKibnQwqv3Y5NdIFDt67OYQ4Q== +"@nx/jest@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/jest/-/jest-18.2.3.tgz#f36a0671bb64e45961dad4a97c835873a5e297cf" + integrity sha512-AMI/RuTlNz5d0JiBdraCkZ1ABfEyuJkdCvVjo/RDu1NAw1Xv4hI4+5UG7sb/bJoX6n+lK1SS51z+Zb/ab8lQoQ== dependencies: "@jest/reporters" "^29.4.1" "@jest/test-result" "^29.4.1" - "@nrwl/jest" "18.1.2" - "@nx/devkit" "18.1.2" - "@nx/js" "18.1.2" + "@nrwl/jest" "18.2.3" + "@nx/devkit" "18.2.3" + "@nx/js" "18.2.3" "@phenomnomnominal/tsquery" "~5.0.1" chalk "^4.1.0" identity-obj-proxy "3.0.0" @@ -5089,10 +5151,10 @@ tslib "^2.3.0" yargs-parser "21.1.1" -"@nx/js@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/js/-/js-18.1.2.tgz#e42c0801ac9edf755dde8c5bbf1501d985250af8" - integrity sha512-bq3goTS6zM6Eg3DNLAz51gB34zHqhYf7LzTFJOGDRogzmEGsttSbX46eiaD4oSpq/s4ybwRe2cHV3ZGodaZL1A== +"@nx/js@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/js/-/js-18.2.3.tgz#fd9a1be56fd674f80563a20d90feffc6ab9b830a" + integrity sha512-hFSmgyaMVIlN/SyFwOwn/IveHsGxxJOv7qhewACg9NlKOa6+eEJYlEbOik9LjvcosDOh5icrngjsFgFJoC1sWA== dependencies: "@babel/core" "^7.23.2" "@babel/plugin-proposal-decorators" "^7.22.7" @@ -5101,9 +5163,9 @@ "@babel/preset-env" "^7.23.2" "@babel/preset-typescript" "^7.22.5" "@babel/runtime" "^7.22.6" - "@nrwl/js" "18.1.2" - "@nx/devkit" "18.1.2" - "@nx/workspace" "18.1.2" + "@nrwl/js" "18.2.3" + "@nx/devkit" "18.2.3" + "@nx/workspace" "18.2.3" "@phenomnomnominal/tsquery" "~5.0.1" babel-plugin-const-enum "^1.0.1" babel-plugin-macros "^2.8.0" @@ -5125,125 +5187,125 @@ tsconfig-paths "^4.1.2" tslib "^2.3.0" -"@nx/linter@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/linter/-/linter-18.1.2.tgz#e511c7fb059edce57a54666e5066008106999d76" - integrity sha512-bIGFQwHixXv6BuVLVIc5HYwzlodGxK9HsTp+5RtokCXZ0LIv4jkm0FsNExkBBqlaf4oLLqu0F/IZYfzhTwcCsA== +"@nx/linter@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/linter/-/linter-18.2.3.tgz#a2b9bd388955f7872c42b5dfcabb7f308344039b" + integrity sha512-buxqe0N/d5iVWA4zE/jX8xrkCJLyGG2h1bSTrz1oyPvM3SdcWr69JpL8j1wtBvnKo/brDzLbNWsnrUwO9cgSAQ== dependencies: - "@nx/eslint" "18.1.2" + "@nx/eslint" "18.2.3" -"@nx/nest@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/nest/-/nest-18.1.2.tgz#63a473739ee90206660d315577f3abc9ec701ff7" - integrity sha512-lhnhTxv2pcKSQYrnpbTW50Xm6O7yPbH4d4VqKDj8p863lU623Wh6SW5scl3YCxwr354i4xITo3Ui212oGDKFog== +"@nx/nest@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/nest/-/nest-18.2.3.tgz#24a01ba16207768e80ff42004fa6552b2605f609" + integrity sha512-kBIKF08iB8V4k9RaPsSzawaVIZo/czx+SEaQmS7+fSsVerLji5ZJoFKqSxnDz6ksW1lfkmRpymSdWWHRc/UDKA== dependencies: "@nestjs/schematics" "^9.1.0" - "@nrwl/nest" "18.1.2" - "@nx/devkit" "18.1.2" - "@nx/eslint" "18.1.2" - "@nx/js" "18.1.2" - "@nx/node" "18.1.2" + "@nrwl/nest" "18.2.3" + "@nx/devkit" "18.2.3" + "@nx/eslint" "18.2.3" + "@nx/js" "18.2.3" + "@nx/node" "18.2.3" "@phenomnomnominal/tsquery" "~5.0.1" tslib "^2.3.0" -"@nx/node@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/node/-/node-18.1.2.tgz#bf432f38c2c695ff26f42b7191c79665b3b58738" - integrity sha512-xXiA0yNIIXIAC6sD/j1kW4SXFbTsYneyKwl0az0TwQkHAwYSPnUASLbj1tfE/DCpH5s9S0x/A35IqtHNhIMZtw== +"@nx/node@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/node/-/node-18.2.3.tgz#5ba965f8163dadb802bd43c9706807efaea750be" + integrity sha512-ryI+xzFLBNlRqLNH5UkHO2ZYIs1u1dUbkf7HTyJ4AOrzH2kuBd7tKfFI/IcDzmhjMOfhDYPC0RV7osOSS5Vdiw== dependencies: - "@nrwl/node" "18.1.2" - "@nx/devkit" "18.1.2" - "@nx/eslint" "18.1.2" - "@nx/jest" "18.1.2" - "@nx/js" "18.1.2" + "@nrwl/node" "18.2.3" + "@nx/devkit" "18.2.3" + "@nx/eslint" "18.2.3" + "@nx/jest" "18.2.3" + "@nx/js" "18.2.3" tslib "^2.3.0" -"@nx/nx-darwin-arm64@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-18.1.2.tgz#8c6d020d744e52900b215d180ad29c2873dc4acd" - integrity sha512-KduC9WBmeTLP8HyTg4NOgQGLk9LEd5qd9dGuYKPU0jA4b+eJIa0rRHEjFdc5WulQrcUAvTIKfmScRCgzR96ogg== - -"@nx/nx-darwin-x64@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-18.1.2.tgz#7247cbea93ea2b8c9ad7d22b1f25374454543589" - integrity sha512-mBf3X8m4P4QHoW8g/L/YoK8zkndDyIw4bojLg8Q3xc47s5JZFCqSSMeOXZ9NicM2DpPiDWSQALtQX7A8lIsoAA== - -"@nx/nx-freebsd-x64@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/nx-freebsd-x64/-/nx-freebsd-x64-18.1.2.tgz#cddc5e345f100a8fa88ff4e39e0e253f843ef3f7" - integrity sha512-ZqzT2BTsOHhWip1PvNm7AZ4Pzn4I+IZNRvtRgpETYvIH+nqoCmi5rrEi1avnhnr6P5hyzh2mISRSyk186SbZew== - -"@nx/nx-linux-arm-gnueabihf@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-18.1.2.tgz#4a1a5de3bc3ca2d8525259ea5c15ff1ca779cdcb" - integrity sha512-V9Dp9uuuce+/f50dXxaYz1C9ULo5+5VS35yc6gN7b6SchCWjNK+xg1YcHBTRNc2ChBtayO2z+mBQ1s6wMDNs/Q== - -"@nx/nx-linux-arm64-gnu@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-18.1.2.tgz#cbb2624d0d245242a09f90715eaabcfb4c8be804" - integrity sha512-aM860T4Hy2JCLcU56mtARIp1MdT1Ms7cGUQzE+a5irM8ZdaHsPdRnYqIgEKd3hoF6PQ6/piHFXWa4xm7pe/2KA== - -"@nx/nx-linux-arm64-musl@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-18.1.2.tgz#a99fd2898030bca1be14077e2e23ec3122c369c1" - integrity sha512-BgBoOeIgCQ56xii7fKNWiE7UIP/0G+OQhdWJQmh+q6NN0kk78WsdCSq+f7f7LQIji5HiNqUUVx9fd1s6xRSb/w== - -"@nx/nx-linux-x64-gnu@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-18.1.2.tgz#e80bfef4f0cf8243f18dd1aa91b4b47a915e3497" - integrity sha512-WDOjtk+K2Tc9SNjGe+zmyy05VUerZpEQ5kvB6Ude0v/W2bMnmpVrLZwwTF5Yrq0ebbUlXM/9wtc1Zjjc75MU2g== - -"@nx/nx-linux-x64-musl@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-18.1.2.tgz#afd9a93b306c5b8f52385a0b54de2c3573e61834" - integrity sha512-I7jTmbfR5CHC3KVlU3SkqYKJnn25MbH8pdRZJY4gaHnqL9JzbHw9rxddhKBj41lez7jQZTGLnPFUV7JPLXTzKg== - -"@nx/nx-win32-arm64-msvc@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-18.1.2.tgz#490f04af286894a3e1b33fb83cd9ce1466166280" - integrity sha512-KQobKvkrdkmaJmx0Pyt2lzHkNugO0gE7q9F4h22KIECyGW1tC3nSPAB4F3mmdE2KuWKgYG5WLafvzusysLsR7g== - -"@nx/nx-win32-x64-msvc@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-18.1.2.tgz#e6587d71e529cc30376d250da0af3095300c259f" - integrity sha512-uvJvROSwHBwkTOoOPkb56jEsKJjr4LnZ3fCHmEbrtGhAUC0gAUL+dWJUDHoatrGzN+bM2VqrvgNCGkityK96hw== - -"@nx/storybook@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/storybook/-/storybook-18.1.2.tgz#dab2c43d2b197cf46fc255301fce5f35774f19d4" - integrity sha512-gRCTvhWdtZK8RiggHoHN3LYI+Go4sfgkawAWBmrGIqBBtuitBvOm/hKJeUM0OdXKq/g6QsK4p4/okDqWOEuYaw== - dependencies: - "@nrwl/storybook" "18.1.2" - "@nx/cypress" "18.1.2" - "@nx/devkit" "18.1.2" - "@nx/eslint" "18.1.2" - "@nx/js" "18.1.2" +"@nx/nx-darwin-arm64@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-18.2.3.tgz#4b3f14437e6f5a7233594f63a8d36097e8872af1" + integrity sha512-TEks/vXHE87rNvVqhcIzQOM/+aZvNCf/70PhGG4RBEb+qV0C1kw7nygzdoLI4inFC76Qxhyya/K3J2OnU5ATiw== + +"@nx/nx-darwin-x64@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-18.2.3.tgz#bc546836bcce2293181a315666d4a0ea7b42642a" + integrity sha512-UsBbNbNXj+L2OzPyQYotyzmZF4h+ryaZ8quYDfdnlYwvFeqkdb2QJ3vJRd6in0kMWGrdk/ria/wZMCxR7U1ggg== + +"@nx/nx-freebsd-x64@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/nx-freebsd-x64/-/nx-freebsd-x64-18.2.3.tgz#afe920b26385fffb77cbad5435ff97607481c01c" + integrity sha512-f9BXGOeRPhrsNm99TCnOqZZeZUqN1BUOEzWa12eo3u+vQG6Qba3qKn7T92SeEzxOx/mUP/Csv3pFYoY6TE26jA== + +"@nx/nx-linux-arm-gnueabihf@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-18.2.3.tgz#d438dddcfb0fd255b8903214118c304eb89f33ef" + integrity sha512-ekqr5jZhD6PxGM5IbI/RtlERDJ+8HR04OIdfo6HkbwxwCHxZlzZq+ApEZYum4AbjP6cuc3Zd/us1uuDqfQbeHw== + +"@nx/nx-linux-arm64-gnu@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-18.2.3.tgz#a496666a70499d22589dfe0df3d46e738921250b" + integrity sha512-iAW2J8NBFU4zDn5nqRgUq4t7gYC8ALyALzznr97ZvMTQorWfmHYgPUAj/opNqUcr10fjxcmXT0Ux2SX3DgUDmw== + +"@nx/nx-linux-arm64-musl@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-18.2.3.tgz#90744f03377959bdc90cf5a8a2f00afb5b084b70" + integrity sha512-AJjGVHGGew0QVKUL30mjFjafowrSDYSQ1GgkJCLuWef5jl4rFvm9ruZswVja1KfZTFaImTCU01tZjPBr3zhmAA== + +"@nx/nx-linux-x64-gnu@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-18.2.3.tgz#0c0fac195dcf5eaf58a89bbd4764e06c5e338f14" + integrity sha512-nk5Xg8vmbBRoL0fOgZNBl1paC7hmjACLaSBmU7U2X+Y+QPGQzSw2b+Zn1MKVUWDmc4E6VnQfZ8n0L27+r9NgRw== + +"@nx/nx-linux-x64-musl@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-18.2.3.tgz#ba2e290ae3e7e0b43669546591e576c3f7ff2c50" + integrity sha512-bOlhul/eov58k9fX8lltopUDOIBEohZq2qc4ag91W2r4jdp6suAiqfXRxQwNZ2iHd8nAXuCDIHCbUuojs6OZnA== + +"@nx/nx-win32-arm64-msvc@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-18.2.3.tgz#5fc56f77ae98e273b1abb9eaf91492f1a40f2dc6" + integrity sha512-olXer0LnCvJrdV5ynd19fZHvvarRK/p1JnkoOUZDPVV+A3jGQQ8+paz+/5iLQBKA+5VcgWyqAaGFJnpyEFmnoQ== + +"@nx/nx-win32-x64-msvc@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-18.2.3.tgz#91083c549d4cdbaa0098cf1158edce98f1b440d6" + integrity sha512-BgzPjF/wqi7zIFcspcKzN37BX1wgGo0OTLncK2PN5nyzSQ+XeNbR5laDswxzOGdB4CRLPqak2+YMhYnoiXeRCg== + +"@nx/storybook@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/storybook/-/storybook-18.2.3.tgz#38a9d6a541113304abf5d918411bf8696ccdb51e" + integrity sha512-6XvgLD2L4+cbEwPneey+mxB7nGUi4l0K+R1AWjijGg14X2IzyCTgs5up56vIAKVuwuXxGWUTuXgSXwfKXINLIg== + dependencies: + "@nrwl/storybook" "18.2.3" + "@nx/cypress" "18.2.3" + "@nx/devkit" "18.2.3" + "@nx/eslint" "18.2.3" + "@nx/js" "18.2.3" "@phenomnomnominal/tsquery" "~5.0.1" semver "^7.5.3" tslib "^2.3.0" -"@nx/web@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/web/-/web-18.1.2.tgz#a5e066e3edd651862cef9b3fac923625d8d20d71" - integrity sha512-SUqwXwwFMjtMakCWHb/pMxIRYiRg9GZnvaIF3/iiaRcXSldReIXbP6+weW36SLv9fjxtObV/CiW59AILwkPzHA== +"@nx/web@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/web/-/web-18.2.3.tgz#c1d1bf7a77d16fd9281453c1c9e68dea853f0fc0" + integrity sha512-nDiCHinZGfkGWuTL2HLk6tUcKILMYtrtd6c/cE8T+5TnTXNaMrOQFt1GvDa60HGh8xgRgpjzTsGfJFrf90GJcA== dependencies: - "@nrwl/web" "18.1.2" - "@nx/devkit" "18.1.2" - "@nx/js" "18.1.2" + "@nrwl/web" "18.2.3" + "@nx/devkit" "18.2.3" + "@nx/js" "18.2.3" chalk "^4.1.0" detect-port "^1.5.1" http-server "^14.1.0" tslib "^2.3.0" -"@nx/webpack@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/webpack/-/webpack-18.1.2.tgz#bb9a65c30644ee017ea6818bcc66edfa67e095d8" - integrity sha512-Mv24F7IlYRqSqsn97+WlpylCpC79v4aQubZRPE/dxx7eRqBMykg1BSy8uDI926ggkr096EUejQkN44pzu7o/gQ== +"@nx/webpack@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/webpack/-/webpack-18.2.3.tgz#15b3c4be376f2313abdd64c3b67e04f11fbde1fc" + integrity sha512-0X7HXrF/VP9BrbbYD4Ewr4KnMT85eSaIBr/TvTrUM4v2BXqPgP4NVQhkd6jLlEkWuDlYtAgwFjcx4NGWRqnwbw== dependencies: "@babel/core" "^7.23.2" - "@nrwl/webpack" "18.1.2" - "@nx/devkit" "18.1.2" - "@nx/js" "18.1.2" + "@nrwl/webpack" "18.2.3" + "@nx/devkit" "18.2.3" + "@nx/js" "18.2.3" ajv "^8.12.0" autoprefixer "^10.4.9" babel-loader "^9.1.2" @@ -5278,16 +5340,16 @@ webpack-node-externals "^3.0.0" webpack-subresource-integrity "^5.1.0" -"@nx/workspace@18.1.2": - version "18.1.2" - resolved "https://registry.yarnpkg.com/@nx/workspace/-/workspace-18.1.2.tgz#8bc8f5e31007535e11e6c64c97e68ef31d179903" - integrity sha512-/b7qJqnxdWYfBb0UDgVJLmPv5qN50LbarzGLwJxSIVnlRWH94UOO4HW+W0tcEDNnf0RnFP1zDIysz+qu5CmV0g== +"@nx/workspace@18.2.3": + version "18.2.3" + resolved "https://registry.yarnpkg.com/@nx/workspace/-/workspace-18.2.3.tgz#797b2aef3613ddb30ea4dbef0bd1bde37b3c60e2" + integrity sha512-en3lSArMrHZ75SqMHnnZjXiMunc6QFDMcglNPQwIE8TuXnV8UWQ1e4hkzRo6hY/YOoY7HcFvMEJ5KyP8OWCmQg== dependencies: - "@nrwl/workspace" "18.1.2" - "@nx/devkit" "18.1.2" + "@nrwl/workspace" "18.2.3" + "@nx/devkit" "18.2.3" chalk "^4.1.0" enquirer "~2.3.6" - nx "18.1.2" + nx "18.2.3" tslib "^2.3.0" yargs-parser "21.1.1" @@ -5760,13 +5822,13 @@ dependencies: any-observable "^0.3.0" -"@schematics/angular@17.2.3": - version "17.2.3" - resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-17.2.3.tgz#0e618017da1139ec921071019ba0c0e13446a996" - integrity sha512-rXsYmWC1a8uvGTC6RwICwg1GLLQlTw8jOSqHf6T2AFMzP4p1FV3/GFSGyPIMl9yPwn6JqbmfQy3Bvj0stQNM0Q== +"@schematics/angular@17.3.3": + version "17.3.3" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-17.3.3.tgz#d6fe530dd478fe2449d0d0990d083a14e2d6a18e" + integrity sha512-kNlyjIKTBhfi8Jab3MCkxNRbbpErbzdu0lZNSL8Nidmqs6Tk23Dc1bZe4t/gPNOCkCvQlwYa6X88SjC/ntyVng== dependencies: - "@angular-devkit/core" "17.2.3" - "@angular-devkit/schematics" "17.2.3" + "@angular-devkit/core" "17.3.3" + "@angular-devkit/schematics" "17.3.3" jsonc-parser "3.2.1" "@schematics/angular@^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0": @@ -7604,22 +7666,6 @@ "@typescript-eslint/types" "5.62.0" "@typescript-eslint/visitor-keys" "5.62.0" -"@typescript-eslint/scope-manager@6.14.0": - version "6.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.14.0.tgz#53d24363fdb5ee0d1d8cda4ed5e5321272ab3d48" - integrity sha512-VT7CFWHbZipPncAZtuALr9y3EuzY1b1t1AEkIq2bTXUPKw+pHoXflGNG5L+Gv6nKul1cz1VH8fz16IThIU0tdg== - dependencies: - "@typescript-eslint/types" "6.14.0" - "@typescript-eslint/visitor-keys" "6.14.0" - -"@typescript-eslint/scope-manager@6.19.0": - version "6.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.19.0.tgz#b6d2abb825b29ab70cb542d220e40c61c1678116" - integrity sha512-dO1XMhV2ehBI6QN8Ufi7I10wmUovmLU0Oru3n5LVlM2JuzB4M+dVphCPLkVpKvGij2j/pHBWuJ9piuXx+BhzxQ== - dependencies: - "@typescript-eslint/types" "6.19.0" - "@typescript-eslint/visitor-keys" "6.19.0" - "@typescript-eslint/scope-manager@6.21.0": version "6.21.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz#ea8a9bfc8f1504a6ac5d59a6df308d3a0630a2b1" @@ -7628,17 +7674,23 @@ "@typescript-eslint/types" "6.21.0" "@typescript-eslint/visitor-keys" "6.21.0" -"@typescript-eslint/type-utils@6.19.0": - version "6.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.19.0.tgz#522a494ef0d3e9fdc5e23a7c22c9331bbade0101" - integrity sha512-mcvS6WSWbjiSxKCwBcXtOM5pRkPQ6kcDds/juxcy/727IQr3xMEcwr/YLHW2A2+Fp5ql6khjbKBzOyjuPqGi/w== +"@typescript-eslint/scope-manager@7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.2.0.tgz#cfb437b09a84f95a0930a76b066e89e35d94e3da" + integrity sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg== + dependencies: + "@typescript-eslint/types" "7.2.0" + "@typescript-eslint/visitor-keys" "7.2.0" + +"@typescript-eslint/scope-manager@7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.5.0.tgz#70f0a7361430ab1043a5f97386da2a0d8b2f4d56" + integrity sha512-Z1r7uJY0MDeUlql9XJ6kRVgk/sP11sr3HKXn268HZyqL7i4cEfrdFuSSY/0tUqT37l5zT0tJOsuDP16kio85iA== dependencies: - "@typescript-eslint/typescript-estree" "6.19.0" - "@typescript-eslint/utils" "6.19.0" - debug "^4.3.4" - ts-api-utils "^1.0.1" + "@typescript-eslint/types" "7.5.0" + "@typescript-eslint/visitor-keys" "7.5.0" -"@typescript-eslint/type-utils@6.21.0", "@typescript-eslint/type-utils@^6.13.2": +"@typescript-eslint/type-utils@6.21.0": version "6.21.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz#6473281cfed4dacabe8004e8521cee0bd9d4c01e" integrity sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag== @@ -7648,13 +7700,23 @@ debug "^4.3.4" ts-api-utils "^1.0.1" -"@typescript-eslint/type-utils@^6.9.1": - version "6.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.14.0.tgz#ac9cb5ba0615c837f1a6b172feeb273d36e4f8af" - integrity sha512-x6OC9Q7HfYKqjnuNu5a7kffIYs3No30isapRBJl1iCHLitD8O0lFbRcVGiOcuyN837fqXzPZ1NS10maQzZMKqw== +"@typescript-eslint/type-utils@7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.2.0.tgz#7be5c30e9b4d49971b79095a1181324ef6089a19" + integrity sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA== + dependencies: + "@typescript-eslint/typescript-estree" "7.2.0" + "@typescript-eslint/utils" "7.2.0" + debug "^4.3.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/type-utils@^7.3.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.5.0.tgz#a8faa403232da3a3901655387c7082111f692cf9" + integrity sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw== dependencies: - "@typescript-eslint/typescript-estree" "6.14.0" - "@typescript-eslint/utils" "6.14.0" + "@typescript-eslint/typescript-estree" "7.5.0" + "@typescript-eslint/utils" "7.5.0" debug "^4.3.4" ts-api-utils "^1.0.1" @@ -7663,21 +7725,21 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== -"@typescript-eslint/types@6.14.0": - version "6.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.14.0.tgz#935307f7a931016b7a5eb25d494ea3e1f613e929" - integrity sha512-uty9H2K4Xs8E47z3SnXEPRNDfsis8JO27amp2GNCnzGETEW3yTqEIVg5+AI7U276oGF/tw6ZA+UesxeQ104ceA== - -"@typescript-eslint/types@6.19.0": - version "6.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.19.0.tgz#689b0498c436272a6a2059b09f44bcbd90de294a" - integrity sha512-lFviGV/vYhOy3m8BJ/nAKoAyNhInTdXpftonhWle66XHAtT1ouBlkjL496b5H5hb8dWXHwtypTqgtb/DEa+j5A== - "@typescript-eslint/types@6.21.0": version "6.21.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== +"@typescript-eslint/types@7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.2.0.tgz#0feb685f16de320e8520f13cca30779c8b7c403f" + integrity sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA== + +"@typescript-eslint/types@7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.5.0.tgz#0a284bcdef3cb850ec9fd57992df9f29d6bde1bc" + integrity sha512-tv5B4IHeAdhR7uS4+bf8Ov3k793VEVHd45viRRkehIUZxm0WF82VPiLgHzA/Xl4TGPg1ZD49vfxBKFPecD5/mg== + "@typescript-eslint/typescript-estree@5.62.0": version "5.62.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" @@ -7691,26 +7753,27 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/typescript-estree@6.14.0": - version "6.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.14.0.tgz#90c7ddd45cd22139adf3d4577580d04c9189ac13" - integrity sha512-yPkaLwK0yH2mZKFE/bXkPAkkFgOv15GJAUzgUVonAbv0Hr4PK/N2yaA/4XQbTZQdygiDkpt5DkxPELqHguNvyw== +"@typescript-eslint/typescript-estree@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz#c47ae7901db3b8bddc3ecd73daff2d0895688c46" + integrity sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ== dependencies: - "@typescript-eslint/types" "6.14.0" - "@typescript-eslint/visitor-keys" "6.14.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" + minimatch "9.0.3" semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/typescript-estree@6.19.0": - version "6.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.19.0.tgz#0813ba364a409afb4d62348aec0202600cb468fa" - integrity sha512-o/zefXIbbLBZ8YJ51NlkSAt2BamrK6XOmuxSR3hynMIzzyMY33KuJ9vuMdFSXW+H0tVvdF9qBPTHA91HDb4BIQ== +"@typescript-eslint/typescript-estree@7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.2.0.tgz#5beda2876c4137f8440c5a84b4f0370828682556" + integrity sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA== dependencies: - "@typescript-eslint/types" "6.19.0" - "@typescript-eslint/visitor-keys" "6.19.0" + "@typescript-eslint/types" "7.2.0" + "@typescript-eslint/visitor-keys" "7.2.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" @@ -7718,13 +7781,13 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/typescript-estree@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz#c47ae7901db3b8bddc3ecd73daff2d0895688c46" - integrity sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ== +"@typescript-eslint/typescript-estree@7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.5.0.tgz#aa5031c511874420f6b5edd90f8e4021525ee776" + integrity sha512-YklQQfe0Rv2PZEueLTUffiQGKQneiIEKKnfIqPIOxgM9lKSZFCjT5Ad4VqRKj/U4+kQE3fa8YQpskViL7WjdPQ== dependencies: - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" + "@typescript-eslint/types" "7.5.0" + "@typescript-eslint/visitor-keys" "7.5.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" @@ -7732,43 +7795,43 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/utils@6.14.0": - version "6.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.14.0.tgz#856a9e274367d99ffbd39c48128b93a86c4261e3" - integrity sha512-XwRTnbvRr7Ey9a1NT6jqdKX8y/atWG+8fAIu3z73HSP8h06i3r/ClMhmaF/RGWGW1tHJEwij1uEg2GbEmPYvYg== +"@typescript-eslint/utils@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.21.0.tgz#4714e7a6b39e773c1c8e97ec587f520840cd8134" + integrity sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ== dependencies: "@eslint-community/eslint-utils" "^4.4.0" "@types/json-schema" "^7.0.12" "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.14.0" - "@typescript-eslint/types" "6.14.0" - "@typescript-eslint/typescript-estree" "6.14.0" + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/typescript-estree" "6.21.0" semver "^7.5.4" -"@typescript-eslint/utils@6.19.0": - version "6.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.19.0.tgz#557b72c3eeb4f73bef8037c85dae57b21beb1a4b" - integrity sha512-QR41YXySiuN++/dC9UArYOg4X86OAYP83OWTewpVx5ct1IZhjjgTLocj7QNxGhWoTqknsgpl7L+hGygCO+sdYw== +"@typescript-eslint/utils@7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.2.0.tgz#fc8164be2f2a7068debb4556881acddbf0b7ce2a" + integrity sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA== dependencies: "@eslint-community/eslint-utils" "^4.4.0" "@types/json-schema" "^7.0.12" "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.19.0" - "@typescript-eslint/types" "6.19.0" - "@typescript-eslint/typescript-estree" "6.19.0" + "@typescript-eslint/scope-manager" "7.2.0" + "@typescript-eslint/types" "7.2.0" + "@typescript-eslint/typescript-estree" "7.2.0" semver "^7.5.4" -"@typescript-eslint/utils@6.21.0", "@typescript-eslint/utils@^6.13.2": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.21.0.tgz#4714e7a6b39e773c1c8e97ec587f520840cd8134" - integrity sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ== +"@typescript-eslint/utils@7.5.0", "@typescript-eslint/utils@^7.3.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.5.0.tgz#bbd963647fbbe9ffea033f42c0fb7e89bb19c858" + integrity sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw== dependencies: "@eslint-community/eslint-utils" "^4.4.0" "@types/json-schema" "^7.0.12" "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.21.0" - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/typescript-estree" "6.21.0" + "@typescript-eslint/scope-manager" "7.5.0" + "@typescript-eslint/types" "7.5.0" + "@typescript-eslint/typescript-estree" "7.5.0" semver "^7.5.4" "@typescript-eslint/utils@^5.45.0": @@ -7793,28 +7856,28 @@ "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" -"@typescript-eslint/visitor-keys@6.14.0": - version "6.14.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.14.0.tgz#1d1d486581819287de824a56c22f32543561138e" - integrity sha512-fB5cw6GRhJUz03MrROVuj5Zm/Q+XWlVdIsFj+Zb1Hvqouc8t+XP2H5y53QYU/MGtd2dPg6/vJJlhoX3xc2ehfw== +"@typescript-eslint/visitor-keys@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz#87a99d077aa507e20e238b11d56cc26ade45fe47" + integrity sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A== dependencies: - "@typescript-eslint/types" "6.14.0" + "@typescript-eslint/types" "6.21.0" eslint-visitor-keys "^3.4.1" -"@typescript-eslint/visitor-keys@6.19.0": - version "6.19.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.19.0.tgz#4565e0ecd63ca1f81b96f1dd76e49f746c6b2b49" - integrity sha512-hZaUCORLgubBvtGpp1JEFEazcuEdfxta9j4iUwdSAr7mEsYYAp3EAUyCZk3VEEqGj6W+AV4uWyrDGtrlawAsgQ== +"@typescript-eslint/visitor-keys@7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.2.0.tgz#5035f177752538a5750cca1af6044b633610bf9e" + integrity sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A== dependencies: - "@typescript-eslint/types" "6.19.0" + "@typescript-eslint/types" "7.2.0" eslint-visitor-keys "^3.4.1" -"@typescript-eslint/visitor-keys@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz#87a99d077aa507e20e238b11d56cc26ade45fe47" - integrity sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A== +"@typescript-eslint/visitor-keys@7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.5.0.tgz#8abcac66f93ef20b093e87a400c2d21e3a6d55ee" + integrity sha512-mcuHM/QircmA6O7fy6nn2w/3ditQkj+SgtOc8DW3uQ10Yfj42amm2i+6F2K4YAOPNNTmE6iM1ynM6lrSwdendA== dependencies: - "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/types" "7.5.0" eslint-visitor-keys "^3.4.1" "@ungap/structured-clone@^1.2.0": @@ -8510,13 +8573,13 @@ at-least-node@^1.0.0: resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== -autoprefixer@10.4.17: - version "10.4.17" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.17.tgz#35cd5695cbbe82f536a50fa025d561b01fdec8be" - integrity sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg== +autoprefixer@10.4.18: + version "10.4.18" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.18.tgz#fcb171a3b017be7cb5d8b7a825f5aacbf2045163" + integrity sha512-1DKbDfsr6KUElM6wg+0zRNkB/Q7WcKYAaK+pzXn+Xqmszm/5Xa9coeNdtP88Vi+dPzZnMjhge8GIV49ZQkDa+g== dependencies: - browserslist "^4.22.2" - caniuse-lite "^1.0.30001578" + browserslist "^4.23.0" + caniuse-lite "^1.0.30001591" fraction.js "^4.3.7" normalize-range "^0.1.2" picocolors "^1.0.0" @@ -8990,6 +9053,16 @@ browserslist@^4.22.2: node-releases "^2.0.14" update-browserslist-db "^1.0.13" +browserslist@^4.23.0: + version "4.23.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" + integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== + dependencies: + caniuse-lite "^1.0.30001587" + electron-to-chromium "^1.4.668" + node-releases "^2.0.14" + update-browserslist-db "^1.0.13" + bs-logger@0.x, bs-logger@^0.2.6: version "0.2.6" resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" @@ -9185,10 +9258,10 @@ caniuse-lite@^1.0.30001565: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz#b4e5c1fa786f733ab78fc70f592df6b3f23244ca" integrity sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw== -caniuse-lite@^1.0.30001578: - version "1.0.30001599" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001599.tgz#571cf4f3f1506df9bf41fcbb6d10d5d017817bce" - integrity sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA== +caniuse-lite@^1.0.30001587, caniuse-lite@^1.0.30001591: + version "1.0.30001606" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001606.tgz#b4d5f67ab0746a3b8b5b6d1f06e39c51beb39a9e" + integrity sha512-LPbwnW4vfpJId225pwjZJOgX1m9sGfbw/RKJvw/t0QhYOOaTXHvkjVGFGPpvwEzufrjvTlsULnVTxdy4/6cqkg== case-sensitive-paths-webpack-plugin@^2.4.0: version "2.4.0" @@ -9868,10 +9941,10 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -critters@0.0.20: - version "0.0.20" - resolved "https://registry.yarnpkg.com/critters/-/critters-0.0.20.tgz#08ddb961550ab7b3a59370537e4f01df208f7646" - integrity sha512-CImNRorKOl5d8TWcnAz5n5izQ6HFsvz29k327/ELy6UFcmbiZNOsinaKvzv16WZR0P6etfSWYzE47C4/56B3Uw== +critters@0.0.22: + version "0.0.22" + resolved "https://registry.yarnpkg.com/critters/-/critters-0.0.22.tgz#ce76b1cbc70078c89d23725646357e3850236dae" + integrity sha512-NU7DEcQZM2Dy8XTKFHxtdnIM/drE312j2T4PCVaSUcS0oBeyT/NImpRw/Ap0zOr/1SE7SgPK9tGPg1WK/sVakw== dependencies: chalk "^4.1.0" css-select "^5.1.0" @@ -9879,7 +9952,7 @@ critters@0.0.20: domhandler "^5.0.2" htmlparser2 "^8.0.2" postcss "^8.4.23" - pretty-bytes "^5.3.0" + postcss-media-query-parser "^0.2.3" cron-parser@^4.2.1: version "4.9.0" @@ -10926,6 +10999,11 @@ electron-to-chromium@^1.4.601: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.614.tgz#2fe789d61fa09cb875569f37c309d0c2701f91c0" integrity sha512-X4ze/9Sc3QWs6h92yerwqv7aB/uU8vCjZcrMjA8N9R1pjMFRe44dLsck5FzLilOYvcXuDn93B+bpGYyufc70gQ== +electron-to-chromium@^1.4.668: + version "1.4.729" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.729.tgz#8477d21e2a50993781950885b2731d92ad532c00" + integrity sha512-bx7+5Saea/qu14kmPTDHQxkp2UnziG3iajUQu3BxFvCOnpAJdDbMV4rSl+EqFDkkpNNVUFlR1kDfpL59xfy1HA== + elegant-spinner@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" @@ -11150,44 +11228,44 @@ esbuild-register@^3.4.0, esbuild-register@^3.5.0: dependencies: debug "^4.3.4" -esbuild-wasm@0.20.0: - version "0.20.0" - resolved "https://registry.yarnpkg.com/esbuild-wasm/-/esbuild-wasm-0.20.0.tgz#79b46ee616d4ca7d207ccd2a80c41de62a9ebfd2" - integrity sha512-Lc9KeQCg1Zf8kCtfDXgy29rx0x8dOuhDWbkP76Wc64q7ctOOc1Zv1C39AxiE+y4N6ONyXtJk4HKpM7jlU7/jSA== +esbuild-wasm@0.20.1: + version "0.20.1" + resolved "https://registry.yarnpkg.com/esbuild-wasm/-/esbuild-wasm-0.20.1.tgz#fdc14b95e3e16ec8e082dd641edb96140c1723f7" + integrity sha512-6v/WJubRsjxBbQdz6izgvx7LsVFvVaGmSdwrFHmEzoVgfXL89hkKPoQHsnVI2ngOkcBUQT9kmAM1hVL1k/Av4A== esbuild-wasm@>=0.15.13: version "0.20.2" resolved "https://registry.yarnpkg.com/esbuild-wasm/-/esbuild-wasm-0.20.2.tgz#bbee2a729776b0b88b765c014f161b627435c5b6" integrity sha512-7o6nmsEqlcXJXMNqnx5K+M4w4OPx7yTFXQHcJyeP3SkXb8p2T8N9E1ayK4vd/qDBepH6fuPoZwiFvZm8x5qv+w== -esbuild@0.20.0: - version "0.20.0" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.20.0.tgz#a7170b63447286cd2ff1f01579f09970e6965da4" - integrity sha512-6iwE3Y2RVYCME1jLpBqq7LQWK3MW6vjV2bZy6gt/WrqkY+WE74Spyc0ThAOYpMtITvnjX09CrC6ym7A/m9mebA== +esbuild@0.20.1: + version "0.20.1" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.20.1.tgz#1e4cbb380ad1959db7609cb9573ee77257724a3e" + integrity sha512-OJwEgrpWm/PCMsLVWXKqvcjme3bHNpOgN7Tb6cQnR5n0TPbQx1/Xrn7rqM+wn17bYeT6MGB5sn1Bh5YiGi70nA== optionalDependencies: - "@esbuild/aix-ppc64" "0.20.0" - "@esbuild/android-arm" "0.20.0" - "@esbuild/android-arm64" "0.20.0" - "@esbuild/android-x64" "0.20.0" - "@esbuild/darwin-arm64" "0.20.0" - "@esbuild/darwin-x64" "0.20.0" - "@esbuild/freebsd-arm64" "0.20.0" - "@esbuild/freebsd-x64" "0.20.0" - "@esbuild/linux-arm" "0.20.0" - "@esbuild/linux-arm64" "0.20.0" - "@esbuild/linux-ia32" "0.20.0" - "@esbuild/linux-loong64" "0.20.0" - "@esbuild/linux-mips64el" "0.20.0" - "@esbuild/linux-ppc64" "0.20.0" - "@esbuild/linux-riscv64" "0.20.0" - "@esbuild/linux-s390x" "0.20.0" - "@esbuild/linux-x64" "0.20.0" - "@esbuild/netbsd-x64" "0.20.0" - "@esbuild/openbsd-x64" "0.20.0" - "@esbuild/sunos-x64" "0.20.0" - "@esbuild/win32-arm64" "0.20.0" - "@esbuild/win32-ia32" "0.20.0" - "@esbuild/win32-x64" "0.20.0" + "@esbuild/aix-ppc64" "0.20.1" + "@esbuild/android-arm" "0.20.1" + "@esbuild/android-arm64" "0.20.1" + "@esbuild/android-x64" "0.20.1" + "@esbuild/darwin-arm64" "0.20.1" + "@esbuild/darwin-x64" "0.20.1" + "@esbuild/freebsd-arm64" "0.20.1" + "@esbuild/freebsd-x64" "0.20.1" + "@esbuild/linux-arm" "0.20.1" + "@esbuild/linux-arm64" "0.20.1" + "@esbuild/linux-ia32" "0.20.1" + "@esbuild/linux-loong64" "0.20.1" + "@esbuild/linux-mips64el" "0.20.1" + "@esbuild/linux-ppc64" "0.20.1" + "@esbuild/linux-riscv64" "0.20.1" + "@esbuild/linux-s390x" "0.20.1" + "@esbuild/linux-x64" "0.20.1" + "@esbuild/netbsd-x64" "0.20.1" + "@esbuild/openbsd-x64" "0.20.1" + "@esbuild/sunos-x64" "0.20.1" + "@esbuild/win32-arm64" "0.20.1" + "@esbuild/win32-ia32" "0.20.1" + "@esbuild/win32-x64" "0.20.1" esbuild@>=0.15.13: version "0.20.2" @@ -12786,10 +12864,10 @@ http2-wrapper@^1.0.0-beta.5.2: quick-lru "^5.1.1" resolve-alpn "^1.0.0" -https-proxy-agent@7.0.2, https-proxy-agent@^7.0.1, https-proxy-agent@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz#e2645b846b90e96c6e6f347fb5b2e41f1590b09b" - integrity sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA== +https-proxy-agent@7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz#8e97b841a029ad8ddc8731f26595bad868cb4168" + integrity sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg== dependencies: agent-base "^7.0.2" debug "4" @@ -12810,6 +12888,14 @@ https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1: agent-base "6" debug "4" +https-proxy-agent@^7.0.1, https-proxy-agent@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz#e2645b846b90e96c6e6f347fb5b2e41f1590b09b" + integrity sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA== + dependencies: + agent-base "^7.0.2" + debug "4" + human-signals@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" @@ -12932,15 +13018,15 @@ ini@1.3.7: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84" integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ== -ini@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ini/-/ini-4.1.1.tgz#d95b3d843b1e906e56d6747d5447904ff50ce7a1" - integrity sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g== +ini@4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/ini/-/ini-4.1.2.tgz#7f646dbd9caea595e61f88ef60bfff8b01f8130a" + integrity sha512-AMB1mvwR1pyBFY/nSevUX6y8nJWS63/SzUKD3JyQn97s4xgIdgQPT75IRouIiBAN4yLQBUShNYVW0+UG25daCw== -inquirer@9.2.14: - version "9.2.14" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-9.2.14.tgz#b55474f1e4f5f0eb28b2f75f09c082209f0cc2ca" - integrity sha512-4ByIMt677Iz5AvjyKrDpzaepIyMewNvDcvwpVVRZNmy9dLakVoVgdCHZXbK1SlVJra1db0JZ6XkJyHsanpdrdQ== +inquirer@9.2.15: + version "9.2.15" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-9.2.15.tgz#2135a36190a6e5c92f5d205e0af1fea36b9d3492" + integrity sha512-vI2w4zl/mDluHt9YEQ/543VTCwPKWiHzKtm9dM2V0NdFcqEexDAjUHzO1oA60HRNaVifGXXM1tRRNluLVHa0Kg== dependencies: "@ljharb/through" "^2.3.12" ansi-escapes "^4.3.2" @@ -14580,10 +14666,10 @@ magic-string@0.30.5, magic-string@^0.30.5, magic-string@~0.30.2: dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" -magic-string@0.30.7: - version "0.30.7" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.7.tgz#0cecd0527d473298679da95a2d7aeb8c64048505" - integrity sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA== +magic-string@0.30.8: + version "0.30.8" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.8.tgz#14e8624246d2bedba70d5462aa99ac9681844613" + integrity sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ== dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" @@ -15009,10 +15095,10 @@ mimic-response@^3.1.0: resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== -mini-css-extract-plugin@2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.0.tgz#1aeae2a90a954b6426c9e8311eab36b450f553a0" - integrity sha512-CxmUYPFcTgET1zImteG/LZOy/4T5rTojesQXkSNBiquhydn78tfbCE9sjIjnJ/UcjNjOC1bphTCCW5rrS7cXAg== +mini-css-extract-plugin@2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.1.tgz#75245f3f30ce3a56dbdd478084df6fe475f02dc7" + integrity sha512-/1HDlyFRxWIZPI1ZpgqlZ8jMw/1Dp/dl3P0L1jtZ+zVcHqwPhGwaJwKL00WVgfnBy6PWCde9W65or7IIETImuA== dependencies: schema-utils "^4.0.0" tapable "^2.2.1" @@ -15547,12 +15633,12 @@ nwsapi@^2.2.2: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.7.tgz#738e0707d3128cb750dddcfe90e4610482df0f30" integrity sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ== -nx@18.1.2: - version "18.1.2" - resolved "https://registry.yarnpkg.com/nx/-/nx-18.1.2.tgz#e193111cbc6162e1e0afad07b24b01a960649423" - integrity sha512-E414xp6lVtiTGdDUMVo72G96G66t7oJMqmcHRMEZ/mVq5ZpNWUhfMuRq5Fh8orXPtrM3xk5SHokmmFvo5PKC+g== +nx@18.2.3: + version "18.2.3" + resolved "https://registry.yarnpkg.com/nx/-/nx-18.2.3.tgz#40d4c18a3b7143e10b3645b5bd47a65c5b9d5e6f" + integrity sha512-4XGvvIzXeeeSj1hObiBL7E7aXX6rbiB1F856AqUdGoysYfkhcxOFyeAv5XsXeukl9gYwh/LH84paXjEOkGaJlA== dependencies: - "@nrwl/tao" "18.1.2" + "@nrwl/tao" "18.2.3" "@yarnpkg/lockfile" "^1.1.0" "@yarnpkg/parsers" "3.0.0-rc.46" "@zkochan/js-yaml" "0.0.6" @@ -15587,16 +15673,16 @@ nx@18.1.2: yargs "^17.6.2" yargs-parser "21.1.1" optionalDependencies: - "@nx/nx-darwin-arm64" "18.1.2" - "@nx/nx-darwin-x64" "18.1.2" - "@nx/nx-freebsd-x64" "18.1.2" - "@nx/nx-linux-arm-gnueabihf" "18.1.2" - "@nx/nx-linux-arm64-gnu" "18.1.2" - "@nx/nx-linux-arm64-musl" "18.1.2" - "@nx/nx-linux-x64-gnu" "18.1.2" - "@nx/nx-linux-x64-musl" "18.1.2" - "@nx/nx-win32-arm64-msvc" "18.1.2" - "@nx/nx-win32-x64-msvc" "18.1.2" + "@nx/nx-darwin-arm64" "18.2.3" + "@nx/nx-darwin-x64" "18.2.3" + "@nx/nx-freebsd-x64" "18.2.3" + "@nx/nx-linux-arm-gnueabihf" "18.2.3" + "@nx/nx-linux-arm64-gnu" "18.2.3" + "@nx/nx-linux-arm64-musl" "18.2.3" + "@nx/nx-linux-x64-gnu" "18.2.3" + "@nx/nx-linux-x64-musl" "18.2.3" + "@nx/nx-win32-arm64-msvc" "18.2.3" + "@nx/nx-win32-x64-msvc" "18.2.3" oauth@0.9.x: version "0.9.15" @@ -16159,10 +16245,10 @@ pirates@^4.0.4, pirates@^4.0.5: resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== -piscina@4.3.1, piscina@^4.2.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/piscina/-/piscina-4.3.1.tgz#eaa59461caa27f07c637e667b14c36a0bd7e7daf" - integrity sha512-MBj0QYm3hJQ/C/wIXTN1OCYC8uQ4BBJ4LVele2P4ZwVQAH04vkk8E1SpDbuemLAL1dZorbuOob9rYqJeWCcCRg== +piscina@4.4.0, piscina@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/piscina/-/piscina-4.4.0.tgz#e3af8e5721d8fad08c6ccaf8a64f9f42279efbb5" + integrity sha512-+AQduEJefrOApE4bV7KRmp3N2JnnyErlVqq4P/jmko4FPz9Z877BCccl/iB3FdrWSUkvbGV9Kan/KllJgat3Vg== optionalDependencies: nice-napi "^1.0.2" @@ -16270,10 +16356,10 @@ postcss-import@~14.1.0: read-cache "^1.0.0" resolve "^1.1.7" -postcss-loader@8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-8.1.0.tgz#590e8bd872d7cdf53c486cbcd40c4c94789f1216" - integrity sha512-AbperNcX3rlob7Ay7A/HQcrofug1caABBkopoFeOQMspZBqcqj6giYn1Bwey/0uiOPAcR+NQD0I2HC7rXzk91w== +postcss-loader@8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-8.1.1.tgz#2822589e7522927344954acb55bbf26e8b195dfe" + integrity sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ== dependencies: cosmiconfig "^9.0.0" jiti "^1.20.0" @@ -16288,6 +16374,11 @@ postcss-loader@^6.1.1: klona "^2.0.5" semver "^7.3.5" +postcss-media-query-parser@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244" + integrity sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig== + postcss-merge-longhand@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-6.0.0.tgz#6f627b27db939bce316eaa97e22400267e798d69" @@ -16495,7 +16586,7 @@ postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^ resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@8.4.35, postcss@^8.4.32: +postcss@8.4.35: version "8.4.35" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.35.tgz#60997775689ce09011edf083a549cea44aabe2f7" integrity sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA== @@ -16522,6 +16613,15 @@ postcss@^8.4.33: picocolors "^1.0.0" source-map-js "^1.2.0" +postcss@^8.4.35: + version "8.4.38" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e" + integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.0" + source-map-js "^1.2.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -16547,7 +16647,7 @@ prettier@^2.8.0: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== -pretty-bytes@^5.3.0, pretty-bytes@^5.4.1: +pretty-bytes@^5.4.1: version "5.6.0" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== @@ -17342,10 +17442,10 @@ safevalues@^0.3.4: resolved "https://registry.yarnpkg.com/safevalues/-/safevalues-0.3.4.tgz#82e846a02b6956d7d40bf9f41e92e13fce0186db" integrity sha512-LRneZZRXNgjzwG4bDQdOTSbze3fHm1EAKN/8bePxnlEZiBmkYEDggaHbuvHI9/hoqHbGfsEA7tWS9GhYHZBBsw== -sass-loader@14.1.0: - version "14.1.0" - resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-14.1.0.tgz#43ba90e0cd8a15a1e932e818c525b0115a0ce8a3" - integrity sha512-LS2mLeFWA+orYxHNu+O18Xe4jR0kyamNOOUsE3NyBP4DvIL+8stHpNX0arYTItdPe80kluIiJ7Wfe/9iHSRO0Q== +sass-loader@14.1.1: + version "14.1.1" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-14.1.1.tgz#2c9d2277c5b1c5fe789cd0570c046d8ad23cb7ca" + integrity sha512-QX8AasDg75monlybel38BZ49JP5Z+uSKfKwF2rO7S74BywaRmGQMUBw9dtkS+ekyM/QnP+NOrRYq8ABMZ9G8jw== dependencies: neo-async "^2.6.2" @@ -17357,10 +17457,10 @@ sass-loader@^12.2.0: klona "^2.0.4" neo-async "^2.6.2" -sass@1.70.0: - version "1.70.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.70.0.tgz#761197419d97b5358cb25f9dd38c176a8a270a75" - integrity sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ== +sass@1.71.1: + version "1.71.1" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.71.1.tgz#dfb09c63ce63f89353777bbd4a88c0a38386ee54" + integrity sha512-wovtnV2PxzteLlfNzbgm1tFXPLoZILYAMJtvoXXkD7/+1uP41eKkIt1ypWq5/q2uT94qHjXehEYfmjKOvjL9sg== dependencies: chokidar ">=3.0.0 <4.0.0" immutable "^4.0.0" @@ -18300,10 +18400,10 @@ terser-webpack-plugin@^5.3.10: serialize-javascript "^6.0.1" terser "^5.26.0" -terser@5.27.0: - version "5.27.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.27.0.tgz#70108689d9ab25fef61c4e93e808e9fd092bf20c" - integrity sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A== +terser@5.29.1: + version "5.29.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.29.1.tgz#44e58045b70c09792ba14bfb7b4e14ca8755b9fa" + integrity sha512-lZQ/fyaIGxsbGxApKmoPTODIzELy3++mXhS5hOqaAWZjQtpq/hFHAc+rm29NND1rYRxRWKcjuARNwULNXa5RtQ== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -18743,10 +18843,10 @@ types-ramda@^0.29.4: dependencies: ts-toolbelt "^9.6.0" -typescript@5.3.3, typescript@~5.3.2: - version "5.3.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" - integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== +typescript@5.4.4, typescript@~5.4.2: + version "5.4.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.4.tgz#eb2471e7b0a5f1377523700a21669dce30c2d952" + integrity sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw== uglify-js@^3.1.4: version "3.17.4" @@ -18785,12 +18885,10 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== -undici@6.6.2: - version "6.6.2" - resolved "https://registry.yarnpkg.com/undici/-/undici-6.6.2.tgz#8dce5ae54e8a3bc7140c2b2a0972b5fde9a88efb" - integrity sha512-vSqvUE5skSxQJ5sztTZ/CdeJb1Wq0Hf44hlYMciqHghvz+K88U0l7D6u1VsndoFgskDcnU+nG3gYmMzJVzd9Qg== - dependencies: - "@fastify/busboy" "^2.0.0" +undici@6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/undici/-/undici-6.7.1.tgz#3cb27222fd5d72c1b2058f4e18bf9b53dd933af8" + integrity sha512-+Wtb9bAQw6HYWzCnxrPTMVEV3Q1QjYanI0E4q02ehReMuquQdLTEFEYbfs7hcImVYKcQkWSwT6buEmSVIiDDtQ== unfetch@^4.2.0: version "4.2.0" @@ -19064,13 +19162,13 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" -vite@5.0.12: - version "5.0.12" - resolved "https://registry.yarnpkg.com/vite/-/vite-5.0.12.tgz#8a2ffd4da36c132aec4adafe05d7adde38333c47" - integrity sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w== +vite@5.1.5: + version "5.1.5" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.1.5.tgz#bdbc2b15e8000d9cc5172f059201178f9c9de5fb" + integrity sha512-BdN1xh0Of/oQafhU+FvopafUp6WaYenLU/NFoL5WyJL++GxkNfieKzBhM24H3HVsPQrlAqB7iJYTHabzaRed5Q== dependencies: esbuild "^0.19.3" - postcss "^8.4.32" + postcss "^8.4.35" rollup "^4.2.0" optionalDependencies: fsevents "~2.3.3" @@ -19145,10 +19243,10 @@ webpack-bundle-analyzer@4.10.1: sirv "^2.0.3" ws "^7.3.1" -webpack-dev-middleware@6.1.1, webpack-dev-middleware@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-6.1.1.tgz#6bbc257ec83ae15522de7a62f995630efde7cc3d" - integrity sha512-y51HrHaFeeWir0YO4f0g+9GwZawuigzcAdRNon6jErXy/SqV/+O6eaVAzDqE6t3e3NpGeR5CS+cCDaTC+V3yEQ== +webpack-dev-middleware@6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-6.1.2.tgz#0463232e59b7d7330fa154121528d484d36eb973" + integrity sha512-Wu+EHmX326YPYUpQLKmKbTyZZJIB8/n6R09pTmB03kJmnMsVPTo9COzHZFr01txwaCAuZvfBJE4ZCHRcKs5JaQ== dependencies: colorette "^2.0.10" memfs "^3.4.12" @@ -19167,6 +19265,17 @@ webpack-dev-middleware@^5.3.1: range-parser "^1.2.1" schema-utils "^4.0.0" +webpack-dev-middleware@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-6.1.1.tgz#6bbc257ec83ae15522de7a62f995630efde7cc3d" + integrity sha512-y51HrHaFeeWir0YO4f0g+9GwZawuigzcAdRNon6jErXy/SqV/+O6eaVAzDqE6t3e3NpGeR5CS+cCDaTC+V3yEQ== + dependencies: + colorette "^2.0.10" + memfs "^3.4.12" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + webpack-dev-server@4.15.1, webpack-dev-server@^4.9.3: version "4.15.1" resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz#8944b29c12760b3a45bdaa70799b17cb91b03df7" @@ -19273,10 +19382,10 @@ webpack@5, webpack@^5.80.0: watchpack "^2.4.0" webpack-sources "^3.2.3" -webpack@5.90.1: - version "5.90.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.90.1.tgz#62ab0c097d7cbe83d32523dbfbb645cdb7c3c01c" - integrity sha512-SstPdlAC5IvgFnhiRok8hqJo/+ArAbNv7rhU4fnWGHNVfN59HSQFaxZDSAL3IFG2YmqxuRs+IU33milSxbPlog== +webpack@5.90.3: + version "5.90.3" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.90.3.tgz#37b8f74d3ded061ba789bb22b31e82eed75bd9ac" + integrity sha512-h6uDYlWCctQRuXBs1oYpVe6sFcWedl0dpcVaTf/YF67J9bKvwJajFulMVSYKHrksMB3I/pIagRzDxwxkebuzKA== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^1.0.5" From 2b97bbd05daabad45afe0fd11ca05a4298b323e0 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 9 Apr 2024 13:44:23 +0200 Subject: [PATCH 111/203] Move getChart() to portfolio calculator (#3255) --- .../calculator/portfolio-calculator.ts | 34 +++++++++- .../portfolio-position-detail.interface.ts | 6 -- .../src/app/portfolio/portfolio.service.ts | 68 ++----------------- 3 files changed, 37 insertions(+), 71 deletions(-) diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index 488f9ce99..a9dbff442 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -4,9 +4,13 @@ import { CurrentPositions } from '@ghostfolio/api/app/portfolio/interfaces/curre import { PortfolioOrder } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order.interface'; import { TransactionPointSymbol } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point-symbol.interface'; import { TransactionPoint } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point.interface'; -import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; +import { + getFactor, + getInterval +} from '@ghostfolio/api/helper/portfolio.helper'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; +import { MAX_CHART_ITEMS } from '@ghostfolio/common/config'; import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper'; import { DataProviderInfo, @@ -17,10 +21,11 @@ import { TimelinePosition, UniqueAsset } from '@ghostfolio/common/interfaces'; -import { GroupBy } from '@ghostfolio/common/types'; +import { DateRange, GroupBy } from '@ghostfolio/common/types'; import { Big } from 'big.js'; import { + differenceInDays, eachDayOfInterval, endOfDay, format, @@ -81,6 +86,31 @@ export abstract class PortfolioCalculator { positions: TimelinePosition[] ): CurrentPositions; + public async getChart({ + dateRange = 'max', + withDataDecimation = true + }: { + dateRange?: DateRange; + withDataDecimation?: boolean; + }): Promise { + if (this.getTransactionPoints().length === 0) { + return []; + } + + const { endDate, startDate } = getInterval(dateRange, this.getStartDate()); + + const daysInMarket = differenceInDays(endDate, startDate) + 1; + const step = withDataDecimation + ? Math.round(daysInMarket / Math.min(daysInMarket, MAX_CHART_ITEMS)) + : 1; + + return this.getChartData({ + step, + end: endDate, + start: startDate + }); + } + public async getChartData({ end = new Date(Date.now()), start, diff --git a/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts b/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts index c058a0249..a32d47e21 100644 --- a/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/portfolio-position-detail.interface.ts @@ -36,9 +36,3 @@ export interface PortfolioPositionDetail { transactionCount: number; value: number; } - -export interface HistoricalDataContainer { - isAllTimeHigh: boolean; - isAllTimeLow: boolean; - items: HistoricalDataItem[]; -} diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 99fb47e2c..198395e51 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -21,7 +21,6 @@ import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/sy import { DEFAULT_CURRENCY, EMERGENCY_FUND_TAG_ID, - MAX_CHART_ITEMS, UNKNOWN_KEY } from '@ghostfolio/common/config'; import { @@ -63,8 +62,7 @@ import { DataSource, Order, Platform, - Prisma, - SymbolProfile + Prisma } from '@prisma/client'; import { Big } from 'big.js'; import { isUUID } from 'class-validator'; @@ -80,15 +78,11 @@ import { } from 'date-fns'; import { isEmpty, isNumber, last, uniq, uniqBy } from 'lodash'; -import { PortfolioCalculator } from './calculator/portfolio-calculator'; import { PerformanceCalculationType, PortfolioCalculatorFactory } from './calculator/portfolio-calculator.factory'; -import { - HistoricalDataContainer, - PortfolioPositionDetail -} from './interfaces/portfolio-position-detail.interface'; +import { PortfolioPositionDetail } from './interfaces/portfolio-position-detail.interface'; import { RulesService } from './rules.service'; const asiaPacificMarkets = require('../../assets/countries/asia-pacific-markets.json'); @@ -292,11 +286,8 @@ export class PortfolioService { currency: this.request.user.Settings.settings.baseCurrency }); - const { items } = await this.getChart({ + const items = await portfolioCalculator.getChart({ dateRange, - impersonationId, - portfolioCalculator, - userId, withDataDecimation: false }); @@ -1161,11 +1152,8 @@ export class PortfolioService { let currentNetPerformanceWithCurrencyEffect = netPerformanceWithCurrencyEffect; - const { items } = await this.getChart({ - dateRange, - impersonationId, - portfolioCalculator, - userId + const items = await portfolioCalculator.getChart({ + dateRange }); const itemOfToday = items.find(({ date }) => { @@ -1381,52 +1369,6 @@ export class PortfolioService { return cashPositions; } - private async getChart({ - dateRange = 'max', - impersonationId, - portfolioCalculator, - userId, - withDataDecimation = true - }: { - dateRange?: DateRange; - impersonationId: string; - portfolioCalculator: PortfolioCalculator; - userId: string; - withDataDecimation?: boolean; - }): Promise { - if (portfolioCalculator.getTransactionPoints().length === 0) { - return { - isAllTimeHigh: false, - isAllTimeLow: false, - items: [] - }; - } - - userId = await this.getUserId(impersonationId, userId); - - const { endDate, startDate } = getInterval( - dateRange, - portfolioCalculator.getStartDate() - ); - - const daysInMarket = differenceInDays(endDate, startDate) + 1; - const step = withDataDecimation - ? Math.round(daysInMarket / Math.min(daysInMarket, MAX_CHART_ITEMS)) - : 1; - - const items = await portfolioCalculator.getChartData({ - step, - end: endDate, - start: startDate - }); - - return { - items, - isAllTimeHigh: false, - isAllTimeLow: false - }; - } - private getDividendsByGroup({ dividends, groupBy From 34d9ceb009cd4240e3ff9cd8f9970a6be8ecb7a3 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 11 Apr 2024 19:14:03 +0200 Subject: [PATCH 112/203] Feature/add support to immediately execute queue job (#3259) * Add support to immediately execute queue job * Update changelog --- CHANGELOG.md | 4 + .../src/app/admin/queue/queue.controller.ts | 7 ++ apps/api/src/app/admin/queue/queue.service.ts | 4 + .../admin-jobs/admin-jobs.component.ts | 9 ++ .../app/components/admin-jobs/admin-jobs.html | 3 + apps/client/src/app/services/admin.service.ts | 4 + apps/client/src/locales/messages.de.xlf | 86 ++++++++++--------- apps/client/src/locales/messages.es.xlf | 86 ++++++++++--------- apps/client/src/locales/messages.fr.xlf | 86 ++++++++++--------- apps/client/src/locales/messages.it.xlf | 86 ++++++++++--------- apps/client/src/locales/messages.nl.xlf | 86 ++++++++++--------- apps/client/src/locales/messages.pl.xlf | 86 ++++++++++--------- apps/client/src/locales/messages.pt.xlf | 86 ++++++++++--------- apps/client/src/locales/messages.tr.xlf | 86 ++++++++++--------- apps/client/src/locales/messages.xlf | 85 +++++++++--------- apps/client/src/locales/messages.zh.xlf | 86 ++++++++++--------- 16 files changed, 500 insertions(+), 390 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9aacb00de..cbb92106f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Added support to immediately execute a queue job from the admin control panel + ### Changed - Upgraded `angular` from version `17.2.4` to `17.3.3` diff --git a/apps/api/src/app/admin/queue/queue.controller.ts b/apps/api/src/app/admin/queue/queue.controller.ts index 89bd851bc..978cb9721 100644 --- a/apps/api/src/app/admin/queue/queue.controller.ts +++ b/apps/api/src/app/admin/queue/queue.controller.ts @@ -46,4 +46,11 @@ export class QueueController { public async deleteJob(@Param('id') id: string): Promise { return this.queueService.deleteJob(id); } + + @Get('job/:id/execute') + @HasPermission(permissions.accessAdminControl) + @UseGuards(AuthGuard('jwt'), HasPermissionGuard) + public async executeJob(@Param('id') id: string): Promise { + return this.queueService.executeJob(id); + } } diff --git a/apps/api/src/app/admin/queue/queue.service.ts b/apps/api/src/app/admin/queue/queue.service.ts index c5143e870..e4f29bc60 100644 --- a/apps/api/src/app/admin/queue/queue.service.ts +++ b/apps/api/src/app/admin/queue/queue.service.ts @@ -32,6 +32,10 @@ export class QueueService { } } + public async executeJob(aId: string) { + return (await this.dataGatheringQueue.getJob(aId))?.promote(); + } + public async getJobs({ limit = 1000, status = QUEUE_JOB_STATUS_LIST diff --git a/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts b/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts index 5eff103df..99d67dea2 100644 --- a/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts +++ b/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts @@ -98,6 +98,15 @@ export class AdminJobsComponent implements OnDestroy, OnInit { }); } + public onExecuteJob(aId: string) { + this.adminService + .executeJob(aId) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(() => { + this.fetchJobs(); + }); + } + public onViewData(aData: AdminJobs['jobs'][0]['data']) { alert(JSON.stringify(aData, null, ' ')); } diff --git a/apps/client/src/app/components/admin-jobs/admin-jobs.html b/apps/client/src/app/components/admin-jobs/admin-jobs.html index 12b31dfc8..31dad0ca6 100644 --- a/apps/client/src/app/components/admin-jobs/admin-jobs.html +++ b/apps/client/src/app/components/admin-jobs/admin-jobs.html @@ -147,6 +147,9 @@ > View Stacktrace + diff --git a/apps/client/src/app/services/admin.service.ts b/apps/client/src/app/services/admin.service.ts index df2c0b603..5bc281900 100644 --- a/apps/client/src/app/services/admin.service.ts +++ b/apps/client/src/app/services/admin.service.ts @@ -72,6 +72,10 @@ export class AdminService { return this.http.delete(`/api/v1/tag/${aId}`); } + public executeJob(aId: string) { + return this.http.get(`/api/v1/admin/queue/job/${aId}/execute`); + } + public fetchAdminData() { return this.http.get('/api/v1/admin'); } diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index f5c2bb6e8..033f5c58d 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -110,7 +110,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 302 + 300 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -130,7 +130,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 214 + 215 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -338,7 +338,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 272 + 270 @@ -426,7 +426,7 @@ Job löschen apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 154 @@ -478,7 +478,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 353 + 365 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -486,7 +486,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 19 + 26 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -506,7 +506,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 412 + 408 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -522,7 +522,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 372 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -530,7 +530,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 33 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -546,7 +546,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 419 + 415 @@ -838,7 +838,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 327 + 325 apps/client/src/app/pages/accounts/accounts-page.html @@ -1496,15 +1496,15 @@ Sektoren apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 190 + 191 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 312 + 316 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 241 + 239 apps/client/src/app/pages/public/public-page.html @@ -1516,15 +1516,15 @@ Länder apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 200 + 201 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 323 + 327 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 253 + 251 @@ -1536,11 +1536,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 347 + 345 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 367 + 363 libs/ui/src/lib/assistant/assistant.html @@ -1552,7 +1552,7 @@ Datenfehler melden apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 365 + 363 @@ -2064,7 +2064,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 220 + 222 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2488,7 +2488,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 314 + 310 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2500,7 +2500,7 @@ Kommentar apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 340 + 352 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2508,7 +2508,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 323 + 319 @@ -2524,15 +2524,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 229 + 232 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 199 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 338 + 334 @@ -2888,15 +2888,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 242 + 245 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 208 + 206 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 350 @@ -2904,11 +2904,11 @@ Sektor apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 176 + 174 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 225 + 223 @@ -2924,7 +2924,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 235 + 233 @@ -3472,7 +3472,7 @@ Symbol Zuordnung apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 276 + 279 @@ -4024,7 +4024,7 @@ Ups! Der historische Wechselkurs konnte nicht abgerufen werden vom apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 304 + 300 @@ -4148,7 +4148,7 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 334 + 339 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -4536,7 +4536,7 @@ Scraper Konfiguration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 287 + 291 @@ -13356,7 +13356,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 273 @@ -14668,7 +14668,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 305 + 309 @@ -15015,6 +15015,14 @@ 156 + + Execute Job + Job ausführen + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 151 + + diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index 9afa12b84..c770a2dc2 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -111,7 +111,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 302 + 300 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -131,7 +131,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 214 + 215 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -339,7 +339,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 272 + 270 @@ -427,7 +427,7 @@ Elimina el trabajo apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 154 @@ -479,7 +479,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 353 + 365 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -487,7 +487,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 19 + 26 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -507,7 +507,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 412 + 408 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -523,7 +523,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 372 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -531,7 +531,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 33 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -547,7 +547,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 419 + 415 @@ -839,7 +839,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 327 + 325 apps/client/src/app/pages/accounts/accounts-page.html @@ -1494,15 +1494,15 @@ Sectores apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 190 + 191 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 312 + 316 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 241 + 239 apps/client/src/app/pages/public/public-page.html @@ -1514,15 +1514,15 @@ Países apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 200 + 201 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 323 + 327 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 253 + 251 @@ -1534,11 +1534,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 347 + 345 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 367 + 363 libs/ui/src/lib/assistant/assistant.html @@ -1550,7 +1550,7 @@ Reporta un anomalía de los datos apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 365 + 363 @@ -2062,7 +2062,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 220 + 222 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2486,7 +2486,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 314 + 310 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2498,7 +2498,7 @@ Nota apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 340 + 352 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2506,7 +2506,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 323 + 319 @@ -2522,15 +2522,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 229 + 232 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 199 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 338 + 334 @@ -2874,15 +2874,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 242 + 245 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 208 + 206 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 350 @@ -2930,11 +2930,11 @@ Sector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 176 + 174 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 225 + 223 @@ -2950,7 +2950,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 235 + 233 @@ -3470,7 +3470,7 @@ Mapeo de símbolos apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 276 + 279 @@ -4022,7 +4022,7 @@ Oops! Could not get the historical exchange rate from apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 304 + 300 @@ -4146,7 +4146,7 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 334 + 339 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -4534,7 +4534,7 @@ Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 287 + 291 @@ -13354,7 +13354,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 273 @@ -14666,7 +14666,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 305 + 309 @@ -15013,6 +15013,14 @@ 156 + + Execute Job + Execute Job + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 151 + + diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index c315dda63..3a241feda 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -122,7 +122,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 302 + 300 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -142,7 +142,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 214 + 215 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -198,7 +198,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 220 + 222 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -386,7 +386,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 272 + 270 @@ -482,7 +482,7 @@ Supprimer Tâche apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 154 @@ -534,7 +534,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 353 + 365 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -542,7 +542,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 19 + 26 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -562,7 +562,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 412 + 408 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -578,7 +578,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 372 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -586,7 +586,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 33 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -602,7 +602,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 419 + 415 @@ -626,15 +626,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 229 + 232 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 199 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 338 + 334 @@ -650,15 +650,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 242 + 245 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 208 + 206 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 350 @@ -758,11 +758,11 @@ Secteur apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 176 + 174 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 225 + 223 @@ -778,7 +778,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 235 + 233 @@ -786,15 +786,15 @@ Secteurs apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 190 + 191 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 312 + 316 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 241 + 239 apps/client/src/app/pages/public/public-page.html @@ -806,15 +806,15 @@ Pays apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 200 + 201 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 323 + 327 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 253 + 251 @@ -822,7 +822,7 @@ Équivalence de Symboles apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 276 + 279 @@ -830,7 +830,7 @@ Note apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 340 + 352 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -838,7 +838,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 323 + 319 @@ -930,11 +930,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 347 + 345 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 367 + 363 libs/ui/src/lib/assistant/assistant.html @@ -1050,7 +1050,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 327 + 325 apps/client/src/app/pages/accounts/accounts-page.html @@ -1913,7 +1913,7 @@ Signaler une Erreur de Données apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 365 + 363 @@ -2697,7 +2697,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 314 + 310 libs/ui/src/lib/activities-table/activities-table.component.html @@ -4021,7 +4021,7 @@ Oups ! Nous n'avons pas pu obtenir le taux de change historique à partir de apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 304 + 300 @@ -4145,7 +4145,7 @@ Lien apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 334 + 339 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -4533,7 +4533,7 @@ Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 287 + 291 @@ -13353,7 +13353,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 273 @@ -14665,7 +14665,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 305 + 309 @@ -15012,6 +15012,14 @@ 156 + + Execute Job + Execute Job + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 151 + + diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index 631ad824c..99f669151 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -111,7 +111,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 302 + 300 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -131,7 +131,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 214 + 215 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -339,7 +339,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 272 + 270 @@ -427,7 +427,7 @@ Elimina il lavoro apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 154 @@ -479,7 +479,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 353 + 365 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -487,7 +487,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 19 + 26 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -507,7 +507,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 412 + 408 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -523,7 +523,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 372 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -531,7 +531,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 33 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -547,7 +547,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 419 + 415 @@ -839,7 +839,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 327 + 325 apps/client/src/app/pages/accounts/accounts-page.html @@ -1494,15 +1494,15 @@ Settori apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 190 + 191 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 312 + 316 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 241 + 239 apps/client/src/app/pages/public/public-page.html @@ -1514,15 +1514,15 @@ Paesi apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 200 + 201 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 323 + 327 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 253 + 251 @@ -1534,11 +1534,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 347 + 345 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 367 + 363 libs/ui/src/lib/assistant/assistant.html @@ -1550,7 +1550,7 @@ Segnala un'anomalia dei dati apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 365 + 363 @@ -2062,7 +2062,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 220 + 222 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2486,7 +2486,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 314 + 310 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2498,7 +2498,7 @@ Nota apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 340 + 352 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2506,7 +2506,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 323 + 319 @@ -2522,15 +2522,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 229 + 232 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 199 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 338 + 334 @@ -2874,15 +2874,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 242 + 245 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 208 + 206 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 350 @@ -2930,11 +2930,11 @@ Settore apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 176 + 174 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 225 + 223 @@ -2950,7 +2950,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 235 + 233 @@ -3470,7 +3470,7 @@ Mappatura dei simboli apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 276 + 279 @@ -4022,7 +4022,7 @@ Ops! Impossibile ottenere il tasso di cambio storico da apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 304 + 300 @@ -4146,7 +4146,7 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 334 + 339 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -4534,7 +4534,7 @@ Configurazione dello scraper apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 287 + 291 @@ -13354,7 +13354,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 273 @@ -14666,7 +14666,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 305 + 309 @@ -15013,6 +15013,14 @@ 156 + + Execute Job + Execute Job + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 151 + + diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index 6464af55e..9116a411a 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -110,7 +110,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 302 + 300 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -130,7 +130,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 214 + 215 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -338,7 +338,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 272 + 270 @@ -426,7 +426,7 @@ Taak verwijderen apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 154 @@ -478,7 +478,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 353 + 365 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -486,7 +486,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 19 + 26 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -506,7 +506,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 412 + 408 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -522,7 +522,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 372 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -530,7 +530,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 33 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -546,7 +546,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 419 + 415 @@ -838,7 +838,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 327 + 325 apps/client/src/app/pages/accounts/accounts-page.html @@ -1493,15 +1493,15 @@ Sectoren apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 190 + 191 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 312 + 316 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 241 + 239 apps/client/src/app/pages/public/public-page.html @@ -1513,15 +1513,15 @@ Landen apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 200 + 201 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 323 + 327 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 253 + 251 @@ -1533,11 +1533,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 347 + 345 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 367 + 363 libs/ui/src/lib/assistant/assistant.html @@ -1549,7 +1549,7 @@ Gegevensstoring melden apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 365 + 363 @@ -2061,7 +2061,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 220 + 222 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2485,7 +2485,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 314 + 310 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2497,7 +2497,7 @@ Opmerking apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 340 + 352 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2505,7 +2505,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 323 + 319 @@ -2521,15 +2521,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 229 + 232 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 199 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 338 + 334 @@ -2873,15 +2873,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 242 + 245 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 208 + 206 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 350 @@ -2929,11 +2929,11 @@ Sector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 176 + 174 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 225 + 223 @@ -2949,7 +2949,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 235 + 233 @@ -3469,7 +3469,7 @@ Symbool toewijzen apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 276 + 279 @@ -4021,7 +4021,7 @@ Oeps! Kon de historische wisselkoers niet krijgen van apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 304 + 300 @@ -4145,7 +4145,7 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 334 + 339 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -4533,7 +4533,7 @@ Scraper instellingen apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 287 + 291 @@ -13353,7 +13353,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 273 @@ -14665,7 +14665,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 305 + 309 @@ -15012,6 +15012,14 @@ 156 + + Execute Job + Execute Job + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 151 + + diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf index 5d685039c..c02f78aee 100644 --- a/apps/client/src/locales/messages.pl.xlf +++ b/apps/client/src/locales/messages.pl.xlf @@ -1626,7 +1626,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 302 + 300 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -1674,7 +1674,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 214 + 215 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1730,7 +1730,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 220 + 222 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1918,7 +1918,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 272 + 270 @@ -1998,7 +1998,7 @@ Delete Job apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 154 @@ -2050,7 +2050,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 353 + 365 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2058,7 +2058,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 19 + 26 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -2078,7 +2078,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 412 + 408 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -2094,7 +2094,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 372 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2102,7 +2102,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 33 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -2118,7 +2118,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 419 + 415 @@ -2174,15 +2174,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 229 + 232 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 199 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 338 + 334 @@ -2198,15 +2198,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 242 + 245 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 208 + 206 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 350 @@ -2338,11 +2338,11 @@ Sector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 176 + 174 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 225 + 223 @@ -2358,7 +2358,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 235 + 233 @@ -2366,15 +2366,15 @@ Sectors apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 190 + 191 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 312 + 316 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 241 + 239 apps/client/src/app/pages/public/public-page.html @@ -2386,15 +2386,15 @@ Countries apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 200 + 201 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 323 + 327 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 253 + 251 @@ -2402,7 +2402,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 273 @@ -2410,7 +2410,7 @@ Symbol Mapping apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 276 + 279 @@ -2418,7 +2418,7 @@ Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 287 + 291 @@ -2426,7 +2426,7 @@ Note apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 340 + 352 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2434,7 +2434,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 323 + 319 @@ -2646,7 +2646,7 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 334 + 339 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -2678,7 +2678,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 327 + 325 apps/client/src/app/pages/accounts/accounts-page.html @@ -2730,11 +2730,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 347 + 345 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 367 + 363 libs/ui/src/lib/assistant/assistant.html @@ -3528,7 +3528,7 @@ Report Data Glitch apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 365 + 363 @@ -5068,7 +5068,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 314 + 310 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5080,7 +5080,7 @@ Oops! Could not get the historical exchange rate from apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 304 + 300 @@ -14668,7 +14668,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 305 + 309 @@ -15015,6 +15015,14 @@ 156 + + Execute Job + Execute Job + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 151 + + diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index 11794a252..6ebacade4 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -122,7 +122,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 302 + 300 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -142,7 +142,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 214 + 215 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -198,7 +198,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 220 + 222 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -386,7 +386,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 272 + 270 @@ -482,7 +482,7 @@ Apagar Tarefa apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 154 @@ -534,7 +534,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 353 + 365 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -542,7 +542,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 19 + 26 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -562,7 +562,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 412 + 408 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -578,7 +578,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 372 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -586,7 +586,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 33 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -602,7 +602,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 419 + 415 @@ -626,15 +626,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 229 + 232 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 199 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 338 + 334 @@ -650,15 +650,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 242 + 245 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 208 + 206 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 350 @@ -918,7 +918,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 327 + 325 apps/client/src/app/pages/accounts/accounts-page.html @@ -1789,11 +1789,11 @@ Setor apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 176 + 174 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 225 + 223 @@ -1809,7 +1809,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 235 + 233 @@ -1817,15 +1817,15 @@ Setores apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 190 + 191 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 312 + 316 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 241 + 239 apps/client/src/app/pages/public/public-page.html @@ -1837,15 +1837,15 @@ Países apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 200 + 201 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 323 + 327 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 253 + 251 @@ -1857,11 +1857,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 347 + 345 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 367 + 363 libs/ui/src/lib/assistant/assistant.html @@ -1873,7 +1873,7 @@ Dados do Relatório com Problema apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 365 + 363 @@ -2601,7 +2601,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 314 + 310 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2613,7 +2613,7 @@ Nota apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 340 + 352 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2621,7 +2621,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 323 + 319 @@ -3437,7 +3437,7 @@ Mapeamento de Símbolo apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 276 + 279 @@ -4021,7 +4021,7 @@ Oops! Não foi possível obter a taxa de câmbio histórica de apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 304 + 300 @@ -4145,7 +4145,7 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 334 + 339 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -4533,7 +4533,7 @@ Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 287 + 291 @@ -13353,7 +13353,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 273 @@ -14665,7 +14665,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 305 + 309 @@ -15012,6 +15012,14 @@ 156 + + Execute Job + Execute Job + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 151 + + diff --git a/apps/client/src/locales/messages.tr.xlf b/apps/client/src/locales/messages.tr.xlf index 7bd98ba40..39f5817ce 100644 --- a/apps/client/src/locales/messages.tr.xlf +++ b/apps/client/src/locales/messages.tr.xlf @@ -1618,7 +1618,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 302 + 300 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -1638,7 +1638,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 214 + 215 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1694,7 +1694,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 220 + 222 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1866,7 +1866,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 272 + 270 @@ -1962,7 +1962,7 @@ İşleri Sil apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 154 @@ -2014,7 +2014,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 353 + 365 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2022,7 +2022,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 19 + 26 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -2042,7 +2042,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 412 + 408 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -2058,7 +2058,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 372 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2066,7 +2066,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 33 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -2082,7 +2082,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 419 + 415 @@ -2130,15 +2130,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 229 + 232 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 199 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 338 + 334 @@ -2154,15 +2154,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 242 + 245 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 208 + 206 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 350 @@ -2270,11 +2270,11 @@ Sektör apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 176 + 174 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 225 + 223 @@ -2290,7 +2290,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 235 + 233 @@ -2298,15 +2298,15 @@ Sektörler apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 190 + 191 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 312 + 316 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 241 + 239 apps/client/src/app/pages/public/public-page.html @@ -2318,15 +2318,15 @@ Ülkeler apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 200 + 201 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 323 + 327 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 253 + 251 @@ -2334,7 +2334,7 @@ Sembol Eşleştirme apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 276 + 279 @@ -2342,7 +2342,7 @@ Veri Toplayıcı Yapılandırması apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 287 + 291 @@ -2350,7 +2350,7 @@ Not apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 340 + 352 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2358,7 +2358,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 323 + 319 @@ -2470,11 +2470,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 347 + 345 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 367 + 363 libs/ui/src/lib/assistant/assistant.html @@ -2558,7 +2558,7 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 334 + 339 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -2590,7 +2590,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 327 + 325 apps/client/src/app/pages/accounts/accounts-page.html @@ -3369,7 +3369,7 @@ Rapor Veri Sorunu apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 365 + 363 @@ -4533,7 +4533,7 @@ Hay Allah! Geçmiş döviz kuru alınamadı: apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 304 + 300 @@ -4545,7 +4545,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 314 + 310 libs/ui/src/lib/activities-table/activities-table.component.html @@ -13353,7 +13353,7 @@ Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 273 @@ -14665,7 +14665,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 305 + 309 @@ -15012,6 +15012,14 @@ 156 + + Execute Job + Execute Job + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 151 + + diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index f11713076..53ff1578b 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -1594,7 +1594,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 302 + 300 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -1646,7 +1646,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 214 + 215 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1700,7 +1700,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 220 + 222 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1881,7 +1881,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 272 + 270 @@ -1952,7 +1952,7 @@ Delete Job apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 154 @@ -2000,7 +2000,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 353 + 365 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2008,7 +2008,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 19 + 26 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -2028,7 +2028,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 412 + 408 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -2043,7 +2043,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 372 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2051,7 +2051,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 33 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -2067,7 +2067,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 419 + 415 @@ -2117,15 +2117,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 229 + 232 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 199 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 338 + 334 @@ -2140,15 +2140,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 242 + 245 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 208 + 206 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 350 @@ -2267,11 +2267,11 @@ Sector apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 176 + 174 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 225 + 223 @@ -2286,22 +2286,22 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 235 + 233 Sectors apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 190 + 191 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 312 + 316 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 241 + 239 apps/client/src/app/pages/public/public-page.html @@ -2312,43 +2312,43 @@ Countries apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 200 + 201 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 323 + 327 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 253 + 251 Benchmark apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 273 Symbol Mapping apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 276 + 279 Scraper Configuration apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 287 + 291 Note apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 340 + 352 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2356,7 +2356,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 323 + 319 @@ -2549,7 +2549,7 @@ Url apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 334 + 339 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -2580,7 +2580,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 327 + 325 apps/client/src/app/pages/accounts/accounts-page.html @@ -2627,11 +2627,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 347 + 345 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 367 + 363 libs/ui/src/lib/assistant/assistant.html @@ -3340,7 +3340,7 @@ Report Data Glitch apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 365 + 363 @@ -4719,7 +4719,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 314 + 310 libs/ui/src/lib/activities-table/activities-table.component.html @@ -4730,7 +4730,7 @@ Oops! Could not get the historical exchange rate from apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 304 + 300 @@ -14086,7 +14086,7 @@ Test apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 305 + 309 @@ -14387,6 +14387,13 @@ 156 + + Execute Job + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 151 + + diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index af033158b..fa47da7e0 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -1627,7 +1627,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 302 + 300 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -1683,7 +1683,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 214 + 215 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -1739,7 +1739,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 220 + 222 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1927,7 +1927,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 272 + 270 @@ -2007,7 +2007,7 @@ 删除作业 apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 154 @@ -2059,7 +2059,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 353 + 365 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2067,7 +2067,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 19 + 26 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -2087,7 +2087,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 412 + 408 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -2103,7 +2103,7 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 360 + 372 apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.html @@ -2111,7 +2111,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 33 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -2127,7 +2127,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 419 + 415 @@ -2183,15 +2183,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 229 + 232 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 199 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 338 + 334 @@ -2207,15 +2207,15 @@ apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 242 + 245 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 208 + 206 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 354 + 350 @@ -2347,11 +2347,11 @@ 行业 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 176 + 174 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 225 + 223 @@ -2367,7 +2367,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 235 + 233 @@ -2375,15 +2375,15 @@ 行业 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 190 + 191 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 312 + 316 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 241 + 239 apps/client/src/app/pages/public/public-page.html @@ -2395,15 +2395,15 @@ 国家 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 200 + 201 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 323 + 327 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 253 + 251 @@ -2411,7 +2411,7 @@ 基准 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 270 + 273 @@ -2419,7 +2419,7 @@ 符号映射 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 276 + 279 @@ -2427,7 +2427,7 @@ 刮削配置 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 287 + 291 @@ -2435,7 +2435,7 @@ 笔记 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 340 + 352 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -2443,7 +2443,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 323 + 319 @@ -2663,7 +2663,7 @@ 网址 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 334 + 339 apps/client/src/app/components/admin-platform/admin-platform.component.html @@ -2695,7 +2695,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 327 + 325 apps/client/src/app/pages/accounts/accounts-page.html @@ -2747,11 +2747,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 347 + 345 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 367 + 363 libs/ui/src/lib/assistant/assistant.html @@ -3545,7 +3545,7 @@ 报告数据故障 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 365 + 363 @@ -5085,7 +5085,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 314 + 310 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5097,7 +5097,7 @@ 哎呀!无法获取历史汇率 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 304 + 300 @@ -14677,7 +14677,7 @@ 测试 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html - 305 + 309 @@ -15016,6 +15016,14 @@ 156 + + Execute Job + Execute Job + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 151 + + From 6f8fe45fc277aeea5332674f82f86e201dbe6be1 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 11 Apr 2024 19:14:56 +0200 Subject: [PATCH 113/203] Update OSS Friends (#3258) --- apps/client/src/assets/oss-friends.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/client/src/assets/oss-friends.json b/apps/client/src/assets/oss-friends.json index cbbbd5987..88037573f 100644 --- a/apps/client/src/assets/oss-friends.json +++ b/apps/client/src/assets/oss-friends.json @@ -1,5 +1,5 @@ { - "createdAt": "2024-03-11T00:00:00.000Z", + "createdAt": "2024-04-09T00:00:00.000Z", "data": [ { "name": "Aptabase", @@ -86,6 +86,11 @@ "description": "Open source, end-to-end encrypted platform that lets you securely manage secrets and configs across your team, devices, and infrastructure.", "href": "https://infisical.com" }, + { + "name": "Keep", + "description": "Open source alert management and AIOps platform.", + "href": "https://keephq.dev" + }, { "name": "Langfuse", "description": "Open source LLM engineering platform. Debug, analyze and iterate together.", @@ -119,7 +124,7 @@ { "name": "Requestly", "description": "Makes frontend development cycle 10x faster with API Client, Mock Server, Intercept & Modify HTTP Requests and Session Replays.", - "href": "https://requestly.io" + "href": "https://requestly.com" }, { "name": "Revert", From 45340b581f4b39f775b7d17645fb70b368852b47 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 12 Apr 2024 15:13:34 +0200 Subject: [PATCH 114/203] Bugfix/fix public page by including markets data (#3263) * Include markets data * Update changelog --- CHANGELOG.md | 4 ++++ apps/api/src/app/portfolio/portfolio.controller.ts | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cbb92106f..68a85fd95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Upgraded `Nx` from version `18.1.2` to `18.2.3` - Upgraded `prisma` from version `5.11.0` to `5.12.1` +### Fixed + +- Fixed an issue in the public page + ## 2.71.0 - 2024-04-07 ### Added diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 0ae596d84..efb9318d7 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -539,7 +539,8 @@ export class PortfolioController { const { holdings } = await this.portfolioService.getDetails({ filters: [{ id: 'EQUITY', type: 'ASSET_CLASS' }], impersonationId: access.userId, - userId: user.id + userId: user.id, + withMarkets: true }); const portfolioPublicDetails: PortfolioPublicDetails = { From 4e7d93db13c6af29bd222c1f93876544d69fdc65 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 13 Apr 2024 09:28:14 +0200 Subject: [PATCH 115/203] Feature/adapt priorities of data gathering jobs (#3262) * Adapt priorities of data gathering jobs * Update changelog --- CHANGELOG.md | 2 + apps/api/src/app/admin/admin.controller.ts | 16 +++---- apps/api/src/app/admin/queue/queue.service.ts | 1 + apps/api/src/app/import/import.service.ts | 13 ++++-- apps/api/src/app/order/order.controller.ts | 22 ++++++---- apps/api/src/app/order/order.service.ts | 22 ++++++---- apps/api/src/services/cron.service.ts | 4 +- .../data-gathering/data-gathering.service.ts | 40 +++++++++++++----- .../admin-jobs/admin-jobs.component.ts | 13 +++++- .../app/components/admin-jobs/admin-jobs.html | 42 ++++++++++++++++--- libs/common/src/lib/config.ts | 7 ++-- .../lib/interfaces/admin-jobs.interface.ts | 1 + 12 files changed, 136 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68a85fd95..73999efb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added support to immediately execute a queue job from the admin control panel +- Added a priority column to the queue jobs view in the admin control panel ### Changed +- Adapted the priorities of queue jobs - Upgraded `angular` from version `17.2.4` to `17.3.3` - Upgraded `Nx` from version `18.1.2` to `18.2.3` - Upgraded `prisma` from version `5.11.0` to `5.12.1` diff --git a/apps/api/src/app/admin/admin.controller.ts b/apps/api/src/app/admin/admin.controller.ts index dab8fb8b2..298a471c3 100644 --- a/apps/api/src/app/admin/admin.controller.ts +++ b/apps/api/src/app/admin/admin.controller.ts @@ -7,13 +7,12 @@ import { ManualService } from '@ghostfolio/api/services/data-provider/manual/man import { MarketDataService } from '@ghostfolio/api/services/market-data/market-data.service'; import { PropertyDto } from '@ghostfolio/api/services/property/property.dto'; import { + DATA_GATHERING_QUEUE_PRIORITY_HIGH, + DATA_GATHERING_QUEUE_PRIORITY_MEDIUM, GATHER_ASSET_PROFILE_PROCESS, GATHER_ASSET_PROFILE_PROCESS_OPTIONS } from '@ghostfolio/common/config'; -import { - getAssetProfileIdentifier, - resetHours -} from '@ghostfolio/common/helper'; +import { getAssetProfileIdentifier } from '@ghostfolio/common/helper'; import { AdminData, AdminMarketData, @@ -94,7 +93,8 @@ export class AdminController { name: GATHER_ASSET_PROFILE_PROCESS, opts: { ...GATHER_ASSET_PROFILE_PROCESS_OPTIONS, - jobId: getAssetProfileIdentifier({ dataSource, symbol }) + jobId: getAssetProfileIdentifier({ dataSource, symbol }), + priority: DATA_GATHERING_QUEUE_PRIORITY_MEDIUM } }; }) @@ -119,7 +119,8 @@ export class AdminController { name: GATHER_ASSET_PROFILE_PROCESS, opts: { ...GATHER_ASSET_PROFILE_PROCESS_OPTIONS, - jobId: getAssetProfileIdentifier({ dataSource, symbol }) + jobId: getAssetProfileIdentifier({ dataSource, symbol }), + priority: DATA_GATHERING_QUEUE_PRIORITY_MEDIUM } }; }) @@ -141,7 +142,8 @@ export class AdminController { name: GATHER_ASSET_PROFILE_PROCESS, opts: { ...GATHER_ASSET_PROFILE_PROCESS_OPTIONS, - jobId: getAssetProfileIdentifier({ dataSource, symbol }) + jobId: getAssetProfileIdentifier({ dataSource, symbol }), + priority: DATA_GATHERING_QUEUE_PRIORITY_HIGH } }); } diff --git a/apps/api/src/app/admin/queue/queue.service.ts b/apps/api/src/app/admin/queue/queue.service.ts index e4f29bc60..abae3cad1 100644 --- a/apps/api/src/app/admin/queue/queue.service.ts +++ b/apps/api/src/app/admin/queue/queue.service.ts @@ -58,6 +58,7 @@ export class QueueService { finishedOn: job.finishedOn, id: job.id, name: job.name, + opts: job.opts, stacktrace: job.stacktrace, state: await job.getState(), timestamp: job.timestamp diff --git a/apps/api/src/app/import/import.service.ts b/apps/api/src/app/import/import.service.ts index cbdff87c0..26df9d069 100644 --- a/apps/api/src/app/import/import.service.ts +++ b/apps/api/src/app/import/import.service.ts @@ -13,6 +13,10 @@ import { DataGatheringService } from '@ghostfolio/api/services/data-gathering/da import { DataProviderService } from '@ghostfolio/api/services/data-provider/data-provider.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; +import { + DATA_GATHERING_QUEUE_PRIORITY_HIGH, + DATA_GATHERING_QUEUE_PRIORITY_MEDIUM +} from '@ghostfolio/common/config'; import { DATE_FORMAT, getAssetProfileIdentifier, @@ -448,15 +452,16 @@ export class ImportService { }); }); - this.dataGatheringService.gatherSymbols( - uniqueActivities.map(({ date, SymbolProfile }) => { + this.dataGatheringService.gatherSymbols({ + dataGatheringItems: uniqueActivities.map(({ date, SymbolProfile }) => { return { date, dataSource: SymbolProfile.dataSource, symbol: SymbolProfile.symbol }; - }) - ); + }), + priority: DATA_GATHERING_QUEUE_PRIORITY_HIGH + }); } return activities; diff --git a/apps/api/src/app/order/order.controller.ts b/apps/api/src/app/order/order.controller.ts index c7fec0dac..3dadedcaf 100644 --- a/apps/api/src/app/order/order.controller.ts +++ b/apps/api/src/app/order/order.controller.ts @@ -7,7 +7,10 @@ import { TransformDataSourceInResponseInterceptor } from '@ghostfolio/api/interc import { ApiService } from '@ghostfolio/api/services/api/api.service'; import { DataGatheringService } from '@ghostfolio/api/services/data-gathering/data-gathering.service'; import { ImpersonationService } from '@ghostfolio/api/services/impersonation/impersonation.service'; -import { HEADER_KEY_IMPERSONATION } from '@ghostfolio/common/config'; +import { + DATA_GATHERING_QUEUE_PRIORITY_HIGH, + HEADER_KEY_IMPERSONATION +} from '@ghostfolio/common/config'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import type { DateRange, RequestWithUser } from '@ghostfolio/common/types'; @@ -160,13 +163,16 @@ export class OrderController { if (data.dataSource && !order.isDraft) { // Gather symbol data in the background, if data source is set // (not MANUAL) and not draft - this.dataGatheringService.gatherSymbols([ - { - dataSource: data.dataSource, - date: order.date, - symbol: data.symbol - } - ]); + this.dataGatheringService.gatherSymbols({ + dataGatheringItems: [ + { + dataSource: data.dataSource, + date: order.date, + symbol: data.symbol + } + ], + priority: DATA_GATHERING_QUEUE_PRIORITY_HIGH + }); } return order; diff --git a/apps/api/src/app/order/order.service.ts b/apps/api/src/app/order/order.service.ts index 20b2d5f15..35bfa1bcf 100644 --- a/apps/api/src/app/order/order.service.ts +++ b/apps/api/src/app/order/order.service.ts @@ -4,6 +4,7 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate- import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; import { + DATA_GATHERING_QUEUE_PRIORITY_HIGH, GATHER_ASSET_PROFILE_PROCESS, GATHER_ASSET_PROFILE_PROCESS_OPTIONS } from '@ghostfolio/common/config'; @@ -101,7 +102,8 @@ export class OrderService { jobId: getAssetProfileIdentifier({ dataSource: data.SymbolProfile.connectOrCreate.create.dataSource, symbol: data.SymbolProfile.connectOrCreate.create.symbol - }) + }), + priority: DATA_GATHERING_QUEUE_PRIORITY_HIGH } }); } @@ -427,13 +429,17 @@ export class OrderService { if (!isDraft) { // Gather symbol data of order in the background, if not draft - this.dataGatheringService.gatherSymbols([ - { - dataSource: data.SymbolProfile.connect.dataSource_symbol.dataSource, - date: data.date, - symbol: data.SymbolProfile.connect.dataSource_symbol.symbol - } - ]); + this.dataGatheringService.gatherSymbols({ + dataGatheringItems: [ + { + dataSource: + data.SymbolProfile.connect.dataSource_symbol.dataSource, + date: data.date, + symbol: data.SymbolProfile.connect.dataSource_symbol.symbol + } + ], + priority: DATA_GATHERING_QUEUE_PRIORITY_HIGH + }); } } diff --git a/apps/api/src/services/cron.service.ts b/apps/api/src/services/cron.service.ts index d74ad6a94..fc5d613a2 100644 --- a/apps/api/src/services/cron.service.ts +++ b/apps/api/src/services/cron.service.ts @@ -1,4 +1,5 @@ import { + DATA_GATHERING_QUEUE_PRIORITY_LOW, GATHER_ASSET_PROFILE_PROCESS, GATHER_ASSET_PROFILE_PROCESS_OPTIONS, PROPERTY_IS_DATA_GATHERING_ENABLED @@ -56,7 +57,8 @@ export class CronService { name: GATHER_ASSET_PROFILE_PROCESS, opts: { ...GATHER_ASSET_PROFILE_PROCESS_OPTIONS, - jobId: getAssetProfileIdentifier({ dataSource, symbol }) + jobId: getAssetProfileIdentifier({ dataSource, symbol }), + priority: DATA_GATHERING_QUEUE_PRIORITY_LOW } }; }) diff --git a/apps/api/src/services/data-gathering/data-gathering.service.ts b/apps/api/src/services/data-gathering/data-gathering.service.ts index 6dccd645e..b2b0c371c 100644 --- a/apps/api/src/services/data-gathering/data-gathering.service.ts +++ b/apps/api/src/services/data-gathering/data-gathering.service.ts @@ -8,6 +8,8 @@ import { PropertyService } from '@ghostfolio/api/services/property/property.serv import { SymbolProfileService } from '@ghostfolio/api/services/symbol-profile/symbol-profile.service'; import { DATA_GATHERING_QUEUE, + DATA_GATHERING_QUEUE_PRIORITY_HIGH, + DATA_GATHERING_QUEUE_PRIORITY_LOW, GATHER_HISTORICAL_MARKET_DATA_PROCESS, GATHER_HISTORICAL_MARKET_DATA_PROCESS_OPTIONS, PROPERTY_BENCHMARKS @@ -61,24 +63,35 @@ export class DataGatheringService { public async gather7Days() { const dataGatheringItems = await this.getSymbols7D(); - await this.gatherSymbols(dataGatheringItems); + await this.gatherSymbols({ + dataGatheringItems, + priority: DATA_GATHERING_QUEUE_PRIORITY_LOW + }); } public async gatherMax() { const dataGatheringItems = await this.getSymbolsMax(); - await this.gatherSymbols(dataGatheringItems); + await this.gatherSymbols({ + dataGatheringItems, + priority: DATA_GATHERING_QUEUE_PRIORITY_LOW + }); } public async gatherSymbol({ dataSource, symbol }: UniqueAsset) { await this.marketDataService.deleteMany({ dataSource, symbol }); - const symbols = (await this.getSymbolsMax()).filter((dataGatheringItem) => { - return ( - dataGatheringItem.dataSource === dataSource && - dataGatheringItem.symbol === symbol - ); + const dataGatheringItems = (await this.getSymbolsMax()).filter( + (dataGatheringItem) => { + return ( + dataGatheringItem.dataSource === dataSource && + dataGatheringItem.symbol === symbol + ); + } + ); + await this.gatherSymbols({ + dataGatheringItems, + priority: DATA_GATHERING_QUEUE_PRIORITY_HIGH }); - await this.gatherSymbols(symbols); } public async gatherSymbolForDate({ @@ -230,9 +243,15 @@ export class DataGatheringService { ); } - public async gatherSymbols(aSymbolsWithStartDate: IDataGatheringItem[]) { + public async gatherSymbols({ + dataGatheringItems, + priority + }: { + dataGatheringItems: IDataGatheringItem[]; + priority: number; + }) { await this.addJobsToQueue( - aSymbolsWithStartDate.map(({ dataSource, date, symbol }) => { + dataGatheringItems.map(({ dataSource, date, symbol }) => { return { data: { dataSource, @@ -242,6 +261,7 @@ export class DataGatheringService { name: GATHER_HISTORICAL_MARKET_DATA_PROCESS, opts: { ...GATHER_HISTORICAL_MARKET_DATA_PROCESS_OPTIONS, + priority, jobId: `${getAssetProfileIdentifier({ dataSource, symbol diff --git a/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts b/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts index 99d67dea2..23730f3aa 100644 --- a/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts +++ b/apps/client/src/app/components/admin-jobs/admin-jobs.component.ts @@ -1,6 +1,11 @@ import { AdminService } from '@ghostfolio/client/services/admin.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; -import { QUEUE_JOB_STATUS_LIST } from '@ghostfolio/common/config'; +import { + DATA_GATHERING_QUEUE_PRIORITY_HIGH, + DATA_GATHERING_QUEUE_PRIORITY_LOW, + DATA_GATHERING_QUEUE_PRIORITY_MEDIUM, + QUEUE_JOB_STATUS_LIST +} from '@ghostfolio/common/config'; import { getDateWithTimeFormatString } from '@ghostfolio/common/helper'; import { AdminJobs, User } from '@ghostfolio/common/interfaces'; @@ -24,6 +29,11 @@ import { takeUntil } from 'rxjs/operators'; templateUrl: './admin-jobs.html' }) export class AdminJobsComponent implements OnDestroy, OnInit { + public DATA_GATHERING_QUEUE_PRIORITY_LOW = DATA_GATHERING_QUEUE_PRIORITY_LOW; + public DATA_GATHERING_QUEUE_PRIORITY_HIGH = + DATA_GATHERING_QUEUE_PRIORITY_HIGH; + public DATA_GATHERING_QUEUE_PRIORITY_MEDIUM = + DATA_GATHERING_QUEUE_PRIORITY_MEDIUM; public defaultDateTimeFormat: string; public filterForm: FormGroup; public dataSource: MatTableDataSource = @@ -33,6 +43,7 @@ export class AdminJobsComponent implements OnDestroy, OnInit { 'type', 'symbol', 'dataSource', + 'priority', 'attempts', 'created', 'finished', diff --git a/apps/client/src/app/components/admin-jobs/admin-jobs.html b/apps/client/src/app/components/admin-jobs/admin-jobs.html index 31dad0ca6..5da929fe1 100644 --- a/apps/client/src/app/components/admin-jobs/admin-jobs.html +++ b/apps/client/src/app/components/admin-jobs/admin-jobs.html @@ -58,6 +58,25 @@ + + + Priority + + + @if (element.opts.priority === DATA_GATHERING_QUEUE_PRIORITY_LOW) { + + } @else if ( + element.opts.priority === DATA_GATHERING_QUEUE_PRIORITY_MEDIUM + ) { + + } @else if ( + element.opts.priority === DATA_GATHERING_QUEUE_PRIORITY_HIGH + ) { + + } + + + Attempts @@ -90,24 +109,37 @@ Status - + - - + + diff --git a/libs/common/src/lib/config.ts b/libs/common/src/lib/config.ts index 293f77488..5e1366ce2 100644 --- a/libs/common/src/lib/config.ts +++ b/libs/common/src/lib/config.ts @@ -32,8 +32,11 @@ export const warnColorRgb = { }; export const DATA_GATHERING_QUEUE = 'DATA_GATHERING_QUEUE'; -export const DATA_GATHERING_QUEUE_PRIORITY_LOW = Number.MAX_SAFE_INTEGER; export const DATA_GATHERING_QUEUE_PRIORITY_HIGH = 1; +export const DATA_GATHERING_QUEUE_PRIORITY_LOW = Number.MAX_SAFE_INTEGER; +export const DATA_GATHERING_QUEUE_PRIORITY_MEDIUM = Math.round( + DATA_GATHERING_QUEUE_PRIORITY_LOW / 2 +); export const DEFAULT_CURRENCY = 'USD'; export const DEFAULT_DATE_FORMAT_MONTH_YEAR = 'MMM yyyy'; @@ -69,7 +72,6 @@ export const GATHER_ASSET_PROFILE_PROCESS_OPTIONS: JobOptions = { delay: ms('1 minute'), type: 'exponential' }, - priority: DATA_GATHERING_QUEUE_PRIORITY_HIGH, removeOnComplete: true }; export const GATHER_HISTORICAL_MARKET_DATA_PROCESS = @@ -80,7 +82,6 @@ export const GATHER_HISTORICAL_MARKET_DATA_PROCESS_OPTIONS: JobOptions = { delay: ms('1 minute'), type: 'exponential' }, - priority: DATA_GATHERING_QUEUE_PRIORITY_LOW, removeOnComplete: true }; diff --git a/libs/common/src/lib/interfaces/admin-jobs.interface.ts b/libs/common/src/lib/interfaces/admin-jobs.interface.ts index 25e937626..b4c91ebc0 100644 --- a/libs/common/src/lib/interfaces/admin-jobs.interface.ts +++ b/libs/common/src/lib/interfaces/admin-jobs.interface.ts @@ -8,6 +8,7 @@ export interface AdminJobs { | 'finishedOn' | 'id' | 'name' + | 'opts' | 'stacktrace' | 'timestamp' > & { From 7d308917ddba1b6f7d1fa40b9005d73b022ec0fb Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 13 Apr 2024 09:28:38 +0200 Subject: [PATCH 116/203] Feature/upgrade yahoo finance2 to version 2.11.1 (#3254) * Upgrade yahoo-finance2 to version 2.11.1 * Update changelog --- CHANGELOG.md | 1 + package.json | 2 +- yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73999efb7..e48f26c0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Upgraded `angular` from version `17.2.4` to `17.3.3` - Upgraded `Nx` from version `18.1.2` to `18.2.3` - Upgraded `prisma` from version `5.11.0` to `5.12.1` +- Upgraded `yahoo-finance2` from version `2.11.0` to `2.11.1` ### Fixed diff --git a/package.json b/package.json index 1f2e7520a..252fb045f 100644 --- a/package.json +++ b/package.json @@ -132,7 +132,7 @@ "svgmap": "2.6.0", "twitter-api-v2": "1.14.2", "uuid": "9.0.1", - "yahoo-finance2": "2.11.0", + "yahoo-finance2": "2.11.1", "zone.js": "0.14.4" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 9c77b9917..8cbfbccd0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19620,10 +19620,10 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yahoo-finance2@2.11.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/yahoo-finance2/-/yahoo-finance2-2.11.0.tgz#293ade36d2e969218ad38fc308abc11ca02c1fab" - integrity sha512-lQWjnf9cnfAEmpL9ymwabxjQxu1xT5jg03NYOYcpn0ObOx9oGk9hes6JDaCeIq/xT+xgMdPMupsgYxnAxfKyhw== +yahoo-finance2@2.11.1: + version "2.11.1" + resolved "https://registry.yarnpkg.com/yahoo-finance2/-/yahoo-finance2-2.11.1.tgz#97758d4784ef0b4efe4b370a72063929cc4c6342" + integrity sha512-YglgpjIDithq1PG8Je/gy8nzJFqkH214x2ZGfr6Y+HV4ymTDFLluq2W9Hsvvyydv1zTv9/Ykedf0J4YIpmO2Zg== dependencies: "@types/tough-cookie" "^4.0.2" ajv "8.10.0" From b31bbbe2d14eee09b78699f80d8d37c1a03613de Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 13 Apr 2024 09:31:07 +0200 Subject: [PATCH 117/203] Release 2.72.0 (#3270) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e48f26c0a..344ad73ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.72.0 - 2024-04-13 ### Added diff --git a/package.json b/package.json index 252fb045f..35ee3b1a4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.71.0", + "version": "2.72.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 6c57609db853f17a95ae761ca6c620eaa33ce5cd Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 13 Apr 2024 11:07:18 +0200 Subject: [PATCH 118/203] Feature/move dividend fee and interest calculation to portfolio calculator (#3267) * Move dividend, feee and interest calculation to portfolio calculator * Update changelog --- CHANGELOG.md | 8 + .../calculator/mwr/portfolio-calculator.ts | 4 +- .../portfolio-calculator.factory.ts | 7 +- .../calculator/portfolio-calculator.ts | 569 ++++++++++-------- ...aln-buy-and-sell-in-two-activities.spec.ts | 14 +- ...folio-calculator-baln-buy-and-sell.spec.ts | 14 +- .../twr/portfolio-calculator-baln-buy.spec.ts | 14 +- ...ator-btcusd-buy-and-sell-partially.spec.ts | 14 +- .../twr/portfolio-calculator-fee.spec.ts | 132 ++++ .../portfolio-calculator-googl-buy.spec.ts | 14 +- ...-calculator-msft-buy-with-dividend.spec.ts | 14 +- .../portfolio-calculator-no-orders.spec.ts | 16 +- ...ulator-novn-buy-and-sell-partially.spec.ts | 13 +- ...folio-calculator-novn-buy-and-sell.spec.ts | 14 +- .../calculator/twr/portfolio-calculator.ts | 32 +- ...ace.ts => portfolio-snapshot.interface.ts} | 4 +- .../interfaces/transaction-point.interface.ts | 4 + .../src/app/portfolio/portfolio.controller.ts | 8 +- .../src/app/portfolio/portfolio.service.ts | 160 ++--- apps/api/src/helper/portfolio.helper.ts | 26 +- .../interfaces/symbol-metrics.interface.ts | 3 + 21 files changed, 655 insertions(+), 429 deletions(-) create mode 100644 apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts rename apps/api/src/app/portfolio/interfaces/{current-positions.interface.ts => portfolio-snapshot.interface.ts} (82%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 344ad73ed..7da5c3ddd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- Moved the dividend calculations into the portfolio calculator +- Moved the fee calculations into the portfolio calculator +- Moved the interest calculations into the portfolio calculator + ## 2.72.0 - 2024-04-13 ### Added diff --git a/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts index ec744f624..978f1f3aa 100644 --- a/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts @@ -1,5 +1,5 @@ import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; -import { CurrentPositions } from '@ghostfolio/api/app/portfolio/interfaces/current-positions.interface'; +import { PortfolioSnapshot } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-snapshot.interface'; import { SymbolMetrics, TimelinePosition, @@ -9,7 +9,7 @@ import { export class MWRPortfolioCalculator extends PortfolioCalculator { protected calculateOverallPerformance( positions: TimelinePosition[] - ): CurrentPositions { + ): PortfolioSnapshot { throw new Error('Method not implemented.'); } diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts index cf1fe9324..e64c23942 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts @@ -1,6 +1,7 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; +import { DateRange } from '@ghostfolio/common/types'; import { Injectable } from '@nestjs/common'; @@ -23,17 +24,20 @@ export class PortfolioCalculatorFactory { public createCalculator({ activities, calculationType, - currency + currency, + dateRange = 'max' }: { activities: Activity[]; calculationType: PerformanceCalculationType; currency: string; + dateRange?: DateRange; }): PortfolioCalculator { switch (calculationType) { case PerformanceCalculationType.MWR: return new MWRPortfolioCalculator({ activities, currency, + dateRange, currentRateService: this.currentRateService, exchangeRateDataService: this.exchangeRateDataService }); @@ -42,6 +46,7 @@ export class PortfolioCalculatorFactory { activities, currency, currentRateService: this.currentRateService, + dateRange, exchangeRateDataService: this.exchangeRateDataService }); default: diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index a9dbff442..712c0ac04 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -1,7 +1,7 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; -import { CurrentPositions } from '@ghostfolio/api/app/portfolio/interfaces/current-positions.interface'; import { PortfolioOrder } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order.interface'; +import { PortfolioSnapshot } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-snapshot.interface'; import { TransactionPointSymbol } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point-symbol.interface'; import { TransactionPoint } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point.interface'; import { @@ -11,7 +11,12 @@ import { import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; import { MAX_CHART_ITEMS } from '@ghostfolio/common/config'; -import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper'; +import { + DATE_FORMAT, + getSum, + parseDate, + resetHours +} from '@ghostfolio/common/helper'; import { DataProviderInfo, HistoricalDataItem, @@ -44,18 +49,24 @@ export abstract class PortfolioCalculator { private currency: string; private currentRateService: CurrentRateService; private dataProviderInfos: DataProviderInfo[]; + private endDate: Date; private exchangeRateDataService: ExchangeRateDataService; + private snapshot: PortfolioSnapshot; + private snapshotPromise: Promise; + private startDate: Date; private transactionPoints: TransactionPoint[]; public constructor({ activities, currency, currentRateService, + dateRange, exchangeRateDataService }: { activities: Activity[]; currency: string; currentRateService: CurrentRateService; + dateRange: DateRange; exchangeRateDataService: ExchangeRateDataService; }) { this.currency = currency; @@ -79,12 +90,270 @@ export abstract class PortfolioCalculator { return a.date?.localeCompare(b.date); }); + const { endDate, startDate } = getInterval(dateRange); + + this.endDate = endDate; + this.startDate = startDate; + this.computeTransactionPoints(); + + this.snapshotPromise = this.initialize(); } protected abstract calculateOverallPerformance( positions: TimelinePosition[] - ): CurrentPositions; + ): PortfolioSnapshot; + + public async computeSnapshot( + start: Date, + end?: Date + ): Promise { + const lastTransactionPoint = last(this.transactionPoints); + + let endDate = end; + + if (!endDate) { + endDate = new Date(Date.now()); + + if (lastTransactionPoint) { + endDate = max([endDate, parseDate(lastTransactionPoint.date)]); + } + } + + const transactionPoints = this.transactionPoints?.filter(({ date }) => { + return isBefore(parseDate(date), endDate); + }); + + if (!transactionPoints.length) { + return { + currentValueInBaseCurrency: new Big(0), + grossPerformance: new Big(0), + grossPerformancePercentage: new Big(0), + grossPerformancePercentageWithCurrencyEffect: new Big(0), + grossPerformanceWithCurrencyEffect: new Big(0), + hasErrors: false, + netPerformance: new Big(0), + netPerformancePercentage: new Big(0), + netPerformancePercentageWithCurrencyEffect: new Big(0), + netPerformanceWithCurrencyEffect: new Big(0), + positions: [], + totalFeesWithCurrencyEffect: new Big(0), + totalInterestWithCurrencyEffect: new Big(0), + totalInvestment: new Big(0), + totalInvestmentWithCurrencyEffect: new Big(0) + }; + } + + const currencies: { [symbol: string]: string } = {}; + const dataGatheringItems: IDataGatheringItem[] = []; + let dates: Date[] = []; + let firstIndex = transactionPoints.length; + let firstTransactionPoint: TransactionPoint = null; + + dates.push(resetHours(start)); + + for (const { currency, dataSource, symbol } of transactionPoints[ + firstIndex - 1 + ].items) { + dataGatheringItems.push({ + dataSource, + symbol + }); + + currencies[symbol] = currency; + } + + for (let i = 0; i < transactionPoints.length; i++) { + if ( + !isBefore(parseDate(transactionPoints[i].date), start) && + firstTransactionPoint === null + ) { + firstTransactionPoint = transactionPoints[i]; + firstIndex = i; + } + + if (firstTransactionPoint !== null) { + dates.push(resetHours(parseDate(transactionPoints[i].date))); + } + } + + dates.push(resetHours(endDate)); + + // Add dates of last week for fallback + dates.push(subDays(resetHours(new Date()), 7)); + dates.push(subDays(resetHours(new Date()), 6)); + dates.push(subDays(resetHours(new Date()), 5)); + dates.push(subDays(resetHours(new Date()), 4)); + dates.push(subDays(resetHours(new Date()), 3)); + dates.push(subDays(resetHours(new Date()), 2)); + dates.push(subDays(resetHours(new Date()), 1)); + dates.push(resetHours(new Date())); + + dates = uniq( + dates.map((date) => { + return date.getTime(); + }) + ) + .map((timestamp) => { + return new Date(timestamp); + }) + .sort((a, b) => { + return a.getTime() - b.getTime(); + }); + + let exchangeRatesByCurrency = + await this.exchangeRateDataService.getExchangeRatesByCurrency({ + currencies: uniq(Object.values(currencies)), + endDate: endOfDay(endDate), + startDate: this.getStartDate(), + targetCurrency: this.currency + }); + + const { + dataProviderInfos, + errors: currentRateErrors, + values: marketSymbols + } = await this.currentRateService.getValues({ + dataGatheringItems, + dateQuery: { + in: dates + } + }); + + this.dataProviderInfos = dataProviderInfos; + + const marketSymbolMap: { + [date: string]: { [symbol: string]: Big }; + } = {}; + + for (const marketSymbol of marketSymbols) { + const date = format(marketSymbol.date, DATE_FORMAT); + + if (!marketSymbolMap[date]) { + marketSymbolMap[date] = {}; + } + + if (marketSymbol.marketPrice) { + marketSymbolMap[date][marketSymbol.symbol] = new Big( + marketSymbol.marketPrice + ); + } + } + + const endDateString = format(endDate, DATE_FORMAT); + + if (firstIndex > 0) { + firstIndex--; + } + + const positions: TimelinePosition[] = []; + let hasAnySymbolMetricsErrors = false; + + const errors: ResponseError['errors'] = []; + + for (const item of lastTransactionPoint.items) { + const marketPriceInBaseCurrency = ( + marketSymbolMap[endDateString]?.[item.symbol] ?? item.averagePrice + ).mul( + exchangeRatesByCurrency[`${item.currency}${this.currency}`]?.[ + endDateString + ] + ); + + const { + grossPerformance, + grossPerformancePercentage, + grossPerformancePercentageWithCurrencyEffect, + grossPerformanceWithCurrencyEffect, + hasErrors, + netPerformance, + netPerformancePercentage, + netPerformancePercentageWithCurrencyEffect, + netPerformanceWithCurrencyEffect, + timeWeightedInvestment, + timeWeightedInvestmentWithCurrencyEffect, + totalDividend, + totalDividendInBaseCurrency, + totalInvestment, + totalInvestmentWithCurrencyEffect + } = this.getSymbolMetrics({ + marketSymbolMap, + start, + dataSource: item.dataSource, + end: endDate, + exchangeRates: + exchangeRatesByCurrency[`${item.currency}${this.currency}`], + symbol: item.symbol + }); + + hasAnySymbolMetricsErrors = hasAnySymbolMetricsErrors || hasErrors; + + positions.push({ + dividend: totalDividend, + dividendInBaseCurrency: totalDividendInBaseCurrency, + timeWeightedInvestment, + timeWeightedInvestmentWithCurrencyEffect, + averagePrice: item.averagePrice, + currency: item.currency, + dataSource: item.dataSource, + fee: item.fee, + firstBuyDate: item.firstBuyDate, + grossPerformance: !hasErrors ? grossPerformance ?? null : null, + grossPerformancePercentage: !hasErrors + ? grossPerformancePercentage ?? null + : null, + grossPerformancePercentageWithCurrencyEffect: !hasErrors + ? grossPerformancePercentageWithCurrencyEffect ?? null + : null, + grossPerformanceWithCurrencyEffect: !hasErrors + ? grossPerformanceWithCurrencyEffect ?? null + : null, + investment: totalInvestment, + investmentWithCurrencyEffect: totalInvestmentWithCurrencyEffect, + marketPrice: + marketSymbolMap[endDateString]?.[item.symbol]?.toNumber() ?? null, + marketPriceInBaseCurrency: + marketPriceInBaseCurrency?.toNumber() ?? null, + netPerformance: !hasErrors ? netPerformance ?? null : null, + netPerformancePercentage: !hasErrors + ? netPerformancePercentage ?? null + : null, + netPerformancePercentageWithCurrencyEffect: !hasErrors + ? netPerformancePercentageWithCurrencyEffect ?? null + : null, + netPerformanceWithCurrencyEffect: !hasErrors + ? netPerformanceWithCurrencyEffect ?? null + : null, + quantity: item.quantity, + symbol: item.symbol, + tags: item.tags, + transactionCount: item.transactionCount, + valueInBaseCurrency: new Big(marketPriceInBaseCurrency).mul( + item.quantity + ) + }); + + if ( + (hasErrors || + currentRateErrors.find(({ dataSource, symbol }) => { + return dataSource === item.dataSource && symbol === item.symbol; + })) && + item.investment.gt(0) + ) { + errors.push({ dataSource: item.dataSource, symbol: item.symbol }); + } + } + + const overall = this.calculateOverallPerformance(positions); + + return { + ...overall, + errors, + positions, + hasErrors: hasAnySymbolMetricsErrors || overall.hasErrors, + totalInterestWithCurrencyEffect: lastTransactionPoint.interest + }; + } public async getChart({ dateRange = 'max', @@ -380,256 +649,30 @@ export abstract class PortfolioCalculator { }); } - public async getCurrentPositions( - start: Date, - end?: Date - ): Promise { - const lastTransactionPoint = last(this.transactionPoints); - - let endDate = end; - - if (!endDate) { - endDate = new Date(Date.now()); - - if (lastTransactionPoint) { - endDate = max([endDate, parseDate(lastTransactionPoint.date)]); - } - } - - const transactionPoints = this.transactionPoints?.filter(({ date }) => { - return isBefore(parseDate(date), endDate); - }); - - if (!transactionPoints.length) { - return { - currentValueInBaseCurrency: new Big(0), - grossPerformance: new Big(0), - grossPerformancePercentage: new Big(0), - grossPerformancePercentageWithCurrencyEffect: new Big(0), - grossPerformanceWithCurrencyEffect: new Big(0), - hasErrors: false, - netPerformance: new Big(0), - netPerformancePercentage: new Big(0), - netPerformancePercentageWithCurrencyEffect: new Big(0), - netPerformanceWithCurrencyEffect: new Big(0), - positions: [], - totalInvestment: new Big(0), - totalInvestmentWithCurrencyEffect: new Big(0) - }; - } - - const currencies: { [symbol: string]: string } = {}; - const dataGatheringItems: IDataGatheringItem[] = []; - let dates: Date[] = []; - let firstIndex = transactionPoints.length; - let firstTransactionPoint: TransactionPoint = null; - - dates.push(resetHours(start)); - - for (const { currency, dataSource, symbol } of transactionPoints[ - firstIndex - 1 - ].items) { - dataGatheringItems.push({ - dataSource, - symbol - }); - - currencies[symbol] = currency; - } - - for (let i = 0; i < transactionPoints.length; i++) { - if ( - !isBefore(parseDate(transactionPoints[i].date), start) && - firstTransactionPoint === null - ) { - firstTransactionPoint = transactionPoints[i]; - firstIndex = i; - } - - if (firstTransactionPoint !== null) { - dates.push(resetHours(parseDate(transactionPoints[i].date))); - } - } - - dates.push(resetHours(endDate)); + public getDataProviderInfos() { + return this.dataProviderInfos; + } - // Add dates of last week for fallback - dates.push(subDays(resetHours(new Date()), 7)); - dates.push(subDays(resetHours(new Date()), 6)); - dates.push(subDays(resetHours(new Date()), 5)); - dates.push(subDays(resetHours(new Date()), 4)); - dates.push(subDays(resetHours(new Date()), 3)); - dates.push(subDays(resetHours(new Date()), 2)); - dates.push(subDays(resetHours(new Date()), 1)); - dates.push(resetHours(new Date())); + public async getDividendInBaseCurrency() { + await this.snapshotPromise; - dates = uniq( - dates.map((date) => { - return date.getTime(); - }) - ) - .map((timestamp) => { - return new Date(timestamp); + return getSum( + this.snapshot.positions.map(({ dividendInBaseCurrency }) => { + return dividendInBaseCurrency; }) - .sort((a, b) => { - return a.getTime() - b.getTime(); - }); - - let exchangeRatesByCurrency = - await this.exchangeRateDataService.getExchangeRatesByCurrency({ - currencies: uniq(Object.values(currencies)), - endDate: endOfDay(endDate), - startDate: this.getStartDate(), - targetCurrency: this.currency - }); - - const { - dataProviderInfos, - errors: currentRateErrors, - values: marketSymbols - } = await this.currentRateService.getValues({ - dataGatheringItems, - dateQuery: { - in: dates - } - }); - - this.dataProviderInfos = dataProviderInfos; - - const marketSymbolMap: { - [date: string]: { [symbol: string]: Big }; - } = {}; - - for (const marketSymbol of marketSymbols) { - const date = format(marketSymbol.date, DATE_FORMAT); - - if (!marketSymbolMap[date]) { - marketSymbolMap[date] = {}; - } - - if (marketSymbol.marketPrice) { - marketSymbolMap[date][marketSymbol.symbol] = new Big( - marketSymbol.marketPrice - ); - } - } - - const endDateString = format(endDate, DATE_FORMAT); - - if (firstIndex > 0) { - firstIndex--; - } - - const positions: TimelinePosition[] = []; - let hasAnySymbolMetricsErrors = false; - - const errors: ResponseError['errors'] = []; - - for (const item of lastTransactionPoint.items) { - const marketPriceInBaseCurrency = ( - marketSymbolMap[endDateString]?.[item.symbol] ?? item.averagePrice - ).mul( - exchangeRatesByCurrency[`${item.currency}${this.currency}`]?.[ - endDateString - ] - ); - - const { - grossPerformance, - grossPerformancePercentage, - grossPerformancePercentageWithCurrencyEffect, - grossPerformanceWithCurrencyEffect, - hasErrors, - netPerformance, - netPerformancePercentage, - netPerformancePercentageWithCurrencyEffect, - netPerformanceWithCurrencyEffect, - timeWeightedInvestment, - timeWeightedInvestmentWithCurrencyEffect, - totalDividend, - totalDividendInBaseCurrency, - totalInvestment, - totalInvestmentWithCurrencyEffect - } = this.getSymbolMetrics({ - marketSymbolMap, - start, - dataSource: item.dataSource, - end: endDate, - exchangeRates: - exchangeRatesByCurrency[`${item.currency}${this.currency}`], - symbol: item.symbol - }); - - hasAnySymbolMetricsErrors = hasAnySymbolMetricsErrors || hasErrors; - - positions.push({ - dividend: totalDividend, - dividendInBaseCurrency: totalDividendInBaseCurrency, - timeWeightedInvestment, - timeWeightedInvestmentWithCurrencyEffect, - averagePrice: item.averagePrice, - currency: item.currency, - dataSource: item.dataSource, - fee: item.fee, - firstBuyDate: item.firstBuyDate, - grossPerformance: !hasErrors ? grossPerformance ?? null : null, - grossPerformancePercentage: !hasErrors - ? grossPerformancePercentage ?? null - : null, - grossPerformancePercentageWithCurrencyEffect: !hasErrors - ? grossPerformancePercentageWithCurrencyEffect ?? null - : null, - grossPerformanceWithCurrencyEffect: !hasErrors - ? grossPerformanceWithCurrencyEffect ?? null - : null, - investment: totalInvestment, - investmentWithCurrencyEffect: totalInvestmentWithCurrencyEffect, - marketPrice: - marketSymbolMap[endDateString]?.[item.symbol]?.toNumber() ?? null, - marketPriceInBaseCurrency: - marketPriceInBaseCurrency?.toNumber() ?? null, - netPerformance: !hasErrors ? netPerformance ?? null : null, - netPerformancePercentage: !hasErrors - ? netPerformancePercentage ?? null - : null, - netPerformancePercentageWithCurrencyEffect: !hasErrors - ? netPerformancePercentageWithCurrencyEffect ?? null - : null, - netPerformanceWithCurrencyEffect: !hasErrors - ? netPerformanceWithCurrencyEffect ?? null - : null, - quantity: item.quantity, - symbol: item.symbol, - tags: item.tags, - transactionCount: item.transactionCount, - valueInBaseCurrency: new Big(marketPriceInBaseCurrency).mul( - item.quantity - ) - }); - - if ( - (hasErrors || - currentRateErrors.find(({ dataSource, symbol }) => { - return dataSource === item.dataSource && symbol === item.symbol; - })) && - item.investment.gt(0) - ) { - errors.push({ dataSource: item.dataSource, symbol: item.symbol }); - } - } + ); + } - const overall = this.calculateOverallPerformance(positions); + public async getFeesInBaseCurrency() { + await this.snapshotPromise; - return { - ...overall, - errors, - positions, - hasErrors: hasAnySymbolMetricsErrors || overall.hasErrors - }; + return this.snapshot.totalFeesWithCurrencyEffect; } - public getDataProviderInfos() { - return this.dataProviderInfos; + public async getInterestInBaseCurrency() { + await this.snapshotPromise; + + return this.snapshot.totalInterestWithCurrencyEffect; } public getInvestments(): { date: string; investment: Big }[] { @@ -672,6 +715,12 @@ export abstract class PortfolioCalculator { })); } + public async getSnapshot() { + await this.snapshotPromise; + + return this.snapshot; + } + public getStartDate() { return this.transactionPoints.length > 0 ? parseDate(this.transactionPoints[0].date) @@ -718,6 +767,13 @@ export abstract class PortfolioCalculator { type, unitPrice } of this.orders) { + if ( + // TODO + ['ITEM', 'LIABILITY'].includes(type) + ) { + continue; + } + let currentTransactionPointItem: TransactionPointSymbol; const oldAccumulatedSymbol = symbols[SymbolProfile.symbol]; @@ -790,18 +846,39 @@ export abstract class PortfolioCalculator { return a.symbol?.localeCompare(b.symbol); }); + let fees = new Big(0); + + if (type === 'FEE') { + fees = fee; + } + + let interest = new Big(0); + + if (type === 'INTEREST') { + interest = quantity.mul(unitPrice); + } + if (lastDate !== date || lastTransactionPoint === null) { lastTransactionPoint = { date, + fees, + interest, items: newItems }; this.transactionPoints.push(lastTransactionPoint); } else { + lastTransactionPoint.fees = lastTransactionPoint.fees.plus(fees); + lastTransactionPoint.interest = + lastTransactionPoint.interest.plus(interest); lastTransactionPoint.items = newItems; } lastDate = date; } } + + private async initialize() { + this.snapshot = await this.computeSnapshot(this.startDate, this.endDate); + } } diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts index b936d21a9..8ddae9df6 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts @@ -46,6 +46,10 @@ describe('PortfolioCalculator', () => { describe('get current positions', () => { it.only('with BALN.SW buy and sell in two activities', async () => { + const spy = jest + .spyOn(Date, 'now') + .mockImplementation(() => parseDate('2021-12-18').getTime()); + const activities: Activity[] = [ { ...activityDummyData, @@ -100,15 +104,11 @@ describe('PortfolioCalculator', () => { currency: 'CHF' }); - const spy = jest - .spyOn(Date, 'now') - .mockImplementation(() => parseDate('2021-12-18').getTime()); - const chartData = await portfolioCalculator.getChartData({ start: parseDate('2021-11-22') }); - const currentPositions = await portfolioCalculator.getCurrentPositions( + const portfolioSnapshot = await portfolioCalculator.computeSnapshot( parseDate('2021-11-22') ); @@ -121,7 +121,7 @@ describe('PortfolioCalculator', () => { spy.mockRestore(); - expect(currentPositions).toEqual({ + expect(portfolioSnapshot).toEqual({ currentValueInBaseCurrency: new Big('0'), errors: [], grossPerformance: new Big('-12.6'), @@ -173,6 +173,8 @@ describe('PortfolioCalculator', () => { valueInBaseCurrency: new Big('0') } ], + totalFeesWithCurrencyEffect: new Big('3.2'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('0'), totalInvestmentWithCurrencyEffect: new Big('0') }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts index d1557bc12..febd1769d 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts @@ -46,6 +46,10 @@ describe('PortfolioCalculator', () => { describe('get current positions', () => { it.only('with BALN.SW buy and sell', async () => { + const spy = jest + .spyOn(Date, 'now') + .mockImplementation(() => parseDate('2021-12-18').getTime()); + const activities: Activity[] = [ { ...activityDummyData, @@ -85,15 +89,11 @@ describe('PortfolioCalculator', () => { currency: 'CHF' }); - const spy = jest - .spyOn(Date, 'now') - .mockImplementation(() => parseDate('2021-12-18').getTime()); - const chartData = await portfolioCalculator.getChartData({ start: parseDate('2021-11-22') }); - const currentPositions = await portfolioCalculator.getCurrentPositions( + const portfolioSnapshot = await portfolioCalculator.computeSnapshot( parseDate('2021-11-22') ); @@ -106,7 +106,7 @@ describe('PortfolioCalculator', () => { spy.mockRestore(); - expect(currentPositions).toEqual({ + expect(portfolioSnapshot).toEqual({ currentValueInBaseCurrency: new Big('0'), errors: [], grossPerformance: new Big('-12.6'), @@ -156,6 +156,8 @@ describe('PortfolioCalculator', () => { valueInBaseCurrency: new Big('0') } ], + totalFeesWithCurrencyEffect: new Big('3.2'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('0'), totalInvestmentWithCurrencyEffect: new Big('0') }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts index 593503493..2b9fd06f0 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts @@ -46,6 +46,10 @@ describe('PortfolioCalculator', () => { describe('get current positions', () => { it.only('with BALN.SW buy', async () => { + const spy = jest + .spyOn(Date, 'now') + .mockImplementation(() => parseDate('2021-12-18').getTime()); + const activities: Activity[] = [ { ...activityDummyData, @@ -70,15 +74,11 @@ describe('PortfolioCalculator', () => { currency: 'CHF' }); - const spy = jest - .spyOn(Date, 'now') - .mockImplementation(() => parseDate('2021-12-18').getTime()); - const chartData = await portfolioCalculator.getChartData({ start: parseDate('2021-11-30') }); - const currentPositions = await portfolioCalculator.getCurrentPositions( + const portfolioSnapshot = await portfolioCalculator.computeSnapshot( parseDate('2021-11-30') ); @@ -91,7 +91,7 @@ describe('PortfolioCalculator', () => { spy.mockRestore(); - expect(currentPositions).toEqual({ + expect(portfolioSnapshot).toEqual({ currentValueInBaseCurrency: new Big('297.8'), errors: [], grossPerformance: new Big('24.6'), @@ -141,6 +141,8 @@ describe('PortfolioCalculator', () => { valueInBaseCurrency: new Big('297.8') } ], + totalFeesWithCurrencyEffect: new Big('1.55'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('273.2'), totalInvestmentWithCurrencyEffect: new Big('273.2') }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts index e3f351b28..ceff92449 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts @@ -59,6 +59,10 @@ describe('PortfolioCalculator', () => { describe('get current positions', () => { it.only('with BTCUSD buy and sell partially', async () => { + const spy = jest + .spyOn(Date, 'now') + .mockImplementation(() => parseDate('2018-01-01').getTime()); + const activities: Activity[] = [ { ...activityDummyData, @@ -98,15 +102,11 @@ describe('PortfolioCalculator', () => { currency: 'CHF' }); - const spy = jest - .spyOn(Date, 'now') - .mockImplementation(() => parseDate('2018-01-01').getTime()); - const chartData = await portfolioCalculator.getChartData({ start: parseDate('2015-01-01') }); - const currentPositions = await portfolioCalculator.getCurrentPositions( + const portfolioSnapshot = await portfolioCalculator.computeSnapshot( parseDate('2015-01-01') ); @@ -119,7 +119,7 @@ describe('PortfolioCalculator', () => { spy.mockRestore(); - expect(currentPositions).toEqual({ + expect(portfolioSnapshot).toEqual({ currentValueInBaseCurrency: new Big('13298.425356'), errors: [], grossPerformance: new Big('27172.74'), @@ -175,6 +175,8 @@ describe('PortfolioCalculator', () => { valueInBaseCurrency: new Big('13298.425356') } ], + totalFeesWithCurrencyEffect: new Big('0'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('320.43'), totalInvestmentWithCurrencyEffect: new Big('318.542667299999967957') }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts new file mode 100644 index 000000000..b689a0c30 --- /dev/null +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts @@ -0,0 +1,132 @@ +import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PortfolioCalculatorFactory, + PerformanceCalculationType +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; +import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; +import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; +import { parseDate } from '@ghostfolio/common/helper'; + +import { Big } from 'big.js'; + +jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + CurrentRateService: jest.fn().mockImplementation(() => { + return CurrentRateServiceMock; + }) + }; +}); + +describe('PortfolioCalculator', () => { + let currentRateService: CurrentRateService; + let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; + + beforeEach(() => { + currentRateService = new CurrentRateService(null, null, null, null); + + exchangeRateDataService = new ExchangeRateDataService( + null, + null, + null, + null + ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); + }); + + describe('compute portfolio snapshot', () => { + it.only('with fee activity', async () => { + const spy = jest + .spyOn(Date, 'now') + .mockImplementation(() => parseDate('2021-12-18').getTime()); + + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2021-09-01'), + fee: 49, + quantity: 0, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'USD', + dataSource: 'MANUAL', + name: 'Account Opening Fee', + symbol: '2c463fb3-af07-486e-adb0-8301b3d72141' + }, + type: 'FEE', + unitPrice: 0 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, + currency: 'USD' + }); + + const portfolioSnapshot = await portfolioCalculator.computeSnapshot( + parseDate('2021-11-30') + ); + + spy.mockRestore(); + + expect(portfolioSnapshot).toEqual({ + currentValueInBaseCurrency: new Big('0'), + errors: [], + grossPerformance: new Big('0'), + grossPerformancePercentage: new Big('0'), + grossPerformancePercentageWithCurrencyEffect: new Big('0'), + grossPerformanceWithCurrencyEffect: new Big('0'), + hasErrors: true, + netPerformance: new Big('0'), + netPerformancePercentage: new Big('0'), + netPerformancePercentageWithCurrencyEffect: new Big('0'), + netPerformanceWithCurrencyEffect: new Big('0'), + positions: [ + { + averagePrice: new Big('0'), + currency: 'USD', + dataSource: 'MANUAL', + dividend: new Big('0'), + dividendInBaseCurrency: new Big('0'), + fee: new Big('49'), + firstBuyDate: '2021-09-01', + grossPerformance: null, + grossPerformancePercentage: null, + grossPerformancePercentageWithCurrencyEffect: null, + grossPerformanceWithCurrencyEffect: null, + investment: new Big('0'), + investmentWithCurrencyEffect: new Big('0'), + marketPrice: null, + marketPriceInBaseCurrency: 0, + netPerformance: null, + netPerformancePercentage: null, + netPerformancePercentageWithCurrencyEffect: null, + netPerformanceWithCurrencyEffect: null, + quantity: new Big('0'), + symbol: '2c463fb3-af07-486e-adb0-8301b3d72141', + tags: [], + timeWeightedInvestment: new Big('0'), + timeWeightedInvestmentWithCurrencyEffect: new Big('0'), + transactionCount: 1, + valueInBaseCurrency: new Big('0') + } + ], + totalFeesWithCurrencyEffect: new Big('49'), + totalInterestWithCurrencyEffect: new Big('0'), + totalInvestment: new Big('0'), + totalInvestmentWithCurrencyEffect: new Big('0') + }); + }); + }); +}); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts index e7796b4d3..911167f7a 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts @@ -59,6 +59,10 @@ describe('PortfolioCalculator', () => { describe('get current positions', () => { it.only('with GOOGL buy', async () => { + const spy = jest + .spyOn(Date, 'now') + .mockImplementation(() => parseDate('2023-07-10').getTime()); + const activities: Activity[] = [ { ...activityDummyData, @@ -83,15 +87,11 @@ describe('PortfolioCalculator', () => { currency: 'CHF' }); - const spy = jest - .spyOn(Date, 'now') - .mockImplementation(() => parseDate('2023-07-10').getTime()); - const chartData = await portfolioCalculator.getChartData({ start: parseDate('2023-01-03') }); - const currentPositions = await portfolioCalculator.getCurrentPositions( + const portfolioSnapshot = await portfolioCalculator.computeSnapshot( parseDate('2023-01-03') ); @@ -104,7 +104,7 @@ describe('PortfolioCalculator', () => { spy.mockRestore(); - expect(currentPositions).toEqual({ + expect(portfolioSnapshot).toEqual({ currentValueInBaseCurrency: new Big('103.10483'), errors: [], grossPerformance: new Big('27.33'), @@ -154,6 +154,8 @@ describe('PortfolioCalculator', () => { valueInBaseCurrency: new Big('103.10483') } ], + totalFeesWithCurrencyEffect: new Big('1'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('89.12'), totalInvestmentWithCurrencyEffect: new Big('82.329056') }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts index 49a07e73f..6dc489c5d 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts @@ -59,6 +59,10 @@ describe('PortfolioCalculator', () => { describe('get current positions', () => { it.only('with MSFT buy', async () => { + const spy = jest + .spyOn(Date, 'now') + .mockImplementation(() => parseDate('2023-07-10').getTime()); + const activities: Activity[] = [ { ...activityDummyData, @@ -98,17 +102,13 @@ describe('PortfolioCalculator', () => { currency: 'USD' }); - const spy = jest - .spyOn(Date, 'now') - .mockImplementation(() => parseDate('2023-07-10').getTime()); - - const currentPositions = await portfolioCalculator.getCurrentPositions( + const portfolioSnapshot = await portfolioCalculator.computeSnapshot( parseDate('2023-07-10') ); spy.mockRestore(); - expect(currentPositions).toMatchObject({ + expect(portfolioSnapshot).toMatchObject({ errors: [], hasErrors: false, positions: [ @@ -130,6 +130,8 @@ describe('PortfolioCalculator', () => { transactionCount: 2 } ], + totalFeesWithCurrencyEffect: new Big('19'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('298.58'), totalInvestmentWithCurrencyEffect: new Big('298.58') }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts index 905747519..ece39c87b 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts @@ -42,22 +42,22 @@ describe('PortfolioCalculator', () => { describe('get current positions', () => { it('with no orders', async () => { + const spy = jest + .spyOn(Date, 'now') + .mockImplementation(() => parseDate('2021-12-18').getTime()); + const portfolioCalculator = factory.createCalculator({ activities: [], calculationType: PerformanceCalculationType.TWR, currency: 'CHF' }); - const spy = jest - .spyOn(Date, 'now') - .mockImplementation(() => parseDate('2021-12-18').getTime()); - const start = subDays(new Date(Date.now()), 10); const chartData = await portfolioCalculator.getChartData({ start }); - const currentPositions = - await portfolioCalculator.getCurrentPositions(start); + const portfolioSnapshot = + await portfolioCalculator.computeSnapshot(start); const investments = portfolioCalculator.getInvestments(); @@ -68,7 +68,7 @@ describe('PortfolioCalculator', () => { spy.mockRestore(); - expect(currentPositions).toEqual({ + expect(portfolioSnapshot).toEqual({ currentValueInBaseCurrency: new Big(0), grossPerformance: new Big(0), grossPerformancePercentage: new Big(0), @@ -80,6 +80,8 @@ describe('PortfolioCalculator', () => { netPerformancePercentageWithCurrencyEffect: new Big(0), netPerformanceWithCurrencyEffect: new Big(0), positions: [], + totalFeesWithCurrencyEffect: new Big('0'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big(0), totalInvestmentWithCurrencyEffect: new Big(0) }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts index 2bfd6d865..a3c12829a 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts @@ -46,6 +46,10 @@ describe('PortfolioCalculator', () => { describe('get current positions', () => { it.only('with NOVN.SW buy and sell partially', async () => { + const spy = jest + .spyOn(Date, 'now') + .mockImplementation(() => parseDate('2022-04-11').getTime()); + const activities: Activity[] = [ { ...activityDummyData, @@ -84,15 +88,12 @@ describe('PortfolioCalculator', () => { calculationType: PerformanceCalculationType.TWR, currency: 'CHF' }); - const spy = jest - .spyOn(Date, 'now') - .mockImplementation(() => parseDate('2022-04-11').getTime()); const chartData = await portfolioCalculator.getChartData({ start: parseDate('2022-03-07') }); - const currentPositions = await portfolioCalculator.getCurrentPositions( + const portfolioSnapshot = await portfolioCalculator.computeSnapshot( parseDate('2022-03-07') ); @@ -105,7 +106,7 @@ describe('PortfolioCalculator', () => { spy.mockRestore(); - expect(currentPositions).toEqual({ + expect(portfolioSnapshot).toEqual({ currentValueInBaseCurrency: new Big('87.8'), errors: [], grossPerformance: new Big('21.93'), @@ -157,6 +158,8 @@ describe('PortfolioCalculator', () => { valueInBaseCurrency: new Big('87.8') } ], + totalFeesWithCurrencyEffect: new Big('4.25'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('75.80'), totalInvestmentWithCurrencyEffect: new Big('75.80') }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts index be3f75dc2..f1bf56f11 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts @@ -46,6 +46,10 @@ describe('PortfolioCalculator', () => { describe('get current positions', () => { it.only('with NOVN.SW buy and sell', async () => { + const spy = jest + .spyOn(Date, 'now') + .mockImplementation(() => parseDate('2022-04-11').getTime()); + const activities: Activity[] = [ { ...activityDummyData, @@ -85,15 +89,11 @@ describe('PortfolioCalculator', () => { currency: 'CHF' }); - const spy = jest - .spyOn(Date, 'now') - .mockImplementation(() => parseDate('2022-04-11').getTime()); - const chartData = await portfolioCalculator.getChartData({ start: parseDate('2022-03-07') }); - const currentPositions = await portfolioCalculator.getCurrentPositions( + const portfolioSnapshot = await portfolioCalculator.computeSnapshot( parseDate('2022-03-07') ); @@ -132,7 +132,7 @@ describe('PortfolioCalculator', () => { valueWithCurrencyEffect: 0 }); - expect(currentPositions).toEqual({ + expect(portfolioSnapshot).toEqual({ currentValueInBaseCurrency: new Big('0'), errors: [], grossPerformance: new Big('19.86'), @@ -182,6 +182,8 @@ describe('PortfolioCalculator', () => { valueInBaseCurrency: new Big('0') } ], + totalFeesWithCurrencyEffect: new Big('0'), + totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('0'), totalInvestmentWithCurrencyEffect: new Big('0') }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index 0fee9c5c7..b9b7fd900 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -1,6 +1,6 @@ import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; -import { CurrentPositions } from '@ghostfolio/api/app/portfolio/interfaces/current-positions.interface'; import { PortfolioOrderItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order-item.interface'; +import { PortfolioSnapshot } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-snapshot.interface'; import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { @@ -23,19 +23,27 @@ import { cloneDeep, first, last, sortBy } from 'lodash'; export class TWRPortfolioCalculator extends PortfolioCalculator { protected calculateOverallPerformance( positions: TimelinePosition[] - ): CurrentPositions { + ): PortfolioSnapshot { let currentValueInBaseCurrency = new Big(0); let grossPerformance = new Big(0); let grossPerformanceWithCurrencyEffect = new Big(0); let hasErrors = false; let netPerformance = new Big(0); let netPerformanceWithCurrencyEffect = new Big(0); + let totalFeesWithCurrencyEffect = new Big(0); + let totalInterestWithCurrencyEffect = new Big(0); let totalInvestment = new Big(0); let totalInvestmentWithCurrencyEffect = new Big(0); let totalTimeWeightedInvestment = new Big(0); let totalTimeWeightedInvestmentWithCurrencyEffect = new Big(0); for (const currentPosition of positions) { + if (currentPosition.fee) { + totalFeesWithCurrencyEffect = totalFeesWithCurrencyEffect.plus( + currentPosition.fee + ); + } + if (currentPosition.valueInBaseCurrency) { currentValueInBaseCurrency = currentValueInBaseCurrency.plus( currentPosition.valueInBaseCurrency @@ -101,6 +109,8 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { hasErrors, netPerformance, netPerformanceWithCurrencyEffect, + totalFeesWithCurrencyEffect, + totalInterestWithCurrencyEffect, totalInvestment, totalInvestmentWithCurrencyEffect, netPerformancePercentage: totalTimeWeightedInvestment.eq(0) @@ -178,6 +188,8 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { let totalDividend = new Big(0); let totalDividendInBaseCurrency = new Big(0); + let totalInterest = new Big(0); + let totalInterestInBaseCurrency = new Big(0); let totalInvestment = new Big(0); let totalInvestmentFromBuyTransactions = new Big(0); let totalInvestmentFromBuyTransactionsWithCurrencyEffect = new Big(0); @@ -198,6 +210,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { return { currentValues: {}, currentValuesWithCurrencyEffect: {}, + feesWithCurrencyEffect: new Big(0), grossPerformance: new Big(0), grossPerformancePercentage: new Big(0), grossPerformancePercentageWithCurrencyEffect: new Big(0), @@ -220,6 +233,8 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { timeWeightedInvestmentWithCurrencyEffect: new Big(0), totalDividend: new Big(0), totalDividendInBaseCurrency: new Big(0), + totalInterest: new Big(0), + totalInterestInBaseCurrency: new Big(0), totalInvestment: new Big(0), totalInvestmentWithCurrencyEffect: new Big(0) }; @@ -240,6 +255,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { return { currentValues: {}, currentValuesWithCurrencyEffect: {}, + feesWithCurrencyEffect: new Big(0), grossPerformance: new Big(0), grossPerformancePercentage: new Big(0), grossPerformancePercentageWithCurrencyEffect: new Big(0), @@ -262,6 +278,8 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { timeWeightedInvestmentWithCurrencyEffect: new Big(0), totalDividend: new Big(0), totalDividendInBaseCurrency: new Big(0), + totalInterest: new Big(0), + totalInterestInBaseCurrency: new Big(0), totalInvestment: new Big(0), totalInvestmentWithCurrencyEffect: new Big(0) }; @@ -511,6 +529,13 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { totalDividendInBaseCurrency = totalDividendInBaseCurrency.plus( dividend.mul(exchangeRateAtOrderDate ?? 1) ); + } else if (order.type === 'INTEREST') { + const interest = order.quantity.mul(order.unitPrice); + + totalInterest = totalInterest.plus(interest); + totalInterestInBaseCurrency = totalInterestInBaseCurrency.plus( + interest.mul(exchangeRateAtOrderDate ?? 1) + ); } const valueOfInvestment = totalUnits.mul(order.unitPriceInBaseCurrency); @@ -808,6 +833,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { return { currentValues, currentValuesWithCurrencyEffect, + feesWithCurrencyEffect, grossPerformancePercentage, grossPerformancePercentageWithCurrencyEffect, initialValue, @@ -823,6 +849,8 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { timeWeightedInvestmentValuesWithCurrencyEffect, totalDividend, totalDividendInBaseCurrency, + totalInterest, + totalInterestInBaseCurrency, totalInvestment, totalInvestmentWithCurrencyEffect, grossPerformance: totalGrossPerformance, diff --git a/apps/api/src/app/portfolio/interfaces/current-positions.interface.ts b/apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts similarity index 82% rename from apps/api/src/app/portfolio/interfaces/current-positions.interface.ts rename to apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts index 308cc4037..b8cc904fa 100644 --- a/apps/api/src/app/portfolio/interfaces/current-positions.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts @@ -2,7 +2,7 @@ import { ResponseError, TimelinePosition } from '@ghostfolio/common/interfaces'; import { Big } from 'big.js'; -export interface CurrentPositions extends ResponseError { +export interface PortfolioSnapshot extends ResponseError { currentValueInBaseCurrency: Big; grossPerformance: Big; grossPerformanceWithCurrencyEffect: Big; @@ -15,6 +15,8 @@ export interface CurrentPositions extends ResponseError { netPerformancePercentage: Big; netPerformancePercentageWithCurrencyEffect: Big; positions: TimelinePosition[]; + totalFeesWithCurrencyEffect: Big; + totalInterestWithCurrencyEffect: Big; totalInvestment: Big; totalInvestmentWithCurrencyEffect: Big; } diff --git a/apps/api/src/app/portfolio/interfaces/transaction-point.interface.ts b/apps/api/src/app/portfolio/interfaces/transaction-point.interface.ts index 178df3456..2f5218405 100644 --- a/apps/api/src/app/portfolio/interfaces/transaction-point.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/transaction-point.interface.ts @@ -1,6 +1,10 @@ +import { Big } from 'big.js'; + import { TransactionPointSymbol } from './transaction-point-symbol.interface'; export interface TransactionPoint { date: string; + fees: Big; + interest: Big; items: TransactionPointSymbol[]; } diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index efb9318d7..7ee92e91c 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -107,7 +107,8 @@ export class PortfolioController { dateRange, filters, impersonationId, - withLiabilities, + // TODO + // withLiabilities, withMarkets, userId: this.request.user.id, withSummary: true @@ -389,11 +390,9 @@ export class PortfolioController { @Query('assetClasses') filterByAssetClasses?: string, @Query('range') dateRange: DateRange = 'max', @Query('tags') filterByTags?: string, - @Query('withExcludedAccounts') withExcludedAccountsParam = 'false', - @Query('withItems') withItemsParam = 'false' + @Query('withExcludedAccounts') withExcludedAccountsParam = 'false' ): Promise { const withExcludedAccounts = withExcludedAccountsParam === 'true'; - const withItems = withItemsParam === 'true'; const hasReadRestrictedAccessPermission = this.userService.hasReadRestrictedAccessPermission({ @@ -412,7 +411,6 @@ export class PortfolioController { filters, impersonationId, withExcludedAccounts, - withItems, userId: this.request.user.id }); diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 198395e51..8714a15ec 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -23,12 +23,7 @@ import { EMERGENCY_FUND_TAG_ID, UNKNOWN_KEY } from '@ghostfolio/common/config'; -import { - DATE_FORMAT, - getAllActivityTypes, - getSum, - parseDate -} from '@ghostfolio/common/helper'; +import { DATE_FORMAT, getSum, parseDate } from '@ghostfolio/common/helper'; import { Accounts, EnhancedSymbolProfile, @@ -78,6 +73,7 @@ import { } from 'date-fns'; import { isEmpty, isNumber, last, uniq, uniqBy } from 'lodash'; +import { PortfolioCalculator } from './calculator/portfolio-calculator'; import { PerformanceCalculationType, PortfolioCalculatorFactory @@ -349,19 +345,8 @@ export class PortfolioService { (user.Settings?.settings as UserSettings)?.emergencyFund ?? 0 ); - let types = getAllActivityTypes().filter((activityType) => { - return activityType !== 'FEE'; - }); - - if (withLiabilities === false) { - types = types.filter((activityType) => { - return activityType !== 'LIABILITY'; - }); - } - const { activities } = await this.orderService.getOrders({ filters, - types, userCurrency, userId, withExcludedAccounts @@ -369,16 +354,13 @@ export class PortfolioService { const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, + dateRange, calculationType: PerformanceCalculationType.TWR, currency: userCurrency }); - const { startDate } = getInterval( - dateRange, - portfolioCalculator.getStartDate() - ); - const currentPositions = - await portfolioCalculator.getCurrentPositions(startDate); + const { currentValueInBaseCurrency, hasErrors, positions } = + await portfolioCalculator.getSnapshot(); const cashDetails = await this.accountService.getCashDetails({ filters, @@ -388,10 +370,9 @@ export class PortfolioService { const holdings: PortfolioDetails['holdings'] = {}; - const totalValueInBaseCurrency = - currentPositions.currentValueInBaseCurrency.plus( - cashDetails.balanceInBaseCurrency - ); + const totalValueInBaseCurrency = currentValueInBaseCurrency.plus( + cashDetails.balanceInBaseCurrency + ); const isFilteredByAccount = filters?.some(({ type }) => { @@ -409,7 +390,7 @@ export class PortfolioService { let filteredValueInBaseCurrency = isFilteredByAccount ? totalValueInBaseCurrency - : currentPositions.currentValueInBaseCurrency; + : currentValueInBaseCurrency; if ( filters?.length === 0 || @@ -422,14 +403,12 @@ export class PortfolioService { ); } - const dataGatheringItems = currentPositions.positions.map( - ({ dataSource, symbol }) => { - return { - dataSource, - symbol - }; - } - ); + const dataGatheringItems = positions.map(({ dataSource, symbol }) => { + return { + dataSource, + symbol + }; + }); const [dataProviderResponses, symbolProfiles] = await Promise.all([ this.dataProviderService.getQuotes({ user, items: dataGatheringItems }), @@ -442,7 +421,7 @@ export class PortfolioService { } const portfolioItemsNow: { [symbol: string]: TimelinePosition } = {}; - for (const position of currentPositions.positions) { + for (const position of positions) { portfolioItemsNow[position.symbol] = position; } @@ -465,7 +444,7 @@ export class PortfolioService { tags, transactionCount, valueInBaseCurrency - } of currentPositions.positions) { + } of positions) { if (isFilteredByClosedHoldings === true) { if (!quantity.eq(0)) { // Ignore positions with a quantity @@ -593,6 +572,7 @@ export class PortfolioService { filteredValueInBaseCurrency, holdings, impersonationId, + portfolioCalculator, userCurrency, userId, balanceInBaseCurrency: cashDetails.balanceInBaseCurrency, @@ -605,10 +585,10 @@ export class PortfolioService { return { accounts, + hasErrors, holdings, platforms, - summary, - hasErrors: currentPositions.hasErrors + summary }; } @@ -681,10 +661,9 @@ export class PortfolioService { const portfolioStart = portfolioCalculator.getStartDate(); const transactionPoints = portfolioCalculator.getTransactionPoints(); - const currentPositions = - await portfolioCalculator.getCurrentPositions(portfolioStart); + const { positions } = await portfolioCalculator.getSnapshot(); - const position = currentPositions.positions.find(({ symbol }) => { + const position = positions.find(({ symbol }) => { return symbol === aSymbol; }); @@ -916,13 +895,12 @@ export class PortfolioService { const userId = await this.getUserId(impersonationId, this.request.user.id); const user = await this.userService.user({ id: userId }); - const { endDate, startDate } = getInterval(dateRange); + const { endDate } = getInterval(dateRange); const { activities } = await this.orderService.getOrders({ endDate, filters, userId, - types: ['BUY', 'SELL'], userCurrency: this.getUserCurrency() }); @@ -935,16 +913,14 @@ export class PortfolioService { const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, + dateRange, calculationType: PerformanceCalculationType.TWR, currency: this.request.user.Settings.settings.baseCurrency }); - const currentPositions = await portfolioCalculator.getCurrentPositions( - startDate, - endDate - ); + let { hasErrors, positions } = await portfolioCalculator.getSnapshot(); - let positions = currentPositions.positions.filter(({ quantity }) => { + positions = positions.filter(({ quantity }) => { return !quantity.eq(0); }); @@ -983,7 +959,7 @@ export class PortfolioService { } return { - hasErrors: currentPositions.hasErrors, + hasErrors, positions: positions.map( ({ averagePrice, @@ -1050,15 +1026,13 @@ export class PortfolioService { filters, impersonationId, userId, - withExcludedAccounts = false, - withItems = false + withExcludedAccounts = false }: { dateRange?: DateRange; filters?: Filter[]; impersonationId: string; userId: string; withExcludedAccounts?: boolean; - withItems?: boolean; }): Promise { userId = await this.getUserId(impersonationId, userId); const user = await this.userService.user({ id: userId }); @@ -1096,8 +1070,7 @@ export class PortfolioService { filters, userCurrency, userId, - withExcludedAccounts, - types: withItems ? ['BUY', 'ITEM', 'SELL'] : ['BUY', 'SELL'] + withExcludedAccounts }); if (accountBalanceItems?.length <= 0 && activities?.length <= 0) { @@ -1123,6 +1096,7 @@ export class PortfolioService { const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, + dateRange, calculationType: PerformanceCalculationType.TWR, currency: userCurrency }); @@ -1140,7 +1114,7 @@ export class PortfolioService { netPerformancePercentageWithCurrencyEffect, netPerformanceWithCurrencyEffect, totalInvestment - } = await portfolioCalculator.getCurrentPositions(startDate, endDate); + } = await portfolioCalculator.getSnapshot(); let currentNetPerformance = netPerformance; @@ -1231,8 +1205,7 @@ export class PortfolioService { const { activities } = await this.orderService.getOrders({ userCurrency, - userId, - types: ['BUY', 'SELL'] + userId }); const portfolioCalculator = this.calculatorFactory.createCalculator({ @@ -1241,13 +1214,10 @@ export class PortfolioService { currency: this.request.user.Settings.settings.baseCurrency }); - const currentPositions = await portfolioCalculator.getCurrentPositions( - portfolioCalculator.getStartDate() - ); + let { totalFeesWithCurrencyEffect, positions, totalInvestment } = + await portfolioCalculator.getSnapshot(); - const positions = currentPositions.positions.filter( - (item) => !item.quantity.eq(0) - ); + positions = positions.filter((item) => !item.quantity.eq(0)); const portfolioItemsNow: { [symbol: string]: TimelinePosition } = {}; @@ -1309,8 +1279,8 @@ export class PortfolioService { [ new FeeRatioInitialInvestment( this.exchangeRateDataService, - currentPositions.totalInvestment.toNumber(), - this.getFees({ activities, userCurrency }).toNumber() + totalInvestment.toNumber(), + totalFeesWithCurrencyEffect.toNumber() ) ], userSettings @@ -1454,30 +1424,6 @@ export class PortfolioService { return valueInBaseCurrencyOfEmergencyFundPositions.toNumber(); } - private getFees({ - activities, - userCurrency - }: { - activities: Activity[]; - userCurrency: string; - }) { - return getSum( - activities - .filter(({ isDraft }) => { - return isDraft === false; - }) - .map(({ fee, SymbolProfile }) => { - return new Big( - this.exchangeRateDataService.toCurrency( - fee, - SymbolProfile.currency, - userCurrency - ) - ); - }) - ); - } - private getInitialCashPosition({ balance, currency @@ -1623,6 +1569,7 @@ export class PortfolioService { filteredValueInBaseCurrency, holdings, impersonationId, + portfolioCalculator, userCurrency, userId }: { @@ -1631,6 +1578,7 @@ export class PortfolioService { filteredValueInBaseCurrency: Big; holdings: PortfolioDetails['holdings']; impersonationId: string; + portfolioCalculator: PortfolioCalculator; userCurrency: string; userId: string; }): Promise { @@ -1659,17 +1607,8 @@ export class PortfolioService { } } - const dividendInBaseCurrency = getSum( - ( - await this.getDividends({ - activities: activities.filter(({ type }) => { - return type === 'DIVIDEND'; - }) - }) - ).map(({ investment }) => { - return new Big(investment); - }) - ); + const dividendInBaseCurrency = + await portfolioCalculator.getDividendInBaseCurrency(); const emergencyFund = new Big( Math.max( @@ -1678,15 +1617,13 @@ export class PortfolioService { ) ); - const fees = this.getFees({ activities, userCurrency }).toNumber(); - const firstOrderDate = activities[0]?.date; + const fees = await portfolioCalculator.getFeesInBaseCurrency(); - const interest = this.getSumOfActivityType({ - activities, - userCurrency, - activityType: 'INTEREST' - }).toNumber(); + const firstOrderDate = portfolioCalculator.getStartDate(); + + const interest = await portfolioCalculator.getInterestInBaseCurrency(); + // TODO: Move to portfolio calculator const items = getSum( Object.keys(holdings) .filter((symbol) => { @@ -1701,6 +1638,7 @@ export class PortfolioService { }) ).toNumber(); + // TODO: Move to portfolio calculator const liabilities = getSum( Object.keys(holdings) .filter((symbol) => { @@ -1791,9 +1729,7 @@ export class PortfolioService { annualizedPerformancePercentWithCurrencyEffect, cash, excludedAccountsAndActivities, - fees, firstOrderDate, - interest, items, liabilities, totalBuy, @@ -1807,6 +1743,7 @@ export class PortfolioService { .toNumber(), total: emergencyFund.toNumber() }, + fees: fees.toNumber(), filteredValueInBaseCurrency: filteredValueInBaseCurrency.toNumber(), filteredValueInPercentage: netWorth ? filteredValueInBaseCurrency.div(netWorth).toNumber() @@ -1814,6 +1751,7 @@ export class PortfolioService { fireWealth: new Big(performanceInformation.performance.currentValue) .minus(emergencyFundPositionsValueInBaseCurrency) .toNumber(), + interest: interest.toNumber(), ordersCount: activities.filter(({ type }) => { return type === 'BUY' || type === 'SELL'; }).length, diff --git a/apps/api/src/helper/portfolio.helper.ts b/apps/api/src/helper/portfolio.helper.ts index 730f34bde..f762b2ad5 100644 --- a/apps/api/src/helper/portfolio.helper.ts +++ b/apps/api/src/helper/portfolio.helper.ts @@ -37,36 +37,48 @@ export function getInterval( aDateRange: DateRange, portfolioStart = new Date(0) ) { - let endDate = endOfDay(new Date()); + let endDate = endOfDay(new Date(Date.now())); let startDate = portfolioStart; switch (aDateRange) { case '1d': - startDate = max([startDate, subDays(resetHours(new Date()), 1)]); + startDate = max([ + startDate, + subDays(resetHours(new Date(Date.now())), 1) + ]); break; case 'mtd': startDate = max([ startDate, - subDays(startOfMonth(resetHours(new Date())), 1) + subDays(startOfMonth(resetHours(new Date(Date.now()))), 1) ]); break; case 'wtd': startDate = max([ startDate, - subDays(startOfWeek(resetHours(new Date()), { weekStartsOn: 1 }), 1) + subDays( + startOfWeek(resetHours(new Date(Date.now())), { weekStartsOn: 1 }), + 1 + ) ]); break; case 'ytd': startDate = max([ startDate, - subDays(startOfYear(resetHours(new Date())), 1) + subDays(startOfYear(resetHours(new Date(Date.now()))), 1) ]); break; case '1y': - startDate = max([startDate, subYears(resetHours(new Date()), 1)]); + startDate = max([ + startDate, + subYears(resetHours(new Date(Date.now())), 1) + ]); break; case '5y': - startDate = max([startDate, subYears(resetHours(new Date()), 5)]); + startDate = max([ + startDate, + subYears(resetHours(new Date(Date.now())), 5) + ]); break; case 'max': break; diff --git a/libs/common/src/lib/interfaces/symbol-metrics.interface.ts b/libs/common/src/lib/interfaces/symbol-metrics.interface.ts index ecb80ef92..99a1b3467 100644 --- a/libs/common/src/lib/interfaces/symbol-metrics.interface.ts +++ b/libs/common/src/lib/interfaces/symbol-metrics.interface.ts @@ -7,6 +7,7 @@ export interface SymbolMetrics { currentValuesWithCurrencyEffect: { [date: string]: Big; }; + feesWithCurrencyEffect: Big; grossPerformance: Big; grossPerformancePercentage: Big; grossPerformancePercentageWithCurrencyEffect: Big; @@ -41,6 +42,8 @@ export interface SymbolMetrics { timeWeightedInvestmentWithCurrencyEffect: Big; totalDividend: Big; totalDividendInBaseCurrency: Big; + totalInterest: Big; + totalInterestInBaseCurrency: Big; totalInvestment: Big; totalInvestmentWithCurrencyEffect: Big; } From 5d4e2fba8c8e160df07a735c1e73578a834f7333 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 14 Apr 2024 08:12:32 +0200 Subject: [PATCH 119/203] Feature/move wealth item and liability calculations to portfolio calculator (#3272) * Move (wealth) item calculations to portfolio calculator * Move liability calculations to portfolio calculator * Update changelog --- CHANGELOG.md | 2 + .../calculator/portfolio-calculator.ts | 66 +++++++-- ...aln-buy-and-sell-in-two-activities.spec.ts | 4 +- ...folio-calculator-baln-buy-and-sell.spec.ts | 4 +- .../twr/portfolio-calculator-baln-buy.spec.ts | 4 +- ...ator-btcusd-buy-and-sell-partially.spec.ts | 4 +- .../twr/portfolio-calculator-fee.spec.ts | 4 +- .../portfolio-calculator-googl-buy.spec.ts | 4 +- .../twr/portfolio-calculator-item.spec.ts | 134 ++++++++++++++++++ .../portfolio-calculator-liability.spec.ts | 134 ++++++++++++++++++ ...-calculator-msft-buy-with-dividend.spec.ts | 4 +- .../portfolio-calculator-no-orders.spec.ts | 4 +- ...ulator-novn-buy-and-sell-partially.spec.ts | 4 +- ...folio-calculator-novn-buy-and-sell.spec.ts | 4 +- .../calculator/twr/portfolio-calculator.ts | 38 ++++- .../portfolio-snapshot.interface.ts | 2 + .../interfaces/transaction-point.interface.ts | 2 + .../src/app/portfolio/portfolio.controller.ts | 4 - .../src/app/portfolio/portfolio.service.ts | 42 +----- apps/api/src/helper/portfolio.helper.ts | 2 - .../home-summary/home-summary.component.ts | 2 +- apps/client/src/app/services/data.service.ts | 6 - .../interfaces/symbol-metrics.interface.ts | 4 + 23 files changed, 406 insertions(+), 72 deletions(-) create mode 100644 apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-item.spec.ts create mode 100644 apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 7da5c3ddd..4fec3111c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Moved the dividend calculations into the portfolio calculator - Moved the fee calculations into the portfolio calculator - Moved the interest calculations into the portfolio calculator +- Moved the liability calculations into the portfolio calculator +- Moved the (wealth) item calculations into the portfolio calculator ## 2.72.0 - 2024-04-13 diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index 712c0ac04..1d2eadfbf 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -140,7 +140,9 @@ export abstract class PortfolioCalculator { totalFeesWithCurrencyEffect: new Big(0), totalInterestWithCurrencyEffect: new Big(0), totalInvestment: new Big(0), - totalInvestmentWithCurrencyEffect: new Big(0) + totalInvestmentWithCurrencyEffect: new Big(0), + totalLiabilitiesWithCurrencyEffect: new Big(0), + totalValuablesWithCurrencyEffect: new Big(0) }; } @@ -149,6 +151,9 @@ export abstract class PortfolioCalculator { let dates: Date[] = []; let firstIndex = transactionPoints.length; let firstTransactionPoint: TransactionPoint = null; + let totalInterestWithCurrencyEffect = new Big(0); + let totalLiabilitiesWithCurrencyEffect = new Big(0); + let totalValuablesWithCurrencyEffect = new Big(0); dates.push(resetHours(start)); @@ -274,8 +279,11 @@ export abstract class PortfolioCalculator { timeWeightedInvestmentWithCurrencyEffect, totalDividend, totalDividendInBaseCurrency, + totalInterestInBaseCurrency, totalInvestment, - totalInvestmentWithCurrencyEffect + totalInvestmentWithCurrencyEffect, + totalLiabilitiesInBaseCurrency, + totalValuablesInBaseCurrency } = this.getSymbolMetrics({ marketSymbolMap, start, @@ -333,6 +341,17 @@ export abstract class PortfolioCalculator { ) }); + totalInterestWithCurrencyEffect = totalInterestWithCurrencyEffect.plus( + totalInterestInBaseCurrency + ); + + totalLiabilitiesWithCurrencyEffect = + totalLiabilitiesWithCurrencyEffect.plus(totalLiabilitiesInBaseCurrency); + + totalValuablesWithCurrencyEffect = totalValuablesWithCurrencyEffect.plus( + totalValuablesInBaseCurrency + ); + if ( (hasErrors || currentRateErrors.find(({ dataSource, symbol }) => { @@ -350,8 +369,10 @@ export abstract class PortfolioCalculator { ...overall, errors, positions, - hasErrors: hasAnySymbolMetricsErrors || overall.hasErrors, - totalInterestWithCurrencyEffect: lastTransactionPoint.interest + totalInterestWithCurrencyEffect, + totalLiabilitiesWithCurrencyEffect, + totalValuablesWithCurrencyEffect, + hasErrors: hasAnySymbolMetricsErrors || overall.hasErrors }; } @@ -715,6 +736,12 @@ export abstract class PortfolioCalculator { })); } + public async getLiabilitiesInBaseCurrency() { + await this.snapshotPromise; + + return this.snapshot.totalLiabilitiesWithCurrencyEffect; + } + public async getSnapshot() { await this.snapshotPromise; @@ -751,6 +778,12 @@ export abstract class PortfolioCalculator { return this.transactionPoints; } + public async getValuablesInBaseCurrency() { + await this.snapshotPromise; + + return this.snapshot.totalValuablesWithCurrencyEffect; + } + private computeTransactionPoints() { this.transactionPoints = []; const symbols: { [symbol: string]: TransactionPointSymbol } = {}; @@ -767,13 +800,6 @@ export abstract class PortfolioCalculator { type, unitPrice } of this.orders) { - if ( - // TODO - ['ITEM', 'LIABILITY'].includes(type) - ) { - continue; - } - let currentTransactionPointItem: TransactionPointSymbol; const oldAccumulatedSymbol = symbols[SymbolProfile.symbol]; @@ -858,11 +884,25 @@ export abstract class PortfolioCalculator { interest = quantity.mul(unitPrice); } + let liabilities = new Big(0); + + if (type === 'LIABILITY') { + liabilities = quantity.mul(unitPrice); + } + + let valuables = new Big(0); + + if (type === 'ITEM') { + valuables = quantity.mul(unitPrice); + } + if (lastDate !== date || lastTransactionPoint === null) { lastTransactionPoint = { date, fees, interest, + liabilities, + valuables, items: newItems }; @@ -872,6 +912,10 @@ export abstract class PortfolioCalculator { lastTransactionPoint.interest = lastTransactionPoint.interest.plus(interest); lastTransactionPoint.items = newItems; + lastTransactionPoint.liabilities = + lastTransactionPoint.liabilities.plus(liabilities); + lastTransactionPoint.valuables = + lastTransactionPoint.valuables.plus(valuables); } lastDate = date; diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts index 8ddae9df6..a11ae8896 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts @@ -176,7 +176,9 @@ describe('PortfolioCalculator', () => { totalFeesWithCurrencyEffect: new Big('3.2'), totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('0'), - totalInvestmentWithCurrencyEffect: new Big('0') + totalInvestmentWithCurrencyEffect: new Big('0'), + totalLiabilitiesWithCurrencyEffect: new Big('0'), + totalValuablesWithCurrencyEffect: new Big('0') }); expect(investments).toEqual([ diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts index febd1769d..8d93d8b97 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts @@ -159,7 +159,9 @@ describe('PortfolioCalculator', () => { totalFeesWithCurrencyEffect: new Big('3.2'), totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('0'), - totalInvestmentWithCurrencyEffect: new Big('0') + totalInvestmentWithCurrencyEffect: new Big('0'), + totalLiabilitiesWithCurrencyEffect: new Big('0'), + totalValuablesWithCurrencyEffect: new Big('0') }); expect(investments).toEqual([ diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts index 2b9fd06f0..f26331134 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts @@ -144,7 +144,9 @@ describe('PortfolioCalculator', () => { totalFeesWithCurrencyEffect: new Big('1.55'), totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('273.2'), - totalInvestmentWithCurrencyEffect: new Big('273.2') + totalInvestmentWithCurrencyEffect: new Big('273.2'), + totalLiabilitiesWithCurrencyEffect: new Big('0'), + totalValuablesWithCurrencyEffect: new Big('0') }); expect(investments).toEqual([ diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts index ceff92449..2a9ba0916 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts @@ -178,7 +178,9 @@ describe('PortfolioCalculator', () => { totalFeesWithCurrencyEffect: new Big('0'), totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('320.43'), - totalInvestmentWithCurrencyEffect: new Big('318.542667299999967957') + totalInvestmentWithCurrencyEffect: new Big('318.542667299999967957'), + totalLiabilitiesWithCurrencyEffect: new Big('0'), + totalValuablesWithCurrencyEffect: new Big('0') }); expect(investments).toEqual([ diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts index b689a0c30..83f99e3cb 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts @@ -125,7 +125,9 @@ describe('PortfolioCalculator', () => { totalFeesWithCurrencyEffect: new Big('49'), totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('0'), - totalInvestmentWithCurrencyEffect: new Big('0') + totalInvestmentWithCurrencyEffect: new Big('0'), + totalLiabilitiesWithCurrencyEffect: new Big('0'), + totalValuablesWithCurrencyEffect: new Big('0') }); }); }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts index 911167f7a..0642b28ed 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts @@ -157,7 +157,9 @@ describe('PortfolioCalculator', () => { totalFeesWithCurrencyEffect: new Big('1'), totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('89.12'), - totalInvestmentWithCurrencyEffect: new Big('82.329056') + totalInvestmentWithCurrencyEffect: new Big('82.329056'), + totalLiabilitiesWithCurrencyEffect: new Big('0'), + totalValuablesWithCurrencyEffect: new Big('0') }); expect(investments).toEqual([ diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-item.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-item.spec.ts new file mode 100644 index 000000000..b8ef6954e --- /dev/null +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-item.spec.ts @@ -0,0 +1,134 @@ +import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PortfolioCalculatorFactory, + PerformanceCalculationType +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; +import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; +import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; +import { parseDate } from '@ghostfolio/common/helper'; + +import { Big } from 'big.js'; + +jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + CurrentRateService: jest.fn().mockImplementation(() => { + return CurrentRateServiceMock; + }) + }; +}); + +describe('PortfolioCalculator', () => { + let currentRateService: CurrentRateService; + let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; + + beforeEach(() => { + currentRateService = new CurrentRateService(null, null, null, null); + + exchangeRateDataService = new ExchangeRateDataService( + null, + null, + null, + null + ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); + }); + + describe('compute portfolio snapshot', () => { + it.only('with item activity', async () => { + const spy = jest + .spyOn(Date, 'now') + .mockImplementation(() => parseDate('2022-01-31').getTime()); + + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2022-01-01'), + fee: 0, + quantity: 1, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'USD', + dataSource: 'MANUAL', + name: 'Penthouse Apartment', + symbol: 'dac95060-d4f2-4653-a253-2c45e6fb5cde' + }, + type: 'ITEM', + unitPrice: 500000 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, + currency: 'USD' + }); + + const portfolioSnapshot = await portfolioCalculator.computeSnapshot( + parseDate('2022-01-01') + ); + + spy.mockRestore(); + + expect(portfolioSnapshot).toEqual({ + currentValueInBaseCurrency: new Big('0'), + errors: [], + grossPerformance: new Big('0'), + grossPerformancePercentage: new Big('0'), + grossPerformancePercentageWithCurrencyEffect: new Big('0'), + grossPerformanceWithCurrencyEffect: new Big('0'), + hasErrors: true, + netPerformance: new Big('0'), + netPerformancePercentage: new Big('0'), + netPerformancePercentageWithCurrencyEffect: new Big('0'), + netPerformanceWithCurrencyEffect: new Big('0'), + positions: [ + { + averagePrice: new Big('500000'), + currency: 'USD', + dataSource: 'MANUAL', + dividend: new Big('0'), + dividendInBaseCurrency: new Big('0'), + fee: new Big('0'), + firstBuyDate: '2022-01-01', + grossPerformance: null, + grossPerformancePercentage: null, + grossPerformancePercentageWithCurrencyEffect: null, + grossPerformanceWithCurrencyEffect: null, + investment: new Big('0'), + investmentWithCurrencyEffect: new Big('0'), + marketPrice: null, + marketPriceInBaseCurrency: 500000, + netPerformance: null, + netPerformancePercentage: null, + netPerformancePercentageWithCurrencyEffect: null, + netPerformanceWithCurrencyEffect: null, + quantity: new Big('0'), + symbol: 'dac95060-d4f2-4653-a253-2c45e6fb5cde', + tags: [], + timeWeightedInvestment: new Big('0'), + timeWeightedInvestmentWithCurrencyEffect: new Big('0'), + transactionCount: 1, + valueInBaseCurrency: new Big('0') + } + ], + totalFeesWithCurrencyEffect: new Big('0'), + totalInterestWithCurrencyEffect: new Big('0'), + totalInvestment: new Big('0'), + totalInvestmentWithCurrencyEffect: new Big('0'), + totalLiabilitiesWithCurrencyEffect: new Big('0'), + totalValuablesWithCurrencyEffect: new Big('0') + }); + }); + }); +}); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts new file mode 100644 index 000000000..9ef369c8f --- /dev/null +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts @@ -0,0 +1,134 @@ +import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { + activityDummyData, + symbolProfileDummyData +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; +import { + PortfolioCalculatorFactory, + PerformanceCalculationType +} from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; +import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; +import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; +import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; +import { parseDate } from '@ghostfolio/common/helper'; + +import { Big } from 'big.js'; + +jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + CurrentRateService: jest.fn().mockImplementation(() => { + return CurrentRateServiceMock; + }) + }; +}); + +describe('PortfolioCalculator', () => { + let currentRateService: CurrentRateService; + let exchangeRateDataService: ExchangeRateDataService; + let factory: PortfolioCalculatorFactory; + + beforeEach(() => { + currentRateService = new CurrentRateService(null, null, null, null); + + exchangeRateDataService = new ExchangeRateDataService( + null, + null, + null, + null + ); + + factory = new PortfolioCalculatorFactory( + currentRateService, + exchangeRateDataService + ); + }); + + describe('compute portfolio snapshot', () => { + it.only('with liability activity', async () => { + const spy = jest + .spyOn(Date, 'now') + .mockImplementation(() => parseDate('2022-01-31').getTime()); + + const activities: Activity[] = [ + { + ...activityDummyData, + date: new Date('2022-01-01'), + fee: 0, + quantity: 1, + SymbolProfile: { + ...symbolProfileDummyData, + currency: 'USD', + dataSource: 'MANUAL', + name: 'Loan', + symbol: '55196015-1365-4560-aa60-8751ae6d18f8' + }, + type: 'LIABILITY', + unitPrice: 3000 + } + ]; + + const portfolioCalculator = factory.createCalculator({ + activities, + calculationType: PerformanceCalculationType.TWR, + currency: 'USD' + }); + + const portfolioSnapshot = await portfolioCalculator.computeSnapshot( + parseDate('2022-01-01') + ); + + spy.mockRestore(); + + expect(portfolioSnapshot).toEqual({ + currentValueInBaseCurrency: new Big('0'), + errors: [], + grossPerformance: new Big('0'), + grossPerformancePercentage: new Big('0'), + grossPerformancePercentageWithCurrencyEffect: new Big('0'), + grossPerformanceWithCurrencyEffect: new Big('0'), + hasErrors: true, + netPerformance: new Big('0'), + netPerformancePercentage: new Big('0'), + netPerformancePercentageWithCurrencyEffect: new Big('0'), + netPerformanceWithCurrencyEffect: new Big('0'), + positions: [ + { + averagePrice: new Big('3000'), + currency: 'USD', + dataSource: 'MANUAL', + dividend: new Big('0'), + dividendInBaseCurrency: new Big('0'), + fee: new Big('0'), + firstBuyDate: '2022-01-01', + grossPerformance: null, + grossPerformancePercentage: null, + grossPerformancePercentageWithCurrencyEffect: null, + grossPerformanceWithCurrencyEffect: null, + investment: new Big('0'), + investmentWithCurrencyEffect: new Big('0'), + marketPrice: null, + marketPriceInBaseCurrency: 3000, + netPerformance: null, + netPerformancePercentage: null, + netPerformancePercentageWithCurrencyEffect: null, + netPerformanceWithCurrencyEffect: null, + quantity: new Big('0'), + symbol: '55196015-1365-4560-aa60-8751ae6d18f8', + tags: [], + timeWeightedInvestment: new Big('0'), + timeWeightedInvestmentWithCurrencyEffect: new Big('0'), + transactionCount: 1, + valueInBaseCurrency: new Big('0') + } + ], + totalFeesWithCurrencyEffect: new Big('0'), + totalInterestWithCurrencyEffect: new Big('0'), + totalInvestment: new Big('0'), + totalInvestmentWithCurrencyEffect: new Big('0'), + totalLiabilitiesWithCurrencyEffect: new Big('0'), + totalValuablesWithCurrencyEffect: new Big('0') + }); + }); + }); +}); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts index 6dc489c5d..e50ce4194 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts @@ -133,7 +133,9 @@ describe('PortfolioCalculator', () => { totalFeesWithCurrencyEffect: new Big('19'), totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('298.58'), - totalInvestmentWithCurrencyEffect: new Big('298.58') + totalInvestmentWithCurrencyEffect: new Big('298.58'), + totalLiabilitiesWithCurrencyEffect: new Big('0'), + totalValuablesWithCurrencyEffect: new Big('0') }); }); }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts index ece39c87b..1d69abfbf 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts @@ -83,7 +83,9 @@ describe('PortfolioCalculator', () => { totalFeesWithCurrencyEffect: new Big('0'), totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big(0), - totalInvestmentWithCurrencyEffect: new Big(0) + totalInvestmentWithCurrencyEffect: new Big(0), + totalLiabilitiesWithCurrencyEffect: new Big('0'), + totalValuablesWithCurrencyEffect: new Big('0') }); expect(investments).toEqual([]); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts index a3c12829a..3d63f1a5d 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts @@ -161,7 +161,9 @@ describe('PortfolioCalculator', () => { totalFeesWithCurrencyEffect: new Big('4.25'), totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('75.80'), - totalInvestmentWithCurrencyEffect: new Big('75.80') + totalInvestmentWithCurrencyEffect: new Big('75.80'), + totalLiabilitiesWithCurrencyEffect: new Big('0'), + totalValuablesWithCurrencyEffect: new Big('0') }); expect(investments).toEqual([ diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts index f1bf56f11..6f0b03800 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts @@ -185,7 +185,9 @@ describe('PortfolioCalculator', () => { totalFeesWithCurrencyEffect: new Big('0'), totalInterestWithCurrencyEffect: new Big('0'), totalInvestment: new Big('0'), - totalInvestmentWithCurrencyEffect: new Big('0') + totalInvestmentWithCurrencyEffect: new Big('0'), + totalLiabilitiesWithCurrencyEffect: new Big('0'), + totalValuablesWithCurrencyEffect: new Big('0') }); expect(investments).toEqual([ diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index b9b7fd900..7dcef89cb 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -109,6 +109,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { hasErrors, netPerformance, netPerformanceWithCurrencyEffect, + positions, totalFeesWithCurrencyEffect, totalInterestWithCurrencyEffect, totalInvestment, @@ -131,7 +132,8 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { : grossPerformanceWithCurrencyEffect.div( totalTimeWeightedInvestmentWithCurrencyEffect ), - positions + totalLiabilitiesWithCurrencyEffect: new Big(0), + totalValuablesWithCurrencyEffect: new Big(0) }; } @@ -194,8 +196,12 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { let totalInvestmentFromBuyTransactions = new Big(0); let totalInvestmentFromBuyTransactionsWithCurrencyEffect = new Big(0); let totalInvestmentWithCurrencyEffect = new Big(0); + let totalLiabilities = new Big(0); + let totalLiabilitiesInBaseCurrency = new Big(0); let totalQuantityFromBuyTransactions = new Big(0); let totalUnits = new Big(0); + let totalValuables = new Big(0); + let totalValuablesInBaseCurrency = new Big(0); let valueAtStartDate: Big; let valueAtStartDateWithCurrencyEffect: Big; @@ -236,7 +242,11 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { totalInterest: new Big(0), totalInterestInBaseCurrency: new Big(0), totalInvestment: new Big(0), - totalInvestmentWithCurrencyEffect: new Big(0) + totalInvestmentWithCurrencyEffect: new Big(0), + totalLiabilities: new Big(0), + totalLiabilitiesInBaseCurrency: new Big(0), + totalValuables: new Big(0), + totalValuablesInBaseCurrency: new Big(0) }; } @@ -281,7 +291,11 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { totalInterest: new Big(0), totalInterestInBaseCurrency: new Big(0), totalInvestment: new Big(0), - totalInvestmentWithCurrencyEffect: new Big(0) + totalInvestmentWithCurrencyEffect: new Big(0), + totalLiabilities: new Big(0), + totalLiabilitiesInBaseCurrency: new Big(0), + totalValuables: new Big(0), + totalValuablesInBaseCurrency: new Big(0) }; } @@ -536,6 +550,20 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { totalInterestInBaseCurrency = totalInterestInBaseCurrency.plus( interest.mul(exchangeRateAtOrderDate ?? 1) ); + } else if (order.type === 'ITEM') { + const valuables = order.quantity.mul(order.unitPrice); + + totalValuables = totalValuables.plus(valuables); + totalValuablesInBaseCurrency = totalValuablesInBaseCurrency.plus( + valuables.mul(exchangeRateAtOrderDate ?? 1) + ); + } else if (order.type === 'LIABILITY') { + const liabilities = order.quantity.mul(order.unitPrice); + + totalLiabilities = totalLiabilities.plus(liabilities); + totalLiabilitiesInBaseCurrency = totalLiabilitiesInBaseCurrency.plus( + liabilities.mul(exchangeRateAtOrderDate ?? 1) + ); } const valueOfInvestment = totalUnits.mul(order.unitPriceInBaseCurrency); @@ -853,6 +881,10 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { totalInterestInBaseCurrency, totalInvestment, totalInvestmentWithCurrencyEffect, + totalLiabilities, + totalLiabilitiesInBaseCurrency, + totalValuables, + totalValuablesInBaseCurrency, grossPerformance: totalGrossPerformance, grossPerformanceWithCurrencyEffect: totalGrossPerformanceWithCurrencyEffect, diff --git a/apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts b/apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts index b8cc904fa..d89734987 100644 --- a/apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts @@ -19,4 +19,6 @@ export interface PortfolioSnapshot extends ResponseError { totalInterestWithCurrencyEffect: Big; totalInvestment: Big; totalInvestmentWithCurrencyEffect: Big; + totalLiabilitiesWithCurrencyEffect: Big; + totalValuablesWithCurrencyEffect: Big; } diff --git a/apps/api/src/app/portfolio/interfaces/transaction-point.interface.ts b/apps/api/src/app/portfolio/interfaces/transaction-point.interface.ts index 2f5218405..fcbea81ca 100644 --- a/apps/api/src/app/portfolio/interfaces/transaction-point.interface.ts +++ b/apps/api/src/app/portfolio/interfaces/transaction-point.interface.ts @@ -7,4 +7,6 @@ export interface TransactionPoint { fees: Big; interest: Big; items: TransactionPointSymbol[]; + liabilities: Big; + valuables: Big; } diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 7ee92e91c..56c0a231c 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -78,10 +78,8 @@ export class PortfolioController { @Query('assetClasses') filterByAssetClasses?: string, @Query('range') dateRange: DateRange = 'max', @Query('tags') filterByTags?: string, - @Query('withLiabilities') withLiabilitiesParam = 'false', @Query('withMarkets') withMarketsParam = 'false' ): Promise { - const withLiabilities = withLiabilitiesParam === 'true'; const withMarkets = withMarketsParam === 'true'; let hasDetails = true; @@ -107,8 +105,6 @@ export class PortfolioController { dateRange, filters, impersonationId, - // TODO - // withLiabilities, withMarkets, userId: this.request.user.id, withSummary: true diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 8714a15ec..95a68eaae 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -60,7 +60,6 @@ import { Prisma } from '@prisma/client'; import { Big } from 'big.js'; -import { isUUID } from 'class-validator'; import { differenceInDays, format, @@ -324,7 +323,6 @@ export class PortfolioService { impersonationId, userId, withExcludedAccounts = false, - withLiabilities = false, withMarkets = false, withSummary = false }: { @@ -333,7 +331,6 @@ export class PortfolioService { impersonationId: string; userId: string; withExcludedAccounts?: boolean; - withLiabilities?: boolean; withMarkets?: boolean; withSummary?: boolean; }): Promise { @@ -1623,35 +1620,10 @@ export class PortfolioService { const interest = await portfolioCalculator.getInterestInBaseCurrency(); - // TODO: Move to portfolio calculator - const items = getSum( - Object.keys(holdings) - .filter((symbol) => { - return ( - isUUID(symbol) && - holdings[symbol].dataSource === 'MANUAL' && - holdings[symbol].valueInBaseCurrency > 0 - ); - }) - .map((symbol) => { - return new Big(holdings[symbol].valueInBaseCurrency).abs(); - }) - ).toNumber(); - - // TODO: Move to portfolio calculator - const liabilities = getSum( - Object.keys(holdings) - .filter((symbol) => { - return ( - isUUID(symbol) && - holdings[symbol].dataSource === 'MANUAL' && - holdings[symbol].valueInBaseCurrency < 0 - ); - }) - .map((symbol) => { - return new Big(holdings[symbol].valueInBaseCurrency).abs(); - }) - ).toNumber(); + const liabilities = + await portfolioCalculator.getLiabilitiesInBaseCurrency(); + + const valuables = await portfolioCalculator.getValuablesInBaseCurrency(); const totalBuy = this.getSumOfActivityType({ userCurrency, @@ -1701,7 +1673,7 @@ export class PortfolioService { const netWorth = new Big(balanceInBaseCurrency) .plus(performanceInformation.performance.currentValue) - .plus(items) + .plus(valuables) .plus(excludedAccountsAndActivities) .minus(liabilities) .toNumber(); @@ -1730,8 +1702,6 @@ export class PortfolioService { cash, excludedAccountsAndActivities, firstOrderDate, - items, - liabilities, totalBuy, totalSell, committedFunds: committedFunds.toNumber(), @@ -1752,6 +1722,8 @@ export class PortfolioService { .minus(emergencyFundPositionsValueInBaseCurrency) .toNumber(), interest: interest.toNumber(), + items: valuables.toNumber(), + liabilities: liabilities.toNumber(), ordersCount: activities.filter(({ type }) => { return type === 'BUY' || type === 'SELL'; }).length, diff --git a/apps/api/src/helper/portfolio.helper.ts b/apps/api/src/helper/portfolio.helper.ts index f762b2ad5..21b111395 100644 --- a/apps/api/src/helper/portfolio.helper.ts +++ b/apps/api/src/helper/portfolio.helper.ts @@ -18,10 +18,8 @@ export function getFactor(activityType: ActivityType) { switch (activityType) { case 'BUY': - case 'ITEM': factor = 1; break; - case 'LIABILITY': case 'SELL': factor = -1; break; diff --git a/apps/client/src/app/components/home-summary/home-summary.component.ts b/apps/client/src/app/components/home-summary/home-summary.component.ts index bb68a4627..b67b67ce5 100644 --- a/apps/client/src/app/components/home-summary/home-summary.component.ts +++ b/apps/client/src/app/components/home-summary/home-summary.component.ts @@ -102,7 +102,7 @@ export class HomeSummaryComponent implements OnDestroy, OnInit { this.isLoading = true; this.dataService - .fetchPortfolioDetails({ withLiabilities: true }) + .fetchPortfolioDetails() .pipe(takeUntil(this.unsubscribeSubject)) .subscribe(({ summary }) => { this.summary = summary; diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts index aeeb2f07b..8a3f7d293 100644 --- a/apps/client/src/app/services/data.service.ts +++ b/apps/client/src/app/services/data.service.ts @@ -411,19 +411,13 @@ export class DataService { public fetchPortfolioDetails({ filters, - withLiabilities = false, withMarkets = false }: { filters?: Filter[]; - withLiabilities?: boolean; withMarkets?: boolean; } = {}): Observable { let params = this.buildFiltersAsQueryParams({ filters }); - if (withLiabilities) { - params = params.append('withLiabilities', withLiabilities); - } - if (withMarkets) { params = params.append('withMarkets', withMarkets); } diff --git a/libs/common/src/lib/interfaces/symbol-metrics.interface.ts b/libs/common/src/lib/interfaces/symbol-metrics.interface.ts index 99a1b3467..57eed9212 100644 --- a/libs/common/src/lib/interfaces/symbol-metrics.interface.ts +++ b/libs/common/src/lib/interfaces/symbol-metrics.interface.ts @@ -46,4 +46,8 @@ export interface SymbolMetrics { totalInterestInBaseCurrency: Big; totalInvestment: Big; totalInvestmentWithCurrencyEffect: Big; + totalLiabilities: Big; + totalLiabilitiesInBaseCurrency: Big; + totalValuables: Big; + totalValuablesInBaseCurrency: Big; } From 9241c04d5a2099665b925b735d3319307b429c52 Mon Sep 17 00:00:00 2001 From: Fedron <40535546+Fedron@users.noreply.github.com> Date: Sun, 14 Apr 2024 18:52:41 +0100 Subject: [PATCH 120/203] Feature/add form validation against DTO for activity and account (#3230) * Add form validation against DTO for activity and account * Update changelog --- CHANGELOG.md | 5 +++ ...eate-or-update-account-dialog.component.ts | 31 +++++++++++---- ...ate-or-update-activity-dialog.component.ts | 35 +++++++++++++---- apps/client/src/app/util/form.util.ts | 38 +++++++++++++++++++ 4 files changed, 94 insertions(+), 15 deletions(-) create mode 100644 apps/client/src/app/util/form.util.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fec3111c..8e26c1369 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Added a form validation against the DTO in the create or update account dialog +- Added a form validation against the DTO in the create or update activity dialog + ### Changed - Moved the dividend calculations into the portfolio calculator diff --git a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts index c97bbf113..4e3ef335e 100644 --- a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts +++ b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts @@ -1,6 +1,7 @@ import { CreateAccountDto } from '@ghostfolio/api/app/account/create-account.dto'; import { UpdateAccountDto } from '@ghostfolio/api/app/account/update-account.dto'; import { DataService } from '@ghostfolio/client/services/data.service'; +import { validateObjectForForm } from '@ghostfolio/client/util/form.util'; import { Currency } from '@ghostfolio/common/interfaces'; import { @@ -102,7 +103,7 @@ export class CreateOrUpdateAccountDialog implements OnDestroy { this.dialogRef.close(); } - public onSubmit() { + public async onSubmit() { const account: CreateAccountDto | UpdateAccountDto = { balance: this.accountForm.controls['balance'].value, comment: this.accountForm.controls['comment'].value, @@ -113,13 +114,29 @@ export class CreateOrUpdateAccountDialog implements OnDestroy { platformId: this.accountForm.controls['platformId'].value?.id ?? null }; - if (this.data.account.id) { - (account as UpdateAccountDto).id = this.data.account.id; - } else { - delete (account as CreateAccountDto).id; - } + try { + if (this.data.account.id) { + (account as UpdateAccountDto).id = this.data.account.id; + + await validateObjectForForm({ + classDto: UpdateAccountDto, + form: this.accountForm, + object: account + }); + } else { + delete (account as CreateAccountDto).id; + + await validateObjectForForm({ + classDto: CreateAccountDto, + form: this.accountForm, + object: account + }); + } - this.dialogRef.close({ account }); + this.dialogRef.close({ account }); + } catch (error) { + console.error(error); + } } public ngOnDestroy() { diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts index 21a2ca920..1196de58c 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts @@ -1,6 +1,7 @@ import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto'; import { UpdateOrderDto } from '@ghostfolio/api/app/order/update-order.dto'; import { DataService } from '@ghostfolio/client/services/data.service'; +import { validateObjectForForm } from '@ghostfolio/client/util/form.util'; import { getDateFormatString } from '@ghostfolio/common/helper'; import { translate } from '@ghostfolio/ui/i18n'; @@ -451,7 +452,7 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { ); } - public onSubmit() { + public async onSubmit() { const activity: CreateOrderDto | UpdateOrderDto = { accountId: this.activityForm.controls['accountId'].value, assetClass: this.activityForm.controls['assetClass'].value, @@ -474,14 +475,32 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { unitPrice: this.activityForm.controls['unitPrice'].value }; - if (this.data.activity.id) { - (activity as UpdateOrderDto).id = this.data.activity.id; - } else { - (activity as CreateOrderDto).updateAccountBalance = - this.activityForm.controls['updateAccountBalance'].value; - } + try { + if (this.data.activity.id) { + (activity as UpdateOrderDto).id = this.data.activity.id; - this.dialogRef.close({ activity }); + await validateObjectForForm({ + classDto: UpdateOrderDto, + form: this.activityForm, + ignoreFields: ['dataSource', 'date'], + object: activity as UpdateOrderDto + }); + } else { + (activity as CreateOrderDto).updateAccountBalance = + this.activityForm.controls['updateAccountBalance'].value; + + await validateObjectForForm({ + classDto: CreateOrderDto, + form: this.activityForm, + ignoreFields: ['dataSource', 'date'], + object: activity + }); + } + + this.dialogRef.close({ activity }); + } catch (error) { + console.error(error); + } } public ngOnDestroy() { diff --git a/apps/client/src/app/util/form.util.ts b/apps/client/src/app/util/form.util.ts new file mode 100644 index 000000000..d11490c7e --- /dev/null +++ b/apps/client/src/app/util/form.util.ts @@ -0,0 +1,38 @@ +import { FormGroup } from '@angular/forms'; +import { plainToInstance } from 'class-transformer'; +import { validate } from 'class-validator'; + +export async function validateObjectForForm({ + classDto, + form, + ignoreFields = [], + object +}: { + classDto: { new (): T }; + form: FormGroup; + ignoreFields?: string[]; + object: T; +}): Promise { + const objectInstance = plainToInstance(classDto, object); + const errors = await validate(objectInstance as object); + + const nonIgnoredErrors = errors.filter(({ property }) => { + return !ignoreFields.includes(property); + }); + + if (nonIgnoredErrors.length === 0) { + return Promise.resolve(); + } + + for (const { constraints, property } of nonIgnoredErrors) { + const formControl = form.get(property); + + if (formControl) { + formControl.setErrors({ + validationError: Object.values(constraints)[0] + }); + } + } + + return Promise.reject(nonIgnoredErrors); +} From 0245e836e0f9b0b45d4d77014186f6670e0b8375 Mon Sep 17 00:00:00 2001 From: Daniel Devaud Date: Mon, 15 Apr 2024 16:42:42 +0200 Subject: [PATCH 121/203] Fixes --- .../calculator/twr/portfolio-calculator.ts | 14 +++ .../src/app/portfolio/portfolio.controller.ts | 6 +- .../src/app/portfolio/portfolio.service.ts | 102 +++--------------- 3 files changed, 29 insertions(+), 93 deletions(-) diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index 7dcef89cb..e71b8be28 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -216,6 +216,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { return { currentValues: {}, currentValuesWithCurrencyEffect: {}, + unitPrices: {}, feesWithCurrencyEffect: new Big(0), grossPerformance: new Big(0), grossPerformancePercentage: new Big(0), @@ -232,6 +233,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { netPerformancePercentageWithCurrencyEffect: new Big(0), netPerformanceValues: {}, netPerformanceValuesWithCurrencyEffect: {}, + netPerformanceValuesPercentage: {}, netPerformanceWithCurrencyEffect: new Big(0), timeWeightedInvestment: new Big(0), timeWeightedInvestmentValues: {}, @@ -265,6 +267,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { return { currentValues: {}, currentValuesWithCurrencyEffect: {}, + unitPrices: {}, feesWithCurrencyEffect: new Big(0), grossPerformance: new Big(0), grossPerformancePercentage: new Big(0), @@ -281,6 +284,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { netPerformancePercentageWithCurrencyEffect: new Big(0), netPerformanceValues: {}, netPerformanceValuesWithCurrencyEffect: {}, + netPerformanceValuesPercentage: {}, netPerformanceWithCurrencyEffect: new Big(0), timeWeightedInvestment: new Big(0), timeWeightedInvestmentValues: {}, @@ -858,9 +862,18 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { ); } + let unitPrices = Object.keys(marketSymbolMap) + .map((date) => { + return { [date]: marketSymbolMap[date][symbol] }; + }) + .reduce((map, u) => { + return { ...u, ...map }; + }, {}); + return { currentValues, currentValuesWithCurrencyEffect, + unitPrices, feesWithCurrencyEffect, grossPerformancePercentage, grossPerformancePercentageWithCurrencyEffect, @@ -873,6 +886,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { netPerformancePercentageWithCurrencyEffect, netPerformanceValues, netPerformanceValuesWithCurrencyEffect, + netPerformanceValuesPercentage: {}, timeWeightedInvestmentValues, timeWeightedInvestmentValuesWithCurrencyEffect, totalDividend, diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index a505c7362..b4f784930 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -79,7 +79,7 @@ export class PortfolioController { @Query('assetClasses') filterByAssetClasses?: string, @Query('range') dateRange: DateRange = 'max', @Query('tags') filterByTags?: string, - @Query('isAllocation') isAllocation: boolean = false + @Query('isAllocation') isAllocation: boolean = false, @Query('withMarkets') withMarketsParam = 'false' ): Promise { const withMarkets = withMarketsParam === 'true'; @@ -428,10 +428,7 @@ export class PortfolioController { @Query('withExcludedAccounts') withExcludedAccounts = false, @Query('timeWeightedPerformance') calculateTimeWeightedPerformance = false, @Query('withItems') withItems = false - @Query('withExcludedAccounts') withExcludedAccountsParam = 'false' ): Promise { - const withExcludedAccounts = withExcludedAccountsParam === 'true'; - const hasReadRestrictedAccessPermission = this.userService.hasReadRestrictedAccessPermission({ impersonationId, @@ -449,7 +446,6 @@ export class PortfolioController { filters, impersonationId, withExcludedAccounts, - withItems, userId: this.request.user.id, calculateTimeWeightedPerformance }); diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 316986475..1432e7df3 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -511,7 +511,6 @@ export class PortfolioService { valueInBaseCurrency: valueInBaseCurrency.toNumber() }; } - } if (filters?.length === 0 || isFilteredByAccount || isFilteredByCash) { const cashPositions = await this.getCashPositions({ @@ -524,7 +523,6 @@ export class PortfolioService { holdings[symbol] = cashPositions[symbol]; } } - } const { accounts, platforms } = await this.getValueOfAccountsAndPlatforms({ activities, @@ -698,6 +696,7 @@ export class PortfolioService { accounts: [], averagePrice: undefined, dataProviderInfo: undefined, + stakeRewards: undefined, dividendInBaseCurrency: undefined, dividendYieldPercent: undefined, dividendYieldPercentWithCurrencyEffect: undefined, @@ -885,6 +884,7 @@ export class PortfolioService { transactionCount, averagePrice: averagePrice.toNumber(), dataProviderInfo: portfolioCalculator.getDataProviderInfos()?.[0], + stakeRewards: stakeRewards.toNumber(), dividendInBaseCurrency: dividendInBaseCurrency.toNumber(), dividendYieldPercent: dividendYieldPercent.toNumber(), dividendYieldPercentWithCurrencyEffect: @@ -963,6 +963,7 @@ export class PortfolioService { accounts: [], averagePrice: 0, dataProviderInfo: undefined, + stakeRewards: 0, dividendInBaseCurrency: 0, dividendYieldPercent: 0, dividendYieldPercentWithCurrencyEffect: 0, @@ -1135,13 +1136,15 @@ export class PortfolioService { filters, impersonationId, userId, - withExcludedAccounts = false + withExcludedAccounts = false, + calculateTimeWeightedPerformance = false }: { dateRange?: DateRange; filters?: Filter[]; impersonationId: string; userId: string; withExcludedAccounts?: boolean; + calculateTimeWeightedPerformance?: boolean; }): Promise { userId = await this.getUserId(impersonationId, userId); const user = await this.userService.user({ id: userId }); @@ -1676,42 +1679,6 @@ export class PortfolioService { return { currentStreak, longestStreak }; } - @LogPerformance - private async getNetWorth( - impersonationId: string, - userId: string, - userCurrency: string - ) { - userId = await this.getUserId(impersonationId, userId); - - const { orders, portfolioOrders, transactionPoints } = - await this.getTransactionPoints({ - userId, - withExcludedAccounts: true - }); - - const portfolioCalculator = new PortfolioCalculator({ - currency: userCurrency, - currentRateService: this.currentRateService, - exchangeRateDataService: this.exchangeRateDataService, - orders: portfolioOrders - }); - - const portfolioStart = parseDate( - transactionPoints[0]?.date ?? format(new Date(), DATE_FORMAT) - ); - - portfolioCalculator.setTransactionPoints(transactionPoints); - - const { currentValue } = await portfolioCalculator.getCurrentPositions( - portfolioStart, - new Date(Date.now()), - false - ); - - return currentValue; - } - @LogPerformance private async getSummary({ balanceInBaseCurrency, @@ -1761,63 +1728,22 @@ export class PortfolioService { withExcludedAccounts: true }); const excludedActivities: Activity[] = []; - let dividend = 0; - let fees = 0; - let items = 0; - let interest = 0; + const nonExcludedActivities: Activity[] = []; - let liabilities = 0; + for (const activity of activities) { + if (activity.Account?.isExcluded) { + excludedActivities.push(activity); + } else { + nonExcludedActivities.push(activity); + } + } - let totalBuy = 0; - let totalSell = 0; - let activitiesUsed: Activity[] = []; - let ordersCount = 0; let excludedAccountsAndActivities = 0; - const firstOrderDate = activities[0]?.date; performanceInformation = await this.getPerformance({ impersonationId, userId }); - for (let order of activities) { - if (order.Account?.isExcluded ?? false) { - excludedActivities.push(order); - } else { - activitiesUsed.push(order); - fees += this.exchangeRateDataService.toCurrency( - order.fee, - order.SymbolProfile.currency, - userCurrency - ); - let amount = this.exchangeRateDataService.toCurrency( - new Big(order.quantity).mul(order.unitPrice).toNumber(), - order.SymbolProfile.currency, - userCurrency - ); - switch (order.type) { - case 'DIVIDEND': - dividend += amount; - break; - case 'ITEM': - items += amount; - break; - case 'SELL': - totalSell += amount; - ordersCount++; - break; - case 'BUY': - totalBuy += amount; - ordersCount++; - break; - case 'LIABILITY': - liabilities += amount; - break; - case 'INTEREST': - interest += amount; - break; - } - } - } const dividendInBaseCurrency = await portfolioCalculator.getDividendInBaseCurrency(); From 26a7912c852fe3a9312085b34e99175bf4dd2d53 Mon Sep 17 00:00:00 2001 From: Daniel Devaud Date: Mon, 15 Apr 2024 16:54:28 +0200 Subject: [PATCH 122/203] Just some fixes --- .../asset-profile-dialog/asset-profile-dialog.component.ts | 1 - .../position-detail-dialog.component.ts | 6 +++++- .../app/pages/portfolio/analysis/analysis-page.component.ts | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts index 3f4dac584..194bbb37e 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts @@ -320,7 +320,6 @@ export class AssetProfileDialog implements OnDestroy, OnInit { currency: (( (this.assetProfileForm.controls['currency'].value) ))?.value, - name: this.assetProfileForm.controls['name'].value, url: this.assetProfileForm.controls['url'].value }; diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts index 41d505b2b..c4d908bf3 100644 --- a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts +++ b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts @@ -110,7 +110,11 @@ export class PositionDetailDialog implements OnDestroy, OnInit { SymbolProfile, tags, transactionCount, - value + value, + dividendYieldPercentWithCurrencyEffect, + feeInBaseCurrency, + firstBuyDate, + historicalData }) => { this.accounts = accounts; this.activities = orders; diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts index 7e7e3a10b..c0e11fc5a 100644 --- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts +++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -20,7 +20,7 @@ import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; import { DataSource, SymbolProfile } from '@prisma/client'; -import Big from 'big.js'; +import { Big } from 'big.js'; import { differenceInDays } from 'date-fns'; import { isNumber, sortBy } from 'lodash'; import { DeviceDetectorService } from 'ngx-device-detector'; From ff91ed21dfbbd2564386e105562eb74eccdab549 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 15 Apr 2024 19:25:46 +0200 Subject: [PATCH 123/203] Upgrade @types/lodash to version 4.17.0 (#3227) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 35ee3b1a4..146c99274 100644 --- a/package.json +++ b/package.json @@ -171,7 +171,7 @@ "@types/color": "3.0.3", "@types/google-spreadsheet": "3.1.5", "@types/jest": "29.4.4", - "@types/lodash": "4.14.195", + "@types/lodash": "4.17.0", "@types/node": "18.16.9", "@types/papaparse": "5.3.7", "@types/passport-google-oauth20": "2.0.11", diff --git a/yarn.lock b/yarn.lock index 8cbfbccd0..b821e4c08 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7314,10 +7314,10 @@ dependencies: "@types/node" "*" -"@types/lodash@4.14.195": - version "4.14.195" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.195.tgz#bafc975b252eb6cea78882ce8a7b6bf22a6de632" - integrity sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg== +"@types/lodash@4.17.0": + version "4.17.0" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.0.tgz#d774355e41f372d5350a4d0714abb48194a489c3" + integrity sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA== "@types/lodash@^4.14.167": version "4.14.200" From 87ab9a65ff2c607c2863caa999c85e6332d31e72 Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 17 Apr 2024 13:48:15 +0200 Subject: [PATCH 124/203] Fix asset class overwrite --- apps/api/src/app/admin/admin.controller.ts | 49 ++++--------------- .../asset-profile-dialog.component.ts | 5 +- 2 files changed, 14 insertions(+), 40 deletions(-) diff --git a/apps/api/src/app/admin/admin.controller.ts b/apps/api/src/app/admin/admin.controller.ts index da6292363..610a0171f 100644 --- a/apps/api/src/app/admin/admin.controller.ts +++ b/apps/api/src/app/admin/admin.controller.ts @@ -327,45 +327,16 @@ export class AdminController { @Param('dataSource') dataSource: DataSource, @Param('symbol') symbol: string ): Promise { - if (dataSource === 'MANUAL') { - await this.adminService.patchAssetProfileData({ - dataSource, - symbol, - tags: { - set: [] - } - }); - - return this.adminService.patchAssetProfileData({ - ...assetProfileData, - dataSource, - symbol, - tags: { - connect: assetProfileData.tags?.map(({ id }) => { - return { id }; - }) - } - }); - } else { - await this.adminService.patchAssetProfileData({ - dataSource, - symbol, - tags: { - set: [] - } - }); - - return this.adminService.patchAssetProfileData({ - ...assetProfileData, - dataSource, - symbol, - tags: { - connect: assetProfileData.tags?.map(({ id }) => { - return { id }; - }) - } - }); - } + return this.adminService.patchAssetProfileData({ + ...assetProfileData, + dataSource, + symbol, + tags: { + connect: assetProfileData.tags?.map(({ id }) => { + return { id }; + }) + } + }); } @HasPermission(permissions.accessAdminControl) diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts index 194bbb37e..bdd92bbfd 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts @@ -188,7 +188,7 @@ export class AssetProfileDialog implements OnDestroy, OnInit { ), sectors: JSON.stringify(this.assetProfile?.sectors ?? []), symbolMapping: JSON.stringify(this.assetProfile?.symbolMapping ?? {}), - url: this.assetProfile?.url ?? '' + url: this.assetProfile?.url }); this.assetProfileForm.markAsPristine(); @@ -323,6 +323,9 @@ export class AssetProfileDialog implements OnDestroy, OnInit { url: this.assetProfileForm.controls['url'].value }; + assetProfileData.url = + assetProfileData.url?.length > 0 ? assetProfileData.url : null; + this.adminService .patchAssetProfile({ ...assetProfileData, From 66d7d9e8f986a4045dfcd8e31fe11d1885084d35 Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 17 Apr 2024 15:10:24 +0200 Subject: [PATCH 125/203] Fix Filter deletion --- .../app/components/header/header.component.ts | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/apps/client/src/app/components/header/header.component.ts b/apps/client/src/app/components/header/header.component.ts index f342a1021..c7151a71f 100644 --- a/apps/client/src/app/components/header/header.component.ts +++ b/apps/client/src/app/components/header/header.component.ts @@ -169,15 +169,7 @@ export class HeaderComponent implements OnChanges { const userSetting: UpdateUserSettingDto = {}; for (const filter of filters) { - let filtersType: string; - - if (filter.type === 'ACCOUNT') { - filtersType = 'accounts'; - } else if (filter.type === 'ASSET_CLASS') { - filtersType = 'assetClasses'; - } else if (filter.type === 'TAG') { - filtersType = 'tags'; - } + let filtersType = this.getFilterType(filter.type); let userFilters = filters .filter((f) => f.type === filter.type && filter.id) @@ -187,6 +179,14 @@ export class HeaderComponent implements OnChanges { ? userFilters : null; } + ['ACCOUNT', 'ASSET_CLASS', 'TAG'] + .filter( + (fitlerType) => + !filters.some((f: Filter) => f.type.toString() === fitlerType) + ) + .forEach((filterType) => { + userSetting[`filters.${this.getFilterType(filterType)}`] = null; + }); this.dataService .putUserSetting(userSetting) @@ -269,4 +269,13 @@ export class HeaderComponent implements OnChanges { this.unsubscribeSubject.next(); this.unsubscribeSubject.complete(); } + private getFilterType(filterType: string) { + if (filterType === 'ACCOUNT') { + return 'accounts'; + } else if (filterType === 'ASSET_CLASS') { + return 'assetClasses'; + } else if (filterType === 'TAG') { + return 'tags'; + } + } } From 50f2f50dc23c4c09a234cd51696affcc89236056 Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 17 Apr 2024 15:42:12 +0200 Subject: [PATCH 126/203] Readded Stake Handling --- apps/api/src/app/import/import.service.ts | 7 ++++++- .../app/portfolio/calculator/portfolio-calculator.ts | 7 ++++++- .../portfolio/calculator/twr/portfolio-calculator.ts | 12 +++++++++++- apps/api/src/helper/portfolio.helper.ts | 1 + 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/apps/api/src/app/import/import.service.ts b/apps/api/src/app/import/import.service.ts index 26df9d069..f6f80ec56 100644 --- a/apps/api/src/app/import/import.service.ts +++ b/apps/api/src/app/import/import.service.ts @@ -604,7 +604,12 @@ export class ImportService { )?.[symbol] }; - if (type === 'BUY' || type === 'DIVIDEND' || type === 'SELL') { + if ( + type === 'BUY' || + type === 'DIVIDEND' || + type === 'SELL' || + type === 'STAKE' + ) { if (!assetProfile?.name) { throw new Error( `activities.${index}.symbol ("${symbol}") is not valid for the specified data source ("${dataSource}")` diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index 1d2eadfbf..47db8cba9 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -450,7 +450,12 @@ export abstract class PortfolioCalculator { await this.currentRateService.getValues({ dataGatheringItems, dateQuery: { - in: dates + in: [ + ...dates, + ...this.transactionPoints.map(({ date }) => + resetHours(parseDate(date)) + ) + ] } }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index e71b8be28..c443babc3 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -189,6 +189,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { } = {}; let totalDividend = new Big(0); + let totalStakeRewards = new Big(0); let totalDividendInBaseCurrency = new Big(0); let totalInterest = new Big(0); let totalInterestInBaseCurrency = new Big(0); @@ -421,6 +422,10 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { ); } + if (order.type === 'STAKE') { + order.unitPrice = marketSymbolMap[order.date]?.[symbol]; + } + if (order.unitPrice) { order.unitPriceInBaseCurrency = order.unitPrice.mul( currentExchangeRate ?? 1 @@ -568,6 +573,8 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { totalLiabilitiesInBaseCurrency = totalLiabilitiesInBaseCurrency.plus( liabilities.mul(exchangeRateAtOrderDate ?? 1) ); + } else if (order.type === 'STAKE') { + totalStakeRewards = totalStakeRewards.plus(order.quantity); } const valueOfInvestment = totalUnits.mul(order.unitPriceInBaseCurrency); @@ -647,7 +654,10 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { grossPerformanceWithCurrencyEffect; } - if (i > indexOfStartOrder && ['BUY', 'SELL'].includes(order.type)) { + if ( + i > indexOfStartOrder && + ['BUY', 'SELL', 'STAKE'].includes(order.type) + ) { // Only consider periods with an investment for the calculation of // the time weighted investment if (valueOfInvestmentBeforeTransaction.gt(0)) { diff --git a/apps/api/src/helper/portfolio.helper.ts b/apps/api/src/helper/portfolio.helper.ts index 21b111395..bd9c34a3d 100644 --- a/apps/api/src/helper/portfolio.helper.ts +++ b/apps/api/src/helper/portfolio.helper.ts @@ -18,6 +18,7 @@ export function getFactor(activityType: ActivityType) { switch (activityType) { case 'BUY': + case 'STAKE': factor = 1; break; case 'SELL': From e2e39d0ea70d49f7926a158fcaba6641c7d237af Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 17 Apr 2024 16:51:48 +0200 Subject: [PATCH 127/203] Added branch publish workflow --- .github/workflows/docker-image-branch.yml | 47 +++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .github/workflows/docker-image-branch.yml diff --git a/.github/workflows/docker-image-branch.yml b/.github/workflows/docker-image-branch.yml new file mode 100644 index 000000000..6775683ea --- /dev/null +++ b/.github/workflows/docker-image-branch.yml @@ -0,0 +1,47 @@ +name: Docker image CD - DEV + +on: + push: + branches: + - '*' + +jobs: + build_and_push: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Docker metadata + id: meta + uses: docker/metadata-action@v4 + with: + images: dandevaud/ghostfolio + tags: | + type=semver,pattern={{major}} + type=semver,pattern={{version}} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to DockerHub + if: github.event_name != 'pull_request' + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v3 + with: + context: . + platforms: linux/amd64,linux/arm/v7,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: dandevaud/ghostfolio:${{ github.ref_name }} + labels: ${{ steps.meta.output.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max From e22b7bb35c770fd45cd44a1e20b00b7f3d457515 Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 17 Apr 2024 16:56:56 +0200 Subject: [PATCH 128/203] Update Docker image CD workflow name --- .github/workflows/docker-image-branch.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image-branch.yml b/.github/workflows/docker-image-branch.yml index 6775683ea..988332c3f 100644 --- a/.github/workflows/docker-image-branch.yml +++ b/.github/workflows/docker-image-branch.yml @@ -1,4 +1,4 @@ -name: Docker image CD - DEV +name: Docker image CD - Branch on: push: From e8200515e61f2a22adaddf9c9d641319a16f4963 Mon Sep 17 00:00:00 2001 From: Dan Date: Wed, 17 Apr 2024 16:57:39 +0200 Subject: [PATCH 129/203] Update yahoo-finance2 to version 2.11.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8f04ef007..d8b62fd89 100644 --- a/package.json +++ b/package.json @@ -135,7 +135,7 @@ "svgmap": "2.6.0", "twitter-api-v2": "1.14.2", "uuid": "9.0.1", - "yahoo-finance2": "2.11.1", + "yahoo-finance2": "2.11.2", "zone.js": "0.14.4" }, "devDependencies": { From 15857118febdc1316aff87b38badc549ccdb2b4d Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Wed, 17 Apr 2024 17:35:51 +0200 Subject: [PATCH 130/203] Feature/let data gathering queue jobs fail by throwing errors (#3281) * Let data gathering queue jobs fail by throwing errors * Update changelog --- CHANGELOG.md | 2 ++ .../src/app/portfolio/portfolio.service.ts | 18 +++++++++++---- apps/api/src/app/symbol/symbol.service.ts | 20 ++++++++++++---- .../data-gathering.processor.ts | 20 ++++++++++++---- .../data-gathering/data-gathering.service.ts | 23 ++++++++----------- .../data-provider/data-provider.service.ts | 18 +++++++++------ 6 files changed, 65 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e26c1369..2941ab9eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Moved the interest calculations into the portfolio calculator - Moved the liability calculations into the portfolio calculator - Moved the (wealth) item calculations into the portfolio calculator +- Let queue jobs for asset profile data gathering fail by throwing an error +- Let queue jobs for historical market data gathering fail by throwing an error ## 2.72.0 - 2024-04-13 diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 95a68eaae..4c65d2eb9 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -822,11 +822,19 @@ export class PortfolioService { ); if (isEmpty(historicalData)) { - historicalData = await this.dataProviderService.getHistoricalRaw( - [{ dataSource: DataSource.YAHOO, symbol: aSymbol }], - portfolioStart, - new Date() - ); + try { + historicalData = await this.dataProviderService.getHistoricalRaw({ + dataGatheringItems: [ + { dataSource: DataSource.YAHOO, symbol: aSymbol } + ], + from: portfolioStart, + to: new Date() + }); + } catch { + historicalData = { + [aSymbol]: {} + }; + } } const historicalDataArray: HistoricalDataItem[] = []; diff --git a/apps/api/src/app/symbol/symbol.service.ts b/apps/api/src/app/symbol/symbol.service.ts index 9a3f7a3a0..90259a776 100644 --- a/apps/api/src/app/symbol/symbol.service.ts +++ b/apps/api/src/app/symbol/symbol.service.ts @@ -74,11 +74,21 @@ export class SymbolService { date = new Date(), symbol }: IDataGatheringItem): Promise { - const historicalData = await this.dataProviderService.getHistoricalRaw( - [{ dataSource, symbol }], - date, - date - ); + let historicalData: { + [symbol: string]: { + [date: string]: IDataProviderHistoricalResponse; + }; + } = { + [symbol]: {} + }; + + try { + historicalData = await this.dataProviderService.getHistoricalRaw({ + dataGatheringItems: [{ dataSource, symbol }], + from: date, + to: date + }); + } catch {} return { marketPrice: diff --git a/apps/api/src/services/data-gathering/data-gathering.processor.ts b/apps/api/src/services/data-gathering/data-gathering.processor.ts index bf960048c..11eda2e7a 100644 --- a/apps/api/src/services/data-gathering/data-gathering.processor.ts +++ b/apps/api/src/services/data-gathering/data-gathering.processor.ts @@ -37,7 +37,17 @@ export class DataGatheringProcessor { @Process({ concurrency: 1, name: GATHER_ASSET_PROFILE_PROCESS }) public async gatherAssetProfile(job: Job) { try { + Logger.log( + `Asset profile data gathering has been started for ${job.data.symbol} (${job.data.dataSource})`, + `DataGatheringProcessor (${GATHER_ASSET_PROFILE_PROCESS})` + ); + await this.dataGatheringService.gatherAssetProfiles([job.data]); + + Logger.log( + `Asset profile data gathering has been completed for ${job.data.symbol} (${job.data.dataSource})`, + `DataGatheringProcessor (${GATHER_ASSET_PROFILE_PROCESS})` + ); } catch (error) { Logger.error( error, @@ -62,11 +72,11 @@ export class DataGatheringProcessor { `DataGatheringProcessor (${GATHER_HISTORICAL_MARKET_DATA_PROCESS})` ); - const historicalData = await this.dataProviderService.getHistoricalRaw( - [{ dataSource, symbol }], - currentDate, - new Date() - ); + const historicalData = await this.dataProviderService.getHistoricalRaw({ + dataGatheringItems: [{ dataSource, symbol }], + from: currentDate, + to: new Date() + }); const data: Prisma.MarketDataUpdateInput[] = []; let lastMarketPrice: number; diff --git a/apps/api/src/services/data-gathering/data-gathering.service.ts b/apps/api/src/services/data-gathering/data-gathering.service.ts index b2b0c371c..31a0040a5 100644 --- a/apps/api/src/services/data-gathering/data-gathering.service.ts +++ b/apps/api/src/services/data-gathering/data-gathering.service.ts @@ -104,11 +104,11 @@ export class DataGatheringService { symbol: string; }) { try { - const historicalData = await this.dataProviderService.getHistoricalRaw( - [{ dataSource, symbol }], - date, - date - ); + const historicalData = await this.dataProviderService.getHistoricalRaw({ + dataGatheringItems: [{ dataSource, symbol }], + from: date, + to: date + }); const marketPrice = historicalData[symbol][format(date, DATE_FORMAT)].marketPrice; @@ -230,17 +230,12 @@ export class DataGatheringService { error, 'DataGatheringService' ); + + if (uniqueAssets.length === 1) { + throw error; + } } } - - Logger.log( - `Asset profile data gathering has been completed for ${uniqueAssets - .map(({ dataSource, symbol }) => { - return `${symbol} (${dataSource})`; - }) - .join(',')}.`, - 'DataGatheringService' - ); } public async gatherSymbols({ diff --git a/apps/api/src/services/data-provider/data-provider.service.ts b/apps/api/src/services/data-provider/data-provider.service.ts index 9afdab1dc..675c13377 100644 --- a/apps/api/src/services/data-provider/data-provider.service.ts +++ b/apps/api/src/services/data-provider/data-provider.service.ts @@ -233,15 +233,17 @@ export class DataProviderService { } } - public async getHistoricalRaw( - aDataGatheringItems: UniqueAsset[], - from: Date, - to: Date - ): Promise<{ + public async getHistoricalRaw({ + dataGatheringItems, + from, + to + }: { + dataGatheringItems: UniqueAsset[]; + from: Date; + to: Date; + }): Promise<{ [symbol: string]: { [date: string]: IDataProviderHistoricalResponse }; }> { - let dataGatheringItems = aDataGatheringItems; - for (const { currency, rootCurrency } of DERIVED_CURRENCIES) { if ( this.hasCurrency({ @@ -330,6 +332,8 @@ export class DataProviderService { } } catch (error) { Logger.error(error, 'DataProviderService'); + + throw error; } return result; From 5f7d083f7c16417381f31987517e856952736fd1 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Wed, 17 Apr 2024 17:40:58 +0200 Subject: [PATCH 131/203] Feature/upgrade yahoo finance2 to version 2.11.2 (#3286) * Upgrade yahoo-finance2 to version 2.11.2 * Update changelog --- CHANGELOG.md | 1 + package.json | 2 +- yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2941ab9eb..577c9ea05 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Moved the (wealth) item calculations into the portfolio calculator - Let queue jobs for asset profile data gathering fail by throwing an error - Let queue jobs for historical market data gathering fail by throwing an error +- Upgraded `yahoo-finance2` from version `2.11.1` to `2.11.2` ## 2.72.0 - 2024-04-13 diff --git a/package.json b/package.json index 146c99274..69c23b97d 100644 --- a/package.json +++ b/package.json @@ -132,7 +132,7 @@ "svgmap": "2.6.0", "twitter-api-v2": "1.14.2", "uuid": "9.0.1", - "yahoo-finance2": "2.11.1", + "yahoo-finance2": "2.11.2", "zone.js": "0.14.4" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index b821e4c08..bdfbec1b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -19620,10 +19620,10 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yahoo-finance2@2.11.1: - version "2.11.1" - resolved "https://registry.yarnpkg.com/yahoo-finance2/-/yahoo-finance2-2.11.1.tgz#97758d4784ef0b4efe4b370a72063929cc4c6342" - integrity sha512-YglgpjIDithq1PG8Je/gy8nzJFqkH214x2ZGfr6Y+HV4ymTDFLluq2W9Hsvvyydv1zTv9/Ykedf0J4YIpmO2Zg== +yahoo-finance2@2.11.2: + version "2.11.2" + resolved "https://registry.yarnpkg.com/yahoo-finance2/-/yahoo-finance2-2.11.2.tgz#44f35105a2500fd1da22ac4f4393106f2bfec6d1" + integrity sha512-S5lHKqneMXMKN/rxowqErEfkvXJE6s/SPuekT7UkOVbsSyRcptea/U3Mud+ikOEXEbKXPiZrU0Jy+iF51ITuSw== dependencies: "@types/tough-cookie" "^4.0.2" ajv "8.10.0" From e79d607ab849111fb1aab759b584edfd039431ba Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Wed, 17 Apr 2024 17:42:28 +0200 Subject: [PATCH 132/203] Release 2.73.0 (#3287) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 577c9ea05..afd01ab81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.73.0 - 2024-04-17 ### Added diff --git a/package.json b/package.json index 69c23b97d..3abee2dc8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.72.0", + "version": "2.73.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 127b7d4f25aa80ba421d65c3ee2f146c0d1ee87b Mon Sep 17 00:00:00 2001 From: Bastien Jeannelle <48835068+Sonlis@users.noreply.github.com> Date: Thu, 18 Apr 2024 19:39:20 +0300 Subject: [PATCH 133/203] Make pre-commit executable by default (#3283) --- git-hooks/pre-commit | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 git-hooks/pre-commit diff --git a/git-hooks/pre-commit b/git-hooks/pre-commit old mode 100644 new mode 100755 From 73d62bb51f19cab2630dfc013c4e5f52801a9f9d Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 18 Apr 2024 20:46:12 +0200 Subject: [PATCH 134/203] Migrate UI components to standalone (#3290) --- .../account-detail-dialog.module.ts | 10 ++-- .../admin-market-data-detail.module.ts | 2 +- .../admin-market-data.module.ts | 2 +- .../asset-profile-dialog.module.ts | 4 +- .../home-market/home-market.module.ts | 2 +- .../home-overview/home-overview.module.ts | 2 +- .../position-detail-dialog.module.ts | 8 +-- .../components/position/position.module.ts | 4 +- .../create-or-update-account-dialog.module.ts | 2 +- .../activities/activities-page.module.ts | 4 +- .../import-activities-dialog.module.ts | 4 +- .../allocations/allocations-page.module.ts | 2 +- .../analysis/analysis-page.module.ts | 2 +- .../pages/portfolio/fire/fire-page.module.ts | 4 +- .../holdings/holdings-page.module.ts | 4 +- .../app/pages/public/public-page.module.ts | 6 +-- libs/ui/src/lib/account-balances/index.ts | 1 + libs/ui/src/lib/activities-filter/index.ts | 1 + .../activities-table.component.ts | 50 +++++++++++++++++-- .../activities-table.module.ts | 43 ---------------- libs/ui/src/lib/activities-table/index.ts | 1 + libs/ui/src/lib/benchmark/benchmark.module.ts | 4 +- libs/ui/src/lib/currency-selector/index.ts | 1 + .../fire-calculator.component.ts | 31 ++++++++++-- .../fire-calculator/fire-calculator.module.ts | 28 ----------- libs/ui/src/lib/fire-calculator/index.ts | 2 +- .../holdings-table.component.ts | 37 ++++++++++++-- .../holdings-table/holdings-table.module.ts | 39 --------------- libs/ui/src/lib/holdings-table/index.ts | 1 + libs/ui/src/lib/line-chart/index.ts | 1 + .../lib/portfolio-proportion-chart/index.ts | 1 + libs/ui/src/lib/trend-indicator/index.ts | 2 +- .../trend-indicator.component.ts | 20 ++++++-- .../trend-indicator/trend-indicator.module.ts | 13 ----- 34 files changed, 162 insertions(+), 176 deletions(-) create mode 100644 libs/ui/src/lib/account-balances/index.ts create mode 100644 libs/ui/src/lib/activities-filter/index.ts delete mode 100644 libs/ui/src/lib/activities-table/activities-table.module.ts create mode 100644 libs/ui/src/lib/activities-table/index.ts create mode 100644 libs/ui/src/lib/currency-selector/index.ts delete mode 100644 libs/ui/src/lib/fire-calculator/fire-calculator.module.ts delete mode 100644 libs/ui/src/lib/holdings-table/holdings-table.module.ts create mode 100644 libs/ui/src/lib/holdings-table/index.ts create mode 100644 libs/ui/src/lib/line-chart/index.ts create mode 100644 libs/ui/src/lib/portfolio-proportion-chart/index.ts delete mode 100644 libs/ui/src/lib/trend-indicator/trend-indicator.module.ts diff --git a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.module.ts b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.module.ts index faba1d6d2..af9d009c1 100644 --- a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.module.ts +++ b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.module.ts @@ -1,9 +1,9 @@ import { GfDialogFooterModule } from '@ghostfolio/client/components/dialog-footer/dialog-footer.module'; import { GfDialogHeaderModule } from '@ghostfolio/client/components/dialog-header/dialog-header.module'; import { GfInvestmentChartModule } from '@ghostfolio/client/components/investment-chart/investment-chart.module'; -import { GfAccountBalancesModule } from '@ghostfolio/ui/account-balances/account-balances.module'; -import { GfActivitiesTableModule } from '@ghostfolio/ui/activities-table/activities-table.module'; -import { GfHoldingsTableModule } from '@ghostfolio/ui/holdings-table/holdings-table.module'; +import { GfAccountBalancesModule } from '@ghostfolio/ui/account-balances'; +import { GfActivitiesTableComponent } from '@ghostfolio/ui/activities-table'; +import { GfHoldingsTableComponent } from '@ghostfolio/ui/holdings-table'; import { GfValueModule } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; @@ -20,10 +20,10 @@ import { AccountDetailDialog } from './account-detail-dialog.component'; imports: [ CommonModule, GfAccountBalancesModule, - GfActivitiesTableModule, + GfActivitiesTableComponent, GfDialogFooterModule, GfDialogHeaderModule, - GfHoldingsTableModule, + GfHoldingsTableComponent, GfInvestmentChartModule, GfValueModule, MatButtonModule, diff --git a/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.module.ts b/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.module.ts index 9e742acba..eafc24c90 100644 --- a/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.module.ts +++ b/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.module.ts @@ -1,4 +1,4 @@ -import { GfLineChartModule } from '@ghostfolio/ui/line-chart/line-chart.module'; +import { GfLineChartModule } from '@ghostfolio/ui/line-chart'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; diff --git a/apps/client/src/app/components/admin-market-data/admin-market-data.module.ts b/apps/client/src/app/components/admin-market-data/admin-market-data.module.ts index c4cdc3bdd..622a01cdb 100644 --- a/apps/client/src/app/components/admin-market-data/admin-market-data.module.ts +++ b/apps/client/src/app/components/admin-market-data/admin-market-data.module.ts @@ -1,5 +1,5 @@ import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; -import { GfActivitiesFilterModule } from '@ghostfolio/ui/activities-filter/activities-filter.module'; +import { GfActivitiesFilterModule } from '@ghostfolio/ui/activities-filter'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts index ffde6c0ae..beb483874 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts @@ -1,8 +1,8 @@ import { GfAdminMarketDataDetailModule } from '@ghostfolio/client/components/admin-market-data-detail/admin-market-data-detail.module'; import { AdminMarketDataService } from '@ghostfolio/client/components/admin-market-data/admin-market-data.service'; import { GfAssetProfileIconComponent } from '@ghostfolio/client/components/asset-profile-icon/asset-profile-icon.component'; -import { GfCurrencySelectorModule } from '@ghostfolio/ui/currency-selector/currency-selector.module'; -import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart/portfolio-proportion-chart.module'; +import { GfCurrencySelectorModule } from '@ghostfolio/ui/currency-selector'; +import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart'; import { GfValueModule } from '@ghostfolio/ui/value'; import { TextFieldModule } from '@angular/cdk/text-field'; diff --git a/apps/client/src/app/components/home-market/home-market.module.ts b/apps/client/src/app/components/home-market/home-market.module.ts index b8d2f8c79..1443d2129 100644 --- a/apps/client/src/app/components/home-market/home-market.module.ts +++ b/apps/client/src/app/components/home-market/home-market.module.ts @@ -1,6 +1,6 @@ import { GfFearAndGreedIndexModule } from '@ghostfolio/client/components/fear-and-greed-index/fear-and-greed-index.module'; import { GfBenchmarkModule } from '@ghostfolio/ui/benchmark/benchmark.module'; -import { GfLineChartModule } from '@ghostfolio/ui/line-chart/line-chart.module'; +import { GfLineChartModule } from '@ghostfolio/ui/line-chart'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; diff --git a/apps/client/src/app/components/home-overview/home-overview.module.ts b/apps/client/src/app/components/home-overview/home-overview.module.ts index 4f5041627..a4968e9c0 100644 --- a/apps/client/src/app/components/home-overview/home-overview.module.ts +++ b/apps/client/src/app/components/home-overview/home-overview.module.ts @@ -1,5 +1,5 @@ import { GfPortfolioPerformanceModule } from '@ghostfolio/client/components/portfolio-performance/portfolio-performance.module'; -import { GfLineChartModule } from '@ghostfolio/ui/line-chart/line-chart.module'; +import { GfLineChartModule } from '@ghostfolio/ui/line-chart'; import { GfNoTransactionsInfoModule } from '@ghostfolio/ui/no-transactions-info'; import { CommonModule } from '@angular/common'; diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.module.ts b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.module.ts index 675f8187b..2a347500a 100644 --- a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.module.ts +++ b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.module.ts @@ -1,10 +1,10 @@ import { GfAccountsTableModule } from '@ghostfolio/client/components/accounts-table/accounts-table.module'; import { GfDialogFooterModule } from '@ghostfolio/client/components/dialog-footer/dialog-footer.module'; import { GfDialogHeaderModule } from '@ghostfolio/client/components/dialog-header/dialog-header.module'; -import { GfActivitiesTableModule } from '@ghostfolio/ui/activities-table/activities-table.module'; +import { GfActivitiesTableComponent } from '@ghostfolio/ui/activities-table'; import { GfDataProviderCreditsModule } from '@ghostfolio/ui/data-provider-credits/data-provider-credits.module'; -import { GfLineChartModule } from '@ghostfolio/ui/line-chart/line-chart.module'; -import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart/portfolio-proportion-chart.module'; +import { GfLineChartModule } from '@ghostfolio/ui/line-chart'; +import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart'; import { GfValueModule } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; @@ -22,7 +22,7 @@ import { PositionDetailDialog } from './position-detail-dialog.component'; imports: [ CommonModule, GfAccountsTableModule, - GfActivitiesTableModule, + GfActivitiesTableComponent, GfDataProviderCreditsModule, GfDialogFooterModule, GfDialogHeaderModule, diff --git a/apps/client/src/app/components/position/position.module.ts b/apps/client/src/app/components/position/position.module.ts index 0b225cd04..d21748a87 100644 --- a/apps/client/src/app/components/position/position.module.ts +++ b/apps/client/src/app/components/position/position.module.ts @@ -1,5 +1,5 @@ import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; -import { GfTrendIndicatorModule } from '@ghostfolio/ui/trend-indicator'; +import { GfTrendIndicatorComponent } from '@ghostfolio/ui/trend-indicator'; import { GfValueModule } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; @@ -18,7 +18,7 @@ import { PositionComponent } from './position.component'; CommonModule, GfPositionDetailDialogModule, GfSymbolModule, - GfTrendIndicatorModule, + GfTrendIndicatorComponent, GfValueModule, MatDialogModule, NgxSkeletonLoaderModule, diff --git a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.module.ts b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.module.ts index e2ea5d091..6838ef2bf 100644 --- a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.module.ts +++ b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.module.ts @@ -1,5 +1,5 @@ import { GfAssetProfileIconComponent } from '@ghostfolio/client/components/asset-profile-icon/asset-profile-icon.component'; -import { GfCurrencySelectorModule } from '@ghostfolio/ui/currency-selector/currency-selector.module'; +import { GfCurrencySelectorModule } from '@ghostfolio/ui/currency-selector'; import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; diff --git a/apps/client/src/app/pages/portfolio/activities/activities-page.module.ts b/apps/client/src/app/pages/portfolio/activities/activities-page.module.ts index c7c14b623..c964022be 100644 --- a/apps/client/src/app/pages/portfolio/activities/activities-page.module.ts +++ b/apps/client/src/app/pages/portfolio/activities/activities-page.module.ts @@ -1,5 +1,5 @@ import { ImportActivitiesService } from '@ghostfolio/client/services/import-activities.service'; -import { GfActivitiesTableModule } from '@ghostfolio/ui/activities-table/activities-table.module'; +import { GfActivitiesTableComponent } from '@ghostfolio/ui/activities-table'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -17,7 +17,7 @@ import { GfImportActivitiesDialogModule } from './import-activities-dialog/impor imports: [ ActivitiesPageRoutingModule, CommonModule, - GfActivitiesTableModule, + GfActivitiesTableComponent, GfCreateOrUpdateActivityDialogModule, GfImportActivitiesDialogModule, MatButtonModule, diff --git a/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.module.ts b/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.module.ts index 95573b1d6..664054a54 100644 --- a/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.module.ts +++ b/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.module.ts @@ -2,7 +2,7 @@ import { GfDialogFooterModule } from '@ghostfolio/client/components/dialog-foote import { GfDialogHeaderModule } from '@ghostfolio/client/components/dialog-header/dialog-header.module'; import { GfFileDropModule } from '@ghostfolio/client/directives/file-drop/file-drop.module'; import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; -import { GfActivitiesTableModule } from '@ghostfolio/ui/activities-table/activities-table.module'; +import { GfActivitiesTableComponent } from '@ghostfolio/ui/activities-table'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -22,7 +22,7 @@ import { ImportActivitiesDialog } from './import-activities-dialog.component'; imports: [ CommonModule, FormsModule, - GfActivitiesTableModule, + GfActivitiesTableComponent, GfDialogFooterModule, GfDialogHeaderModule, GfFileDropModule, diff --git a/apps/client/src/app/pages/portfolio/allocations/allocations-page.module.ts b/apps/client/src/app/pages/portfolio/allocations/allocations-page.module.ts index b0a027cb5..efa362af6 100644 --- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.module.ts +++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.module.ts @@ -1,5 +1,5 @@ import { GfWorldMapChartModule } from '@ghostfolio/client/components/world-map-chart/world-map-chart.module'; -import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart/portfolio-proportion-chart.module'; +import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart'; import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; import { GfValueModule } from '@ghostfolio/ui/value'; diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.module.ts b/apps/client/src/app/pages/portfolio/analysis/analysis-page.module.ts index 52e45c330..1803a1cd7 100644 --- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.module.ts +++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.module.ts @@ -1,7 +1,7 @@ import { GfBenchmarkComparatorModule } from '@ghostfolio/client/components/benchmark-comparator/benchmark-comparator.module'; import { GfInvestmentChartModule } from '@ghostfolio/client/components/investment-chart/investment-chart.module'; import { GfToggleModule } from '@ghostfolio/client/components/toggle/toggle.module'; -import { GfActivitiesFilterModule } from '@ghostfolio/ui/activities-filter/activities-filter.module'; +import { GfActivitiesFilterModule } from '@ghostfolio/ui/activities-filter'; import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; import { GfValueModule } from '@ghostfolio/ui/value'; diff --git a/apps/client/src/app/pages/portfolio/fire/fire-page.module.ts b/apps/client/src/app/pages/portfolio/fire/fire-page.module.ts index 90b6f204f..2db99babd 100644 --- a/apps/client/src/app/pages/portfolio/fire/fire-page.module.ts +++ b/apps/client/src/app/pages/portfolio/fire/fire-page.module.ts @@ -1,5 +1,5 @@ import { GfRulesModule } from '@ghostfolio/client/components/rules/rules.module'; -import { GfFireCalculatorModule } from '@ghostfolio/ui/fire-calculator'; +import { GfFireCalculatorComponent } from '@ghostfolio/ui/fire-calculator'; import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; import { GfValueModule } from '@ghostfolio/ui/value'; @@ -15,7 +15,7 @@ import { FirePageComponent } from './fire-page.component'; imports: [ CommonModule, FirePageRoutingModule, - GfFireCalculatorModule, + GfFireCalculatorComponent, GfPremiumIndicatorModule, GfRulesModule, GfValueModule, diff --git a/apps/client/src/app/pages/portfolio/holdings/holdings-page.module.ts b/apps/client/src/app/pages/portfolio/holdings/holdings-page.module.ts index eae26d2b3..a5040f373 100644 --- a/apps/client/src/app/pages/portfolio/holdings/holdings-page.module.ts +++ b/apps/client/src/app/pages/portfolio/holdings/holdings-page.module.ts @@ -1,5 +1,5 @@ import { GfToggleModule } from '@ghostfolio/client/components/toggle/toggle.module'; -import { GfHoldingsTableModule } from '@ghostfolio/ui/holdings-table/holdings-table.module'; +import { GfHoldingsTableComponent } from '@ghostfolio/ui/holdings-table'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -12,7 +12,7 @@ import { HoldingsPageComponent } from './holdings-page.component'; declarations: [HoldingsPageComponent], imports: [ CommonModule, - GfHoldingsTableModule, + GfHoldingsTableComponent, GfToggleModule, HoldingsPageRoutingModule, MatButtonModule diff --git a/apps/client/src/app/pages/public/public-page.module.ts b/apps/client/src/app/pages/public/public-page.module.ts index 2a595f7fe..f894f7bf5 100644 --- a/apps/client/src/app/pages/public/public-page.module.ts +++ b/apps/client/src/app/pages/public/public-page.module.ts @@ -1,6 +1,6 @@ import { GfWorldMapChartModule } from '@ghostfolio/client/components/world-map-chart/world-map-chart.module'; -import { GfHoldingsTableModule } from '@ghostfolio/ui/holdings-table/holdings-table.module'; -import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart/portfolio-proportion-chart.module'; +import { GfHoldingsTableComponent } from '@ghostfolio/ui/holdings-table'; +import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart'; import { GfValueModule } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; @@ -15,7 +15,7 @@ import { PublicPageComponent } from './public-page.component'; declarations: [PublicPageComponent], imports: [ CommonModule, - GfHoldingsTableModule, + GfHoldingsTableComponent, GfPortfolioProportionChartModule, GfValueModule, GfWorldMapChartModule, diff --git a/libs/ui/src/lib/account-balances/index.ts b/libs/ui/src/lib/account-balances/index.ts new file mode 100644 index 000000000..732615851 --- /dev/null +++ b/libs/ui/src/lib/account-balances/index.ts @@ -0,0 +1 @@ +export * from './account-balances.module'; diff --git a/libs/ui/src/lib/activities-filter/index.ts b/libs/ui/src/lib/activities-filter/index.ts new file mode 100644 index 000000000..ce1d30e5e --- /dev/null +++ b/libs/ui/src/lib/activities-filter/index.ts @@ -0,0 +1 @@ +export * from './activities-filter.module'; diff --git a/libs/ui/src/lib/activities-table/activities-table.component.ts b/libs/ui/src/lib/activities-table/activities-table.component.ts index af42f86e4..df8fdec1b 100644 --- a/libs/ui/src/lib/activities-table/activities-table.component.ts +++ b/libs/ui/src/lib/activities-table/activities-table.component.ts @@ -1,12 +1,19 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; +import { GfAssetProfileIconComponent } from '@ghostfolio/client/components/asset-profile-icon/asset-profile-icon.component'; +import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; import { DEFAULT_PAGE_SIZE } from '@ghostfolio/common/config'; import { getDateFormatString, getLocale } from '@ghostfolio/common/helper'; import { UniqueAsset } from '@ghostfolio/common/interfaces'; import { OrderWithAccount } from '@ghostfolio/common/types'; +import { GfActivityTypeModule } from '@ghostfolio/ui/activity-type'; +import { GfNoTransactionsInfoModule } from '@ghostfolio/ui/no-transactions-info'; +import { GfValueModule } from '@ghostfolio/ui/value'; import { SelectionModel } from '@angular/cdk/collections'; +import { CommonModule } from '@angular/common'; import { AfterViewInit, + CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, EventEmitter, @@ -17,21 +24,54 @@ import { Output, ViewChild } from '@angular/core'; -import { MatPaginator, PageEvent } from '@angular/material/paginator'; -import { MatSort, Sort, SortDirection } from '@angular/material/sort'; -import { MatTableDataSource } from '@angular/material/table'; -import { Router } from '@angular/router'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatMenuModule } from '@angular/material/menu'; +import { + MatPaginator, + MatPaginatorModule, + PageEvent +} from '@angular/material/paginator'; +import { + MatSort, + MatSortModule, + Sort, + SortDirection +} from '@angular/material/sort'; +import { MatTableDataSource, MatTableModule } from '@angular/material/table'; +import { MatTooltipModule } from '@angular/material/tooltip'; +import { Router, RouterModule } from '@angular/router'; import { isUUID } from 'class-validator'; import { endOfToday, isAfter } from 'date-fns'; +import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { Subject, Subscription, takeUntil } from 'rxjs'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, + imports: [ + CommonModule, + GfActivityTypeModule, + GfAssetProfileIconComponent, + GfNoTransactionsInfoModule, + GfSymbolModule, + GfValueModule, + MatButtonModule, + MatCheckboxModule, + MatMenuModule, + MatPaginatorModule, + MatSortModule, + MatTableModule, + MatTooltipModule, + NgxSkeletonLoaderModule, + RouterModule + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA], selector: 'gf-activities-table', + standalone: true, styleUrls: ['./activities-table.component.scss'], templateUrl: './activities-table.component.html' }) -export class ActivitiesTableComponent +export class GfActivitiesTableComponent implements AfterViewInit, OnChanges, OnDestroy, OnInit { @Input() baseCurrency: string; diff --git a/libs/ui/src/lib/activities-table/activities-table.module.ts b/libs/ui/src/lib/activities-table/activities-table.module.ts deleted file mode 100644 index 1d80c9fb0..000000000 --- a/libs/ui/src/lib/activities-table/activities-table.module.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { GfAssetProfileIconComponent } from '@ghostfolio/client/components/asset-profile-icon/asset-profile-icon.component'; -import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; -import { GfActivityTypeModule } from '@ghostfolio/ui/activity-type'; -import { GfNoTransactionsInfoModule } from '@ghostfolio/ui/no-transactions-info'; -import { GfValueModule } from '@ghostfolio/ui/value'; - -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { MatButtonModule } from '@angular/material/button'; -import { MatCheckboxModule } from '@angular/material/checkbox'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatPaginatorModule } from '@angular/material/paginator'; -import { MatSortModule } from '@angular/material/sort'; -import { MatTableModule } from '@angular/material/table'; -import { MatTooltipModule } from '@angular/material/tooltip'; -import { RouterModule } from '@angular/router'; -import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; - -import { ActivitiesTableComponent } from './activities-table.component'; - -@NgModule({ - declarations: [ActivitiesTableComponent], - exports: [ActivitiesTableComponent], - imports: [ - CommonModule, - GfActivityTypeModule, - GfAssetProfileIconComponent, - GfNoTransactionsInfoModule, - GfSymbolModule, - GfValueModule, - MatButtonModule, - MatCheckboxModule, - MatMenuModule, - MatPaginatorModule, - MatSortModule, - MatTableModule, - MatTooltipModule, - NgxSkeletonLoaderModule, - RouterModule - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfActivitiesTableModule {} diff --git a/libs/ui/src/lib/activities-table/index.ts b/libs/ui/src/lib/activities-table/index.ts new file mode 100644 index 000000000..82eee49b1 --- /dev/null +++ b/libs/ui/src/lib/activities-table/index.ts @@ -0,0 +1 @@ +export * from './activities-table.component'; diff --git a/libs/ui/src/lib/benchmark/benchmark.module.ts b/libs/ui/src/lib/benchmark/benchmark.module.ts index 5b3e00209..67b64ec6d 100644 --- a/libs/ui/src/lib/benchmark/benchmark.module.ts +++ b/libs/ui/src/lib/benchmark/benchmark.module.ts @@ -3,7 +3,7 @@ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import { MatTableModule } from '@angular/material/table'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; -import { GfTrendIndicatorModule } from '../trend-indicator'; +import { GfTrendIndicatorComponent } from '../trend-indicator'; import { GfValueModule } from '../value'; import { BenchmarkComponent } from './benchmark.component'; @@ -12,7 +12,7 @@ import { BenchmarkComponent } from './benchmark.component'; exports: [BenchmarkComponent], imports: [ CommonModule, - GfTrendIndicatorModule, + GfTrendIndicatorComponent, GfValueModule, MatTableModule, NgxSkeletonLoaderModule diff --git a/libs/ui/src/lib/currency-selector/index.ts b/libs/ui/src/lib/currency-selector/index.ts new file mode 100644 index 000000000..5790d8acc --- /dev/null +++ b/libs/ui/src/lib/currency-selector/index.ts @@ -0,0 +1 @@ +export * from './currency-selector.module'; diff --git a/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts b/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts index 60c47a309..4f6c8dc08 100644 --- a/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts +++ b/libs/ui/src/lib/fire-calculator/fire-calculator.component.ts @@ -6,6 +6,7 @@ import { primaryColorRgb } from '@ghostfolio/common/config'; import { getLocale } from '@ghostfolio/common/helper'; import { ColorScheme } from '@ghostfolio/common/types'; +import { CommonModule } from '@angular/common'; import { ChangeDetectionStrategy, ChangeDetectorRef, @@ -17,8 +18,19 @@ import { Output, ViewChild } from '@angular/core'; -import { FormBuilder, FormControl } from '@angular/forms'; -import { MatDatepicker } from '@angular/material/datepicker'; +import { + FormBuilder, + FormControl, + FormsModule, + ReactiveFormsModule +} from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { + MatDatepicker, + MatDatepickerModule +} from '@angular/material/datepicker'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; import { BarController, BarElement, @@ -39,17 +51,30 @@ import { sub } from 'date-fns'; import { isNumber } from 'lodash'; +import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { Subject, debounceTime, takeUntil } from 'rxjs'; import { FireCalculatorService } from './fire-calculator.service'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, + imports: [ + CommonModule, + FormsModule, + MatButtonModule, + MatDatepickerModule, + MatFormFieldModule, + MatInputModule, + NgxSkeletonLoaderModule, + ReactiveFormsModule + ], + providers: [FireCalculatorService], selector: 'gf-fire-calculator', + standalone: true, styleUrls: ['./fire-calculator.component.scss'], templateUrl: './fire-calculator.component.html' }) -export class FireCalculatorComponent implements OnChanges, OnDestroy { +export class GfFireCalculatorComponent implements OnChanges, OnDestroy { @Input() annualInterestRate = 5; @Input() colorScheme: ColorScheme; @Input() currency: string; diff --git a/libs/ui/src/lib/fire-calculator/fire-calculator.module.ts b/libs/ui/src/lib/fire-calculator/fire-calculator.module.ts deleted file mode 100644 index 02b59dc27..000000000 --- a/libs/ui/src/lib/fire-calculator/fire-calculator.module.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatButtonModule } from '@angular/material/button'; -import { MatDatepickerModule } from '@angular/material/datepicker'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; - -import { FireCalculatorComponent } from './fire-calculator.component'; -import { FireCalculatorService } from './fire-calculator.service'; - -@NgModule({ - declarations: [FireCalculatorComponent], - exports: [FireCalculatorComponent], - imports: [ - CommonModule, - FormsModule, - MatButtonModule, - MatDatepickerModule, - MatFormFieldModule, - MatInputModule, - NgxSkeletonLoaderModule, - ReactiveFormsModule - ], - providers: [FireCalculatorService] -}) -export class GfFireCalculatorModule {} diff --git a/libs/ui/src/lib/fire-calculator/index.ts b/libs/ui/src/lib/fire-calculator/index.ts index aea6c656a..1636174fc 100644 --- a/libs/ui/src/lib/fire-calculator/index.ts +++ b/libs/ui/src/lib/fire-calculator/index.ts @@ -1 +1 @@ -export * from './fire-calculator.module'; +export * from './fire-calculator.component'; diff --git a/libs/ui/src/lib/holdings-table/holdings-table.component.ts b/libs/ui/src/lib/holdings-table/holdings-table.component.ts index 38403d519..063582139 100644 --- a/libs/ui/src/lib/holdings-table/holdings-table.component.ts +++ b/libs/ui/src/lib/holdings-table/holdings-table.component.ts @@ -1,7 +1,14 @@ +import { GfAssetProfileIconComponent } from '@ghostfolio/client/components/asset-profile-icon/asset-profile-icon.component'; +import { GfPositionDetailDialogModule } from '@ghostfolio/client/components/position/position-detail-dialog/position-detail-dialog.module'; +import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; import { getLocale } from '@ghostfolio/common/helper'; import { PortfolioPosition, UniqueAsset } from '@ghostfolio/common/interfaces'; +import { GfNoTransactionsInfoModule } from '@ghostfolio/ui/no-transactions-info'; +import { GfValueModule } from '@ghostfolio/ui/value'; +import { CommonModule } from '@angular/common'; import { + CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, Input, @@ -10,20 +17,40 @@ import { OnInit, ViewChild } from '@angular/core'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import { MatTableDataSource } from '@angular/material/table'; -import { Router } from '@angular/router'; +import { MatButtonModule } from '@angular/material/button'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator'; +import { MatSort, MatSortModule } from '@angular/material/sort'; +import { MatTableDataSource, MatTableModule } from '@angular/material/table'; +import { Router, RouterModule } from '@angular/router'; import { AssetClass } from '@prisma/client'; +import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { Subject, Subscription } from 'rxjs'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, + imports: [ + CommonModule, + GfAssetProfileIconComponent, + GfNoTransactionsInfoModule, + GfPositionDetailDialogModule, + GfSymbolModule, + GfValueModule, + MatButtonModule, + MatDialogModule, + MatPaginatorModule, + MatSortModule, + MatTableModule, + NgxSkeletonLoaderModule, + RouterModule + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA], selector: 'gf-holdings-table', + standalone: true, styleUrls: ['./holdings-table.component.scss'], templateUrl: './holdings-table.component.html' }) -export class HoldingsTableComponent implements OnChanges, OnDestroy, OnInit { +export class GfHoldingsTableComponent implements OnChanges, OnDestroy, OnInit { @Input() baseCurrency: string; @Input() deviceType: string; @Input() hasPermissionToCreateActivity: boolean; diff --git a/libs/ui/src/lib/holdings-table/holdings-table.module.ts b/libs/ui/src/lib/holdings-table/holdings-table.module.ts deleted file mode 100644 index a944bc1c1..000000000 --- a/libs/ui/src/lib/holdings-table/holdings-table.module.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { GfAssetProfileIconComponent } from '@ghostfolio/client/components/asset-profile-icon/asset-profile-icon.component'; -import { GfPositionDetailDialogModule } from '@ghostfolio/client/components/position/position-detail-dialog/position-detail-dialog.module'; -import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; -import { GfNoTransactionsInfoModule } from '@ghostfolio/ui/no-transactions-info'; -import { GfValueModule } from '@ghostfolio/ui/value'; - -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { MatButtonModule } from '@angular/material/button'; -import { MatDialogModule } from '@angular/material/dialog'; -import { MatPaginatorModule } from '@angular/material/paginator'; -import { MatSortModule } from '@angular/material/sort'; -import { MatTableModule } from '@angular/material/table'; -import { RouterModule } from '@angular/router'; -import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; - -import { HoldingsTableComponent } from './holdings-table.component'; - -@NgModule({ - declarations: [HoldingsTableComponent], - exports: [HoldingsTableComponent], - imports: [ - CommonModule, - GfAssetProfileIconComponent, - GfNoTransactionsInfoModule, - GfPositionDetailDialogModule, - GfSymbolModule, - GfValueModule, - MatButtonModule, - MatDialogModule, - MatPaginatorModule, - MatSortModule, - MatTableModule, - NgxSkeletonLoaderModule, - RouterModule - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfHoldingsTableModule {} diff --git a/libs/ui/src/lib/holdings-table/index.ts b/libs/ui/src/lib/holdings-table/index.ts new file mode 100644 index 000000000..f2dd696ce --- /dev/null +++ b/libs/ui/src/lib/holdings-table/index.ts @@ -0,0 +1 @@ +export * from './holdings-table.component'; diff --git a/libs/ui/src/lib/line-chart/index.ts b/libs/ui/src/lib/line-chart/index.ts new file mode 100644 index 000000000..0edc13b6e --- /dev/null +++ b/libs/ui/src/lib/line-chart/index.ts @@ -0,0 +1 @@ +export * from './line-chart.module'; diff --git a/libs/ui/src/lib/portfolio-proportion-chart/index.ts b/libs/ui/src/lib/portfolio-proportion-chart/index.ts new file mode 100644 index 000000000..16ceaf055 --- /dev/null +++ b/libs/ui/src/lib/portfolio-proportion-chart/index.ts @@ -0,0 +1 @@ +export * from './portfolio-proportion-chart.module'; diff --git a/libs/ui/src/lib/trend-indicator/index.ts b/libs/ui/src/lib/trend-indicator/index.ts index 5d9fc1d42..3e5ebf36e 100644 --- a/libs/ui/src/lib/trend-indicator/index.ts +++ b/libs/ui/src/lib/trend-indicator/index.ts @@ -1 +1 @@ -export * from './trend-indicator.module'; +export * from './trend-indicator.component'; diff --git a/libs/ui/src/lib/trend-indicator/trend-indicator.component.ts b/libs/ui/src/lib/trend-indicator/trend-indicator.component.ts index fafe6e0f3..d03ee8cf4 100644 --- a/libs/ui/src/lib/trend-indicator/trend-indicator.component.ts +++ b/libs/ui/src/lib/trend-indicator/trend-indicator.component.ts @@ -1,14 +1,24 @@ import { DateRange, MarketState } from '@ghostfolio/common/types'; -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { + CUSTOM_ELEMENTS_SCHEMA, + ChangeDetectionStrategy, + Component, + Input +} from '@angular/core'; +import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; @Component({ - selector: 'gf-trend-indicator', changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './trend-indicator.component.html', - styleUrls: ['./trend-indicator.component.scss'] + imports: [CommonModule, NgxSkeletonLoaderModule], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + selector: 'gf-trend-indicator', + standalone: true, + styleUrls: ['./trend-indicator.component.scss'], + templateUrl: './trend-indicator.component.html' }) -export class TrendIndicatorComponent { +export class GfTrendIndicatorComponent { @Input() isLoading = false; @Input() marketState: MarketState = 'open'; @Input() range: DateRange = 'max'; diff --git a/libs/ui/src/lib/trend-indicator/trend-indicator.module.ts b/libs/ui/src/lib/trend-indicator/trend-indicator.module.ts deleted file mode 100644 index dc84a3baa..000000000 --- a/libs/ui/src/lib/trend-indicator/trend-indicator.module.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; - -import { TrendIndicatorComponent } from './trend-indicator.component'; - -@NgModule({ - declarations: [TrendIndicatorComponent], - exports: [TrendIndicatorComponent], - imports: [CommonModule, NgxSkeletonLoaderModule], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfTrendIndicatorModule {} From 92fb05320ac01f9652c9814122465be52ee6d5da Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 19 Apr 2024 18:31:35 +0200 Subject: [PATCH 135/203] Migrate UI components to standalone (#3296) --- .../account-detail-dialog.module.ts | 4 +- .../accounts-table/accounts-table.module.ts | 4 +- .../asset-profile-dialog.module.ts | 8 ++-- .../create-asset-profile-dialog.module.ts | 4 +- .../admin-overview/admin-overview.module.ts | 4 +- .../admin-users/admin-users.module.ts | 8 ++-- .../benchmark-comparator.module.ts | 4 +- .../app/components/header/header.module.ts | 4 +- .../home-overview/home-overview.module.ts | 4 +- .../portfolio-performance.module.ts | 4 +- .../portfolio-summary.module.ts | 4 +- .../position-detail-dialog.module.ts | 4 +- .../components/position/position.module.ts | 4 +- .../components/positions/positions.module.ts | 4 +- .../src/app/components/rules/rules.module.ts | 4 +- ...subscription-interstitial-dialog.module.ts | 4 +- .../user-account-access.module.ts | 4 +- .../user-account-membership.module.ts | 8 ++-- .../user-account-settings.module.ts | 4 +- .../create-or-update-account-dialog.module.ts | 4 +- .../black-friday-2022-page.component.ts | 4 +- .../black-week-2023-page.component.ts | 4 +- .../pages/features/features-page.module.ts | 4 +- .../app/pages/landing/landing-page.module.ts | 4 +- .../src/app/pages/open/open-page.module.ts | 9 +++- ...create-or-update-activity-dialog.module.ts | 8 ++-- .../allocations/allocations-page.module.ts | 8 ++-- .../analysis/analysis-page.module.ts | 8 ++-- .../pages/portfolio/fire/fire-page.module.ts | 8 ++-- .../app/pages/pricing/pricing-page.module.ts | 4 +- .../app/pages/public/public-page.module.ts | 4 +- .../account-balances.module.ts | 4 +- .../activities-table.component.ts | 8 ++-- libs/ui/src/lib/benchmark/benchmark.module.ts | 4 +- .../currency-selector.component.ts | 32 +++++++++++-- .../currency-selector.module.ts | 23 ---------- libs/ui/src/lib/currency-selector/index.ts | 2 +- .../holdings-table.component.ts | 8 ++-- libs/ui/src/lib/no-transactions-info/index.ts | 2 +- .../no-transactions-info.component.ts | 17 +++++-- .../no-transactions-info.module.ts | 16 ------- libs/ui/src/lib/premium-indicator/index.ts | 2 +- .../premium-indicator.component.ts | 20 ++++++-- .../premium-indicator.module.ts | 13 ------ libs/ui/src/lib/symbol-autocomplete/index.ts | 2 +- .../symbol-autocomplete.component.ts | 46 +++++++++++++++---- .../symbol-autocomplete.module.ts | 29 ------------ libs/ui/src/lib/value/index.ts | 2 +- libs/ui/src/lib/value/value.component.ts | 14 ++++-- libs/ui/src/lib/value/value.module.ts | 13 ------ 50 files changed, 200 insertions(+), 214 deletions(-) delete mode 100644 libs/ui/src/lib/currency-selector/currency-selector.module.ts delete mode 100644 libs/ui/src/lib/no-transactions-info/no-transactions-info.module.ts delete mode 100644 libs/ui/src/lib/premium-indicator/premium-indicator.module.ts delete mode 100644 libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.module.ts delete mode 100644 libs/ui/src/lib/value/value.module.ts diff --git a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.module.ts b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.module.ts index af9d009c1..4ab7eb058 100644 --- a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.module.ts +++ b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.module.ts @@ -4,7 +4,7 @@ import { GfInvestmentChartModule } from '@ghostfolio/client/components/investmen import { GfAccountBalancesModule } from '@ghostfolio/ui/account-balances'; import { GfActivitiesTableComponent } from '@ghostfolio/ui/activities-table'; import { GfHoldingsTableComponent } from '@ghostfolio/ui/holdings-table'; -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -25,7 +25,7 @@ import { AccountDetailDialog } from './account-detail-dialog.component'; GfDialogHeaderModule, GfHoldingsTableComponent, GfInvestmentChartModule, - GfValueModule, + GfValueComponent, MatButtonModule, MatDialogModule, MatTabsModule, diff --git a/apps/client/src/app/components/accounts-table/accounts-table.module.ts b/apps/client/src/app/components/accounts-table/accounts-table.module.ts index bae24fda3..879ca13ea 100644 --- a/apps/client/src/app/components/accounts-table/accounts-table.module.ts +++ b/apps/client/src/app/components/accounts-table/accounts-table.module.ts @@ -1,5 +1,5 @@ import { GfAssetProfileIconComponent } from '@ghostfolio/client/components/asset-profile-icon/asset-profile-icon.component'; -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -18,7 +18,7 @@ import { AccountsTableComponent } from './accounts-table.component'; imports: [ CommonModule, GfAssetProfileIconComponent, - GfValueModule, + GfValueComponent, MatButtonModule, MatMenuModule, MatSortModule, diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts index beb483874..544213c05 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts @@ -1,9 +1,9 @@ import { GfAdminMarketDataDetailModule } from '@ghostfolio/client/components/admin-market-data-detail/admin-market-data-detail.module'; import { AdminMarketDataService } from '@ghostfolio/client/components/admin-market-data/admin-market-data.service'; import { GfAssetProfileIconComponent } from '@ghostfolio/client/components/asset-profile-icon/asset-profile-icon.component'; -import { GfCurrencySelectorModule } from '@ghostfolio/ui/currency-selector'; +import { GfCurrencySelectorComponent } from '@ghostfolio/ui/currency-selector'; import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart'; -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { TextFieldModule } from '@angular/cdk/text-field'; import { CommonModule } from '@angular/common'; @@ -26,9 +26,9 @@ import { AssetProfileDialog } from './asset-profile-dialog.component'; FormsModule, GfAdminMarketDataDetailModule, GfAssetProfileIconComponent, - GfCurrencySelectorModule, + GfCurrencySelectorComponent, GfPortfolioProportionChartModule, - GfValueModule, + GfValueComponent, MatButtonModule, MatCheckboxModule, MatDialogModule, diff --git a/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.module.ts b/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.module.ts index 888abfa56..24cc90dbe 100644 --- a/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.module.ts +++ b/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.module.ts @@ -1,4 +1,4 @@ -import { GfSymbolAutocompleteModule } from '@ghostfolio/ui/symbol-autocomplete'; +import { GfSymbolAutocompleteComponent } from '@ghostfolio/ui/symbol-autocomplete'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -16,7 +16,7 @@ import { CreateAssetProfileDialog } from './create-asset-profile-dialog.componen imports: [ CommonModule, FormsModule, - GfSymbolAutocompleteModule, + GfSymbolAutocompleteComponent, MatDialogModule, MatButtonModule, MatFormFieldModule, diff --git a/apps/client/src/app/components/admin-overview/admin-overview.module.ts b/apps/client/src/app/components/admin-overview/admin-overview.module.ts index a5a0a35e7..da49eb858 100644 --- a/apps/client/src/app/components/admin-overview/admin-overview.module.ts +++ b/apps/client/src/app/components/admin-overview/admin-overview.module.ts @@ -1,5 +1,5 @@ import { CacheService } from '@ghostfolio/client/services/cache.service'; -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -19,7 +19,7 @@ import { AdminOverviewComponent } from './admin-overview.component'; imports: [ CommonModule, FormsModule, - GfValueModule, + GfValueComponent, MatButtonModule, MatCardModule, MatMenuModule, diff --git a/apps/client/src/app/components/admin-users/admin-users.module.ts b/apps/client/src/app/components/admin-users/admin-users.module.ts index 0e232a4ed..3f4e9f2f7 100644 --- a/apps/client/src/app/components/admin-users/admin-users.module.ts +++ b/apps/client/src/app/components/admin-users/admin-users.module.ts @@ -1,5 +1,5 @@ -import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -14,8 +14,8 @@ import { AdminUsersComponent } from './admin-users.component'; exports: [], imports: [ CommonModule, - GfPremiumIndicatorModule, - GfValueModule, + GfPremiumIndicatorComponent, + GfValueComponent, MatButtonModule, MatMenuModule, MatTableModule diff --git a/apps/client/src/app/components/benchmark-comparator/benchmark-comparator.module.ts b/apps/client/src/app/components/benchmark-comparator/benchmark-comparator.module.ts index 2e6cae5cf..1bd4b0792 100644 --- a/apps/client/src/app/components/benchmark-comparator/benchmark-comparator.module.ts +++ b/apps/client/src/app/components/benchmark-comparator/benchmark-comparator.module.ts @@ -1,4 +1,4 @@ -import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; +import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; @@ -15,7 +15,7 @@ import { BenchmarkComparatorComponent } from './benchmark-comparator.component'; imports: [ CommonModule, FormsModule, - GfPremiumIndicatorModule, + GfPremiumIndicatorComponent, MatSelectModule, NgxSkeletonLoaderModule, ReactiveFormsModule, diff --git a/apps/client/src/app/components/header/header.module.ts b/apps/client/src/app/components/header/header.module.ts index 8ec816625..eb2069f32 100644 --- a/apps/client/src/app/components/header/header.module.ts +++ b/apps/client/src/app/components/header/header.module.ts @@ -1,7 +1,7 @@ import { LoginWithAccessTokenDialogModule } from '@ghostfolio/client/components/login-with-access-token-dialog/login-with-access-token-dialog.module'; import { GfAssistantModule } from '@ghostfolio/ui/assistant'; import { GfLogoModule } from '@ghostfolio/ui/logo'; -import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; +import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -19,7 +19,7 @@ import { HeaderComponent } from './header.component'; CommonModule, GfAssistantModule, GfLogoModule, - GfPremiumIndicatorModule, + GfPremiumIndicatorComponent, LoginWithAccessTokenDialogModule, MatButtonModule, MatMenuModule, diff --git a/apps/client/src/app/components/home-overview/home-overview.module.ts b/apps/client/src/app/components/home-overview/home-overview.module.ts index a4968e9c0..1a654b724 100644 --- a/apps/client/src/app/components/home-overview/home-overview.module.ts +++ b/apps/client/src/app/components/home-overview/home-overview.module.ts @@ -1,6 +1,6 @@ import { GfPortfolioPerformanceModule } from '@ghostfolio/client/components/portfolio-performance/portfolio-performance.module'; import { GfLineChartModule } from '@ghostfolio/ui/line-chart'; -import { GfNoTransactionsInfoModule } from '@ghostfolio/ui/no-transactions-info'; +import { GfNoTransactionsInfoComponent } from '@ghostfolio/ui/no-transactions-info'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -14,7 +14,7 @@ import { HomeOverviewComponent } from './home-overview.component'; imports: [ CommonModule, GfLineChartModule, - GfNoTransactionsInfoModule, + GfNoTransactionsInfoComponent, GfPortfolioPerformanceModule, MatButtonModule, RouterModule diff --git a/apps/client/src/app/components/portfolio-performance/portfolio-performance.module.ts b/apps/client/src/app/components/portfolio-performance/portfolio-performance.module.ts index b72f64b15..5c62cca87 100644 --- a/apps/client/src/app/components/portfolio-performance/portfolio-performance.module.ts +++ b/apps/client/src/app/components/portfolio-performance/portfolio-performance.module.ts @@ -1,4 +1,4 @@ -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -9,7 +9,7 @@ import { PortfolioPerformanceComponent } from './portfolio-performance.component @NgModule({ declarations: [PortfolioPerformanceComponent], exports: [PortfolioPerformanceComponent], - imports: [CommonModule, GfValueModule, NgxSkeletonLoaderModule], + imports: [CommonModule, GfValueComponent, NgxSkeletonLoaderModule], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class GfPortfolioPerformanceModule {} diff --git a/apps/client/src/app/components/portfolio-summary/portfolio-summary.module.ts b/apps/client/src/app/components/portfolio-summary/portfolio-summary.module.ts index be9f6fef8..603d5271a 100644 --- a/apps/client/src/app/components/portfolio-summary/portfolio-summary.module.ts +++ b/apps/client/src/app/components/portfolio-summary/portfolio-summary.module.ts @@ -1,4 +1,4 @@ -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -8,7 +8,7 @@ import { PortfolioSummaryComponent } from './portfolio-summary.component'; @NgModule({ declarations: [PortfolioSummaryComponent], exports: [PortfolioSummaryComponent], - imports: [CommonModule, GfValueModule], + imports: [CommonModule, GfValueComponent], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class GfPortfolioSummaryModule {} diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.module.ts b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.module.ts index 2a347500a..ddd090cdc 100644 --- a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.module.ts +++ b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.module.ts @@ -5,7 +5,7 @@ import { GfActivitiesTableComponent } from '@ghostfolio/ui/activities-table'; import { GfDataProviderCreditsModule } from '@ghostfolio/ui/data-provider-credits/data-provider-credits.module'; import { GfLineChartModule } from '@ghostfolio/ui/line-chart'; import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart'; -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -28,7 +28,7 @@ import { PositionDetailDialog } from './position-detail-dialog.component'; GfDialogHeaderModule, GfLineChartModule, GfPortfolioProportionChartModule, - GfValueModule, + GfValueComponent, MatButtonModule, MatChipsModule, MatDialogModule, diff --git a/apps/client/src/app/components/position/position.module.ts b/apps/client/src/app/components/position/position.module.ts index d21748a87..6483e274a 100644 --- a/apps/client/src/app/components/position/position.module.ts +++ b/apps/client/src/app/components/position/position.module.ts @@ -1,6 +1,6 @@ import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; import { GfTrendIndicatorComponent } from '@ghostfolio/ui/trend-indicator'; -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -19,7 +19,7 @@ import { PositionComponent } from './position.component'; GfPositionDetailDialogModule, GfSymbolModule, GfTrendIndicatorComponent, - GfValueModule, + GfValueComponent, MatDialogModule, NgxSkeletonLoaderModule, RouterModule diff --git a/apps/client/src/app/components/positions/positions.module.ts b/apps/client/src/app/components/positions/positions.module.ts index e9d1cb838..34bd38b2d 100644 --- a/apps/client/src/app/components/positions/positions.module.ts +++ b/apps/client/src/app/components/positions/positions.module.ts @@ -1,4 +1,4 @@ -import { GfNoTransactionsInfoModule } from '@ghostfolio/ui/no-transactions-info'; +import { GfNoTransactionsInfoComponent } from '@ghostfolio/ui/no-transactions-info'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -12,7 +12,7 @@ import { PositionsComponent } from './positions.component'; exports: [PositionsComponent], imports: [ CommonModule, - GfNoTransactionsInfoModule, + GfNoTransactionsInfoComponent, GfPositionModule, MatButtonModule ], diff --git a/apps/client/src/app/components/rules/rules.module.ts b/apps/client/src/app/components/rules/rules.module.ts index 48cd02388..3b82c6ab1 100644 --- a/apps/client/src/app/components/rules/rules.module.ts +++ b/apps/client/src/app/components/rules/rules.module.ts @@ -1,5 +1,5 @@ import { GfRuleModule } from '@ghostfolio/client/components/rule/rule.module'; -import { GfNoTransactionsInfoModule } from '@ghostfolio/ui/no-transactions-info'; +import { GfNoTransactionsInfoComponent } from '@ghostfolio/ui/no-transactions-info'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -14,7 +14,7 @@ import { RulesComponent } from './rules.component'; exports: [RulesComponent], imports: [ CommonModule, - GfNoTransactionsInfoModule, + GfNoTransactionsInfoComponent, GfPositionModule, GfRuleModule, MatButtonModule, diff --git a/apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.module.ts b/apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.module.ts index b67d2783c..36bc931b0 100644 --- a/apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.module.ts +++ b/apps/client/src/app/components/subscription-interstitial-dialog/subscription-interstitial-dialog.module.ts @@ -1,4 +1,4 @@ -import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; +import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -12,7 +12,7 @@ import { SubscriptionInterstitialDialog } from './subscription-interstitial-dial declarations: [SubscriptionInterstitialDialog], imports: [ CommonModule, - GfPremiumIndicatorModule, + GfPremiumIndicatorComponent, MatButtonModule, MatDialogModule, RouterModule diff --git a/apps/client/src/app/components/user-account-access/user-account-access.module.ts b/apps/client/src/app/components/user-account-access/user-account-access.module.ts index c8d1cc578..93270ee3c 100644 --- a/apps/client/src/app/components/user-account-access/user-account-access.module.ts +++ b/apps/client/src/app/components/user-account-access/user-account-access.module.ts @@ -1,5 +1,5 @@ import { GfPortfolioAccessTableModule } from '@ghostfolio/client/components/access-table/access-table.module'; -import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; +import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; @@ -17,7 +17,7 @@ import { UserAccountAccessComponent } from './user-account-access.component'; CommonModule, GfCreateOrUpdateAccessDialogModule, GfPortfolioAccessTableModule, - GfPremiumIndicatorModule, + GfPremiumIndicatorComponent, MatButtonModule, MatDialogModule, RouterModule diff --git a/apps/client/src/app/components/user-account-membership/user-account-membership.module.ts b/apps/client/src/app/components/user-account-membership/user-account-membership.module.ts index b5f91a521..cdb315ad9 100644 --- a/apps/client/src/app/components/user-account-membership/user-account-membership.module.ts +++ b/apps/client/src/app/components/user-account-membership/user-account-membership.module.ts @@ -1,6 +1,6 @@ import { GfMembershipCardModule } from '@ghostfolio/ui/membership-card'; -import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; @@ -16,8 +16,8 @@ import { UserAccountMembershipComponent } from './user-account-membership.compon imports: [ CommonModule, GfMembershipCardModule, - GfPremiumIndicatorModule, - GfValueModule, + GfPremiumIndicatorComponent, + GfValueComponent, MatButtonModule, MatCardModule, RouterModule diff --git a/apps/client/src/app/components/user-account-settings/user-account-settings.module.ts b/apps/client/src/app/components/user-account-settings/user-account-settings.module.ts index 50d092a1e..89626a96c 100644 --- a/apps/client/src/app/components/user-account-settings/user-account-settings.module.ts +++ b/apps/client/src/app/components/user-account-settings/user-account-settings.module.ts @@ -1,4 +1,4 @@ -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; @@ -18,7 +18,7 @@ import { UserAccountSettingsComponent } from './user-account-settings.component' imports: [ CommonModule, FormsModule, - GfValueModule, + GfValueComponent, MatButtonModule, MatCardModule, MatFormFieldModule, diff --git a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.module.ts b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.module.ts index 6838ef2bf..249715d61 100644 --- a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.module.ts +++ b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.module.ts @@ -1,5 +1,5 @@ import { GfAssetProfileIconComponent } from '@ghostfolio/client/components/asset-profile-icon/asset-profile-icon.component'; -import { GfCurrencySelectorModule } from '@ghostfolio/ui/currency-selector'; +import { GfCurrencySelectorComponent } from '@ghostfolio/ui/currency-selector'; import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; @@ -19,7 +19,7 @@ import { CreateOrUpdateAccountDialog } from './create-or-update-account-dialog.c CommonModule, FormsModule, GfAssetProfileIconComponent, - GfCurrencySelectorModule, + GfCurrencySelectorComponent, MatAutocompleteModule, MatButtonModule, MatCheckboxModule, diff --git a/apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.component.ts b/apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.component.ts index ab117d0a3..5820104d9 100644 --- a/apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.component.ts +++ b/apps/client/src/app/pages/blog/2022/11/black-friday-2022/black-friday-2022-page.component.ts @@ -1,4 +1,4 @@ -import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; +import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; @@ -6,7 +6,7 @@ import { RouterModule } from '@angular/router'; @Component({ host: { class: 'page' }, - imports: [GfPremiumIndicatorModule, MatButtonModule, RouterModule], + imports: [GfPremiumIndicatorComponent, MatButtonModule, RouterModule], selector: 'gf-black-friday-2022-page', standalone: true, templateUrl: './black-friday-2022-page.html' diff --git a/apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts b/apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts index 9f23f30ff..f0c88cfd4 100644 --- a/apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts +++ b/apps/client/src/app/pages/blog/2023/11/black-week-2023/black-week-2023-page.component.ts @@ -1,4 +1,4 @@ -import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; +import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { Component } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; @@ -6,7 +6,7 @@ import { RouterModule } from '@angular/router'; @Component({ host: { class: 'page' }, - imports: [GfPremiumIndicatorModule, MatButtonModule, RouterModule], + imports: [GfPremiumIndicatorComponent, MatButtonModule, RouterModule], selector: 'gf-black-week-2023-page', standalone: true, templateUrl: './black-week-2023-page.html' diff --git a/apps/client/src/app/pages/features/features-page.module.ts b/apps/client/src/app/pages/features/features-page.module.ts index ede263d94..fb5b00c14 100644 --- a/apps/client/src/app/pages/features/features-page.module.ts +++ b/apps/client/src/app/pages/features/features-page.module.ts @@ -1,4 +1,4 @@ -import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; +import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -13,7 +13,7 @@ import { FeaturesPageComponent } from './features-page.component'; imports: [ CommonModule, FeaturesPageRoutingModule, - GfPremiumIndicatorModule, + GfPremiumIndicatorComponent, MatButtonModule, MatCardModule ], diff --git a/apps/client/src/app/pages/landing/landing-page.module.ts b/apps/client/src/app/pages/landing/landing-page.module.ts index ef1d3d0ac..9f70313f5 100644 --- a/apps/client/src/app/pages/landing/landing-page.module.ts +++ b/apps/client/src/app/pages/landing/landing-page.module.ts @@ -1,7 +1,7 @@ import { GfWorldMapChartModule } from '@ghostfolio/client/components/world-map-chart/world-map-chart.module'; import { GfCarouselModule } from '@ghostfolio/ui/carousel'; import { GfLogoModule } from '@ghostfolio/ui/logo'; -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -18,7 +18,7 @@ import { LandingPageComponent } from './landing-page.component'; CommonModule, GfCarouselModule, GfLogoModule, - GfValueModule, + GfValueComponent, GfWorldMapChartModule, LandingPageRoutingModule, MatButtonModule, diff --git a/apps/client/src/app/pages/open/open-page.module.ts b/apps/client/src/app/pages/open/open-page.module.ts index ba8a94831..ab48f2d4a 100644 --- a/apps/client/src/app/pages/open/open-page.module.ts +++ b/apps/client/src/app/pages/open/open-page.module.ts @@ -1,4 +1,4 @@ -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -9,7 +9,12 @@ import { OpenPageComponent } from './open-page.component'; @NgModule({ declarations: [OpenPageComponent], - imports: [CommonModule, GfValueModule, MatCardModule, OpenPageRoutingModule], + imports: [ + CommonModule, + GfValueComponent, + MatCardModule, + OpenPageRoutingModule + ], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class OpenPageModule {} diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.module.ts b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.module.ts index 0d258f1ca..a4d28d0e0 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.module.ts +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.module.ts @@ -1,6 +1,6 @@ import { GfAssetProfileIconComponent } from '@ghostfolio/client/components/asset-profile-icon/asset-profile-icon.component'; -import { GfSymbolAutocompleteModule } from '@ghostfolio/ui/symbol-autocomplete/symbol-autocomplete.module'; -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfSymbolAutocompleteComponent } from '@ghostfolio/ui/symbol-autocomplete'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -23,8 +23,8 @@ import { CreateOrUpdateActivityDialog } from './create-or-update-activity-dialog CommonModule, FormsModule, GfAssetProfileIconComponent, - GfSymbolAutocompleteModule, - GfValueModule, + GfSymbolAutocompleteComponent, + GfValueComponent, MatAutocompleteModule, MatButtonModule, MatCheckboxModule, diff --git a/apps/client/src/app/pages/portfolio/allocations/allocations-page.module.ts b/apps/client/src/app/pages/portfolio/allocations/allocations-page.module.ts index efa362af6..22d08bcd6 100644 --- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.module.ts +++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.module.ts @@ -1,7 +1,7 @@ import { GfWorldMapChartModule } from '@ghostfolio/client/components/world-map-chart/world-map-chart.module'; import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart'; -import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -18,9 +18,9 @@ import { AllocationsPageComponent } from './allocations-page.component'; AllocationsPageRoutingModule, CommonModule, GfPortfolioProportionChartModule, - GfPremiumIndicatorModule, + GfPremiumIndicatorComponent, GfWorldMapChartModule, - GfValueModule, + GfValueComponent, MatCardModule, MatDialogModule, MatProgressBarModule diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.module.ts b/apps/client/src/app/pages/portfolio/analysis/analysis-page.module.ts index 1803a1cd7..5fb86efa8 100644 --- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.module.ts +++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.module.ts @@ -2,8 +2,8 @@ import { GfBenchmarkComparatorModule } from '@ghostfolio/client/components/bench import { GfInvestmentChartModule } from '@ghostfolio/client/components/investment-chart/investment-chart.module'; import { GfToggleModule } from '@ghostfolio/client/components/toggle/toggle.module'; import { GfActivitiesFilterModule } from '@ghostfolio/ui/activities-filter'; -import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -21,9 +21,9 @@ import { AnalysisPageComponent } from './analysis-page.component'; GfActivitiesFilterModule, GfBenchmarkComparatorModule, GfInvestmentChartModule, - GfPremiumIndicatorModule, + GfPremiumIndicatorComponent, GfToggleModule, - GfValueModule, + GfValueComponent, MatCardModule, NgxSkeletonLoaderModule ], diff --git a/apps/client/src/app/pages/portfolio/fire/fire-page.module.ts b/apps/client/src/app/pages/portfolio/fire/fire-page.module.ts index 2db99babd..60e3127d9 100644 --- a/apps/client/src/app/pages/portfolio/fire/fire-page.module.ts +++ b/apps/client/src/app/pages/portfolio/fire/fire-page.module.ts @@ -1,7 +1,7 @@ import { GfRulesModule } from '@ghostfolio/client/components/rules/rules.module'; import { GfFireCalculatorComponent } from '@ghostfolio/ui/fire-calculator'; -import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -16,9 +16,9 @@ import { FirePageComponent } from './fire-page.component'; CommonModule, FirePageRoutingModule, GfFireCalculatorComponent, - GfPremiumIndicatorModule, + GfPremiumIndicatorComponent, GfRulesModule, - GfValueModule, + GfValueComponent, NgxSkeletonLoaderModule ], schemas: [CUSTOM_ELEMENTS_SCHEMA] diff --git a/apps/client/src/app/pages/pricing/pricing-page.module.ts b/apps/client/src/app/pages/pricing/pricing-page.module.ts index 19bc99ce2..cb3766f13 100644 --- a/apps/client/src/app/pages/pricing/pricing-page.module.ts +++ b/apps/client/src/app/pages/pricing/pricing-page.module.ts @@ -1,4 +1,4 @@ -import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; +import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -14,7 +14,7 @@ import { PricingPageComponent } from './pricing-page.component'; declarations: [PricingPageComponent], imports: [ CommonModule, - GfPremiumIndicatorModule, + GfPremiumIndicatorComponent, MatButtonModule, MatCardModule, MatTooltipModule, diff --git a/apps/client/src/app/pages/public/public-page.module.ts b/apps/client/src/app/pages/public/public-page.module.ts index f894f7bf5..3cd5d8227 100644 --- a/apps/client/src/app/pages/public/public-page.module.ts +++ b/apps/client/src/app/pages/public/public-page.module.ts @@ -1,7 +1,7 @@ import { GfWorldMapChartModule } from '@ghostfolio/client/components/world-map-chart/world-map-chart.module'; import { GfHoldingsTableComponent } from '@ghostfolio/ui/holdings-table'; import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart'; -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -17,7 +17,7 @@ import { PublicPageComponent } from './public-page.component'; CommonModule, GfHoldingsTableComponent, GfPortfolioProportionChartModule, - GfValueModule, + GfValueComponent, GfWorldMapChartModule, MatButtonModule, MatCardModule, diff --git a/libs/ui/src/lib/account-balances/account-balances.module.ts b/libs/ui/src/lib/account-balances/account-balances.module.ts index a789dcc39..e7c7aaab7 100644 --- a/libs/ui/src/lib/account-balances/account-balances.module.ts +++ b/libs/ui/src/lib/account-balances/account-balances.module.ts @@ -1,4 +1,4 @@ -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -14,7 +14,7 @@ import { AccountBalancesComponent } from './account-balances.component'; exports: [AccountBalancesComponent], imports: [ CommonModule, - GfValueModule, + GfValueComponent, MatButtonModule, MatMenuModule, MatSortModule, diff --git a/libs/ui/src/lib/activities-table/activities-table.component.ts b/libs/ui/src/lib/activities-table/activities-table.component.ts index df8fdec1b..d7511df97 100644 --- a/libs/ui/src/lib/activities-table/activities-table.component.ts +++ b/libs/ui/src/lib/activities-table/activities-table.component.ts @@ -6,8 +6,8 @@ import { getDateFormatString, getLocale } from '@ghostfolio/common/helper'; import { UniqueAsset } from '@ghostfolio/common/interfaces'; import { OrderWithAccount } from '@ghostfolio/common/types'; import { GfActivityTypeModule } from '@ghostfolio/ui/activity-type'; -import { GfNoTransactionsInfoModule } from '@ghostfolio/ui/no-transactions-info'; -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfNoTransactionsInfoComponent } from '@ghostfolio/ui/no-transactions-info'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { SelectionModel } from '@angular/cdk/collections'; import { CommonModule } from '@angular/common'; @@ -52,9 +52,9 @@ import { Subject, Subscription, takeUntil } from 'rxjs'; CommonModule, GfActivityTypeModule, GfAssetProfileIconComponent, - GfNoTransactionsInfoModule, + GfNoTransactionsInfoComponent, GfSymbolModule, - GfValueModule, + GfValueComponent, MatButtonModule, MatCheckboxModule, MatMenuModule, diff --git a/libs/ui/src/lib/benchmark/benchmark.module.ts b/libs/ui/src/lib/benchmark/benchmark.module.ts index 67b64ec6d..91f5be938 100644 --- a/libs/ui/src/lib/benchmark/benchmark.module.ts +++ b/libs/ui/src/lib/benchmark/benchmark.module.ts @@ -4,7 +4,7 @@ import { MatTableModule } from '@angular/material/table'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { GfTrendIndicatorComponent } from '../trend-indicator'; -import { GfValueModule } from '../value'; +import { GfValueComponent } from '../value'; import { BenchmarkComponent } from './benchmark.component'; @NgModule({ @@ -13,7 +13,7 @@ import { BenchmarkComponent } from './benchmark.component'; imports: [ CommonModule, GfTrendIndicatorComponent, - GfValueModule, + GfValueComponent, MatTableModule, NgxSkeletonLoaderModule ], diff --git a/libs/ui/src/lib/currency-selector/currency-selector.component.ts b/libs/ui/src/lib/currency-selector/currency-selector.component.ts index 8c9415689..a0ed3c88a 100644 --- a/libs/ui/src/lib/currency-selector/currency-selector.component.ts +++ b/libs/ui/src/lib/currency-selector/currency-selector.component.ts @@ -2,7 +2,9 @@ import { Currency } from '@ghostfolio/common/interfaces'; import { AbstractMatFormField } from '@ghostfolio/ui/shared/abstract-mat-form-field'; import { FocusMonitor } from '@angular/cdk/a11y'; +import { CommonModule } from '@angular/common'; import { + CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Component, @@ -12,13 +14,23 @@ import { OnInit, ViewChild } from '@angular/core'; -import { FormControl, FormGroupDirective, NgControl } from '@angular/forms'; +import { + FormControl, + FormGroupDirective, + FormsModule, + NgControl, + ReactiveFormsModule +} from '@angular/forms'; import { MatAutocomplete, + MatAutocompleteModule, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete'; -import { MatFormFieldControl } from '@angular/material/form-field'; -import { MatInput } from '@angular/material/input'; +import { + MatFormFieldControl, + MatFormFieldModule +} from '@angular/material/form-field'; +import { MatInput, MatInputModule } from '@angular/material/input'; import { Subject } from 'rxjs'; import { map, startWith, takeUntil } from 'rxjs/operators'; @@ -28,17 +40,27 @@ import { map, startWith, takeUntil } from 'rxjs/operators'; '[attr.aria-describedBy]': 'describedBy', '[id]': 'id' }, + imports: [ + CommonModule, + FormsModule, + MatAutocompleteModule, + MatFormFieldModule, + MatInputModule, + ReactiveFormsModule + ], providers: [ { provide: MatFormFieldControl, - useExisting: CurrencySelectorComponent + useExisting: GfCurrencySelectorComponent } ], + schemas: [CUSTOM_ELEMENTS_SCHEMA], selector: 'gf-currency-selector', + standalone: true, styleUrls: ['./currency-selector.component.scss'], templateUrl: 'currency-selector.component.html' }) -export class CurrencySelectorComponent +export class GfCurrencySelectorComponent extends AbstractMatFormField implements OnInit, OnDestroy { diff --git a/libs/ui/src/lib/currency-selector/currency-selector.module.ts b/libs/ui/src/lib/currency-selector/currency-selector.module.ts deleted file mode 100644 index ac4d12096..000000000 --- a/libs/ui/src/lib/currency-selector/currency-selector.module.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatAutocompleteModule } from '@angular/material/autocomplete'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; - -import { CurrencySelectorComponent } from './currency-selector.component'; - -@NgModule({ - declarations: [CurrencySelectorComponent], - exports: [CurrencySelectorComponent], - imports: [ - CommonModule, - FormsModule, - MatAutocompleteModule, - MatFormFieldModule, - MatInputModule, - ReactiveFormsModule - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfCurrencySelectorModule {} diff --git a/libs/ui/src/lib/currency-selector/index.ts b/libs/ui/src/lib/currency-selector/index.ts index 5790d8acc..2faa42b80 100644 --- a/libs/ui/src/lib/currency-selector/index.ts +++ b/libs/ui/src/lib/currency-selector/index.ts @@ -1 +1 @@ -export * from './currency-selector.module'; +export * from './currency-selector.component'; diff --git a/libs/ui/src/lib/holdings-table/holdings-table.component.ts b/libs/ui/src/lib/holdings-table/holdings-table.component.ts index 063582139..9d568abf7 100644 --- a/libs/ui/src/lib/holdings-table/holdings-table.component.ts +++ b/libs/ui/src/lib/holdings-table/holdings-table.component.ts @@ -3,8 +3,8 @@ import { GfPositionDetailDialogModule } from '@ghostfolio/client/components/posi import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; import { getLocale } from '@ghostfolio/common/helper'; import { PortfolioPosition, UniqueAsset } from '@ghostfolio/common/interfaces'; -import { GfNoTransactionsInfoModule } from '@ghostfolio/ui/no-transactions-info'; -import { GfValueModule } from '@ghostfolio/ui/value'; +import { GfNoTransactionsInfoComponent } from '@ghostfolio/ui/no-transactions-info'; +import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { @@ -32,10 +32,10 @@ import { Subject, Subscription } from 'rxjs'; imports: [ CommonModule, GfAssetProfileIconComponent, - GfNoTransactionsInfoModule, + GfNoTransactionsInfoComponent, GfPositionDetailDialogModule, GfSymbolModule, - GfValueModule, + GfValueComponent, MatButtonModule, MatDialogModule, MatPaginatorModule, diff --git a/libs/ui/src/lib/no-transactions-info/index.ts b/libs/ui/src/lib/no-transactions-info/index.ts index 8a907c9ec..956d0304d 100644 --- a/libs/ui/src/lib/no-transactions-info/index.ts +++ b/libs/ui/src/lib/no-transactions-info/index.ts @@ -1 +1 @@ -export * from './no-transactions-info.module'; +export * from './no-transactions-info.component'; diff --git a/libs/ui/src/lib/no-transactions-info/no-transactions-info.component.ts b/libs/ui/src/lib/no-transactions-info/no-transactions-info.component.ts index 8910943b0..f1a17d777 100644 --- a/libs/ui/src/lib/no-transactions-info/no-transactions-info.component.ts +++ b/libs/ui/src/lib/no-transactions-info/no-transactions-info.component.ts @@ -1,17 +1,26 @@ +import { CommonModule } from '@angular/common'; import { + CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, HostBinding, Input } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { RouterModule } from '@angular/router'; + +import { GfLogoModule } from '../logo'; @Component({ - selector: 'gf-no-transactions-info-indicator', changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './no-transactions-info.component.html', - styleUrls: ['./no-transactions-info.component.scss'] + imports: [CommonModule, GfLogoModule, MatButtonModule, RouterModule], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + selector: 'gf-no-transactions-info-indicator', + standalone: true, + styleUrls: ['./no-transactions-info.component.scss'], + templateUrl: './no-transactions-info.component.html' }) -export class NoTransactionsInfoComponent { +export class GfNoTransactionsInfoComponent { @HostBinding('class.has-border') @Input() hasBorder = true; public constructor() {} diff --git a/libs/ui/src/lib/no-transactions-info/no-transactions-info.module.ts b/libs/ui/src/lib/no-transactions-info/no-transactions-info.module.ts deleted file mode 100644 index 03363abc8..000000000 --- a/libs/ui/src/lib/no-transactions-info/no-transactions-info.module.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { GfLogoModule } from '@ghostfolio/ui/logo'; - -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { MatButtonModule } from '@angular/material/button'; -import { RouterModule } from '@angular/router'; - -import { NoTransactionsInfoComponent } from './no-transactions-info.component'; - -@NgModule({ - declarations: [NoTransactionsInfoComponent], - exports: [NoTransactionsInfoComponent], - imports: [CommonModule, GfLogoModule, MatButtonModule, RouterModule], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfNoTransactionsInfoModule {} diff --git a/libs/ui/src/lib/premium-indicator/index.ts b/libs/ui/src/lib/premium-indicator/index.ts index 593823bbd..a61db2559 100644 --- a/libs/ui/src/lib/premium-indicator/index.ts +++ b/libs/ui/src/lib/premium-indicator/index.ts @@ -1 +1 @@ -export * from './premium-indicator.module'; +export * from './premium-indicator.component'; diff --git a/libs/ui/src/lib/premium-indicator/premium-indicator.component.ts b/libs/ui/src/lib/premium-indicator/premium-indicator.component.ts index 3711a28dd..ff2b158b5 100644 --- a/libs/ui/src/lib/premium-indicator/premium-indicator.component.ts +++ b/libs/ui/src/lib/premium-indicator/premium-indicator.component.ts @@ -1,12 +1,22 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { + CUSTOM_ELEMENTS_SCHEMA, + ChangeDetectionStrategy, + Component, + Input +} from '@angular/core'; +import { RouterModule } from '@angular/router'; @Component({ - selector: 'gf-premium-indicator', changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './premium-indicator.component.html', - styleUrls: ['./premium-indicator.component.scss'] + imports: [CommonModule, RouterModule], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + selector: 'gf-premium-indicator', + standalone: true, + styleUrls: ['./premium-indicator.component.scss'], + templateUrl: './premium-indicator.component.html' }) -export class PremiumIndicatorComponent { +export class GfPremiumIndicatorComponent { @Input() enableLink = true; public constructor() {} diff --git a/libs/ui/src/lib/premium-indicator/premium-indicator.module.ts b/libs/ui/src/lib/premium-indicator/premium-indicator.module.ts deleted file mode 100644 index f79dc2f60..000000000 --- a/libs/ui/src/lib/premium-indicator/premium-indicator.module.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; - -import { PremiumIndicatorComponent } from './premium-indicator.component'; - -@NgModule({ - declarations: [PremiumIndicatorComponent], - exports: [PremiumIndicatorComponent], - imports: [CommonModule, RouterModule], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfPremiumIndicatorModule {} diff --git a/libs/ui/src/lib/symbol-autocomplete/index.ts b/libs/ui/src/lib/symbol-autocomplete/index.ts index 7271d1ca9..2964effa0 100644 --- a/libs/ui/src/lib/symbol-autocomplete/index.ts +++ b/libs/ui/src/lib/symbol-autocomplete/index.ts @@ -1 +1 @@ -export * from './symbol-autocomplete.module'; +export * from './symbol-autocomplete.component'; diff --git a/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts b/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts index d25a15a28..7da62d9df 100644 --- a/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts +++ b/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts @@ -1,10 +1,13 @@ import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; +import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; import { DataService } from '@ghostfolio/client/services/data.service'; import { translate } from '@ghostfolio/ui/i18n'; import { AbstractMatFormField } from '@ghostfolio/ui/shared/abstract-mat-form-field'; import { FocusMonitor } from '@angular/cdk/a11y'; +import { CommonModule } from '@angular/common'; import { + CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Component, @@ -14,13 +17,23 @@ import { OnInit, ViewChild } from '@angular/core'; -import { FormControl, NgControl } from '@angular/forms'; +import { + FormControl, + FormsModule, + NgControl, + ReactiveFormsModule +} from '@angular/forms'; import { MatAutocomplete, + MatAutocompleteModule, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete'; -import { MatFormFieldControl } from '@angular/material/form-field'; -import { MatInput } from '@angular/material/input'; +import { + MatFormFieldControl, + MatFormFieldModule +} from '@angular/material/form-field'; +import { MatInput, MatInputModule } from '@angular/material/input'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { isString } from 'lodash'; import { Subject, tap } from 'rxjs'; import { @@ -31,23 +44,38 @@ import { takeUntil } from 'rxjs/operators'; +import { GfPremiumIndicatorComponent } from '../premium-indicator'; + @Component({ changeDetection: ChangeDetectionStrategy.OnPush, host: { '[attr.aria-describedBy]': 'describedBy', '[id]': 'id' }, - selector: 'gf-symbol-autocomplete', - styleUrls: ['./symbol-autocomplete.component.scss'], - templateUrl: 'symbol-autocomplete.component.html', + imports: [ + CommonModule, + FormsModule, + GfPremiumIndicatorComponent, + GfSymbolModule, + MatAutocompleteModule, + MatFormFieldModule, + MatInputModule, + MatProgressSpinnerModule, + ReactiveFormsModule + ], providers: [ { provide: MatFormFieldControl, - useExisting: SymbolAutocompleteComponent + useExisting: GfSymbolAutocompleteComponent } - ] + ], + selector: 'gf-symbol-autocomplete', + schemas: [CUSTOM_ELEMENTS_SCHEMA], + standalone: true, + styleUrls: ['./symbol-autocomplete.component.scss'], + templateUrl: 'symbol-autocomplete.component.html' }) -export class SymbolAutocompleteComponent +export class GfSymbolAutocompleteComponent extends AbstractMatFormField implements OnInit, OnDestroy { diff --git a/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.module.ts b/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.module.ts deleted file mode 100644 index cdb6cc97a..000000000 --- a/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.module.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; -import { GfPremiumIndicatorModule } from '@ghostfolio/ui/premium-indicator'; -import { SymbolAutocompleteComponent } from '@ghostfolio/ui/symbol-autocomplete/symbol-autocomplete.component'; - -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatAutocompleteModule } from '@angular/material/autocomplete'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; - -@NgModule({ - declarations: [SymbolAutocompleteComponent], - exports: [SymbolAutocompleteComponent], - imports: [ - CommonModule, - FormsModule, - GfPremiumIndicatorModule, - GfSymbolModule, - MatAutocompleteModule, - MatFormFieldModule, - MatInputModule, - MatProgressSpinnerModule, - ReactiveFormsModule - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfSymbolAutocompleteModule {} diff --git a/libs/ui/src/lib/value/index.ts b/libs/ui/src/lib/value/index.ts index 1e8ac4def..9dc866865 100644 --- a/libs/ui/src/lib/value/index.ts +++ b/libs/ui/src/lib/value/index.ts @@ -1 +1 @@ -export * from './value.module'; +export * from './value.component'; diff --git a/libs/ui/src/lib/value/value.component.ts b/libs/ui/src/lib/value/value.component.ts index 13675403f..28cb3c90a 100644 --- a/libs/ui/src/lib/value/value.component.ts +++ b/libs/ui/src/lib/value/value.component.ts @@ -1,20 +1,26 @@ import { getLocale } from '@ghostfolio/common/helper'; +import { CommonModule } from '@angular/common'; import { + CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core'; import { isNumber } from 'lodash'; +import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; @Component({ - selector: 'gf-value', changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './value.component.html', - styleUrls: ['./value.component.scss'] + imports: [CommonModule, NgxSkeletonLoaderModule], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + selector: 'gf-value', + standalone: true, + styleUrls: ['./value.component.scss'], + templateUrl: './value.component.html' }) -export class ValueComponent implements OnChanges { +export class GfValueComponent implements OnChanges { @Input() colorizeSign = false; @Input() icon = ''; @Input() isAbsolute = false; diff --git a/libs/ui/src/lib/value/value.module.ts b/libs/ui/src/lib/value/value.module.ts deleted file mode 100644 index 1cb91050e..000000000 --- a/libs/ui/src/lib/value/value.module.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; - -import { ValueComponent } from './value.component'; - -@NgModule({ - declarations: [ValueComponent], - exports: [ValueComponent], - imports: [CommonModule, NgxSkeletonLoaderModule], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfValueModule {} From dba73d80a3ab8c6bf0dfd5cf1c36423ff6f2f1f8 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 19 Apr 2024 20:31:38 +0200 Subject: [PATCH 136/203] Improve logging (#3300) --- .../calculator/twr/portfolio-calculator.ts | 74 +++++++++---------- 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index 7dcef89cb..1567483bb 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -396,11 +396,46 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { if (PortfolioCalculator.ENABLE_LOGGING) { console.log(); console.log(); - console.log(i + 1, order.type, order.itemType); + console.log( + i + 1, + order.date, + order.type, + order.itemType ? `(${order.itemType})` : '' + ); } const exchangeRateAtOrderDate = exchangeRates[order.date]; + if (order.type === 'DIVIDEND') { + const dividend = order.quantity.mul(order.unitPrice); + + totalDividend = totalDividend.plus(dividend); + totalDividendInBaseCurrency = totalDividendInBaseCurrency.plus( + dividend.mul(exchangeRateAtOrderDate ?? 1) + ); + } else if (order.type === 'INTEREST') { + const interest = order.quantity.mul(order.unitPrice); + + totalInterest = totalInterest.plus(interest); + totalInterestInBaseCurrency = totalInterestInBaseCurrency.plus( + interest.mul(exchangeRateAtOrderDate ?? 1) + ); + } else if (order.type === 'ITEM') { + const valuables = order.quantity.mul(order.unitPrice); + + totalValuables = totalValuables.plus(valuables); + totalValuablesInBaseCurrency = totalValuablesInBaseCurrency.plus( + valuables.mul(exchangeRateAtOrderDate ?? 1) + ); + } else if (order.type === 'LIABILITY') { + const liabilities = order.quantity.mul(order.unitPrice); + + totalLiabilities = totalLiabilities.plus(liabilities); + totalLiabilitiesInBaseCurrency = totalLiabilitiesInBaseCurrency.plus( + liabilities.mul(exchangeRateAtOrderDate ?? 1) + ); + } + if (order.itemType === 'start') { // Take the unit price of the order as the market price if there are no // orders of this symbol before the start date @@ -483,13 +518,6 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { } if (PortfolioCalculator.ENABLE_LOGGING) { - console.log('totalInvestment', totalInvestment.toNumber()); - - console.log( - 'totalInvestmentWithCurrencyEffect', - totalInvestmentWithCurrencyEffect.toNumber() - ); - console.log('order.quantity', order.quantity.toNumber()); console.log('transactionInvestment', transactionInvestment.toNumber()); @@ -536,36 +564,6 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { totalUnits = totalUnits.plus(order.quantity.mul(getFactor(order.type))); - if (order.type === 'DIVIDEND') { - const dividend = order.quantity.mul(order.unitPrice); - - totalDividend = totalDividend.plus(dividend); - totalDividendInBaseCurrency = totalDividendInBaseCurrency.plus( - dividend.mul(exchangeRateAtOrderDate ?? 1) - ); - } else if (order.type === 'INTEREST') { - const interest = order.quantity.mul(order.unitPrice); - - totalInterest = totalInterest.plus(interest); - totalInterestInBaseCurrency = totalInterestInBaseCurrency.plus( - interest.mul(exchangeRateAtOrderDate ?? 1) - ); - } else if (order.type === 'ITEM') { - const valuables = order.quantity.mul(order.unitPrice); - - totalValuables = totalValuables.plus(valuables); - totalValuablesInBaseCurrency = totalValuablesInBaseCurrency.plus( - valuables.mul(exchangeRateAtOrderDate ?? 1) - ); - } else if (order.type === 'LIABILITY') { - const liabilities = order.quantity.mul(order.unitPrice); - - totalLiabilities = totalLiabilities.plus(liabilities); - totalLiabilitiesInBaseCurrency = totalLiabilitiesInBaseCurrency.plus( - liabilities.mul(exchangeRateAtOrderDate ?? 1) - ); - } - const valueOfInvestment = totalUnits.mul(order.unitPriceInBaseCurrency); const valueOfInvestmentWithCurrencyEffect = totalUnits.mul( From ab86dd53188acadf7c3d0a9ccdd9716a31e93490 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 19 Apr 2024 20:43:52 +0200 Subject: [PATCH 137/203] Add Home Assistant (#3291) --- README.md | 2 +- .../src/app/pages/faq/self-hosting/self-hosting-page.html | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 234e2c941..2c8cb664c 100644 --- a/README.md +++ b/README.md @@ -144,7 +144,7 @@ docker compose --env-file ./.env -f docker/docker-compose.build.yml up -d ### Home Server Systems (Community) -Ghostfolio is available for various home server systems, including [CasaOS](https://github.com/bigbeartechworld/big-bear-casaos), [Runtipi](https://www.runtipi.io/docs/apps-available), [TrueCharts](https://truecharts.org/charts/stable/ghostfolio), [Umbrel](https://apps.umbrel.com/app/ghostfolio), and [Unraid](https://unraid.net/community/apps?q=ghostfolio). +Ghostfolio is available for various home server systems, including [CasaOS](https://github.com/bigbeartechworld/big-bear-casaos), Home Assistant, [Runtipi](https://www.runtipi.io/docs/apps-available), [TrueCharts](https://truecharts.org/charts/stable/ghostfolio), [Umbrel](https://apps.umbrel.com/app/ghostfolio), and [Unraid](https://unraid.net/community/apps?q=ghostfolio). ## Development diff --git a/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html b/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html index 0272f535e..7df2cdbe9 100644 --- a/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html +++ b/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html @@ -30,7 +30,8 @@ systems, including CasaOS, Runtipi, + >, Home Assistant, + Runtipi, TrueCharts, Umbrel, and From b6ad362850c504d4ced5f2c9e76ec28681c0abf2 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 19 Apr 2024 20:44:28 +0200 Subject: [PATCH 138/203] Feature/remove date range support in activities table on portfolio activities page (#3301) * Remove date range support * Update changelog --- CHANGELOG.md | 6 ++++++ .../pages/portfolio/activities/activities-page.component.ts | 3 --- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index afd01ab81..81a6da6d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- Removed the date range support in the activities table on the portfolio activities page (experimental) + ## 2.73.0 - 2024-04-17 ### Added diff --git a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts index 3e45ec037..190fc673e 100644 --- a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts @@ -124,9 +124,6 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit { this.dataService .fetchActivities({ filters: this.userService.getFilters(), - range: this.user?.settings?.isExperimentalFeatures - ? this.user?.settings?.dateRange - : undefined, skip: this.pageIndex * this.pageSize, sortColumn: this.sortColumn, sortDirection: this.sortDirection, From bed9ae916cad617caa240f1f1205a9d2375a3fcd Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 19 Apr 2024 20:57:47 +0200 Subject: [PATCH 139/203] Migrate UI components to standalone (#3302) --- apps/client/src/app/app.module.ts | 4 +- .../account-detail-dialog.module.ts | 4 +- .../admin-market-data-detail.module.ts | 4 +- .../admin-market-data.module.ts | 4 +- .../asset-profile-dialog.module.ts | 4 +- .../app/components/header/header.component.ts | 4 +- .../app/components/header/header.module.ts | 8 ++-- .../home-market/home-market.module.ts | 8 ++-- .../home-overview/home-overview.module.ts | 4 +- .../position-detail-dialog.module.ts | 12 ++--- .../user-account-membership.module.ts | 4 +- .../app/pages/landing/landing-page.module.ts | 8 ++-- .../allocations/allocations-page.module.ts | 4 +- .../analysis/analysis-page.module.ts | 4 +- .../app/pages/public/public-page.module.ts | 4 +- .../pages/register/register-page.module.ts | 4 +- .../pages/webauthn/webauthn-page.module.ts | 4 +- .../account-balances.component.ts | 24 ++++++++-- .../account-balances.module.ts | 25 ----------- libs/ui/src/lib/account-balances/index.ts | 2 +- .../activities-filter.component.ts | 25 +++++++++-- .../activities-filter.module.ts | 29 ------------ libs/ui/src/lib/activities-filter/index.ts | 2 +- .../activities-table.component.ts | 4 +- .../activity-type/activity-type.component.ts | 7 ++- .../lib/activity-type/activity-type.module.ts | 12 ----- libs/ui/src/lib/activity-type/index.ts | 2 +- .../assistant-list-item.component.ts | 14 ++++-- .../assistant-list-item.module.ts | 14 ------ .../src/lib/assistant/assistant.component.ts | 45 +++++++++++++++---- libs/ui/src/lib/assistant/assistant.module.ts | 32 ------------- libs/ui/src/lib/assistant/index.ts | 2 +- .../src/lib/benchmark/benchmark.component.ts | 24 ++++++++-- libs/ui/src/lib/benchmark/benchmark.module.ts | 22 --------- libs/ui/src/lib/benchmark/index.ts | 2 +- .../ui/src/lib/carousel/carousel.component.ts | 8 +++- libs/ui/src/lib/carousel/carousel.module.ts | 14 ------ libs/ui/src/lib/carousel/index.ts | 2 +- .../data-provider-credits.component.ts | 13 +++++- .../data-provider-credits.module.ts | 12 ----- .../ui/src/lib/data-provider-credits/index.ts | 2 +- libs/ui/src/lib/line-chart/index.ts | 2 +- .../lib/line-chart/line-chart.component.ts | 14 ++++-- .../src/lib/line-chart/line-chart.module.ts | 12 ----- libs/ui/src/lib/logo/index.ts | 2 +- libs/ui/src/lib/logo/logo.component.ts | 13 ++++-- libs/ui/src/lib/logo/logo.module.ts | 12 ----- libs/ui/src/lib/membership-card/index.ts | 2 +- .../membership-card.component.ts | 16 ++++++- .../membership-card/membership-card.module.ts | 15 ------- .../no-transactions-info.component.ts | 4 +- .../lib/portfolio-proportion-chart/index.ts | 2 +- .../portfolio-proportion-chart.component.ts | 12 +++-- .../portfolio-proportion-chart.module.ts | 12 ----- 54 files changed, 233 insertions(+), 311 deletions(-) delete mode 100644 libs/ui/src/lib/account-balances/account-balances.module.ts delete mode 100644 libs/ui/src/lib/activities-filter/activities-filter.module.ts delete mode 100644 libs/ui/src/lib/activity-type/activity-type.module.ts delete mode 100644 libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.module.ts delete mode 100644 libs/ui/src/lib/assistant/assistant.module.ts delete mode 100644 libs/ui/src/lib/benchmark/benchmark.module.ts delete mode 100644 libs/ui/src/lib/carousel/carousel.module.ts delete mode 100644 libs/ui/src/lib/data-provider-credits/data-provider-credits.module.ts delete mode 100644 libs/ui/src/lib/line-chart/line-chart.module.ts delete mode 100644 libs/ui/src/lib/logo/logo.module.ts delete mode 100644 libs/ui/src/lib/membership-card/membership-card.module.ts delete mode 100644 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.module.ts diff --git a/apps/client/src/app/app.module.ts b/apps/client/src/app/app.module.ts index f8b52faa9..fac59bf48 100644 --- a/apps/client/src/app/app.module.ts +++ b/apps/client/src/app/app.module.ts @@ -1,4 +1,4 @@ -import { GfLogoModule } from '@ghostfolio/ui/logo'; +import { GfLogoComponent } from '@ghostfolio/ui/logo'; import { Platform } from '@angular/cdk/platform'; import { HttpClientModule } from '@angular/common/http'; @@ -43,7 +43,7 @@ export function NgxStripeFactory(): string { BrowserAnimationsModule, BrowserModule, GfHeaderModule, - GfLogoModule, + GfLogoComponent, GfSubscriptionInterstitialDialogModule, HttpClientModule, MarkdownModule.forRoot(), diff --git a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.module.ts b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.module.ts index 4ab7eb058..e404aaad1 100644 --- a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.module.ts +++ b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.module.ts @@ -1,7 +1,7 @@ import { GfDialogFooterModule } from '@ghostfolio/client/components/dialog-footer/dialog-footer.module'; import { GfDialogHeaderModule } from '@ghostfolio/client/components/dialog-header/dialog-header.module'; import { GfInvestmentChartModule } from '@ghostfolio/client/components/investment-chart/investment-chart.module'; -import { GfAccountBalancesModule } from '@ghostfolio/ui/account-balances'; +import { GfAccountBalancesComponent } from '@ghostfolio/ui/account-balances'; import { GfActivitiesTableComponent } from '@ghostfolio/ui/activities-table'; import { GfHoldingsTableComponent } from '@ghostfolio/ui/holdings-table'; import { GfValueComponent } from '@ghostfolio/ui/value'; @@ -19,7 +19,7 @@ import { AccountDetailDialog } from './account-detail-dialog.component'; declarations: [AccountDetailDialog], imports: [ CommonModule, - GfAccountBalancesModule, + GfAccountBalancesComponent, GfActivitiesTableComponent, GfDialogFooterModule, GfDialogHeaderModule, diff --git a/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.module.ts b/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.module.ts index eafc24c90..9f4e1b3bc 100644 --- a/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.module.ts +++ b/apps/client/src/app/components/admin-market-data-detail/admin-market-data-detail.module.ts @@ -1,4 +1,4 @@ -import { GfLineChartModule } from '@ghostfolio/ui/line-chart'; +import { GfLineChartComponent } from '@ghostfolio/ui/line-chart'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -9,7 +9,7 @@ import { GfMarketDataDetailDialogModule } from './market-data-detail-dialog/mark @NgModule({ declarations: [AdminMarketDataDetailComponent], exports: [AdminMarketDataDetailComponent], - imports: [CommonModule, GfLineChartModule, GfMarketDataDetailDialogModule], + imports: [CommonModule, GfLineChartComponent, GfMarketDataDetailDialogModule], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class GfAdminMarketDataDetailModule {} diff --git a/apps/client/src/app/components/admin-market-data/admin-market-data.module.ts b/apps/client/src/app/components/admin-market-data/admin-market-data.module.ts index 622a01cdb..73bf47f7f 100644 --- a/apps/client/src/app/components/admin-market-data/admin-market-data.module.ts +++ b/apps/client/src/app/components/admin-market-data/admin-market-data.module.ts @@ -1,5 +1,5 @@ import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; -import { GfActivitiesFilterModule } from '@ghostfolio/ui/activities-filter'; +import { GfActivitiesFilterComponent } from '@ghostfolio/ui/activities-filter'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -20,7 +20,7 @@ import { GfCreateAssetProfileDialogModule } from './create-asset-profile-dialog/ declarations: [AdminMarketDataComponent], imports: [ CommonModule, - GfActivitiesFilterModule, + GfActivitiesFilterComponent, GfAssetProfileDialogModule, GfCreateAssetProfileDialogModule, GfSymbolModule, diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts index 544213c05..a872f567f 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.module.ts @@ -2,7 +2,7 @@ import { GfAdminMarketDataDetailModule } from '@ghostfolio/client/components/adm import { AdminMarketDataService } from '@ghostfolio/client/components/admin-market-data/admin-market-data.service'; import { GfAssetProfileIconComponent } from '@ghostfolio/client/components/asset-profile-icon/asset-profile-icon.component'; import { GfCurrencySelectorComponent } from '@ghostfolio/ui/currency-selector'; -import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart'; +import { GfPortfolioProportionChartComponent } from '@ghostfolio/ui/portfolio-proportion-chart'; import { GfValueComponent } from '@ghostfolio/ui/value'; import { TextFieldModule } from '@angular/cdk/text-field'; @@ -27,7 +27,7 @@ import { AssetProfileDialog } from './asset-profile-dialog.component'; GfAdminMarketDataDetailModule, GfAssetProfileIconComponent, GfCurrencySelectorComponent, - GfPortfolioProportionChartModule, + GfPortfolioProportionChartComponent, GfValueComponent, MatButtonModule, MatCheckboxModule, diff --git a/apps/client/src/app/components/header/header.component.ts b/apps/client/src/app/components/header/header.component.ts index 1251853e7..dd1e3cc3c 100644 --- a/apps/client/src/app/components/header/header.component.ts +++ b/apps/client/src/app/components/header/header.component.ts @@ -12,7 +12,7 @@ import { UserService } from '@ghostfolio/client/services/user/user.service'; import { Filter, InfoItem, User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { DateRange } from '@ghostfolio/common/types'; -import { AssistantComponent } from '@ghostfolio/ui/assistant/assistant.component'; +import { GfAssistantComponent } from '@ghostfolio/ui/assistant/assistant.component'; import { ChangeDetectionStrategy, @@ -62,7 +62,7 @@ export class HeaderComponent implements OnChanges { @Output() signOut = new EventEmitter(); - @ViewChild('assistant') assistantElement: AssistantComponent; + @ViewChild('assistant') assistantElement: GfAssistantComponent; @ViewChild('assistantTrigger') assistentMenuTriggerElement: MatMenuTrigger; public hasPermissionForSocialLogin: boolean; diff --git a/apps/client/src/app/components/header/header.module.ts b/apps/client/src/app/components/header/header.module.ts index eb2069f32..797ff7b6e 100644 --- a/apps/client/src/app/components/header/header.module.ts +++ b/apps/client/src/app/components/header/header.module.ts @@ -1,6 +1,6 @@ import { LoginWithAccessTokenDialogModule } from '@ghostfolio/client/components/login-with-access-token-dialog/login-with-access-token-dialog.module'; -import { GfAssistantModule } from '@ghostfolio/ui/assistant'; -import { GfLogoModule } from '@ghostfolio/ui/logo'; +import { GfAssistantComponent } from '@ghostfolio/ui/assistant'; +import { GfLogoComponent } from '@ghostfolio/ui/logo'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { CommonModule } from '@angular/common'; @@ -17,8 +17,8 @@ import { HeaderComponent } from './header.component'; exports: [HeaderComponent], imports: [ CommonModule, - GfAssistantModule, - GfLogoModule, + GfAssistantComponent, + GfLogoComponent, GfPremiumIndicatorComponent, LoginWithAccessTokenDialogModule, MatButtonModule, diff --git a/apps/client/src/app/components/home-market/home-market.module.ts b/apps/client/src/app/components/home-market/home-market.module.ts index 1443d2129..bc35b4bef 100644 --- a/apps/client/src/app/components/home-market/home-market.module.ts +++ b/apps/client/src/app/components/home-market/home-market.module.ts @@ -1,6 +1,6 @@ import { GfFearAndGreedIndexModule } from '@ghostfolio/client/components/fear-and-greed-index/fear-and-greed-index.module'; -import { GfBenchmarkModule } from '@ghostfolio/ui/benchmark/benchmark.module'; -import { GfLineChartModule } from '@ghostfolio/ui/line-chart'; +import { GfBenchmarkComponent } from '@ghostfolio/ui/benchmark'; +import { GfLineChartComponent } from '@ghostfolio/ui/line-chart'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -13,9 +13,9 @@ import { HomeMarketComponent } from './home-market.component'; exports: [HomeMarketComponent], imports: [ CommonModule, - GfBenchmarkModule, + GfBenchmarkComponent, GfFearAndGreedIndexModule, - GfLineChartModule, + GfLineChartComponent, NgxSkeletonLoaderModule ], schemas: [CUSTOM_ELEMENTS_SCHEMA] diff --git a/apps/client/src/app/components/home-overview/home-overview.module.ts b/apps/client/src/app/components/home-overview/home-overview.module.ts index 1a654b724..44c96953d 100644 --- a/apps/client/src/app/components/home-overview/home-overview.module.ts +++ b/apps/client/src/app/components/home-overview/home-overview.module.ts @@ -1,5 +1,5 @@ import { GfPortfolioPerformanceModule } from '@ghostfolio/client/components/portfolio-performance/portfolio-performance.module'; -import { GfLineChartModule } from '@ghostfolio/ui/line-chart'; +import { GfLineChartComponent } from '@ghostfolio/ui/line-chart'; import { GfNoTransactionsInfoComponent } from '@ghostfolio/ui/no-transactions-info'; import { CommonModule } from '@angular/common'; @@ -13,7 +13,7 @@ import { HomeOverviewComponent } from './home-overview.component'; declarations: [HomeOverviewComponent], imports: [ CommonModule, - GfLineChartModule, + GfLineChartComponent, GfNoTransactionsInfoComponent, GfPortfolioPerformanceModule, MatButtonModule, diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.module.ts b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.module.ts index ddd090cdc..751c645e5 100644 --- a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.module.ts +++ b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.module.ts @@ -2,9 +2,9 @@ import { GfAccountsTableModule } from '@ghostfolio/client/components/accounts-ta import { GfDialogFooterModule } from '@ghostfolio/client/components/dialog-footer/dialog-footer.module'; import { GfDialogHeaderModule } from '@ghostfolio/client/components/dialog-header/dialog-header.module'; import { GfActivitiesTableComponent } from '@ghostfolio/ui/activities-table'; -import { GfDataProviderCreditsModule } from '@ghostfolio/ui/data-provider-credits/data-provider-credits.module'; -import { GfLineChartModule } from '@ghostfolio/ui/line-chart'; -import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart'; +import { GfDataProviderCreditsComponent } from '@ghostfolio/ui/data-provider-credits'; +import { GfLineChartComponent } from '@ghostfolio/ui/line-chart'; +import { GfPortfolioProportionChartComponent } from '@ghostfolio/ui/portfolio-proportion-chart'; import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; @@ -23,11 +23,11 @@ import { PositionDetailDialog } from './position-detail-dialog.component'; CommonModule, GfAccountsTableModule, GfActivitiesTableComponent, - GfDataProviderCreditsModule, + GfDataProviderCreditsComponent, GfDialogFooterModule, GfDialogHeaderModule, - GfLineChartModule, - GfPortfolioProportionChartModule, + GfLineChartComponent, + GfPortfolioProportionChartComponent, GfValueComponent, MatButtonModule, MatChipsModule, diff --git a/apps/client/src/app/components/user-account-membership/user-account-membership.module.ts b/apps/client/src/app/components/user-account-membership/user-account-membership.module.ts index cdb315ad9..90646c09e 100644 --- a/apps/client/src/app/components/user-account-membership/user-account-membership.module.ts +++ b/apps/client/src/app/components/user-account-membership/user-account-membership.module.ts @@ -1,4 +1,4 @@ -import { GfMembershipCardModule } from '@ghostfolio/ui/membership-card'; +import { GfMembershipCardComponent } from '@ghostfolio/ui/membership-card'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { GfValueComponent } from '@ghostfolio/ui/value'; @@ -15,7 +15,7 @@ import { UserAccountMembershipComponent } from './user-account-membership.compon exports: [UserAccountMembershipComponent], imports: [ CommonModule, - GfMembershipCardModule, + GfMembershipCardComponent, GfPremiumIndicatorComponent, GfValueComponent, MatButtonModule, diff --git a/apps/client/src/app/pages/landing/landing-page.module.ts b/apps/client/src/app/pages/landing/landing-page.module.ts index 9f70313f5..ca39e6023 100644 --- a/apps/client/src/app/pages/landing/landing-page.module.ts +++ b/apps/client/src/app/pages/landing/landing-page.module.ts @@ -1,6 +1,6 @@ import { GfWorldMapChartModule } from '@ghostfolio/client/components/world-map-chart/world-map-chart.module'; -import { GfCarouselModule } from '@ghostfolio/ui/carousel'; -import { GfLogoModule } from '@ghostfolio/ui/logo'; +import { GfCarouselComponent } from '@ghostfolio/ui/carousel'; +import { GfLogoComponent } from '@ghostfolio/ui/logo'; import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; @@ -16,8 +16,8 @@ import { LandingPageComponent } from './landing-page.component'; declarations: [LandingPageComponent], imports: [ CommonModule, - GfCarouselModule, - GfLogoModule, + GfCarouselComponent, + GfLogoComponent, GfValueComponent, GfWorldMapChartModule, LandingPageRoutingModule, diff --git a/apps/client/src/app/pages/portfolio/allocations/allocations-page.module.ts b/apps/client/src/app/pages/portfolio/allocations/allocations-page.module.ts index 22d08bcd6..0f500ab35 100644 --- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.module.ts +++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.module.ts @@ -1,5 +1,5 @@ import { GfWorldMapChartModule } from '@ghostfolio/client/components/world-map-chart/world-map-chart.module'; -import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart'; +import { GfPortfolioProportionChartComponent } from '@ghostfolio/ui/portfolio-proportion-chart'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { GfValueComponent } from '@ghostfolio/ui/value'; @@ -17,7 +17,7 @@ import { AllocationsPageComponent } from './allocations-page.component'; imports: [ AllocationsPageRoutingModule, CommonModule, - GfPortfolioProportionChartModule, + GfPortfolioProportionChartComponent, GfPremiumIndicatorComponent, GfWorldMapChartModule, GfValueComponent, diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.module.ts b/apps/client/src/app/pages/portfolio/analysis/analysis-page.module.ts index 5fb86efa8..b33905456 100644 --- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.module.ts +++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.module.ts @@ -1,7 +1,7 @@ import { GfBenchmarkComparatorModule } from '@ghostfolio/client/components/benchmark-comparator/benchmark-comparator.module'; import { GfInvestmentChartModule } from '@ghostfolio/client/components/investment-chart/investment-chart.module'; import { GfToggleModule } from '@ghostfolio/client/components/toggle/toggle.module'; -import { GfActivitiesFilterModule } from '@ghostfolio/ui/activities-filter'; +import { GfActivitiesFilterComponent } from '@ghostfolio/ui/activities-filter'; import { GfPremiumIndicatorComponent } from '@ghostfolio/ui/premium-indicator'; import { GfValueComponent } from '@ghostfolio/ui/value'; @@ -18,7 +18,7 @@ import { AnalysisPageComponent } from './analysis-page.component'; imports: [ AnalysisPageRoutingModule, CommonModule, - GfActivitiesFilterModule, + GfActivitiesFilterComponent, GfBenchmarkComparatorModule, GfInvestmentChartModule, GfPremiumIndicatorComponent, diff --git a/apps/client/src/app/pages/public/public-page.module.ts b/apps/client/src/app/pages/public/public-page.module.ts index 3cd5d8227..68c43b45f 100644 --- a/apps/client/src/app/pages/public/public-page.module.ts +++ b/apps/client/src/app/pages/public/public-page.module.ts @@ -1,6 +1,6 @@ import { GfWorldMapChartModule } from '@ghostfolio/client/components/world-map-chart/world-map-chart.module'; import { GfHoldingsTableComponent } from '@ghostfolio/ui/holdings-table'; -import { GfPortfolioProportionChartModule } from '@ghostfolio/ui/portfolio-proportion-chart'; +import { GfPortfolioProportionChartComponent } from '@ghostfolio/ui/portfolio-proportion-chart'; import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; @@ -16,7 +16,7 @@ import { PublicPageComponent } from './public-page.component'; imports: [ CommonModule, GfHoldingsTableComponent, - GfPortfolioProportionChartModule, + GfPortfolioProportionChartComponent, GfValueComponent, GfWorldMapChartModule, MatButtonModule, diff --git a/apps/client/src/app/pages/register/register-page.module.ts b/apps/client/src/app/pages/register/register-page.module.ts index f0bcfd1a8..b6e917e6d 100644 --- a/apps/client/src/app/pages/register/register-page.module.ts +++ b/apps/client/src/app/pages/register/register-page.module.ts @@ -1,4 +1,4 @@ -import { GfLogoModule } from '@ghostfolio/ui/logo'; +import { GfLogoComponent } from '@ghostfolio/ui/logo'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; @@ -13,7 +13,7 @@ import { ShowAccessTokenDialogModule } from './show-access-token-dialog/show-acc declarations: [RegisterPageComponent], imports: [ CommonModule, - GfLogoModule, + GfLogoComponent, MatButtonModule, RegisterPageRoutingModule, RouterModule, diff --git a/apps/client/src/app/pages/webauthn/webauthn-page.module.ts b/apps/client/src/app/pages/webauthn/webauthn-page.module.ts index 0ef7d12ce..93f9fe870 100644 --- a/apps/client/src/app/pages/webauthn/webauthn-page.module.ts +++ b/apps/client/src/app/pages/webauthn/webauthn-page.module.ts @@ -1,5 +1,5 @@ import { WebauthnPageComponent } from '@ghostfolio/client/pages/webauthn/webauthn-page.component'; -import { GfLogoModule } from '@ghostfolio/ui/logo'; +import { GfLogoComponent } from '@ghostfolio/ui/logo'; import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; @@ -12,7 +12,7 @@ import { WebauthnPageRoutingModule } from './webauthn-page-routing.module'; declarations: [WebauthnPageComponent], imports: [ CommonModule, - GfLogoModule, + GfLogoComponent, MatButtonModule, MatProgressSpinnerModule, WebauthnPageRoutingModule diff --git a/libs/ui/src/lib/account-balances/account-balances.component.ts b/libs/ui/src/lib/account-balances/account-balances.component.ts index 65f2547b9..9d9e8ab19 100644 --- a/libs/ui/src/lib/account-balances/account-balances.component.ts +++ b/libs/ui/src/lib/account-balances/account-balances.component.ts @@ -1,7 +1,9 @@ import { getLocale } from '@ghostfolio/common/helper'; import { AccountBalancesResponse } from '@ghostfolio/common/interfaces'; +import { CommonModule } from '@angular/common'; import { + CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, EventEmitter, @@ -12,18 +14,34 @@ import { Output, ViewChild } from '@angular/core'; -import { MatSort } from '@angular/material/sort'; -import { MatTableDataSource } from '@angular/material/table'; +import { MatButtonModule } from '@angular/material/button'; +import { MatMenuModule } from '@angular/material/menu'; +import { MatSort, MatSortModule } from '@angular/material/sort'; +import { MatTableDataSource, MatTableModule } from '@angular/material/table'; import { get } from 'lodash'; import { Subject } from 'rxjs'; +import { GfValueComponent } from '../value'; + @Component({ changeDetection: ChangeDetectionStrategy.OnPush, + imports: [ + CommonModule, + GfValueComponent, + MatButtonModule, + MatMenuModule, + MatSortModule, + MatTableModule + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA], selector: 'gf-account-balances', + standalone: true, styleUrls: ['./account-balances.component.scss'], templateUrl: './account-balances.component.html' }) -export class AccountBalancesComponent implements OnChanges, OnDestroy, OnInit { +export class GfAccountBalancesComponent + implements OnChanges, OnDestroy, OnInit +{ @Input() accountBalances: AccountBalancesResponse['balances']; @Input() accountId: string; @Input() locale = getLocale(); diff --git a/libs/ui/src/lib/account-balances/account-balances.module.ts b/libs/ui/src/lib/account-balances/account-balances.module.ts deleted file mode 100644 index e7c7aaab7..000000000 --- a/libs/ui/src/lib/account-balances/account-balances.module.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { GfValueComponent } from '@ghostfolio/ui/value'; - -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { MatButtonModule } from '@angular/material/button'; -import { MatMenuModule } from '@angular/material/menu'; -import { MatSortModule } from '@angular/material/sort'; -import { MatTableModule } from '@angular/material/table'; - -import { AccountBalancesComponent } from './account-balances.component'; - -@NgModule({ - declarations: [AccountBalancesComponent], - exports: [AccountBalancesComponent], - imports: [ - CommonModule, - GfValueComponent, - MatButtonModule, - MatMenuModule, - MatSortModule, - MatTableModule - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfAccountBalancesModule {} diff --git a/libs/ui/src/lib/account-balances/index.ts b/libs/ui/src/lib/account-balances/index.ts index 732615851..b32ba9a0f 100644 --- a/libs/ui/src/lib/account-balances/index.ts +++ b/libs/ui/src/lib/account-balances/index.ts @@ -1 +1 @@ -export * from './account-balances.module'; +export * from './account-balances.component'; diff --git a/libs/ui/src/lib/activities-filter/activities-filter.component.ts b/libs/ui/src/lib/activities-filter/activities-filter.component.ts index db4cc2d31..6244fa5fc 100644 --- a/libs/ui/src/lib/activities-filter/activities-filter.component.ts +++ b/libs/ui/src/lib/activities-filter/activities-filter.component.ts @@ -1,8 +1,11 @@ +import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; import { Filter, FilterGroup } from '@ghostfolio/common/interfaces'; import { translate } from '@ghostfolio/ui/i18n'; import { COMMA, ENTER } from '@angular/cdk/keycodes'; +import { CommonModule } from '@angular/common'; import { + CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, ElementRef, @@ -14,23 +17,39 @@ import { SimpleChanges, ViewChild } from '@angular/core'; -import { FormControl } from '@angular/forms'; +import { FormControl, ReactiveFormsModule } from '@angular/forms'; import { MatAutocomplete, + MatAutocompleteModule, MatAutocompleteSelectedEvent } from '@angular/material/autocomplete'; -import { MatChipInputEvent } from '@angular/material/chips'; +import { MatButtonModule } from '@angular/material/button'; +import { MatChipInputEvent, MatChipsModule } from '@angular/material/chips'; +import { MatInputModule } from '@angular/material/input'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { groupBy } from 'lodash'; import { BehaviorSubject, Observable, Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, + imports: [ + CommonModule, + GfSymbolModule, + MatAutocompleteModule, + MatButtonModule, + MatChipsModule, + MatInputModule, + MatProgressSpinnerModule, + ReactiveFormsModule + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA], selector: 'gf-activities-filter', + standalone: true, styleUrls: ['./activities-filter.component.scss'], templateUrl: './activities-filter.component.html' }) -export class ActivitiesFilterComponent implements OnChanges, OnDestroy { +export class GfActivitiesFilterComponent implements OnChanges, OnDestroy { @Input() allFilters: Filter[]; @Input() isLoading: boolean; @Input() placeholder: string; diff --git a/libs/ui/src/lib/activities-filter/activities-filter.module.ts b/libs/ui/src/lib/activities-filter/activities-filter.module.ts deleted file mode 100644 index 56f082e7b..000000000 --- a/libs/ui/src/lib/activities-filter/activities-filter.module.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; - -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { ReactiveFormsModule } from '@angular/forms'; -import { MatAutocompleteModule } from '@angular/material/autocomplete'; -import { MatButtonModule } from '@angular/material/button'; -import { MatChipsModule } from '@angular/material/chips'; -import { MatInputModule } from '@angular/material/input'; -import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; - -import { ActivitiesFilterComponent } from './activities-filter.component'; - -@NgModule({ - declarations: [ActivitiesFilterComponent], - exports: [ActivitiesFilterComponent], - imports: [ - CommonModule, - GfSymbolModule, - MatAutocompleteModule, - MatButtonModule, - MatChipsModule, - MatInputModule, - MatProgressSpinnerModule, - ReactiveFormsModule - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfActivitiesFilterModule {} diff --git a/libs/ui/src/lib/activities-filter/index.ts b/libs/ui/src/lib/activities-filter/index.ts index ce1d30e5e..ef776e130 100644 --- a/libs/ui/src/lib/activities-filter/index.ts +++ b/libs/ui/src/lib/activities-filter/index.ts @@ -1 +1 @@ -export * from './activities-filter.module'; +export * from './activities-filter.component'; diff --git a/libs/ui/src/lib/activities-table/activities-table.component.ts b/libs/ui/src/lib/activities-table/activities-table.component.ts index d7511df97..edc0cc64f 100644 --- a/libs/ui/src/lib/activities-table/activities-table.component.ts +++ b/libs/ui/src/lib/activities-table/activities-table.component.ts @@ -5,7 +5,7 @@ import { DEFAULT_PAGE_SIZE } from '@ghostfolio/common/config'; import { getDateFormatString, getLocale } from '@ghostfolio/common/helper'; import { UniqueAsset } from '@ghostfolio/common/interfaces'; import { OrderWithAccount } from '@ghostfolio/common/types'; -import { GfActivityTypeModule } from '@ghostfolio/ui/activity-type'; +import { GfActivityTypeComponent } from '@ghostfolio/ui/activity-type'; import { GfNoTransactionsInfoComponent } from '@ghostfolio/ui/no-transactions-info'; import { GfValueComponent } from '@ghostfolio/ui/value'; @@ -50,7 +50,7 @@ import { Subject, Subscription, takeUntil } from 'rxjs'; changeDetection: ChangeDetectionStrategy.OnPush, imports: [ CommonModule, - GfActivityTypeModule, + GfActivityTypeComponent, GfAssetProfileIconComponent, GfNoTransactionsInfoComponent, GfSymbolModule, diff --git a/libs/ui/src/lib/activity-type/activity-type.component.ts b/libs/ui/src/lib/activity-type/activity-type.component.ts index bf7621882..1554794b3 100644 --- a/libs/ui/src/lib/activity-type/activity-type.component.ts +++ b/libs/ui/src/lib/activity-type/activity-type.component.ts @@ -1,6 +1,8 @@ import { translate } from '@ghostfolio/ui/i18n'; +import { CommonModule } from '@angular/common'; import { + CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, Input, @@ -10,11 +12,14 @@ import { Type as ActivityType } from '@prisma/client'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, + imports: [CommonModule], + schemas: [CUSTOM_ELEMENTS_SCHEMA], selector: 'gf-activity-type', + standalone: true, styleUrls: ['./activity-type.component.scss'], templateUrl: './activity-type.component.html' }) -export class ActivityTypeComponent implements OnChanges { +export class GfActivityTypeComponent implements OnChanges { @Input() activityType: ActivityType; public activityTypeLabel: string; diff --git a/libs/ui/src/lib/activity-type/activity-type.module.ts b/libs/ui/src/lib/activity-type/activity-type.module.ts deleted file mode 100644 index e4cc71815..000000000 --- a/libs/ui/src/lib/activity-type/activity-type.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; - -import { ActivityTypeComponent } from './activity-type.component'; - -@NgModule({ - declarations: [ActivityTypeComponent], - exports: [ActivityTypeComponent], - imports: [CommonModule], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfActivityTypeModule {} diff --git a/libs/ui/src/lib/activity-type/index.ts b/libs/ui/src/lib/activity-type/index.ts index a1e626fef..9fcf60eeb 100644 --- a/libs/ui/src/lib/activity-type/index.ts +++ b/libs/ui/src/lib/activity-type/index.ts @@ -1 +1 @@ -export * from './activity-type.module'; +export * from './activity-type.component'; diff --git a/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts b/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts index bb67b16c5..b909145c7 100644 --- a/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts +++ b/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts @@ -1,6 +1,8 @@ +import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; import { ISearchResultItem } from '@ghostfolio/ui/assistant/interfaces/interfaces'; import { FocusableOption } from '@angular/cdk/a11y'; +import { CommonModule } from '@angular/common'; import { ChangeDetectionStrategy, ChangeDetectorRef, @@ -13,15 +15,19 @@ import { Output, ViewChild } from '@angular/core'; -import { Params } from '@angular/router'; +import { Params, RouterModule } from '@angular/router'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, + imports: [CommonModule, GfSymbolModule, RouterModule], selector: 'gf-assistant-list-item', - templateUrl: './assistant-list-item.html', - styleUrls: ['./assistant-list-item.scss'] + standalone: true, + styleUrls: ['./assistant-list-item.scss'], + templateUrl: './assistant-list-item.html' }) -export class AssistantListItemComponent implements FocusableOption, OnChanges { +export class GfAssistantListItemComponent + implements FocusableOption, OnChanges +{ @HostBinding('attr.tabindex') tabindex = -1; @HostBinding('class.has-focus') get getHasFocus() { return this.hasFocus; diff --git a/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.module.ts b/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.module.ts deleted file mode 100644 index fb512ee5e..000000000 --- a/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; - -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; - -import { AssistantListItemComponent } from './assistant-list-item.component'; - -@NgModule({ - declarations: [AssistantListItemComponent], - exports: [AssistantListItemComponent], - imports: [CommonModule, GfSymbolModule, RouterModule] -}) -export class GfAssistantListItemModule {} diff --git a/libs/ui/src/lib/assistant/assistant.component.ts b/libs/ui/src/lib/assistant/assistant.component.ts index 310bede05..f932fd5c2 100644 --- a/libs/ui/src/lib/assistant/assistant.component.ts +++ b/libs/ui/src/lib/assistant/assistant.component.ts @@ -1,3 +1,4 @@ +import { GfAssetProfileIconComponent } from '@ghostfolio/client/components/asset-profile-icon/asset-profile-icon.component'; import { AdminService } from '@ghostfolio/client/services/admin.service'; import { DataService } from '@ghostfolio/client/services/data.service'; import { Filter, User } from '@ghostfolio/common/interfaces'; @@ -5,7 +6,9 @@ import { DateRange } from '@ghostfolio/common/types'; import { translate } from '@ghostfolio/ui/i18n'; import { FocusKeyManager } from '@angular/cdk/a11y'; +import { CommonModule } from '@angular/common'; import { + CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, ChangeDetectorRef, Component, @@ -21,10 +24,20 @@ import { ViewChild, ViewChildren } from '@angular/core'; -import { FormBuilder, FormControl } from '@angular/forms'; +import { + FormBuilder, + FormControl, + FormsModule, + ReactiveFormsModule +} from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatFormFieldModule } from '@angular/material/form-field'; import { MatMenuTrigger } from '@angular/material/menu'; +import { MatSelectModule } from '@angular/material/select'; +import { RouterModule } from '@angular/router'; import { Account, AssetClass } from '@prisma/client'; import { eachYearOfInterval, format } from 'date-fns'; +import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { EMPTY, Observable, Subject, lastValueFrom } from 'rxjs'; import { catchError, @@ -35,7 +48,7 @@ import { takeUntil } from 'rxjs/operators'; -import { AssistantListItemComponent } from './assistant-list-item/assistant-list-item.component'; +import { GfAssistantListItemComponent } from './assistant-list-item/assistant-list-item.component'; import { IDateRangeOption, ISearchResultItem, @@ -44,11 +57,25 @@ import { @Component({ changeDetection: ChangeDetectionStrategy.OnPush, + imports: [ + CommonModule, + FormsModule, + GfAssetProfileIconComponent, + GfAssistantListItemComponent, + MatButtonModule, + MatFormFieldModule, + MatSelectModule, + NgxSkeletonLoaderModule, + ReactiveFormsModule, + RouterModule + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA], selector: 'gf-assistant', + standalone: true, styleUrls: ['./assistant.scss'], templateUrl: './assistant.html' }) -export class AssistantComponent implements OnChanges, OnDestroy, OnInit { +export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit { @HostListener('document:keydown', ['$event']) onKeydown( event: KeyboardEvent ) { @@ -92,8 +119,8 @@ export class AssistantComponent implements OnChanges, OnDestroy, OnInit { @ViewChild('menuTrigger') menuTriggerElement: MatMenuTrigger; @ViewChild('search', { static: true }) searchElement: ElementRef; - @ViewChildren(AssistantListItemComponent) - assistantListItems: QueryList; + @ViewChildren(GfAssistantListItemComponent) + assistantListItems: QueryList; public static readonly SEARCH_RESULTS_DEFAULT_LIMIT = 5; @@ -117,7 +144,7 @@ export class AssistantComponent implements OnChanges, OnDestroy, OnInit { public tags: Filter[] = []; private filterTypes: Filter['type'][] = ['ACCOUNT', 'ASSET_CLASS', 'TAG']; - private keyManager: FocusKeyManager; + private keyManager: FocusKeyManager; private unsubscribeSubject = new Subject(); public constructor( @@ -334,7 +361,7 @@ export class AssistantComponent implements OnChanges, OnDestroy, OnInit { ); assetProfiles = assetProfiles.slice( 0, - AssistantComponent.SEARCH_RESULTS_DEFAULT_LIMIT + GfAssistantComponent.SEARCH_RESULTS_DEFAULT_LIMIT ); } catch {} } @@ -343,7 +370,7 @@ export class AssistantComponent implements OnChanges, OnDestroy, OnInit { holdings = await lastValueFrom(this.searchHoldings(aSearchTerm)); holdings = holdings.slice( 0, - AssistantComponent.SEARCH_RESULTS_DEFAULT_LIMIT + GfAssistantComponent.SEARCH_RESULTS_DEFAULT_LIMIT ); } catch {} @@ -364,7 +391,7 @@ export class AssistantComponent implements OnChanges, OnDestroy, OnInit { type: 'SEARCH_QUERY' } ], - take: AssistantComponent.SEARCH_RESULTS_DEFAULT_LIMIT + take: GfAssistantComponent.SEARCH_RESULTS_DEFAULT_LIMIT }) .pipe( catchError(() => { diff --git a/libs/ui/src/lib/assistant/assistant.module.ts b/libs/ui/src/lib/assistant/assistant.module.ts deleted file mode 100644 index 031f57f46..000000000 --- a/libs/ui/src/lib/assistant/assistant.module.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { GfAssetProfileIconComponent } from '@ghostfolio/client/components/asset-profile-icon/asset-profile-icon.component'; - -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { MatButtonModule } from '@angular/material/button'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatSelectModule } from '@angular/material/select'; -import { RouterModule } from '@angular/router'; -import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; - -import { GfAssistantListItemModule } from './assistant-list-item/assistant-list-item.module'; -import { AssistantComponent } from './assistant.component'; - -@NgModule({ - declarations: [AssistantComponent], - exports: [AssistantComponent], - imports: [ - CommonModule, - FormsModule, - GfAssetProfileIconComponent, - GfAssistantListItemModule, - MatButtonModule, - MatFormFieldModule, - MatSelectModule, - NgxSkeletonLoaderModule, - ReactiveFormsModule, - RouterModule - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfAssistantModule {} diff --git a/libs/ui/src/lib/assistant/index.ts b/libs/ui/src/lib/assistant/index.ts index f58d1b2f3..aded19f26 100644 --- a/libs/ui/src/lib/assistant/index.ts +++ b/libs/ui/src/lib/assistant/index.ts @@ -1 +1 @@ -export * from './assistant.module'; +export * from './assistant.component'; diff --git a/libs/ui/src/lib/benchmark/benchmark.component.ts b/libs/ui/src/lib/benchmark/benchmark.component.ts index 032c131bf..07e70c2fd 100644 --- a/libs/ui/src/lib/benchmark/benchmark.component.ts +++ b/libs/ui/src/lib/benchmark/benchmark.component.ts @@ -2,20 +2,36 @@ import { getLocale, resolveMarketCondition } from '@ghostfolio/common/helper'; import { Benchmark, User } from '@ghostfolio/common/interfaces'; import { translate } from '@ghostfolio/ui/i18n'; +import { CommonModule } from '@angular/common'; import { + CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, Input, OnChanges } from '@angular/core'; +import { MatTableModule } from '@angular/material/table'; +import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; + +import { GfTrendIndicatorComponent } from '../trend-indicator'; +import { GfValueComponent } from '../value'; @Component({ - selector: 'gf-benchmark', changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './benchmark.component.html', - styleUrls: ['./benchmark.component.scss'] + imports: [ + CommonModule, + GfTrendIndicatorComponent, + GfValueComponent, + MatTableModule, + NgxSkeletonLoaderModule + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + selector: 'gf-benchmark', + standalone: true, + styleUrls: ['./benchmark.component.scss'], + templateUrl: './benchmark.component.html' }) -export class BenchmarkComponent implements OnChanges { +export class GfBenchmarkComponent implements OnChanges { @Input() benchmarks: Benchmark[]; @Input() locale = getLocale(); @Input() user: User; diff --git a/libs/ui/src/lib/benchmark/benchmark.module.ts b/libs/ui/src/lib/benchmark/benchmark.module.ts deleted file mode 100644 index 91f5be938..000000000 --- a/libs/ui/src/lib/benchmark/benchmark.module.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { MatTableModule } from '@angular/material/table'; -import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; - -import { GfTrendIndicatorComponent } from '../trend-indicator'; -import { GfValueComponent } from '../value'; -import { BenchmarkComponent } from './benchmark.component'; - -@NgModule({ - declarations: [BenchmarkComponent], - exports: [BenchmarkComponent], - imports: [ - CommonModule, - GfTrendIndicatorComponent, - GfValueComponent, - MatTableModule, - NgxSkeletonLoaderModule - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfBenchmarkModule {} diff --git a/libs/ui/src/lib/benchmark/index.ts b/libs/ui/src/lib/benchmark/index.ts index b8cd0c1a8..87fdc713c 100644 --- a/libs/ui/src/lib/benchmark/index.ts +++ b/libs/ui/src/lib/benchmark/index.ts @@ -1 +1 @@ -export * from './benchmark.module'; +export * from './benchmark.component'; diff --git a/libs/ui/src/lib/carousel/carousel.component.ts b/libs/ui/src/lib/carousel/carousel.component.ts index a0eb0f8a1..33f68b249 100644 --- a/libs/ui/src/lib/carousel/carousel.component.ts +++ b/libs/ui/src/lib/carousel/carousel.component.ts @@ -1,7 +1,9 @@ import { FocusKeyManager } from '@angular/cdk/a11y'; import { LEFT_ARROW, RIGHT_ARROW, TAB } from '@angular/cdk/keycodes'; +import { CommonModule } from '@angular/common'; import { AfterContentInit, + CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, ContentChildren, @@ -13,17 +15,21 @@ import { QueryList, ViewChild } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; import { ANIMATION_MODULE_TYPE } from '@angular/platform-browser/animations'; import { CarouselItem } from './carousel-item.directive'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, + imports: [CommonModule, MatButtonModule], + schemas: [CUSTOM_ELEMENTS_SCHEMA], selector: 'gf-carousel', + standalone: true, styleUrls: ['./carousel.component.scss'], templateUrl: './carousel.component.html' }) -export class CarouselComponent implements AfterContentInit { +export class GfCarouselComponent implements AfterContentInit { @ContentChildren(CarouselItem) public items!: QueryList; @HostBinding('class.animations-disabled') diff --git a/libs/ui/src/lib/carousel/carousel.module.ts b/libs/ui/src/lib/carousel/carousel.module.ts deleted file mode 100644 index 4e43f23b0..000000000 --- a/libs/ui/src/lib/carousel/carousel.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { MatButtonModule } from '@angular/material/button'; - -import { CarouselItem } from './carousel-item.directive'; -import { CarouselComponent } from './carousel.component'; - -@NgModule({ - declarations: [CarouselComponent, CarouselItem], - exports: [CarouselComponent, CarouselItem], - imports: [CommonModule, MatButtonModule], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfCarouselModule {} diff --git a/libs/ui/src/lib/carousel/index.ts b/libs/ui/src/lib/carousel/index.ts index 2e039a80b..3cd42148e 100644 --- a/libs/ui/src/lib/carousel/index.ts +++ b/libs/ui/src/lib/carousel/index.ts @@ -1 +1 @@ -export * from './carousel.module'; +export * from './carousel.component'; diff --git a/libs/ui/src/lib/data-provider-credits/data-provider-credits.component.ts b/libs/ui/src/lib/data-provider-credits/data-provider-credits.component.ts index afdcb969a..bfab714f9 100644 --- a/libs/ui/src/lib/data-provider-credits/data-provider-credits.component.ts +++ b/libs/ui/src/lib/data-provider-credits/data-provider-credits.component.ts @@ -1,14 +1,23 @@ import { DataProviderInfo } from '@ghostfolio/common/interfaces'; -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { + CUSTOM_ELEMENTS_SCHEMA, + ChangeDetectionStrategy, + Component, + Input +} from '@angular/core'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, + imports: [CommonModule], + schemas: [CUSTOM_ELEMENTS_SCHEMA], selector: 'gf-data-provider-credits', + standalone: true, styleUrls: ['./data-provider-credits.component.scss'], templateUrl: './data-provider-credits.component.html' }) -export class DataProviderCreditsComponent { +export class GfDataProviderCreditsComponent { @Input() dataProviderInfos: DataProviderInfo[]; public constructor() {} diff --git a/libs/ui/src/lib/data-provider-credits/data-provider-credits.module.ts b/libs/ui/src/lib/data-provider-credits/data-provider-credits.module.ts deleted file mode 100644 index e5dd9d3b9..000000000 --- a/libs/ui/src/lib/data-provider-credits/data-provider-credits.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; - -import { DataProviderCreditsComponent } from './data-provider-credits.component'; - -@NgModule({ - declarations: [DataProviderCreditsComponent], - exports: [DataProviderCreditsComponent], - imports: [CommonModule], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfDataProviderCreditsModule {} diff --git a/libs/ui/src/lib/data-provider-credits/index.ts b/libs/ui/src/lib/data-provider-credits/index.ts index 5d3759577..44db13ea5 100644 --- a/libs/ui/src/lib/data-provider-credits/index.ts +++ b/libs/ui/src/lib/data-provider-credits/index.ts @@ -1 +1 @@ -export * from './data-provider-credits.module'; +export * from './data-provider-credits.component'; diff --git a/libs/ui/src/lib/line-chart/index.ts b/libs/ui/src/lib/line-chart/index.ts index 0edc13b6e..fca368497 100644 --- a/libs/ui/src/lib/line-chart/index.ts +++ b/libs/ui/src/lib/line-chart/index.ts @@ -1 +1 @@ -export * from './line-chart.module'; +export * from './line-chart.component'; diff --git a/libs/ui/src/lib/line-chart/line-chart.component.ts b/libs/ui/src/lib/line-chart/line-chart.component.ts index bad5e2f3f..4098e1d5b 100644 --- a/libs/ui/src/lib/line-chart/line-chart.component.ts +++ b/libs/ui/src/lib/line-chart/line-chart.component.ts @@ -13,6 +13,7 @@ import { import { LineChartItem } from '@ghostfolio/common/interfaces'; import { ColorScheme } from '@ghostfolio/common/types'; +import { CommonModule } from '@angular/common'; import { AfterViewInit, ChangeDetectionStrategy, @@ -34,14 +35,19 @@ import { Tooltip } from 'chart.js'; import 'chartjs-adapter-date-fns'; +import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; @Component({ - selector: 'gf-line-chart', changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './line-chart.component.html', - styleUrls: ['./line-chart.component.scss'] + imports: [CommonModule, NgxSkeletonLoaderModule], + selector: 'gf-line-chart', + standalone: true, + styleUrls: ['./line-chart.component.scss'], + templateUrl: './line-chart.component.html' }) -export class LineChartComponent implements AfterViewInit, OnChanges, OnDestroy { +export class GfLineChartComponent + implements AfterViewInit, OnChanges, OnDestroy +{ @Input() benchmarkDataItems: LineChartItem[] = []; @Input() benchmarkLabel = ''; @Input() colorScheme: ColorScheme; diff --git a/libs/ui/src/lib/line-chart/line-chart.module.ts b/libs/ui/src/lib/line-chart/line-chart.module.ts deleted file mode 100644 index 0483fc996..000000000 --- a/libs/ui/src/lib/line-chart/line-chart.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; - -import { LineChartComponent } from './line-chart.component'; - -@NgModule({ - declarations: [LineChartComponent], - exports: [LineChartComponent], - imports: [CommonModule, NgxSkeletonLoaderModule] -}) -export class GfLineChartModule {} diff --git a/libs/ui/src/lib/logo/index.ts b/libs/ui/src/lib/logo/index.ts index a02a37ec8..9a94f8985 100644 --- a/libs/ui/src/lib/logo/index.ts +++ b/libs/ui/src/lib/logo/index.ts @@ -1 +1 @@ -export * from './logo.module'; +export * from './logo.component'; diff --git a/libs/ui/src/lib/logo/logo.component.ts b/libs/ui/src/lib/logo/logo.component.ts index ecb3885dc..d9edd546e 100644 --- a/libs/ui/src/lib/logo/logo.component.ts +++ b/libs/ui/src/lib/logo/logo.component.ts @@ -1,4 +1,6 @@ +import { CommonModule } from '@angular/common'; import { + CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, HostBinding, @@ -6,12 +8,15 @@ import { } from '@angular/core'; @Component({ - selector: 'gf-logo', changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './logo.component.html', - styleUrls: ['./logo.component.scss'] + imports: [CommonModule], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + selector: 'gf-logo', + standalone: true, + styleUrls: ['./logo.component.scss'], + templateUrl: './logo.component.html' }) -export class LogoComponent { +export class GfLogoComponent { @HostBinding('class') @Input() size: 'large' | 'medium' = 'medium'; @Input() label: string; @Input() showLabel = true; diff --git a/libs/ui/src/lib/logo/logo.module.ts b/libs/ui/src/lib/logo/logo.module.ts deleted file mode 100644 index ced9bae30..000000000 --- a/libs/ui/src/lib/logo/logo.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; - -import { LogoComponent } from './logo.component'; - -@NgModule({ - declarations: [LogoComponent], - exports: [LogoComponent], - imports: [CommonModule], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfLogoModule {} diff --git a/libs/ui/src/lib/membership-card/index.ts b/libs/ui/src/lib/membership-card/index.ts index eccd8c4fd..1a0b5cac1 100644 --- a/libs/ui/src/lib/membership-card/index.ts +++ b/libs/ui/src/lib/membership-card/index.ts @@ -1 +1 @@ -export * from './membership-card.module'; +export * from './membership-card.component'; diff --git a/libs/ui/src/lib/membership-card/membership-card.component.ts b/libs/ui/src/lib/membership-card/membership-card.component.ts index 0ae760aba..f82dee3f1 100644 --- a/libs/ui/src/lib/membership-card/membership-card.component.ts +++ b/libs/ui/src/lib/membership-card/membership-card.component.ts @@ -1,12 +1,24 @@ -import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { + CUSTOM_ELEMENTS_SCHEMA, + ChangeDetectionStrategy, + Component, + Input +} from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { GfLogoComponent } from '../logo'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, + imports: [CommonModule, GfLogoComponent, RouterModule], + schemas: [CUSTOM_ELEMENTS_SCHEMA], selector: 'gf-membership-card', + standalone: true, styleUrls: ['./membership-card.component.scss'], templateUrl: './membership-card.component.html' }) -export class MembershipCardComponent { +export class GfMembershipCardComponent { @Input() public expiresAt: string; @Input() public name: string; diff --git a/libs/ui/src/lib/membership-card/membership-card.module.ts b/libs/ui/src/lib/membership-card/membership-card.module.ts deleted file mode 100644 index 564308e29..000000000 --- a/libs/ui/src/lib/membership-card/membership-card.module.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { GfLogoModule } from '@ghostfolio/ui/logo'; - -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { RouterModule } from '@angular/router'; - -import { MembershipCardComponent } from './membership-card.component'; - -@NgModule({ - declarations: [MembershipCardComponent], - exports: [MembershipCardComponent], - imports: [CommonModule, GfLogoModule, RouterModule], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfMembershipCardModule {} diff --git a/libs/ui/src/lib/no-transactions-info/no-transactions-info.component.ts b/libs/ui/src/lib/no-transactions-info/no-transactions-info.component.ts index f1a17d777..0c30041b6 100644 --- a/libs/ui/src/lib/no-transactions-info/no-transactions-info.component.ts +++ b/libs/ui/src/lib/no-transactions-info/no-transactions-info.component.ts @@ -9,11 +9,11 @@ import { import { MatButtonModule } from '@angular/material/button'; import { RouterModule } from '@angular/router'; -import { GfLogoModule } from '../logo'; +import { GfLogoComponent } from '../logo'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, - imports: [CommonModule, GfLogoModule, MatButtonModule, RouterModule], + imports: [CommonModule, GfLogoComponent, MatButtonModule, RouterModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], selector: 'gf-no-transactions-info-indicator', standalone: true, diff --git a/libs/ui/src/lib/portfolio-proportion-chart/index.ts b/libs/ui/src/lib/portfolio-proportion-chart/index.ts index 16ceaf055..edf1fa198 100644 --- a/libs/ui/src/lib/portfolio-proportion-chart/index.ts +++ b/libs/ui/src/lib/portfolio-proportion-chart/index.ts @@ -1 +1 @@ -export * from './portfolio-proportion-chart.module'; +export * from './portfolio-proportion-chart.component'; diff --git a/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts b/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts index 620cb2066..f243f888a 100644 --- a/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts +++ b/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts @@ -5,6 +5,7 @@ import { PortfolioPosition, UniqueAsset } from '@ghostfolio/common/interfaces'; import { ColorScheme } from '@ghostfolio/common/types'; import { translate } from '@ghostfolio/ui/i18n'; +import { CommonModule } from '@angular/common'; import { AfterViewInit, ChangeDetectionStrategy, @@ -26,14 +27,17 @@ import { DoughnutController } from 'chart.js'; import { Chart } from 'chart.js'; import ChartDataLabels from 'chartjs-plugin-datalabels'; import * as Color from 'color'; +import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; @Component({ - selector: 'gf-portfolio-proportion-chart', changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './portfolio-proportion-chart.component.html', - styleUrls: ['./portfolio-proportion-chart.component.scss'] + imports: [CommonModule, NgxSkeletonLoaderModule], + selector: 'gf-portfolio-proportion-chart', + standalone: true, + styleUrls: ['./portfolio-proportion-chart.component.scss'], + templateUrl: './portfolio-proportion-chart.component.html' }) -export class PortfolioProportionChartComponent +export class GfPortfolioProportionChartComponent implements AfterViewInit, OnChanges, OnDestroy { @Input() baseCurrency: string; diff --git a/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.module.ts b/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.module.ts deleted file mode 100644 index 587c19072..000000000 --- a/libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.module.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { NgModule } from '@angular/core'; -import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; - -import { PortfolioProportionChartComponent } from './portfolio-proportion-chart.component'; - -@NgModule({ - declarations: [PortfolioProportionChartComponent], - exports: [PortfolioProportionChartComponent], - imports: [CommonModule, NgxSkeletonLoaderModule] -}) -export class GfPortfolioProportionChartModule {} From 212aa6a63b8fecb4aa93788032ef7948dfe1a9d2 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 20 Apr 2024 09:51:12 +0200 Subject: [PATCH 140/203] Feature/add date range support to portfolio holdings page (#3303) * Add date range support * Update changelog --- CHANGELOG.md | 4 ++++ apps/api/src/app/portfolio/portfolio.controller.ts | 2 ++ .../portfolio/holdings/holdings-page.component.ts | 3 ++- apps/client/src/app/services/data.service.ts | 14 +++++++++++--- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81a6da6d7..c88ee481d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Added the date range support to the portfolio holdings page + ### Changed - Removed the date range support in the activities table on the portfolio activities page (experimental) diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 56c0a231c..81d0c3df9 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -290,6 +290,7 @@ export class PortfolioController { @Query('assetClasses') filterByAssetClasses?: string, @Query('holdingType') filterByHoldingType?: string, @Query('query') filterBySearchQuery?: string, + @Query('range') dateRange: DateRange = 'max', @Query('tags') filterByTags?: string ): Promise { const filters = this.apiService.buildFiltersFromQueryParams({ @@ -301,6 +302,7 @@ export class PortfolioController { }); const { holdings } = await this.portfolioService.getDetails({ + dateRange, filters, impersonationId, userId: this.request.user.id diff --git a/apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts b/apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts index 8834593e1..107e8f307 100644 --- a/apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts +++ b/apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts @@ -123,7 +123,8 @@ export class HoldingsPageComponent implements OnDestroy, OnInit { } return this.dataService.fetchPortfolioHoldings({ - filters + filters, + range: this.user?.settings?.dateRange }); } diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts index 8a3f7d293..a1d94c646 100644 --- a/apps/client/src/app/services/data.service.ts +++ b/apps/client/src/app/services/data.service.ts @@ -464,13 +464,21 @@ export class DataService { } public fetchPortfolioHoldings({ - filters + filters, + range }: { filters?: Filter[]; - } = {}) { + range?: DateRange; + }) { + let params = this.buildFiltersAsQueryParams({ filters }); + + if (range) { + params = params.append('range', range); + } + return this.http .get('/api/v1/portfolio/holdings', { - params: this.buildFiltersAsQueryParams({ filters }) + params }) .pipe( map((response) => { From 22d63c6102647e4fe2ba13ffe1174b5a30d2410a Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 20 Apr 2024 10:49:18 +0200 Subject: [PATCH 141/203] Improve logging (#3304) * Improve logging --- .../exchange-rate-data.service.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts b/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts index a02ddb597..683002a10 100644 --- a/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts +++ b/apps/api/src/services/exchange-rate-data/exchange-rate-data.service.ts @@ -449,13 +449,16 @@ export class ExchangeRateDataService { factors[format(date, DATE_FORMAT)] = factor; } } catch { - Logger.error( - `No exchange rate has been found for ${currencyFrom}${currencyTo} at ${format( - date, - DATE_FORMAT - )}. Please complement market data for ${DEFAULT_CURRENCY}${currencyFrom} and ${DEFAULT_CURRENCY}${currencyTo}.`, - 'ExchangeRateDataService' - ); + let errorMessage = `No exchange rate has been found for ${currencyFrom}${currencyTo} at ${format( + date, + DATE_FORMAT + )}. Please complement market data for ${DEFAULT_CURRENCY}${currencyFrom}`; + + if (DEFAULT_CURRENCY !== currencyTo) { + errorMessage = `${errorMessage} and ${DEFAULT_CURRENCY}${currencyTo}`; + } + + Logger.error(`${errorMessage}.`, 'ExchangeRateDataService'); } } } From dfacbed66d7b72b9453b53bf8564a6d0c8695cdf Mon Sep 17 00:00:00 2001 From: Bastien Jeannelle <48835068+Sonlis@users.noreply.github.com> Date: Sat, 20 Apr 2024 12:00:00 +0300 Subject: [PATCH 142/203] Feature/add support to create account cash balances (#3260) * Add support to create account cash balances * Update changelog --------- Co-authored-by: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> --- CHANGELOG.md | 1 + .../account-balance.controller.ts | 39 +++++ .../account-balance/account-balance.module.ts | 3 +- .../create-account-balance.dto.ts | 12 ++ .../account-detail-dialog.component.ts | 28 +++- .../account-detail-dialog.html | 2 + apps/client/src/app/services/data.service.ts | 22 ++- libs/common/src/lib/permissions.ts | 3 + .../account-balances.component.html | 152 ++++++++++++------ .../account-balances.component.scss | 7 + .../account-balances.component.ts | 38 ++++- 11 files changed, 244 insertions(+), 63 deletions(-) create mode 100644 apps/api/src/app/account-balance/create-account-balance.dto.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index c88ee481d..06c7b37a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added the date range support to the portfolio holdings page +- Added support to create an account balance ### Changed diff --git a/apps/api/src/app/account-balance/account-balance.controller.ts b/apps/api/src/app/account-balance/account-balance.controller.ts index 943d0aeb5..12f21753b 100644 --- a/apps/api/src/app/account-balance/account-balance.controller.ts +++ b/apps/api/src/app/account-balance/account-balance.controller.ts @@ -1,3 +1,4 @@ +import { AccountService } from '@ghostfolio/api/app/account/account.service'; import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator'; import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; import { permissions } from '@ghostfolio/common/permissions'; @@ -5,6 +6,8 @@ import type { RequestWithUser } from '@ghostfolio/common/types'; import { Controller, + Body, + Post, Delete, HttpException, Inject, @@ -17,14 +20,50 @@ import { AccountBalance } from '@prisma/client'; import { StatusCodes, getReasonPhrase } from 'http-status-codes'; import { AccountBalanceService } from './account-balance.service'; +import { CreateAccountBalanceDto } from './create-account-balance.dto'; @Controller('account-balance') export class AccountBalanceController { public constructor( private readonly accountBalanceService: AccountBalanceService, + private readonly accountService: AccountService, @Inject(REQUEST) private readonly request: RequestWithUser ) {} + @HasPermission(permissions.createAccountBalance) + @Post() + @UseGuards(AuthGuard('jwt'), HasPermissionGuard) + public async createAccountBalance( + @Body() data: CreateAccountBalanceDto + ): Promise { + const account = await this.accountService.account({ + id_userId: { + id: data.accountId, + userId: this.request.user.id + } + }); + + if (!account) { + throw new HttpException( + getReasonPhrase(StatusCodes.FORBIDDEN), + StatusCodes.FORBIDDEN + ); + } + + return this.accountBalanceService.createAccountBalance({ + Account: { + connect: { + id_userId: { + id: account.id, + userId: account.userId + } + } + }, + date: data.date, + value: data.balance + }); + } + @HasPermission(permissions.deleteAccountBalance) @Delete(':id') @UseGuards(AuthGuard('jwt'), HasPermissionGuard) diff --git a/apps/api/src/app/account-balance/account-balance.module.ts b/apps/api/src/app/account-balance/account-balance.module.ts index 1fba60fce..02323acc9 100644 --- a/apps/api/src/app/account-balance/account-balance.module.ts +++ b/apps/api/src/app/account-balance/account-balance.module.ts @@ -1,3 +1,4 @@ +import { AccountService } from '@ghostfolio/api/app/account/account.service'; import { ExchangeRateDataModule } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.module'; import { PrismaModule } from '@ghostfolio/api/services/prisma/prisma.module'; @@ -10,6 +11,6 @@ import { AccountBalanceService } from './account-balance.service'; controllers: [AccountBalanceController], exports: [AccountBalanceService], imports: [ExchangeRateDataModule, PrismaModule], - providers: [AccountBalanceService] + providers: [AccountBalanceService, AccountService] }) export class AccountBalanceModule {} diff --git a/apps/api/src/app/account-balance/create-account-balance.dto.ts b/apps/api/src/app/account-balance/create-account-balance.dto.ts new file mode 100644 index 000000000..28e939b82 --- /dev/null +++ b/apps/api/src/app/account-balance/create-account-balance.dto.ts @@ -0,0 +1,12 @@ +import { IsISO8601, IsNumber, IsUUID } from 'class-validator'; + +export class CreateAccountBalanceDto { + @IsUUID() + accountId: string; + + @IsNumber() + balance: number; + + @IsISO8601() + date: string; +} diff --git a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts index 537adf1d1..2c2036b16 100644 --- a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts +++ b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts @@ -140,15 +140,33 @@ export class AccountDetailDialog implements OnDestroy, OnInit { this.dialogRef.close(); } + public onAddAccountBalance({ + balance, + date + }: { + balance: number; + date: Date; + }) { + this.dataService + .postAccountBalance({ + balance, + date, + accountId: this.data.accountId + }) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(() => { + this.fetchAccountBalances(); + this.fetchPortfolioPerformance(); + }); + } + public onDeleteAccountBalance(aId: string) { this.dataService .deleteAccountBalance(aId) .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe({ - next: () => { - this.fetchAccountBalances(); - this.fetchPortfolioPerformance(); - } + .subscribe(() => { + this.fetchAccountBalances(); + this.fetchPortfolioPerformance(); }); } diff --git a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html index 041a779c4..e092cce68 100644 --- a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html +++ b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.html @@ -115,6 +115,7 @@ diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts index a1d94c646..16d104834 100644 --- a/apps/client/src/app/services/data.service.ts +++ b/apps/client/src/app/services/data.service.ts @@ -42,7 +42,11 @@ import { translate } from '@ghostfolio/ui/i18n'; import { HttpClient, HttpParams } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { SortDirection } from '@angular/material/sort'; -import { DataSource, Order as OrderModel } from '@prisma/client'; +import { + AccountBalance, + DataSource, + Order as OrderModel +} from '@prisma/client'; import { format, parseISO } from 'date-fns'; import { cloneDeep, groupBy, isNumber } from 'lodash'; import { Observable } from 'rxjs'; @@ -611,6 +615,22 @@ export class DataService { return this.http.post(`/api/v1/account`, aAccount); } + public postAccountBalance({ + accountId, + balance, + date + }: { + accountId: string; + balance: number; + date: Date; + }) { + return this.http.post(`/api/v1/account-balance`, { + accountId, + balance, + date + }); + } + public postBenchmark(benchmark: UniqueAsset) { return this.http.post(`/api/v1/benchmark`, benchmark); } diff --git a/libs/common/src/lib/permissions.ts b/libs/common/src/lib/permissions.ts index 09bbfa1bd..890cb8b63 100644 --- a/libs/common/src/lib/permissions.ts +++ b/libs/common/src/lib/permissions.ts @@ -7,6 +7,7 @@ export const permissions = { accessAssistant: 'accessAssistant', createAccess: 'createAccess', createAccount: 'createAccount', + createAccountBalance: 'createAccountBalance', createOrder: 'createOrder', createPlatform: 'createPlatform', createTag: 'createTag', @@ -47,6 +48,7 @@ export function getPermissions(aRole: Role): string[] { permissions.accessAssistant, permissions.createAccess, permissions.createAccount, + permissions.createAccountBalance, permissions.deleteAccountBalance, permissions.createOrder, permissions.createPlatform, @@ -75,6 +77,7 @@ export function getPermissions(aRole: Role): string[] { permissions.accessAssistant, permissions.createAccess, permissions.createAccount, + permissions.createAccountBalance, permissions.createOrder, permissions.deleteAccess, permissions.deleteAccount, diff --git a/libs/ui/src/lib/account-balances/account-balances.component.html b/libs/ui/src/lib/account-balances/account-balances.component.html index 0d1a79f41..0cfa4a5da 100644 --- a/libs/ui/src/lib/account-balances/account-balances.component.html +++ b/libs/ui/src/lib/account-balances/account-balances.component.html @@ -1,60 +1,106 @@ - - - - - + +
- Date - - -
+ + + + + - - - - + + + + + - - - + + - + + - - -
+ Date + + + + + + + + + + + - Value - -
- -
-
+ Value + +
+ +
+
+
+ + +
+ {{ accountCurrency }} +
+
+
+
- @if (showActions) { + + + @if (showActions) { + + } + + + + - } - - - -
+ + + + + diff --git a/libs/ui/src/lib/account-balances/account-balances.component.scss b/libs/ui/src/lib/account-balances/account-balances.component.scss index 5d4e87f30..0bf48a9e7 100644 --- a/libs/ui/src/lib/account-balances/account-balances.component.scss +++ b/libs/ui/src/lib/account-balances/account-balances.component.scss @@ -1,3 +1,10 @@ :host { display: block; } + +:host-context(.is-dark-theme) { + input { + color: rgb(var(--light-primary-text)); + background-color: rgb(var(--palette-foreground-text-light)); + } +} diff --git a/libs/ui/src/lib/account-balances/account-balances.component.ts b/libs/ui/src/lib/account-balances/account-balances.component.ts index 9d9e8ab19..c4fd379c8 100644 --- a/libs/ui/src/lib/account-balances/account-balances.component.ts +++ b/libs/ui/src/lib/account-balances/account-balances.component.ts @@ -14,7 +14,17 @@ import { Output, ViewChild } from '@angular/core'; +import { + FormGroup, + FormControl, + Validators, + ReactiveFormsModule +} from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; +import { DateAdapter } from '@angular/material/core'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; import { MatMenuModule } from '@angular/material/menu'; import { MatSort, MatSortModule } from '@angular/material/sort'; import { MatTableDataSource, MatTableModule } from '@angular/material/table'; @@ -29,9 +39,13 @@ import { GfValueComponent } from '../value'; CommonModule, GfValueComponent, MatButtonModule, + MatDatepickerModule, + MatFormFieldModule, + MatInputModule, MatMenuModule, MatSortModule, - MatTableModule + MatTableModule, + ReactiveFormsModule ], schemas: [CUSTOM_ELEMENTS_SCHEMA], selector: 'gf-account-balances', @@ -43,24 +57,38 @@ export class GfAccountBalancesComponent implements OnChanges, OnDestroy, OnInit { @Input() accountBalances: AccountBalancesResponse['balances']; + @Input() accountCurrency: string; @Input() accountId: string; @Input() locale = getLocale(); @Input() showActions = true; + @Output() accountBalanceCreated = new EventEmitter<{ + balance: number; + date: Date; + }>(); @Output() accountBalanceDeleted = new EventEmitter(); @ViewChild(MatSort) sort: MatSort; + public accountBalanceForm = new FormGroup({ + balance: new FormControl(0, Validators.required), + date: new FormControl(new Date(), Validators.required) + }); + public dataSource: MatTableDataSource< AccountBalancesResponse['balances'][0] > = new MatTableDataSource(); + public displayedColumns: string[] = ['date', 'value', 'actions']; + public Validators = Validators; private unsubscribeSubject = new Subject(); - public constructor() {} + public constructor(private dateAdapter: DateAdapter) {} - public ngOnInit() {} + public ngOnInit() { + this.dateAdapter.setLocale(this.locale); + } public ngOnChanges() { if (this.accountBalances) { @@ -81,6 +109,10 @@ export class GfAccountBalancesComponent } } + public onSubmitAccountBalance() { + this.accountBalanceCreated.emit(this.accountBalanceForm.getRawValue()); + } + public ngOnDestroy() { this.unsubscribeSubject.next(); this.unsubscribeSubject.complete(); From 458ee159e19a416350861b0089f9bce5343e685c Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 20 Apr 2024 12:14:50 +0200 Subject: [PATCH 143/203] Feature/upgrade nx to version 18.3.3 (#3307) * Upgrade angular and Nx dependencies * Update changelog --- CHANGELOG.md | 2 + package.json | 60 ++--- yarn.lock | 710 +++++++++++++++++++++++++++------------------------ 3 files changed, 403 insertions(+), 369 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06c7b37a9..935981c20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Removed the date range support in the activities table on the portfolio activities page (experimental) +- Upgraded `angular` from version `17.3.3` to `17.3.5` +- Upgraded `Nx` from version `18.2.3` to `18.3.3` ## 2.73.0 - 2024-04-17 diff --git a/package.json b/package.json index 3abee2dc8..efd40e324 100644 --- a/package.json +++ b/package.json @@ -54,17 +54,17 @@ "workspace-generator": "nx workspace-generator" }, "dependencies": { - "@angular/animations": "17.3.3", - "@angular/cdk": "17.3.3", - "@angular/common": "17.3.3", - "@angular/compiler": "17.3.3", - "@angular/core": "17.3.3", - "@angular/forms": "17.3.3", - "@angular/material": "17.3.3", - "@angular/platform-browser": "17.3.3", - "@angular/platform-browser-dynamic": "17.3.3", - "@angular/router": "17.3.3", - "@angular/service-worker": "17.3.3", + "@angular/animations": "17.3.5", + "@angular/cdk": "17.3.5", + "@angular/common": "17.3.5", + "@angular/compiler": "17.3.5", + "@angular/core": "17.3.5", + "@angular/forms": "17.3.5", + "@angular/material": "17.3.5", + "@angular/platform-browser": "17.3.5", + "@angular/platform-browser-dynamic": "17.3.5", + "@angular/router": "17.3.5", + "@angular/service-worker": "17.3.5", "@codewithdan/observable-store": "2.2.15", "@dfinity/agent": "0.15.7", "@dfinity/auth-client": "0.15.7", @@ -136,29 +136,29 @@ "zone.js": "0.14.4" }, "devDependencies": { - "@angular-devkit/build-angular": "17.3.3", - "@angular-devkit/core": "17.3.3", - "@angular-devkit/schematics": "17.3.3", + "@angular-devkit/build-angular": "17.3.5", + "@angular-devkit/core": "17.3.5", + "@angular-devkit/schematics": "17.3.5", "@angular-eslint/eslint-plugin": "17.3.0", "@angular-eslint/eslint-plugin-template": "17.3.0", "@angular-eslint/template-parser": "17.3.0", - "@angular/cli": "17.3.3", - "@angular/compiler-cli": "17.3.3", - "@angular/language-service": "17.3.3", - "@angular/localize": "17.3.3", - "@angular/pwa": "17.3.3", + "@angular/cli": "17.3.5", + "@angular/compiler-cli": "17.3.5", + "@angular/language-service": "17.3.5", + "@angular/localize": "17.3.5", + "@angular/pwa": "17.3.5", "@nestjs/schematics": "10.0.1", "@nestjs/testing": "10.1.3", - "@nx/angular": "18.2.3", - "@nx/cypress": "18.2.3", - "@nx/eslint-plugin": "18.2.3", - "@nx/jest": "18.2.3", - "@nx/js": "18.2.3", - "@nx/nest": "18.2.3", - "@nx/node": "18.2.3", - "@nx/storybook": "18.2.3", - "@nx/web": "18.2.3", - "@nx/workspace": "18.2.3", + "@nx/angular": "18.3.3", + "@nx/cypress": "18.3.3", + "@nx/eslint-plugin": "18.3.3", + "@nx/jest": "18.3.3", + "@nx/js": "18.3.3", + "@nx/nest": "18.3.3", + "@nx/node": "18.3.3", + "@nx/storybook": "18.3.3", + "@nx/web": "18.3.3", + "@nx/workspace": "18.3.3", "@schematics/angular": "17.3.3", "@simplewebauthn/types": "9.0.1", "@storybook/addon-essentials": "7.6.5", @@ -187,7 +187,7 @@ "jest": "29.4.3", "jest-environment-jsdom": "29.4.3", "jest-preset-angular": "14.0.3", - "nx": "18.2.3", + "nx": "18.3.3", "prettier": "3.2.5", "prettier-plugin-organize-attributes": "1.0.0", "react": "18.2.0", diff --git a/yarn.lock b/yarn.lock index bdfbec1b2..2eda4d271 100644 --- a/yarn.lock +++ b/yarn.lock @@ -28,12 +28,12 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@angular-devkit/architect@0.1703.3": - version "0.1703.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1703.3.tgz#d60cdc2d2ad3b204d8b353124a8defa92c40db69" - integrity sha512-BKbdigCjmspqxOxSIQuWgPZzpyuKqZoTBDh0jDeLcAmvPsuxCgIWbsExI4OQ0CyusnQ+XT0IT39q8B9rvF56cg== +"@angular-devkit/architect@0.1703.5": + version "0.1703.5" + resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1703.5.tgz#2e6e534c99fd99d53034237d64de6317f24af52a" + integrity sha512-j3+9QeXIafuRMtk7N5Cmm/IiMSS/TOaybzfCv/LK+DP3hjEd8f8Az7hPmevUuOArvWNzUvoUeu30GmR3wABydA== dependencies: - "@angular-devkit/core" "17.3.3" + "@angular-devkit/core" "17.3.5" rxjs "7.8.1" "@angular-devkit/architect@^0.1301.0 || ^0.1401.0 || ^0.1501.0 || ^0.1601.0 || ^0.1700.0": @@ -44,15 +44,15 @@ "@angular-devkit/core" "17.0.0" rxjs "7.8.1" -"@angular-devkit/build-angular@17.3.3": - version "17.3.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-17.3.3.tgz#94b610596300a8acba22f5c30dcb03220cbd96da" - integrity sha512-E/6Z1MIMhEB1I2sN+Pw4/zinwAFj4vLDh6dEuj856WWEPndgPiUB6fGX4EbCTsyIUzboXI5ysdNyt2Eq56bllA== +"@angular-devkit/build-angular@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-17.3.5.tgz#a1b1fdfe906a0132191c0fee56c2a1dc0a1d5f8f" + integrity sha512-Ju2MkMidJglJq/iWgM9CNbhK7A/2n0LNYPZx+ucb+aOFWvurCQrU4Mt/es6xCsxOEs5OPhjqdva8mxE5FHwzTQ== dependencies: "@ampproject/remapping" "2.3.0" - "@angular-devkit/architect" "0.1703.3" - "@angular-devkit/build-webpack" "0.1703.3" - "@angular-devkit/core" "17.3.3" + "@angular-devkit/architect" "0.1703.5" + "@angular-devkit/build-webpack" "0.1703.5" + "@angular-devkit/core" "17.3.5" "@babel/core" "7.24.0" "@babel/generator" "7.23.6" "@babel/helper-annotate-as-pure" "7.22.5" @@ -63,7 +63,7 @@ "@babel/preset-env" "7.24.0" "@babel/runtime" "7.24.0" "@discoveryjs/json-ext" "0.5.7" - "@ngtools/webpack" "17.3.3" + "@ngtools/webpack" "17.3.5" "@vitejs/plugin-basic-ssl" "1.1.0" ansi-colors "4.1.3" autoprefixer "10.4.18" @@ -104,8 +104,8 @@ terser "5.29.1" tree-kill "1.2.2" tslib "2.6.2" - undici "6.7.1" - vite "5.1.5" + undici "6.11.1" + vite "5.1.7" watchpack "2.4.0" webpack "5.90.3" webpack-dev-middleware "6.1.2" @@ -115,12 +115,12 @@ optionalDependencies: esbuild "0.20.1" -"@angular-devkit/build-webpack@0.1703.3": - version "0.1703.3" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1703.3.tgz#b7fcc2fa2c0c6ba4cc1dcdd8d108c8f536d03a60" - integrity sha512-d0JjE8MaGVNphlJfeP1OZKhNT4wCXkEZKdSdwE0+W+vDHNUuZiUBB1czO48sb7T4xBrdjRWlV/9CzMNJ7n3ydA== +"@angular-devkit/build-webpack@0.1703.5": + version "0.1703.5" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1703.5.tgz#3f8912aacb5b0d986e1f86756a40e4d21b3d7855" + integrity sha512-KcoKlWhDP6+2q3laQ6elXLt2QrVxWJFdCPUC9dIm0Tnc997Tal/UVhlDKaZgITYDgDvRFqG+tzNm2uFd8l7h+A== dependencies: - "@angular-devkit/architect" "0.1703.3" + "@angular-devkit/architect" "0.1703.5" rxjs "7.8.1" "@angular-devkit/core@16.0.1": @@ -169,6 +169,18 @@ rxjs "7.8.1" source-map "0.7.4" +"@angular-devkit/core@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-17.3.5.tgz#5af01de95b4945587aea1feaa1011f87485ffee5" + integrity sha512-iqGv45HVI+yRROoTqQTY0QChYlRCZkFUfIjdfJLegjc6xq9sLtxDr03CWM45BKGG5lSxDOy+qu/pdRvtL3V2eg== + dependencies: + ajv "8.12.0" + ajv-formats "2.1.1" + jsonc-parser "3.2.1" + picomatch "4.0.1" + rxjs "7.8.1" + source-map "0.7.4" + "@angular-devkit/schematics@16.0.1": version "16.0.1" resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-16.0.1.tgz#d49387e9e41c9cce98b155da51b0e193333dd178" @@ -213,6 +225,17 @@ ora "5.4.1" rxjs "7.8.1" +"@angular-devkit/schematics@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-17.3.5.tgz#5ea31a3e5d7dc5eb11f786b796d0536f0a9b05bd" + integrity sha512-oh/mvpMKxGfk5v9QIB7LfGsDC/iVpmsIAvbb4+1ddCx86EJXdz3xWnVDbUehOd6n7HJXnQrNirWjWvWquM2GhQ== + dependencies: + "@angular-devkit/core" "17.3.5" + jsonc-parser "3.2.1" + magic-string "0.30.8" + ora "5.4.1" + rxjs "7.8.1" + "@angular-eslint/bundled-angular-compiler@17.3.0": version "17.3.0" resolved "https://registry.yarnpkg.com/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-17.3.0.tgz#08b8b1bebbb677a1f208b56516fc9177a289d212" @@ -254,31 +277,31 @@ "@angular-eslint/bundled-angular-compiler" "17.3.0" "@typescript-eslint/utils" "7.2.0" -"@angular/animations@17.3.3": - version "17.3.3" - resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-17.3.3.tgz#b6487fbaa970cfd1f998d72a61e74c7e3deb14be" - integrity sha512-poLW3FHe5wkxmTIsQ3em2vq4obgQHyZJz6biF+4hCqQSNMbMBS0e5ZycAiJLkUD/WLc88lQZ20muRO7qjVuMLA== +"@angular/animations@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-17.3.5.tgz#68f1f209137b3e7148143b66ab3a2b444ac9b546" + integrity sha512-hbfCnBxwhYQMKB+9tDcmfvckUtB8LdY1gPST6TZ7CzrWCSPddsnXxqxBZSBjBI6zXvE4FOV3kUzaUXM/Bq5sRw== dependencies: tslib "^2.3.0" -"@angular/cdk@17.3.3": - version "17.3.3" - resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-17.3.3.tgz#a266eb76a91ee2ce8f1e2df4bdc9a40b8dab29eb" - integrity sha512-hfS9pwaNE6CTZqP3FBh9tZPbuf//bDqZ5IpMzscfDFrwX8ycxBiI3znH/rFSf9l1rL0OQGoqWWNVfJCT+RrukA== +"@angular/cdk@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-17.3.5.tgz#a610ec34fe7adb4ebd30798664a421ce204c653d" + integrity sha512-6y8+yIPWG0wTdPwHIPxKrEFCX1JxxBh4aXcmQnrNTDIvtoEPGaea9SU9XKaU8ahiZMlcpUXqKLG0BVbEhA1Oow== dependencies: tslib "^2.3.0" optionalDependencies: parse5 "^7.1.2" -"@angular/cli@17.3.3": - version "17.3.3" - resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-17.3.3.tgz#66880fb12b0d4e536222ec7a256431795fe344c9" - integrity sha512-veIGK2sRm0SfiLHeftx0W0xC3N8uxoqxXiSG57V6W2wIFN/fKm3aRq3sa8phz7vxUzoKGqyZh6hsT7ybkjgkGA== +"@angular/cli@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-17.3.5.tgz#f668db09d283d669e42f166b7c9cfc0a8298b0a3" + integrity sha512-6MHJzPKy4uB9qlJO1eKs4rtDlRuCe0lOiz1f3kHFZ/GQQm5xA1xsmZJMN4ASsnu4yU3oZs6vJ/vt8i2/jvdPbA== dependencies: - "@angular-devkit/architect" "0.1703.3" - "@angular-devkit/core" "17.3.3" - "@angular-devkit/schematics" "17.3.3" - "@schematics/angular" "17.3.3" + "@angular-devkit/architect" "0.1703.5" + "@angular-devkit/core" "17.3.5" + "@angular-devkit/schematics" "17.3.5" + "@schematics/angular" "17.3.5" "@yarnpkg/lockfile" "1.1.0" ansi-colors "4.1.3" ini "4.1.2" @@ -294,17 +317,17 @@ symbol-observable "4.0.0" yargs "17.7.2" -"@angular/common@17.3.3": - version "17.3.3" - resolved "https://registry.yarnpkg.com/@angular/common/-/common-17.3.3.tgz#6bbd0c033446010ada04511b6955d048259cf9d7" - integrity sha512-GwlKetNpfWKiG2j4S6bYTi6PA2iT4+eln7o8owo44xZWdQnWQjfxnH39vQuCyhi6OOQL1dozmae+fVXgQsV6jQ== +"@angular/common@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-17.3.5.tgz#901f5d85b78f5e28f36156064961d58732e73a7b" + integrity sha512-Ox91WxSnOSrQ6I21cHi69EfT2Pxtd5Knb5AsdwpxqE57V2E7EnWMhb+LP+holCtFUhK529EGXCk788M+Elyw6g== dependencies: tslib "^2.3.0" -"@angular/compiler-cli@17.3.3": - version "17.3.3" - resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-17.3.3.tgz#e2505b95b0d56118ea0950eae18bb0fa2c2e7515" - integrity sha512-vM0lqwuXQZ912HbLnIuvUblvIz2WEUsU7a5Z2ieNey6famH4zxPH12vCbVwXgicB6GLHorhOfcWC5443wD2mJw== +"@angular/compiler-cli@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-17.3.5.tgz#d24cb2039d130b03a898ec3bedf7cbabb573ba03" + integrity sha512-R53JNbbVDHWSGdL0e2vGQ5iJCrILOWZ1oemKjekOFB93fUBlEyi+nZmm4uTO7RU8PgjB0UpxI6ok5ZE3Amkt6A== dependencies: "@babel/core" "7.23.9" "@jridgewell/sourcemap-codec" "^1.4.14" @@ -315,10 +338,10 @@ tslib "^2.3.0" yargs "^17.2.1" -"@angular/compiler@17.3.3": - version "17.3.3" - resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-17.3.3.tgz#ac6aefbb01f031b5834477aff46aa267719f7156" - integrity sha512-ZNMRfagMxMjk1KW5H3ssCg5QL0J6ZW1JAZ1mrTXixqS7gbdwl60bTGE+EfuEwbjvovEYaj4l9cga47eMaxZTbQ== +"@angular/compiler@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-17.3.5.tgz#308ac763c2a95fb6cea764d1ec3e8bd5f2384b89" + integrity sha512-lTubBFNlpH9zK46+yeVI7VJQNUELLAB8W1ucndYLCA9Rr9Jop+rYIXijmr42AGokOYr7yLc8HRiSQ5e+X2pUQg== dependencies: tslib "^2.3.0" @@ -327,10 +350,10 @@ resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-9.0.0.tgz#87e0bef4c369b6cadae07e3a4295778fc93799d5" integrity sha512-ctjwuntPfZZT2mNj2NDIVu51t9cvbhl/16epc5xEwyzyDt76pX9UgwvY+MbXrf/C/FWwdtmNtfP698BKI+9leQ== -"@angular/core@17.3.3": - version "17.3.3" - resolved "https://registry.yarnpkg.com/@angular/core/-/core-17.3.3.tgz#e0fd86eccd0106a5b8602c56eb4449cbb4538219" - integrity sha512-O/jr3aFJMCxF6Jmymjx4jIigRHJfqM/ALIi60y2LVznBVFkk9xyMTsAjgWQIEHX+2muEIzgfKuXzpL0y30y+wA== +"@angular/core@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-17.3.5.tgz#5445e5dad4dc713b032dde10dc048169afe998db" + integrity sha512-y6P27lcrKy3yMx/rtMuGsAnDyVEsS3BdyArTXcD0TOImVGHhVIaB0L95DUCam3ajTe2f2x39eozJZDh7QSpJaw== dependencies: tslib "^2.3.0" @@ -339,32 +362,32 @@ resolved "https://registry.yarnpkg.com/@angular/core/-/core-9.0.0.tgz#227dc53e1ac81824f998c6e76000b7efc522641e" integrity sha512-6Pxgsrf0qF9iFFqmIcWmjJGkkCaCm6V5QNnxMy2KloO3SDq6QuMVRbN9RtC8Urmo25LP+eZ6ZgYqFYpdD8Hd9w== -"@angular/forms@17.3.3": - version "17.3.3" - resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-17.3.3.tgz#ff00da4f7ab1f6fefda7b3c323ddb07c2a4b23ac" - integrity sha512-wqn+eAggbOZY91hr7oDjv5qdflszVOC9SZMcWJUoZTGn+8eoV6v6728GDFuDDwYkKQ9G9eQbX4IZmYoVw3TVjQ== +"@angular/forms@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-17.3.5.tgz#68a1511c1c2b147d704f2579563840c3f94cb714" + integrity sha512-Rf/8XWHdFYZQaOVTJ0QVwxQm9fDqQqIJc0yfPcH/DYL5pT7R0U2z98I5McZawzUBJUo1Zt1gijzDlzNUGf6jiA== dependencies: tslib "^2.3.0" -"@angular/language-service@17.3.3": - version "17.3.3" - resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-17.3.3.tgz#99b26aabc10b210e1cedf4b8cca1cac64ccf4183" - integrity sha512-OtdWNY0Syg4UvA8j2IhQJeq/UjWHYbRiyUcZjGKPRzuqIPjUhsmMyuW3zpi7Pwx2CpBzZXcik1Ra2WZ0gbwigg== +"@angular/language-service@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-17.3.5.tgz#64d31f5948f24bc2217047be1899b34c177c8cc6" + integrity sha512-s3W5o+pRPU3jNWeeyO4XEdc28+s4MPhew+k0meQfZ11VMdmShzwFu5nPgOMmLB3fBhQqlSBrHUh1P9SB7Hu3FQ== -"@angular/localize@17.3.3": - version "17.3.3" - resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-17.3.3.tgz#3f9c3c66eb02648edc9c8d348124d7170bab1946" - integrity sha512-gahGKy0VBZ+KP6MUULGQMoi5SN3REwslaPvtomizzz9fdmqHfR8PPd1vOJSNm2IEVlvm1hv1dDRjPcR4DJwvaQ== +"@angular/localize@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-17.3.5.tgz#2af9f4f5db3c0b99d55534ef14058c6831a2fb4d" + integrity sha512-/5iKRvnleA2vsf8zqNZaXeOBjFFq3FLrbot+ygfmk3uYqz949X0nXrXBKk9kpakw/WC6kgzK+tmiEHKQY6cLiQ== dependencies: "@babel/core" "7.23.9" "@types/babel__core" "7.20.5" fast-glob "3.3.2" yargs "^17.2.1" -"@angular/material@17.3.3": - version "17.3.3" - resolved "https://registry.yarnpkg.com/@angular/material/-/material-17.3.3.tgz#33f7ca38d3c0ff909bde4e8ae490ea2da49ecd3f" - integrity sha512-cb3PYY+Lf3FvXxXIRmOBcTn5QS9Ghr5Eq0aiJiiYV6YVohr0YGWsndMCZ/5a2j8fxpboDo9THeTnOuuAOJv7AA== +"@angular/material@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular/material/-/material-17.3.5.tgz#66e5479ba342277b0549cc301f0578ef51c40c3c" + integrity sha512-1+QqBQ8HVOwxOkx/v2n53JA9ALOee55yVDbnAv7TkseNN4JEDxOcE5TO5HGmdV2A4tcsXQ00MIdy04jiB4sCng== dependencies: "@material/animation" "15.0.0-canary.7f224ddd4.0" "@material/auto-init" "15.0.0-canary.7f224ddd4.0" @@ -415,40 +438,40 @@ "@material/typography" "15.0.0-canary.7f224ddd4.0" tslib "^2.3.0" -"@angular/platform-browser-dynamic@17.3.3": - version "17.3.3" - resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-17.3.3.tgz#0e747cecb51ebaec53c11ebfef289972b793484d" - integrity sha512-jSgSNHRTXCIat20I+4tLm/e8qOvrIE3Zv7S/DtYZEiAth84uoznvo1kXnN+KREse2vP/WoNgSDKQ2JLzkwYXSQ== +"@angular/platform-browser-dynamic@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-17.3.5.tgz#39cedb2144e093a7b6127a694565c6b1afb8b872" + integrity sha512-KuS4j3Gh1h/CEj+bIOc/IcZIdiCB/DNbtUvz1eNp1o23aM8QutqelI3A4WBnQuR4yq8Z/8M3FH9F1OVwwhn2QQ== dependencies: tslib "^2.3.0" -"@angular/platform-browser@17.3.3": - version "17.3.3" - resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-17.3.3.tgz#b00a68526e2f39e9797ad4696f9dd8b42451f268" - integrity sha512-XFWjquD+Pr9VszRzrDlT6uaf57TsY9XhL9iHCNok6Op5DpVQpIAuw1vFt2t5ZoQ0gv+lY8mVWnxgqe3CgTdYxw== +"@angular/platform-browser@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-17.3.5.tgz#f1b3832163a7bfccb8e7c3cafa0246226f03a6aa" + integrity sha512-ITlu/GTD64Sr0FMaFCJiHoTJrEZw8qRFXjPjv3BKhAp5dQKcwnCm02o1NOaj5d8oIItIh5fbI2zP0CSU2qNZkQ== dependencies: tslib "^2.3.0" -"@angular/pwa@17.3.3": - version "17.3.3" - resolved "https://registry.yarnpkg.com/@angular/pwa/-/pwa-17.3.3.tgz#28851976b5763b2e6608dafc6fdd86af1416d42a" - integrity sha512-my2EHZ+ld9L+r2BUfL1Mq9ozUvE+1BY3bav5o4ZkwwtQOZ3XTqYIK2v3Z5O/Mot3XAIAeUR9rksoHGtCZcagMg== +"@angular/pwa@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular/pwa/-/pwa-17.3.5.tgz#c0f9fb156a4dcd8961de191638728f18bd431854" + integrity sha512-qa1w36x/oRErS9eMTUkmVolA7G/d6lEshAs4RprGxh/2cZ5WkrOxdzb2u1KAEZr0X/C6118laFvr6KRyPCsxpw== dependencies: - "@angular-devkit/schematics" "17.3.3" - "@schematics/angular" "17.3.3" + "@angular-devkit/schematics" "17.3.5" + "@schematics/angular" "17.3.5" parse5-html-rewriting-stream "7.0.0" -"@angular/router@17.3.3": - version "17.3.3" - resolved "https://registry.yarnpkg.com/@angular/router/-/router-17.3.3.tgz#29859efaeaf9e70ff098011679d1407b68de5997" - integrity sha512-kj42+TtwvET7MFqxB3pkKyob0VNmspASlv8Y29vSpzzaOHn8J1fDf6H+8opoIC+Gmvo5NqXUDwq7nxI5aQ0mUQ== +"@angular/router@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-17.3.5.tgz#6498d91560296424a2e2bc8a09cd0d9d81058a85" + integrity sha512-KsIIs3t9IpxsdMSrJDZzO5WgIWkVE6Ep5WWiSyPIgEfA+ndGpJLmyv0d/r1yKKlYUJxz7Hde55o4thgT2n2x/A== dependencies: tslib "^2.3.0" -"@angular/service-worker@17.3.3": - version "17.3.3" - resolved "https://registry.yarnpkg.com/@angular/service-worker/-/service-worker-17.3.3.tgz#cd8c83793771e93e0a98192428d956d92e9cb487" - integrity sha512-ZS7MPNPdvIoNKuPfK2pukKiyn+OXVMUALBjSH6k2ayiKxhMiNBCybA4KkQf6DZ9NIlKiGoBc46wf7FZybWAYbQ== +"@angular/service-worker@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@angular/service-worker/-/service-worker-17.3.5.tgz#7e297ef8a654b517cbb93cb6ac702df815068e21" + integrity sha512-YJBSxlrLDUINHjy1GTrbfmUJOUf2ArLN2y/nM4OOsIev7w0d6PIqruKX7wnT6tl6jJZwFRcEGulo/bSd68P63A== dependencies: tslib "^2.3.0" @@ -4858,10 +4881,10 @@ dependencies: tslib "2.6.1" -"@ngtools/webpack@17.3.3": - version "17.3.3" - resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-17.3.3.tgz#da62af790e2d7280fe8b03f5dbff343580ffc0f0" - integrity sha512-053KMbg1Tb+Mmg4Htsv8yTpI7ABghguoxhwosQXKB0CjO6M0oexuvdaxbRDQ1vd5xYNOW9LcOfxOMPIwyU4BBA== +"@ngtools/webpack@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-17.3.5.tgz#5f1a8d6e59e8fb37b8f1a4fe69116d9f46f2102f" + integrity sha512-0heI0yHUckdGI8uywu/wkp24KR/tdYMKYJOaYIU+9JydyN1zJRpbR7x0thddl7+k/zu2ZGbfFdv1779Ecw/xdA== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -4947,98 +4970,98 @@ read-package-json-fast "^3.0.0" which "^4.0.0" -"@nrwl/angular@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nrwl/angular/-/angular-18.2.3.tgz#eb65c229726c50f00d78e679d5696b0494548a24" - integrity sha512-F0RtvSIH/Qs0ju7VcdfBpDeBZvwio2g4KdNpRog9ZBlgJjEmRWu7aA733A2xng96IkJkIrO0DiJaFbNdm8Yelw== +"@nrwl/angular@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nrwl/angular/-/angular-18.3.3.tgz#63d7b65e4d96637d7361d018ec56d061595cb0d4" + integrity sha512-pQsxy58DZBVna3qeJH+osdiRBpx+FCAnCz5kogO6EmRsM17zP4zGpgijVHorAI4EjCNhl2vWa3X/bZ8yQIFBpg== dependencies: - "@nx/angular" "18.2.3" + "@nx/angular" "18.3.3" tslib "^2.3.0" -"@nrwl/cypress@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nrwl/cypress/-/cypress-18.2.3.tgz#934f7615f347ece85025a925de2e132a9a924164" - integrity sha512-P44e3hmhXWK6jALoHK8bAVUvIqGP8SCX/GM/e6jVAZIjvAC+L69WTkAXVLgZkiD8WpZegSho47AtaL1D256a/g== +"@nrwl/cypress@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nrwl/cypress/-/cypress-18.3.3.tgz#3b85e45169c3aff23ea46e19835956a355111b22" + integrity sha512-CsoPFX+iLwvc/+Im/zZsk3FP8c8epBMmI8GNvZFnDZe8J9bdBmtlxp8/Yh3LdUw8ycmPGPvW7eggv31yNZmT+Q== dependencies: - "@nx/cypress" "18.2.3" + "@nx/cypress" "18.3.3" -"@nrwl/devkit@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-18.2.3.tgz#4de5589b99c6e5a15da334630079d027a59fdd4c" - integrity sha512-BJQdPmXFze7g4zsHhwSTssAcm/hvl0rXbIzZYQxncsVU4d+Fx0GS3JYBZ+9EcfnCeAEb10jGvn7Rfk+0okMmOw== +"@nrwl/devkit@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-18.3.3.tgz#9ec5575afe6d14b17acd5e8da4e98a0de27704c6" + integrity sha512-3zZLE1vfwsNie7qjVUt9lqaM1slU0RTr/dW+Yt/2lxe8Peu6f8bnCM1Pf3kSlzoxQroctfocRtVHFXJsAuAt4g== dependencies: - "@nx/devkit" "18.2.3" + "@nx/devkit" "18.3.3" -"@nrwl/eslint-plugin-nx@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nrwl/eslint-plugin-nx/-/eslint-plugin-nx-18.2.3.tgz#f66513f8a2bbb63f3555129f8d8236a0936d7573" - integrity sha512-hwIqxp2A0G250tFzEDmVbhwhtldoB7858848AME99Nt9Ij27ThzYaLIG+TYicmb+Rq2FqG9G/6wS89eg1aAg2Q== +"@nrwl/eslint-plugin-nx@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nrwl/eslint-plugin-nx/-/eslint-plugin-nx-18.3.3.tgz#b41316daa9ac7f55379cb4510767f7a865c920a6" + integrity sha512-ARqwcA2n2NN+8ATrooZtPbaW5fb9WSjDFZaI8RdphMXFnPrEkZnMpbrjFpLTj+wc1R6hIgTcYbli6fv4Gfbo3Q== dependencies: - "@nx/eslint-plugin" "18.2.3" + "@nx/eslint-plugin" "18.3.3" -"@nrwl/jest@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nrwl/jest/-/jest-18.2.3.tgz#f603d310729b216788d00d70ad0c00193f8bc430" - integrity sha512-64Ebl6GYOQ8AWp/MpPx8qXwKla3x0wnVGjJK4gUGOJ9ShMQnzd4hgYLpVuB4Des7QSxXoict3YVOVocY0joNow== +"@nrwl/jest@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nrwl/jest/-/jest-18.3.3.tgz#6d75e59c47be007cbe4b78c23fd3e08fe954ed68" + integrity sha512-BPI0mIbmjTHFb0/qtMND59ECld7gorV+SEVLwf4BLl7SWumVB2gLAA2+yx71cvF1jO4R5Ndi2FrBwBC9E2Va5Q== dependencies: - "@nx/jest" "18.2.3" + "@nx/jest" "18.3.3" -"@nrwl/js@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nrwl/js/-/js-18.2.3.tgz#f7aa58ae957403215ca2507c6740245796a27d3e" - integrity sha512-fOpKQg7CvzOmcow9fbBc5l96Pbv8gTe9qba4jiw3Z+EH776qraNBL9pRpff653V+obVh//gkq84BUeoJgk8vzQ== +"@nrwl/js@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nrwl/js/-/js-18.3.3.tgz#e1a83fb43541cd06752aced6dd7ad932d0c1afa1" + integrity sha512-7Wtv5kpeMWUDBUFu5go49HM/S8vDrtMOvZf9xnUcnjsFDReWe8XIEkTWudZDbzID3X4T6WQAftzj2Ov6k566lQ== dependencies: - "@nx/js" "18.2.3" + "@nx/js" "18.3.3" -"@nrwl/nest@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nrwl/nest/-/nest-18.2.3.tgz#c4544725ab375f1189e719b50410d38c36bcec95" - integrity sha512-hQqh3kGZ6Ky7zHzyRDNnzZ57Egn7w96IEfABsT2nnpej0LPWebryPefGSAI4Afgy2q8jSUFj9Bgjf6j93Ogiqg== +"@nrwl/nest@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nrwl/nest/-/nest-18.3.3.tgz#28709e32ef4cef6db06a9e219de46ae9b9f40378" + integrity sha512-LIyCiS73O58n7NRWT/SnuA8xHWDu4ANLd9fvguyAzXk1TcPekFvTo6zpY+iu0lkxJ7RfvZHVDGC90bIFSyV9YA== dependencies: - "@nx/nest" "18.2.3" + "@nx/nest" "18.3.3" -"@nrwl/node@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nrwl/node/-/node-18.2.3.tgz#fff8c16005c41c8c7d3fe6b7ee4a1b4446e44461" - integrity sha512-cQWAAtG+AexiWsU+5DRfEvbHhU0vkcvhdD3yUG8HjcMjc7eHS82PPxWUk/EzEI/3+3fYcHhSw5F/WyqaVkYJaw== +"@nrwl/node@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nrwl/node/-/node-18.3.3.tgz#eb0850a8e7877332550d7e06e7c959d0842b25e2" + integrity sha512-87PXppPqI/jOl6swYVdQi8RBveOF7Oqmqw9m9eEbts6U2bazPipKTwBO4E9afkz3GMqaxe+d2H794JqH05Mr8w== dependencies: - "@nx/node" "18.2.3" + "@nx/node" "18.3.3" -"@nrwl/storybook@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nrwl/storybook/-/storybook-18.2.3.tgz#340b10b845dfa373c0513fba40213631e6d0bf51" - integrity sha512-+kZYFSKtZp4+qDav2Z9+xGtRoCiYFE7toKSWNO+7qBmuEm+noCppgxyJ4dv92gc2DR8FSWPrHKp5x+Km0dwJYQ== +"@nrwl/storybook@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nrwl/storybook/-/storybook-18.3.3.tgz#80c60ef3975150127a9b09e2d7b79900cd962af0" + integrity sha512-i8mZoJz9CTT7hmXJxgqlz8u4nm48S4XTZLH5nARXcArjoiojUQTQnRr8iDZlJsZxa3+kHTMCJVyQ5WQUC6+Uog== dependencies: - "@nx/storybook" "18.2.3" + "@nx/storybook" "18.3.3" -"@nrwl/tao@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-18.2.3.tgz#c29abf614c23b404d30340326fb52d33822815c0" - integrity sha512-vmteqzGcKPbexaAVPb/7VfXI5dXxzZwSm3rem3z20QlDOmNh1545VLO9YEfT5xzmZT2CC7F0etR4KcrJLtoT5g== +"@nrwl/tao@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-18.3.3.tgz#2d0c60d233f2cc07c85ba08126dd46f21dda1ef0" + integrity sha512-f/PUDLpSMEObiLQ5sIDySJM+5DxSCNunkxxbY1R9rmQ1cFcgrHaXIHQqbSj91mMa3mmtbKACk8u1LbI+oQV0Tg== dependencies: - nx "18.2.3" + nx "18.3.3" tslib "^2.3.0" -"@nrwl/web@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nrwl/web/-/web-18.2.3.tgz#15e43dd727ba06df111edf16c7f74f915600e41d" - integrity sha512-nlucIDaMUOAG5xOJTCzvKHhCAxergYUrfi2XgPYjg4mu+ApqJxI7HO6FVXZazdivEwNy++BLErjmOjMb52iaVw== +"@nrwl/web@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nrwl/web/-/web-18.3.3.tgz#3e31d086fef5aa1e68ac5af9d5c27592ef2fe39d" + integrity sha512-EuEht/tk9VHLKxjVMEh96wu8WNkRFRabpmLBc++pp2bEaoxz8Qm2xDO+sOU3Wp4zGNx/qQVxA1kKMZCjVjk75g== dependencies: - "@nx/web" "18.2.3" + "@nx/web" "18.3.3" -"@nrwl/webpack@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nrwl/webpack/-/webpack-18.2.3.tgz#d3443ed4478e87defb5be209a335d71b91ccce27" - integrity sha512-ygkYzE+ihhFBuMmOuOkGse0Aas0CSbJ8uLth8UumnapU1euBTP5blhp+y6HRCRT8SzfGzc0qJ+M8YLb6E/DvMQ== +"@nrwl/webpack@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nrwl/webpack/-/webpack-18.3.3.tgz#0c29dc1561c9b8e613313fd02f805be72515dfa6" + integrity sha512-E/8vr1qAFSan1FnewvLBRBHYIaPG9dxZeYKRcQvcDx+Jf2oPyJNYI+9kkoNxEZg9FeFJMShK2x8YBgwB+ivH5A== dependencies: - "@nx/webpack" "18.2.3" + "@nx/webpack" "18.3.3" -"@nrwl/workspace@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nrwl/workspace/-/workspace-18.2.3.tgz#811b3778b3222be835248eb366de0b9a98f3843e" - integrity sha512-5tVtui/iy+VZTk3x/eFj21Zm0ICPUre9CfB5jlJ2MwH8w+96+186Yt2XGJATkFfnVnjqnszOcjk5BLlra8fdLA== +"@nrwl/workspace@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nrwl/workspace/-/workspace-18.3.3.tgz#291ecda3c4fddcb534f0cc6b7c7796a21483ae49" + integrity sha512-9Giuec9l3PpS8mekD00W9kBIKmWRpQSkp+/RvYmc+7kKtVC+Uj/kc68exBOanVgq6zKzYrn+FqHWHGWnHxp+ww== dependencies: - "@nx/workspace" "18.2.3" + "@nx/workspace" "18.3.3" "@nuxtjs/opencollective@0.3.2": version "0.3.2" @@ -5049,18 +5072,18 @@ consola "^2.15.0" node-fetch "^2.6.1" -"@nx/angular@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/angular/-/angular-18.2.3.tgz#564c304c253a268c87d2cb751655691f471e98f7" - integrity sha512-oSp4cNlyCUd03SNoa+x5zjrnqBjxANInB0+vsGD5VlOewpfkVNWPb7TIRa+JyOFXWSWblF0LNEiLxWnxY+27gw== - dependencies: - "@nrwl/angular" "18.2.3" - "@nx/devkit" "18.2.3" - "@nx/eslint" "18.2.3" - "@nx/js" "18.2.3" - "@nx/web" "18.2.3" - "@nx/webpack" "18.2.3" - "@nx/workspace" "18.2.3" +"@nx/angular@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/angular/-/angular-18.3.3.tgz#3648480ddec56e2ca54caed7482eb941b60df3e4" + integrity sha512-KAWpIxd+cNAjSNaArHzJGavES6hBJApE6KVgg3lJwSThkjgTy6loEC4mw8VAQaSlHVx/OEQcbebC1LPkJadG9w== + dependencies: + "@nrwl/angular" "18.3.3" + "@nx/devkit" "18.3.3" + "@nx/eslint" "18.3.3" + "@nx/js" "18.3.3" + "@nx/web" "18.3.3" + "@nx/webpack" "18.3.3" + "@nx/workspace" "18.3.3" "@phenomnomnominal/tsquery" "~5.0.1" "@typescript-eslint/type-utils" "^7.3.0" chalk "^4.1.0" @@ -5074,26 +5097,26 @@ webpack "^5.80.0" webpack-merge "^5.8.0" -"@nx/cypress@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/cypress/-/cypress-18.2.3.tgz#fe32cbb21d592fbe0c62f1ee47abc5ffc232bd23" - integrity sha512-TY5LC4cXFAMq3hrIQDTKYwGgNVDWCTF6i22gaaMlTayowfSWcEug5FHfBGXzpvYR4Q5Snci988krI1yN/6Fbfw== +"@nx/cypress@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/cypress/-/cypress-18.3.3.tgz#d0af052f421312018b0d0ddc3476cd4a31ca748f" + integrity sha512-ou7Q6XXM9zIiWFVojZwnnFFJxx4iKACWvusfCOIwJ3zcel1vtamWHffRp2Z9WjdBDxy26Ax/DM+lZj4t6hQRmA== dependencies: - "@nrwl/cypress" "18.2.3" - "@nx/devkit" "18.2.3" - "@nx/eslint" "18.2.3" - "@nx/js" "18.2.3" + "@nrwl/cypress" "18.3.3" + "@nx/devkit" "18.3.3" + "@nx/eslint" "18.3.3" + "@nx/js" "18.3.3" "@phenomnomnominal/tsquery" "~5.0.1" detect-port "^1.5.1" semver "^7.5.3" tslib "^2.3.0" -"@nx/devkit@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/devkit/-/devkit-18.2.3.tgz#81788e9d018772414ddad0f1aba7ce007da570a3" - integrity sha512-dugw9Jm3Og28uwGee94P3KYkqiUV7J8RgibOQjQG4J2Vt3DPBNEGSgBD72qKkzpioEo+XSVUkn9h3GrdmnRU+Q== +"@nx/devkit@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/devkit/-/devkit-18.3.3.tgz#2ec37855020da74ad1e77b51711b057b3cb12fec" + integrity sha512-FtkZ6mA5//vEA5lcbT80m080ROVacHYV5F1peztTRA+IY2JZGJoqx425kn5ylDO8aCSAIAwcn2qIdhI8BnpG3Q== dependencies: - "@nrwl/devkit" "18.2.3" + "@nrwl/devkit" "18.3.3" ejs "^3.1.7" enquirer "~2.3.6" ignore "^5.0.4" @@ -5102,14 +5125,14 @@ tslib "^2.3.0" yargs-parser "21.1.1" -"@nx/eslint-plugin@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/eslint-plugin/-/eslint-plugin-18.2.3.tgz#99e7e46d8bc32966bdb9c0be7783b7e7bc84a795" - integrity sha512-vOHkzHNpDLLd5RMrL/8/sAdqBqMcf2FrSJWug6W4cC0x8hzUpNwnfEn+i4ZCV/QxduQH4/UP96AbOm7rzwoAdg== +"@nx/eslint-plugin@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/eslint-plugin/-/eslint-plugin-18.3.3.tgz#0410261cf7f1a227eefbe2a979c9482ad9c19894" + integrity sha512-ww3r8VRlzJXOBRG+qCTd+VXHRKxiIrOH+cIokTtuzGrnCXWEMSPO5Ts6z/Jsbb0xAcfZ39WUnxuDZdKbp4aHqA== dependencies: - "@nrwl/eslint-plugin-nx" "18.2.3" - "@nx/devkit" "18.2.3" - "@nx/js" "18.2.3" + "@nrwl/eslint-plugin-nx" "18.3.3" + "@nx/devkit" "18.3.3" + "@nx/js" "18.3.3" "@typescript-eslint/type-utils" "^7.3.0" "@typescript-eslint/utils" "^7.3.0" chalk "^4.1.0" @@ -5118,28 +5141,28 @@ semver "^7.5.3" tslib "^2.3.0" -"@nx/eslint@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/eslint/-/eslint-18.2.3.tgz#714106ffb0e9a7dd35e3248640a073e811eb9c66" - integrity sha512-qr1A3on5tPR3Rxsrg1wlPLVB/L6iFDp+II1xBb/3PBAsddKvPCzPASsogAm0Q3RdqK2JkJrwo/rX3YxwrjZ5cQ== +"@nx/eslint@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/eslint/-/eslint-18.3.3.tgz#ce28b4240e0558333dee08c824d8f82d72a11159" + integrity sha512-cvJjyykTEtQN08b5wQFelD/cbye7Nl5zFVESs+mn9/ezCukjAgP9seOk39nchKykRBAm7zzA1xZOB9thNqw9aA== dependencies: - "@nx/devkit" "18.2.3" - "@nx/js" "18.2.3" - "@nx/linter" "18.2.3" + "@nx/devkit" "18.3.3" + "@nx/js" "18.3.3" + "@nx/linter" "18.3.3" eslint "^8.0.0" tslib "^2.3.0" typescript "~5.4.2" -"@nx/jest@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/jest/-/jest-18.2.3.tgz#f36a0671bb64e45961dad4a97c835873a5e297cf" - integrity sha512-AMI/RuTlNz5d0JiBdraCkZ1ABfEyuJkdCvVjo/RDu1NAw1Xv4hI4+5UG7sb/bJoX6n+lK1SS51z+Zb/ab8lQoQ== +"@nx/jest@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/jest/-/jest-18.3.3.tgz#4a25f77169d0e630cb9b5f49bd0cde1faf0aae31" + integrity sha512-AwkwYSJqu0vrDFMxKAc3lb0yHZFhsD8rX6rMMwe/fZMlAYml9FvGCp/ixWpcRWIo/1t3pxiF3Vejk9+oq/Avfw== dependencies: "@jest/reporters" "^29.4.1" "@jest/test-result" "^29.4.1" - "@nrwl/jest" "18.2.3" - "@nx/devkit" "18.2.3" - "@nx/js" "18.2.3" + "@nrwl/jest" "18.3.3" + "@nx/devkit" "18.3.3" + "@nx/js" "18.3.3" "@phenomnomnominal/tsquery" "~5.0.1" chalk "^4.1.0" identity-obj-proxy "3.0.0" @@ -5151,10 +5174,10 @@ tslib "^2.3.0" yargs-parser "21.1.1" -"@nx/js@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/js/-/js-18.2.3.tgz#fd9a1be56fd674f80563a20d90feffc6ab9b830a" - integrity sha512-hFSmgyaMVIlN/SyFwOwn/IveHsGxxJOv7qhewACg9NlKOa6+eEJYlEbOik9LjvcosDOh5icrngjsFgFJoC1sWA== +"@nx/js@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/js/-/js-18.3.3.tgz#977968160d6edc11f320bc0f654b52d36a9101ac" + integrity sha512-e8u56oG0mlTVz48EeH0C7txX0GeLYN0o4mK1LDAMIHQa4tKefNfwrdqHaZBiVqFOPopeFtqi8s0kqce5prwCaw== dependencies: "@babel/core" "^7.23.2" "@babel/plugin-proposal-decorators" "^7.22.7" @@ -5163,9 +5186,9 @@ "@babel/preset-env" "^7.23.2" "@babel/preset-typescript" "^7.22.5" "@babel/runtime" "^7.22.6" - "@nrwl/js" "18.2.3" - "@nx/devkit" "18.2.3" - "@nx/workspace" "18.2.3" + "@nrwl/js" "18.3.3" + "@nx/devkit" "18.3.3" + "@nx/workspace" "18.3.3" "@phenomnomnominal/tsquery" "~5.0.1" babel-plugin-const-enum "^1.0.1" babel-plugin-macros "^2.8.0" @@ -5187,125 +5210,125 @@ tsconfig-paths "^4.1.2" tslib "^2.3.0" -"@nx/linter@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/linter/-/linter-18.2.3.tgz#a2b9bd388955f7872c42b5dfcabb7f308344039b" - integrity sha512-buxqe0N/d5iVWA4zE/jX8xrkCJLyGG2h1bSTrz1oyPvM3SdcWr69JpL8j1wtBvnKo/brDzLbNWsnrUwO9cgSAQ== +"@nx/linter@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/linter/-/linter-18.3.3.tgz#ae861fb7d10c4f1dcdb4389f5b9f25aecab6fee0" + integrity sha512-5HmAN/8jZ2scrA0OiJSUdBPhIjwIHecK8AK7TxYX4fg1VJ3VcpknV8pWcETuNoBW8WlgF1RX2RW7Gog7vjf+Ww== dependencies: - "@nx/eslint" "18.2.3" + "@nx/eslint" "18.3.3" -"@nx/nest@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/nest/-/nest-18.2.3.tgz#24a01ba16207768e80ff42004fa6552b2605f609" - integrity sha512-kBIKF08iB8V4k9RaPsSzawaVIZo/czx+SEaQmS7+fSsVerLji5ZJoFKqSxnDz6ksW1lfkmRpymSdWWHRc/UDKA== +"@nx/nest@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/nest/-/nest-18.3.3.tgz#16fe7ba6d1f8634ffae58b8e6dda4132ef112c5e" + integrity sha512-e2uPVBsewdLkgf9ncAxN/UEln3ygc1lyy8LTfR5X0Gzx3CUPiayDfd9OxZaxnDFi7Jpu89dpckMO8NhAIBvheA== dependencies: "@nestjs/schematics" "^9.1.0" - "@nrwl/nest" "18.2.3" - "@nx/devkit" "18.2.3" - "@nx/eslint" "18.2.3" - "@nx/js" "18.2.3" - "@nx/node" "18.2.3" + "@nrwl/nest" "18.3.3" + "@nx/devkit" "18.3.3" + "@nx/eslint" "18.3.3" + "@nx/js" "18.3.3" + "@nx/node" "18.3.3" "@phenomnomnominal/tsquery" "~5.0.1" tslib "^2.3.0" -"@nx/node@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/node/-/node-18.2.3.tgz#5ba965f8163dadb802bd43c9706807efaea750be" - integrity sha512-ryI+xzFLBNlRqLNH5UkHO2ZYIs1u1dUbkf7HTyJ4AOrzH2kuBd7tKfFI/IcDzmhjMOfhDYPC0RV7osOSS5Vdiw== +"@nx/node@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/node/-/node-18.3.3.tgz#a000284eb88dc58cbb4dad9909c1e0a930560c61" + integrity sha512-OoeRuuvqrdEH8AsFKrJ91lnDVL9mlqvLzUy9D5PZCYspjCesc7Tmt7Xmbu3VEGzhQPilqZz4hVfXH6MLE7TvqA== dependencies: - "@nrwl/node" "18.2.3" - "@nx/devkit" "18.2.3" - "@nx/eslint" "18.2.3" - "@nx/jest" "18.2.3" - "@nx/js" "18.2.3" + "@nrwl/node" "18.3.3" + "@nx/devkit" "18.3.3" + "@nx/eslint" "18.3.3" + "@nx/jest" "18.3.3" + "@nx/js" "18.3.3" tslib "^2.3.0" -"@nx/nx-darwin-arm64@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-18.2.3.tgz#4b3f14437e6f5a7233594f63a8d36097e8872af1" - integrity sha512-TEks/vXHE87rNvVqhcIzQOM/+aZvNCf/70PhGG4RBEb+qV0C1kw7nygzdoLI4inFC76Qxhyya/K3J2OnU5ATiw== - -"@nx/nx-darwin-x64@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-18.2.3.tgz#bc546836bcce2293181a315666d4a0ea7b42642a" - integrity sha512-UsBbNbNXj+L2OzPyQYotyzmZF4h+ryaZ8quYDfdnlYwvFeqkdb2QJ3vJRd6in0kMWGrdk/ria/wZMCxR7U1ggg== - -"@nx/nx-freebsd-x64@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/nx-freebsd-x64/-/nx-freebsd-x64-18.2.3.tgz#afe920b26385fffb77cbad5435ff97607481c01c" - integrity sha512-f9BXGOeRPhrsNm99TCnOqZZeZUqN1BUOEzWa12eo3u+vQG6Qba3qKn7T92SeEzxOx/mUP/Csv3pFYoY6TE26jA== - -"@nx/nx-linux-arm-gnueabihf@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-18.2.3.tgz#d438dddcfb0fd255b8903214118c304eb89f33ef" - integrity sha512-ekqr5jZhD6PxGM5IbI/RtlERDJ+8HR04OIdfo6HkbwxwCHxZlzZq+ApEZYum4AbjP6cuc3Zd/us1uuDqfQbeHw== - -"@nx/nx-linux-arm64-gnu@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-18.2.3.tgz#a496666a70499d22589dfe0df3d46e738921250b" - integrity sha512-iAW2J8NBFU4zDn5nqRgUq4t7gYC8ALyALzznr97ZvMTQorWfmHYgPUAj/opNqUcr10fjxcmXT0Ux2SX3DgUDmw== - -"@nx/nx-linux-arm64-musl@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-18.2.3.tgz#90744f03377959bdc90cf5a8a2f00afb5b084b70" - integrity sha512-AJjGVHGGew0QVKUL30mjFjafowrSDYSQ1GgkJCLuWef5jl4rFvm9ruZswVja1KfZTFaImTCU01tZjPBr3zhmAA== - -"@nx/nx-linux-x64-gnu@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-18.2.3.tgz#0c0fac195dcf5eaf58a89bbd4764e06c5e338f14" - integrity sha512-nk5Xg8vmbBRoL0fOgZNBl1paC7hmjACLaSBmU7U2X+Y+QPGQzSw2b+Zn1MKVUWDmc4E6VnQfZ8n0L27+r9NgRw== - -"@nx/nx-linux-x64-musl@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-18.2.3.tgz#ba2e290ae3e7e0b43669546591e576c3f7ff2c50" - integrity sha512-bOlhul/eov58k9fX8lltopUDOIBEohZq2qc4ag91W2r4jdp6suAiqfXRxQwNZ2iHd8nAXuCDIHCbUuojs6OZnA== - -"@nx/nx-win32-arm64-msvc@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-18.2.3.tgz#5fc56f77ae98e273b1abb9eaf91492f1a40f2dc6" - integrity sha512-olXer0LnCvJrdV5ynd19fZHvvarRK/p1JnkoOUZDPVV+A3jGQQ8+paz+/5iLQBKA+5VcgWyqAaGFJnpyEFmnoQ== - -"@nx/nx-win32-x64-msvc@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-18.2.3.tgz#91083c549d4cdbaa0098cf1158edce98f1b440d6" - integrity sha512-BgzPjF/wqi7zIFcspcKzN37BX1wgGo0OTLncK2PN5nyzSQ+XeNbR5laDswxzOGdB4CRLPqak2+YMhYnoiXeRCg== - -"@nx/storybook@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/storybook/-/storybook-18.2.3.tgz#38a9d6a541113304abf5d918411bf8696ccdb51e" - integrity sha512-6XvgLD2L4+cbEwPneey+mxB7nGUi4l0K+R1AWjijGg14X2IzyCTgs5up56vIAKVuwuXxGWUTuXgSXwfKXINLIg== - dependencies: - "@nrwl/storybook" "18.2.3" - "@nx/cypress" "18.2.3" - "@nx/devkit" "18.2.3" - "@nx/eslint" "18.2.3" - "@nx/js" "18.2.3" +"@nx/nx-darwin-arm64@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-18.3.3.tgz#dcdbcfe2796bbe3f1dfd61bce81389b05a50e69b" + integrity sha512-NpA2/7o1uUuaocMYopX9muxKif9HlGfWaXo2UeiR918usF6xri4aUqweZbaXVc9iqCAEbVMWUsjaLYGKPXHAjw== + +"@nx/nx-darwin-x64@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-18.3.3.tgz#aa7bdd1a3ea0bb81682422b805914efccab3b179" + integrity sha512-aydPLbc7DeceJ6szRf6DLT4ERoPvwfWyFiGXdAlEZYWhjEuNZLeG8K6jA3yHeWltKfX/qJqhnyKbnubBNzBKlQ== + +"@nx/nx-freebsd-x64@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/nx-freebsd-x64/-/nx-freebsd-x64-18.3.3.tgz#331f5dbb56c90b08e99c1ce9ff51e0c5b956f030" + integrity sha512-sEYEWsK/fwC1l7wzls7RNOjhmrooH0lK0mpgj1vDXesLBSZ7k+pddAqaHFECN4QXBSbHZI2PWOEhbnIH+Errsg== + +"@nx/nx-linux-arm-gnueabihf@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-18.3.3.tgz#d66d4787f5cfc56b5a7aa9a0453174b96b4729a8" + integrity sha512-B9GGMkrrzwiAfvew22x85ITO9TiNxbgRbKJQWQaoopNpXrnSWpY8WTNxpDT24fwV1qdQfsPKcY3F4O0NOUgPRA== + +"@nx/nx-linux-arm64-gnu@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-18.3.3.tgz#2ab08df1d052a55d4a52ba910fe41c25701d5361" + integrity sha512-1EucHf5/0JeqZmhritqkpEdOcdo9Dl32gpFvhNfS6kCAYmaDlEl4zqedz3VIoj4C7+C0pV3mcRO9qB9H7GM5bQ== + +"@nx/nx-linux-arm64-musl@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-18.3.3.tgz#69376454bb9759c376d0a90aa876dfff6bbf4d15" + integrity sha512-HPgOgnYYLPVCBEaAkSEGPGzZqTDCiyCAF/qtvx5z0f1U/hZYb1ubgxw70ogY82Cafr7X4gQBz5k4/ZCnoCXlOQ== + +"@nx/nx-linux-x64-gnu@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-18.3.3.tgz#0b8ba8ec0c2371f0df462742460d52d63b1cc715" + integrity sha512-FgYTQ3VEE6EUOGtJT9riRK8IBwPGFjKS+N2mudQJn2bB/9IumUvVRYQUIX08gqGLlqZPO6uUUhUjwZY8SnjRLQ== + +"@nx/nx-linux-x64-musl@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-18.3.3.tgz#c96d6f8d2d94b99ac8da723077ebbc92f833beea" + integrity sha512-QnWjGViR1Wj9gJXa1RJ9mXyy2/JzQ7NF2C4ulTYSH5St1HoxhkfnLsV0+uNLFEV9PSZq+2BfxmQuT8Appefv1A== + +"@nx/nx-win32-arm64-msvc@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-18.3.3.tgz#0d2c7396e7a063849edbd6e3d34ea81445c389b5" + integrity sha512-Xn3LUaPsF8QkEYUVV3lc693NTCMWrfZBFXTy1cQpvLzQ+idsXQ/EGWoq93cIM3Nc2YWyblT2hHHelb8dHCZAlw== + +"@nx/nx-win32-x64-msvc@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-18.3.3.tgz#ea1a60ae1ffe805529d5cb95e7b28e6b8ae24621" + integrity sha512-t8HvOnQEiaaoTFOOIrql30NPhIwDFO7jg0Jtz3Tbneulh7ceswJp71yFHsRGGrYZ23Tgg+Sna6M9qLRGzlRGkg== + +"@nx/storybook@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/storybook/-/storybook-18.3.3.tgz#4fa01568e3189984d14bae217281f16e2cea5f4e" + integrity sha512-wqca3J20F9HakmPBzq9fwmcZ25LFNb9iWnSngXMgDXjRizbjZrXrCkpyiZe3qlYzhoCNN9oYlUsbas3dec/lwA== + dependencies: + "@nrwl/storybook" "18.3.3" + "@nx/cypress" "18.3.3" + "@nx/devkit" "18.3.3" + "@nx/eslint" "18.3.3" + "@nx/js" "18.3.3" "@phenomnomnominal/tsquery" "~5.0.1" semver "^7.5.3" tslib "^2.3.0" -"@nx/web@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/web/-/web-18.2.3.tgz#c1d1bf7a77d16fd9281453c1c9e68dea853f0fc0" - integrity sha512-nDiCHinZGfkGWuTL2HLk6tUcKILMYtrtd6c/cE8T+5TnTXNaMrOQFt1GvDa60HGh8xgRgpjzTsGfJFrf90GJcA== +"@nx/web@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/web/-/web-18.3.3.tgz#99e6952942b3e43bc52ba444f6933dd279f49a6a" + integrity sha512-/NfQirVd2Ncq2if+1n8DaxNQF0OLaFaDag7qm5pDWJnjXFNh8N7NGZQRry2k/bTSfSc8gN+KJjqSMLAUNNtKgQ== dependencies: - "@nrwl/web" "18.2.3" - "@nx/devkit" "18.2.3" - "@nx/js" "18.2.3" + "@nrwl/web" "18.3.3" + "@nx/devkit" "18.3.3" + "@nx/js" "18.3.3" chalk "^4.1.0" detect-port "^1.5.1" http-server "^14.1.0" tslib "^2.3.0" -"@nx/webpack@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/webpack/-/webpack-18.2.3.tgz#15b3c4be376f2313abdd64c3b67e04f11fbde1fc" - integrity sha512-0X7HXrF/VP9BrbbYD4Ewr4KnMT85eSaIBr/TvTrUM4v2BXqPgP4NVQhkd6jLlEkWuDlYtAgwFjcx4NGWRqnwbw== +"@nx/webpack@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/webpack/-/webpack-18.3.3.tgz#2b13c08c99821a413edd4ff7749936871ae6ae32" + integrity sha512-DPs8wfmYe/mEZCQ/TQgUqb/zgXY8hevR23d8bDkYjB3Akjk4OOF3QpQ2OXQ4c+Jf0ckGnQYOg6XAkE682UZqzg== dependencies: "@babel/core" "^7.23.2" - "@nrwl/webpack" "18.2.3" - "@nx/devkit" "18.2.3" - "@nx/js" "18.2.3" + "@nrwl/webpack" "18.3.3" + "@nx/devkit" "18.3.3" + "@nx/js" "18.3.3" ajv "^8.12.0" autoprefixer "^10.4.9" babel-loader "^9.1.2" @@ -5340,16 +5363,16 @@ webpack-node-externals "^3.0.0" webpack-subresource-integrity "^5.1.0" -"@nx/workspace@18.2.3": - version "18.2.3" - resolved "https://registry.yarnpkg.com/@nx/workspace/-/workspace-18.2.3.tgz#797b2aef3613ddb30ea4dbef0bd1bde37b3c60e2" - integrity sha512-en3lSArMrHZ75SqMHnnZjXiMunc6QFDMcglNPQwIE8TuXnV8UWQ1e4hkzRo6hY/YOoY7HcFvMEJ5KyP8OWCmQg== +"@nx/workspace@18.3.3": + version "18.3.3" + resolved "https://registry.yarnpkg.com/@nx/workspace/-/workspace-18.3.3.tgz#bae369fe9d6c8aca425222ec53f797bcacd715e6" + integrity sha512-SUJJKzOUuNnclpHHde6f6nlF+pQwMjeF026jFpWDFaNzdsADhhRulkz0GLRXB9kKszvzz2JKde9WBWnKrFZ2IQ== dependencies: - "@nrwl/workspace" "18.2.3" - "@nx/devkit" "18.2.3" + "@nrwl/workspace" "18.3.3" + "@nx/devkit" "18.3.3" chalk "^4.1.0" enquirer "~2.3.6" - nx "18.2.3" + nx "18.3.3" tslib "^2.3.0" yargs-parser "21.1.1" @@ -5831,6 +5854,15 @@ "@angular-devkit/schematics" "17.3.3" jsonc-parser "3.2.1" +"@schematics/angular@17.3.5": + version "17.3.5" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-17.3.5.tgz#c58a6afef977e9280cc7a5e24e70b058f68fdc5e" + integrity sha512-SWCK16Eob0K86hpZ3NHmrTS6LSzTlhvnIdf3BXC6nzoiyDhcAS0oJ2Tjdq1opW/PaL1hB7MulcbIhxYln5du0w== + dependencies: + "@angular-devkit/core" "17.3.5" + "@angular-devkit/schematics" "17.3.5" + jsonc-parser "3.2.1" + "@schematics/angular@^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0": version "17.0.0" resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-17.0.0.tgz#63ddf8bfbb3b117fe7a355bd22b43d2c9ff7f0ee" @@ -15633,12 +15665,12 @@ nwsapi@^2.2.2: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.7.tgz#738e0707d3128cb750dddcfe90e4610482df0f30" integrity sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ== -nx@18.2.3: - version "18.2.3" - resolved "https://registry.yarnpkg.com/nx/-/nx-18.2.3.tgz#40d4c18a3b7143e10b3645b5bd47a65c5b9d5e6f" - integrity sha512-4XGvvIzXeeeSj1hObiBL7E7aXX6rbiB1F856AqUdGoysYfkhcxOFyeAv5XsXeukl9gYwh/LH84paXjEOkGaJlA== +nx@18.3.3: + version "18.3.3" + resolved "https://registry.yarnpkg.com/nx/-/nx-18.3.3.tgz#ab96811961b631efd4f0c83550e92f7b0a625e83" + integrity sha512-GqC5ANfTWV6SFbgquZwuRMI2Z2nO0c0Yx4JzM3x32aJOgXsmRml3WcV0a5648bIXSen34gylHYl2EHaxVWkzNQ== dependencies: - "@nrwl/tao" "18.2.3" + "@nrwl/tao" "18.3.3" "@yarnpkg/lockfile" "^1.1.0" "@yarnpkg/parsers" "3.0.0-rc.46" "@zkochan/js-yaml" "0.0.6" @@ -15673,16 +15705,16 @@ nx@18.2.3: yargs "^17.6.2" yargs-parser "21.1.1" optionalDependencies: - "@nx/nx-darwin-arm64" "18.2.3" - "@nx/nx-darwin-x64" "18.2.3" - "@nx/nx-freebsd-x64" "18.2.3" - "@nx/nx-linux-arm-gnueabihf" "18.2.3" - "@nx/nx-linux-arm64-gnu" "18.2.3" - "@nx/nx-linux-arm64-musl" "18.2.3" - "@nx/nx-linux-x64-gnu" "18.2.3" - "@nx/nx-linux-x64-musl" "18.2.3" - "@nx/nx-win32-arm64-msvc" "18.2.3" - "@nx/nx-win32-x64-msvc" "18.2.3" + "@nx/nx-darwin-arm64" "18.3.3" + "@nx/nx-darwin-x64" "18.3.3" + "@nx/nx-freebsd-x64" "18.3.3" + "@nx/nx-linux-arm-gnueabihf" "18.3.3" + "@nx/nx-linux-arm64-gnu" "18.3.3" + "@nx/nx-linux-arm64-musl" "18.3.3" + "@nx/nx-linux-x64-gnu" "18.3.3" + "@nx/nx-linux-x64-musl" "18.3.3" + "@nx/nx-win32-arm64-msvc" "18.3.3" + "@nx/nx-win32-x64-msvc" "18.3.3" oauth@0.9.x: version "0.9.15" @@ -18885,10 +18917,10 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== -undici@6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/undici/-/undici-6.7.1.tgz#3cb27222fd5d72c1b2058f4e18bf9b53dd933af8" - integrity sha512-+Wtb9bAQw6HYWzCnxrPTMVEV3Q1QjYanI0E4q02ehReMuquQdLTEFEYbfs7hcImVYKcQkWSwT6buEmSVIiDDtQ== +undici@6.11.1: + version "6.11.1" + resolved "https://registry.yarnpkg.com/undici/-/undici-6.11.1.tgz#75ab573677885b421ca2e6f5f17ff1185b24c68d" + integrity sha512-KyhzaLJnV1qa3BSHdj4AZ2ndqI0QWPxYzaIOio0WzcEJB9gvuysprJSLtpvc2D9mhR9jPDUk7xlJlZbH2KR5iw== unfetch@^4.2.0: version "4.2.0" @@ -19162,10 +19194,10 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" -vite@5.1.5: - version "5.1.5" - resolved "https://registry.yarnpkg.com/vite/-/vite-5.1.5.tgz#bdbc2b15e8000d9cc5172f059201178f9c9de5fb" - integrity sha512-BdN1xh0Of/oQafhU+FvopafUp6WaYenLU/NFoL5WyJL++GxkNfieKzBhM24H3HVsPQrlAqB7iJYTHabzaRed5Q== +vite@5.1.7: + version "5.1.7" + resolved "https://registry.yarnpkg.com/vite/-/vite-5.1.7.tgz#9f685a2c4c70707fef6d37341b0e809c366da619" + integrity sha512-sgnEEFTZYMui/sTlH1/XEnVNHMujOahPLGMxn1+5sIT45Xjng1Ec1K78jRP15dSmVgg5WBin9yO81j3o9OxofA== dependencies: esbuild "^0.19.3" postcss "^8.4.35" From 47fd029e0cf1f646cf672cc879dc6c3f2930e1c5 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 20 Apr 2024 12:15:21 +0200 Subject: [PATCH 144/203] Clean up styles (#3305) --- .../lib/account-balances/account-balances.component.scss | 7 ------- 1 file changed, 7 deletions(-) diff --git a/libs/ui/src/lib/account-balances/account-balances.component.scss b/libs/ui/src/lib/account-balances/account-balances.component.scss index 0bf48a9e7..5d4e87f30 100644 --- a/libs/ui/src/lib/account-balances/account-balances.component.scss +++ b/libs/ui/src/lib/account-balances/account-balances.component.scss @@ -1,10 +1,3 @@ :host { display: block; } - -:host-context(.is-dark-theme) { - input { - color: rgb(var(--light-primary-text)); - background-color: rgb(var(--palette-foreground-text-light)); - } -} From 7788b5a987607b602f23b9af707c93a72776d016 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 20 Apr 2024 12:53:51 +0200 Subject: [PATCH 145/203] Improve messages (#3308) --- apps/client/src/app/core/http-response.interceptor.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/client/src/app/core/http-response.interceptor.ts b/apps/client/src/app/core/http-response.interceptor.ts index 15a0d2e9f..5314c10f1 100644 --- a/apps/client/src/app/core/http-response.interceptor.ts +++ b/apps/client/src/app/core/http-response.interceptor.ts @@ -63,9 +63,11 @@ export class HttpResponseInterceptor implements HttpInterceptor { undefined, { duration: 6000 } ); - } else if (!error.url.endsWith('auth/anonymous')) { + } else if (!error.url.includes('/auth')) { this.snackBarRef = this.snackBar.open( - $localize`This feature requires a subscription.`, + this.hasPermissionForSubscription + ? $localize`This feature requires a subscription.` + : $localize`This action is not allowed.`, this.hasPermissionForSubscription ? $localize`Upgrade Plan` : undefined, From ccb1bf881ee29a30650078c66314971f205726be Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 20 Apr 2024 12:54:06 +0200 Subject: [PATCH 146/203] Feature/improve language localization for de 20240420 (#3309) * Update translations * Update changelog --- CHANGELOG.md | 1 + apps/client/src/locales/messages.de.xlf | 104 ++++++++++++++---------- apps/client/src/locales/messages.es.xlf | 104 ++++++++++++++---------- apps/client/src/locales/messages.fr.xlf | 104 ++++++++++++++---------- apps/client/src/locales/messages.it.xlf | 104 ++++++++++++++---------- apps/client/src/locales/messages.nl.xlf | 104 ++++++++++++++---------- apps/client/src/locales/messages.pl.xlf | 104 ++++++++++++++---------- apps/client/src/locales/messages.pt.xlf | 104 ++++++++++++++---------- apps/client/src/locales/messages.tr.xlf | 104 ++++++++++++++---------- apps/client/src/locales/messages.xlf | 102 +++++++++++++---------- apps/client/src/locales/messages.zh.xlf | 104 ++++++++++++++---------- 11 files changed, 619 insertions(+), 420 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 935981c20..2e6f610cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Removed the date range support in the activities table on the portfolio activities page (experimental) +- Improved the language localization for German (`de`) - Upgraded `angular` from version `17.3.3` to `17.3.5` - Upgraded `Nx` from version `18.2.3` to `18.3.3` diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index 033f5c58d..ef828af83 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -218,7 +218,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 20 + 34 libs/ui/src/lib/activities-table/activities-table.component.html @@ -294,7 +294,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 51 + 80 libs/ui/src/lib/activities-table/activities-table.component.html @@ -314,7 +314,7 @@ Jobs löschen apps/client/src/app/components/admin-jobs/admin-jobs.html - 126 + 158 @@ -362,7 +362,7 @@ Versuche apps/client/src/app/components/admin-jobs/admin-jobs.html - 63 + 82 @@ -370,7 +370,7 @@ Erstellt apps/client/src/app/components/admin-jobs/admin-jobs.html - 72 + 91 @@ -378,7 +378,7 @@ Abgeschlossen apps/client/src/app/components/admin-jobs/admin-jobs.html - 81 + 100 @@ -386,7 +386,7 @@ Status apps/client/src/app/components/admin-jobs/admin-jobs.html - 90 + 109 @@ -410,7 +410,7 @@ Daten anzeigen apps/client/src/app/components/admin-jobs/admin-jobs.html - 141 + 173 @@ -418,7 +418,7 @@ Stacktrace anzeigen apps/client/src/app/components/admin-jobs/admin-jobs.html - 148 + 180 @@ -426,7 +426,7 @@ Job löschen apps/client/src/app/components/admin-jobs/admin-jobs.html - 154 + 186 @@ -450,7 +450,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 11 + 12 libs/ui/src/lib/activities-table/activities-table.component.html @@ -728,6 +728,10 @@ apps/client/src/app/components/admin-overview/admin-overview.html 231 + + libs/ui/src/lib/account-balances/account-balances.component.html + 93 + Housekeeping @@ -1596,7 +1600,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 188 + 215 @@ -1608,7 +1612,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -1620,7 +1624,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -1632,7 +1636,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -1644,7 +1648,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 209 + 236 @@ -1656,7 +1660,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 68 + 69 @@ -1668,7 +1672,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 70 + 72 @@ -1676,7 +1680,7 @@ Okay apps/client/src/app/core/http-response.interceptor.ts - 90 + 92 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -2748,7 +2752,7 @@ Möchtest du diese Aktivität wirklich löschen? libs/ui/src/lib/activities-table/activities-table.component.ts - 175 + 215 @@ -2824,7 +2828,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 89 + 91 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -2836,7 +2840,7 @@ Ups! Es ist etwas schief gelaufen. apps/client/src/app/core/http-response.interceptor.ts - 87 + 89 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -2984,7 +2988,7 @@ Einlage libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 332 + 357 @@ -2992,7 +2996,7 @@ Verzinsung libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 342 + 367 libs/ui/src/lib/i18n.ts @@ -3004,7 +3008,7 @@ Ersparnisse libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 352 + 377 @@ -3324,7 +3328,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 385 + 389 @@ -3332,11 +3336,11 @@ Keine Daten verfügbar libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 387 + 391 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 400 + 404 @@ -4108,7 +4112,7 @@ Möchtest du wirklich alle Aktivitäten löschen? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 171 + 168 @@ -11152,7 +11156,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 81 + 83 apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts @@ -11188,7 +11192,7 @@ libs/ui/src/lib/membership-card/membership-card.component.ts - 13 + 25 @@ -13436,7 +13440,7 @@ Finde Position... libs/ui/src/lib/assistant/assistant.component.ts - 111 + 138 @@ -14636,7 +14640,7 @@ Möchtest du diesen Cash-Bestand wirklich löschen? libs/ui/src/lib/account-balances/account-balances.component.ts - 58 + 104 @@ -14804,7 +14808,7 @@ Seit Wochenbeginn libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14812,7 +14816,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14820,7 +14824,7 @@ Seit Monatsbeginn libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 @@ -14828,7 +14832,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 @@ -14836,7 +14840,7 @@ Seit Jahresbeginn libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -14880,7 +14884,7 @@ Jahr libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -14888,7 +14892,7 @@ Jahre libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -14972,7 +14976,7 @@ Ups! Es sieht so aus, als würdest du zu viele Anfragen senden. Bitte geh es ein bisschen langsamer an. apps/client/src/app/core/http-response.interceptor.ts - 105 + 107 @@ -15020,7 +15024,23 @@ Job ausführen apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 183 + + + + Priority + Priorität + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 63 + + + + This action is not allowed. + Diese Aktion ist nicht zulässig. + + apps/client/src/app/core/http-response.interceptor.ts + 70 diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index c770a2dc2..4e480b139 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -219,7 +219,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 20 + 34 libs/ui/src/lib/activities-table/activities-table.component.html @@ -295,7 +295,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 51 + 80 libs/ui/src/lib/activities-table/activities-table.component.html @@ -315,7 +315,7 @@ Elimina los trabajos apps/client/src/app/components/admin-jobs/admin-jobs.html - 126 + 158 @@ -363,7 +363,7 @@ Intentos apps/client/src/app/components/admin-jobs/admin-jobs.html - 63 + 82 @@ -371,7 +371,7 @@ Creado apps/client/src/app/components/admin-jobs/admin-jobs.html - 72 + 91 @@ -379,7 +379,7 @@ Finalizado apps/client/src/app/components/admin-jobs/admin-jobs.html - 81 + 100 @@ -387,7 +387,7 @@ Estado apps/client/src/app/components/admin-jobs/admin-jobs.html - 90 + 109 @@ -411,7 +411,7 @@ Visualiza los datos apps/client/src/app/components/admin-jobs/admin-jobs.html - 141 + 173 @@ -419,7 +419,7 @@ Visualiza Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 148 + 180 @@ -427,7 +427,7 @@ Elimina el trabajo apps/client/src/app/components/admin-jobs/admin-jobs.html - 154 + 186 @@ -451,7 +451,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 11 + 12 libs/ui/src/lib/activities-table/activities-table.component.html @@ -729,6 +729,10 @@ apps/client/src/app/components/admin-overview/admin-overview.html 231 + + libs/ui/src/lib/account-balances/account-balances.component.html + 93 + Housekeeping @@ -1594,7 +1598,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 188 + 215 @@ -1606,7 +1610,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -1618,7 +1622,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -1630,7 +1634,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -1642,7 +1646,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 209 + 236 @@ -1654,7 +1658,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 68 + 69 @@ -1666,7 +1670,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 70 + 72 @@ -1674,7 +1678,7 @@ De acuerdo apps/client/src/app/core/http-response.interceptor.ts - 90 + 92 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -2746,7 +2750,7 @@ ¿Estás seguro de eliminar esta operación? libs/ui/src/lib/activities-table/activities-table.component.ts - 175 + 215 @@ -2818,7 +2822,7 @@ Vaya! Algo no funcionó bien. apps/client/src/app/core/http-response.interceptor.ts - 87 + 89 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -2834,7 +2838,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 89 + 91 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -2974,7 +2978,7 @@ Ahorros libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 352 + 377 @@ -2982,7 +2986,7 @@ Interés libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 342 + 367 libs/ui/src/lib/i18n.ts @@ -2994,7 +2998,7 @@ Depósito libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 332 + 357 @@ -3322,7 +3326,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 385 + 389 @@ -3330,11 +3334,11 @@ Sin datos disponibles libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 387 + 391 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 400 + 404 @@ -4106,7 +4110,7 @@ Do you really want to delete all your activities? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 171 + 168 @@ -11150,7 +11154,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 81 + 83 apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts @@ -11186,7 +11190,7 @@ libs/ui/src/lib/membership-card/membership-card.component.ts - 13 + 25 @@ -13434,7 +13438,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 111 + 138 @@ -14634,7 +14638,7 @@ Do you really want to delete this account balance? libs/ui/src/lib/account-balances/account-balances.component.ts - 58 + 104 @@ -14802,7 +14806,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14810,7 +14814,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14818,7 +14822,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 @@ -14826,7 +14830,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 @@ -14834,7 +14838,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -14878,7 +14882,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -14886,7 +14890,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -14970,7 +14974,7 @@ Oops! It looks like you’re making too many requests. Please slow down a bit. apps/client/src/app/core/http-response.interceptor.ts - 105 + 107 @@ -15018,7 +15022,23 @@ Execute Job apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 183 + + + + Priority + Priority + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 63 + + + + This action is not allowed. + This action is not allowed. + + apps/client/src/app/core/http-response.interceptor.ts + 70 diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index 3a241feda..fbc210fce 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -274,7 +274,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 20 + 34 libs/ui/src/lib/activities-table/activities-table.component.html @@ -350,7 +350,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 51 + 80 libs/ui/src/lib/activities-table/activities-table.component.html @@ -410,7 +410,7 @@ Tentatives apps/client/src/app/components/admin-jobs/admin-jobs.html - 63 + 82 @@ -418,7 +418,7 @@ Créé apps/client/src/app/components/admin-jobs/admin-jobs.html - 72 + 91 @@ -426,7 +426,7 @@ Terminé apps/client/src/app/components/admin-jobs/admin-jobs.html - 81 + 100 @@ -434,7 +434,7 @@ Statut apps/client/src/app/components/admin-jobs/admin-jobs.html - 90 + 109 @@ -442,7 +442,7 @@ Supprimer Tâches apps/client/src/app/components/admin-jobs/admin-jobs.html - 126 + 158 @@ -466,7 +466,7 @@ Voir Données apps/client/src/app/components/admin-jobs/admin-jobs.html - 141 + 173 @@ -474,7 +474,7 @@ Voir la Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 148 + 180 @@ -482,7 +482,7 @@ Supprimer Tâche apps/client/src/app/components/admin-jobs/admin-jobs.html - 154 + 186 @@ -506,7 +506,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 11 + 12 libs/ui/src/lib/activities-table/activities-table.component.html @@ -988,6 +988,10 @@ apps/client/src/app/components/admin-overview/admin-overview.html 231 + + libs/ui/src/lib/account-balances/account-balances.component.html + 93 + Housekeeping @@ -1578,7 +1582,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 68 + 69 @@ -1590,7 +1594,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 70 + 72 @@ -1925,7 +1929,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 188 + 215 @@ -1937,7 +1941,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -1949,7 +1953,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -1961,7 +1965,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -1973,7 +1977,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 209 + 236 @@ -1993,7 +1997,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 89 + 91 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -2005,7 +2009,7 @@ Oups! Quelque chose s'est mal passé. apps/client/src/app/core/http-response.interceptor.ts - 87 + 89 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -2017,7 +2021,7 @@ D'accord apps/client/src/app/core/http-response.interceptor.ts - 90 + 92 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -2925,7 +2929,7 @@ Dépôt libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 332 + 357 @@ -3265,7 +3269,7 @@ Voulez-vous vraiment supprimer cette activité ? libs/ui/src/lib/activities-table/activities-table.component.ts - 175 + 215 @@ -3313,7 +3317,7 @@ Intérêt libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 342 + 367 libs/ui/src/lib/i18n.ts @@ -3325,7 +3329,7 @@ Épargne libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 352 + 377 @@ -3385,7 +3389,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 385 + 389 @@ -3561,11 +3565,11 @@ Pas de données disponibles libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 387 + 391 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 400 + 404 @@ -4105,7 +4109,7 @@ Voulez-vous vraiment supprimer toutes vos activités ? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 171 + 168 @@ -11149,7 +11153,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 81 + 83 apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts @@ -11185,7 +11189,7 @@ libs/ui/src/lib/membership-card/membership-card.component.ts - 13 + 25 @@ -13433,7 +13437,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 111 + 138 @@ -14633,7 +14637,7 @@ Do you really want to delete this account balance? libs/ui/src/lib/account-balances/account-balances.component.ts - 58 + 104 @@ -14801,7 +14805,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14809,7 +14813,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14817,7 +14821,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 @@ -14825,7 +14829,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 @@ -14833,7 +14837,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -14877,7 +14881,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -14885,7 +14889,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -14969,7 +14973,7 @@ Oops! It looks like you’re making too many requests. Please slow down a bit. apps/client/src/app/core/http-response.interceptor.ts - 105 + 107 @@ -15017,7 +15021,23 @@ Execute Job apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 183 + + + + Priority + Priority + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 63 + + + + This action is not allowed. + This action is not allowed. + + apps/client/src/app/core/http-response.interceptor.ts + 70 diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index 99f669151..7075781c5 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -219,7 +219,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 20 + 34 libs/ui/src/lib/activities-table/activities-table.component.html @@ -295,7 +295,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 51 + 80 libs/ui/src/lib/activities-table/activities-table.component.html @@ -315,7 +315,7 @@ Elimina i lavori apps/client/src/app/components/admin-jobs/admin-jobs.html - 126 + 158 @@ -363,7 +363,7 @@ Tentativi apps/client/src/app/components/admin-jobs/admin-jobs.html - 63 + 82 @@ -371,7 +371,7 @@ Creato apps/client/src/app/components/admin-jobs/admin-jobs.html - 72 + 91 @@ -379,7 +379,7 @@ Finito apps/client/src/app/components/admin-jobs/admin-jobs.html - 81 + 100 @@ -387,7 +387,7 @@ Stato apps/client/src/app/components/admin-jobs/admin-jobs.html - 90 + 109 @@ -411,7 +411,7 @@ Visualizza i dati apps/client/src/app/components/admin-jobs/admin-jobs.html - 141 + 173 @@ -419,7 +419,7 @@ Visualizza Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 148 + 180 @@ -427,7 +427,7 @@ Elimina il lavoro apps/client/src/app/components/admin-jobs/admin-jobs.html - 154 + 186 @@ -451,7 +451,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 11 + 12 libs/ui/src/lib/activities-table/activities-table.component.html @@ -729,6 +729,10 @@ apps/client/src/app/components/admin-overview/admin-overview.html 231 + + libs/ui/src/lib/account-balances/account-balances.component.html + 93 + Housekeeping @@ -1594,7 +1598,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 188 + 215 @@ -1606,7 +1610,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -1618,7 +1622,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -1630,7 +1634,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -1642,7 +1646,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 209 + 236 @@ -1654,7 +1658,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 68 + 69 @@ -1666,7 +1670,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 70 + 72 @@ -1674,7 +1678,7 @@ Bene apps/client/src/app/core/http-response.interceptor.ts - 90 + 92 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -2746,7 +2750,7 @@ Vuoi davvero eliminare questa attività? libs/ui/src/lib/activities-table/activities-table.component.ts - 175 + 215 @@ -2818,7 +2822,7 @@ Ops! Qualcosa è andato storto. apps/client/src/app/core/http-response.interceptor.ts - 87 + 89 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -2834,7 +2838,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 89 + 91 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -2974,7 +2978,7 @@ Risparmio libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 352 + 377 @@ -2982,7 +2986,7 @@ Interesse libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 342 + 367 libs/ui/src/lib/i18n.ts @@ -2994,7 +2998,7 @@ Deposito libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 332 + 357 @@ -3322,7 +3326,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 385 + 389 @@ -3330,11 +3334,11 @@ Nessun dato disponibile libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 387 + 391 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 400 + 404 @@ -4106,7 +4110,7 @@ Vuoi davvero eliminare tutte le tue attività? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 171 + 168 @@ -11150,7 +11154,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 81 + 83 apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts @@ -11186,7 +11190,7 @@ libs/ui/src/lib/membership-card/membership-card.component.ts - 13 + 25 @@ -13434,7 +13438,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 111 + 138 @@ -14634,7 +14638,7 @@ Do you really want to delete this account balance? libs/ui/src/lib/account-balances/account-balances.component.ts - 58 + 104 @@ -14802,7 +14806,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14810,7 +14814,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14818,7 +14822,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 @@ -14826,7 +14830,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 @@ -14834,7 +14838,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -14878,7 +14882,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -14886,7 +14890,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -14970,7 +14974,7 @@ Oops! It looks like you’re making too many requests. Please slow down a bit. apps/client/src/app/core/http-response.interceptor.ts - 105 + 107 @@ -15018,7 +15022,23 @@ Execute Job apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 183 + + + + Priority + Priority + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 63 + + + + This action is not allowed. + This action is not allowed. + + apps/client/src/app/core/http-response.interceptor.ts + 70 diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index 9116a411a..b4b13691a 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -218,7 +218,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 20 + 34 libs/ui/src/lib/activities-table/activities-table.component.html @@ -294,7 +294,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 51 + 80 libs/ui/src/lib/activities-table/activities-table.component.html @@ -314,7 +314,7 @@ Taken verwijderen apps/client/src/app/components/admin-jobs/admin-jobs.html - 126 + 158 @@ -362,7 +362,7 @@ Pogingen apps/client/src/app/components/admin-jobs/admin-jobs.html - 63 + 82 @@ -370,7 +370,7 @@ Aangemaakt apps/client/src/app/components/admin-jobs/admin-jobs.html - 72 + 91 @@ -378,7 +378,7 @@ Voltooid apps/client/src/app/components/admin-jobs/admin-jobs.html - 81 + 100 @@ -386,7 +386,7 @@ Status apps/client/src/app/components/admin-jobs/admin-jobs.html - 90 + 109 @@ -410,7 +410,7 @@ Bekijk gegevens apps/client/src/app/components/admin-jobs/admin-jobs.html - 141 + 173 @@ -418,7 +418,7 @@ Bekijk Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 148 + 180 @@ -426,7 +426,7 @@ Taak verwijderen apps/client/src/app/components/admin-jobs/admin-jobs.html - 154 + 186 @@ -450,7 +450,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 11 + 12 libs/ui/src/lib/activities-table/activities-table.component.html @@ -728,6 +728,10 @@ apps/client/src/app/components/admin-overview/admin-overview.html 231 + + libs/ui/src/lib/account-balances/account-balances.component.html + 93 + Housekeeping @@ -1593,7 +1597,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 188 + 215 @@ -1605,7 +1609,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -1617,7 +1621,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -1629,7 +1633,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -1641,7 +1645,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 209 + 236 @@ -1653,7 +1657,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 68 + 69 @@ -1665,7 +1669,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 70 + 72 @@ -1673,7 +1677,7 @@ Oké apps/client/src/app/core/http-response.interceptor.ts - 90 + 92 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -2745,7 +2749,7 @@ Wil je deze activiteit echt verwijderen? libs/ui/src/lib/activities-table/activities-table.component.ts - 175 + 215 @@ -2817,7 +2821,7 @@ Oeps! Er ging iets mis. apps/client/src/app/core/http-response.interceptor.ts - 87 + 89 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -2833,7 +2837,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 89 + 91 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -2973,7 +2977,7 @@ Besparingen libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 352 + 377 @@ -2981,7 +2985,7 @@ Rente libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 342 + 367 libs/ui/src/lib/i18n.ts @@ -2993,7 +2997,7 @@ Storting libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 332 + 357 @@ -3321,7 +3325,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 385 + 389 @@ -3329,11 +3333,11 @@ Geen gegevens beschikbaar libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 387 + 391 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 400 + 404 @@ -4105,7 +4109,7 @@ Wil je echt al je activiteiten verwijderen? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 171 + 168 @@ -11149,7 +11153,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 81 + 83 apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts @@ -11185,7 +11189,7 @@ libs/ui/src/lib/membership-card/membership-card.component.ts - 13 + 25 @@ -13433,7 +13437,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 111 + 138 @@ -14633,7 +14637,7 @@ Do you really want to delete this account balance? libs/ui/src/lib/account-balances/account-balances.component.ts - 58 + 104 @@ -14801,7 +14805,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14809,7 +14813,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14817,7 +14821,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 @@ -14825,7 +14829,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 @@ -14833,7 +14837,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -14877,7 +14881,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -14885,7 +14889,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -14969,7 +14973,7 @@ Oops! It looks like you’re making too many requests. Please slow down a bit. apps/client/src/app/core/http-response.interceptor.ts - 105 + 107 @@ -15017,7 +15021,23 @@ Execute Job apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 183 + + + + Priority + Priority + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 63 + + + + This action is not allowed. + This action is not allowed. + + apps/client/src/app/core/http-response.interceptor.ts + 70 diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf index c02f78aee..1d7e40388 100644 --- a/apps/client/src/locales/messages.pl.xlf +++ b/apps/client/src/locales/messages.pl.xlf @@ -654,7 +654,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 81 + 83 apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts @@ -690,7 +690,7 @@ libs/ui/src/lib/membership-card/membership-card.component.ts - 13 + 25 @@ -1790,7 +1790,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 20 + 34 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1866,7 +1866,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 51 + 80 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1942,7 +1942,7 @@ Attempts apps/client/src/app/components/admin-jobs/admin-jobs.html - 63 + 82 @@ -1950,7 +1950,7 @@ Created apps/client/src/app/components/admin-jobs/admin-jobs.html - 72 + 91 @@ -1958,7 +1958,7 @@ Finished apps/client/src/app/components/admin-jobs/admin-jobs.html - 81 + 100 @@ -1966,7 +1966,7 @@ Status apps/client/src/app/components/admin-jobs/admin-jobs.html - 90 + 109 @@ -1974,7 +1974,7 @@ Delete Jobs apps/client/src/app/components/admin-jobs/admin-jobs.html - 126 + 158 @@ -1982,7 +1982,7 @@ View Data apps/client/src/app/components/admin-jobs/admin-jobs.html - 141 + 173 @@ -1990,7 +1990,7 @@ View Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 148 + 180 @@ -1998,7 +1998,7 @@ Delete Job apps/client/src/app/components/admin-jobs/admin-jobs.html - 154 + 186 @@ -2022,7 +2022,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 11 + 12 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2616,6 +2616,10 @@ apps/client/src/app/components/admin-overview/admin-overview.html 231 + + libs/ui/src/lib/account-balances/account-balances.component.html + 93 + Housekeeping @@ -3138,7 +3142,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 68 + 69 @@ -3150,7 +3154,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 70 + 72 @@ -3688,7 +3692,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 188 + 215 @@ -3700,7 +3704,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -3712,7 +3716,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -3724,7 +3728,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -3736,7 +3740,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 209 + 236 @@ -4016,7 +4020,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 89 + 91 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -4028,7 +4032,7 @@ Oops! Something went wrong. apps/client/src/app/core/http-response.interceptor.ts - 87 + 89 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -4040,7 +4044,7 @@ Okay apps/client/src/app/core/http-response.interceptor.ts - 90 + 92 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -4952,7 +4956,7 @@ Do you really want to delete all your activities? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 171 + 168 @@ -5396,7 +5400,7 @@ Deposit libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 332 + 357 @@ -13220,7 +13224,7 @@ Do you really want to delete this activity? libs/ui/src/lib/activities-table/activities-table.component.ts - 175 + 215 @@ -13228,7 +13232,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 111 + 138 @@ -13328,7 +13332,7 @@ Interest libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 342 + 367 libs/ui/src/lib/i18n.ts @@ -13340,7 +13344,7 @@ Savings libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 352 + 377 @@ -13496,7 +13500,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 385 + 389 @@ -13792,11 +13796,11 @@ No data available libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 387 + 391 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 400 + 404 @@ -14636,7 +14640,7 @@ Do you really want to delete this account balance? libs/ui/src/lib/account-balances/account-balances.component.ts - 58 + 104 @@ -14804,7 +14808,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14812,7 +14816,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14820,7 +14824,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 @@ -14828,7 +14832,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 @@ -14836,7 +14840,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -14880,7 +14884,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -14888,7 +14892,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -14972,7 +14976,7 @@ Oops! It looks like you’re making too many requests. Please slow down a bit. apps/client/src/app/core/http-response.interceptor.ts - 105 + 107 @@ -15020,7 +15024,23 @@ Execute Job apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 183 + + + + Priority + Priority + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 63 + + + + This action is not allowed. + This action is not allowed. + + apps/client/src/app/core/http-response.interceptor.ts + 70 diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index 6ebacade4..d7156d354 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -274,7 +274,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 20 + 34 libs/ui/src/lib/activities-table/activities-table.component.html @@ -350,7 +350,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 51 + 80 libs/ui/src/lib/activities-table/activities-table.component.html @@ -410,7 +410,7 @@ Tentativas apps/client/src/app/components/admin-jobs/admin-jobs.html - 63 + 82 @@ -418,7 +418,7 @@ Criado apps/client/src/app/components/admin-jobs/admin-jobs.html - 72 + 91 @@ -426,7 +426,7 @@ Terminado apps/client/src/app/components/admin-jobs/admin-jobs.html - 81 + 100 @@ -434,7 +434,7 @@ Estado apps/client/src/app/components/admin-jobs/admin-jobs.html - 90 + 109 @@ -442,7 +442,7 @@ Eliminar Tarefas apps/client/src/app/components/admin-jobs/admin-jobs.html - 126 + 158 @@ -466,7 +466,7 @@ Visualizar dados apps/client/src/app/components/admin-jobs/admin-jobs.html - 141 + 173 @@ -474,7 +474,7 @@ Ver Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 148 + 180 @@ -482,7 +482,7 @@ Apagar Tarefa apps/client/src/app/components/admin-jobs/admin-jobs.html - 154 + 186 @@ -506,7 +506,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 11 + 12 libs/ui/src/lib/activities-table/activities-table.component.html @@ -856,6 +856,10 @@ apps/client/src/app/components/admin-overview/admin-overview.html 231 + + libs/ui/src/lib/account-balances/account-balances.component.html + 93 + Housekeeping @@ -1446,7 +1450,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 68 + 69 @@ -1458,7 +1462,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 70 + 72 @@ -1474,7 +1478,7 @@ Depósito libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 332 + 357 @@ -1901,7 +1905,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 188 + 215 @@ -1913,7 +1917,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -1925,7 +1929,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -1937,7 +1941,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -1949,7 +1953,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 209 + 236 @@ -1969,7 +1973,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 89 + 91 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -1981,7 +1985,7 @@ Oops! Ocorreu um erro. apps/client/src/app/core/http-response.interceptor.ts - 87 + 89 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -1993,7 +1997,7 @@ OK apps/client/src/app/core/http-response.interceptor.ts - 90 + 92 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -3137,7 +3141,7 @@ Deseja realmente eliminar esta atividade? libs/ui/src/lib/activities-table/activities-table.component.ts - 175 + 215 @@ -3185,7 +3189,7 @@ Juros libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 342 + 367 libs/ui/src/lib/i18n.ts @@ -3197,7 +3201,7 @@ Poupanças libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 352 + 377 @@ -3233,7 +3237,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 385 + 389 @@ -3409,11 +3413,11 @@ Sem dados disponíveis libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 387 + 391 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 400 + 404 @@ -4105,7 +4109,7 @@ Deseja mesmo eliminar todas as suas atividades? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 171 + 168 @@ -11149,7 +11153,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 81 + 83 apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts @@ -11185,7 +11189,7 @@ libs/ui/src/lib/membership-card/membership-card.component.ts - 13 + 25 @@ -13433,7 +13437,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 111 + 138 @@ -14633,7 +14637,7 @@ Do you really want to delete this account balance? libs/ui/src/lib/account-balances/account-balances.component.ts - 58 + 104 @@ -14801,7 +14805,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14809,7 +14813,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14817,7 +14821,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 @@ -14825,7 +14829,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 @@ -14833,7 +14837,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -14877,7 +14881,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -14885,7 +14889,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -14969,7 +14973,7 @@ Oops! It looks like you’re making too many requests. Please slow down a bit. apps/client/src/app/core/http-response.interceptor.ts - 105 + 107 @@ -15017,7 +15021,23 @@ Execute Job apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 183 + + + + Priority + Priority + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 63 + + + + This action is not allowed. + This action is not allowed. + + apps/client/src/app/core/http-response.interceptor.ts + 70 diff --git a/apps/client/src/locales/messages.tr.xlf b/apps/client/src/locales/messages.tr.xlf index 39f5817ce..51dd75275 100644 --- a/apps/client/src/locales/messages.tr.xlf +++ b/apps/client/src/locales/messages.tr.xlf @@ -654,7 +654,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 81 + 83 apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts @@ -690,7 +690,7 @@ libs/ui/src/lib/membership-card/membership-card.component.ts - 13 + 25 @@ -1754,7 +1754,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 20 + 34 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1830,7 +1830,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 51 + 80 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1890,7 +1890,7 @@ Deneme apps/client/src/app/components/admin-jobs/admin-jobs.html - 63 + 82 @@ -1898,7 +1898,7 @@ Oluşturuldu apps/client/src/app/components/admin-jobs/admin-jobs.html - 72 + 91 @@ -1906,7 +1906,7 @@ Tamamlandı apps/client/src/app/components/admin-jobs/admin-jobs.html - 81 + 100 @@ -1914,7 +1914,7 @@ Durum apps/client/src/app/components/admin-jobs/admin-jobs.html - 90 + 109 @@ -1922,7 +1922,7 @@ İşleri Sil apps/client/src/app/components/admin-jobs/admin-jobs.html - 126 + 158 @@ -1946,7 +1946,7 @@ Veri Gör apps/client/src/app/components/admin-jobs/admin-jobs.html - 141 + 173 @@ -1954,7 +1954,7 @@ Hata İzini Görüntüle apps/client/src/app/components/admin-jobs/admin-jobs.html - 148 + 180 @@ -1962,7 +1962,7 @@ İşleri Sil apps/client/src/app/components/admin-jobs/admin-jobs.html - 154 + 186 @@ -1986,7 +1986,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 11 + 12 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2528,6 +2528,10 @@ apps/client/src/app/components/admin-overview/admin-overview.html 231 + + libs/ui/src/lib/account-balances/account-balances.component.html + 93 + Housekeeping @@ -2990,7 +2994,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 68 + 69 @@ -3002,7 +3006,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 70 + 72 @@ -3529,7 +3533,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 188 + 215 @@ -3541,7 +3545,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -3553,7 +3557,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -3565,7 +3569,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -3577,7 +3581,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 209 + 236 @@ -3597,7 +3601,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 89 + 91 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -3609,7 +3613,7 @@ Hay Allah! Bir şeyler yanlış gitti. apps/client/src/app/core/http-response.interceptor.ts - 87 + 89 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -3621,7 +3625,7 @@ Tamam apps/client/src/app/core/http-response.interceptor.ts - 90 + 92 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -4453,7 +4457,7 @@ Tüm işlemlerinizi silmeyi gerçekten istiyor musunuz? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 171 + 168 @@ -4873,7 +4877,7 @@ Para Yatırma libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 332 + 357 @@ -12669,7 +12673,7 @@ TBu işlemi silmeyi gerçekten istiyor musunuz? libs/ui/src/lib/activities-table/activities-table.component.ts - 175 + 215 @@ -12741,7 +12745,7 @@ Faiz libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 342 + 367 libs/ui/src/lib/i18n.ts @@ -12753,7 +12757,7 @@ Tasarruflar libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 352 + 377 @@ -12909,7 +12913,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 385 + 389 @@ -13157,11 +13161,11 @@ No data available libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 387 + 391 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 400 + 404 @@ -13433,7 +13437,7 @@ Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 111 + 138 @@ -14633,7 +14637,7 @@ Do you really want to delete this account balance? libs/ui/src/lib/account-balances/account-balances.component.ts - 58 + 104 @@ -14801,7 +14805,7 @@ Week to date libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14809,7 +14813,7 @@ WTD libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14817,7 +14821,7 @@ Month to date libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 @@ -14825,7 +14829,7 @@ MTD libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 @@ -14833,7 +14837,7 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -14877,7 +14881,7 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -14885,7 +14889,7 @@ years libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -14969,7 +14973,7 @@ Oops! It looks like you’re making too many requests. Please slow down a bit. apps/client/src/app/core/http-response.interceptor.ts - 105 + 107 @@ -15017,7 +15021,23 @@ Execute Job apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 183 + + + + Priority + Priority + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 63 + + + + This action is not allowed. + This action is not allowed. + + apps/client/src/app/core/http-response.interceptor.ts + 70 diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index 53ff1578b..b39de189e 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -649,7 +649,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 81 + 83 apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts @@ -685,7 +685,7 @@ libs/ui/src/lib/membership-card/membership-card.component.ts - 13 + 25 @@ -1759,7 +1759,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 20 + 34 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1833,7 +1833,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 51 + 80 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1903,56 +1903,56 @@ Attempts apps/client/src/app/components/admin-jobs/admin-jobs.html - 63 + 82 Created apps/client/src/app/components/admin-jobs/admin-jobs.html - 72 + 91 Finished apps/client/src/app/components/admin-jobs/admin-jobs.html - 81 + 100 Status apps/client/src/app/components/admin-jobs/admin-jobs.html - 90 + 109 Delete Jobs apps/client/src/app/components/admin-jobs/admin-jobs.html - 126 + 158 View Data apps/client/src/app/components/admin-jobs/admin-jobs.html - 141 + 173 View Stacktrace apps/client/src/app/components/admin-jobs/admin-jobs.html - 148 + 180 Delete Job apps/client/src/app/components/admin-jobs/admin-jobs.html - 154 + 186 @@ -1974,7 +1974,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 11 + 12 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2523,6 +2523,10 @@ apps/client/src/app/components/admin-overview/admin-overview.html 231 + + libs/ui/src/lib/account-balances/account-balances.component.html + 93 + Housekeeping @@ -2992,7 +2996,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 68 + 69 @@ -3003,7 +3007,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 70 + 72 @@ -3488,7 +3492,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 188 + 215 @@ -3499,7 +3503,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -3510,7 +3514,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -3521,7 +3525,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -3532,7 +3536,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 209 + 236 @@ -3779,7 +3783,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 89 + 91 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -3790,7 +3794,7 @@ Oops! Something went wrong. apps/client/src/app/core/http-response.interceptor.ts - 87 + 89 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -3801,7 +3805,7 @@ Okay apps/client/src/app/core/http-response.interceptor.ts - 90 + 92 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -4615,7 +4619,7 @@ Do you really want to delete all your activities? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 171 + 168 @@ -5011,7 +5015,7 @@ Deposit libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 332 + 357 @@ -13459,7 +13463,7 @@ Do you really want to delete this account balance? libs/ui/src/lib/account-balances/account-balances.component.ts - 58 + 104 @@ -13538,14 +13542,14 @@ Do you really want to delete this activity? libs/ui/src/lib/activities-table/activities-table.component.ts - 175 + 215 Find holding... libs/ui/src/lib/assistant/assistant.component.ts - 111 + 138 @@ -13647,7 +13651,7 @@ Interest libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 342 + 367 libs/ui/src/lib/i18n.ts @@ -13658,7 +13662,7 @@ Savings libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 352 + 377 @@ -13795,7 +13799,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 385 + 389 @@ -14054,11 +14058,11 @@ No data available libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 387 + 391 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 400 + 404 @@ -14200,35 +14204,35 @@ Year to date libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 Week to date libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 Month to date libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 MTD libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 WTD libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14267,14 +14271,14 @@ year libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 years libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -14349,7 +14353,7 @@ Oops! It looks like you’re making too many requests. Please slow down a bit. apps/client/src/app/core/http-response.interceptor.ts - 105 + 107 @@ -14391,7 +14395,21 @@ Execute Job apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 183 + + + + This action is not allowed. + + apps/client/src/app/core/http-response.interceptor.ts + 70 + + + + Priority + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 63 diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index fa47da7e0..8b44e31b6 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -655,7 +655,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 81 + 83 apps/client/src/app/pages/blog/2021/07/hallo-ghostfolio/hallo-ghostfolio-page.component.ts @@ -691,7 +691,7 @@ libs/ui/src/lib/membership-card/membership-card.component.ts - 13 + 25 @@ -1799,7 +1799,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 20 + 34 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1875,7 +1875,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 51 + 80 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1951,7 +1951,7 @@ 尝试 apps/client/src/app/components/admin-jobs/admin-jobs.html - 63 + 82 @@ -1959,7 +1959,7 @@ 创建 apps/client/src/app/components/admin-jobs/admin-jobs.html - 72 + 91 @@ -1967,7 +1967,7 @@ 完成的 apps/client/src/app/components/admin-jobs/admin-jobs.html - 81 + 100 @@ -1975,7 +1975,7 @@ 状况 apps/client/src/app/components/admin-jobs/admin-jobs.html - 90 + 109 @@ -1983,7 +1983,7 @@ 删除作业 apps/client/src/app/components/admin-jobs/admin-jobs.html - 126 + 158 @@ -1991,7 +1991,7 @@ 查看数据 apps/client/src/app/components/admin-jobs/admin-jobs.html - 141 + 173 @@ -1999,7 +1999,7 @@ 查看堆栈跟踪 apps/client/src/app/components/admin-jobs/admin-jobs.html - 148 + 180 @@ -2007,7 +2007,7 @@ 删除作业 apps/client/src/app/components/admin-jobs/admin-jobs.html - 154 + 186 @@ -2031,7 +2031,7 @@ libs/ui/src/lib/account-balances/account-balances.component.html - 11 + 12 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2633,6 +2633,10 @@ apps/client/src/app/components/admin-overview/admin-overview.html 231 + + libs/ui/src/lib/account-balances/account-balances.component.html + 93 + Housekeeping @@ -3155,7 +3159,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 68 + 69 @@ -3167,7 +3171,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 70 + 72 @@ -3705,7 +3709,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 188 + 215 @@ -3717,7 +3721,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -3729,7 +3733,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -3741,7 +3745,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -3753,7 +3757,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 209 + 236 @@ -4033,7 +4037,7 @@ apps/client/src/app/core/http-response.interceptor.ts - 89 + 91 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -4045,7 +4049,7 @@ 哎呀!出了些问题。 apps/client/src/app/core/http-response.interceptor.ts - 87 + 89 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -4057,7 +4061,7 @@ 好的 apps/client/src/app/core/http-response.interceptor.ts - 90 + 92 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -4969,7 +4973,7 @@ 您真的要删除所有活动吗? apps/client/src/app/pages/portfolio/activities/activities-page.component.ts - 171 + 168 @@ -5413,7 +5417,7 @@ 订金 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 332 + 357 @@ -13965,7 +13969,7 @@ 您确实要删除该帐户余额吗? libs/ui/src/lib/account-balances/account-balances.component.ts - 58 + 104 @@ -14053,7 +14057,7 @@ 您确实要删除此活动吗? libs/ui/src/lib/activities-table/activities-table.component.ts - 175 + 215 @@ -14061,7 +14065,7 @@ 查找持有... libs/ui/src/lib/assistant/assistant.component.ts - 111 + 138 @@ -14177,7 +14181,7 @@ 利息 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 342 + 367 libs/ui/src/lib/i18n.ts @@ -14189,7 +14193,7 @@ 储蓄 libs/ui/src/lib/fire-calculator/fire-calculator.component.ts - 352 + 377 @@ -14345,7 +14349,7 @@ libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 385 + 389 @@ -14641,11 +14645,11 @@ 无可用数据 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 387 + 391 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts - 400 + 404 @@ -14805,7 +14809,7 @@ 今年迄今为止 libs/ui/src/lib/assistant/assistant.component.ts - 198 + 225 @@ -14813,7 +14817,7 @@ 本周至今 libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14821,7 +14825,7 @@ 本月至今 libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 @@ -14829,7 +14833,7 @@ 最大输运量 libs/ui/src/lib/assistant/assistant.component.ts - 194 + 221 @@ -14837,7 +14841,7 @@ 世界贸易组织 libs/ui/src/lib/assistant/assistant.component.ts - 190 + 217 @@ -14881,7 +14885,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 202 + 229 @@ -14889,7 +14893,7 @@ libs/ui/src/lib/assistant/assistant.component.ts - 206 + 233 @@ -14973,7 +14977,7 @@ 哎呀!看来您提出了太多要求。请慢一点。 apps/client/src/app/core/http-response.interceptor.ts - 105 + 107 @@ -15021,7 +15025,23 @@ Execute Job apps/client/src/app/components/admin-jobs/admin-jobs.html - 151 + 183 + + + + Priority + Priority + + apps/client/src/app/components/admin-jobs/admin-jobs.html + 63 + + + + This action is not allowed. + This action is not allowed. + + apps/client/src/app/core/http-response.interceptor.ts + 70 From 895c4fe2999fadb77c67538af7db2c13fc4f8c1e Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 20 Apr 2024 12:54:23 +0200 Subject: [PATCH 147/203] Improve style on mobile (#3310) --- apps/client/src/app/pages/webauthn/webauthn-page.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/client/src/app/pages/webauthn/webauthn-page.scss b/apps/client/src/app/pages/webauthn/webauthn-page.scss index 5d4e87f30..e138a380b 100644 --- a/apps/client/src/app/pages/webauthn/webauthn-page.scss +++ b/apps/client/src/app/pages/webauthn/webauthn-page.scss @@ -1,3 +1,9 @@ :host { display: block; + + button { + @media (max-width: 575.98px) { + width: 100%; + } + } } From 551b83a6e346e9fa54fc79cd8bce3c2a248e9fdb Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 20 Apr 2024 15:40:59 +0200 Subject: [PATCH 148/203] Bugfix/fix gaps in portfolio performance charts (#3311) * Fix gaps in charts * Update changelog --- CHANGELOG.md | 4 ++++ .../app/portfolio/calculator/twr/portfolio-calculator.ts | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e6f610cd..85ae101f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Upgraded `angular` from version `17.3.3` to `17.3.5` - Upgraded `Nx` from version `18.2.3` to `18.3.3` +### Fixed + +- Fixed gaps in the portfolio performance charts by considering `BUY` and `SELL` activities + ## 2.73.0 - 2024-04-17 ### Added diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index 1567483bb..032d13a64 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -334,8 +334,10 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { if (isChartMode) { const datesWithOrders = {}; - for (const order of orders) { - datesWithOrders[order.date] = true; + for (const { date, type } of orders) { + if (['BUY', 'SELL'].includes(type)) { + datesWithOrders[date] = true; + } } while (isBefore(day, end)) { From 95382581f1dfcebf67f08a9f8a185ccd9d2572e0 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 20 Apr 2024 15:43:03 +0200 Subject: [PATCH 149/203] Release 2.74.0 (#3312) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85ae101f0..68b4be4d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.74.0 - 2024-04-20 ### Added diff --git a/package.json b/package.json index efd40e324..49a992841 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.73.0", + "version": "2.74.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From b6ea7d23fabd08ce27432924992e297d802bbd11 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 21 Apr 2024 08:33:38 +0200 Subject: [PATCH 150/203] Bugfix/add total value in base currency to redacted values (#3313) * Add totalValueInBaseCurrency * Update changelog --- CHANGELOG.md | 6 ++++++ .../interceptors/redact-values-in-response.interceptor.ts | 1 + 2 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68b4be4d0..87b393347 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Fixed + +- Fixed an issue with `totalValueInBaseCurrency` in the value redaction interceptor for the impersonation mode + ## 2.74.0 - 2024-04-20 ### Added diff --git a/apps/api/src/interceptors/redact-values-in-response.interceptor.ts b/apps/api/src/interceptors/redact-values-in-response.interceptor.ts index 78ae918d2..17d4e3c17 100644 --- a/apps/api/src/interceptors/redact-values-in-response.interceptor.ts +++ b/apps/api/src/interceptors/redact-values-in-response.interceptor.ts @@ -57,6 +57,7 @@ export class RedactValuesInResponseInterceptor 'quantity', 'symbolMapping', 'totalBalanceInBaseCurrency', + 'totalValueInBaseCurrency', 'unitPrice', 'value', 'valueInBaseCurrency' From 2d70b18593d213623ec896c0e2e0be49a0d0d7a2 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 21 Apr 2024 10:08:22 +0200 Subject: [PATCH 151/203] Remove links (#3306) --- README.md | 2 -- apps/client/src/app/pages/landing/landing-page.html | 6 ------ 2 files changed, 8 deletions(-) diff --git a/README.md b/README.md index 2c8cb664c..d63bb10d0 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,6 @@ [![Shield: Contributions Welcome](https://img.shields.io/badge/Contributions-Welcome-orange.svg)](#contributing) [![Shield: License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0) -New: [Ghostfolio 2.0](https://ghostfol.io/en/blog/2023/09/ghostfolio-2) -
**Ghostfolio** is an open source wealth management software built with web technology. The application empowers busy people to keep track of stocks, ETFs or cryptocurrencies and make solid, data-driven investment decisions. The software is designed for personal use in continuous operation. diff --git a/apps/client/src/app/pages/landing/landing-page.html b/apps/client/src/app/pages/landing/landing-page.html index 579b35702..331defae4 100644 --- a/apps/client/src/app/pages/landing/landing-page.html +++ b/apps/client/src/app/pages/landing/landing-page.html @@ -2,12 +2,6 @@
-

Manage your wealth like a boss

From 1132dc9bdd90122032b1e897152cb9c41b069b80 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 21 Apr 2024 10:28:51 +0200 Subject: [PATCH 152/203] Feature/add unique constraint to account balance database schema (#3315) * Add accountId and date as unique constraint to AccountBalance schema * Update changelog --- CHANGELOG.md | 4 ++ .../account-balance.controller.ts | 16 +++----- .../account-balance.service.ts | 39 ++++++++++++++++--- apps/api/src/app/account/account.service.ts | 17 +++----- .../migration.sql | 29 ++++++++++++++ prisma/schema.prisma | 1 + 6 files changed, 80 insertions(+), 26 deletions(-) create mode 100644 prisma/migrations/20240421080039_added_account_id_and_date_to_account_balance_as_unique_constraint/migration.sql diff --git a/CHANGELOG.md b/CHANGELOG.md index 87b393347..460310451 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Added `accountId` and `date` as a unique constraint to the `AccountBalance` database schema + ### Fixed - Fixed an issue with `totalValueInBaseCurrency` in the value redaction interceptor for the impersonation mode diff --git a/apps/api/src/app/account-balance/account-balance.controller.ts b/apps/api/src/app/account-balance/account-balance.controller.ts index 12f21753b..4a8412003 100644 --- a/apps/api/src/app/account-balance/account-balance.controller.ts +++ b/apps/api/src/app/account-balance/account-balance.controller.ts @@ -1,6 +1,7 @@ import { AccountService } from '@ghostfolio/api/app/account/account.service'; import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator'; import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; +import { resetHours } from '@ghostfolio/common/helper'; import { permissions } from '@ghostfolio/common/permissions'; import type { RequestWithUser } from '@ghostfolio/common/types'; @@ -17,6 +18,7 @@ import { import { REQUEST } from '@nestjs/core'; import { AuthGuard } from '@nestjs/passport'; import { AccountBalance } from '@prisma/client'; +import { parseISO } from 'date-fns'; import { StatusCodes, getReasonPhrase } from 'http-status-codes'; import { AccountBalanceService } from './account-balance.service'; @@ -50,17 +52,11 @@ export class AccountBalanceController { ); } - return this.accountBalanceService.createAccountBalance({ - Account: { - connect: { - id_userId: { - id: account.id, - userId: account.userId - } - } - }, + return this.accountBalanceService.createOrUpdateAccountBalance({ + accountId: account.id, + balance: data.balance, date: data.date, - value: data.balance + userId: account.userId }); } diff --git a/apps/api/src/app/account-balance/account-balance.service.ts b/apps/api/src/app/account-balance/account-balance.service.ts index 8a9d7b83e..5a5ec5be0 100644 --- a/apps/api/src/app/account-balance/account-balance.service.ts +++ b/apps/api/src/app/account-balance/account-balance.service.ts @@ -1,10 +1,14 @@ import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; +import { resetHours } from '@ghostfolio/common/helper'; import { AccountBalancesResponse, Filter } from '@ghostfolio/common/interfaces'; import { UserWithSettings } from '@ghostfolio/common/types'; import { Injectable } from '@nestjs/common'; import { AccountBalance, Prisma } from '@prisma/client'; +import { parseISO } from 'date-fns'; + +import { CreateAccountBalanceDto } from './create-account-balance.dto'; @Injectable() export class AccountBalanceService { @@ -24,11 +28,36 @@ export class AccountBalanceService { }); } - public async createAccountBalance( - data: Prisma.AccountBalanceCreateInput - ): Promise { - return this.prismaService.accountBalance.create({ - data + public async createOrUpdateAccountBalance({ + accountId, + balance, + date, + userId + }: CreateAccountBalanceDto & { + userId: string; + }): Promise { + return this.prismaService.accountBalance.upsert({ + create: { + Account: { + connect: { + id_userId: { + userId, + id: accountId + } + } + }, + date: resetHours(parseISO(date)), + value: balance + }, + update: { + value: balance + }, + where: { + accountId_date: { + accountId, + date: resetHours(parseISO(date)) + } + } }); } diff --git a/apps/api/src/app/account/account.service.ts b/apps/api/src/app/account/account.service.ts index 697041645..fed1860cd 100644 --- a/apps/api/src/app/account/account.service.ts +++ b/apps/api/src/app/account/account.service.ts @@ -6,6 +6,7 @@ import { Filter } from '@ghostfolio/common/interfaces'; import { Injectable } from '@nestjs/common'; import { Account, Order, Platform, Prisma } from '@prisma/client'; import { Big } from 'big.js'; +import { parseISO } from 'date-fns'; import { groupBy } from 'lodash'; import { CashDetails } from './interfaces/cash-details.interface'; @@ -242,17 +243,11 @@ export class AccountService { ); if (amountInCurrencyOfAccount) { - await this.accountBalanceService.createAccountBalance({ - date, - Account: { - connect: { - id_userId: { - userId, - id: accountId - } - } - }, - value: new Big(balance).plus(amountInCurrencyOfAccount).toNumber() + await this.accountBalanceService.createOrUpdateAccountBalance({ + accountId, + userId, + balance: new Big(balance).plus(amountInCurrencyOfAccount).toNumber(), + date: date.toISOString() }); } } diff --git a/prisma/migrations/20240421080039_added_account_id_and_date_to_account_balance_as_unique_constraint/migration.sql b/prisma/migrations/20240421080039_added_account_id_and_date_to_account_balance_as_unique_constraint/migration.sql new file mode 100644 index 000000000..96521bbfa --- /dev/null +++ b/prisma/migrations/20240421080039_added_account_id_and_date_to_account_balance_as_unique_constraint/migration.sql @@ -0,0 +1,29 @@ +-- Only keep the newest AccountBalance entry for each account / day +WITH entries_to_keep AS ( + SELECT + id, + "accountId", + date, + ROW_NUMBER() OVER (PARTITION BY "accountId", DATE(date) ORDER BY date DESC) AS row_num + FROM + "AccountBalance" +), +entries_to_delete AS ( + SELECT + id + FROM + entries_to_keep + WHERE + row_num > 1 +) +DELETE FROM + "AccountBalance" +WHERE + id IN (SELECT id FROM entries_to_delete); + +-- Reset time part of the date +UPDATE "AccountBalance" +SET date = DATE_TRUNC('day', date); + +-- CreateIndex +CREATE UNIQUE INDEX "AccountBalance_accountId_date_key" ON "AccountBalance"("accountId", "date"); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index f9a17d114..af7ad1845 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -59,6 +59,7 @@ model AccountBalance { value Float Account Account @relation(fields: [accountId, userId], onDelete: Cascade, references: [id, userId]) + @@unique([accountId, date]) @@index([accountId]) @@index([date]) } From ab59eb5c925892690e3c777b8729fee5e87bcd37 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 21 Apr 2024 10:30:14 +0200 Subject: [PATCH 153/203] Release 2.75.0 (#3316) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 460310451..d4b1e2c0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.75.0 - 2024-04-21 ### Added diff --git a/package.json b/package.json index 49a992841..505db31f0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.74.0", + "version": "2.75.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 39bd4a349bbdf1d457a119b53263028ce020c33c Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 21 Apr 2024 17:11:53 +0200 Subject: [PATCH 154/203] Feature/improve chart in account detail dialog (#3314) * Improve net worth calculation in portfolio performance chart * Improve account balance management * Update changelog --- CHANGELOG.md | 7 + apps/api/src/app/account/account.service.ts | 31 ++- .../portfolio-calculator.factory.ts | 5 + .../calculator/portfolio-calculator.ts | 178 +++++++++++++----- .../portfolio-calculator-no-orders.spec.ts | 7 +- ...folio-calculator-novn-buy-and-sell.spec.ts | 4 + .../calculator/twr/portfolio-calculator.ts | 4 + .../src/app/portfolio/portfolio.service.ts | 84 ++------- .../account-detail-dialog.component.ts | 108 ++++++----- .../pages/accounts/accounts-page.component.ts | 2 + .../interfaces/symbol-metrics.interface.ts | 1 + 11 files changed, 245 insertions(+), 186 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4b1e2c0c..7bb4dc05a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- Improved the chart in the account detail dialog +- Improved the account balance management + ## 2.75.0 - 2024-04-21 ### Added diff --git a/apps/api/src/app/account/account.service.ts b/apps/api/src/app/account/account.service.ts index fed1860cd..6be7e8ffb 100644 --- a/apps/api/src/app/account/account.service.ts +++ b/apps/api/src/app/account/account.service.ts @@ -1,12 +1,13 @@ import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; +import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { Filter } from '@ghostfolio/common/interfaces'; import { Injectable } from '@nestjs/common'; import { Account, Order, Platform, Prisma } from '@prisma/client'; import { Big } from 'big.js'; -import { parseISO } from 'date-fns'; +import { format } from 'date-fns'; import { groupBy } from 'lodash'; import { CashDetails } from './interfaces/cash-details.interface'; @@ -86,15 +87,11 @@ export class AccountService { data }); - await this.prismaService.accountBalance.create({ - data: { - Account: { - connect: { - id_userId: { id: account.id, userId: aUserId } - } - }, - value: data.balance - } + await this.accountBalanceService.createOrUpdateAccountBalance({ + accountId: account.id, + balance: data.balance, + date: format(new Date(), DATE_FORMAT), + userId: aUserId }); return account; @@ -197,15 +194,11 @@ export class AccountService { ): Promise { const { data, where } = params; - await this.prismaService.accountBalance.create({ - data: { - Account: { - connect: { - id_userId: where.id_userId - } - }, - value: data.balance - } + await this.accountBalanceService.createOrUpdateAccountBalance({ + accountId: data.id, + balance: data.balance, + date: format(new Date(), DATE_FORMAT), + userId: aUserId }); return this.prismaService.account.update({ diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts index e64c23942..a75ce9b62 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts @@ -1,6 +1,7 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; +import { HistoricalDataItem } from '@ghostfolio/common/interfaces'; import { DateRange } from '@ghostfolio/common/types'; import { Injectable } from '@nestjs/common'; @@ -22,11 +23,13 @@ export class PortfolioCalculatorFactory { ) {} public createCalculator({ + accountBalanceItems = [], activities, calculationType, currency, dateRange = 'max' }: { + accountBalanceItems?: HistoricalDataItem[]; activities: Activity[]; calculationType: PerformanceCalculationType; currency: string; @@ -35,6 +38,7 @@ export class PortfolioCalculatorFactory { switch (calculationType) { case PerformanceCalculationType.MWR: return new MWRPortfolioCalculator({ + accountBalanceItems, activities, currency, dateRange, @@ -43,6 +47,7 @@ export class PortfolioCalculatorFactory { }); case PerformanceCalculationType.TWR: return new TWRPortfolioCalculator({ + accountBalanceItems, activities, currency, currentRateService: this.currentRateService, diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index 1d2eadfbf..54e474779 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -37,13 +37,15 @@ import { isBefore, isSameDay, max, + min, subDays } from 'date-fns'; -import { last, uniq, uniqBy } from 'lodash'; +import { first, last, uniq, uniqBy } from 'lodash'; export abstract class PortfolioCalculator { protected static readonly ENABLE_LOGGING = false; + protected accountBalanceItems: HistoricalDataItem[]; protected orders: PortfolioOrder[]; private currency: string; @@ -57,18 +59,21 @@ export abstract class PortfolioCalculator { private transactionPoints: TransactionPoint[]; public constructor({ + accountBalanceItems, activities, currency, currentRateService, dateRange, exchangeRateDataService }: { + accountBalanceItems: HistoricalDataItem[]; activities: Activity[]; currency: string; currentRateService: CurrentRateService; dateRange: DateRange; exchangeRateDataService: ExchangeRateDataService; }) { + this.accountBalanceItems = accountBalanceItems; this.currency = currency; this.currentRateService = currentRateService; this.exchangeRateDataService = exchangeRateDataService; @@ -383,10 +388,6 @@ export abstract class PortfolioCalculator { dateRange?: DateRange; withDataDecimation?: boolean; }): Promise { - if (this.getTransactionPoints().length === 0) { - return []; - } - const { endDate, startDate } = getInterval(dateRange, this.getStartDate()); const daysInMarket = differenceInDays(endDate, startDate) + 1; @@ -485,6 +486,7 @@ export abstract class PortfolioCalculator { investmentValueWithCurrencyEffect: Big; totalCurrentValue: Big; totalCurrentValueWithCurrencyEffect: Big; + totalAccountBalanceWithCurrencyEffect: Big; totalInvestmentValue: Big; totalInvestmentValueWithCurrencyEffect: Big; totalNetPerformanceValue: Big; @@ -544,9 +546,24 @@ export abstract class PortfolioCalculator { }; } + let lastDate = format(this.startDate, DATE_FORMAT); + for (const currentDate of dates) { const dateString = format(currentDate, DATE_FORMAT); + accumulatedValuesByDate[dateString] = { + investmentValueWithCurrencyEffect: new Big(0), + totalAccountBalanceWithCurrencyEffect: new Big(0), + totalCurrentValue: new Big(0), + totalCurrentValueWithCurrencyEffect: new Big(0), + totalInvestmentValue: new Big(0), + totalInvestmentValueWithCurrencyEffect: new Big(0), + totalNetPerformanceValue: new Big(0), + totalNetPerformanceValueWithCurrencyEffect: new Big(0), + totalTimeWeightedInvestmentValue: new Big(0), + totalTimeWeightedInvestmentValueWithCurrencyEffect: new Big(0) + }; + for (const symbol of Object.keys(valuesBySymbol)) { const symbolValues = valuesBySymbol[symbol]; @@ -584,49 +601,94 @@ export abstract class PortfolioCalculator { dateString ] ?? new Big(0); - accumulatedValuesByDate[dateString] = { - investmentValueWithCurrencyEffect: ( - accumulatedValuesByDate[dateString] - ?.investmentValueWithCurrencyEffect ?? new Big(0) - ).add(investmentValueWithCurrencyEffect), - totalCurrentValue: ( - accumulatedValuesByDate[dateString]?.totalCurrentValue ?? new Big(0) - ).add(currentValue), - totalCurrentValueWithCurrencyEffect: ( - accumulatedValuesByDate[dateString] - ?.totalCurrentValueWithCurrencyEffect ?? new Big(0) - ).add(currentValueWithCurrencyEffect), - totalInvestmentValue: ( - accumulatedValuesByDate[dateString]?.totalInvestmentValue ?? - new Big(0) - ).add(investmentValueAccumulated), - totalInvestmentValueWithCurrencyEffect: ( - accumulatedValuesByDate[dateString] - ?.totalInvestmentValueWithCurrencyEffect ?? new Big(0) - ).add(investmentValueAccumulatedWithCurrencyEffect), - totalNetPerformanceValue: ( - accumulatedValuesByDate[dateString]?.totalNetPerformanceValue ?? - new Big(0) - ).add(netPerformanceValue), - totalNetPerformanceValueWithCurrencyEffect: ( - accumulatedValuesByDate[dateString] - ?.totalNetPerformanceValueWithCurrencyEffect ?? new Big(0) - ).add(netPerformanceValueWithCurrencyEffect), - totalTimeWeightedInvestmentValue: ( - accumulatedValuesByDate[dateString] - ?.totalTimeWeightedInvestmentValue ?? new Big(0) - ).add(timeWeightedInvestmentValue), - totalTimeWeightedInvestmentValueWithCurrencyEffect: ( - accumulatedValuesByDate[dateString] - ?.totalTimeWeightedInvestmentValueWithCurrencyEffect ?? new Big(0) - ).add(timeWeightedInvestmentValueWithCurrencyEffect) - }; + accumulatedValuesByDate[dateString].investmentValueWithCurrencyEffect = + accumulatedValuesByDate[ + dateString + ].investmentValueWithCurrencyEffect.add( + investmentValueWithCurrencyEffect + ); + + accumulatedValuesByDate[dateString].totalCurrentValue = + accumulatedValuesByDate[dateString].totalCurrentValue.add( + currentValue + ); + + accumulatedValuesByDate[ + dateString + ].totalCurrentValueWithCurrencyEffect = accumulatedValuesByDate[ + dateString + ].totalCurrentValueWithCurrencyEffect.add( + currentValueWithCurrencyEffect + ); + + accumulatedValuesByDate[dateString].totalInvestmentValue = + accumulatedValuesByDate[dateString].totalInvestmentValue.add( + investmentValueAccumulated + ); + + accumulatedValuesByDate[ + dateString + ].totalInvestmentValueWithCurrencyEffect = accumulatedValuesByDate[ + dateString + ].totalInvestmentValueWithCurrencyEffect.add( + investmentValueAccumulatedWithCurrencyEffect + ); + + accumulatedValuesByDate[dateString].totalNetPerformanceValue = + accumulatedValuesByDate[dateString].totalNetPerformanceValue.add( + netPerformanceValue + ); + + accumulatedValuesByDate[ + dateString + ].totalNetPerformanceValueWithCurrencyEffect = accumulatedValuesByDate[ + dateString + ].totalNetPerformanceValueWithCurrencyEffect.add( + netPerformanceValueWithCurrencyEffect + ); + + accumulatedValuesByDate[dateString].totalTimeWeightedInvestmentValue = + accumulatedValuesByDate[ + dateString + ].totalTimeWeightedInvestmentValue.add(timeWeightedInvestmentValue); + + accumulatedValuesByDate[ + dateString + ].totalTimeWeightedInvestmentValueWithCurrencyEffect = + accumulatedValuesByDate[ + dateString + ].totalTimeWeightedInvestmentValueWithCurrencyEffect.add( + timeWeightedInvestmentValueWithCurrencyEffect + ); + } + + if ( + this.accountBalanceItems.some(({ date }) => { + return date === dateString; + }) + ) { + accumulatedValuesByDate[ + dateString + ].totalAccountBalanceWithCurrencyEffect = new Big( + this.accountBalanceItems.find(({ date }) => { + return date === dateString; + }).value + ); + } else { + accumulatedValuesByDate[ + dateString + ].totalAccountBalanceWithCurrencyEffect = + accumulatedValuesByDate[lastDate] + ?.totalAccountBalanceWithCurrencyEffect ?? new Big(0); } + + lastDate = dateString; } return Object.entries(accumulatedValuesByDate).map(([date, values]) => { const { investmentValueWithCurrencyEffect, + totalAccountBalanceWithCurrencyEffect, totalCurrentValue, totalCurrentValueWithCurrencyEffect, totalInvestmentValue, @@ -661,6 +723,11 @@ export abstract class PortfolioCalculator { netPerformance: totalNetPerformanceValue.toNumber(), netPerformanceWithCurrencyEffect: totalNetPerformanceValueWithCurrencyEffect.toNumber(), + // TODO: Add valuables + netWorth: totalCurrentValueWithCurrencyEffect + .plus(totalAccountBalanceWithCurrencyEffect) + .toNumber(), + totalAccountBalance: totalAccountBalanceWithCurrencyEffect.toNumber(), totalInvestment: totalInvestmentValue.toNumber(), totalInvestmentValueWithCurrencyEffect: totalInvestmentValueWithCurrencyEffect.toNumber(), @@ -749,9 +816,30 @@ export abstract class PortfolioCalculator { } public getStartDate() { - return this.transactionPoints.length > 0 - ? parseDate(this.transactionPoints[0].date) - : new Date(); + let firstAccountBalanceDate: Date; + let firstActivityDate: Date; + + try { + const firstAccountBalanceDateString = first( + this.accountBalanceItems + )?.date; + firstAccountBalanceDate = firstAccountBalanceDateString + ? parseDate(firstAccountBalanceDateString) + : new Date(); + } catch (error) { + firstAccountBalanceDate = new Date(); + } + + try { + const firstActivityDateString = this.transactionPoints[0].date; + firstActivityDate = firstActivityDateString + ? parseDate(firstActivityDateString) + : new Date(); + } catch (error) { + firstActivityDate = new Date(); + } + + return min([firstAccountBalanceDate, firstActivityDate]); } protected abstract getSymbolMetrics({ diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts index 1d69abfbf..bd04d6045 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts @@ -90,7 +90,12 @@ describe('PortfolioCalculator', () => { expect(investments).toEqual([]); - expect(investmentsByMonth).toEqual([]); + expect(investmentsByMonth).toEqual([ + { + date: '2021-12-01', + investment: 0 + } + ]); }); }); }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts index 6f0b03800..0dd16b045 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts @@ -113,6 +113,8 @@ describe('PortfolioCalculator', () => { netPerformanceInPercentage: 0, netPerformanceInPercentageWithCurrencyEffect: 0, netPerformanceWithCurrencyEffect: 0, + netWorth: 151.6, + totalAccountBalance: 0, totalInvestment: 151.6, totalInvestmentValueWithCurrencyEffect: 151.6, value: 151.6, @@ -126,6 +128,8 @@ describe('PortfolioCalculator', () => { netPerformanceInPercentage: 13.100263852242744, netPerformanceInPercentageWithCurrencyEffect: 13.100263852242744, netPerformanceWithCurrencyEffect: 19.86, + netWorth: 0, + totalAccountBalance: 0, totalInvestment: 0, totalInvestmentValueWithCurrencyEffect: 0, value: 0, diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index 032d13a64..9458fb1bd 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -188,6 +188,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { [date: string]: Big; } = {}; + let totalAccountBalanceInBaseCurrency = new Big(0); let totalDividend = new Big(0); let totalDividendInBaseCurrency = new Big(0); let totalInterest = new Big(0); @@ -237,6 +238,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { timeWeightedInvestmentValues: {}, timeWeightedInvestmentValuesWithCurrencyEffect: {}, timeWeightedInvestmentWithCurrencyEffect: new Big(0), + totalAccountBalanceInBaseCurrency: new Big(0), totalDividend: new Big(0), totalDividendInBaseCurrency: new Big(0), totalInterest: new Big(0), @@ -286,6 +288,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { timeWeightedInvestmentValues: {}, timeWeightedInvestmentValuesWithCurrencyEffect: {}, timeWeightedInvestmentWithCurrencyEffect: new Big(0), + totalAccountBalanceInBaseCurrency: new Big(0), totalDividend: new Big(0), totalDividendInBaseCurrency: new Big(0), totalInterest: new Big(0), @@ -875,6 +878,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { netPerformanceValuesWithCurrencyEffect, timeWeightedInvestmentValues, timeWeightedInvestmentValuesWithCurrencyEffect, + totalAccountBalanceInBaseCurrency, totalDividend, totalDividendInBaseCurrency, totalInterest, diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 4c65d2eb9..cf7a47f52 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -64,7 +64,6 @@ import { differenceInDays, format, isAfter, - isBefore, isSameMonth, isSameYear, parseISO, @@ -1056,11 +1055,16 @@ export class PortfolioService { ) => { const formattedDate = format(date, DATE_FORMAT); - // Store the item in the map, overwriting if the date already exists - map[formattedDate] = { - date: formattedDate, - value: valueInBaseCurrency - }; + if (map[formattedDate]) { + // If the value exists, add the current value to the existing one + map[formattedDate].value += valueInBaseCurrency; + } else { + // Otherwise, initialize the value for that date + map[formattedDate] = { + date: formattedDate, + value: valueInBaseCurrency + }; + } return map; }, @@ -1100,6 +1104,7 @@ export class PortfolioService { } const portfolioCalculator = this.calculatorFactory.createCalculator({ + accountBalanceItems, activities, dateRange, calculationType: PerformanceCalculationType.TWR, @@ -1131,6 +1136,8 @@ export class PortfolioService { let currentNetPerformanceWithCurrencyEffect = netPerformanceWithCurrencyEffect; + let currentNetWorth = 0; + const items = await portfolioCalculator.getChart({ dateRange }); @@ -1153,35 +1160,14 @@ export class PortfolioService { currentNetPerformanceWithCurrencyEffect = new Big( itemOfToday.netPerformanceWithCurrencyEffect ); - } - - accountBalanceItems = accountBalanceItems.filter(({ date }) => { - return !isBefore(parseDate(date), startDate); - }); - const accountBalanceItemOfToday = accountBalanceItems.find(({ date }) => { - return date === format(new Date(), DATE_FORMAT); - }); - - if (!accountBalanceItemOfToday) { - accountBalanceItems.push({ - date: format(new Date(), DATE_FORMAT), - value: last(accountBalanceItems)?.value ?? 0 - }); + currentNetWorth = itemOfToday.netWorth; } - const mergedHistoricalDataItems = this.mergeHistoricalDataItems( - accountBalanceItems, - items - ); - - const currentHistoricalDataItem = last(mergedHistoricalDataItems); - const currentNetWorth = currentHistoricalDataItem?.netWorth ?? 0; - return { errors, hasErrors, - chart: mergedHistoricalDataItems, + chart: items, firstOrderDate: parseDate(items[0]?.date), performance: { currentNetWorth, @@ -1909,44 +1895,4 @@ export class PortfolioService { return { accounts, platforms }; } - - private mergeHistoricalDataItems( - accountBalanceItems: HistoricalDataItem[], - performanceChartItems: HistoricalDataItem[] - ): HistoricalDataItem[] { - const historicalDataItemsMap: { [date: string]: HistoricalDataItem } = {}; - let latestAccountBalance = 0; - - for (const item of accountBalanceItems.concat(performanceChartItems)) { - const isAccountBalanceItem = accountBalanceItems.includes(item); - - const totalAccountBalance = isAccountBalanceItem - ? item.value - : latestAccountBalance; - - if (isAccountBalanceItem && performanceChartItems.length > 0) { - latestAccountBalance = item.value; - } else { - historicalDataItemsMap[item.date] = { - ...item, - totalAccountBalance, - netWorth: - (isAccountBalanceItem ? 0 : item.value) + totalAccountBalance - }; - } - } - - // Convert to an array and sort by date in ascending order - const historicalDataItems = Object.keys(historicalDataItemsMap).map( - (date) => { - return historicalDataItemsMap[date]; - } - ); - - historicalDataItems.sort((a, b) => { - return new Date(a.date).getTime() - new Date(b.date).getTime(); - }); - - return historicalDataItems; - } } diff --git a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts index 2c2036b16..aeec7d2a5 100644 --- a/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts +++ b/apps/client/src/app/components/account-detail-dialog/account-detail-dialog.component.ts @@ -84,55 +84,10 @@ export class AccountDetailDialog implements OnDestroy, OnInit { } public ngOnInit() { - this.dataService - .fetchAccount(this.data.accountId) - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe( - ({ - balance, - currency, - name, - Platform, - transactionCount, - value, - valueInBaseCurrency - }) => { - this.balance = balance; - this.currency = currency; - - if (isNumber(balance) && isNumber(value)) { - this.equity = new Big(value).minus(balance).toNumber(); - } else { - this.equity = null; - } - - this.name = name; - this.platformName = Platform?.name ?? '-'; - this.transactionCount = transactionCount; - this.valueInBaseCurrency = valueInBaseCurrency; - - this.changeDetectorRef.markForCheck(); - } - ); - - this.dataService - .fetchPortfolioHoldings({ - filters: [ - { - type: 'ACCOUNT', - id: this.data.accountId - } - ] - }) - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(({ holdings }) => { - this.holdings = holdings; - - this.changeDetectorRef.markForCheck(); - }); - + this.fetchAccount(); this.fetchAccountBalances(); this.fetchActivities(); + this.fetchPortfolioHoldings(); this.fetchPortfolioPerformance(); } @@ -155,6 +110,7 @@ export class AccountDetailDialog implements OnDestroy, OnInit { }) .pipe(takeUntil(this.unsubscribeSubject)) .subscribe(() => { + this.fetchAccount(); this.fetchAccountBalances(); this.fetchPortfolioPerformance(); }); @@ -165,6 +121,7 @@ export class AccountDetailDialog implements OnDestroy, OnInit { .deleteAccountBalance(aId) .pipe(takeUntil(this.unsubscribeSubject)) .subscribe(() => { + this.fetchAccount(); this.fetchAccountBalances(); this.fetchPortfolioPerformance(); }); @@ -199,6 +156,39 @@ export class AccountDetailDialog implements OnDestroy, OnInit { this.fetchActivities(); } + private fetchAccount() { + this.dataService + .fetchAccount(this.data.accountId) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe( + ({ + balance, + currency, + name, + Platform, + transactionCount, + value, + valueInBaseCurrency + }) => { + this.balance = balance; + this.currency = currency; + + if (isNumber(balance) && isNumber(value)) { + this.equity = new Big(value).minus(balance).toNumber(); + } else { + this.equity = null; + } + + this.name = name; + this.platformName = Platform?.name ?? '-'; + this.transactionCount = transactionCount; + this.valueInBaseCurrency = valueInBaseCurrency; + + this.changeDetectorRef.markForCheck(); + } + ); + } + private fetchAccountBalances() { this.dataService .fetchAccountBalances(this.data.accountId) @@ -230,6 +220,24 @@ export class AccountDetailDialog implements OnDestroy, OnInit { }); } + private fetchPortfolioHoldings() { + this.dataService + .fetchPortfolioHoldings({ + filters: [ + { + type: 'ACCOUNT', + id: this.data.accountId + } + ] + }) + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(({ holdings }) => { + this.holdings = holdings; + + this.changeDetectorRef.markForCheck(); + }); + } + private fetchPortfolioPerformance() { this.isLoadingChart = true; @@ -251,11 +259,7 @@ export class AccountDetailDialog implements OnDestroy, OnInit { ({ date, netWorth, netWorthInPercentage }) => { return { date, - value: - this.data.hasImpersonationId || - this.user.settings.isRestrictedView - ? netWorthInPercentage - : netWorth + value: isNumber(netWorth) ? netWorth : netWorthInPercentage }; } ); diff --git a/apps/client/src/app/pages/accounts/accounts-page.component.ts b/apps/client/src/app/pages/accounts/accounts-page.component.ts index 93d88cd64..e1b53acd3 100644 --- a/apps/client/src/app/pages/accounts/accounts-page.component.ts +++ b/apps/client/src/app/pages/accounts/accounts-page.component.ts @@ -233,6 +233,8 @@ export class AccountsPageComponent implements OnDestroy, OnInit { .afterClosed() .pipe(takeUntil(this.unsubscribeSubject)) .subscribe(() => { + this.fetchAccounts(); + this.router.navigate(['.'], { relativeTo: this.route }); }); } diff --git a/libs/common/src/lib/interfaces/symbol-metrics.interface.ts b/libs/common/src/lib/interfaces/symbol-metrics.interface.ts index 57eed9212..6b78f273a 100644 --- a/libs/common/src/lib/interfaces/symbol-metrics.interface.ts +++ b/libs/common/src/lib/interfaces/symbol-metrics.interface.ts @@ -40,6 +40,7 @@ export interface SymbolMetrics { [date: string]: Big; }; timeWeightedInvestmentWithCurrencyEffect: Big; + totalAccountBalanceInBaseCurrency: Big; totalDividend: Big; totalDividendInBaseCurrency: Big; totalInterest: Big; From a6dde8ad434d54569fd4f686795d1b6abb5db546 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 21 Apr 2024 17:14:35 +0200 Subject: [PATCH 155/203] Release 2.75.1 (#3317) --- CHANGELOG.md | 12 +++++------- package.json | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bb4dc05a..d1d18ebaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,19 +5,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.75.1 - 2024-04-21 + +### Added + +- Added `accountId` and `date` as a unique constraint to the `AccountBalance` database schema ### Changed - Improved the chart in the account detail dialog - Improved the account balance management -## 2.75.0 - 2024-04-21 - -### Added - -- Added `accountId` and `date` as a unique constraint to the `AccountBalance` database schema - ### Fixed - Fixed an issue with `totalValueInBaseCurrency` in the value redaction interceptor for the impersonation mode diff --git a/package.json b/package.json index 505db31f0..da5c207ae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.75.0", + "version": "2.75.1", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From cdbe6eedebc670579d0f31baaa6fcad051e48084 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 23 Apr 2024 18:55:37 +0200 Subject: [PATCH 156/203] Feature/change cash to liquidity in asset class enum (#3321) * Change CASH to LIQUIDITY in asset class enum * Update changelog --- CHANGELOG.md | 6 + apps/api/src/app/admin/admin.service.ts | 2 +- .../src/app/portfolio/portfolio.controller.ts | 16 +- .../src/app/portfolio/portfolio.service.ts | 11 +- .../coingecko/coingecko.service.ts | 4 +- .../yahoo-finance/yahoo-finance.service.ts | 2 +- .../eod-historical-data.service.ts | 2 +- .../allocations/allocations-page.component.ts | 4 +- apps/client/src/locales/messages.de.xlf | 140 +++++++++--------- apps/client/src/locales/messages.es.xlf | 140 +++++++++--------- apps/client/src/locales/messages.fr.xlf | 140 +++++++++--------- apps/client/src/locales/messages.it.xlf | 140 +++++++++--------- apps/client/src/locales/messages.nl.xlf | 140 +++++++++--------- apps/client/src/locales/messages.pl.xlf | 140 +++++++++--------- apps/client/src/locales/messages.pt.xlf | 140 +++++++++--------- apps/client/src/locales/messages.tr.xlf | 140 +++++++++--------- apps/client/src/locales/messages.xlf | 138 ++++++++--------- apps/client/src/locales/messages.zh.xlf | 140 +++++++++--------- libs/common/src/lib/config.ts | 1 - .../portfolio-position.interface.ts | 2 +- .../holdings-table.component.ts | 4 +- libs/ui/src/lib/i18n.ts | 1 + .../migration.sql | 2 + .../migration.sql | 2 + .../migration.sql | 7 + .../migration.sql | 9 ++ prisma/schema.prisma | 3 +- 27 files changed, 755 insertions(+), 721 deletions(-) create mode 100644 prisma/migrations/20240422181320_added_liquidity_to_asset_class/migration.sql create mode 100644 prisma/migrations/20240422181356_added_cash_to_asset_sub_class/migration.sql create mode 100644 prisma/migrations/20240422181835_changed_cash_to_liquidity_in_asset_sub_class/migration.sql create mode 100644 prisma/migrations/20240422182643_removed_cash_from_asset_class/migration.sql diff --git a/CHANGELOG.md b/CHANGELOG.md index d1d18ebaf..8f01e52cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- Changed `CASH` to `LIQUIDITY` in the asset class enum + ## 2.75.1 - 2024-04-21 ### Added diff --git a/apps/api/src/app/admin/admin.service.ts b/apps/api/src/app/admin/admin.service.ts index 2aac43a18..7df4498d7 100644 --- a/apps/api/src/app/admin/admin.service.ts +++ b/apps/api/src/app/admin/admin.service.ts @@ -416,7 +416,7 @@ export class AdminService { dataSource, marketDataItemCount, symbol, - assetClass: 'CASH', + assetClass: AssetClass.LIQUIDITY, countriesCount: 0, currency: symbol.replace(DEFAULT_CURRENCY, ''), id: undefined, diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 81d0c3df9..0828fb3e4 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -47,6 +47,7 @@ import { } from '@nestjs/common'; import { REQUEST } from '@nestjs/core'; import { AuthGuard } from '@nestjs/passport'; +import { AssetClass, AssetSubClass } from '@prisma/client'; import { Big } from 'big.js'; import { StatusCodes, getReasonPhrase } from 'http-status-codes'; @@ -128,14 +129,19 @@ export class PortfolioController { const totalValue = Object.values(holdings) .filter(({ assetClass, assetSubClass }) => { - return assetClass !== 'CASH' && assetSubClass !== 'CASH'; + return ( + assetClass !== AssetClass.LIQUIDITY && + assetSubClass !== AssetSubClass.CASH + ); }) .map(({ valueInBaseCurrency }) => { return valueInBaseCurrency; }) - .reduce((a, b) => a + b, 0); + .reduce((a, b) => { + return a + b; + }, 0); - for (const [symbol, portfolioPosition] of Object.entries(holdings)) { + for (const [, portfolioPosition] of Object.entries(holdings)) { portfolioPosition.investment = portfolioPosition.investment / totalInvestment; portfolioPosition.valueInPercentage = @@ -185,11 +191,11 @@ export class PortfolioController { holdings[symbol] = { ...portfolioPosition, assetClass: - hasDetails || portfolioPosition.assetClass === 'CASH' + hasDetails || portfolioPosition.assetClass === AssetClass.LIQUIDITY ? portfolioPosition.assetClass : undefined, assetSubClass: - hasDetails || portfolioPosition.assetSubClass === 'CASH' + hasDetails || portfolioPosition.assetSubClass === AssetSubClass.CASH ? portfolioPosition.assetSubClass : undefined, countries: hasDetails ? portfolioPosition.countries : [], diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index cf7a47f52..4e56f844b 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -54,6 +54,7 @@ import { Account, Type as ActivityType, AssetClass, + AssetSubClass, DataSource, Order, Platform, @@ -376,7 +377,7 @@ export class PortfolioService { }) ?? false; const isFilteredByCash = filters?.some(({ id, type }) => { - return id === 'CASH' && type === 'ASSET_CLASS'; + return id === AssetClass.LIQUIDITY && type === 'ASSET_CLASS'; }); const isFilteredByClosedHoldings = @@ -391,8 +392,8 @@ export class PortfolioService { if ( filters?.length === 0 || (filters?.length === 1 && - filters[0].type === 'ASSET_CLASS' && - filters[0].id === 'CASH') + filters[0].id === AssetClass.LIQUIDITY && + filters[0].type === 'ASSET_CLASS') ) { filteredValueInBaseCurrency = filteredValueInBaseCurrency.plus( cashDetails.balanceInBaseCurrency @@ -1425,8 +1426,8 @@ export class PortfolioService { return { currency, allocationInPercentage: 0, - assetClass: AssetClass.CASH, - assetSubClass: AssetClass.CASH, + assetClass: AssetClass.LIQUIDITY, + assetSubClass: AssetSubClass.CASH, countries: [], dataSource: undefined, dateOfFirstActivity: undefined, diff --git a/apps/api/src/services/data-provider/coingecko/coingecko.service.ts b/apps/api/src/services/data-provider/coingecko/coingecko.service.ts index d17ba4b7e..d673dd7aa 100644 --- a/apps/api/src/services/data-provider/coingecko/coingecko.service.ts +++ b/apps/api/src/services/data-provider/coingecko/coingecko.service.ts @@ -59,7 +59,7 @@ export class CoinGeckoService implements DataProviderInterface { }): Promise> { const response: Partial = { symbol, - assetClass: AssetClass.CASH, + assetClass: AssetClass.LIQUIDITY, assetSubClass: AssetSubClass.CRYPTOCURRENCY, currency: DEFAULT_CURRENCY, dataSource: this.getName() @@ -243,7 +243,7 @@ export class CoinGeckoService implements DataProviderInterface { return { name, symbol, - assetClass: AssetClass.CASH, + assetClass: AssetClass.LIQUIDITY, assetSubClass: AssetSubClass.CRYPTOCURRENCY, currency: DEFAULT_CURRENCY, dataProviderInfo: this.getDataProviderInfo(), diff --git a/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.ts b/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.ts index c6edef0ca..35fa9604a 100644 --- a/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.ts +++ b/apps/api/src/services/data-provider/data-enhancer/yahoo-finance/yahoo-finance.service.ts @@ -266,7 +266,7 @@ export class YahooFinanceDataEnhancerService implements DataEnhancerInterface { switch (quoteType?.toLowerCase()) { case 'cryptocurrency': - assetClass = AssetClass.CASH; + assetClass = AssetClass.LIQUIDITY; assetSubClass = AssetSubClass.CRYPTOCURRENCY; break; case 'equity': diff --git a/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts b/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts index 99104a78d..1b6abd585 100644 --- a/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts +++ b/apps/api/src/services/data-provider/eod-historical-data/eod-historical-data.service.ts @@ -468,7 +468,7 @@ export class EodHistoricalDataService implements DataProviderInterface { assetSubClass = AssetSubClass.STOCK; break; case 'currency': - assetClass = AssetClass.CASH; + assetClass = AssetClass.LIQUIDITY; if (Exchange?.toLowerCase() === 'cc') { assetSubClass = AssetSubClass.CRYPTOCURRENCY; diff --git a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts index 0dba81d1e..6d3aed4d3 100644 --- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts +++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts @@ -348,8 +348,8 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { name: position.name }; - if (position.assetClass !== AssetClass.CASH) { - // Prepare analysis data by continents, countries and sectors except for cash + if (position.assetClass !== AssetClass.LIQUIDITY) { + // Prepare analysis data by continents, countries and sectors except for liquidity if (position.countries.length > 0) { this.markets.developedMarkets.value += diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index ef828af83..8c8b5e68f 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -1266,7 +1266,7 @@ apps/client/src/app/pages/landing/landing-page.html - 429 + 423 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -3036,7 +3036,7 @@ libs/ui/src/lib/i18n.ts - 69 + 70 @@ -3048,7 +3048,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -3252,7 +3252,7 @@ Immobilien libs/ui/src/lib/i18n.ts - 43 + 44 @@ -3260,7 +3260,7 @@ Anleihe libs/ui/src/lib/i18n.ts - 46 + 47 @@ -3268,7 +3268,7 @@ Kryptowährung libs/ui/src/lib/i18n.ts - 47 + 48 @@ -3276,7 +3276,7 @@ ETF libs/ui/src/lib/i18n.ts - 48 + 49 @@ -3284,7 +3284,7 @@ Investmentfonds libs/ui/src/lib/i18n.ts - 49 + 50 @@ -3292,7 +3292,7 @@ Edelmetall libs/ui/src/lib/i18n.ts - 50 + 51 @@ -3300,7 +3300,7 @@ Privates Beteiligungskapital libs/ui/src/lib/i18n.ts - 51 + 52 @@ -3308,7 +3308,7 @@ Aktie libs/ui/src/lib/i18n.ts - 52 + 53 @@ -3348,7 +3348,7 @@ Nordamerika libs/ui/src/lib/i18n.ts - 62 + 63 @@ -3356,7 +3356,7 @@ Afrika libs/ui/src/lib/i18n.ts - 59 + 60 @@ -3364,7 +3364,7 @@ Asien libs/ui/src/lib/i18n.ts - 60 + 61 @@ -3372,7 +3372,7 @@ Europa libs/ui/src/lib/i18n.ts - 61 + 62 @@ -3380,7 +3380,7 @@ Ozeanien libs/ui/src/lib/i18n.ts - 63 + 64 @@ -3388,7 +3388,7 @@ Südamerika libs/ui/src/lib/i18n.ts - 64 + 65 @@ -10076,7 +10076,7 @@ Sterne auf GitHub apps/client/src/app/pages/landing/landing-page.html - 93 + 87 apps/client/src/app/pages/open/open-page.html @@ -10088,7 +10088,7 @@ Downloads auf Docker Hub apps/client/src/app/pages/landing/landing-page.html - 111 + 105 apps/client/src/app/pages/open/open-page.html @@ -10188,7 +10188,7 @@ Verwalte dein Vermögen wie ein Profi apps/client/src/app/pages/landing/landing-page.html - 11 + 5 @@ -10196,7 +10196,7 @@ Ghostfolio ist ein Open Source Dashboard für deine persönlichen Finanzen mit Fokus auf Datenschutz. Analysiere deine Vermögensverteilung, ermittle dein Nettovermögen und treffe fundierte, datengestützte Investitionsentscheidungen. apps/client/src/app/pages/landing/landing-page.html - 15 + 9 @@ -10204,11 +10204,11 @@ Jetzt loslegen apps/client/src/app/pages/landing/landing-page.html - 47 + 41 apps/client/src/app/pages/landing/landing-page.html - 425 + 419 @@ -10216,7 +10216,7 @@ oder apps/client/src/app/pages/landing/landing-page.html - 52 + 46 @@ -10224,7 +10224,7 @@ Monatlich aktive Nutzer apps/client/src/app/pages/landing/landing-page.html - 75 + 69 @@ -10232,7 +10232,7 @@ Bekannt aus apps/client/src/app/pages/landing/landing-page.html - 119 + 113 @@ -10240,7 +10240,7 @@ Schützen Sie Ihr Vermögen. Optimieren Sie Ihre persönliche Anlagestrategie. apps/client/src/app/pages/landing/landing-page.html - 221 + 215 @@ -10248,7 +10248,7 @@ Ghostfolio ermöglicht es geschäftigen Leuten, den Überblick über Aktien, ETFs oder Kryptowährungen zu behalten, ohne überwacht zu werden. apps/client/src/app/pages/landing/landing-page.html - 225 + 219 @@ -10256,7 +10256,7 @@ 360° Ansicht apps/client/src/app/pages/landing/landing-page.html - 236 + 230 @@ -10264,7 +10264,7 @@ Web3 ready apps/client/src/app/pages/landing/landing-page.html - 247 + 241 @@ -10272,7 +10272,7 @@ Nutze Ghostfolio ganz anonym und behalte deine Finanzdaten. apps/client/src/app/pages/landing/landing-page.html - 249 + 243 @@ -10280,7 +10280,7 @@ Open Source apps/client/src/app/pages/landing/landing-page.html - 257 + 251 @@ -10288,7 +10288,7 @@ Profitiere von kontinuierlichen Verbesserungen durch eine aktive Community. apps/client/src/app/pages/landing/landing-page.html - 259 + 253 @@ -10296,7 +10296,7 @@ Warum Ghostfolio? apps/client/src/app/pages/landing/landing-page.html - 268 + 262 @@ -10304,7 +10304,7 @@ Ghostfolio ist für dich geeignet, wenn du... apps/client/src/app/pages/landing/landing-page.html - 269 + 263 @@ -10312,7 +10312,7 @@ Aktien, ETFs oder Kryptowährungen auf unterschiedlichen Plattformen handelst apps/client/src/app/pages/landing/landing-page.html - 276 + 270 @@ -10320,7 +10320,7 @@ eine Buy & Hold Strategie verfolgst apps/client/src/app/pages/landing/landing-page.html - 282 + 276 @@ -10328,7 +10328,7 @@ dich für die Zusammensetzung deines Portfolios interessierst apps/client/src/app/pages/landing/landing-page.html - 287 + 281 @@ -10336,7 +10336,7 @@ Privatsphäre und Datenhoheit wertschätzt apps/client/src/app/pages/landing/landing-page.html - 292 + 286 @@ -10344,7 +10344,7 @@ zum Frugalismus oder Minimalismus neigst apps/client/src/app/pages/landing/landing-page.html - 295 + 289 @@ -10352,7 +10352,7 @@ dich um die Diversifizierung deiner finanziellen Mittel kümmerst apps/client/src/app/pages/landing/landing-page.html - 299 + 293 @@ -10360,7 +10360,7 @@ Interesse an finanzieller Freiheit hast apps/client/src/app/pages/landing/landing-page.html - 303 + 297 @@ -10368,7 +10368,7 @@ Nein sagst zu Excel-Tabellen im Jahr apps/client/src/app/pages/landing/landing-page.html - 307 + 301 @@ -10376,7 +10376,7 @@ diese Liste bis zum Ende liest apps/client/src/app/pages/landing/landing-page.html - 310 + 304 @@ -10384,7 +10384,7 @@ Erfahre mehr über Ghostfolio apps/client/src/app/pages/landing/landing-page.html - 315 + 309 @@ -10392,7 +10392,7 @@ Was unsere Nutzer sagen apps/client/src/app/pages/landing/landing-page.html - 323 + 317 @@ -10400,7 +10400,7 @@ Nutzer aus aller Welt verwenden Ghostfolio Premium apps/client/src/app/pages/landing/landing-page.html - 355 + 349 @@ -10408,7 +10408,7 @@ Wie funktioniert Ghostfolio ? apps/client/src/app/pages/landing/landing-page.html - 367 + 361 @@ -10416,7 +10416,7 @@ Registriere dich anonym* apps/client/src/app/pages/landing/landing-page.html - 376 + 370 @@ -10424,7 +10424,7 @@ * Keine E-Mail-Adresse oder Kreditkarte erforderlich apps/client/src/app/pages/landing/landing-page.html - 378 + 372 @@ -10432,7 +10432,7 @@ Füge historische Transaktionen hinzu apps/client/src/app/pages/landing/landing-page.html - 389 + 383 @@ -10440,7 +10440,7 @@ Erhalte nützliche Erkenntnisse über die Zusammensetzung deines Portfolios apps/client/src/app/pages/landing/landing-page.html - 401 + 395 @@ -10448,7 +10448,7 @@ Bist du bereit? apps/client/src/app/pages/landing/landing-page.html - 413 + 407 @@ -10456,7 +10456,7 @@ Melde dich jetzt an oder probiere die Live Demo aus apps/client/src/app/pages/landing/landing-page.html - 414 + 408 @@ -10464,11 +10464,11 @@ Live Demo apps/client/src/app/pages/landing/landing-page.html - 55 + 49 apps/client/src/app/pages/landing/landing-page.html - 430 + 424 @@ -10476,7 +10476,7 @@ Verschaffe dir einen vollständigen Überblick deiner persönlichen Finanzen über mehrere Plattformen hinweg. apps/client/src/app/pages/landing/landing-page.html - 238 + 232 @@ -10484,7 +10484,7 @@ Beginne mit nur 3 Schritten apps/client/src/app/pages/landing/landing-page.html - 370 + 364 @@ -13199,14 +13199,6 @@ 127 - - New - Neu - - apps/client/src/app/pages/landing/landing-page.html - 7 - - Choose or drop a file here Wählen Sie eine Datei aus oder ziehen Sie sie hierhin @@ -13744,7 +13736,7 @@ Ups, der Cash-Bestand Transfer ist fehlgeschlagen. apps/client/src/app/pages/accounts/accounts-page.component.ts - 306 + 308 @@ -13768,7 +13760,7 @@ Extreme Angst libs/ui/src/lib/i18n.ts - 67 + 68 @@ -13776,7 +13768,7 @@ Extreme Gier libs/ui/src/lib/i18n.ts - 68 + 69 @@ -13784,7 +13776,7 @@ Neutral libs/ui/src/lib/i18n.ts - 71 + 72 @@ -15043,6 +15035,14 @@ 70 + + Liquidity + Liquidität + + libs/ui/src/lib/i18n.ts + 43 + + diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index 4e480b139..42e5e299a 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -1267,7 +1267,7 @@ apps/client/src/app/pages/landing/landing-page.html - 429 + 423 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -3034,7 +3034,7 @@ libs/ui/src/lib/i18n.ts - 69 + 70 @@ -3046,7 +3046,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -3250,7 +3250,7 @@ Propiedad inmobiliaria libs/ui/src/lib/i18n.ts - 43 + 44 @@ -3258,7 +3258,7 @@ Bono libs/ui/src/lib/i18n.ts - 46 + 47 @@ -3266,7 +3266,7 @@ Criptomoneda libs/ui/src/lib/i18n.ts - 47 + 48 @@ -3274,7 +3274,7 @@ ETF libs/ui/src/lib/i18n.ts - 48 + 49 @@ -3282,7 +3282,7 @@ Fondo de inversión libs/ui/src/lib/i18n.ts - 49 + 50 @@ -3290,7 +3290,7 @@ Metal precioso libs/ui/src/lib/i18n.ts - 50 + 51 @@ -3298,7 +3298,7 @@ Capital riesgo libs/ui/src/lib/i18n.ts - 51 + 52 @@ -3306,7 +3306,7 @@ Acción libs/ui/src/lib/i18n.ts - 52 + 53 @@ -3346,7 +3346,7 @@ América del Norte libs/ui/src/lib/i18n.ts - 62 + 63 @@ -3354,7 +3354,7 @@ África libs/ui/src/lib/i18n.ts - 59 + 60 @@ -3362,7 +3362,7 @@ Asia libs/ui/src/lib/i18n.ts - 60 + 61 @@ -3370,7 +3370,7 @@ Europa libs/ui/src/lib/i18n.ts - 61 + 62 @@ -3378,7 +3378,7 @@ Oceanía libs/ui/src/lib/i18n.ts - 63 + 64 @@ -3386,7 +3386,7 @@ América del Sur libs/ui/src/lib/i18n.ts - 64 + 65 @@ -10074,7 +10074,7 @@ Stars on GitHub apps/client/src/app/pages/landing/landing-page.html - 93 + 87 apps/client/src/app/pages/open/open-page.html @@ -10086,7 +10086,7 @@ Pulls on Docker Hub apps/client/src/app/pages/landing/landing-page.html - 111 + 105 apps/client/src/app/pages/open/open-page.html @@ -10186,7 +10186,7 @@ Manage your wealth like a boss apps/client/src/app/pages/landing/landing-page.html - 11 + 5 @@ -10194,7 +10194,7 @@ Ghostfolio is a privacy-first, open source dashboard for your personal finances. Break down your asset allocation, know your net worth and make solid, data-driven investment decisions. apps/client/src/app/pages/landing/landing-page.html - 15 + 9 @@ -10202,11 +10202,11 @@ Get Started apps/client/src/app/pages/landing/landing-page.html - 47 + 41 apps/client/src/app/pages/landing/landing-page.html - 425 + 419 @@ -10214,7 +10214,7 @@ or apps/client/src/app/pages/landing/landing-page.html - 52 + 46 @@ -10222,7 +10222,7 @@ Monthly Active Users apps/client/src/app/pages/landing/landing-page.html - 75 + 69 @@ -10230,7 +10230,7 @@ As seen in apps/client/src/app/pages/landing/landing-page.html - 119 + 113 @@ -10238,7 +10238,7 @@ Protect your assets. Refine your personal investment strategy. apps/client/src/app/pages/landing/landing-page.html - 221 + 215 @@ -10246,7 +10246,7 @@ Ghostfolio empowers busy people to keep track of stocks, ETFs or cryptocurrencies without being tracked. apps/client/src/app/pages/landing/landing-page.html - 225 + 219 @@ -10254,7 +10254,7 @@ 360° View apps/client/src/app/pages/landing/landing-page.html - 236 + 230 @@ -10262,7 +10262,7 @@ Web3 Ready apps/client/src/app/pages/landing/landing-page.html - 247 + 241 @@ -10270,7 +10270,7 @@ Use Ghostfolio anonymously and own your financial data. apps/client/src/app/pages/landing/landing-page.html - 249 + 243 @@ -10278,7 +10278,7 @@ Open Source apps/client/src/app/pages/landing/landing-page.html - 257 + 251 @@ -10286,7 +10286,7 @@ Benefit from continuous improvements through a strong community. apps/client/src/app/pages/landing/landing-page.html - 259 + 253 @@ -10294,7 +10294,7 @@ Why Ghostfolio? apps/client/src/app/pages/landing/landing-page.html - 268 + 262 @@ -10302,7 +10302,7 @@ Ghostfolio is for you if you are... apps/client/src/app/pages/landing/landing-page.html - 269 + 263 @@ -10310,7 +10310,7 @@ trading stocks, ETFs or cryptocurrencies on multiple platforms apps/client/src/app/pages/landing/landing-page.html - 276 + 270 @@ -10318,7 +10318,7 @@ pursuing a buy & hold strategy apps/client/src/app/pages/landing/landing-page.html - 282 + 276 @@ -10326,7 +10326,7 @@ interested in getting insights of your portfolio composition apps/client/src/app/pages/landing/landing-page.html - 287 + 281 @@ -10334,7 +10334,7 @@ valuing privacy and data ownership apps/client/src/app/pages/landing/landing-page.html - 292 + 286 @@ -10342,7 +10342,7 @@ into minimalism apps/client/src/app/pages/landing/landing-page.html - 295 + 289 @@ -10350,7 +10350,7 @@ caring about diversifying your financial resources apps/client/src/app/pages/landing/landing-page.html - 299 + 293 @@ -10358,7 +10358,7 @@ interested in financial independence apps/client/src/app/pages/landing/landing-page.html - 303 + 297 @@ -10366,7 +10366,7 @@ saying no to spreadsheets in apps/client/src/app/pages/landing/landing-page.html - 307 + 301 @@ -10374,7 +10374,7 @@ still reading this list apps/client/src/app/pages/landing/landing-page.html - 310 + 304 @@ -10382,7 +10382,7 @@ Learn more about Ghostfolio apps/client/src/app/pages/landing/landing-page.html - 315 + 309 @@ -10390,7 +10390,7 @@ What our users are saying apps/client/src/app/pages/landing/landing-page.html - 323 + 317 @@ -10398,7 +10398,7 @@ Members from around the globe are using Ghostfolio Premium apps/client/src/app/pages/landing/landing-page.html - 355 + 349 @@ -10406,7 +10406,7 @@ How does Ghostfolio work? apps/client/src/app/pages/landing/landing-page.html - 367 + 361 @@ -10414,7 +10414,7 @@ Sign up anonymously* apps/client/src/app/pages/landing/landing-page.html - 376 + 370 @@ -10422,7 +10422,7 @@ * no e-mail address nor credit card required apps/client/src/app/pages/landing/landing-page.html - 378 + 372 @@ -10430,7 +10430,7 @@ Add any of your historical transactions apps/client/src/app/pages/landing/landing-page.html - 389 + 383 @@ -10438,7 +10438,7 @@ Get valuable insights of your portfolio composition apps/client/src/app/pages/landing/landing-page.html - 401 + 395 @@ -10446,7 +10446,7 @@ Are you ready? apps/client/src/app/pages/landing/landing-page.html - 413 + 407 @@ -10454,7 +10454,7 @@ Join now or check out the example account apps/client/src/app/pages/landing/landing-page.html - 414 + 408 @@ -10462,11 +10462,11 @@ Live Demo apps/client/src/app/pages/landing/landing-page.html - 55 + 49 apps/client/src/app/pages/landing/landing-page.html - 430 + 424 @@ -10474,7 +10474,7 @@ Get the full picture of your personal finances across multiple platforms. apps/client/src/app/pages/landing/landing-page.html - 238 + 232 @@ -10482,7 +10482,7 @@ Get started in only 3 steps apps/client/src/app/pages/landing/landing-page.html - 370 + 364 @@ -13197,14 +13197,6 @@ 127 - - New - New - - apps/client/src/app/pages/landing/landing-page.html - 7 - - Choose or drop a file here Choose or drop a file here @@ -13742,7 +13734,7 @@ Oops, cash balance transfer has failed. apps/client/src/app/pages/accounts/accounts-page.component.ts - 306 + 308 @@ -13766,7 +13758,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 67 + 68 @@ -13774,7 +13766,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 68 + 69 @@ -13782,7 +13774,7 @@ Neutral libs/ui/src/lib/i18n.ts - 71 + 72 @@ -15041,6 +15033,14 @@ 70 + + Liquidity + Liquidity + + libs/ui/src/lib/i18n.ts + 43 + + diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index fbc210fce..3955e6dd8 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -1550,7 +1550,7 @@ libs/ui/src/lib/i18n.ts - 69 + 70 @@ -1562,7 +1562,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -1642,7 +1642,7 @@ apps/client/src/app/pages/landing/landing-page.html - 429 + 423 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -3445,7 +3445,7 @@ Immobilier libs/ui/src/lib/i18n.ts - 43 + 44 @@ -3453,7 +3453,7 @@ Obligation libs/ui/src/lib/i18n.ts - 46 + 47 @@ -3461,7 +3461,7 @@ Cryptomonnaie libs/ui/src/lib/i18n.ts - 47 + 48 @@ -3469,7 +3469,7 @@ ETF libs/ui/src/lib/i18n.ts - 48 + 49 @@ -3477,7 +3477,7 @@ SICAV libs/ui/src/lib/i18n.ts - 49 + 50 @@ -3485,7 +3485,7 @@ Métal Précieux libs/ui/src/lib/i18n.ts - 50 + 51 @@ -3493,7 +3493,7 @@ Capital Propre libs/ui/src/lib/i18n.ts - 51 + 52 @@ -3501,7 +3501,7 @@ Action libs/ui/src/lib/i18n.ts - 52 + 53 @@ -3509,7 +3509,7 @@ Afrique libs/ui/src/lib/i18n.ts - 59 + 60 @@ -3517,7 +3517,7 @@ Asie libs/ui/src/lib/i18n.ts - 60 + 61 @@ -3525,7 +3525,7 @@ Europe libs/ui/src/lib/i18n.ts - 61 + 62 @@ -3533,7 +3533,7 @@ Amérique du Nord libs/ui/src/lib/i18n.ts - 62 + 63 @@ -3541,7 +3541,7 @@ Océanie libs/ui/src/lib/i18n.ts - 63 + 64 @@ -3549,7 +3549,7 @@ Amérique du Sud libs/ui/src/lib/i18n.ts - 64 + 65 @@ -10073,7 +10073,7 @@ Stars on GitHub apps/client/src/app/pages/landing/landing-page.html - 93 + 87 apps/client/src/app/pages/open/open-page.html @@ -10085,7 +10085,7 @@ Pulls on Docker Hub apps/client/src/app/pages/landing/landing-page.html - 111 + 105 apps/client/src/app/pages/open/open-page.html @@ -10185,7 +10185,7 @@ Manage your wealth like a boss apps/client/src/app/pages/landing/landing-page.html - 11 + 5 @@ -10193,7 +10193,7 @@ Ghostfolio is a privacy-first, open source dashboard for your personal finances. Break down your asset allocation, know your net worth and make solid, data-driven investment decisions. apps/client/src/app/pages/landing/landing-page.html - 15 + 9 @@ -10201,11 +10201,11 @@ Get Started apps/client/src/app/pages/landing/landing-page.html - 47 + 41 apps/client/src/app/pages/landing/landing-page.html - 425 + 419 @@ -10213,7 +10213,7 @@ or apps/client/src/app/pages/landing/landing-page.html - 52 + 46 @@ -10221,7 +10221,7 @@ Monthly Active Users apps/client/src/app/pages/landing/landing-page.html - 75 + 69 @@ -10229,7 +10229,7 @@ As seen in apps/client/src/app/pages/landing/landing-page.html - 119 + 113 @@ -10237,7 +10237,7 @@ Protect your assets. Refine your personal investment strategy. apps/client/src/app/pages/landing/landing-page.html - 221 + 215 @@ -10245,7 +10245,7 @@ Ghostfolio empowers busy people to keep track of stocks, ETFs or cryptocurrencies without being tracked. apps/client/src/app/pages/landing/landing-page.html - 225 + 219 @@ -10253,7 +10253,7 @@ 360° View apps/client/src/app/pages/landing/landing-page.html - 236 + 230 @@ -10261,7 +10261,7 @@ Web3 Ready apps/client/src/app/pages/landing/landing-page.html - 247 + 241 @@ -10269,7 +10269,7 @@ Use Ghostfolio anonymously and own your financial data. apps/client/src/app/pages/landing/landing-page.html - 249 + 243 @@ -10277,7 +10277,7 @@ Open Source apps/client/src/app/pages/landing/landing-page.html - 257 + 251 @@ -10285,7 +10285,7 @@ Benefit from continuous improvements through a strong community. apps/client/src/app/pages/landing/landing-page.html - 259 + 253 @@ -10293,7 +10293,7 @@ Why Ghostfolio? apps/client/src/app/pages/landing/landing-page.html - 268 + 262 @@ -10301,7 +10301,7 @@ Ghostfolio is for you if you are... apps/client/src/app/pages/landing/landing-page.html - 269 + 263 @@ -10309,7 +10309,7 @@ trading stocks, ETFs or cryptocurrencies on multiple platforms apps/client/src/app/pages/landing/landing-page.html - 276 + 270 @@ -10317,7 +10317,7 @@ pursuing a buy & hold strategy apps/client/src/app/pages/landing/landing-page.html - 282 + 276 @@ -10325,7 +10325,7 @@ interested in getting insights of your portfolio composition apps/client/src/app/pages/landing/landing-page.html - 287 + 281 @@ -10333,7 +10333,7 @@ valuing privacy and data ownership apps/client/src/app/pages/landing/landing-page.html - 292 + 286 @@ -10341,7 +10341,7 @@ into minimalism apps/client/src/app/pages/landing/landing-page.html - 295 + 289 @@ -10349,7 +10349,7 @@ caring about diversifying your financial resources apps/client/src/app/pages/landing/landing-page.html - 299 + 293 @@ -10357,7 +10357,7 @@ interested in financial independence apps/client/src/app/pages/landing/landing-page.html - 303 + 297 @@ -10365,7 +10365,7 @@ saying no to spreadsheets in apps/client/src/app/pages/landing/landing-page.html - 307 + 301 @@ -10373,7 +10373,7 @@ still reading this list apps/client/src/app/pages/landing/landing-page.html - 310 + 304 @@ -10381,7 +10381,7 @@ Learn more about Ghostfolio apps/client/src/app/pages/landing/landing-page.html - 315 + 309 @@ -10389,7 +10389,7 @@ What our users are saying apps/client/src/app/pages/landing/landing-page.html - 323 + 317 @@ -10397,7 +10397,7 @@ Members from around the globe are using Ghostfolio Premium apps/client/src/app/pages/landing/landing-page.html - 355 + 349 @@ -10405,7 +10405,7 @@ How does Ghostfolio work? apps/client/src/app/pages/landing/landing-page.html - 367 + 361 @@ -10413,7 +10413,7 @@ Sign up anonymously* apps/client/src/app/pages/landing/landing-page.html - 376 + 370 @@ -10421,7 +10421,7 @@ * no e-mail address nor credit card required apps/client/src/app/pages/landing/landing-page.html - 378 + 372 @@ -10429,7 +10429,7 @@ Add any of your historical transactions apps/client/src/app/pages/landing/landing-page.html - 389 + 383 @@ -10437,7 +10437,7 @@ Get valuable insights of your portfolio composition apps/client/src/app/pages/landing/landing-page.html - 401 + 395 @@ -10445,7 +10445,7 @@ Are you ready? apps/client/src/app/pages/landing/landing-page.html - 413 + 407 @@ -10453,7 +10453,7 @@ Join now or check out the example account apps/client/src/app/pages/landing/landing-page.html - 414 + 408 @@ -10461,11 +10461,11 @@ Live Demo apps/client/src/app/pages/landing/landing-page.html - 55 + 49 apps/client/src/app/pages/landing/landing-page.html - 430 + 424 @@ -10473,7 +10473,7 @@ Get the full picture of your personal finances across multiple platforms. apps/client/src/app/pages/landing/landing-page.html - 238 + 232 @@ -10481,7 +10481,7 @@ Get started in only 3 steps apps/client/src/app/pages/landing/landing-page.html - 370 + 364 @@ -13196,14 +13196,6 @@ 127 - - New - New - - apps/client/src/app/pages/landing/landing-page.html - 7 - - Choose or drop a file here Choose or drop a file here @@ -13741,7 +13733,7 @@ Oops, cash balance transfer has failed. apps/client/src/app/pages/accounts/accounts-page.component.ts - 306 + 308 @@ -13765,7 +13757,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 67 + 68 @@ -13773,7 +13765,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 68 + 69 @@ -13781,7 +13773,7 @@ Neutral libs/ui/src/lib/i18n.ts - 71 + 72 @@ -15040,6 +15032,14 @@ 70 + + Liquidity + Liquidity + + libs/ui/src/lib/i18n.ts + 43 + + diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index 7075781c5..7aafd8d57 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -1267,7 +1267,7 @@ apps/client/src/app/pages/landing/landing-page.html - 429 + 423 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -3034,7 +3034,7 @@ libs/ui/src/lib/i18n.ts - 69 + 70 @@ -3046,7 +3046,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -3250,7 +3250,7 @@ Immobiliare libs/ui/src/lib/i18n.ts - 43 + 44 @@ -3258,7 +3258,7 @@ Obbligazioni libs/ui/src/lib/i18n.ts - 46 + 47 @@ -3266,7 +3266,7 @@ Criptovaluta libs/ui/src/lib/i18n.ts - 47 + 48 @@ -3274,7 +3274,7 @@ ETF libs/ui/src/lib/i18n.ts - 48 + 49 @@ -3282,7 +3282,7 @@ Fondo comune di investimento libs/ui/src/lib/i18n.ts - 49 + 50 @@ -3290,7 +3290,7 @@ Metalli preziosi libs/ui/src/lib/i18n.ts - 50 + 51 @@ -3298,7 +3298,7 @@ Azione ordinaria privata libs/ui/src/lib/i18n.ts - 51 + 52 @@ -3306,7 +3306,7 @@ Azione libs/ui/src/lib/i18n.ts - 52 + 53 @@ -3346,7 +3346,7 @@ Nord America libs/ui/src/lib/i18n.ts - 62 + 63 @@ -3354,7 +3354,7 @@ Africa libs/ui/src/lib/i18n.ts - 59 + 60 @@ -3362,7 +3362,7 @@ Asia libs/ui/src/lib/i18n.ts - 60 + 61 @@ -3370,7 +3370,7 @@ Europa libs/ui/src/lib/i18n.ts - 61 + 62 @@ -3378,7 +3378,7 @@ Oceania libs/ui/src/lib/i18n.ts - 63 + 64 @@ -3386,7 +3386,7 @@ Sud America libs/ui/src/lib/i18n.ts - 64 + 65 @@ -10074,7 +10074,7 @@ Stelle su GitHub apps/client/src/app/pages/landing/landing-page.html - 93 + 87 apps/client/src/app/pages/open/open-page.html @@ -10086,7 +10086,7 @@ Estrazioni su Docker Hub apps/client/src/app/pages/landing/landing-page.html - 111 + 105 apps/client/src/app/pages/open/open-page.html @@ -10186,7 +10186,7 @@ Gestisci la tua ricchezza come un capo apps/client/src/app/pages/landing/landing-page.html - 11 + 5 @@ -10194,7 +10194,7 @@ Ghostfolio è uno strumento open source e rispettoso della privacy per la gestione delle tue finanze personali. Analizza la tua allocazione degli asset, conosci il tuo patrimonio netto e prendi decisioni di investimento solide e basate sui dati. apps/client/src/app/pages/landing/landing-page.html - 15 + 9 @@ -10202,11 +10202,11 @@ Inizia apps/client/src/app/pages/landing/landing-page.html - 47 + 41 apps/client/src/app/pages/landing/landing-page.html - 425 + 419 @@ -10214,7 +10214,7 @@ o apps/client/src/app/pages/landing/landing-page.html - 52 + 46 @@ -10222,7 +10222,7 @@ Utenti attivi mensili apps/client/src/app/pages/landing/landing-page.html - 75 + 69 @@ -10230,7 +10230,7 @@ Come si vede su apps/client/src/app/pages/landing/landing-page.html - 119 + 113 @@ -10238,7 +10238,7 @@ Proteggi i tuoi asset. Perfeziona la tua strategia di investimento personale. apps/client/src/app/pages/landing/landing-page.html - 221 + 215 @@ -10246,7 +10246,7 @@ Ghostfolio permette alle persone impegnate di tenere traccia di azioni, ETF o criptovalute senza essere tracciate. apps/client/src/app/pages/landing/landing-page.html - 225 + 219 @@ -10254,7 +10254,7 @@ Vista a 360° apps/client/src/app/pages/landing/landing-page.html - 236 + 230 @@ -10262,7 +10262,7 @@ Pronto per il Web3 apps/client/src/app/pages/landing/landing-page.html - 247 + 241 @@ -10270,7 +10270,7 @@ Usa Ghostfolio in modo anonimo e possiedi i tuoi dati finanziari. apps/client/src/app/pages/landing/landing-page.html - 249 + 243 @@ -10278,7 +10278,7 @@ Open source apps/client/src/app/pages/landing/landing-page.html - 257 + 251 @@ -10286,7 +10286,7 @@ Beneficia dei continui miglioramenti grazie a una forte comunità. apps/client/src/app/pages/landing/landing-page.html - 259 + 253 @@ -10294,7 +10294,7 @@ Perché Ghostfolio? apps/client/src/app/pages/landing/landing-page.html - 268 + 262 @@ -10302,7 +10302,7 @@ Ghostfolio è per te se... apps/client/src/app/pages/landing/landing-page.html - 269 + 263 @@ -10310,7 +10310,7 @@ fai trading di azioni, ETF o criptovalute su più piattaforme apps/client/src/app/pages/landing/landing-page.html - 276 + 270 @@ -10318,7 +10318,7 @@ persegui una strategia buy & hold apps/client/src/app/pages/landing/landing-page.html - 282 + 276 @@ -10326,7 +10326,7 @@ sei interessato a conoscere la composizione del tuo portafoglio apps/client/src/app/pages/landing/landing-page.html - 287 + 281 @@ -10334,7 +10334,7 @@ valorizzi la privacy e la proprietà dei dati apps/client/src/app/pages/landing/landing-page.html - 292 + 286 @@ -10342,7 +10342,7 @@ sei per il minimalismo apps/client/src/app/pages/landing/landing-page.html - 295 + 289 @@ -10350,7 +10350,7 @@ ti interessa diversificare le tue risorse finanziarie apps/client/src/app/pages/landing/landing-page.html - 299 + 293 @@ -10358,7 +10358,7 @@ sei interessato all'indipendenza finanziaria apps/client/src/app/pages/landing/landing-page.html - 303 + 297 @@ -10366,7 +10366,7 @@ non vuoi utilizzare il foglio elettronico nel apps/client/src/app/pages/landing/landing-page.html - 307 + 301 @@ -10374,7 +10374,7 @@ stai ancora leggendo questo elenco apps/client/src/app/pages/landing/landing-page.html - 310 + 304 @@ -10382,7 +10382,7 @@ Ulteriori informazioni su Ghostfolio apps/client/src/app/pages/landing/landing-page.html - 315 + 309 @@ -10390,7 +10390,7 @@ Cosa dicono i nostri utenti apps/client/src/app/pages/landing/landing-page.html - 323 + 317 @@ -10398,7 +10398,7 @@ Membri da tutto il mondo utilizzano Ghostfolio Premium apps/client/src/app/pages/landing/landing-page.html - 355 + 349 @@ -10406,7 +10406,7 @@ Come funziona Ghostfolio? apps/client/src/app/pages/landing/landing-page.html - 367 + 361 @@ -10414,7 +10414,7 @@ Iscriviti in modo anonimo* apps/client/src/app/pages/landing/landing-page.html - 376 + 370 @@ -10422,7 +10422,7 @@ * non è richiesto alcun indirizzo email né la carta di credito apps/client/src/app/pages/landing/landing-page.html - 378 + 372 @@ -10430,7 +10430,7 @@ Aggiungi le tue transazioni storiche apps/client/src/app/pages/landing/landing-page.html - 389 + 383 @@ -10438,7 +10438,7 @@ Ottieni informazioni preziose sulla composizione del tuo portafoglio apps/client/src/app/pages/landing/landing-page.html - 401 + 395 @@ -10446,7 +10446,7 @@ Seipronto? apps/client/src/app/pages/landing/landing-page.html - 413 + 407 @@ -10454,7 +10454,7 @@ Iscriviti adesso o consulta l'account di esempio apps/client/src/app/pages/landing/landing-page.html - 414 + 408 @@ -10462,11 +10462,11 @@ Demo in tempo reale apps/client/src/app/pages/landing/landing-page.html - 55 + 49 apps/client/src/app/pages/landing/landing-page.html - 430 + 424 @@ -10474,7 +10474,7 @@ Ottieni un quadro completo delle tue finanze personali su più piattaforme. apps/client/src/app/pages/landing/landing-page.html - 238 + 232 @@ -10482,7 +10482,7 @@ Inizia in soli 3 passi apps/client/src/app/pages/landing/landing-page.html - 370 + 364 @@ -13197,14 +13197,6 @@ 127 - - New - Nuovo - - apps/client/src/app/pages/landing/landing-page.html - 7 - - Choose or drop a file here Choose or drop a file here @@ -13742,7 +13734,7 @@ Oops, cash balance transfer has failed. apps/client/src/app/pages/accounts/accounts-page.component.ts - 306 + 308 @@ -13766,7 +13758,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 67 + 68 @@ -13774,7 +13766,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 68 + 69 @@ -13782,7 +13774,7 @@ Neutral libs/ui/src/lib/i18n.ts - 71 + 72 @@ -15041,6 +15033,14 @@ 70 + + Liquidity + Liquidity + + libs/ui/src/lib/i18n.ts + 43 + + diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index b4b13691a..65a45962a 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -1266,7 +1266,7 @@ apps/client/src/app/pages/landing/landing-page.html - 429 + 423 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -3033,7 +3033,7 @@ libs/ui/src/lib/i18n.ts - 69 + 70 @@ -3045,7 +3045,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -3249,7 +3249,7 @@ Vastgoed libs/ui/src/lib/i18n.ts - 43 + 44 @@ -3257,7 +3257,7 @@ Obligatie libs/ui/src/lib/i18n.ts - 46 + 47 @@ -3265,7 +3265,7 @@ Cryptovaluta libs/ui/src/lib/i18n.ts - 47 + 48 @@ -3273,7 +3273,7 @@ ETF libs/ui/src/lib/i18n.ts - 48 + 49 @@ -3281,7 +3281,7 @@ Beleggingsfonds libs/ui/src/lib/i18n.ts - 49 + 50 @@ -3289,7 +3289,7 @@ Edelmetaal libs/ui/src/lib/i18n.ts - 50 + 51 @@ -3297,7 +3297,7 @@ Private equity libs/ui/src/lib/i18n.ts - 51 + 52 @@ -3305,7 +3305,7 @@ Aandeel libs/ui/src/lib/i18n.ts - 52 + 53 @@ -3345,7 +3345,7 @@ Noord-Amerika libs/ui/src/lib/i18n.ts - 62 + 63 @@ -3353,7 +3353,7 @@ Afrika libs/ui/src/lib/i18n.ts - 59 + 60 @@ -3361,7 +3361,7 @@ Azië libs/ui/src/lib/i18n.ts - 60 + 61 @@ -3369,7 +3369,7 @@ Europa libs/ui/src/lib/i18n.ts - 61 + 62 @@ -3377,7 +3377,7 @@ Oceanië libs/ui/src/lib/i18n.ts - 63 + 64 @@ -3385,7 +3385,7 @@ Zuid-Amerika libs/ui/src/lib/i18n.ts - 64 + 65 @@ -10073,7 +10073,7 @@ Sterren op GitHub apps/client/src/app/pages/landing/landing-page.html - 93 + 87 apps/client/src/app/pages/open/open-page.html @@ -10085,7 +10085,7 @@ Pulls op Docker Hub apps/client/src/app/pages/landing/landing-page.html - 111 + 105 apps/client/src/app/pages/open/open-page.html @@ -10185,7 +10185,7 @@ Beheer je vermogen als een baas apps/client/src/app/pages/landing/landing-page.html - 11 + 5 @@ -10193,7 +10193,7 @@ Ghostfolio is een privacygericht, open source dashboard voor je persoonlijke financiën. Analyseer je asset-allocatie, ken je nettowaarde en neem gefundeerde, datagedreven investeringsbeslissingen. apps/client/src/app/pages/landing/landing-page.html - 15 + 9 @@ -10201,11 +10201,11 @@ Aan de slag apps/client/src/app/pages/landing/landing-page.html - 47 + 41 apps/client/src/app/pages/landing/landing-page.html - 425 + 419 @@ -10213,7 +10213,7 @@ of apps/client/src/app/pages/landing/landing-page.html - 52 + 46 @@ -10221,7 +10221,7 @@ Maandelijkse actieve gebruikers apps/client/src/app/pages/landing/landing-page.html - 75 + 69 @@ -10229,7 +10229,7 @@ Zoals te zien in apps/client/src/app/pages/landing/landing-page.html - 119 + 113 @@ -10237,7 +10237,7 @@ Bescherm je financiële bezittingen. Verfijn je persoonlijke investeringsstrategie. apps/client/src/app/pages/landing/landing-page.html - 221 + 215 @@ -10245,7 +10245,7 @@ Ghostfolio stelt drukbezette mensen in staat om aandelen, ETF's of cryptocurrencies bij te houden zonder gevolgd te worden. apps/client/src/app/pages/landing/landing-page.html - 225 + 219 @@ -10253,7 +10253,7 @@ 360°-overzicht apps/client/src/app/pages/landing/landing-page.html - 236 + 230 @@ -10261,7 +10261,7 @@ Klaar voor Web3 apps/client/src/app/pages/landing/landing-page.html - 247 + 241 @@ -10269,7 +10269,7 @@ Gebruik Ghostfolio anoniem en bezit je financiële gegevens. apps/client/src/app/pages/landing/landing-page.html - 249 + 243 @@ -10277,7 +10277,7 @@ Open Source apps/client/src/app/pages/landing/landing-page.html - 257 + 251 @@ -10285,7 +10285,7 @@ Profiteer van voortdurende verbeteringen door een sterke gemeenschap. apps/client/src/app/pages/landing/landing-page.html - 259 + 253 @@ -10293,7 +10293,7 @@ Waarom Ghostfolio? apps/client/src/app/pages/landing/landing-page.html - 268 + 262 @@ -10301,7 +10301,7 @@ Ghostfolio is iets voor je als je... apps/client/src/app/pages/landing/landing-page.html - 269 + 263 @@ -10309,7 +10309,7 @@ handelt in aandelen, ETF's of cryptocurrencies op meerdere platforms apps/client/src/app/pages/landing/landing-page.html - 276 + 270 @@ -10317,7 +10317,7 @@ streeft naar een buy & hold strategie apps/client/src/app/pages/landing/landing-page.html - 282 + 276 @@ -10325,7 +10325,7 @@ geïnteresseerd bent in het krijgen van inzicht in je portefeuillesamenstelling apps/client/src/app/pages/landing/landing-page.html - 287 + 281 @@ -10333,7 +10333,7 @@ privacy en eigendom van gegevens waardeert apps/client/src/app/pages/landing/landing-page.html - 292 + 286 @@ -10341,7 +10341,7 @@ houdt van een minimalistisch ontwerp apps/client/src/app/pages/landing/landing-page.html - 295 + 289 @@ -10349,7 +10349,7 @@ zorgdraagt voor het diversifiëren van je financiële middelen apps/client/src/app/pages/landing/landing-page.html - 299 + 293 @@ -10357,7 +10357,7 @@ geïnteresseerd bent in financiële onafhankelijkheid apps/client/src/app/pages/landing/landing-page.html - 303 + 297 @@ -10365,7 +10365,7 @@ "nee" zegt tegen spreadsheets in apps/client/src/app/pages/landing/landing-page.html - 307 + 301 @@ -10373,7 +10373,7 @@ nog steeds deze lijst aan het lezen bent apps/client/src/app/pages/landing/landing-page.html - 310 + 304 @@ -10381,7 +10381,7 @@ Leer meer over Ghostfolio apps/client/src/app/pages/landing/landing-page.html - 315 + 309 @@ -10389,7 +10389,7 @@ Wat onze gebruikers zeggen apps/client/src/app/pages/landing/landing-page.html - 323 + 317 @@ -10397,7 +10397,7 @@ Leden van over de hele wereld gebruikenGhostfolio Premium apps/client/src/app/pages/landing/landing-page.html - 355 + 349 @@ -10405,7 +10405,7 @@ Hoe Ghostfolio werkt? apps/client/src/app/pages/landing/landing-page.html - 367 + 361 @@ -10413,7 +10413,7 @@ Anoniem aanmelden* apps/client/src/app/pages/landing/landing-page.html - 376 + 370 @@ -10421,7 +10421,7 @@ * geen e-mailadres of creditcard nodig apps/client/src/app/pages/landing/landing-page.html - 378 + 372 @@ -10429,7 +10429,7 @@ Voeg al je historische transacties toe apps/client/src/app/pages/landing/landing-page.html - 389 + 383 @@ -10437,7 +10437,7 @@ Krijg waardevolle inzichten in de samenstelling van je portefeuille apps/client/src/app/pages/landing/landing-page.html - 401 + 395 @@ -10445,7 +10445,7 @@ Ben je er klaar voor? apps/client/src/app/pages/landing/landing-page.html - 413 + 407 @@ -10453,7 +10453,7 @@ Nu lid worden of bekijk het voorbeeld account apps/client/src/app/pages/landing/landing-page.html - 414 + 408 @@ -10461,11 +10461,11 @@ Live Demo apps/client/src/app/pages/landing/landing-page.html - 55 + 49 apps/client/src/app/pages/landing/landing-page.html - 430 + 424 @@ -10473,7 +10473,7 @@ Krijg een volledig beeld van je persoonlijke financiën op meerdere platforms. apps/client/src/app/pages/landing/landing-page.html - 238 + 232 @@ -10481,7 +10481,7 @@ Aan de slag in slechts 3 stappen apps/client/src/app/pages/landing/landing-page.html - 370 + 364 @@ -13196,14 +13196,6 @@ 127 - - New - New - - apps/client/src/app/pages/landing/landing-page.html - 7 - - Choose or drop a file here Choose or drop a file here @@ -13741,7 +13733,7 @@ Oops, cash balance transfer has failed. apps/client/src/app/pages/accounts/accounts-page.component.ts - 306 + 308 @@ -13765,7 +13757,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 67 + 68 @@ -13773,7 +13765,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 68 + 69 @@ -13781,7 +13773,7 @@ Neutral libs/ui/src/lib/i18n.ts - 71 + 72 @@ -15040,6 +15032,14 @@ 70 + + Liquidity + Liquidity + + libs/ui/src/lib/i18n.ts + 43 + + diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf index 1d7e40388..966be7459 100644 --- a/apps/client/src/locales/messages.pl.xlf +++ b/apps/client/src/locales/messages.pl.xlf @@ -3026,7 +3026,7 @@ libs/ui/src/lib/i18n.ts - 69 + 70 @@ -3038,7 +3038,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -3202,7 +3202,7 @@ apps/client/src/app/pages/landing/landing-page.html - 429 + 423 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -4140,7 +4140,7 @@ Oops, cash balance transfer has failed. apps/client/src/app/pages/accounts/accounts-page.component.ts - 306 + 308 @@ -4523,20 +4523,12 @@ 14 - - New - New - - apps/client/src/app/pages/landing/landing-page.html - 7 - - Manage your wealth like a boss Manage your wealth like a boss apps/client/src/app/pages/landing/landing-page.html - 11 + 5 @@ -4544,7 +4536,7 @@ Ghostfolio is a privacy-first, open source dashboard for your personal finances. Break down your asset allocation, know your net worth and make solid, data-driven investment decisions. apps/client/src/app/pages/landing/landing-page.html - 15 + 9 @@ -4552,11 +4544,11 @@ Get Started apps/client/src/app/pages/landing/landing-page.html - 47 + 41 apps/client/src/app/pages/landing/landing-page.html - 425 + 419 @@ -4564,7 +4556,7 @@ or apps/client/src/app/pages/landing/landing-page.html - 52 + 46 @@ -4572,11 +4564,11 @@ Live Demo apps/client/src/app/pages/landing/landing-page.html - 55 + 49 apps/client/src/app/pages/landing/landing-page.html - 430 + 424 @@ -4584,7 +4576,7 @@ Monthly Active Users apps/client/src/app/pages/landing/landing-page.html - 75 + 69 @@ -4592,7 +4584,7 @@ Stars on GitHub apps/client/src/app/pages/landing/landing-page.html - 93 + 87 apps/client/src/app/pages/open/open-page.html @@ -4604,7 +4596,7 @@ Pulls on Docker Hub apps/client/src/app/pages/landing/landing-page.html - 111 + 105 apps/client/src/app/pages/open/open-page.html @@ -4616,7 +4608,7 @@ As seen in apps/client/src/app/pages/landing/landing-page.html - 119 + 113 @@ -4624,7 +4616,7 @@ Protect your assets. Refine your personal investment strategy. apps/client/src/app/pages/landing/landing-page.html - 221 + 215 @@ -4632,7 +4624,7 @@ Ghostfolio empowers busy people to keep track of stocks, ETFs or cryptocurrencies without being tracked. apps/client/src/app/pages/landing/landing-page.html - 225 + 219 @@ -4640,7 +4632,7 @@ 360° View apps/client/src/app/pages/landing/landing-page.html - 236 + 230 @@ -4648,7 +4640,7 @@ Get the full picture of your personal finances across multiple platforms. apps/client/src/app/pages/landing/landing-page.html - 238 + 232 @@ -4656,7 +4648,7 @@ Web3 Ready apps/client/src/app/pages/landing/landing-page.html - 247 + 241 @@ -4664,7 +4656,7 @@ Use Ghostfolio anonymously and own your financial data. apps/client/src/app/pages/landing/landing-page.html - 249 + 243 @@ -4672,7 +4664,7 @@ Open Source apps/client/src/app/pages/landing/landing-page.html - 257 + 251 @@ -4680,7 +4672,7 @@ Benefit from continuous improvements through a strong community. apps/client/src/app/pages/landing/landing-page.html - 259 + 253 @@ -4688,7 +4680,7 @@ Why Ghostfolio? apps/client/src/app/pages/landing/landing-page.html - 268 + 262 @@ -4696,7 +4688,7 @@ Ghostfolio is for you if you are... apps/client/src/app/pages/landing/landing-page.html - 269 + 263 @@ -4704,7 +4696,7 @@ trading stocks, ETFs or cryptocurrencies on multiple platforms apps/client/src/app/pages/landing/landing-page.html - 276 + 270 @@ -4712,7 +4704,7 @@ pursuing a buy & hold strategy apps/client/src/app/pages/landing/landing-page.html - 282 + 276 @@ -4720,7 +4712,7 @@ interested in getting insights of your portfolio composition apps/client/src/app/pages/landing/landing-page.html - 287 + 281 @@ -4728,7 +4720,7 @@ valuing privacy and data ownership apps/client/src/app/pages/landing/landing-page.html - 292 + 286 @@ -4736,7 +4728,7 @@ into minimalism apps/client/src/app/pages/landing/landing-page.html - 295 + 289 @@ -4744,7 +4736,7 @@ caring about diversifying your financial resources apps/client/src/app/pages/landing/landing-page.html - 299 + 293 @@ -4752,7 +4744,7 @@ interested in financial independence apps/client/src/app/pages/landing/landing-page.html - 303 + 297 @@ -4760,7 +4752,7 @@ saying no to spreadsheets in apps/client/src/app/pages/landing/landing-page.html - 307 + 301 @@ -4768,7 +4760,7 @@ still reading this list apps/client/src/app/pages/landing/landing-page.html - 310 + 304 @@ -4776,7 +4768,7 @@ Learn more about Ghostfolio apps/client/src/app/pages/landing/landing-page.html - 315 + 309 @@ -4784,7 +4776,7 @@ What our users are saying apps/client/src/app/pages/landing/landing-page.html - 323 + 317 @@ -4792,7 +4784,7 @@ Members from around the globe are using Ghostfolio Premium apps/client/src/app/pages/landing/landing-page.html - 355 + 349 @@ -4800,7 +4792,7 @@ How does Ghostfolio work? apps/client/src/app/pages/landing/landing-page.html - 367 + 361 @@ -4808,7 +4800,7 @@ Get started in only 3 steps apps/client/src/app/pages/landing/landing-page.html - 370 + 364 @@ -4816,7 +4808,7 @@ Sign up anonymously* apps/client/src/app/pages/landing/landing-page.html - 376 + 370 @@ -4824,7 +4816,7 @@ * no e-mail address nor credit card required apps/client/src/app/pages/landing/landing-page.html - 378 + 372 @@ -4832,7 +4824,7 @@ Add any of your historical transactions apps/client/src/app/pages/landing/landing-page.html - 389 + 383 @@ -4840,7 +4832,7 @@ Get valuable insights of your portfolio composition apps/client/src/app/pages/landing/landing-page.html - 401 + 395 @@ -4848,7 +4840,7 @@ Are you ready? apps/client/src/app/pages/landing/landing-page.html - 413 + 407 @@ -4856,7 +4848,7 @@ Join now or check out the example account apps/client/src/app/pages/landing/landing-page.html - 414 + 408 @@ -13636,7 +13628,7 @@ Real Estate libs/ui/src/lib/i18n.ts - 43 + 44 @@ -13644,7 +13636,7 @@ Bond libs/ui/src/lib/i18n.ts - 46 + 47 @@ -13652,7 +13644,7 @@ Cryptocurrency libs/ui/src/lib/i18n.ts - 47 + 48 @@ -13660,7 +13652,7 @@ ETF libs/ui/src/lib/i18n.ts - 48 + 49 @@ -13668,7 +13660,7 @@ Mutual Fund libs/ui/src/lib/i18n.ts - 49 + 50 @@ -13676,7 +13668,7 @@ Precious Metal libs/ui/src/lib/i18n.ts - 50 + 51 @@ -13684,7 +13676,7 @@ Private Equity libs/ui/src/lib/i18n.ts - 51 + 52 @@ -13692,7 +13684,7 @@ Stock libs/ui/src/lib/i18n.ts - 52 + 53 @@ -13700,7 +13692,7 @@ Africa libs/ui/src/lib/i18n.ts - 59 + 60 @@ -13708,7 +13700,7 @@ Asia libs/ui/src/lib/i18n.ts - 60 + 61 @@ -13716,7 +13708,7 @@ Europe libs/ui/src/lib/i18n.ts - 61 + 62 @@ -13724,7 +13716,7 @@ North America libs/ui/src/lib/i18n.ts - 62 + 63 @@ -13732,7 +13724,7 @@ Oceania libs/ui/src/lib/i18n.ts - 63 + 64 @@ -13740,7 +13732,7 @@ South America libs/ui/src/lib/i18n.ts - 64 + 65 @@ -13748,7 +13740,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 67 + 68 @@ -13756,7 +13748,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 68 + 69 @@ -13764,7 +13756,7 @@ Neutral libs/ui/src/lib/i18n.ts - 71 + 72 @@ -15043,6 +15035,14 @@ 70 + + Liquidity + Liquidity + + libs/ui/src/lib/i18n.ts + 43 + + diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index d7156d354..ad6aedb7a 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -1418,7 +1418,7 @@ libs/ui/src/lib/i18n.ts - 69 + 70 @@ -1430,7 +1430,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -1518,7 +1518,7 @@ apps/client/src/app/pages/landing/landing-page.html - 429 + 423 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -3293,7 +3293,7 @@ Imobiliário libs/ui/src/lib/i18n.ts - 43 + 44 @@ -3301,7 +3301,7 @@ Obrigação libs/ui/src/lib/i18n.ts - 46 + 47 @@ -3309,7 +3309,7 @@ Criptomoedas libs/ui/src/lib/i18n.ts - 47 + 48 @@ -3317,7 +3317,7 @@ ETF libs/ui/src/lib/i18n.ts - 48 + 49 @@ -3325,7 +3325,7 @@ Fundo de Investimento libs/ui/src/lib/i18n.ts - 49 + 50 @@ -3333,7 +3333,7 @@ Metal Precioso libs/ui/src/lib/i18n.ts - 50 + 51 @@ -3341,7 +3341,7 @@ Private Equity libs/ui/src/lib/i18n.ts - 51 + 52 @@ -3349,7 +3349,7 @@ Ação libs/ui/src/lib/i18n.ts - 52 + 53 @@ -3357,7 +3357,7 @@ África libs/ui/src/lib/i18n.ts - 59 + 60 @@ -3365,7 +3365,7 @@ Ásia libs/ui/src/lib/i18n.ts - 60 + 61 @@ -3373,7 +3373,7 @@ Europa libs/ui/src/lib/i18n.ts - 61 + 62 @@ -3381,7 +3381,7 @@ América do Norte libs/ui/src/lib/i18n.ts - 62 + 63 @@ -3389,7 +3389,7 @@ Oceânia libs/ui/src/lib/i18n.ts - 63 + 64 @@ -3397,7 +3397,7 @@ América do Sul libs/ui/src/lib/i18n.ts - 64 + 65 @@ -10073,7 +10073,7 @@ Stars on GitHub apps/client/src/app/pages/landing/landing-page.html - 93 + 87 apps/client/src/app/pages/open/open-page.html @@ -10085,7 +10085,7 @@ Pulls on Docker Hub apps/client/src/app/pages/landing/landing-page.html - 111 + 105 apps/client/src/app/pages/open/open-page.html @@ -10185,7 +10185,7 @@ Manage your wealth like a boss apps/client/src/app/pages/landing/landing-page.html - 11 + 5 @@ -10193,7 +10193,7 @@ Ghostfolio is a privacy-first, open source dashboard for your personal finances. Break down your asset allocation, know your net worth and make solid, data-driven investment decisions. apps/client/src/app/pages/landing/landing-page.html - 15 + 9 @@ -10201,11 +10201,11 @@ Get Started apps/client/src/app/pages/landing/landing-page.html - 47 + 41 apps/client/src/app/pages/landing/landing-page.html - 425 + 419 @@ -10213,7 +10213,7 @@ or apps/client/src/app/pages/landing/landing-page.html - 52 + 46 @@ -10221,7 +10221,7 @@ Monthly Active Users apps/client/src/app/pages/landing/landing-page.html - 75 + 69 @@ -10229,7 +10229,7 @@ As seen in apps/client/src/app/pages/landing/landing-page.html - 119 + 113 @@ -10237,7 +10237,7 @@ Protect your assets. Refine your personal investment strategy. apps/client/src/app/pages/landing/landing-page.html - 221 + 215 @@ -10245,7 +10245,7 @@ Ghostfolio empowers busy people to keep track of stocks, ETFs or cryptocurrencies without being tracked. apps/client/src/app/pages/landing/landing-page.html - 225 + 219 @@ -10253,7 +10253,7 @@ 360° View apps/client/src/app/pages/landing/landing-page.html - 236 + 230 @@ -10261,7 +10261,7 @@ Web3 Ready apps/client/src/app/pages/landing/landing-page.html - 247 + 241 @@ -10269,7 +10269,7 @@ Use Ghostfolio anonymously and own your financial data. apps/client/src/app/pages/landing/landing-page.html - 249 + 243 @@ -10277,7 +10277,7 @@ Open Source apps/client/src/app/pages/landing/landing-page.html - 257 + 251 @@ -10285,7 +10285,7 @@ Benefit from continuous improvements through a strong community. apps/client/src/app/pages/landing/landing-page.html - 259 + 253 @@ -10293,7 +10293,7 @@ Why Ghostfolio? apps/client/src/app/pages/landing/landing-page.html - 268 + 262 @@ -10301,7 +10301,7 @@ Ghostfolio is for you if you are... apps/client/src/app/pages/landing/landing-page.html - 269 + 263 @@ -10309,7 +10309,7 @@ trading stocks, ETFs or cryptocurrencies on multiple platforms apps/client/src/app/pages/landing/landing-page.html - 276 + 270 @@ -10317,7 +10317,7 @@ pursuing a buy & hold strategy apps/client/src/app/pages/landing/landing-page.html - 282 + 276 @@ -10325,7 +10325,7 @@ interested in getting insights of your portfolio composition apps/client/src/app/pages/landing/landing-page.html - 287 + 281 @@ -10333,7 +10333,7 @@ valuing privacy and data ownership apps/client/src/app/pages/landing/landing-page.html - 292 + 286 @@ -10341,7 +10341,7 @@ into minimalism apps/client/src/app/pages/landing/landing-page.html - 295 + 289 @@ -10349,7 +10349,7 @@ caring about diversifying your financial resources apps/client/src/app/pages/landing/landing-page.html - 299 + 293 @@ -10357,7 +10357,7 @@ interested in financial independence apps/client/src/app/pages/landing/landing-page.html - 303 + 297 @@ -10365,7 +10365,7 @@ saying no to spreadsheets in apps/client/src/app/pages/landing/landing-page.html - 307 + 301 @@ -10373,7 +10373,7 @@ still reading this list apps/client/src/app/pages/landing/landing-page.html - 310 + 304 @@ -10381,7 +10381,7 @@ Learn more about Ghostfolio apps/client/src/app/pages/landing/landing-page.html - 315 + 309 @@ -10389,7 +10389,7 @@ What our users are saying apps/client/src/app/pages/landing/landing-page.html - 323 + 317 @@ -10397,7 +10397,7 @@ Members from around the globe are using Ghostfolio Premium apps/client/src/app/pages/landing/landing-page.html - 355 + 349 @@ -10405,7 +10405,7 @@ How does Ghostfolio work? apps/client/src/app/pages/landing/landing-page.html - 367 + 361 @@ -10413,7 +10413,7 @@ Sign up anonymously* apps/client/src/app/pages/landing/landing-page.html - 376 + 370 @@ -10421,7 +10421,7 @@ * no e-mail address nor credit card required apps/client/src/app/pages/landing/landing-page.html - 378 + 372 @@ -10429,7 +10429,7 @@ Add any of your historical transactions apps/client/src/app/pages/landing/landing-page.html - 389 + 383 @@ -10437,7 +10437,7 @@ Get valuable insights of your portfolio composition apps/client/src/app/pages/landing/landing-page.html - 401 + 395 @@ -10445,7 +10445,7 @@ Are you ready? apps/client/src/app/pages/landing/landing-page.html - 413 + 407 @@ -10453,7 +10453,7 @@ Join now or check out the example account apps/client/src/app/pages/landing/landing-page.html - 414 + 408 @@ -10461,11 +10461,11 @@ Live Demo apps/client/src/app/pages/landing/landing-page.html - 55 + 49 apps/client/src/app/pages/landing/landing-page.html - 430 + 424 @@ -10473,7 +10473,7 @@ Get the full picture of your personal finances across multiple platforms. apps/client/src/app/pages/landing/landing-page.html - 238 + 232 @@ -10481,7 +10481,7 @@ Get started in only 3 steps apps/client/src/app/pages/landing/landing-page.html - 370 + 364 @@ -13196,14 +13196,6 @@ 127 - - New - New - - apps/client/src/app/pages/landing/landing-page.html - 7 - - Choose or drop a file here Choose or drop a file here @@ -13741,7 +13733,7 @@ Oops, cash balance transfer has failed. apps/client/src/app/pages/accounts/accounts-page.component.ts - 306 + 308 @@ -13765,7 +13757,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 67 + 68 @@ -13773,7 +13765,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 68 + 69 @@ -13781,7 +13773,7 @@ Neutral libs/ui/src/lib/i18n.ts - 71 + 72 @@ -15040,6 +15032,14 @@ 70 + + Liquidity + Liquidity + + libs/ui/src/lib/i18n.ts + 43 + + diff --git a/apps/client/src/locales/messages.tr.xlf b/apps/client/src/locales/messages.tr.xlf index 51dd75275..af530e9d5 100644 --- a/apps/client/src/locales/messages.tr.xlf +++ b/apps/client/src/locales/messages.tr.xlf @@ -2878,7 +2878,7 @@ libs/ui/src/lib/i18n.ts - 69 + 70 @@ -2890,7 +2890,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -3054,7 +3054,7 @@ apps/client/src/app/pages/landing/landing-page.html - 429 + 423 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -4065,7 +4065,7 @@ Servetinizi bir patron gibi yönetin apps/client/src/app/pages/landing/landing-page.html - 11 + 5 @@ -4073,7 +4073,7 @@ Ghostfolio, mali durumunuz için gizlilik odaklı, açık kaynaklı bir kontrol panelidi. Varlık dağılımınızı analiz edin, net değerinizi öğrenin ve sağlam, veriye dayalı yatırım kararları alın. apps/client/src/app/pages/landing/landing-page.html - 15 + 9 @@ -4081,11 +4081,11 @@ Başla apps/client/src/app/pages/landing/landing-page.html - 47 + 41 apps/client/src/app/pages/landing/landing-page.html - 425 + 419 @@ -4093,7 +4093,7 @@ veya apps/client/src/app/pages/landing/landing-page.html - 52 + 46 @@ -4101,11 +4101,11 @@ Canlı Deneme apps/client/src/app/pages/landing/landing-page.html - 55 + 49 apps/client/src/app/pages/landing/landing-page.html - 430 + 424 @@ -4113,7 +4113,7 @@ Aylık Aktif Kullanıcılar apps/client/src/app/pages/landing/landing-page.html - 75 + 69 @@ -4121,7 +4121,7 @@ GitHub'daki Beğeniler apps/client/src/app/pages/landing/landing-page.html - 93 + 87 apps/client/src/app/pages/open/open-page.html @@ -4133,7 +4133,7 @@ Docker Hub'ta Çekmeler apps/client/src/app/pages/landing/landing-page.html - 111 + 105 apps/client/src/app/pages/open/open-page.html @@ -4145,7 +4145,7 @@ Şurada görüldüğü gibi apps/client/src/app/pages/landing/landing-page.html - 119 + 113 @@ -4153,7 +4153,7 @@ varlıklarınızı koruyun. Kişisel yatırım stratejinizi geliştirin. apps/client/src/app/pages/landing/landing-page.html - 221 + 215 @@ -4161,7 +4161,7 @@ Ghostfolio, takip edilmeden hisse senetleri, ETF'ler veya kripto paraları izlemek isteyen yoğun insanlara güç verir. apps/client/src/app/pages/landing/landing-page.html - 225 + 219 @@ -4169,7 +4169,7 @@ 360° Görünüm apps/client/src/app/pages/landing/landing-page.html - 236 + 230 @@ -4177,7 +4177,7 @@ Kişisel finansınızın tam resmini birden fazla platformda edinin. apps/client/src/app/pages/landing/landing-page.html - 238 + 232 @@ -4185,7 +4185,7 @@ Web3 Hazır apps/client/src/app/pages/landing/landing-page.html - 247 + 241 @@ -4193,7 +4193,7 @@ Ghostfolio'yu anonim olarak kullanın ve finansal verilerinize sahip çıkın. apps/client/src/app/pages/landing/landing-page.html - 249 + 243 @@ -4201,7 +4201,7 @@ Açık Kaynak apps/client/src/app/pages/landing/landing-page.html - 257 + 251 @@ -4209,7 +4209,7 @@ Güçlü bir topluluk aracılığıyla sürekli gelişmelerden faydalanın. apps/client/src/app/pages/landing/landing-page.html - 259 + 253 @@ -4217,7 +4217,7 @@ Why Ghostfolio? apps/client/src/app/pages/landing/landing-page.html - 268 + 262 @@ -4225,7 +4225,7 @@ Ghostfolio tam size göre, apps/client/src/app/pages/landing/landing-page.html - 269 + 263 @@ -4233,7 +4233,7 @@ Birden fazla platformda hisse senedi, ETF veya kripto para ticareti yapıyorsanız, apps/client/src/app/pages/landing/landing-page.html - 276 + 270 @@ -4241,7 +4241,7 @@ al ve tut stratejisi izliyorsanız, apps/client/src/app/pages/landing/landing-page.html - 282 + 276 @@ -4249,7 +4249,7 @@ Portföy bileşimine dair içgörüleri edinmek istiyorsanız, apps/client/src/app/pages/landing/landing-page.html - 287 + 281 @@ -4257,7 +4257,7 @@ Gizliliğe ve verilerinize sahip çıkmayı önemsiyorsanız apps/client/src/app/pages/landing/landing-page.html - 292 + 286 @@ -4265,7 +4265,7 @@ minimalizme ilgi duyuyorsanız apps/client/src/app/pages/landing/landing-page.html - 295 + 289 @@ -4273,7 +4273,7 @@ finansal kaynaklarınızı çeşitlendirmeye önem veriyorsanız apps/client/src/app/pages/landing/landing-page.html - 299 + 293 @@ -4281,7 +4281,7 @@ finansal özgürlük peşindeyseniz apps/client/src/app/pages/landing/landing-page.html - 303 + 297 @@ -4289,7 +4289,7 @@ elektronik tablo uygulamalarına hayır diyorsanız apps/client/src/app/pages/landing/landing-page.html - 307 + 301 @@ -4297,7 +4297,7 @@ bu listeyi hala okuyorsanız apps/client/src/app/pages/landing/landing-page.html - 310 + 304 @@ -4305,7 +4305,7 @@ Ghostfolio hakkında daha fazla bilgi edinin apps/client/src/app/pages/landing/landing-page.html - 315 + 309 @@ -4313,7 +4313,7 @@ What our users are saying apps/client/src/app/pages/landing/landing-page.html - 323 + 317 @@ -4321,7 +4321,7 @@ Members from around the globe are using Ghostfolio Premium apps/client/src/app/pages/landing/landing-page.html - 355 + 349 @@ -4329,7 +4329,7 @@ How does Ghostfolio work? apps/client/src/app/pages/landing/landing-page.html - 367 + 361 @@ -4337,7 +4337,7 @@ Sadece 3 adımda başlayın apps/client/src/app/pages/landing/landing-page.html - 370 + 364 @@ -4345,7 +4345,7 @@ Anonim olarak kaydolun* apps/client/src/app/pages/landing/landing-page.html - 376 + 370 @@ -4353,7 +4353,7 @@ * e-posta adresi veya kredi kartı gerekmez apps/client/src/app/pages/landing/landing-page.html - 378 + 372 @@ -4361,7 +4361,7 @@ Herhangi bir geçmiş işleminizi ekleyin apps/client/src/app/pages/landing/landing-page.html - 389 + 383 @@ -4369,7 +4369,7 @@ Portföy bileşiminizle ilgili değerli bilgiler edinin apps/client/src/app/pages/landing/landing-page.html - 401 + 395 @@ -4377,7 +4377,7 @@ Are you ready? apps/client/src/app/pages/landing/landing-page.html - 413 + 407 @@ -4385,7 +4385,7 @@ Join now or check out the example account apps/client/src/app/pages/landing/landing-page.html - 414 + 408 @@ -13041,7 +13041,7 @@ Real Estate libs/ui/src/lib/i18n.ts - 43 + 44 @@ -13049,7 +13049,7 @@ Bond libs/ui/src/lib/i18n.ts - 46 + 47 @@ -13057,7 +13057,7 @@ Cryptocurrency libs/ui/src/lib/i18n.ts - 47 + 48 @@ -13065,7 +13065,7 @@ ETF libs/ui/src/lib/i18n.ts - 48 + 49 @@ -13073,7 +13073,7 @@ Mutual Fund libs/ui/src/lib/i18n.ts - 49 + 50 @@ -13081,7 +13081,7 @@ Precious Metal libs/ui/src/lib/i18n.ts - 50 + 51 @@ -13089,7 +13089,7 @@ Private Equity libs/ui/src/lib/i18n.ts - 51 + 52 @@ -13097,7 +13097,7 @@ Stock libs/ui/src/lib/i18n.ts - 52 + 53 @@ -13105,7 +13105,7 @@ Africa libs/ui/src/lib/i18n.ts - 59 + 60 @@ -13113,7 +13113,7 @@ Asia libs/ui/src/lib/i18n.ts - 60 + 61 @@ -13121,7 +13121,7 @@ Europe libs/ui/src/lib/i18n.ts - 61 + 62 @@ -13129,7 +13129,7 @@ North America libs/ui/src/lib/i18n.ts - 62 + 63 @@ -13137,7 +13137,7 @@ Oceania libs/ui/src/lib/i18n.ts - 63 + 64 @@ -13145,7 +13145,7 @@ South America libs/ui/src/lib/i18n.ts - 64 + 65 @@ -13184,14 +13184,6 @@ 312 - - New - New - - apps/client/src/app/pages/landing/landing-page.html - 7 - - (Last 24 hours) (Last 24 hours) @@ -13741,7 +13733,7 @@ Oops, cash balance transfer has failed. apps/client/src/app/pages/accounts/accounts-page.component.ts - 306 + 308 @@ -13765,7 +13757,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 67 + 68 @@ -13773,7 +13765,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 68 + 69 @@ -13781,7 +13773,7 @@ Neutral libs/ui/src/lib/i18n.ts - 71 + 72 @@ -15040,6 +15032,14 @@ 70 + + Liquidity + Liquidity + + libs/ui/src/lib/i18n.ts + 43 + + diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index b39de189e..d12c7f060 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -2893,7 +2893,7 @@ libs/ui/src/lib/i18n.ts - 69 + 70 @@ -2904,7 +2904,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -3050,7 +3050,7 @@ apps/client/src/app/pages/landing/landing-page.html - 429 + 423 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -3892,7 +3892,7 @@ Oops, cash balance transfer has failed. apps/client/src/app/pages/accounts/accounts-page.component.ts - 306 + 308 @@ -4237,68 +4237,61 @@ 14 - - New - - apps/client/src/app/pages/landing/landing-page.html - 7 - - Manage your wealth like a boss apps/client/src/app/pages/landing/landing-page.html - 11 + 5 Ghostfolio is a privacy-first, open source dashboard for your personal finances. Break down your asset allocation, know your net worth and make solid, data-driven investment decisions. apps/client/src/app/pages/landing/landing-page.html - 15 + 9 Get Started apps/client/src/app/pages/landing/landing-page.html - 47 + 41 apps/client/src/app/pages/landing/landing-page.html - 425 + 419 or apps/client/src/app/pages/landing/landing-page.html - 52 + 46 Live Demo apps/client/src/app/pages/landing/landing-page.html - 55 + 49 apps/client/src/app/pages/landing/landing-page.html - 430 + 424 Monthly Active Users apps/client/src/app/pages/landing/landing-page.html - 75 + 69 Stars on GitHub apps/client/src/app/pages/landing/landing-page.html - 93 + 87 apps/client/src/app/pages/open/open-page.html @@ -4309,7 +4302,7 @@ Pulls on Docker Hub apps/client/src/app/pages/landing/landing-page.html - 111 + 105 apps/client/src/app/pages/open/open-page.html @@ -4320,217 +4313,217 @@ As seen in apps/client/src/app/pages/landing/landing-page.html - 119 + 113 Protect your assets. Refine your personal investment strategy. apps/client/src/app/pages/landing/landing-page.html - 221 + 215 Ghostfolio empowers busy people to keep track of stocks, ETFs or cryptocurrencies without being tracked. apps/client/src/app/pages/landing/landing-page.html - 225 + 219 360° View apps/client/src/app/pages/landing/landing-page.html - 236 + 230 Get the full picture of your personal finances across multiple platforms. apps/client/src/app/pages/landing/landing-page.html - 238 + 232 Web3 Ready apps/client/src/app/pages/landing/landing-page.html - 247 + 241 Use Ghostfolio anonymously and own your financial data. apps/client/src/app/pages/landing/landing-page.html - 249 + 243 Open Source apps/client/src/app/pages/landing/landing-page.html - 257 + 251 Benefit from continuous improvements through a strong community. apps/client/src/app/pages/landing/landing-page.html - 259 + 253 Why Ghostfolio? apps/client/src/app/pages/landing/landing-page.html - 268 + 262 Ghostfolio is for you if you are... apps/client/src/app/pages/landing/landing-page.html - 269 + 263 trading stocks, ETFs or cryptocurrencies on multiple platforms apps/client/src/app/pages/landing/landing-page.html - 276 + 270 pursuing a buy & hold strategy apps/client/src/app/pages/landing/landing-page.html - 282 + 276 interested in getting insights of your portfolio composition apps/client/src/app/pages/landing/landing-page.html - 287 + 281 valuing privacy and data ownership apps/client/src/app/pages/landing/landing-page.html - 292 + 286 into minimalism apps/client/src/app/pages/landing/landing-page.html - 295 + 289 caring about diversifying your financial resources apps/client/src/app/pages/landing/landing-page.html - 299 + 293 interested in financial independence apps/client/src/app/pages/landing/landing-page.html - 303 + 297 saying no to spreadsheets in apps/client/src/app/pages/landing/landing-page.html - 307 + 301 still reading this list apps/client/src/app/pages/landing/landing-page.html - 310 + 304 Learn more about Ghostfolio apps/client/src/app/pages/landing/landing-page.html - 315 + 309 What our users are saying apps/client/src/app/pages/landing/landing-page.html - 323 + 317 Members from around the globe are using Ghostfolio Premium apps/client/src/app/pages/landing/landing-page.html - 355 + 349 How does Ghostfolio work? apps/client/src/app/pages/landing/landing-page.html - 367 + 361 Get started in only 3 steps apps/client/src/app/pages/landing/landing-page.html - 370 + 364 Sign up anonymously* apps/client/src/app/pages/landing/landing-page.html - 376 + 370 * no e-mail address nor credit card required apps/client/src/app/pages/landing/landing-page.html - 378 + 372 Add any of your historical transactions apps/client/src/app/pages/landing/landing-page.html - 389 + 383 Get valuable insights of your portfolio composition apps/client/src/app/pages/landing/landing-page.html - 401 + 395 Are you ready? apps/client/src/app/pages/landing/landing-page.html - 413 + 407 Join now or check out the example account apps/client/src/app/pages/landing/landing-page.html - 414 + 408 @@ -13918,119 +13911,119 @@ Real Estate libs/ui/src/lib/i18n.ts - 43 + 44 Bond libs/ui/src/lib/i18n.ts - 46 + 47 Cryptocurrency libs/ui/src/lib/i18n.ts - 47 + 48 ETF libs/ui/src/lib/i18n.ts - 48 + 49 Mutual Fund libs/ui/src/lib/i18n.ts - 49 + 50 Precious Metal libs/ui/src/lib/i18n.ts - 50 + 51 Private Equity libs/ui/src/lib/i18n.ts - 51 + 52 Stock libs/ui/src/lib/i18n.ts - 52 + 53 Africa libs/ui/src/lib/i18n.ts - 59 + 60 Asia libs/ui/src/lib/i18n.ts - 60 + 61 Europe libs/ui/src/lib/i18n.ts - 61 + 62 North America libs/ui/src/lib/i18n.ts - 62 + 63 Oceania libs/ui/src/lib/i18n.ts - 63 + 64 South America libs/ui/src/lib/i18n.ts - 64 + 65 Extreme Fear libs/ui/src/lib/i18n.ts - 67 + 68 Extreme Greed libs/ui/src/lib/i18n.ts - 68 + 69 Neutral libs/ui/src/lib/i18n.ts - 71 + 72 @@ -14412,6 +14405,13 @@ 63 + + Liquidity + + libs/ui/src/lib/i18n.ts + 43 + + diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index 8b44e31b6..36f0ef1bc 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -3043,7 +3043,7 @@ libs/ui/src/lib/i18n.ts - 69 + 70 @@ -3055,7 +3055,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -3219,7 +3219,7 @@ apps/client/src/app/pages/landing/landing-page.html - 429 + 423 apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -4157,7 +4157,7 @@ 糟糕,现金余额转账失败。 apps/client/src/app/pages/accounts/accounts-page.component.ts - 306 + 308 @@ -4540,20 +4540,12 @@ 14 - - New - 新的 - - apps/client/src/app/pages/landing/landing-page.html - 7 - - Manage your wealth like a boss 像老板一样管理您的财富 apps/client/src/app/pages/landing/landing-page.html - 11 + 5 @@ -4561,7 +4553,7 @@ Ghostfolio 是一个隐私优先、开源的个人财务仪表板。分解您的资产配置,了解您的净资产并做出可靠的、数据驱动的投资决策。 apps/client/src/app/pages/landing/landing-page.html - 15 + 9 @@ -4569,11 +4561,11 @@ 开始使用 apps/client/src/app/pages/landing/landing-page.html - 47 + 41 apps/client/src/app/pages/landing/landing-page.html - 425 + 419 @@ -4581,7 +4573,7 @@ apps/client/src/app/pages/landing/landing-page.html - 52 + 46 @@ -4589,11 +4581,11 @@ 现场演示 apps/client/src/app/pages/landing/landing-page.html - 55 + 49 apps/client/src/app/pages/landing/landing-page.html - 430 + 424 @@ -4601,7 +4593,7 @@ 每月活跃用户数 apps/client/src/app/pages/landing/landing-page.html - 75 + 69 @@ -4609,7 +4601,7 @@ GitHub 上的星星 apps/client/src/app/pages/landing/landing-page.html - 93 + 87 apps/client/src/app/pages/open/open-page.html @@ -4621,7 +4613,7 @@ 拉动 Docker Hub apps/client/src/app/pages/landing/landing-page.html - 111 + 105 apps/client/src/app/pages/open/open-page.html @@ -4633,7 +4625,7 @@ 如图所示 apps/client/src/app/pages/landing/landing-page.html - 119 + 113 @@ -4641,7 +4633,7 @@ 保护你的资产。完善你的个人投资策略 apps/client/src/app/pages/landing/landing-page.html - 221 + 215 @@ -4649,7 +4641,7 @@ Ghostfolio 使忙碌的人们能够在不被追踪的情况下跟踪股票、ETF 或加密货币。 apps/client/src/app/pages/landing/landing-page.html - 225 + 219 @@ -4657,7 +4649,7 @@ 360° 视角 apps/client/src/app/pages/landing/landing-page.html - 236 + 230 @@ -4665,7 +4657,7 @@ 跨多个平台全面了解您的个人财务状况。 apps/client/src/app/pages/landing/landing-page.html - 238 + 232 @@ -4673,7 +4665,7 @@ Web3 就绪 apps/client/src/app/pages/landing/landing-page.html - 247 + 241 @@ -4681,7 +4673,7 @@ 匿名使用 Ghostfolio 并拥有您的财务数据。 apps/client/src/app/pages/landing/landing-page.html - 249 + 243 @@ -4689,7 +4681,7 @@ 开源 apps/client/src/app/pages/landing/landing-page.html - 257 + 251 @@ -4697,7 +4689,7 @@ 通过强大的社区不断改进,从中受益。 apps/client/src/app/pages/landing/landing-page.html - 259 + 253 @@ -4705,7 +4697,7 @@ 为什么使用Ghostfolio apps/client/src/app/pages/landing/landing-page.html - 268 + 262 @@ -4713,7 +4705,7 @@ 如果您符合以下条件,那么 Ghostfolio 适合您... apps/client/src/app/pages/landing/landing-page.html - 269 + 263 @@ -4721,7 +4713,7 @@ 在多个平台上交易股票、ETF 或加密货币 apps/client/src/app/pages/landing/landing-page.html - 276 + 270 @@ -4729,7 +4721,7 @@ 采取买入并持有策略 apps/client/src/app/pages/landing/landing-page.html - 282 + 276 @@ -4737,7 +4729,7 @@ 有兴趣深入了解您的投资组合构成 apps/client/src/app/pages/landing/landing-page.html - 287 + 281 @@ -4745,7 +4737,7 @@ 重视隐私和数据所有权 apps/client/src/app/pages/landing/landing-page.html - 292 + 286 @@ -4753,7 +4745,7 @@ 进入极简主义 apps/client/src/app/pages/landing/landing-page.html - 295 + 289 @@ -4761,7 +4753,7 @@ 关心您的财务资源多元化 apps/client/src/app/pages/landing/landing-page.html - 299 + 293 @@ -4769,7 +4761,7 @@ 对财务独立感兴趣 apps/client/src/app/pages/landing/landing-page.html - 303 + 297 @@ -4777,7 +4769,7 @@ 对电子表格说不 apps/client/src/app/pages/landing/landing-page.html - 307 + 301 @@ -4785,7 +4777,7 @@ 仍在阅读此列表 apps/client/src/app/pages/landing/landing-page.html - 310 + 304 @@ -4793,7 +4785,7 @@ 了解有关 Ghostfolio 的更多信息 apps/client/src/app/pages/landing/landing-page.html - 315 + 309 @@ -4801,7 +4793,7 @@ 我们的什么用户正在说 apps/client/src/app/pages/landing/landing-page.html - 323 + 317 @@ -4809,7 +4801,7 @@ 来自世界各地的会员正在使用Ghostfolio 高级版 apps/client/src/app/pages/landing/landing-page.html - 355 + 349 @@ -4817,7 +4809,7 @@ 如何幽灵作品集工作? apps/client/src/app/pages/landing/landing-page.html - 367 + 361 @@ -4825,7 +4817,7 @@ 只需 3 步即可开始 apps/client/src/app/pages/landing/landing-page.html - 370 + 364 @@ -4833,7 +4825,7 @@ 匿名注册* apps/client/src/app/pages/landing/landing-page.html - 376 + 370 @@ -4841,7 +4833,7 @@ * 无需电子邮件地址或信用卡 apps/client/src/app/pages/landing/landing-page.html - 378 + 372 @@ -4849,7 +4841,7 @@ 添加您的任何历史交易 apps/client/src/app/pages/landing/landing-page.html - 389 + 383 @@ -4857,7 +4849,7 @@ 获取有关您的投资组合构成的宝贵见解 apps/client/src/app/pages/landing/landing-page.html - 401 + 395 @@ -4865,7 +4857,7 @@ 准备好? apps/client/src/app/pages/landing/landing-page.html - 413 + 407 @@ -4873,7 +4865,7 @@ 立即加入或查看示例帐户 apps/client/src/app/pages/landing/landing-page.html - 414 + 408 @@ -14485,7 +14477,7 @@ 房地产 libs/ui/src/lib/i18n.ts - 43 + 44 @@ -14493,7 +14485,7 @@ 纽带 libs/ui/src/lib/i18n.ts - 46 + 47 @@ -14501,7 +14493,7 @@ 加密货币 libs/ui/src/lib/i18n.ts - 47 + 48 @@ -14509,7 +14501,7 @@ 交易所交易基金 libs/ui/src/lib/i18n.ts - 48 + 49 @@ -14517,7 +14509,7 @@ 共同基金 libs/ui/src/lib/i18n.ts - 49 + 50 @@ -14525,7 +14517,7 @@ 贵金属 libs/ui/src/lib/i18n.ts - 50 + 51 @@ -14533,7 +14525,7 @@ 私人产权 libs/ui/src/lib/i18n.ts - 51 + 52 @@ -14541,7 +14533,7 @@ 库存 libs/ui/src/lib/i18n.ts - 52 + 53 @@ -14549,7 +14541,7 @@ 非洲 libs/ui/src/lib/i18n.ts - 59 + 60 @@ -14557,7 +14549,7 @@ 亚洲 libs/ui/src/lib/i18n.ts - 60 + 61 @@ -14565,7 +14557,7 @@ 欧洲 libs/ui/src/lib/i18n.ts - 61 + 62 @@ -14573,7 +14565,7 @@ 北美 libs/ui/src/lib/i18n.ts - 62 + 63 @@ -14581,7 +14573,7 @@ 大洋洲 libs/ui/src/lib/i18n.ts - 63 + 64 @@ -14589,7 +14581,7 @@ 南美洲 libs/ui/src/lib/i18n.ts - 64 + 65 @@ -14597,7 +14589,7 @@ 极度恐惧 libs/ui/src/lib/i18n.ts - 67 + 68 @@ -14605,7 +14597,7 @@ 极度贪婪 libs/ui/src/lib/i18n.ts - 68 + 69 @@ -14613,7 +14605,7 @@ 中性的 libs/ui/src/lib/i18n.ts - 71 + 72 @@ -15044,6 +15036,14 @@ 70 + + Liquidity + Liquidity + + libs/ui/src/lib/i18n.ts + 43 + + diff --git a/libs/common/src/lib/config.ts b/libs/common/src/lib/config.ts index 5e1366ce2..9e438c0f5 100644 --- a/libs/common/src/lib/config.ts +++ b/libs/common/src/lib/config.ts @@ -4,7 +4,6 @@ import ms from 'ms'; export const ghostfolioPrefix = 'GF'; export const ghostfolioScraperApiSymbolPrefix = `_${ghostfolioPrefix}_`; -export const ghostfolioCashSymbol = `${ghostfolioScraperApiSymbolPrefix}CASH`; export const ghostfolioFearAndGreedIndexDataSource = DataSource.RAPID_API; export const ghostfolioFearAndGreedIndexSymbol = `${ghostfolioScraperApiSymbolPrefix}FEAR_AND_GREED_INDEX`; diff --git a/libs/common/src/lib/interfaces/portfolio-position.interface.ts b/libs/common/src/lib/interfaces/portfolio-position.interface.ts index 2e5772ef7..a47a1ebc7 100644 --- a/libs/common/src/lib/interfaces/portfolio-position.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-position.interface.ts @@ -8,7 +8,7 @@ export interface PortfolioPosition { allocationInPercentage: number; assetClass?: AssetClass; assetClassLabel?: string; - assetSubClass?: AssetSubClass | 'CASH'; + assetSubClass?: AssetSubClass; assetSubClassLabel?: string; countries: Country[]; currency: string; diff --git a/libs/ui/src/lib/holdings-table/holdings-table.component.ts b/libs/ui/src/lib/holdings-table/holdings-table.component.ts index 9d568abf7..93ac5b6fe 100644 --- a/libs/ui/src/lib/holdings-table/holdings-table.component.ts +++ b/libs/ui/src/lib/holdings-table/holdings-table.component.ts @@ -23,7 +23,7 @@ import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator'; import { MatSort, MatSortModule } from '@angular/material/sort'; import { MatTableDataSource, MatTableModule } from '@angular/material/table'; import { Router, RouterModule } from '@angular/router'; -import { AssetClass } from '@prisma/client'; +import { AssetClass, AssetSubClass } from '@prisma/client'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { Subject, Subscription } from 'rxjs'; @@ -66,7 +66,7 @@ export class GfHoldingsTableComponent implements OnChanges, OnDestroy, OnInit { public dataSource: MatTableDataSource = new MatTableDataSource(); public displayedColumns = []; - public ignoreAssetSubClasses = [AssetClass.CASH]; + public ignoreAssetSubClasses = [AssetSubClass.CASH]; public isLoading = true; public routeQueryParams: Subscription; diff --git a/libs/ui/src/lib/i18n.ts b/libs/ui/src/lib/i18n.ts index 9687f461c..e1266baa3 100644 --- a/libs/ui/src/lib/i18n.ts +++ b/libs/ui/src/lib/i18n.ts @@ -40,6 +40,7 @@ const locales = { COMMODITY: $localize`Commodity`, EQUITY: $localize`Equity`, FIXED_INCOME: $localize`Fixed Income`, + LIQUIDITY: $localize`Liquidity`, REAL_ESTATE: $localize`Real Estate`, // AssetSubClass (enum) diff --git a/prisma/migrations/20240422181320_added_liquidity_to_asset_class/migration.sql b/prisma/migrations/20240422181320_added_liquidity_to_asset_class/migration.sql new file mode 100644 index 000000000..685cae6bb --- /dev/null +++ b/prisma/migrations/20240422181320_added_liquidity_to_asset_class/migration.sql @@ -0,0 +1,2 @@ +-- AlterEnum +ALTER TYPE "AssetClass" ADD VALUE 'LIQUIDITY'; diff --git a/prisma/migrations/20240422181356_added_cash_to_asset_sub_class/migration.sql b/prisma/migrations/20240422181356_added_cash_to_asset_sub_class/migration.sql new file mode 100644 index 000000000..7aeaf5abd --- /dev/null +++ b/prisma/migrations/20240422181356_added_cash_to_asset_sub_class/migration.sql @@ -0,0 +1,2 @@ +-- AlterEnum +ALTER TYPE "AssetSubClass" ADD VALUE 'CASH'; diff --git a/prisma/migrations/20240422181835_changed_cash_to_liquidity_in_asset_sub_class/migration.sql b/prisma/migrations/20240422181835_changed_cash_to_liquidity_in_asset_sub_class/migration.sql new file mode 100644 index 000000000..f0b260a09 --- /dev/null +++ b/prisma/migrations/20240422181835_changed_cash_to_liquidity_in_asset_sub_class/migration.sql @@ -0,0 +1,7 @@ +UPDATE "SymbolProfile" +SET "assetClass" = 'LIQUIDITY' +WHERE "assetClass" = 'CASH'; + +UPDATE "SymbolProfileOverrides" +SET "assetClass" = 'LIQUIDITY' +WHERE "assetClass" = 'CASH'; diff --git a/prisma/migrations/20240422182643_removed_cash_from_asset_class/migration.sql b/prisma/migrations/20240422182643_removed_cash_from_asset_class/migration.sql new file mode 100644 index 000000000..6a08aee78 --- /dev/null +++ b/prisma/migrations/20240422182643_removed_cash_from_asset_class/migration.sql @@ -0,0 +1,9 @@ +-- AlterEnum +BEGIN; +CREATE TYPE "AssetClass_new" AS ENUM ('COMMODITY', 'EQUITY', 'FIXED_INCOME', 'LIQUIDITY', 'REAL_ESTATE'); +ALTER TABLE "SymbolProfile" ALTER COLUMN "assetClass" TYPE "AssetClass_new" USING ("assetClass"::text::"AssetClass_new"); +ALTER TABLE "SymbolProfileOverrides" ALTER COLUMN "assetClass" TYPE "AssetClass_new" USING ("assetClass"::text::"AssetClass_new"); +ALTER TYPE "AssetClass" RENAME TO "AssetClass_old"; +ALTER TYPE "AssetClass_new" RENAME TO "AssetClass"; +DROP TYPE "AssetClass_old"; +COMMIT; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index af7ad1845..43052de11 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -248,15 +248,16 @@ enum AccessPermission { } enum AssetClass { - CASH COMMODITY EQUITY FIXED_INCOME + LIQUIDITY REAL_ESTATE } enum AssetSubClass { BOND + CASH COMMODITY CRYPTOCURRENCY ETF From 0fdeef795325fa7591bb56d202e4579eef5fa4cc Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 23 Apr 2024 18:58:43 +0200 Subject: [PATCH 157/203] Release 2.76.0 (#3322) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f01e52cd..4dbf29776 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.76.0 - 2024-04-23 ### Changed diff --git a/package.json b/package.json index da5c207ae..4834f5abb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.75.1", + "version": "2.76.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 37871fbabcbaab5b9172343a0804dacf479ac68e Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Wed, 24 Apr 2024 20:20:09 +0200 Subject: [PATCH 158/203] Feature/upgrade prisma to version 5.13.0 (#3323) * Upgrade prisma to version 5.13.0 * Update changelog --- CHANGELOG.md | 6 ++++ package.json | 4 +-- yarn.lock | 90 ++++++++++++++++++++++++++-------------------------- 3 files changed, 53 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4dbf29776..ff93075b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- Upgraded `prisma` from version `5.12.1` to `5.13.0` + ## 2.76.0 - 2024-04-23 ### Changed diff --git a/package.json b/package.json index 4834f5abb..8b036f588 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "@nestjs/platform-express": "10.1.3", "@nestjs/schedule": "3.0.2", "@nestjs/serve-static": "4.0.0", - "@prisma/client": "5.12.1", + "@prisma/client": "5.13.0", "@simplewebauthn/browser": "9.0.1", "@simplewebauthn/server": "9.0.3", "@stripe/stripe-js": "1.47.0", @@ -125,7 +125,7 @@ "passport": "0.6.0", "passport-google-oauth20": "2.0.0", "passport-jwt": "4.0.0", - "prisma": "5.12.1", + "prisma": "5.13.0", "reflect-metadata": "0.1.13", "rxjs": "7.5.6", "stripe": "11.12.0", diff --git a/yarn.lock b/yarn.lock index 2eda4d271..5dd3bcd98 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5442,46 +5442,46 @@ resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.25.tgz#f077fdc0b5d0078d30893396ff4827a13f99e817" integrity sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ== -"@prisma/client@5.12.1": - version "5.12.1" - resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.12.1.tgz#c26a674fea76754b3a9e8b90a11e617f90212f76" - integrity sha512-6/JnizEdlSBxDIdiLbrBdMW5NqDxOmhXAJaNXiPpgzAPr/nLZResT6MMpbOHLo5yAbQ1Vv5UU8PTPRzb0WIxdA== - -"@prisma/debug@5.12.1": - version "5.12.1" - resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-5.12.1.tgz#007c8ad2e466d565bcd0671b8846c27f8700c722" - integrity sha512-kd/wNsR0klrv79o1ITsbWxYyh4QWuBidvxsXSParPsYSu0ircUmNk3q4ojsgNc3/81b0ozg76iastOG43tbf8A== - -"@prisma/engines-version@5.12.0-21.473ed3124229e22d881cb7addf559799debae1ab": - version "5.12.0-21.473ed3124229e22d881cb7addf559799debae1ab" - resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.12.0-21.473ed3124229e22d881cb7addf559799debae1ab.tgz#c78d099a3fe86d446db7442e64e56987e39e7f32" - integrity sha512-6yvO8s80Tym61aB4QNtYZfWVmE3pwqe807jEtzm8C5VDe7nw8O1FGX3TXUaXmWV0fQTIAfRbeL2Gwrndabp/0g== - -"@prisma/engines@5.12.1": - version "5.12.1" - resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.12.1.tgz#a50649427d627a9af962a188a84c65d61c6e2b3f" - integrity sha512-HQDdglLw2bZR/TXD2Y+YfDMvi5Q8H+acbswqOsWyq9pPjBLYJ6gzM+ptlTU/AV6tl0XSZLU1/7F4qaWa8bqpJA== - dependencies: - "@prisma/debug" "5.12.1" - "@prisma/engines-version" "5.12.0-21.473ed3124229e22d881cb7addf559799debae1ab" - "@prisma/fetch-engine" "5.12.1" - "@prisma/get-platform" "5.12.1" - -"@prisma/fetch-engine@5.12.1": - version "5.12.1" - resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-5.12.1.tgz#c38e9fa17fdc535b4c83cbb7645569ad0a511fa9" - integrity sha512-qSs3KcX1HKcea1A+hlJVK/ljj0PNIUHDxAayGMvgJBqmaN32P9tCidlKz1EGv6WoRFICYnk3Dd/YFLBwnFIozA== - dependencies: - "@prisma/debug" "5.12.1" - "@prisma/engines-version" "5.12.0-21.473ed3124229e22d881cb7addf559799debae1ab" - "@prisma/get-platform" "5.12.1" - -"@prisma/get-platform@5.12.1": - version "5.12.1" - resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-5.12.1.tgz#33f427f6d744dee62a9e06858889691d78b50804" - integrity sha512-pgIR+pSvhYHiUcqXVEZS31NrFOTENC9yFUdEAcx7cdQBoZPmHVjtjN4Ss6NzVDMYPrKJJ51U14EhEoeuBlMioQ== - dependencies: - "@prisma/debug" "5.12.1" +"@prisma/client@5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.13.0.tgz#b9f1d0983d714e982675201d8222a9ecb4bdad4a" + integrity sha512-uYdfpPncbZ/syJyiYBwGZS8Gt1PTNoErNYMuqHDa2r30rNSFtgTA/LXsSk55R7pdRTMi5pHkeP9B14K6nHmwkg== + +"@prisma/debug@5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-5.13.0.tgz#d88b0f6fafa0c216e20e284ed9fc30f1cbe45786" + integrity sha512-699iqlEvzyCj9ETrXhs8o8wQc/eVW+FigSsHpiskSFydhjVuwTJEfj/nIYqTaWFYuxiWQRfm3r01meuW97SZaQ== + +"@prisma/engines-version@5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b": + version "5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b" + resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b.tgz#a72a4fb83ba1fd01ad45f795aa55168f60d34723" + integrity sha512-AyUuhahTINGn8auyqYdmxsN+qn0mw3eg+uhkp8zwknXYIqoT3bChG4RqNY/nfDkPvzWAPBa9mrDyBeOnWSgO6A== + +"@prisma/engines@5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.13.0.tgz#8994ebf7b4e35aee7746a8465ec22738379bcab6" + integrity sha512-hIFLm4H1boj6CBZx55P4xKby9jgDTeDG0Jj3iXtwaaHmlD5JmiDkZhh8+DYWkTGchu+rRF36AVROLnk0oaqhHw== + dependencies: + "@prisma/debug" "5.13.0" + "@prisma/engines-version" "5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b" + "@prisma/fetch-engine" "5.13.0" + "@prisma/get-platform" "5.13.0" + +"@prisma/fetch-engine@5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-5.13.0.tgz#9b6945c7b38bb59e840f8905b20ea7a3d059ca55" + integrity sha512-Yh4W+t6YKyqgcSEB3odBXt7QyVSm0OQlBSldQF2SNXtmOgMX8D7PF/fvH6E6qBCpjB/yeJLy/FfwfFijoHI6sA== + dependencies: + "@prisma/debug" "5.13.0" + "@prisma/engines-version" "5.13.0-23.b9a39a7ee606c28e3455d0fd60e78c3ba82b1a2b" + "@prisma/get-platform" "5.13.0" + +"@prisma/get-platform@5.13.0": + version "5.13.0" + resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-5.13.0.tgz#99ef909a52b9d79b64d72d2d3d8210c4892b6572" + integrity sha512-B/WrQwYTzwr7qCLifQzYOmQhZcFmIFhR81xC45gweInSUn2hTEbfKUPd2keAog+y5WI5xLAFNJ3wkXplvSVkSw== + dependencies: + "@prisma/debug" "5.13.0" "@radix-ui/number@1.0.1": version "1.0.1" @@ -16706,12 +16706,12 @@ pretty-hrtime@^1.0.3: resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A== -prisma@5.12.1: - version "5.12.1" - resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.12.1.tgz#db4596253bb066afc9f08744642f200a398d8d51" - integrity sha512-SkMnb6wyIxTv9ACqiHBI2u9gD6y98qXRoCoLEnZsF6yee5Qg828G+ARrESN+lQHdw4maSZFFSBPPDpvSiVTo0Q== +prisma@5.13.0: + version "5.13.0" + resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.13.0.tgz#1f06e20ccfb6038ad68869e6eacd3b346f9d0851" + integrity sha512-kGtcJaElNRAdAGsCNykFSZ7dBKpL14Cbs+VaQ8cECxQlRPDjBlMHNFYeYt0SKovAVy2Y65JXQwB3A5+zIQwnTg== dependencies: - "@prisma/engines" "5.12.1" + "@prisma/engines" "5.13.0" prismjs@^1.28.0: version "1.29.0" From 990028316e2cb80a910f59cf46cf24c487e00597 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Wed, 24 Apr 2024 20:20:56 +0200 Subject: [PATCH 159/203] Refactor form controls to form getter (#3325) --- .../asset-profile-dialog.component.ts | 29 +- .../asset-profile-dialog.html | 6 +- .../create-asset-profile-dialog.component.ts | 8 +- ...reate-or-update-access-dialog.component.ts | 6 +- .../create-or-update-access-dialog.html | 2 +- ...eate-or-update-account-dialog.component.ts | 18 +- .../create-or-update-account-dialog.html | 2 +- .../transfer-balance-dialog.component.ts | 6 +- ...ate-or-update-activity-dialog.component.ts | 314 +++++++++--------- .../create-or-update-activity-dialog.html | 69 ++-- .../import-activities-dialog.component.ts | 10 +- .../import-activities-dialog.html | 2 +- .../fire-calculator.component.html | 5 +- 13 files changed, 226 insertions(+), 251 deletions(-) diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts index 2f0c2546b..d6403540a 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts @@ -265,22 +265,22 @@ export class AssetProfileDialog implements OnDestroy, OnInit { let symbolMapping = {}; try { - countries = JSON.parse(this.assetProfileForm.controls['countries'].value); + countries = JSON.parse(this.assetProfileForm.get('countries').value); } catch {} try { scraperConfiguration = JSON.parse( - this.assetProfileForm.controls['scraperConfiguration'].value + this.assetProfileForm.get('scraperConfiguration').value ); } catch {} try { - sectors = JSON.parse(this.assetProfileForm.controls['sectors'].value); + sectors = JSON.parse(this.assetProfileForm.get('sectors').value); } catch {} try { symbolMapping = JSON.parse( - this.assetProfileForm.controls['symbolMapping'].value + this.assetProfileForm.get('symbolMapping').value ); } catch {} @@ -289,14 +289,14 @@ export class AssetProfileDialog implements OnDestroy, OnInit { scraperConfiguration, sectors, symbolMapping, - assetClass: this.assetProfileForm.controls['assetClass'].value, - assetSubClass: this.assetProfileForm.controls['assetSubClass'].value, - comment: this.assetProfileForm.controls['comment'].value ?? null, + assetClass: this.assetProfileForm.get('assetClass').value, + assetSubClass: this.assetProfileForm.get('assetSubClass').value, + comment: this.assetProfileForm.get('comment').value ?? null, currency: (( - (this.assetProfileForm.controls['currency'].value) + (this.assetProfileForm.get('currency').value) ))?.value, - name: this.assetProfileForm.controls['name'].value, - url: this.assetProfileForm.controls['url'].value + name: this.assetProfileForm.get('name').value, + url: this.assetProfileForm.get('url').value }; this.adminService @@ -314,8 +314,8 @@ export class AssetProfileDialog implements OnDestroy, OnInit { this.adminService .testMarketData({ dataSource: this.data.dataSource, - scraperConfiguration: - this.assetProfileForm.controls['scraperConfiguration'].value, + scraperConfiguration: this.assetProfileForm.get('scraperConfiguration') + .value, symbol: this.data.symbol }) .pipe( @@ -331,9 +331,8 @@ export class AssetProfileDialog implements OnDestroy, OnInit { ' ' + price + ' ' + - (( - (this.assetProfileForm.controls['currency'].value) - ))?.value + ((this.assetProfileForm.get('currency').value)) + ?.value ); }); } diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html index b0b57df09..4f01a933e 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.html @@ -302,7 +302,7 @@ mat-flat-button type="button" [disabled]=" - assetProfileForm.controls['scraperConfiguration'].value === '{}' + assetProfileForm.get('scraperConfiguration').value === '{}' " (click)="onTestMarketData()" > @@ -338,11 +338,11 @@ Url - @if (assetProfileForm.controls['url'].value) { + @if (assetProfileForm.get('url').value) { } diff --git a/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.ts b/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.ts index d5415524b..f0a47ad1b 100644 --- a/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.ts +++ b/apps/client/src/app/components/admin-market-data/create-asset-profile-dialog/create-asset-profile-dialog.component.ts @@ -59,14 +59,12 @@ export class CreateAssetProfileDialog implements OnInit, OnDestroy { this.mode === 'auto' ? this.dialogRef.close({ dataSource: - this.createAssetProfileForm.controls['searchSymbol'].value - .dataSource, - symbol: - this.createAssetProfileForm.controls['searchSymbol'].value.symbol + this.createAssetProfileForm.get('searchSymbol').value.dataSource, + symbol: this.createAssetProfileForm.get('searchSymbol').value.symbol }) : this.dialogRef.close({ dataSource: 'MANUAL', - symbol: this.createAssetProfileForm.controls['addSymbol'].value + symbol: this.createAssetProfileForm.get('addSymbol').value }); } diff --git a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts index 4c6cbbb85..5e08635e0 100644 --- a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts +++ b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts @@ -67,9 +67,9 @@ export class CreateOrUpdateAccessDialog implements OnDestroy { public onSubmit() { const access: CreateAccessDto = { - alias: this.accessForm.controls['alias'].value, - granteeUserId: this.accessForm.controls['userId'].value, - permissions: [this.accessForm.controls['permissions'].value] + alias: this.accessForm.get('alias').value, + granteeUserId: this.accessForm.get('userId').value, + permissions: [this.accessForm.get('permissions').value] }; this.dataService diff --git a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html index eba44adbd..a6f20f2f4 100644 --- a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html +++ b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -27,7 +27,7 @@
- @if (accessForm.controls['type'].value === 'PRIVATE') { + @if (accessForm.get('type').value === 'PRIVATE') {
Permission diff --git a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts index 4e3ef335e..35dd2835f 100644 --- a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts +++ b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts @@ -82,7 +82,7 @@ export class CreateOrUpdateAccountDialog implements OnDestroy { } public autoCompleteCheck() { - const inputValue = this.accountForm.controls['platformId'].value; + const inputValue = this.accountForm.get('platformId').value; if (typeof inputValue === 'string') { const matchingEntry = this.platforms.find(({ name }) => { @@ -90,7 +90,7 @@ export class CreateOrUpdateAccountDialog implements OnDestroy { }); if (matchingEntry) { - this.accountForm.controls['platformId'].setValue(matchingEntry); + this.accountForm.get('platformId').setValue(matchingEntry); } } } @@ -105,13 +105,13 @@ export class CreateOrUpdateAccountDialog implements OnDestroy { public async onSubmit() { const account: CreateAccountDto | UpdateAccountDto = { - balance: this.accountForm.controls['balance'].value, - comment: this.accountForm.controls['comment'].value, - currency: this.accountForm.controls['currency'].value?.value, - id: this.accountForm.controls['accountId'].value, - isExcluded: this.accountForm.controls['isExcluded'].value, - name: this.accountForm.controls['name'].value, - platformId: this.accountForm.controls['platformId'].value?.id ?? null + balance: this.accountForm.get('balance').value, + comment: this.accountForm.get('comment').value, + currency: this.accountForm.get('currency').value?.value, + id: this.accountForm.get('accountId').value, + isExcluded: this.accountForm.get('isExcluded').value, + name: this.accountForm.get('name').value, + platformId: this.accountForm.get('platformId').value?.id ?? null }; try { diff --git a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html index e2981462f..af97bfce3 100644 --- a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html +++ b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -39,7 +39,7 @@ (keydown.enter)="$event.stopPropagation()" /> {{ - accountForm.controls['currency']?.value?.value + accountForm.get('currency')?.value?.value }}
diff --git a/apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.component.ts b/apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.component.ts index 60acd52b3..4547710cb 100644 --- a/apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.component.ts +++ b/apps/client/src/app/pages/accounts/transfer-balance/transfer-balance-dialog.component.ts @@ -66,9 +66,9 @@ export class TransferBalanceDialog implements OnDestroy { public onSubmit() { const account: TransferBalanceDto = { - accountIdFrom: this.transferBalanceForm.controls['fromAccount'].value, - accountIdTo: this.transferBalanceForm.controls['toAccount'].value, - balance: this.transferBalanceForm.controls['balance'].value + accountIdFrom: this.transferBalanceForm.get('fromAccount').value, + accountIdTo: this.transferBalanceForm.get('toAccount').value, + balance: this.transferBalanceForm.get('balance').value }; this.dialogRef.close({ account }); diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts index 1196de58c..f9ea4817c 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts @@ -148,13 +148,14 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { .subscribe(async () => { let exchangeRateOfUnitPrice = 1; - this.activityForm.controls['feeInCustomCurrency'].setErrors(null); - this.activityForm.controls['unitPriceInCustomCurrency'].setErrors(null); + this.activityForm.get('feeInCustomCurrency').setErrors(null); + this.activityForm.get('unitPriceInCustomCurrency').setErrors(null); - const currency = this.activityForm.controls['currency'].value; - const currencyOfUnitPrice = - this.activityForm.controls['currencyOfUnitPrice'].value; - const date = this.activityForm.controls['date'].value; + const currency = this.activityForm.get('currency').value; + const currencyOfUnitPrice = this.activityForm.get( + 'currencyOfUnitPrice' + ).value; + const date = this.activityForm.get('date').value; if ( currency && @@ -174,104 +175,97 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { exchangeRateOfUnitPrice = marketPrice; } catch { - this.activityForm.controls['unitPriceInCustomCurrency'].setErrors({ + this.activityForm.get('unitPriceInCustomCurrency').setErrors({ invalid: true }); } } const feeInCustomCurrency = - this.activityForm.controls['feeInCustomCurrency'].value * + this.activityForm.get('feeInCustomCurrency').value * exchangeRateOfUnitPrice; const unitPriceInCustomCurrency = - this.activityForm.controls['unitPriceInCustomCurrency'].value * + this.activityForm.get('unitPriceInCustomCurrency').value * exchangeRateOfUnitPrice; - this.activityForm.controls['fee'].setValue(feeInCustomCurrency, { + this.activityForm.get('fee').setValue(feeInCustomCurrency, { emitEvent: false }); - this.activityForm.controls['unitPrice'].setValue( - unitPriceInCustomCurrency, - { - emitEvent: false - } - ); + this.activityForm.get('unitPrice').setValue(unitPriceInCustomCurrency, { + emitEvent: false + }); if ( - this.activityForm.controls['type'].value === 'BUY' || - this.activityForm.controls['type'].value === 'FEE' || - this.activityForm.controls['type'].value === 'ITEM' + this.activityForm.get('type').value === 'BUY' || + this.activityForm.get('type').value === 'FEE' || + this.activityForm.get('type').value === 'ITEM' ) { this.total = - this.activityForm.controls['quantity'].value * - this.activityForm.controls['unitPrice'].value + - this.activityForm.controls['fee'].value ?? 0; + this.activityForm.get('quantity').value * + this.activityForm.get('unitPrice').value + + this.activityForm.get('fee').value ?? 0; } else { this.total = - this.activityForm.controls['quantity'].value * - this.activityForm.controls['unitPrice'].value - - this.activityForm.controls['fee'].value ?? 0; + this.activityForm.get('quantity').value * + this.activityForm.get('unitPrice').value - + this.activityForm.get('fee').value ?? 0; } this.changeDetectorRef.markForCheck(); }); - this.activityForm.controls['accountId'].valueChanges.subscribe( - (accountId) => { - const type = this.activityForm.controls['type'].value; + this.activityForm.get('accountId').valueChanges.subscribe((accountId) => { + const type = this.activityForm.get('type').value; - if ( - type === 'FEE' || - type === 'INTEREST' || - type === 'ITEM' || - type === 'LIABILITY' - ) { - const currency = - this.data.accounts.find(({ id }) => { - return id === accountId; - })?.currency ?? this.data.user.settings.baseCurrency; + if ( + type === 'FEE' || + type === 'INTEREST' || + type === 'ITEM' || + type === 'LIABILITY' + ) { + const currency = + this.data.accounts.find(({ id }) => { + return id === accountId; + })?.currency ?? this.data.user.settings.baseCurrency; - this.activityForm.controls['currency'].setValue(currency); - this.activityForm.controls['currencyOfUnitPrice'].setValue(currency); - - if (['FEE', 'INTEREST'].includes(type)) { - if (this.activityForm.controls['accountId'].value) { - this.activityForm.controls['updateAccountBalance'].enable(); - } else { - this.activityForm.controls['updateAccountBalance'].disable(); - this.activityForm.controls['updateAccountBalance'].setValue( - false - ); - } + this.activityForm.get('currency').setValue(currency); + this.activityForm.get('currencyOfUnitPrice').setValue(currency); + + if (['FEE', 'INTEREST'].includes(type)) { + if (this.activityForm.get('accountId').value) { + this.activityForm.get('updateAccountBalance').enable(); + } else { + this.activityForm.get('updateAccountBalance').disable(); + this.activityForm.get('updateAccountBalance').setValue(false); } } } - ); + }); - this.activityForm.controls['date'].valueChanges.subscribe(() => { - if (isToday(this.activityForm.controls['date'].value)) { - this.activityForm.controls['updateAccountBalance'].enable(); + this.activityForm.get('date').valueChanges.subscribe(() => { + if (isToday(this.activityForm.get('date').value)) { + this.activityForm.get('updateAccountBalance').enable(); } else { - this.activityForm.controls['updateAccountBalance'].disable(); - this.activityForm.controls['updateAccountBalance'].setValue(false); + this.activityForm.get('updateAccountBalance').disable(); + this.activityForm.get('updateAccountBalance').setValue(false); } this.changeDetectorRef.markForCheck(); }); - this.activityForm.controls['searchSymbol'].valueChanges.subscribe(() => { - if (this.activityForm.controls['searchSymbol'].invalid) { + this.activityForm.get('searchSymbol').valueChanges.subscribe(() => { + if (this.activityForm.get('searchSymbol').invalid) { this.data.activity.SymbolProfile = null; } else if ( ['BUY', 'DIVIDEND', 'SELL'].includes( - this.activityForm.controls['type'].value + this.activityForm.get('type').value ) ) { - this.activityForm.controls['dataSource'].setValue( - this.activityForm.controls['searchSymbol'].value.dataSource - ); + this.activityForm + .get('dataSource') + .setValue(this.activityForm.get('searchSymbol').value.dataSource); this.updateSymbol(); } @@ -282,130 +276,127 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { this.filteredTagsObservable = this.activityForm.controls[ 'tags' ].valueChanges.pipe( - startWith(this.activityForm.controls['tags'].value), + startWith(this.activityForm.get('tags').value), map((aTags: Tag[] | null) => { return aTags ? this.filterTags(aTags) : this.tags.slice(); }) ); - this.activityForm.controls['type'].valueChanges - .pipe(takeUntil(this.unsubscribeSubject)) + this.activityForm + .get('type') + .valueChanges.pipe(takeUntil(this.unsubscribeSubject)) .subscribe((type: Type) => { if (type === 'ITEM') { - this.activityForm.controls['accountId'].removeValidators( - Validators.required - ); - this.activityForm.controls['accountId'].updateValueAndValidity(); + this.activityForm + .get('accountId') + .removeValidators(Validators.required); + this.activityForm.get('accountId').updateValueAndValidity(); const currency = this.data.accounts.find(({ id }) => { - return id === this.activityForm.controls['accountId'].value; + return id === this.activityForm.get('accountId').value; })?.currency ?? this.data.user.settings.baseCurrency; - this.activityForm.controls['currency'].setValue(currency); - this.activityForm.controls['currencyOfUnitPrice'].setValue(currency); - - this.activityForm.controls['dataSource'].removeValidators( - Validators.required - ); - this.activityForm.controls['dataSource'].updateValueAndValidity(); - this.activityForm.controls['feeInCustomCurrency'].reset(); - this.activityForm.controls['name'].setValidators(Validators.required); - this.activityForm.controls['name'].updateValueAndValidity(); - this.activityForm.controls['quantity'].setValue(1); - this.activityForm.controls['searchSymbol'].removeValidators( - Validators.required - ); - this.activityForm.controls['searchSymbol'].updateValueAndValidity(); - this.activityForm.controls['updateAccountBalance'].disable(); - this.activityForm.controls['updateAccountBalance'].setValue(false); + this.activityForm.get('currency').setValue(currency); + this.activityForm.get('currencyOfUnitPrice').setValue(currency); + + this.activityForm + .get('dataSource') + .removeValidators(Validators.required); + this.activityForm.get('dataSource').updateValueAndValidity(); + this.activityForm.get('feeInCustomCurrency').reset(); + this.activityForm.get('name').setValidators(Validators.required); + this.activityForm.get('name').updateValueAndValidity(); + this.activityForm.get('quantity').setValue(1); + this.activityForm + .get('searchSymbol') + .removeValidators(Validators.required); + this.activityForm.get('searchSymbol').updateValueAndValidity(); + this.activityForm.get('updateAccountBalance').disable(); + this.activityForm.get('updateAccountBalance').setValue(false); } else if ( type === 'FEE' || type === 'INTEREST' || type === 'LIABILITY' ) { - this.activityForm.controls['accountId'].removeValidators( - Validators.required - ); - this.activityForm.controls['accountId'].updateValueAndValidity(); + this.activityForm + .get('accountId') + .removeValidators(Validators.required); + this.activityForm.get('accountId').updateValueAndValidity(); const currency = this.data.accounts.find(({ id }) => { - return id === this.activityForm.controls['accountId'].value; + return id === this.activityForm.get('accountId').value; })?.currency ?? this.data.user.settings.baseCurrency; - this.activityForm.controls['currency'].setValue(currency); - this.activityForm.controls['currencyOfUnitPrice'].setValue(currency); + this.activityForm.get('currency').setValue(currency); + this.activityForm.get('currencyOfUnitPrice').setValue(currency); - this.activityForm.controls['dataSource'].removeValidators( - Validators.required - ); - this.activityForm.controls['dataSource'].updateValueAndValidity(); + this.activityForm + .get('dataSource') + .removeValidators(Validators.required); + this.activityForm.get('dataSource').updateValueAndValidity(); if ( (type === 'FEE' && - this.activityForm.controls['feeInCustomCurrency'].value === 0) || + this.activityForm.get('feeInCustomCurrency').value === 0) || type === 'INTEREST' || type === 'LIABILITY' ) { - this.activityForm.controls['feeInCustomCurrency'].reset(); + this.activityForm.get('feeInCustomCurrency').reset(); } - this.activityForm.controls['name'].setValidators(Validators.required); - this.activityForm.controls['name'].updateValueAndValidity(); + this.activityForm.get('name').setValidators(Validators.required); + this.activityForm.get('name').updateValueAndValidity(); if (type === 'FEE') { - this.activityForm.controls['quantity'].setValue(0); + this.activityForm.get('quantity').setValue(0); } else if (type === 'INTEREST' || type === 'LIABILITY') { - this.activityForm.controls['quantity'].setValue(1); + this.activityForm.get('quantity').setValue(1); } - this.activityForm.controls['searchSymbol'].removeValidators( - Validators.required - ); - this.activityForm.controls['searchSymbol'].updateValueAndValidity(); + this.activityForm + .get('searchSymbol') + .removeValidators(Validators.required); + this.activityForm.get('searchSymbol').updateValueAndValidity(); if (type === 'FEE') { - this.activityForm.controls['unitPriceInCustomCurrency'].setValue(0); + this.activityForm.get('unitPriceInCustomCurrency').setValue(0); } if ( ['FEE', 'INTEREST'].includes(type) && - this.activityForm.controls['accountId'].value + this.activityForm.get('accountId').value ) { - this.activityForm.controls['updateAccountBalance'].enable(); + this.activityForm.get('updateAccountBalance').enable(); } else { - this.activityForm.controls['updateAccountBalance'].disable(); - this.activityForm.controls['updateAccountBalance'].setValue(false); + this.activityForm.get('updateAccountBalance').disable(); + this.activityForm.get('updateAccountBalance').setValue(false); } } else { - this.activityForm.controls['accountId'].setValidators( - Validators.required - ); - this.activityForm.controls['accountId'].updateValueAndValidity(); - this.activityForm.controls['dataSource'].setValidators( - Validators.required - ); - this.activityForm.controls['dataSource'].updateValueAndValidity(); - this.activityForm.controls['name'].removeValidators( - Validators.required - ); - this.activityForm.controls['name'].updateValueAndValidity(); - this.activityForm.controls['searchSymbol'].setValidators( - Validators.required - ); - this.activityForm.controls['searchSymbol'].updateValueAndValidity(); - this.activityForm.controls['updateAccountBalance'].enable(); + this.activityForm.get('accountId').setValidators(Validators.required); + this.activityForm.get('accountId').updateValueAndValidity(); + this.activityForm + .get('dataSource') + .setValidators(Validators.required); + this.activityForm.get('dataSource').updateValueAndValidity(); + this.activityForm.get('name').removeValidators(Validators.required); + this.activityForm.get('name').updateValueAndValidity(); + this.activityForm + .get('searchSymbol') + .setValidators(Validators.required); + this.activityForm.get('searchSymbol').updateValueAndValidity(); + this.activityForm.get('updateAccountBalance').enable(); } this.changeDetectorRef.markForCheck(); }); - this.activityForm.controls['type'].setValue(this.data.activity?.type); + this.activityForm.get('type').setValue(this.data.activity?.type); if (this.data.activity?.id) { - this.activityForm.controls['searchSymbol'].disable(); - this.activityForm.controls['type'].disable(); + this.activityForm.get('searchSymbol').disable(); + this.activityForm.get('type').disable(); } if (this.data.activity?.SymbolProfile?.symbol) { @@ -425,14 +416,14 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { public applyCurrentMarketPrice() { this.activityForm.patchValue({ - currencyOfUnitPrice: this.activityForm.controls['currency'].value, + currencyOfUnitPrice: this.activityForm.get('currency').value, unitPriceInCustomCurrency: this.currentMarketPrice }); } public onAddTag(event: MatAutocompleteSelectedEvent) { - this.activityForm.controls['tags'].setValue([ - ...(this.activityForm.controls['tags'].value ?? []), + this.activityForm.get('tags').setValue([ + ...(this.activityForm.get('tags').value ?? []), this.tags.find(({ id }) => { return id === event.option.value; }) @@ -445,8 +436,8 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { } public onRemoveTag(aTag: Tag) { - this.activityForm.controls['tags'].setValue( - this.activityForm.controls['tags'].value.filter(({ id }) => { + this.activityForm.get('tags').setValue( + this.activityForm.get('tags').value.filter(({ id }) => { return id !== aTag.id; }) ); @@ -454,25 +445,24 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { public async onSubmit() { const activity: CreateOrderDto | UpdateOrderDto = { - accountId: this.activityForm.controls['accountId'].value, - assetClass: this.activityForm.controls['assetClass'].value, - assetSubClass: this.activityForm.controls['assetSubClass'].value, - comment: this.activityForm.controls['comment'].value, - currency: this.activityForm.controls['currency'].value, - customCurrency: this.activityForm.controls['currencyOfUnitPrice'].value, - date: this.activityForm.controls['date'].value, - dataSource: this.activityForm.controls['dataSource'].value, - fee: this.activityForm.controls['fee'].value, - quantity: this.activityForm.controls['quantity'].value, + accountId: this.activityForm.get('accountId').value, + assetClass: this.activityForm.get('assetClass').value, + assetSubClass: this.activityForm.get('assetSubClass').value, + comment: this.activityForm.get('comment').value, + currency: this.activityForm.get('currency').value, + customCurrency: this.activityForm.get('currencyOfUnitPrice').value, + date: this.activityForm.get('date').value, + dataSource: this.activityForm.get('dataSource').value, + fee: this.activityForm.get('fee').value, + quantity: this.activityForm.get('quantity').value, symbol: - this.activityForm.controls['searchSymbol'].value?.symbol === - undefined || - isUUID(this.activityForm.controls['searchSymbol'].value?.symbol) - ? this.activityForm.controls['name'].value - : this.activityForm.controls['searchSymbol'].value.symbol, - tags: this.activityForm.controls['tags'].value, - type: this.activityForm.controls['type'].value, - unitPrice: this.activityForm.controls['unitPrice'].value + this.activityForm.get('searchSymbol').value?.symbol === undefined || + isUUID(this.activityForm.get('searchSymbol').value?.symbol) + ? this.activityForm.get('name').value + : this.activityForm.get('searchSymbol').value.symbol, + tags: this.activityForm.get('tags').value, + type: this.activityForm.get('type').value, + unitPrice: this.activityForm.get('unitPrice').value }; try { @@ -487,7 +477,7 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { }); } else { (activity as CreateOrderDto).updateAccountBalance = - this.activityForm.controls['updateAccountBalance'].value; + this.activityForm.get('updateAccountBalance').value; await validateObjectForForm({ classDto: CreateOrderDto, @@ -524,8 +514,8 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { this.dataService .fetchSymbolItem({ - dataSource: this.activityForm.controls['dataSource'].value, - symbol: this.activityForm.controls['searchSymbol'].value.symbol + dataSource: this.activityForm.get('dataSource').value, + symbol: this.activityForm.get('searchSymbol').value.symbol }) .pipe( catchError(() => { @@ -540,9 +530,9 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { takeUntil(this.unsubscribeSubject) ) .subscribe(({ currency, dataSource, marketPrice }) => { - this.activityForm.controls['currency'].setValue(currency); - this.activityForm.controls['currencyOfUnitPrice'].setValue(currency); - this.activityForm.controls['dataSource'].setValue(dataSource); + this.activityForm.get('currency').setValue(currency); + this.activityForm.get('currencyOfUnitPrice').setValue(currency); + this.activityForm.get('dataSource').setValue(dataSource); this.currentMarketPrice = marketPrice; diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html index 79ea7647a..65ba637db 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html @@ -12,7 +12,7 @@ Type {{ - typesTranslationMap[activityForm.controls['type'].value] + typesTranslationMap[activityForm.get('type').value] }} @@ -113,9 +111,9 @@
@@ -129,9 +127,7 @@
@@ -173,10 +169,10 @@ class="mb-3" [ngClass]="{ 'd-none': - activityForm.controls['type']?.value === 'FEE' || - activityForm.controls['type']?.value === 'INTEREST' || - activityForm.controls['type']?.value === 'ITEM' || - activityForm.controls['type']?.value === 'LIABILITY' + activityForm.get('type')?.value === 'FEE' || + activityForm.get('type')?.value === 'INTEREST' || + activityForm.get('type')?.value === 'ITEM' || + activityForm.get('type')?.value === 'LIABILITY' }" > @@ -186,12 +182,12 @@
+ > Dividend @@ -211,7 +207,7 @@
Oops! Could not get the historical exchange rate from {{ - activityForm.controls['date']?.value | date: defaultDateFormat + activityForm.get('date')?.value | date: defaultDateFormat }} @@ -241,7 +235,7 @@ *ngIf=" currentMarketPrice && (data.activity.type === 'BUY' || data.activity.type === 'SELL') && - isToday(activityForm.controls['date']?.value) + isToday(activityForm.get('date')?.value) " class="ml-2 mt-1 no-min-width" mat-button @@ -256,7 +250,7 @@
+ > Dividend @@ -269,7 +263,7 @@ {{ - activityForm.controls['currency'].value + activityForm.get('currency').value }}
@@ -277,9 +271,9 @@ class="mb-3" [ngClass]="{ 'd-none': - activityForm.controls['type']?.value === 'INTEREST' || - activityForm.controls['type']?.value === 'ITEM' || - activityForm.controls['type']?.value === 'LIABILITY' + activityForm.get('type')?.value === 'INTEREST' || + activityForm.get('type')?.value === 'ITEM' || + activityForm.get('type')?.value === 'LIABILITY' }" > @@ -288,19 +282,17 @@
- {{ activityForm.controls['currencyOfUnitPrice'].value }} + {{ activityForm.get('currencyOfUnitPrice').value }}
Oops! Could not get the historical exchange rate from {{ - activityForm.controls['date']?.value | date: defaultDateFormat + activityForm.get('date')?.value | date: defaultDateFormat }}
@@ -310,7 +302,7 @@ Fee {{ - activityForm.controls['currency'].value + activityForm.get('currency').value }}
@@ -328,7 +320,7 @@
Asset Class @@ -344,7 +336,7 @@
Asset Sub Class @@ -363,7 +355,7 @@ Tags diff --git a/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts b/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts index c8d369f54..ccc861335 100644 --- a/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -85,7 +85,7 @@ export class ImportActivitiesDialog implements OnDestroy { this.dialogTitle = $localize`Import Dividends`; this.mode = 'DIVIDEND'; - this.uniqueAssetForm.controls['uniqueAsset'].disable(); + this.uniqueAssetForm.get('uniqueAsset').disable(); this.dataService .fetchPositions({ @@ -102,7 +102,7 @@ export class ImportActivitiesDialog implements OnDestroy { this.holdings = sortBy(positions, ({ name }) => { return name.toLowerCase(); }); - this.uniqueAssetForm.controls['uniqueAsset'].enable(); + this.uniqueAssetForm.get('uniqueAsset').enable(); this.isLoading = false; @@ -167,10 +167,10 @@ export class ImportActivitiesDialog implements OnDestroy { } public onLoadDividends(aStepper: MatStepper) { - this.uniqueAssetForm.controls['uniqueAsset'].disable(); + this.uniqueAssetForm.get('uniqueAsset').disable(); const { dataSource, symbol } = - this.uniqueAssetForm.controls['uniqueAsset'].value; + this.uniqueAssetForm.get('uniqueAsset').value; this.dataService .fetchDividendsImport({ @@ -193,7 +193,7 @@ export class ImportActivitiesDialog implements OnDestroy { this.details = []; this.errorMessages = []; this.importStep = ImportStep.SELECT_ACTIVITIES; - this.uniqueAssetForm.controls['uniqueAsset'].enable(); + this.uniqueAssetForm.get('uniqueAsset').enable(); aStepper.reset(); } diff --git a/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html b/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html index 032480acf..3e0a00e93 100644 --- a/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html +++ b/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html @@ -33,7 +33,7 @@ Holding {{ - uniqueAssetForm.controls['uniqueAsset']?.value?.name + uniqueAssetForm.get('uniqueAsset')?.value?.name }} Retirement Date
- {{ - calculatorForm.controls['retirementDate'].value - | date: 'MMMM YYYY' - }} + {{ calculatorForm.get('retirementDate').value | date: 'MMMM YYYY' }}
Date: Wed, 24 Apr 2024 20:35:39 +0200 Subject: [PATCH 160/203] Feature/extend faq by custom asset instructions (#3326) * Add instructions for custom asset * Update changelog --- CHANGELOG.md | 4 ++++ .../faq/self-hosting/self-hosting-page.html | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff93075b9..8568b2c0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Extended the content of the _Self-Hosting_ section by the custom asset instructions on the Frequently Asked Questions (FAQ) page + ### Changed - Upgraded `prisma` from version `5.12.1` to `5.13.0` diff --git a/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html b/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html index 7df2cdbe9..da6690d58 100644 --- a/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html +++ b/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html @@ -118,6 +118,25 @@ providers are considered experimental. + + + How do I add a custom asset? + + +

+ If you want to track an asset that is not available from any data + provider, you can create a custom asset as follows. +

+
    +
  1. Go to the Admin Control panel
  2. +
  3. Go to the Market Data section
  4. +
  5. Create an asset profile
  6. +
  7. Select Add Manually and enter a unique symbol
  8. +
  9. Edit your asset profile
  10. +
  11. Add a new activity by searching for the symbol
  12. +
+
+
Which devices are supported? From 55b0fe232c4557f7f7198bd779f834e8546c15c9 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 25 Apr 2024 19:04:28 +0200 Subject: [PATCH 161/203] Bugfix/reset form values to null if empty string (#3327) * Reset form values to null if empty string * Update changelog --- CHANGELOG.md | 4 ++++ .../asset-profile-dialog/asset-profile-dialog.component.ts | 4 ++-- .../create-or-update-account-dialog.component.ts | 4 ++-- .../create-or-update-activity-dialog.component.ts | 2 +- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8568b2c0a..7bdafc2b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Upgraded `prisma` from version `5.12.1` to `5.13.0` +### Fixed + +- Fixed the form submit in the asset profile details dialog of the admin control due to the `url` validation + ## 2.76.0 - 2024-04-23 ### Changed diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts index d6403540a..783bbdbc4 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts @@ -291,12 +291,12 @@ export class AssetProfileDialog implements OnDestroy, OnInit { symbolMapping, assetClass: this.assetProfileForm.get('assetClass').value, assetSubClass: this.assetProfileForm.get('assetSubClass').value, - comment: this.assetProfileForm.get('comment').value ?? null, + comment: this.assetProfileForm.get('comment').value || null, currency: (( (this.assetProfileForm.get('currency').value) ))?.value, name: this.assetProfileForm.get('name').value, - url: this.assetProfileForm.get('url').value + url: this.assetProfileForm.get('url').value || null }; this.adminService diff --git a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts index 35dd2835f..6c3624344 100644 --- a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts +++ b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts @@ -106,12 +106,12 @@ export class CreateOrUpdateAccountDialog implements OnDestroy { public async onSubmit() { const account: CreateAccountDto | UpdateAccountDto = { balance: this.accountForm.get('balance').value, - comment: this.accountForm.get('comment').value, + comment: this.accountForm.get('comment').value || null, currency: this.accountForm.get('currency').value?.value, id: this.accountForm.get('accountId').value, isExcluded: this.accountForm.get('isExcluded').value, name: this.accountForm.get('name').value, - platformId: this.accountForm.get('platformId').value?.id ?? null + platformId: this.accountForm.get('platformId').value?.id || null }; try { diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts index f9ea4817c..700e997e1 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts @@ -448,7 +448,7 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { accountId: this.activityForm.get('accountId').value, assetClass: this.activityForm.get('assetClass').value, assetSubClass: this.activityForm.get('assetSubClass').value, - comment: this.activityForm.get('comment').value, + comment: this.activityForm.get('comment').value || null, currency: this.activityForm.get('currency').value, customCurrency: this.activityForm.get('currencyOfUnitPrice').value, date: this.activityForm.get('date').value, From a4efbc0131d839fb44e38126bdb98316315637de Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:40:00 +0200 Subject: [PATCH 162/203] Feature/migrate UI components to control flow (#3324) * Migrate to control flow * Update changelog --- CHANGELOG.md | 1 + .../account-balances.component.ts | 2 - .../assistant-list-item.component.ts | 3 +- .../assistant-list-item.html | 10 +-- .../ui/src/lib/carousel/carousel.component.ts | 3 +- .../currency-selector.component.ts | 2 - .../no-transactions-info.component.ts | 3 +- .../symbol-autocomplete.component.ts | 2 - .../trend-indicator.component.html | 76 ++++++++----------- 9 files changed, 40 insertions(+), 62 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bdafc2b3..8d614067d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Migrated the `@ghostfolio/ui` components to control flow - Upgraded `prisma` from version `5.12.1` to `5.13.0` ### Fixed diff --git a/libs/ui/src/lib/account-balances/account-balances.component.ts b/libs/ui/src/lib/account-balances/account-balances.component.ts index c4fd379c8..996b513e6 100644 --- a/libs/ui/src/lib/account-balances/account-balances.component.ts +++ b/libs/ui/src/lib/account-balances/account-balances.component.ts @@ -1,7 +1,6 @@ import { getLocale } from '@ghostfolio/common/helper'; import { AccountBalancesResponse } from '@ghostfolio/common/interfaces'; -import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, @@ -36,7 +35,6 @@ import { GfValueComponent } from '../value'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, imports: [ - CommonModule, GfValueComponent, MatButtonModule, MatDatepickerModule, diff --git a/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts b/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts index b909145c7..4b3908369 100644 --- a/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts +++ b/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.component.ts @@ -2,7 +2,6 @@ import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; import { ISearchResultItem } from '@ghostfolio/ui/assistant/interfaces/interfaces'; import { FocusableOption } from '@angular/cdk/a11y'; -import { CommonModule } from '@angular/common'; import { ChangeDetectionStrategy, ChangeDetectorRef, @@ -19,7 +18,7 @@ import { Params, RouterModule } from '@angular/router'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, - imports: [CommonModule, GfSymbolModule, RouterModule], + imports: [GfSymbolModule, RouterModule], selector: 'gf-assistant-list-item', standalone: true, styleUrls: ['./assistant-list-item.scss'], diff --git a/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.html b/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.html index 53bf60680..46c8a4c24 100644 --- a/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.html +++ b/libs/ui/src/lib/assistant/assistant-list-item/assistant-list-item.html @@ -9,9 +9,9 @@ >
{{ item?.symbol | gfSymbol }} · {{ item?.currency - }} - · {{ item?.assetSubClassString }}{{ item?.symbol | gfSymbol }} · {{ item?.currency }} + @if (item?.assetSubClassString) { + · {{ item.assetSubClassString }} + } + diff --git a/libs/ui/src/lib/carousel/carousel.component.ts b/libs/ui/src/lib/carousel/carousel.component.ts index 33f68b249..7f93297dd 100644 --- a/libs/ui/src/lib/carousel/carousel.component.ts +++ b/libs/ui/src/lib/carousel/carousel.component.ts @@ -1,6 +1,5 @@ import { FocusKeyManager } from '@angular/cdk/a11y'; import { LEFT_ARROW, RIGHT_ARROW, TAB } from '@angular/cdk/keycodes'; -import { CommonModule } from '@angular/common'; import { AfterContentInit, CUSTOM_ELEMENTS_SCHEMA, @@ -22,7 +21,7 @@ import { CarouselItem } from './carousel-item.directive'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, - imports: [CommonModule, MatButtonModule], + imports: [MatButtonModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], selector: 'gf-carousel', standalone: true, diff --git a/libs/ui/src/lib/currency-selector/currency-selector.component.ts b/libs/ui/src/lib/currency-selector/currency-selector.component.ts index a0ed3c88a..046af1cf8 100644 --- a/libs/ui/src/lib/currency-selector/currency-selector.component.ts +++ b/libs/ui/src/lib/currency-selector/currency-selector.component.ts @@ -2,7 +2,6 @@ import { Currency } from '@ghostfolio/common/interfaces'; import { AbstractMatFormField } from '@ghostfolio/ui/shared/abstract-mat-form-field'; import { FocusMonitor } from '@angular/cdk/a11y'; -import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, @@ -41,7 +40,6 @@ import { map, startWith, takeUntil } from 'rxjs/operators'; '[id]': 'id' }, imports: [ - CommonModule, FormsModule, MatAutocompleteModule, MatFormFieldModule, diff --git a/libs/ui/src/lib/no-transactions-info/no-transactions-info.component.ts b/libs/ui/src/lib/no-transactions-info/no-transactions-info.component.ts index 0c30041b6..7fc8830a8 100644 --- a/libs/ui/src/lib/no-transactions-info/no-transactions-info.component.ts +++ b/libs/ui/src/lib/no-transactions-info/no-transactions-info.component.ts @@ -1,4 +1,3 @@ -import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, @@ -13,7 +12,7 @@ import { GfLogoComponent } from '../logo'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, - imports: [CommonModule, GfLogoComponent, MatButtonModule, RouterModule], + imports: [GfLogoComponent, MatButtonModule, RouterModule], schemas: [CUSTOM_ELEMENTS_SCHEMA], selector: 'gf-no-transactions-info-indicator', standalone: true, diff --git a/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts b/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts index 7da62d9df..8e07ed674 100644 --- a/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts +++ b/libs/ui/src/lib/symbol-autocomplete/symbol-autocomplete.component.ts @@ -5,7 +5,6 @@ import { translate } from '@ghostfolio/ui/i18n'; import { AbstractMatFormField } from '@ghostfolio/ui/shared/abstract-mat-form-field'; import { FocusMonitor } from '@angular/cdk/a11y'; -import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, @@ -53,7 +52,6 @@ import { GfPremiumIndicatorComponent } from '../premium-indicator'; '[id]': 'id' }, imports: [ - CommonModule, FormsModule, GfPremiumIndicatorComponent, GfSymbolModule, diff --git a/libs/ui/src/lib/trend-indicator/trend-indicator.component.html b/libs/ui/src/lib/trend-indicator/trend-indicator.component.html index 81ce57bfc..761b3f232 100644 --- a/libs/ui/src/lib/trend-indicator/trend-indicator.component.html +++ b/libs/ui/src/lib/trend-indicator/trend-indicator.component.html @@ -1,50 +1,36 @@ - - - - - +} @else { + @if (marketState === 'closed' && range === '1d') { + + } @else if (marketState === 'delayed' && range === '1d') { + + } @else if (value <= -0.0005) { + + } @else if (value > -0.0005 && value < 0.0005) { + } @else { + - - - - - - - - - + } +} From b692b7432cd516f65cd15222a919f86f6a583e88 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 26 Apr 2024 20:13:53 +0200 Subject: [PATCH 163/203] Feature/set up event system for portfolio changes (#3333) * Set up event system for portfolio changes * Update changelog --- CHANGELOG.md | 1 + .../account-balance.controller.ts | 10 +++--- .../account-balance.service.ts | 25 +++++++++++-- apps/api/src/app/account/account.service.ts | 32 +++++++++++++++-- apps/api/src/app/app.module.ts | 6 +++- apps/api/src/app/order/order.controller.ts | 12 +++---- apps/api/src/app/order/order.service.ts | 36 +++++++++++++++++-- apps/api/src/app/user/user.service.ts | 20 +++++++---- apps/api/src/events/events.module.ts | 8 +++++ .../api/src/events/portfolio-changed.event.ts | 15 ++++++++ .../src/events/portfolio-changed.listener.ts | 15 ++++++++ package.json | 1 + yarn.lock | 9 ++++- 13 files changed, 165 insertions(+), 25 deletions(-) create mode 100644 apps/api/src/events/events.module.ts create mode 100644 apps/api/src/events/portfolio-changed.event.ts create mode 100644 apps/api/src/events/portfolio-changed.listener.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 8d614067d..18e38e100 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Extended the content of the _Self-Hosting_ section by the custom asset instructions on the Frequently Asked Questions (FAQ) page +- Set up an event system to follow portfolio changes ### Changed diff --git a/apps/api/src/app/account-balance/account-balance.controller.ts b/apps/api/src/app/account-balance/account-balance.controller.ts index 4a8412003..bc454c5ab 100644 --- a/apps/api/src/app/account-balance/account-balance.controller.ts +++ b/apps/api/src/app/account-balance/account-balance.controller.ts @@ -1,7 +1,6 @@ import { AccountService } from '@ghostfolio/api/app/account/account.service'; import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorator'; import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; -import { resetHours } from '@ghostfolio/common/helper'; import { permissions } from '@ghostfolio/common/permissions'; import type { RequestWithUser } from '@ghostfolio/common/types'; @@ -18,7 +17,6 @@ import { import { REQUEST } from '@nestjs/core'; import { AuthGuard } from '@nestjs/passport'; import { AccountBalance } from '@prisma/client'; -import { parseISO } from 'date-fns'; import { StatusCodes, getReasonPhrase } from 'http-status-codes'; import { AccountBalanceService } from './account-balance.service'; @@ -67,10 +65,11 @@ export class AccountBalanceController { @Param('id') id: string ): Promise { const accountBalance = await this.accountBalanceService.accountBalance({ - id + id, + userId: this.request.user.id }); - if (!accountBalance || accountBalance.userId !== this.request.user.id) { + if (!accountBalance) { throw new HttpException( getReasonPhrase(StatusCodes.FORBIDDEN), StatusCodes.FORBIDDEN @@ -78,7 +77,8 @@ export class AccountBalanceController { } return this.accountBalanceService.deleteAccountBalance({ - id + id: accountBalance.id, + userId: accountBalance.userId }); } } diff --git a/apps/api/src/app/account-balance/account-balance.service.ts b/apps/api/src/app/account-balance/account-balance.service.ts index 5a5ec5be0..65393cec8 100644 --- a/apps/api/src/app/account-balance/account-balance.service.ts +++ b/apps/api/src/app/account-balance/account-balance.service.ts @@ -1,3 +1,4 @@ +import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { resetHours } from '@ghostfolio/common/helper'; @@ -5,6 +6,7 @@ import { AccountBalancesResponse, Filter } from '@ghostfolio/common/interfaces'; import { UserWithSettings } from '@ghostfolio/common/types'; import { Injectable } from '@nestjs/common'; +import { EventEmitter2 } from '@nestjs/event-emitter'; import { AccountBalance, Prisma } from '@prisma/client'; import { parseISO } from 'date-fns'; @@ -13,6 +15,7 @@ import { CreateAccountBalanceDto } from './create-account-balance.dto'; @Injectable() export class AccountBalanceService { public constructor( + private readonly eventEmitter: EventEmitter2, private readonly exchangeRateDataService: ExchangeRateDataService, private readonly prismaService: PrismaService ) {} @@ -36,7 +39,7 @@ export class AccountBalanceService { }: CreateAccountBalanceDto & { userId: string; }): Promise { - return this.prismaService.accountBalance.upsert({ + const accountBalance = await this.prismaService.accountBalance.upsert({ create: { Account: { connect: { @@ -59,14 +62,32 @@ export class AccountBalanceService { } } }); + + this.eventEmitter.emit( + PortfolioChangedEvent.getName(), + new PortfolioChangedEvent({ + userId + }) + ); + + return accountBalance; } public async deleteAccountBalance( where: Prisma.AccountBalanceWhereUniqueInput ): Promise { - return this.prismaService.accountBalance.delete({ + const accountBalance = await this.prismaService.accountBalance.delete({ where }); + + this.eventEmitter.emit( + PortfolioChangedEvent.getName(), + new PortfolioChangedEvent({ + userId: where.userId + }) + ); + + return accountBalance; } public async getAccountBalances({ diff --git a/apps/api/src/app/account/account.service.ts b/apps/api/src/app/account/account.service.ts index 6be7e8ffb..1564fa5b3 100644 --- a/apps/api/src/app/account/account.service.ts +++ b/apps/api/src/app/account/account.service.ts @@ -1,10 +1,12 @@ import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service'; +import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { Filter } from '@ghostfolio/common/interfaces'; import { Injectable } from '@nestjs/common'; +import { EventEmitter2 } from '@nestjs/event-emitter'; import { Account, Order, Platform, Prisma } from '@prisma/client'; import { Big } from 'big.js'; import { format } from 'date-fns'; @@ -16,6 +18,7 @@ import { CashDetails } from './interfaces/cash-details.interface'; export class AccountService { public constructor( private readonly accountBalanceService: AccountBalanceService, + private readonly eventEmitter: EventEmitter2, private readonly exchangeRateDataService: ExchangeRateDataService, private readonly prismaService: PrismaService ) {} @@ -94,6 +97,13 @@ export class AccountService { userId: aUserId }); + this.eventEmitter.emit( + PortfolioChangedEvent.getName(), + new PortfolioChangedEvent({ + userId: account.userId + }) + ); + return account; } @@ -101,9 +111,18 @@ export class AccountService { where: Prisma.AccountWhereUniqueInput, aUserId: string ): Promise { - return this.prismaService.account.delete({ + const account = await this.prismaService.account.delete({ where }); + + this.eventEmitter.emit( + PortfolioChangedEvent.getName(), + new PortfolioChangedEvent({ + userId: account.userId + }) + ); + + return account; } public async getAccounts(aUserId: string): Promise { @@ -201,10 +220,19 @@ export class AccountService { userId: aUserId }); - return this.prismaService.account.update({ + const account = await this.prismaService.account.update({ data, where }); + + this.eventEmitter.emit( + PortfolioChangedEvent.getName(), + new PortfolioChangedEvent({ + userId: account.userId + }) + ); + + return account; } public async updateAccountBalance({ diff --git a/apps/api/src/app/app.module.ts b/apps/api/src/app/app.module.ts index 5f2be5c8e..67bb9e03c 100644 --- a/apps/api/src/app/app.module.ts +++ b/apps/api/src/app/app.module.ts @@ -1,3 +1,4 @@ +import { EventsModule } from '@ghostfolio/api/events/events.module'; import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module'; import { CronService } from '@ghostfolio/api/services/cron.service'; import { DataGatheringModule } from '@ghostfolio/api/services/data-gathering/data-gathering.module'; @@ -14,6 +15,7 @@ import { import { BullModule } from '@nestjs/bull'; import { Module } from '@nestjs/common'; import { ConfigModule } from '@nestjs/config'; +import { EventEmitterModule } from '@nestjs/event-emitter'; import { ScheduleModule } from '@nestjs/schedule'; import { ServeStaticModule } from '@nestjs/serve-static'; import { StatusCodes } from 'http-status-codes'; @@ -44,6 +46,7 @@ import { TagModule } from './tag/tag.module'; import { UserModule } from './user/user.module'; @Module({ + controllers: [AppController], imports: [ AdminModule, AccessModule, @@ -64,6 +67,8 @@ import { UserModule } from './user/user.module'; ConfigurationModule, DataGatheringModule, DataProviderModule, + EventEmitterModule.forRoot(), + EventsModule, ExchangeRateModule, ExchangeRateDataModule, ExportModule, @@ -109,7 +114,6 @@ import { UserModule } from './user/user.module'; TwitterBotModule, UserModule ], - controllers: [AppController], providers: [CronService] }) export class AppModule {} diff --git a/apps/api/src/app/order/order.controller.ts b/apps/api/src/app/order/order.controller.ts index 3dadedcaf..4a85dce57 100644 --- a/apps/api/src/app/order/order.controller.ts +++ b/apps/api/src/app/order/order.controller.ts @@ -60,15 +60,15 @@ export class OrderController { } @Delete(':id') + @HasPermission(permissions.deleteOrder) @UseGuards(AuthGuard('jwt'), HasPermissionGuard) public async deleteOrder(@Param('id') id: string): Promise { - const order = await this.orderService.order({ id }); + const order = await this.orderService.order({ + id, + userId: this.request.user.id + }); - if ( - !hasPermission(this.request.user.permissions, permissions.deleteOrder) || - !order || - order.userId !== this.request.user.id - ) { + if (!order) { throw new HttpException( getReasonPhrase(StatusCodes.FORBIDDEN), StatusCodes.FORBIDDEN diff --git a/apps/api/src/app/order/order.service.ts b/apps/api/src/app/order/order.service.ts index 35bfa1bcf..a78daa143 100644 --- a/apps/api/src/app/order/order.service.ts +++ b/apps/api/src/app/order/order.service.ts @@ -1,4 +1,5 @@ import { AccountService } from '@ghostfolio/api/app/account/account.service'; +import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event'; import { DataGatheringService } from '@ghostfolio/api/services/data-gathering/data-gathering.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; @@ -13,6 +14,7 @@ import { Filter, UniqueAsset } from '@ghostfolio/common/interfaces'; import { OrderWithAccount } from '@ghostfolio/common/types'; import { Injectable } from '@nestjs/common'; +import { EventEmitter2 } from '@nestjs/event-emitter'; import { AssetClass, AssetSubClass, @@ -27,7 +29,6 @@ import { endOfToday, isAfter } from 'date-fns'; import { groupBy, uniqBy } from 'lodash'; import { v4 as uuidv4 } from 'uuid'; -import { CreateOrderDto } from './create-order.dto'; import { Activities } from './interfaces/activities.interface'; @Injectable() @@ -35,6 +36,7 @@ export class OrderService { public constructor( private readonly accountService: AccountService, private readonly dataGatheringService: DataGatheringService, + private readonly eventEmitter: EventEmitter2, private readonly exchangeRateDataService: ExchangeRateDataService, private readonly prismaService: PrismaService, private readonly symbolProfileService: SymbolProfileService @@ -160,6 +162,13 @@ export class OrderService { }); } + this.eventEmitter.emit( + PortfolioChangedEvent.getName(), + new PortfolioChangedEvent({ + userId: order.userId + }) + ); + return order; } @@ -174,6 +183,13 @@ export class OrderService { await this.symbolProfileService.deleteById(order.symbolProfileId); } + this.eventEmitter.emit( + PortfolioChangedEvent.getName(), + new PortfolioChangedEvent({ + userId: order.userId + }) + ); + return order; } @@ -182,6 +198,13 @@ export class OrderService { where }); + this.eventEmitter.emit( + PortfolioChangedEvent.getName(), + new PortfolioChangedEvent({ + userId: where.userId + }) + ); + return count; } @@ -455,7 +478,7 @@ export class OrderService { where }); - return this.prismaService.order.update({ + const order = await this.prismaService.order.update({ data: { ...data, isDraft, @@ -467,6 +490,15 @@ export class OrderService { }, where }); + + this.eventEmitter.emit( + PortfolioChangedEvent.getName(), + new PortfolioChangedEvent({ + userId: order.userId + }) + ); + + return order; } private async orders(params: { diff --git a/apps/api/src/app/user/user.service.ts b/apps/api/src/app/user/user.service.ts index 4cc60770f..3a370d88a 100644 --- a/apps/api/src/app/user/user.service.ts +++ b/apps/api/src/app/user/user.service.ts @@ -1,5 +1,6 @@ import { SubscriptionService } from '@ghostfolio/api/app/subscription/subscription.service'; import { environment } from '@ghostfolio/api/environments/environment'; +import { PortfolioChangedEvent } from '@ghostfolio/api/events/portfolio-changed.event'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { I18nService } from '@ghostfolio/api/services/i18n/i18n.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; @@ -25,6 +26,7 @@ import { import { UserWithSettings } from '@ghostfolio/common/types'; import { Injectable } from '@nestjs/common'; +import { EventEmitter2 } from '@nestjs/event-emitter'; import { Prisma, Role, User } from '@prisma/client'; import { differenceInDays } from 'date-fns'; import { sortBy, without } from 'lodash'; @@ -37,6 +39,7 @@ export class UserService { public constructor( private readonly configurationService: ConfigurationService, + private readonly eventEmitter: EventEmitter2, private readonly prismaService: PrismaService, private readonly propertyService: PropertyService, private readonly subscriptionService: SubscriptionService, @@ -437,11 +440,9 @@ export class UserService { userId: string; userSettings: UserSettings; }) { - const settings = userSettings as unknown as Prisma.JsonObject; - - await this.prismaService.settings.upsert({ + const { settings } = await this.prismaService.settings.upsert({ create: { - settings, + settings: userSettings as unknown as Prisma.JsonObject, User: { connect: { id: userId @@ -449,14 +450,21 @@ export class UserService { } }, update: { - settings + settings: userSettings as unknown as Prisma.JsonObject }, where: { userId } }); - return; + this.eventEmitter.emit( + PortfolioChangedEvent.getName(), + new PortfolioChangedEvent({ + userId + }) + ); + + return settings; } private getRandomString(length: number) { diff --git a/apps/api/src/events/events.module.ts b/apps/api/src/events/events.module.ts new file mode 100644 index 000000000..bf9708f4b --- /dev/null +++ b/apps/api/src/events/events.module.ts @@ -0,0 +1,8 @@ +import { Module } from '@nestjs/common'; + +import { PortfolioChangedListener } from './portfolio-changed.listener'; + +@Module({ + providers: [PortfolioChangedListener] +}) +export class EventsModule {} diff --git a/apps/api/src/events/portfolio-changed.event.ts b/apps/api/src/events/portfolio-changed.event.ts new file mode 100644 index 000000000..a3b0710fb --- /dev/null +++ b/apps/api/src/events/portfolio-changed.event.ts @@ -0,0 +1,15 @@ +export class PortfolioChangedEvent { + private userId: string; + + public constructor({ userId }: { userId: string }) { + this.userId = userId; + } + + public static getName() { + return 'portfolio.changed'; + } + + public getUserId() { + return this.userId; + } +} diff --git a/apps/api/src/events/portfolio-changed.listener.ts b/apps/api/src/events/portfolio-changed.listener.ts new file mode 100644 index 000000000..3dd856084 --- /dev/null +++ b/apps/api/src/events/portfolio-changed.listener.ts @@ -0,0 +1,15 @@ +import { Injectable, Logger } from '@nestjs/common'; +import { OnEvent } from '@nestjs/event-emitter'; + +import { PortfolioChangedEvent } from './portfolio-changed.event'; + +@Injectable() +export class PortfolioChangedListener { + @OnEvent(PortfolioChangedEvent.getName()) + handlePortfolioChangedEvent(event: PortfolioChangedEvent) { + Logger.log( + `Portfolio of user with id ${event.getUserId()} has changed`, + 'PortfolioChangedListener' + ); + } +} diff --git a/package.json b/package.json index 8b036f588..690918edf 100644 --- a/package.json +++ b/package.json @@ -78,6 +78,7 @@ "@nestjs/common": "10.1.3", "@nestjs/config": "3.0.0", "@nestjs/core": "10.1.3", + "@nestjs/event-emitter": "2.0.4", "@nestjs/jwt": "10.1.0", "@nestjs/passport": "10.0.0", "@nestjs/platform-express": "10.1.3", diff --git a/yarn.lock b/yarn.lock index 5dd3bcd98..f5fd0d164 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4814,6 +4814,13 @@ path-to-regexp "3.2.0" tslib "2.6.1" +"@nestjs/event-emitter@2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@nestjs/event-emitter/-/event-emitter-2.0.4.tgz#de7d3986cfeb82639bb95181fab4fe5525437c74" + integrity sha512-quMiw8yOwoSul0pp3mOonGz8EyXWHSBTqBy8B0TbYYgpnG1Ix2wGUnuTksLWaaBiiOTDhciaZ41Y5fJZsSJE1Q== + dependencies: + eventemitter2 "6.4.9" + "@nestjs/jwt@10.1.0": version "10.1.0" resolved "https://registry.yarnpkg.com/@nestjs/jwt/-/jwt-10.1.0.tgz#7899b68d68b998cc140bc0af392c63fc00755236" @@ -11653,7 +11660,7 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== -eventemitter2@^6.4.2: +eventemitter2@6.4.9, eventemitter2@^6.4.2: version "6.4.9" resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.9.tgz#41f2750781b4230ed58827bc119d293471ecb125" integrity sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg== From cd07802400301f2ab3f2f4b3ef9e6ff7a416bf18 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 27 Apr 2024 15:29:32 +0200 Subject: [PATCH 164/203] Bugfix/fix historical market data gathering for asset profiles with manual data source (#3336) * Fix historical market data gathering for asset profiles with MANUAL data source * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/import/import.service.ts | 5 +++++ apps/api/src/app/order/order.service.ts | 3 ++- apps/api/src/services/data-provider/manual/manual.service.ts | 2 +- 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18e38e100..e558f5afd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fixed the form submit in the asset profile details dialog of the admin control due to the `url` validation +- Fixed the historical market data gathering for asset profiles with `MANUAL` data source ## 2.76.0 - 2024-04-23 diff --git a/apps/api/src/app/import/import.service.ts b/apps/api/src/app/import/import.service.ts index 26df9d069..a1ddeb482 100644 --- a/apps/api/src/app/import/import.service.ts +++ b/apps/api/src/app/import/import.service.ts @@ -416,6 +416,11 @@ export class ImportService { User: { connect: { id: user.id } }, userId: user.id }); + + if (order.SymbolProfile?.symbol) { + // Update symbol that may have been assigned in createOrder() + assetProfile.symbol = order.SymbolProfile.symbol; + } } const value = new Big(quantity).mul(unitPrice).toNumber(); diff --git a/apps/api/src/app/order/order.service.ts b/apps/api/src/app/order/order.service.ts index a78daa143..e976fc80d 100644 --- a/apps/api/src/app/order/order.service.ts +++ b/apps/api/src/app/order/order.service.ts @@ -140,7 +140,8 @@ export class OrderService { return { id }; }) } - } + }, + include: { SymbolProfile: true } }); if (updateAccountBalance === true) { diff --git a/apps/api/src/services/data-provider/manual/manual.service.ts b/apps/api/src/services/data-provider/manual/manual.service.ts index 4ff3ba653..5066a4d3a 100644 --- a/apps/api/src/services/data-provider/manual/manual.service.ts +++ b/apps/api/src/services/data-provider/manual/manual.service.ts @@ -91,7 +91,7 @@ export class ManualService implements DataProviderInterface { headers = {}, selector, url - } = symbolProfile.scraperConfiguration ?? {}; + } = symbolProfile?.scraperConfiguration ?? {}; if (defaultMarketPrice) { const historical: { From 4f41bac3288595ec9a8e3190aeadffd30df3892b Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 27 Apr 2024 15:35:28 +0200 Subject: [PATCH 165/203] Feature/set up caching in portfolio calculator (#3335) * Set up caching * Update changelog --- CHANGELOG.md | 2 +- .../calculator/mwr/portfolio-calculator.ts | 8 +- .../portfolio-calculator-test-utils.ts | 4 + .../portfolio-calculator.factory.ts | 26 ++++- .../calculator/portfolio-calculator.ts | 108 +++++++++++++++--- ...aln-buy-and-sell-in-two-activities.spec.ts | 28 ++++- ...folio-calculator-baln-buy-and-sell.spec.ts | 28 ++++- .../twr/portfolio-calculator-baln-buy.spec.ts | 28 ++++- ...ator-btcusd-buy-and-sell-partially.spec.ts | 28 ++++- .../twr/portfolio-calculator-fee.spec.ts | 28 ++++- .../portfolio-calculator-googl-buy.spec.ts | 28 ++++- .../twr/portfolio-calculator-item.spec.ts | 28 ++++- .../portfolio-calculator-liability.spec.ts | 28 ++++- ...-calculator-msft-buy-with-dividend.spec.ts | 28 ++++- .../portfolio-calculator-no-orders.spec.ts | 26 ++++- ...ulator-novn-buy-and-sell-partially.spec.ts | 28 ++++- ...folio-calculator-novn-buy-and-sell.spec.ts | 28 ++++- .../twr/portfolio-calculator.spec.ts | 12 +- .../calculator/twr/portfolio-calculator.ts | 8 +- .../portfolio-snapshot.interface.ts | 24 ---- .../api/src/app/portfolio/portfolio.module.ts | 2 + .../src/app/portfolio/portfolio.service.ts | 34 ++++-- .../redis-cache/redis-cache.service.mock.ts | 13 +++ .../app/redis-cache/redis-cache.service.ts | 4 + apps/api/src/events/events.module.ts | 3 + .../src/events/portfolio-changed.listener.ts | 8 ++ apps/api/src/models/rule.ts | 3 +- .../base-currency-current-investment.ts | 3 +- .../current-investment.ts | 3 +- .../data-provider/data-provider.service.ts | 13 ++- libs/common/src/lib/class-transformer.ts | 9 ++ libs/common/src/lib/interfaces/index.ts | 2 - .../interfaces/timeline-position.interface.ts | 31 ----- libs/common/src/lib/models/index.ts | 4 + .../src/lib/models/portfolio-snapshot.ts | 82 +++++++++++++ .../src/lib/models/timeline-position.ts | 92 +++++++++++++++ 36 files changed, 687 insertions(+), 145 deletions(-) delete mode 100644 apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts create mode 100644 apps/api/src/app/redis-cache/redis-cache.service.mock.ts create mode 100644 libs/common/src/lib/class-transformer.ts delete mode 100644 libs/common/src/lib/interfaces/timeline-position.interface.ts create mode 100644 libs/common/src/lib/models/index.ts create mode 100644 libs/common/src/lib/models/portfolio-snapshot.ts create mode 100644 libs/common/src/lib/models/timeline-position.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index e558f5afd..d718476d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Extended the content of the _Self-Hosting_ section by the custom asset instructions on the Frequently Asked Questions (FAQ) page -- Set up an event system to follow portfolio changes +- Added the caching to the portfolio calculator (experimental) ### Changed diff --git a/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts index 978f1f3aa..5d168b619 100644 --- a/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/mwr/portfolio-calculator.ts @@ -1,10 +1,6 @@ import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; -import { PortfolioSnapshot } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-snapshot.interface'; -import { - SymbolMetrics, - TimelinePosition, - UniqueAsset -} from '@ghostfolio/common/interfaces'; +import { SymbolMetrics, UniqueAsset } from '@ghostfolio/common/interfaces'; +import { PortfolioSnapshot, TimelinePosition } from '@ghostfolio/common/models'; export class MWRPortfolioCalculator extends PortfolioCalculator { protected calculateOverallPerformance( diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts index 504b5b171..51ad40c31 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator-test-utils.ts @@ -24,3 +24,7 @@ export const symbolProfileDummyData = { sectors: [], updatedAt: undefined }; + +export const userDummyData = { + id: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' +}; diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts index a75ce9b62..4937f1008 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts @@ -1,8 +1,10 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; +import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { HistoricalDataItem } from '@ghostfolio/common/interfaces'; -import { DateRange } from '@ghostfolio/common/types'; +import { DateRange, UserWithSettings } from '@ghostfolio/common/types'; import { Injectable } from '@nestjs/common'; @@ -18,8 +20,10 @@ export enum PerformanceCalculationType { @Injectable() export class PortfolioCalculatorFactory { public constructor( + private readonly configurationService: ConfigurationService, private readonly currentRateService: CurrentRateService, - private readonly exchangeRateDataService: ExchangeRateDataService + private readonly exchangeRateDataService: ExchangeRateDataService, + private readonly redisCacheService: RedisCacheService ) {} public createCalculator({ @@ -27,13 +31,17 @@ export class PortfolioCalculatorFactory { activities, calculationType, currency, - dateRange = 'max' + dateRange = 'max', + isExperimentalFeatures = false, + userId }: { accountBalanceItems?: HistoricalDataItem[]; activities: Activity[]; calculationType: PerformanceCalculationType; currency: string; dateRange?: DateRange; + isExperimentalFeatures?: boolean; + userId: string; }): PortfolioCalculator { switch (calculationType) { case PerformanceCalculationType.MWR: @@ -42,8 +50,12 @@ export class PortfolioCalculatorFactory { activities, currency, dateRange, + isExperimentalFeatures, + userId, + configurationService: this.configurationService, currentRateService: this.currentRateService, - exchangeRateDataService: this.exchangeRateDataService + exchangeRateDataService: this.exchangeRateDataService, + redisCacheService: this.redisCacheService }); case PerformanceCalculationType.TWR: return new TWRPortfolioCalculator({ @@ -52,7 +64,11 @@ export class PortfolioCalculatorFactory { currency, currentRateService: this.currentRateService, dateRange, - exchangeRateDataService: this.exchangeRateDataService + isExperimentalFeatures, + userId, + configurationService: this.configurationService, + exchangeRateDataService: this.exchangeRateDataService, + redisCacheService: this.redisCacheService }); default: throw new Error('Invalid calculation type'); diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index 54e474779..ba9833948 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -1,13 +1,14 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { PortfolioOrder } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order.interface'; -import { PortfolioSnapshot } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-snapshot.interface'; import { TransactionPointSymbol } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point-symbol.interface'; import { TransactionPoint } from '@ghostfolio/api/app/portfolio/interfaces/transaction-point.interface'; +import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; import { getFactor, getInterval } from '@ghostfolio/api/helper/portfolio.helper'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { IDataGatheringItem } from '@ghostfolio/api/services/interfaces/interfaces'; import { MAX_CHART_ITEMS } from '@ghostfolio/common/config'; @@ -23,12 +24,14 @@ import { InvestmentItem, ResponseError, SymbolMetrics, - TimelinePosition, UniqueAsset } from '@ghostfolio/common/interfaces'; +import { PortfolioSnapshot, TimelinePosition } from '@ghostfolio/common/models'; import { DateRange, GroupBy } from '@ghostfolio/common/types'; +import { Logger } from '@nestjs/common'; import { Big } from 'big.js'; +import { plainToClass } from 'class-transformer'; import { differenceInDays, eachDayOfInterval, @@ -41,6 +44,7 @@ import { subDays } from 'date-fns'; import { first, last, uniq, uniqBy } from 'lodash'; +import ms from 'ms'; export abstract class PortfolioCalculator { protected static readonly ENABLE_LOGGING = false; @@ -48,52 +52,78 @@ export abstract class PortfolioCalculator { protected accountBalanceItems: HistoricalDataItem[]; protected orders: PortfolioOrder[]; + private configurationService: ConfigurationService; private currency: string; private currentRateService: CurrentRateService; private dataProviderInfos: DataProviderInfo[]; private endDate: Date; private exchangeRateDataService: ExchangeRateDataService; + private isExperimentalFeatures: boolean; + private redisCacheService: RedisCacheService; private snapshot: PortfolioSnapshot; private snapshotPromise: Promise; private startDate: Date; private transactionPoints: TransactionPoint[]; + private userId: string; public constructor({ accountBalanceItems, activities, + configurationService, currency, currentRateService, dateRange, - exchangeRateDataService + exchangeRateDataService, + isExperimentalFeatures, + redisCacheService, + userId }: { accountBalanceItems: HistoricalDataItem[]; activities: Activity[]; + configurationService: ConfigurationService; currency: string; currentRateService: CurrentRateService; dateRange: DateRange; exchangeRateDataService: ExchangeRateDataService; + isExperimentalFeatures: boolean; + redisCacheService: RedisCacheService; + userId: string; }) { this.accountBalanceItems = accountBalanceItems; + this.configurationService = configurationService; this.currency = currency; this.currentRateService = currentRateService; this.exchangeRateDataService = exchangeRateDataService; - this.orders = activities.map( - ({ date, fee, quantity, SymbolProfile, tags = [], type, unitPrice }) => { - return { + this.isExperimentalFeatures = isExperimentalFeatures; + + this.orders = activities + .map( + ({ + date, + fee, + quantity, SymbolProfile, - tags, + tags = [], type, - date: format(date, DATE_FORMAT), - fee: new Big(fee), - quantity: new Big(quantity), - unitPrice: new Big(unitPrice) - }; - } - ); + unitPrice + }) => { + return { + SymbolProfile, + tags, + type, + date: format(date, DATE_FORMAT), + fee: new Big(fee), + quantity: new Big(quantity), + unitPrice: new Big(unitPrice) + }; + } + ) + .sort((a, b) => { + return a.date?.localeCompare(b.date); + }); - this.orders.sort((a, b) => { - return a.date?.localeCompare(b.date); - }); + this.redisCacheService = redisCacheService; + this.userId = userId; const { endDate, startDate } = getInterval(dateRange); @@ -1011,6 +1041,48 @@ export abstract class PortfolioCalculator { } private async initialize() { - this.snapshot = await this.computeSnapshot(this.startDate, this.endDate); + if (this.isExperimentalFeatures) { + const startTimeTotal = performance.now(); + + const cachedSnapshot = await this.redisCacheService.get( + this.redisCacheService.getPortfolioSnapshotKey(this.userId) + ); + + if (cachedSnapshot) { + this.snapshot = plainToClass( + PortfolioSnapshot, + JSON.parse(cachedSnapshot) + ); + + Logger.debug( + `Fetched portfolio snapshot from cache in ${( + (performance.now() - startTimeTotal) / + 1000 + ).toFixed(3)} seconds`, + 'PortfolioCalculator' + ); + } else { + this.snapshot = await this.computeSnapshot( + this.startDate, + this.endDate + ); + + this.redisCacheService.set( + this.redisCacheService.getPortfolioSnapshotKey(this.userId), + JSON.stringify(this.snapshot), + this.configurationService.get('CACHE_QUOTES_TTL') + ); + + Logger.debug( + `Computed portfolio snapshot in ${( + (performance.now() - startTimeTotal) / + 1000 + ).toFixed(3)} seconds`, + 'PortfolioCalculator' + ); + } + } else { + this.snapshot = await this.computeSnapshot(this.startDate, this.endDate); + } } } diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts index a11ae8896..422cf8bff 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts @@ -1,7 +1,8 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { activityDummyData, - symbolProfileDummyData + symbolProfileDummyData, + userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; import { PortfolioCalculatorFactory, @@ -9,6 +10,9 @@ import { } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; +import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; +import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { parseDate } from '@ghostfolio/common/helper'; @@ -23,12 +27,25 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { }; }); +jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + RedisCacheService: jest.fn().mockImplementation(() => { + return RedisCacheServiceMock; + }) + }; +}); + describe('PortfolioCalculator', () => { + let configurationService: ConfigurationService; let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; let factory: PortfolioCalculatorFactory; + let redisCacheService: RedisCacheService; beforeEach(() => { + configurationService = new ConfigurationService(); + currentRateService = new CurrentRateService(null, null, null, null); exchangeRateDataService = new ExchangeRateDataService( @@ -38,9 +55,13 @@ describe('PortfolioCalculator', () => { null ); + redisCacheService = new RedisCacheService(null, null); + factory = new PortfolioCalculatorFactory( + configurationService, currentRateService, - exchangeRateDataService + exchangeRateDataService, + redisCacheService ); }); @@ -101,7 +122,8 @@ describe('PortfolioCalculator', () => { const portfolioCalculator = factory.createCalculator({ activities, calculationType: PerformanceCalculationType.TWR, - currency: 'CHF' + currency: 'CHF', + userId: userDummyData.id }); const chartData = await portfolioCalculator.getChartData({ diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts index 8d93d8b97..dee8b2478 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts @@ -1,7 +1,8 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { activityDummyData, - symbolProfileDummyData + symbolProfileDummyData, + userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; import { PerformanceCalculationType, @@ -9,6 +10,9 @@ import { } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; +import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; +import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { parseDate } from '@ghostfolio/common/helper'; @@ -23,12 +27,25 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { }; }); +jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + RedisCacheService: jest.fn().mockImplementation(() => { + return RedisCacheServiceMock; + }) + }; +}); + describe('PortfolioCalculator', () => { + let configurationService: ConfigurationService; let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; let factory: PortfolioCalculatorFactory; + let redisCacheService: RedisCacheService; beforeEach(() => { + configurationService = new ConfigurationService(); + currentRateService = new CurrentRateService(null, null, null, null); exchangeRateDataService = new ExchangeRateDataService( @@ -38,9 +55,13 @@ describe('PortfolioCalculator', () => { null ); + redisCacheService = new RedisCacheService(null, null); + factory = new PortfolioCalculatorFactory( + configurationService, currentRateService, - exchangeRateDataService + exchangeRateDataService, + redisCacheService ); }); @@ -86,7 +107,8 @@ describe('PortfolioCalculator', () => { const portfolioCalculator = factory.createCalculator({ activities, calculationType: PerformanceCalculationType.TWR, - currency: 'CHF' + currency: 'CHF', + userId: userDummyData.id }); const chartData = await portfolioCalculator.getChartData({ diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts index f26331134..db8ce01b3 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts @@ -1,7 +1,8 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { activityDummyData, - symbolProfileDummyData + symbolProfileDummyData, + userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; import { PortfolioCalculatorFactory, @@ -9,6 +10,9 @@ import { } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; +import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; +import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { parseDate } from '@ghostfolio/common/helper'; @@ -23,12 +27,25 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { }; }); +jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + RedisCacheService: jest.fn().mockImplementation(() => { + return RedisCacheServiceMock; + }) + }; +}); + describe('PortfolioCalculator', () => { + let configurationService: ConfigurationService; let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; let factory: PortfolioCalculatorFactory; + let redisCacheService: RedisCacheService; beforeEach(() => { + configurationService = new ConfigurationService(); + currentRateService = new CurrentRateService(null, null, null, null); exchangeRateDataService = new ExchangeRateDataService( @@ -38,9 +55,13 @@ describe('PortfolioCalculator', () => { null ); + redisCacheService = new RedisCacheService(null, null); + factory = new PortfolioCalculatorFactory( + configurationService, currentRateService, - exchangeRateDataService + exchangeRateDataService, + redisCacheService ); }); @@ -71,7 +92,8 @@ describe('PortfolioCalculator', () => { const portfolioCalculator = factory.createCalculator({ activities, calculationType: PerformanceCalculationType.TWR, - currency: 'CHF' + currency: 'CHF', + userId: userDummyData.id }); const chartData = await portfolioCalculator.getChartData({ diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts index 2a9ba0916..5a403eda1 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts @@ -1,7 +1,8 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { activityDummyData, - symbolProfileDummyData + symbolProfileDummyData, + userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; import { PortfolioCalculatorFactory, @@ -9,6 +10,9 @@ import { } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; +import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; +import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { ExchangeRateDataServiceMock } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service.mock'; import { parseDate } from '@ghostfolio/common/helper'; @@ -24,6 +28,15 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { }; }); +jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + RedisCacheService: jest.fn().mockImplementation(() => { + return RedisCacheServiceMock; + }) + }; +}); + jest.mock( '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service', () => { @@ -37,11 +50,15 @@ jest.mock( ); describe('PortfolioCalculator', () => { + let configurationService: ConfigurationService; let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; let factory: PortfolioCalculatorFactory; + let redisCacheService: RedisCacheService; beforeEach(() => { + configurationService = new ConfigurationService(); + currentRateService = new CurrentRateService(null, null, null, null); exchangeRateDataService = new ExchangeRateDataService( @@ -51,9 +68,13 @@ describe('PortfolioCalculator', () => { null ); + redisCacheService = new RedisCacheService(null, null); + factory = new PortfolioCalculatorFactory( + configurationService, currentRateService, - exchangeRateDataService + exchangeRateDataService, + redisCacheService ); }); @@ -99,7 +120,8 @@ describe('PortfolioCalculator', () => { const portfolioCalculator = factory.createCalculator({ activities, calculationType: PerformanceCalculationType.TWR, - currency: 'CHF' + currency: 'CHF', + userId: userDummyData.id }); const chartData = await portfolioCalculator.getChartData({ diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts index 83f99e3cb..97a77492b 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts @@ -1,7 +1,8 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { activityDummyData, - symbolProfileDummyData + symbolProfileDummyData, + userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; import { PortfolioCalculatorFactory, @@ -9,6 +10,9 @@ import { } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; +import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; +import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { parseDate } from '@ghostfolio/common/helper'; @@ -23,12 +27,25 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { }; }); +jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + RedisCacheService: jest.fn().mockImplementation(() => { + return RedisCacheServiceMock; + }) + }; +}); + describe('PortfolioCalculator', () => { + let configurationService: ConfigurationService; let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; let factory: PortfolioCalculatorFactory; + let redisCacheService: RedisCacheService; beforeEach(() => { + configurationService = new ConfigurationService(); + currentRateService = new CurrentRateService(null, null, null, null); exchangeRateDataService = new ExchangeRateDataService( @@ -38,9 +55,13 @@ describe('PortfolioCalculator', () => { null ); + redisCacheService = new RedisCacheService(null, null); + factory = new PortfolioCalculatorFactory( + configurationService, currentRateService, - exchangeRateDataService + exchangeRateDataService, + redisCacheService ); }); @@ -71,7 +92,8 @@ describe('PortfolioCalculator', () => { const portfolioCalculator = factory.createCalculator({ activities, calculationType: PerformanceCalculationType.TWR, - currency: 'USD' + currency: 'USD', + userId: userDummyData.id }); const portfolioSnapshot = await portfolioCalculator.computeSnapshot( diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts index 0642b28ed..c916a381d 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts @@ -1,7 +1,8 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { activityDummyData, - symbolProfileDummyData + symbolProfileDummyData, + userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; import { PortfolioCalculatorFactory, @@ -9,6 +10,9 @@ import { } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; +import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; +import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { ExchangeRateDataServiceMock } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service.mock'; import { parseDate } from '@ghostfolio/common/helper'; @@ -24,6 +28,15 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { }; }); +jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + RedisCacheService: jest.fn().mockImplementation(() => { + return RedisCacheServiceMock; + }) + }; +}); + jest.mock( '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service', () => { @@ -37,11 +50,15 @@ jest.mock( ); describe('PortfolioCalculator', () => { + let configurationService: ConfigurationService; let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; let factory: PortfolioCalculatorFactory; + let redisCacheService: RedisCacheService; beforeEach(() => { + configurationService = new ConfigurationService(); + currentRateService = new CurrentRateService(null, null, null, null); exchangeRateDataService = new ExchangeRateDataService( @@ -51,9 +68,13 @@ describe('PortfolioCalculator', () => { null ); + redisCacheService = new RedisCacheService(null, null); + factory = new PortfolioCalculatorFactory( + configurationService, currentRateService, - exchangeRateDataService + exchangeRateDataService, + redisCacheService ); }); @@ -84,7 +105,8 @@ describe('PortfolioCalculator', () => { const portfolioCalculator = factory.createCalculator({ activities, calculationType: PerformanceCalculationType.TWR, - currency: 'CHF' + currency: 'CHF', + userId: userDummyData.id }); const chartData = await portfolioCalculator.getChartData({ diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-item.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-item.spec.ts index b8ef6954e..bf212f80b 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-item.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-item.spec.ts @@ -1,7 +1,8 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { activityDummyData, - symbolProfileDummyData + symbolProfileDummyData, + userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; import { PortfolioCalculatorFactory, @@ -9,6 +10,9 @@ import { } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; +import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; +import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { parseDate } from '@ghostfolio/common/helper'; @@ -23,12 +27,25 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { }; }); +jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + RedisCacheService: jest.fn().mockImplementation(() => { + return RedisCacheServiceMock; + }) + }; +}); + describe('PortfolioCalculator', () => { + let configurationService: ConfigurationService; let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; let factory: PortfolioCalculatorFactory; + let redisCacheService: RedisCacheService; beforeEach(() => { + configurationService = new ConfigurationService(); + currentRateService = new CurrentRateService(null, null, null, null); exchangeRateDataService = new ExchangeRateDataService( @@ -38,9 +55,13 @@ describe('PortfolioCalculator', () => { null ); + redisCacheService = new RedisCacheService(null, null); + factory = new PortfolioCalculatorFactory( + configurationService, currentRateService, - exchangeRateDataService + exchangeRateDataService, + redisCacheService ); }); @@ -71,7 +92,8 @@ describe('PortfolioCalculator', () => { const portfolioCalculator = factory.createCalculator({ activities, calculationType: PerformanceCalculationType.TWR, - currency: 'USD' + currency: 'USD', + userId: userDummyData.id }); const portfolioSnapshot = await portfolioCalculator.computeSnapshot( diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts index 9ef369c8f..fc858f293 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts @@ -1,7 +1,8 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { activityDummyData, - symbolProfileDummyData + symbolProfileDummyData, + userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; import { PortfolioCalculatorFactory, @@ -9,6 +10,9 @@ import { } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; +import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; +import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { parseDate } from '@ghostfolio/common/helper'; @@ -23,12 +27,25 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { }; }); +jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + RedisCacheService: jest.fn().mockImplementation(() => { + return RedisCacheServiceMock; + }) + }; +}); + describe('PortfolioCalculator', () => { + let configurationService: ConfigurationService; let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; let factory: PortfolioCalculatorFactory; + let redisCacheService: RedisCacheService; beforeEach(() => { + configurationService = new ConfigurationService(); + currentRateService = new CurrentRateService(null, null, null, null); exchangeRateDataService = new ExchangeRateDataService( @@ -38,9 +55,13 @@ describe('PortfolioCalculator', () => { null ); + redisCacheService = new RedisCacheService(null, null); + factory = new PortfolioCalculatorFactory( + configurationService, currentRateService, - exchangeRateDataService + exchangeRateDataService, + redisCacheService ); }); @@ -71,7 +92,8 @@ describe('PortfolioCalculator', () => { const portfolioCalculator = factory.createCalculator({ activities, calculationType: PerformanceCalculationType.TWR, - currency: 'USD' + currency: 'USD', + userId: userDummyData.id }); const portfolioSnapshot = await portfolioCalculator.computeSnapshot( diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts index e50ce4194..6948b4dbd 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts @@ -1,7 +1,8 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { activityDummyData, - symbolProfileDummyData + symbolProfileDummyData, + userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; import { PerformanceCalculationType, @@ -9,6 +10,9 @@ import { } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; +import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; +import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { ExchangeRateDataServiceMock } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service.mock'; import { parseDate } from '@ghostfolio/common/helper'; @@ -24,6 +28,15 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { }; }); +jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + RedisCacheService: jest.fn().mockImplementation(() => { + return RedisCacheServiceMock; + }) + }; +}); + jest.mock( '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service', () => { @@ -37,11 +50,15 @@ jest.mock( ); describe('PortfolioCalculator', () => { + let configurationService: ConfigurationService; let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; let factory: PortfolioCalculatorFactory; + let redisCacheService: RedisCacheService; beforeEach(() => { + configurationService = new ConfigurationService(); + currentRateService = new CurrentRateService(null, null, null, null); exchangeRateDataService = new ExchangeRateDataService( @@ -51,9 +68,13 @@ describe('PortfolioCalculator', () => { null ); + redisCacheService = new RedisCacheService(null, null); + factory = new PortfolioCalculatorFactory( + configurationService, currentRateService, - exchangeRateDataService + exchangeRateDataService, + redisCacheService ); }); @@ -99,7 +120,8 @@ describe('PortfolioCalculator', () => { const portfolioCalculator = factory.createCalculator({ activities, calculationType: PerformanceCalculationType.TWR, - currency: 'USD' + currency: 'USD', + userId: userDummyData.id }); const portfolioSnapshot = await portfolioCalculator.computeSnapshot( diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts index bd04d6045..1dd74d7e5 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts @@ -1,9 +1,13 @@ +import { userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; import { PerformanceCalculationType, PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; +import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; +import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { parseDate } from '@ghostfolio/common/helper'; @@ -19,12 +23,25 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { }; }); +jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + RedisCacheService: jest.fn().mockImplementation(() => { + return RedisCacheServiceMock; + }) + }; +}); + describe('PortfolioCalculator', () => { + let configurationService: ConfigurationService; let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; let factory: PortfolioCalculatorFactory; + let redisCacheService: RedisCacheService; beforeEach(() => { + configurationService = new ConfigurationService(); + currentRateService = new CurrentRateService(null, null, null, null); exchangeRateDataService = new ExchangeRateDataService( @@ -34,9 +51,13 @@ describe('PortfolioCalculator', () => { null ); + redisCacheService = new RedisCacheService(null, null); + factory = new PortfolioCalculatorFactory( + configurationService, currentRateService, - exchangeRateDataService + exchangeRateDataService, + redisCacheService ); }); @@ -49,7 +70,8 @@ describe('PortfolioCalculator', () => { const portfolioCalculator = factory.createCalculator({ activities: [], calculationType: PerformanceCalculationType.TWR, - currency: 'CHF' + currency: 'CHF', + userId: userDummyData.id }); const start = subDays(new Date(Date.now()), 10); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts index 3d63f1a5d..d4451503a 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts @@ -1,7 +1,8 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { activityDummyData, - symbolProfileDummyData + symbolProfileDummyData, + userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; import { PerformanceCalculationType, @@ -9,6 +10,9 @@ import { } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; +import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; +import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { parseDate } from '@ghostfolio/common/helper'; @@ -23,12 +27,25 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { }; }); +jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + RedisCacheService: jest.fn().mockImplementation(() => { + return RedisCacheServiceMock; + }) + }; +}); + describe('PortfolioCalculator', () => { + let configurationService: ConfigurationService; let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; let factory: PortfolioCalculatorFactory; + let redisCacheService: RedisCacheService; beforeEach(() => { + configurationService = new ConfigurationService(); + currentRateService = new CurrentRateService(null, null, null, null); exchangeRateDataService = new ExchangeRateDataService( @@ -38,9 +55,13 @@ describe('PortfolioCalculator', () => { null ); + redisCacheService = new RedisCacheService(null, null); + factory = new PortfolioCalculatorFactory( + configurationService, currentRateService, - exchangeRateDataService + exchangeRateDataService, + redisCacheService ); }); @@ -86,7 +107,8 @@ describe('PortfolioCalculator', () => { const portfolioCalculator = factory.createCalculator({ activities, calculationType: PerformanceCalculationType.TWR, - currency: 'CHF' + currency: 'CHF', + userId: userDummyData.id }); const chartData = await portfolioCalculator.getChartData({ diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts index 0dd16b045..7850fb2bd 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts @@ -1,7 +1,8 @@ import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { activityDummyData, - symbolProfileDummyData + symbolProfileDummyData, + userDummyData } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator-test-utils'; import { PerformanceCalculationType, @@ -9,6 +10,9 @@ import { } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; import { CurrentRateServiceMock } from '@ghostfolio/api/app/portfolio/current-rate.service.mock'; +import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; +import { RedisCacheServiceMock } from '@ghostfolio/api/app/redis-cache/redis-cache.service.mock'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { parseDate } from '@ghostfolio/common/helper'; @@ -23,12 +27,25 @@ jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { }; }); +jest.mock('@ghostfolio/api/app/redis-cache/redis-cache.service', () => { + return { + // eslint-disable-next-line @typescript-eslint/naming-convention + RedisCacheService: jest.fn().mockImplementation(() => { + return RedisCacheServiceMock; + }) + }; +}); + describe('PortfolioCalculator', () => { + let configurationService: ConfigurationService; let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; let factory: PortfolioCalculatorFactory; + let redisCacheService: RedisCacheService; beforeEach(() => { + configurationService = new ConfigurationService(); + currentRateService = new CurrentRateService(null, null, null, null); exchangeRateDataService = new ExchangeRateDataService( @@ -38,9 +55,13 @@ describe('PortfolioCalculator', () => { null ); + redisCacheService = new RedisCacheService(null, null); + factory = new PortfolioCalculatorFactory( + configurationService, currentRateService, - exchangeRateDataService + exchangeRateDataService, + redisCacheService ); }); @@ -86,7 +107,8 @@ describe('PortfolioCalculator', () => { const portfolioCalculator = factory.createCalculator({ activities, calculationType: PerformanceCalculationType.TWR, - currency: 'CHF' + currency: 'CHF', + userId: userDummyData.id }); const chartData = await portfolioCalculator.getChartData({ diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts index 365593846..536581070 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.spec.ts @@ -1,13 +1,19 @@ import { PortfolioCalculatorFactory } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator.factory'; import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; +import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; +import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; describe('PortfolioCalculator', () => { + let configurationService: ConfigurationService; let currentRateService: CurrentRateService; let exchangeRateDataService: ExchangeRateDataService; let factory: PortfolioCalculatorFactory; + let redisCacheService: RedisCacheService; beforeEach(() => { + configurationService = new ConfigurationService(); + currentRateService = new CurrentRateService(null, null, null, null); exchangeRateDataService = new ExchangeRateDataService( @@ -17,9 +23,13 @@ describe('PortfolioCalculator', () => { null ); + redisCacheService = new RedisCacheService(null, null); + factory = new PortfolioCalculatorFactory( + configurationService, currentRateService, - exchangeRateDataService + exchangeRateDataService, + redisCacheService ); }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index 9458fb1bd..f480fdc59 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -1,13 +1,9 @@ import { PortfolioCalculator } from '@ghostfolio/api/app/portfolio/calculator/portfolio-calculator'; import { PortfolioOrderItem } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-order-item.interface'; -import { PortfolioSnapshot } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-snapshot.interface'; import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; import { DATE_FORMAT } from '@ghostfolio/common/helper'; -import { - SymbolMetrics, - TimelinePosition, - UniqueAsset -} from '@ghostfolio/common/interfaces'; +import { SymbolMetrics, UniqueAsset } from '@ghostfolio/common/interfaces'; +import { PortfolioSnapshot, TimelinePosition } from '@ghostfolio/common/models'; import { Logger } from '@nestjs/common'; import { Big } from 'big.js'; diff --git a/apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts b/apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts deleted file mode 100644 index d89734987..000000000 --- a/apps/api/src/app/portfolio/interfaces/portfolio-snapshot.interface.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { ResponseError, TimelinePosition } from '@ghostfolio/common/interfaces'; - -import { Big } from 'big.js'; - -export interface PortfolioSnapshot extends ResponseError { - currentValueInBaseCurrency: Big; - grossPerformance: Big; - grossPerformanceWithCurrencyEffect: Big; - grossPerformancePercentage: Big; - grossPerformancePercentageWithCurrencyEffect: Big; - netAnnualizedPerformance?: Big; - netAnnualizedPerformanceWithCurrencyEffect?: Big; - netPerformance: Big; - netPerformanceWithCurrencyEffect: Big; - netPerformancePercentage: Big; - netPerformancePercentageWithCurrencyEffect: Big; - positions: TimelinePosition[]; - totalFeesWithCurrencyEffect: Big; - totalInterestWithCurrencyEffect: Big; - totalInvestment: Big; - totalInvestmentWithCurrencyEffect: Big; - totalLiabilitiesWithCurrencyEffect: Big; - totalValuablesWithCurrencyEffect: Big; -} diff --git a/apps/api/src/app/portfolio/portfolio.module.ts b/apps/api/src/app/portfolio/portfolio.module.ts index 6b06bf02d..5659f2a7e 100644 --- a/apps/api/src/app/portfolio/portfolio.module.ts +++ b/apps/api/src/app/portfolio/portfolio.module.ts @@ -2,6 +2,7 @@ import { AccessModule } from '@ghostfolio/api/app/access/access.module'; import { AccountBalanceService } from '@ghostfolio/api/app/account-balance/account-balance.service'; import { AccountService } from '@ghostfolio/api/app/account/account.service'; import { OrderModule } from '@ghostfolio/api/app/order/order.module'; +import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module'; import { UserModule } from '@ghostfolio/api/app/user/user.module'; import { ApiModule } from '@ghostfolio/api/services/api/api.module'; import { ConfigurationModule } from '@ghostfolio/api/services/configuration/configuration.module'; @@ -35,6 +36,7 @@ import { RulesService } from './rules.service'; MarketDataModule, OrderModule, PrismaModule, + RedisCacheModule, SymbolProfileModule, UserModule ], diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 4e56f844b..a7e80ce1c 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -29,6 +29,7 @@ import { EnhancedSymbolProfile, Filter, HistoricalDataItem, + InvestmentItem, PortfolioDetails, PortfolioInvestments, PortfolioPerformanceResponse, @@ -36,10 +37,9 @@ import { PortfolioReport, PortfolioSummary, Position, - TimelinePosition, UserSettings } from '@ghostfolio/common/interfaces'; -import { InvestmentItem } from '@ghostfolio/common/interfaces/investment-item.interface'; +import { TimelinePosition } from '@ghostfolio/common/models'; import type { AccountWithValue, DateRange, @@ -277,8 +277,11 @@ export class PortfolioService { const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, + userId, calculationType: PerformanceCalculationType.TWR, - currency: this.request.user.Settings.settings.baseCurrency + currency: this.request.user.Settings.settings.baseCurrency, + isExperimentalFeatures: + this.request.user.Settings.settings.isExperimentalFeatures }); const items = await portfolioCalculator.getChart({ @@ -352,8 +355,11 @@ export class PortfolioService { const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, dateRange, + userId, calculationType: PerformanceCalculationType.TWR, - currency: userCurrency + currency: userCurrency, + isExperimentalFeatures: + this.request.user.Settings.settings.isExperimentalFeatures }); const { currentValueInBaseCurrency, hasErrors, positions } = @@ -648,11 +654,14 @@ export class PortfolioService { ]); const portfolioCalculator = this.calculatorFactory.createCalculator({ + userId, activities: orders.filter((order) => { return ['BUY', 'DIVIDEND', 'ITEM', 'SELL'].includes(order.type); }), calculationType: PerformanceCalculationType.TWR, - currency: userCurrency + currency: userCurrency, + isExperimentalFeatures: + this.request.user.Settings.settings.isExperimentalFeatures }); const portfolioStart = portfolioCalculator.getStartDate(); @@ -919,8 +928,11 @@ export class PortfolioService { const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, dateRange, + userId, calculationType: PerformanceCalculationType.TWR, - currency: this.request.user.Settings.settings.baseCurrency + currency: this.request.user.Settings.settings.baseCurrency, + isExperimentalFeatures: + this.request.user.Settings.settings.isExperimentalFeatures }); let { hasErrors, positions } = await portfolioCalculator.getSnapshot(); @@ -1108,8 +1120,11 @@ export class PortfolioService { accountBalanceItems, activities, dateRange, + userId, calculationType: PerformanceCalculationType.TWR, - currency: userCurrency + currency: userCurrency, + isExperimentalFeatures: + this.request.user.Settings.settings.isExperimentalFeatures }); const { @@ -1202,8 +1217,11 @@ export class PortfolioService { const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, + userId, calculationType: PerformanceCalculationType.TWR, - currency: this.request.user.Settings.settings.baseCurrency + currency: this.request.user.Settings.settings.baseCurrency, + isExperimentalFeatures: + this.request.user.Settings.settings.isExperimentalFeatures }); let { totalFeesWithCurrencyEffect, positions, totalInvestment } = diff --git a/apps/api/src/app/redis-cache/redis-cache.service.mock.ts b/apps/api/src/app/redis-cache/redis-cache.service.mock.ts new file mode 100644 index 000000000..2422e88ab --- /dev/null +++ b/apps/api/src/app/redis-cache/redis-cache.service.mock.ts @@ -0,0 +1,13 @@ +import { RedisCacheService } from './redis-cache.service'; + +export const RedisCacheServiceMock = { + get: (key: string): Promise => { + return Promise.resolve(null); + }, + getPortfolioSnapshotKey: (userId: string): string => { + return `portfolio-snapshot-${userId}`; + }, + set: (key: string, value: string, ttlInSeconds?: number): Promise => { + return Promise.resolve(value); + } +}; diff --git a/apps/api/src/app/redis-cache/redis-cache.service.ts b/apps/api/src/app/redis-cache/redis-cache.service.ts index 3891cc5ab..a313eadf1 100644 --- a/apps/api/src/app/redis-cache/redis-cache.service.ts +++ b/apps/api/src/app/redis-cache/redis-cache.service.ts @@ -24,6 +24,10 @@ export class RedisCacheService { return this.cache.get(key); } + public getPortfolioSnapshotKey(userId: string) { + return `portfolio-snapshot-${userId}`; + } + public getQuoteKey({ dataSource, symbol }: UniqueAsset) { return `quote-${getAssetProfileIdentifier({ dataSource, symbol })}`; } diff --git a/apps/api/src/events/events.module.ts b/apps/api/src/events/events.module.ts index bf9708f4b..0e6b25ba4 100644 --- a/apps/api/src/events/events.module.ts +++ b/apps/api/src/events/events.module.ts @@ -1,8 +1,11 @@ +import { RedisCacheModule } from '@ghostfolio/api/app/redis-cache/redis-cache.module'; + import { Module } from '@nestjs/common'; import { PortfolioChangedListener } from './portfolio-changed.listener'; @Module({ + imports: [RedisCacheModule], providers: [PortfolioChangedListener] }) export class EventsModule {} diff --git a/apps/api/src/events/portfolio-changed.listener.ts b/apps/api/src/events/portfolio-changed.listener.ts index 3dd856084..0f8877127 100644 --- a/apps/api/src/events/portfolio-changed.listener.ts +++ b/apps/api/src/events/portfolio-changed.listener.ts @@ -1,3 +1,5 @@ +import { RedisCacheService } from '@ghostfolio/api/app/redis-cache/redis-cache.service'; + import { Injectable, Logger } from '@nestjs/common'; import { OnEvent } from '@nestjs/event-emitter'; @@ -5,11 +7,17 @@ import { PortfolioChangedEvent } from './portfolio-changed.event'; @Injectable() export class PortfolioChangedListener { + public constructor(private readonly redisCacheService: RedisCacheService) {} + @OnEvent(PortfolioChangedEvent.getName()) handlePortfolioChangedEvent(event: PortfolioChangedEvent) { Logger.log( `Portfolio of user with id ${event.getUserId()} has changed`, 'PortfolioChangedListener' ); + + this.redisCacheService.remove( + this.redisCacheService.getPortfolioSnapshotKey(event.getUserId()) + ); } } diff --git a/apps/api/src/models/rule.ts b/apps/api/src/models/rule.ts index ba37f4e94..8397f3e46 100644 --- a/apps/api/src/models/rule.ts +++ b/apps/api/src/models/rule.ts @@ -1,7 +1,8 @@ import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; import { groupBy } from '@ghostfolio/common/helper'; -import { TimelinePosition, UserSettings } from '@ghostfolio/common/interfaces'; +import { UserSettings } from '@ghostfolio/common/interfaces'; +import { TimelinePosition } from '@ghostfolio/common/models'; import { EvaluationResult } from './interfaces/evaluation-result.interface'; import { RuleInterface } from './interfaces/rule.interface'; diff --git a/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts b/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts index 39406e6c2..372250dbc 100644 --- a/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts +++ b/apps/api/src/models/rules/currency-cluster-risk/base-currency-current-investment.ts @@ -1,7 +1,8 @@ import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface'; import { Rule } from '@ghostfolio/api/models/rule'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; -import { TimelinePosition, UserSettings } from '@ghostfolio/common/interfaces'; +import { UserSettings } from '@ghostfolio/common/interfaces'; +import { TimelinePosition } from '@ghostfolio/common/models'; export class CurrencyClusterRiskBaseCurrencyCurrentInvestment extends Rule { private positions: TimelinePosition[]; diff --git a/apps/api/src/models/rules/currency-cluster-risk/current-investment.ts b/apps/api/src/models/rules/currency-cluster-risk/current-investment.ts index 078aaba9b..8ebb24ac0 100644 --- a/apps/api/src/models/rules/currency-cluster-risk/current-investment.ts +++ b/apps/api/src/models/rules/currency-cluster-risk/current-investment.ts @@ -1,7 +1,8 @@ import { RuleSettings } from '@ghostfolio/api/models/interfaces/rule-settings.interface'; import { Rule } from '@ghostfolio/api/models/rule'; import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; -import { TimelinePosition, UserSettings } from '@ghostfolio/common/interfaces'; +import { UserSettings } from '@ghostfolio/common/interfaces'; +import { TimelinePosition } from '@ghostfolio/common/models'; export class CurrencyClusterRiskCurrentInvestment extends Rule { private positions: TimelinePosition[]; diff --git a/apps/api/src/services/data-provider/data-provider.service.ts b/apps/api/src/services/data-provider/data-provider.service.ts index 675c13377..26fc171b5 100644 --- a/apps/api/src/services/data-provider/data-provider.service.ts +++ b/apps/api/src/services/data-provider/data-provider.service.ts @@ -399,7 +399,8 @@ export class DataProviderService { numberOfItemsInCache > 1 ? 's' : '' } from cache in ${((performance.now() - startTimeTotal) / 1000).toFixed( 3 - )} seconds` + )} seconds`, + 'DataProviderService' ); } @@ -505,7 +506,8 @@ export class DataProviderService { } from ${dataSource} in ${( (performance.now() - startTimeDataSource) / 1000 - ).toFixed(3)} seconds` + ).toFixed(3)} seconds`, + 'DataProviderService' ); try { @@ -535,14 +537,15 @@ export class DataProviderService { await Promise.all(promises); - Logger.debug('------------------------------------------------'); + Logger.debug('--------------------------------------------------------'); Logger.debug( `Fetched ${items.length} quote${items.length > 1 ? 's' : ''} in ${( (performance.now() - startTimeTotal) / 1000 - ).toFixed(3)} seconds` + ).toFixed(3)} seconds`, + 'DataProviderService' ); - Logger.debug('================================================'); + Logger.debug('========================================================'); return response; } diff --git a/libs/common/src/lib/class-transformer.ts b/libs/common/src/lib/class-transformer.ts new file mode 100644 index 000000000..bd9db22da --- /dev/null +++ b/libs/common/src/lib/class-transformer.ts @@ -0,0 +1,9 @@ +import { Big } from 'big.js'; + +export function transformToBig({ value }: { value: string }): Big { + if (value === null) { + return null; + } + + return new Big(value); +} diff --git a/libs/common/src/lib/interfaces/index.ts b/libs/common/src/lib/interfaces/index.ts index dba1ac79a..c2c9ce619 100644 --- a/libs/common/src/lib/interfaces/index.ts +++ b/libs/common/src/lib/interfaces/index.ts @@ -48,7 +48,6 @@ import type { Subscription } from './subscription.interface'; import type { SymbolMetrics } from './symbol-metrics.interface'; import type { SystemMessage } from './system-message.interface'; import type { TabConfiguration } from './tab-configuration.interface'; -import type { TimelinePosition } from './timeline-position.interface'; import type { UniqueAsset } from './unique-asset.interface'; import type { UserSettings } from './user-settings.interface'; import type { User } from './user.interface'; @@ -102,7 +101,6 @@ export { Subscription, SymbolMetrics, TabConfiguration, - TimelinePosition, UniqueAsset, User, UserSettings diff --git a/libs/common/src/lib/interfaces/timeline-position.interface.ts b/libs/common/src/lib/interfaces/timeline-position.interface.ts deleted file mode 100644 index 539f887ce..000000000 --- a/libs/common/src/lib/interfaces/timeline-position.interface.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { DataSource, Tag } from '@prisma/client'; -import { Big } from 'big.js'; - -export interface TimelinePosition { - averagePrice: Big; - currency: string; - dataSource: DataSource; - dividend: Big; - dividendInBaseCurrency: Big; - fee: Big; - firstBuyDate: string; - grossPerformance: Big; - grossPerformancePercentage: Big; - grossPerformancePercentageWithCurrencyEffect: Big; - grossPerformanceWithCurrencyEffect: Big; - investment: Big; - investmentWithCurrencyEffect: Big; - marketPrice: number; - marketPriceInBaseCurrency: number; - netPerformance: Big; - netPerformancePercentage: Big; - netPerformancePercentageWithCurrencyEffect: Big; - netPerformanceWithCurrencyEffect: Big; - quantity: Big; - symbol: string; - tags?: Tag[]; - timeWeightedInvestment: Big; - timeWeightedInvestmentWithCurrencyEffect: Big; - transactionCount: number; - valueInBaseCurrency: Big; -} diff --git a/libs/common/src/lib/models/index.ts b/libs/common/src/lib/models/index.ts new file mode 100644 index 000000000..0dd601a0e --- /dev/null +++ b/libs/common/src/lib/models/index.ts @@ -0,0 +1,4 @@ +import { PortfolioSnapshot } from './portfolio-snapshot'; +import { TimelinePosition } from './timeline-position'; + +export { PortfolioSnapshot, TimelinePosition }; diff --git a/libs/common/src/lib/models/portfolio-snapshot.ts b/libs/common/src/lib/models/portfolio-snapshot.ts new file mode 100644 index 000000000..909f44f2a --- /dev/null +++ b/libs/common/src/lib/models/portfolio-snapshot.ts @@ -0,0 +1,82 @@ +import { transformToBig } from '@ghostfolio/common/class-transformer'; +import { UniqueAsset } from '@ghostfolio/common/interfaces'; +import { TimelinePosition } from '@ghostfolio/common/models'; + +import { Big } from 'big.js'; +import { Transform, Type } from 'class-transformer'; + +export class PortfolioSnapshot { + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + currentValueInBaseCurrency: Big; + errors?: UniqueAsset[]; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + grossPerformance: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + grossPerformanceWithCurrencyEffect: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + grossPerformancePercentage: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + grossPerformancePercentageWithCurrencyEffect: Big; + + hasErrors: boolean; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + netAnnualizedPerformance?: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + netAnnualizedPerformanceWithCurrencyEffect?: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + netPerformance: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + netPerformanceWithCurrencyEffect: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + netPerformancePercentage: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + netPerformancePercentageWithCurrencyEffect: Big; + + @Type(() => TimelinePosition) + positions: TimelinePosition[]; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + totalFeesWithCurrencyEffect: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + totalInterestWithCurrencyEffect: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + totalInvestment: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + totalInvestmentWithCurrencyEffect: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + totalLiabilitiesWithCurrencyEffect: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + totalValuablesWithCurrencyEffect: Big; +} diff --git a/libs/common/src/lib/models/timeline-position.ts b/libs/common/src/lib/models/timeline-position.ts new file mode 100644 index 000000000..412449590 --- /dev/null +++ b/libs/common/src/lib/models/timeline-position.ts @@ -0,0 +1,92 @@ +import { transformToBig } from '@ghostfolio/common/class-transformer'; + +import { DataSource, Tag } from '@prisma/client'; +import { Big } from 'big.js'; +import { Transform, Type } from 'class-transformer'; + +export class TimelinePosition { + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + averagePrice: Big; + + currency: string; + dataSource: DataSource; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + dividend: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + dividendInBaseCurrency: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + fee: Big; + + firstBuyDate: string; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + grossPerformance: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + grossPerformancePercentage: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + grossPerformancePercentageWithCurrencyEffect: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + grossPerformanceWithCurrencyEffect: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + investment: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + investmentWithCurrencyEffect: Big; + + marketPrice: number; + marketPriceInBaseCurrency: number; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + netPerformance: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + netPerformancePercentage: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + netPerformancePercentageWithCurrencyEffect: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + netPerformanceWithCurrencyEffect: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + quantity: Big; + + symbol: string; + tags?: Tag[]; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + timeWeightedInvestment: Big; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + timeWeightedInvestmentWithCurrencyEffect: Big; + + transactionCount: number; + + @Transform(transformToBig, { toClassOnly: true }) + @Type(() => Big) + valueInBaseCurrency: Big; +} From bb4ee507385e7855e567365bf06cbd8d329ca81c Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 27 Apr 2024 15:35:57 +0200 Subject: [PATCH 166/203] Feature/update browserslist database 20240417 (#3288) * Update the browserslist database * Update changelog --- CHANGELOG.md | 1 + yarn.lock | 18 ++++-------------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d718476d8..31b332ce7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Migrated the `@ghostfolio/ui` components to control flow +- Updated the browserslist database - Upgraded `prisma` from version `5.12.1` to `5.13.0` ### Fixed diff --git a/yarn.lock b/yarn.lock index f5fd0d164..86c62b958 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9287,20 +9287,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001538, caniuse-lite@^1.0.30001541: - version "1.0.30001554" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001554.tgz#ba80d88dff9acbc0cd4b7535fc30e0191c5e2e2a" - integrity sha512-A2E3U//MBwbJVzebddm1YfNp7Nud5Ip+IPn4BozBmn4KqVX7AvluoIDFWjsv5OkGnKUXQVmMSoMKLa3ScCblcQ== - -caniuse-lite@^1.0.30001565: - version "1.0.30001570" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001570.tgz#b4e5c1fa786f733ab78fc70f592df6b3f23244ca" - integrity sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw== - -caniuse-lite@^1.0.30001587, caniuse-lite@^1.0.30001591: - version "1.0.30001606" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001606.tgz#b4d5f67ab0746a3b8b5b6d1f06e39c51beb39a9e" - integrity sha512-LPbwnW4vfpJId225pwjZJOgX1m9sGfbw/RKJvw/t0QhYOOaTXHvkjVGFGPpvwEzufrjvTlsULnVTxdy4/6cqkg== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001538, caniuse-lite@^1.0.30001541, caniuse-lite@^1.0.30001565, caniuse-lite@^1.0.30001587, caniuse-lite@^1.0.30001591: + version "1.0.30001610" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001610.tgz" + integrity sha512-QFutAY4NgaelojVMjY63o6XlZyORPaLfyMnsl3HgnWdJUcX6K0oaJymHjH8PT5Gk7sTm8rvC/c5COUQKXqmOMA== case-sensitive-paths-webpack-plugin@^2.4.0: version "2.4.0" From ac953df8091d4b4e7bb3c6ca24f853d39392e031 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 27 Apr 2024 15:37:48 +0200 Subject: [PATCH 167/203] Release 2.77.0 (#3338) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31b332ce7..fa8af9932 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.77.0 - 2024-04-27 ### Added diff --git a/package.json b/package.json index 690918edf..7dac6401d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.76.0", + "version": "2.77.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From e10707fde4fbf4b1f5b1cf8f8f2173e5cb2010e5 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 27 Apr 2024 19:24:08 +0200 Subject: [PATCH 168/203] Add missing guard to fix public page (#3339) --- apps/api/src/app/portfolio/portfolio.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index a7e80ce1c..573c48a83 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -359,7 +359,7 @@ export class PortfolioService { calculationType: PerformanceCalculationType.TWR, currency: userCurrency, isExperimentalFeatures: - this.request.user.Settings.settings.isExperimentalFeatures + this.request.user?.Settings.settings.isExperimentalFeatures }); const { currentValueInBaseCurrency, hasErrors, positions } = From d735e4db75f9ac88994b89ed2234fb168ec56a68 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 27 Apr 2024 19:25:23 +0200 Subject: [PATCH 169/203] Release 2.77.1 (#3340) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fa8af9932..8584582a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 2.77.0 - 2024-04-27 +## 2.77.1 - 2024-04-27 ### Added diff --git a/package.json b/package.json index 7dac6401d..35a66b550 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.77.0", + "version": "2.77.1", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 4efd5cefd8ff9893adc3e9a586ee6160bcea4757 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 29 Apr 2024 20:12:12 +0200 Subject: [PATCH 170/203] Bugfix/calculation of portfolio summary caused by future liabilities (#3342) * Adapt date of future activities * Update changelog --- CHANGELOG.md | 6 ++ apps/api/src/app/order/order.controller.ts | 11 +++- .../calculator/portfolio-calculator.ts | 14 +++-- .../portfolio-calculator-liability.spec.ts | 59 ++----------------- .../calculator/twr/portfolio-calculator.ts | 2 +- .../portfolio/current-rate.service.mock.ts | 7 +++ 6 files changed, 37 insertions(+), 62 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8584582a3..36a4eff54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Fixed + +- Fixed an issue in the calculation of the portfolio summary caused by future liabilities + ## 2.77.1 - 2024-04-27 ### Added diff --git a/apps/api/src/app/order/order.controller.ts b/apps/api/src/app/order/order.controller.ts index 4a85dce57..bf4920463 100644 --- a/apps/api/src/app/order/order.controller.ts +++ b/apps/api/src/app/order/order.controller.ts @@ -88,21 +88,26 @@ export class OrderController { @Headers(HEADER_KEY_IMPERSONATION.toLowerCase()) impersonationId, @Query('accounts') filterByAccounts?: string, @Query('assetClasses') filterByAssetClasses?: string, - @Query('range') dateRange: DateRange = 'max', + @Query('range') dateRange?: DateRange, @Query('skip') skip?: number, @Query('sortColumn') sortColumn?: string, @Query('sortDirection') sortDirection?: Prisma.SortOrder, @Query('tags') filterByTags?: string, @Query('take') take?: number ): Promise { + let endDate: Date; + let startDate: Date; + + if (dateRange) { + ({ endDate, startDate } = getInterval(dateRange)); + } + const filters = this.apiService.buildFiltersFromQueryParams({ filterByAccounts, filterByAssetClasses, filterByTags }); - const { endDate, startDate } = getInterval(dateRange); - const impersonationUserId = await this.impersonationService.validateImpersonationId(impersonationId); const userCurrency = this.request.user.Settings.settings.baseCurrency; diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index ba9833948..568969603 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -37,6 +37,7 @@ import { eachDayOfInterval, endOfDay, format, + isAfter, isBefore, isSameDay, max, @@ -44,13 +45,12 @@ import { subDays } from 'date-fns'; import { first, last, uniq, uniqBy } from 'lodash'; -import ms from 'ms'; export abstract class PortfolioCalculator { protected static readonly ENABLE_LOGGING = false; protected accountBalanceItems: HistoricalDataItem[]; - protected orders: PortfolioOrder[]; + protected activities: PortfolioOrder[]; private configurationService: ConfigurationService; private currency: string; @@ -96,7 +96,7 @@ export abstract class PortfolioCalculator { this.exchangeRateDataService = exchangeRateDataService; this.isExperimentalFeatures = isExperimentalFeatures; - this.orders = activities + this.activities = activities .map( ({ date, @@ -107,6 +107,12 @@ export abstract class PortfolioCalculator { type, unitPrice }) => { + if (isAfter(date, new Date(Date.now()))) { + // Adapt date to today if activity is in future (e.g. liability) + // to include it in the interval + date = endOfDay(new Date(Date.now())); + } + return { SymbolProfile, tags, @@ -917,7 +923,7 @@ export abstract class PortfolioCalculator { tags, type, unitPrice - } of this.orders) { + } of this.activities) { let currentTransactionPointItem: TransactionPointSymbol; const oldAccumulatedSymbol = symbols[SymbolProfile.symbol]; diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts index fc858f293..3ae63c72a 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts @@ -74,7 +74,7 @@ describe('PortfolioCalculator', () => { const activities: Activity[] = [ { ...activityDummyData, - date: new Date('2022-01-01'), + date: new Date('2023-01-01'), // Date in future fee: 0, quantity: 1, SymbolProfile: { @@ -96,61 +96,12 @@ describe('PortfolioCalculator', () => { userId: userDummyData.id }); - const portfolioSnapshot = await portfolioCalculator.computeSnapshot( - parseDate('2022-01-01') - ); - spy.mockRestore(); - expect(portfolioSnapshot).toEqual({ - currentValueInBaseCurrency: new Big('0'), - errors: [], - grossPerformance: new Big('0'), - grossPerformancePercentage: new Big('0'), - grossPerformancePercentageWithCurrencyEffect: new Big('0'), - grossPerformanceWithCurrencyEffect: new Big('0'), - hasErrors: true, - netPerformance: new Big('0'), - netPerformancePercentage: new Big('0'), - netPerformancePercentageWithCurrencyEffect: new Big('0'), - netPerformanceWithCurrencyEffect: new Big('0'), - positions: [ - { - averagePrice: new Big('3000'), - currency: 'USD', - dataSource: 'MANUAL', - dividend: new Big('0'), - dividendInBaseCurrency: new Big('0'), - fee: new Big('0'), - firstBuyDate: '2022-01-01', - grossPerformance: null, - grossPerformancePercentage: null, - grossPerformancePercentageWithCurrencyEffect: null, - grossPerformanceWithCurrencyEffect: null, - investment: new Big('0'), - investmentWithCurrencyEffect: new Big('0'), - marketPrice: null, - marketPriceInBaseCurrency: 3000, - netPerformance: null, - netPerformancePercentage: null, - netPerformancePercentageWithCurrencyEffect: null, - netPerformanceWithCurrencyEffect: null, - quantity: new Big('0'), - symbol: '55196015-1365-4560-aa60-8751ae6d18f8', - tags: [], - timeWeightedInvestment: new Big('0'), - timeWeightedInvestmentWithCurrencyEffect: new Big('0'), - transactionCount: 1, - valueInBaseCurrency: new Big('0') - } - ], - totalFeesWithCurrencyEffect: new Big('0'), - totalInterestWithCurrencyEffect: new Big('0'), - totalInvestment: new Big('0'), - totalInvestmentWithCurrencyEffect: new Big('0'), - totalLiabilitiesWithCurrencyEffect: new Big('0'), - totalValuablesWithCurrencyEffect: new Big('0') - }); + const liabilitiesInBaseCurrency = + await portfolioCalculator.getLiabilitiesInBaseCurrency(); + + expect(liabilitiesInBaseCurrency).toEqual(new Big(3000)); }); }); }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index f480fdc59..f8b62a940 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -203,7 +203,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { let valueAtStartDateWithCurrencyEffect: Big; // Clone orders to keep the original values in this.orders - let orders: PortfolioOrderItem[] = cloneDeep(this.orders).filter( + let orders: PortfolioOrderItem[] = cloneDeep(this.activities).filter( ({ SymbolProfile }) => { return SymbolProfile.symbol === symbol; } diff --git a/apps/api/src/app/portfolio/current-rate.service.mock.ts b/apps/api/src/app/portfolio/current-rate.service.mock.ts index ed9229691..8ac1d15bd 100644 --- a/apps/api/src/app/portfolio/current-rate.service.mock.ts +++ b/apps/api/src/app/portfolio/current-rate.service.mock.ts @@ -8,6 +8,13 @@ import { GetValuesParams } from './interfaces/get-values-params.interface'; function mockGetValue(symbol: string, date: Date) { switch (symbol) { + case '55196015-1365-4560-aa60-8751ae6d18f8': + if (isSameDay(parseDate('2022-01-31'), date)) { + return { marketPrice: 3000 }; + } + + return { marketPrice: 0 }; + case 'BALN.SW': if (isSameDay(parseDate('2021-11-12'), date)) { return { marketPrice: 146 }; From 2173c418a778af6f4601cb409ba815449a97c140 Mon Sep 17 00:00:00 2001 From: Fedron <40535546+Fedron@users.noreply.github.com> Date: Tue, 30 Apr 2024 07:04:45 +0100 Subject: [PATCH 171/203] Feature/validate forms using DTO for access, asset profile, tag and platform management (#3337) * Validate forms using DTO for access, asset profile, tag and platform management * Update changelog --- CHANGELOG.md | 7 +++ .../asset-profile-dialog.component.ts | 14 ++++- .../admin-platform.component.ts | 8 +-- ...ate-or-update-platform-dialog.component.ts | 54 +++++++++++++++++-- .../create-or-update-platform-dialog.html | 25 ++++++--- .../admin-tag/admin-tag.component.ts | 8 +-- .../create-or-update-tag-dialog.component.ts | 52 ++++++++++++++++-- .../create-or-update-tag-dialog.html | 19 +++++-- ...reate-or-update-access-dialog.component.ts | 53 ++++++++++-------- .../create-or-update-access-dialog.html | 2 +- .../user-account-access.component.ts | 3 +- .../pages/accounts/accounts-page.component.ts | 8 +-- ...eate-or-update-account-dialog.component.ts | 6 ++- .../activities/activities-page.component.ts | 8 +-- ...ate-or-update-activity-dialog.component.ts | 6 ++- apps/client/src/app/util/form.util.ts | 8 +++ 16 files changed, 210 insertions(+), 71 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 36a4eff54..f682d51db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Added a form validation against the DTO in the create or update access dialog +- Added a form validation against the DTO in the asset profile details dialog of the admin control +- Added a form validation against the DTO in the platform management of the admin control panel +- Added a form validation against the DTO in the tag management of the admin control panel + ### Fixed - Fixed an issue in the calculation of the portfolio summary caused by future liabilities diff --git a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts index 783bbdbc4..5016a4205 100644 --- a/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts +++ b/apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts @@ -3,6 +3,7 @@ import { UpdateMarketDataDto } from '@ghostfolio/api/app/admin/update-market-dat import { AdminMarketDataService } from '@ghostfolio/client/components/admin-market-data/admin-market-data.service'; import { AdminService } from '@ghostfolio/client/services/admin.service'; import { DataService } from '@ghostfolio/client/services/data.service'; +import { validateObjectForForm } from '@ghostfolio/client/util/form.util'; import { ghostfolioScraperApiSymbolPrefix } from '@ghostfolio/common/config'; import { DATE_FORMAT } from '@ghostfolio/common/helper'; import { @@ -258,7 +259,7 @@ export class AssetProfileDialog implements OnDestroy, OnInit { }); } - public onSubmit() { + public async onSubmit() { let countries = []; let scraperConfiguration = {}; let sectors = []; @@ -299,6 +300,17 @@ export class AssetProfileDialog implements OnDestroy, OnInit { url: this.assetProfileForm.get('url').value || null }; + try { + await validateObjectForForm({ + classDto: UpdateAssetProfileDto, + form: this.assetProfileForm, + object: assetProfileData + }); + } catch (error) { + console.error(error); + return; + } + this.adminService .patchAssetProfile({ ...assetProfileData, diff --git a/apps/client/src/app/components/admin-platform/admin-platform.component.ts b/apps/client/src/app/components/admin-platform/admin-platform.component.ts index 6a2a3de3c..8a2004f8d 100644 --- a/apps/client/src/app/components/admin-platform/admin-platform.component.ts +++ b/apps/client/src/app/components/admin-platform/admin-platform.component.ts @@ -143,9 +143,7 @@ export class AdminPlatformComponent implements OnInit, OnDestroy { dialogRef .afterClosed() .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((data) => { - const platform: CreatePlatformDto = data?.platform; - + .subscribe((platform: CreatePlatformDto | null) => { if (platform) { this.adminService .postPlatform(platform) @@ -182,9 +180,7 @@ export class AdminPlatformComponent implements OnInit, OnDestroy { dialogRef .afterClosed() .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((data) => { - const platform: UpdatePlatformDto = data?.platform; - + .subscribe((platform: UpdatePlatformDto | null) => { if (platform) { this.adminService .putPlatform(platform) diff --git a/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.component.ts b/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.component.ts index 14d893900..518b6dd52 100644 --- a/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.component.ts +++ b/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.component.ts @@ -1,4 +1,14 @@ -import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'; +import { CreatePlatformDto } from '@ghostfolio/api/app/platform/create-platform.dto'; +import { UpdatePlatformDto } from '@ghostfolio/api/app/platform/update-platform.dto'; +import { validateObjectForForm } from '@ghostfolio/client/util/form.util'; + +import { + ChangeDetectionStrategy, + Component, + Inject, + OnDestroy +} from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Subject } from 'rxjs'; @@ -11,18 +21,54 @@ import { CreateOrUpdatePlatformDialogParams } from './interfaces/interfaces'; styleUrls: ['./create-or-update-platform-dialog.scss'], templateUrl: 'create-or-update-platform-dialog.html' }) -export class CreateOrUpdatePlatformDialog { +export class CreateOrUpdatePlatformDialog implements OnDestroy { + public platformForm: FormGroup; + private unsubscribeSubject = new Subject(); public constructor( @Inject(MAT_DIALOG_DATA) public data: CreateOrUpdatePlatformDialogParams, - public dialogRef: MatDialogRef - ) {} + public dialogRef: MatDialogRef, + private formBuilder: FormBuilder + ) { + this.platformForm = this.formBuilder.group({ + name: [this.data.platform.name, Validators.required], + url: [this.data.platform.url, Validators.required] + }); + } public onCancel() { this.dialogRef.close(); } + public async onSubmit() { + try { + const platform: CreatePlatformDto | UpdatePlatformDto = { + name: this.platformForm.get('name')?.value, + url: this.platformForm.get('url')?.value + }; + + if (this.data.platform.id) { + (platform as UpdatePlatformDto).id = this.data.platform.id; + await validateObjectForForm({ + classDto: UpdatePlatformDto, + form: this.platformForm, + object: platform + }); + } else { + await validateObjectForForm({ + classDto: CreatePlatformDto, + form: this.platformForm, + object: platform + }); + } + + this.dialogRef.close(platform); + } catch (error) { + console.error(error); + } + } + public ngOnDestroy() { this.unsubscribeSubject.next(); this.unsubscribeSubject.complete(); diff --git a/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html b/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html index bcd3d0340..0e85cff2c 100644 --- a/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html +++ b/apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html @@ -1,17 +1,30 @@ -
+

Update platform

Add platform

Name - +
Url - + @if (data.platform.url) {
- + diff --git a/apps/client/src/app/components/admin-tag/admin-tag.component.ts b/apps/client/src/app/components/admin-tag/admin-tag.component.ts index a8bb7720a..5b5d5aa84 100644 --- a/apps/client/src/app/components/admin-tag/admin-tag.component.ts +++ b/apps/client/src/app/components/admin-tag/admin-tag.component.ts @@ -142,9 +142,7 @@ export class AdminTagComponent implements OnInit, OnDestroy { dialogRef .afterClosed() .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((data) => { - const tag: CreateTagDto = data?.tag; - + .subscribe((tag: CreateTagDto | null) => { if (tag) { this.adminService .postTag(tag) @@ -180,9 +178,7 @@ export class AdminTagComponent implements OnInit, OnDestroy { dialogRef .afterClosed() .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((data) => { - const tag: UpdateTagDto = data?.tag; - + .subscribe((tag: UpdateTagDto | null) => { if (tag) { this.adminService .putTag(tag) diff --git a/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.component.ts b/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.component.ts index aaa5a0221..f50974358 100644 --- a/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.component.ts +++ b/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.component.ts @@ -1,4 +1,14 @@ -import { ChangeDetectionStrategy, Component, Inject } from '@angular/core'; +import { CreateTagDto } from '@ghostfolio/api/app/tag/create-tag.dto'; +import { UpdateTagDto } from '@ghostfolio/api/app/tag/update-tag.dto'; +import { validateObjectForForm } from '@ghostfolio/client/util/form.util'; + +import { + ChangeDetectionStrategy, + Component, + Inject, + OnDestroy +} from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { Subject } from 'rxjs'; @@ -11,18 +21,52 @@ import { CreateOrUpdateTagDialogParams } from './interfaces/interfaces'; styleUrls: ['./create-or-update-tag-dialog.scss'], templateUrl: 'create-or-update-tag-dialog.html' }) -export class CreateOrUpdateTagDialog { +export class CreateOrUpdateTagDialog implements OnDestroy { + public tagForm: FormGroup; + private unsubscribeSubject = new Subject(); public constructor( @Inject(MAT_DIALOG_DATA) public data: CreateOrUpdateTagDialogParams, - public dialogRef: MatDialogRef - ) {} + public dialogRef: MatDialogRef, + private formBuilder: FormBuilder + ) { + this.tagForm = this.formBuilder.group({ + name: [this.data.tag.name] + }); + } public onCancel() { this.dialogRef.close(); } + public async onSubmit() { + try { + const tag: CreateTagDto | UpdateTagDto = { + name: this.tagForm.get('name')?.value + }; + + if (this.data.tag.id) { + (tag as UpdateTagDto).id = this.data.tag.id; + await validateObjectForForm({ + classDto: UpdateTagDto, + form: this.tagForm, + object: tag + }); + } else { + await validateObjectForForm({ + classDto: CreateTagDto, + form: this.tagForm, + object: tag + }); + } + + this.dialogRef.close(tag); + } catch (error) { + console.error(error); + } + } + public ngOnDestroy() { this.unsubscribeSubject.next(); this.unsubscribeSubject.complete(); diff --git a/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html b/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html index c2e8f4ee1..46ab1a39e 100644 --- a/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html +++ b/apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html @@ -1,21 +1,30 @@ - +

Update tag

Add tag

Name - +
- + diff --git a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts index 5e08635e0..d7a41f62f 100644 --- a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts +++ b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts @@ -1,5 +1,6 @@ import { CreateAccessDto } from '@ghostfolio/api/app/access/create-access.dto'; import { DataService } from '@ghostfolio/client/services/data.service'; +import { validateObjectForForm } from '@ghostfolio/client/util/form.util'; import { ChangeDetectionStrategy, @@ -40,22 +41,22 @@ export class CreateOrUpdateAccessDialog implements OnDestroy { alias: [this.data.access.alias], permissions: [this.data.access.permissions[0], Validators.required], type: [this.data.access.type, Validators.required], - userId: [this.data.access.grantee, Validators.required] + granteeUserId: [this.data.access.grantee, Validators.required] }); this.accessForm.get('type').valueChanges.subscribe((accessType) => { + const granteeUserIdControl = this.accessForm.get('granteeUserId'); const permissionsControl = this.accessForm.get('permissions'); - const userIdControl = this.accessForm.get('userId'); if (accessType === 'PRIVATE') { + granteeUserIdControl.setValidators(Validators.required); permissionsControl.setValidators(Validators.required); - userIdControl.setValidators(Validators.required); } else { - userIdControl.clearValidators(); + granteeUserIdControl.clearValidators(); } + granteeUserIdControl.updateValueAndValidity(); permissionsControl.updateValueAndValidity(); - userIdControl.updateValueAndValidity(); this.changeDetectorRef.markForCheck(); }); @@ -65,28 +66,38 @@ export class CreateOrUpdateAccessDialog implements OnDestroy { this.dialogRef.close(); } - public onSubmit() { + public async onSubmit() { const access: CreateAccessDto = { alias: this.accessForm.get('alias').value, - granteeUserId: this.accessForm.get('userId').value, + granteeUserId: this.accessForm.get('granteeUserId').value, permissions: [this.accessForm.get('permissions').value] }; - this.dataService - .postAccess(access) - .pipe( - catchError((error) => { - if (error.status === StatusCodes.BAD_REQUEST) { - alert($localize`Oops! Could not grant access.`); - } - - return EMPTY; - }), - takeUntil(this.unsubscribeSubject) - ) - .subscribe(() => { - this.dialogRef.close({ access }); + try { + await validateObjectForForm({ + classDto: CreateAccessDto, + form: this.accessForm, + object: access }); + + this.dataService + .postAccess(access) + .pipe( + catchError((error) => { + if (error.status === StatusCodes.BAD_REQUEST) { + alert($localize`Oops! Could not grant access.`); + } + + return EMPTY; + }), + takeUntil(this.unsubscribeSubject) + ) + .subscribe(() => { + this.dialogRef.close(access); + }); + } catch (error) { + console.error(error); + } } public ngOnDestroy() { diff --git a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html index a6f20f2f4..951079717 100644 --- a/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html +++ b/apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -45,7 +45,7 @@ Ghostfolio User ID { + dialogRef.afterClosed().subscribe((access: CreateAccessDto | null) => { if (access) { this.update(); } diff --git a/apps/client/src/app/pages/accounts/accounts-page.component.ts b/apps/client/src/app/pages/accounts/accounts-page.component.ts index e1b53acd3..e445863b4 100644 --- a/apps/client/src/app/pages/accounts/accounts-page.component.ts +++ b/apps/client/src/app/pages/accounts/accounts-page.component.ts @@ -189,9 +189,7 @@ export class AccountsPageComponent implements OnDestroy, OnInit { dialogRef .afterClosed() .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((data: any) => { - const account: UpdateAccountDto = data?.account; - + .subscribe((account: UpdateAccountDto | null) => { if (account) { this.dataService .putAccount(account) @@ -258,9 +256,7 @@ export class AccountsPageComponent implements OnDestroy, OnInit { dialogRef .afterClosed() .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((data: any) => { - const account: CreateAccountDto = data?.account; - + .subscribe((account: CreateAccountDto | null) => { if (account) { this.dataService .postAccount(account) diff --git a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts index 6c3624344..91e0769fc 100644 --- a/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts +++ b/apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.component.ts @@ -123,6 +123,8 @@ export class CreateOrUpdateAccountDialog implements OnDestroy { form: this.accountForm, object: account }); + + this.dialogRef.close(account as UpdateAccountDto); } else { delete (account as CreateAccountDto).id; @@ -131,9 +133,9 @@ export class CreateOrUpdateAccountDialog implements OnDestroy { form: this.accountForm, object: account }); - } - this.dialogRef.close({ account }); + this.dialogRef.close(account as CreateAccountDto); + } } catch (error) { console.error(error); } diff --git a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts index 190fc673e..f6f0feded 100644 --- a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts @@ -287,9 +287,7 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit { dialogRef .afterClosed() .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((data: any) => { - const transaction: UpdateOrderDto = data?.activity; - + .subscribe((transaction: UpdateOrderDto | null) => { if (transaction) { this.dataService .putOrder(transaction) @@ -338,9 +336,7 @@ export class ActivitiesPageComponent implements OnDestroy, OnInit { dialogRef .afterClosed() .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((data: any) => { - const transaction: CreateOrderDto = data?.activity; - + .subscribe((transaction: CreateOrderDto | null) => { if (transaction) { this.dataService.postOrder(transaction).subscribe({ next: () => { diff --git a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts index 700e997e1..f49860028 100644 --- a/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.component.ts @@ -475,6 +475,8 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { ignoreFields: ['dataSource', 'date'], object: activity as UpdateOrderDto }); + + this.dialogRef.close(activity as UpdateOrderDto); } else { (activity as CreateOrderDto).updateAccountBalance = this.activityForm.get('updateAccountBalance').value; @@ -485,9 +487,9 @@ export class CreateOrUpdateActivityDialog implements OnDestroy { ignoreFields: ['dataSource', 'date'], object: activity }); - } - this.dialogRef.close({ activity }); + this.dialogRef.close(activity as CreateOrderDto); + } } catch (error) { console.error(error); } diff --git a/apps/client/src/app/util/form.util.ts b/apps/client/src/app/util/form.util.ts index d11490c7e..f629cc4a2 100644 --- a/apps/client/src/app/util/form.util.ts +++ b/apps/client/src/app/util/form.util.ts @@ -32,6 +32,14 @@ export async function validateObjectForForm({ validationError: Object.values(constraints)[0] }); } + + const formControlInCustomCurrency = form.get(`${property}InCustomCurrency`); + + if (formControlInCustomCurrency) { + formControlInCustomCurrency.setErrors({ + validationError: Object.values(constraints)[0] + }); + } } return Promise.reject(nonIgnoredErrors); From 261f5844ddda627ee62a52f1779d8f67c2bfbed9 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 30 Apr 2024 14:08:14 +0200 Subject: [PATCH 172/203] Add type column to README.md (#3295) --- README.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index d63bb10d0..b48fa48db 100644 --- a/README.md +++ b/README.md @@ -85,23 +85,23 @@ We provide official container images hosted on [Docker Hub](https://hub.docker.c ### Supported Environment Variables -| Name | Default Value | Description | -| ------------------------ | ------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| `ACCESS_TOKEN_SALT` | | A random string used as salt for access tokens | -| `API_KEY_COINGECKO_DEMO` |   | The _CoinGecko_ Demo API key | -| `API_KEY_COINGECKO_PRO` |   | The _CoinGecko_ Pro API | -| `DATABASE_URL` | | The database connection URL, e.g. `postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}?sslmode=prefer` | -| `HOST` | `0.0.0.0` | The host where the Ghostfolio application will run on | -| `JWT_SECRET_KEY` | | A random string used for _JSON Web Tokens_ (JWT) | -| `PORT` | `3333` | The port where the Ghostfolio application will run on | -| `POSTGRES_DB` | | The name of the _PostgreSQL_ database | -| `POSTGRES_PASSWORD` | | The password of the _PostgreSQL_ database | -| `POSTGRES_USER` | | The user of the _PostgreSQL_ database | -| `REDIS_DB` | `0` | The database index of _Redis_ | -| `REDIS_HOST` | | The host where _Redis_ is running | -| `REDIS_PASSWORD` | | The password of _Redis_ | -| `REDIS_PORT` | | The port where _Redis_ is running | -| `REQUEST_TIMEOUT` | `2000` | The timeout of network requests to data providers in milliseconds | +| Name | Type | Default Value | Description | +| ------------------------ | ------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| `ACCESS_TOKEN_SALT` | string | | A random string used as salt for access tokens | +| `API_KEY_COINGECKO_DEMO` | string (`optional`) |   | The _CoinGecko_ Demo API key | +| `API_KEY_COINGECKO_PRO` | string (`optional`) | | The _CoinGecko_ Pro API | +| `DATABASE_URL` | string | | The database connection URL, e.g. `postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@localhost:5432/${POSTGRES_DB}?sslmode=prefer` | +| `HOST` | string (`optional`) | `0.0.0.0` | The host where the Ghostfolio application will run on | +| `JWT_SECRET_KEY` | string | | A random string used for _JSON Web Tokens_ (JWT) | +| `PORT` | number (`optional`) | `3333` | The port where the Ghostfolio application will run on | +| `POSTGRES_DB` | string | | The name of the _PostgreSQL_ database | +| `POSTGRES_PASSWORD` | string | | The password of the _PostgreSQL_ database | +| `POSTGRES_USER` | string | | The user of the _PostgreSQL_ database | +| `REDIS_DB` | number (`optional`) | `0` | The database index of _Redis_ | +| `REDIS_HOST` | string | | The host where _Redis_ is running | +| `REDIS_PASSWORD` | string | | The password of _Redis_ | +| `REDIS_PORT` | number | | The port where _Redis_ is running | +| `REQUEST_TIMEOUT` | number (`optional`) | `2000` | The timeout of network requests to data providers in milliseconds | ### Run with Docker Compose From a5833566a8053dc3ae78573feba101626826cb98 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 2 May 2024 17:52:39 +0200 Subject: [PATCH 173/203] Feature/skip caching in portfolio calculator if active filters (#3348) * Skip caching if active filters * Update changelog --- CHANGELOG.md | 4 ++++ .../portfolio-calculator.factory.ts | 8 ++++++-- .../calculator/portfolio-calculator.ts | 20 ++++++++++++------- ...aln-buy-and-sell-in-two-activities.spec.ts | 1 + ...folio-calculator-baln-buy-and-sell.spec.ts | 1 + .../twr/portfolio-calculator-baln-buy.spec.ts | 1 + ...ator-btcusd-buy-and-sell-partially.spec.ts | 1 + .../twr/portfolio-calculator-fee.spec.ts | 1 + .../portfolio-calculator-googl-buy.spec.ts | 1 + .../twr/portfolio-calculator-item.spec.ts | 1 + .../portfolio-calculator-liability.spec.ts | 1 + ...-calculator-msft-buy-with-dividend.spec.ts | 1 + .../portfolio-calculator-no-orders.spec.ts | 1 + ...ulator-novn-buy-and-sell-partially.spec.ts | 1 + ...folio-calculator-novn-buy-and-sell.spec.ts | 1 + .../src/app/portfolio/portfolio.service.ts | 9 ++++++++- .../app/redis-cache/redis-cache.service.ts | 2 +- .../src/events/portfolio-changed.listener.ts | 4 +++- 18 files changed, 47 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f682d51db..50e732acb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added a form validation against the DTO in the platform management of the admin control panel - Added a form validation against the DTO in the tag management of the admin control panel +### Changed + +- Skipped the caching in the portfolio calculator if there are active filters (experimental) + ### Fixed - Fixed an issue in the calculation of the portfolio summary caused by future liabilities diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts index 4937f1008..762415d1e 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts @@ -32,6 +32,7 @@ export class PortfolioCalculatorFactory { calculationType, currency, dateRange = 'max', + hasFilters, isExperimentalFeatures = false, userId }: { @@ -40,9 +41,12 @@ export class PortfolioCalculatorFactory { calculationType: PerformanceCalculationType; currency: string; dateRange?: DateRange; + hasFilters: boolean; isExperimentalFeatures?: boolean; userId: string; }): PortfolioCalculator { + const useCache = !hasFilters && isExperimentalFeatures; + switch (calculationType) { case PerformanceCalculationType.MWR: return new MWRPortfolioCalculator({ @@ -50,7 +54,7 @@ export class PortfolioCalculatorFactory { activities, currency, dateRange, - isExperimentalFeatures, + useCache, userId, configurationService: this.configurationService, currentRateService: this.currentRateService, @@ -64,7 +68,7 @@ export class PortfolioCalculatorFactory { currency, currentRateService: this.currentRateService, dateRange, - isExperimentalFeatures, + useCache, userId, configurationService: this.configurationService, exchangeRateDataService: this.exchangeRateDataService, diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index 568969603..e021eb2d4 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -56,14 +56,15 @@ export abstract class PortfolioCalculator { private currency: string; private currentRateService: CurrentRateService; private dataProviderInfos: DataProviderInfo[]; + private dateRange: DateRange; private endDate: Date; private exchangeRateDataService: ExchangeRateDataService; - private isExperimentalFeatures: boolean; private redisCacheService: RedisCacheService; private snapshot: PortfolioSnapshot; private snapshotPromise: Promise; private startDate: Date; private transactionPoints: TransactionPoint[]; + private useCache: boolean; private userId: string; public constructor({ @@ -74,8 +75,8 @@ export abstract class PortfolioCalculator { currentRateService, dateRange, exchangeRateDataService, - isExperimentalFeatures, redisCacheService, + useCache, userId }: { accountBalanceItems: HistoricalDataItem[]; @@ -85,16 +86,16 @@ export abstract class PortfolioCalculator { currentRateService: CurrentRateService; dateRange: DateRange; exchangeRateDataService: ExchangeRateDataService; - isExperimentalFeatures: boolean; redisCacheService: RedisCacheService; + useCache: boolean; userId: string; }) { this.accountBalanceItems = accountBalanceItems; this.configurationService = configurationService; this.currency = currency; this.currentRateService = currentRateService; + this.dateRange = dateRange; this.exchangeRateDataService = exchangeRateDataService; - this.isExperimentalFeatures = isExperimentalFeatures; this.activities = activities .map( @@ -129,6 +130,7 @@ export abstract class PortfolioCalculator { }); this.redisCacheService = redisCacheService; + this.useCache = useCache; this.userId = userId; const { endDate, startDate } = getInterval(dateRange); @@ -1047,11 +1049,13 @@ export abstract class PortfolioCalculator { } private async initialize() { - if (this.isExperimentalFeatures) { + if (this.useCache) { const startTimeTotal = performance.now(); const cachedSnapshot = await this.redisCacheService.get( - this.redisCacheService.getPortfolioSnapshotKey(this.userId) + this.redisCacheService.getPortfolioSnapshotKey({ + userId: this.userId + }) ); if (cachedSnapshot) { @@ -1074,7 +1078,9 @@ export abstract class PortfolioCalculator { ); this.redisCacheService.set( - this.redisCacheService.getPortfolioSnapshotKey(this.userId), + this.redisCacheService.getPortfolioSnapshotKey({ + userId: this.userId + }), JSON.stringify(this.snapshot), this.configurationService.get('CACHE_QUOTES_TTL') ); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts index 422cf8bff..340f16b87 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell-in-two-activities.spec.ts @@ -123,6 +123,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'CHF', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts index dee8b2478..53ebdf19f 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts @@ -108,6 +108,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'CHF', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts index db8ce01b3..bab265887 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy.spec.ts @@ -93,6 +93,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'CHF', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts index 5a403eda1..eba5d4674 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-btcusd-buy-and-sell-partially.spec.ts @@ -121,6 +121,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'CHF', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts index 97a77492b..88d7adb71 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-fee.spec.ts @@ -93,6 +93,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'USD', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts index c916a381d..690f1eb51 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-googl-buy.spec.ts @@ -106,6 +106,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'CHF', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-item.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-item.spec.ts index bf212f80b..422d119b2 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-item.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-item.spec.ts @@ -93,6 +93,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'USD', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts index 3ae63c72a..d468e8e00 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-liability.spec.ts @@ -93,6 +93,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'USD', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts index 6948b4dbd..094c6cc2e 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-msft-buy-with-dividend.spec.ts @@ -121,6 +121,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'USD', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts index 1dd74d7e5..6bb432bfc 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-no-orders.spec.ts @@ -71,6 +71,7 @@ describe('PortfolioCalculator', () => { activities: [], calculationType: PerformanceCalculationType.TWR, currency: 'CHF', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts index d4451503a..f65d2ba61 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell-partially.spec.ts @@ -108,6 +108,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'CHF', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts index 7850fb2bd..902f710ee 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts @@ -108,6 +108,7 @@ describe('PortfolioCalculator', () => { activities, calculationType: PerformanceCalculationType.TWR, currency: 'CHF', + hasFilters: false, userId: userDummyData.id }); diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 573c48a83..61906982b 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -277,9 +277,11 @@ export class PortfolioService { const portfolioCalculator = this.calculatorFactory.createCalculator({ activities, + dateRange, userId, calculationType: PerformanceCalculationType.TWR, currency: this.request.user.Settings.settings.baseCurrency, + hasFilters: filters?.length > 0, isExperimentalFeatures: this.request.user.Settings.settings.isExperimentalFeatures }); @@ -358,6 +360,7 @@ export class PortfolioService { userId, calculationType: PerformanceCalculationType.TWR, currency: userCurrency, + hasFilters: filters?.length > 0, isExperimentalFeatures: this.request.user?.Settings.settings.isExperimentalFeatures }); @@ -660,6 +663,7 @@ export class PortfolioService { }), calculationType: PerformanceCalculationType.TWR, currency: userCurrency, + hasFilters: true, isExperimentalFeatures: this.request.user.Settings.settings.isExperimentalFeatures }); @@ -931,6 +935,7 @@ export class PortfolioService { userId, calculationType: PerformanceCalculationType.TWR, currency: this.request.user.Settings.settings.baseCurrency, + hasFilters: filters?.length > 0, isExperimentalFeatures: this.request.user.Settings.settings.isExperimentalFeatures }); @@ -1085,7 +1090,7 @@ export class PortfolioService { ) ); - const { endDate, startDate } = getInterval(dateRange); + const { endDate } = getInterval(dateRange); const { activities } = await this.orderService.getOrders({ endDate, @@ -1123,6 +1128,7 @@ export class PortfolioService { userId, calculationType: PerformanceCalculationType.TWR, currency: userCurrency, + hasFilters: filters?.length > 0, isExperimentalFeatures: this.request.user.Settings.settings.isExperimentalFeatures }); @@ -1220,6 +1226,7 @@ export class PortfolioService { userId, calculationType: PerformanceCalculationType.TWR, currency: this.request.user.Settings.settings.baseCurrency, + hasFilters: false, isExperimentalFeatures: this.request.user.Settings.settings.isExperimentalFeatures }); diff --git a/apps/api/src/app/redis-cache/redis-cache.service.ts b/apps/api/src/app/redis-cache/redis-cache.service.ts index a313eadf1..53b177b4f 100644 --- a/apps/api/src/app/redis-cache/redis-cache.service.ts +++ b/apps/api/src/app/redis-cache/redis-cache.service.ts @@ -24,7 +24,7 @@ export class RedisCacheService { return this.cache.get(key); } - public getPortfolioSnapshotKey(userId: string) { + public getPortfolioSnapshotKey({ userId }: { userId: string }) { return `portfolio-snapshot-${userId}`; } diff --git a/apps/api/src/events/portfolio-changed.listener.ts b/apps/api/src/events/portfolio-changed.listener.ts index 0f8877127..4a6e3d386 100644 --- a/apps/api/src/events/portfolio-changed.listener.ts +++ b/apps/api/src/events/portfolio-changed.listener.ts @@ -17,7 +17,9 @@ export class PortfolioChangedListener { ); this.redisCacheService.remove( - this.redisCacheService.getPortfolioSnapshotKey(event.getUserId()) + this.redisCacheService.getPortfolioSnapshotKey({ + userId: event.getUserId() + }) ); } } From 486de968a2130bf9d6ed880b43a018e553a61acf Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 2 May 2024 17:53:34 +0200 Subject: [PATCH 174/203] Bugfix/fix division by zero error in dividend yield calculation (#3354) * Handle division by zero * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/portfolio/portfolio.service.ts | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50e732acb..8b3bdbbac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fixed an issue in the calculation of the portfolio summary caused by future liabilities +- Fixed a division by zero error in the dividend yield calculation (experimental) ## 2.77.1 - 2024-04-27 diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 61906982b..10c09a21f 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -704,17 +704,19 @@ export class PortfolioService { const dividendYieldPercent = this.getAnnualizedPerformancePercent({ daysInMarket: differenceInDays(new Date(), parseDate(firstBuyDate)), - netPerformancePercent: dividendInBaseCurrency.div( - timeWeightedInvestment - ) + netPerformancePercent: timeWeightedInvestment.eq(0) + ? new Big(0) + : dividendInBaseCurrency.div(timeWeightedInvestment) }); const dividendYieldPercentWithCurrencyEffect = this.getAnnualizedPerformancePercent({ daysInMarket: differenceInDays(new Date(), parseDate(firstBuyDate)), - netPerformancePercent: dividendInBaseCurrency.div( - timeWeightedInvestmentWithCurrencyEffect - ) + netPerformancePercent: timeWeightedInvestmentWithCurrencyEffect.eq(0) + ? new Big(0) + : dividendInBaseCurrency.div( + timeWeightedInvestmentWithCurrencyEffect + ) }); const historicalData = await this.dataProviderService.getHistorical( From 4416ba0c88a141f8f06e74eea67217d17683fdae Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 2 May 2024 19:16:59 +0200 Subject: [PATCH 175/203] Feature/set performance column of holdings table to stick at end (#3353) * Set up stickyEnd in performance column * Update changelog --- CHANGELOG.md | 1 + libs/ui/src/lib/holdings-table/holdings-table.component.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b3bdbbac..5dc779dba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Set the performance column of the holdings table to stick at the end - Skipped the caching in the portfolio calculator if there are active filters (experimental) ### Fixed diff --git a/libs/ui/src/lib/holdings-table/holdings-table.component.html b/libs/ui/src/lib/holdings-table/holdings-table.component.html index 8c0bca20f..181b120a8 100644 --- a/libs/ui/src/lib/holdings-table/holdings-table.component.html +++ b/libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -109,7 +109,7 @@ - + Date: Thu, 2 May 2024 20:31:20 +0200 Subject: [PATCH 176/203] Feature/improve inactive user role (#3360) * Improve inactive role * Update changelog --- CHANGELOG.md | 1 + apps/api/src/app/auth/jwt.strategy.ts | 27 ++++++++++++++++++++---- apps/api/src/app/user/user.controller.ts | 13 +----------- apps/client/src/app/core/auth.guard.ts | 7 +++--- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dc779dba..467738562 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Set the performance column of the holdings table to stick at the end - Skipped the caching in the portfolio calculator if there are active filters (experimental) +- Improved the `INACTIVE` user role ### Fixed diff --git a/apps/api/src/app/auth/jwt.strategy.ts b/apps/api/src/app/auth/jwt.strategy.ts index c7ce38986..a8ad8fd08 100644 --- a/apps/api/src/app/auth/jwt.strategy.ts +++ b/apps/api/src/app/auth/jwt.strategy.ts @@ -2,10 +2,12 @@ import { UserService } from '@ghostfolio/api/app/user/user.service'; import { ConfigurationService } from '@ghostfolio/api/services/configuration/configuration.service'; import { PrismaService } from '@ghostfolio/api/services/prisma/prisma.service'; import { HEADER_KEY_TIMEZONE } from '@ghostfolio/common/config'; +import { hasRole } from '@ghostfolio/common/permissions'; -import { Injectable, UnauthorizedException } from '@nestjs/common'; +import { HttpException, Injectable } from '@nestjs/common'; import { PassportStrategy } from '@nestjs/passport'; import * as countriesAndTimezones from 'countries-and-timezones'; +import { StatusCodes, getReasonPhrase } from 'http-status-codes'; import { ExtractJwt, Strategy } from 'passport-jwt'; @Injectable() @@ -29,6 +31,13 @@ export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') { if (user) { if (this.configurationService.get('ENABLE_FEATURE_SUBSCRIPTION')) { + if (hasRole(user, 'INACTIVE')) { + throw new HttpException( + getReasonPhrase(StatusCodes.TOO_MANY_REQUESTS), + StatusCodes.TOO_MANY_REQUESTS + ); + } + const country = countriesAndTimezones.getCountryForTimezone(timezone)?.id; @@ -45,10 +54,20 @@ export class JwtStrategy extends PassportStrategy(Strategy, 'jwt') { return user; } else { - throw ''; + throw new HttpException( + getReasonPhrase(StatusCodes.NOT_FOUND), + StatusCodes.NOT_FOUND + ); + } + } catch (error) { + if (error?.getStatus() === StatusCodes.TOO_MANY_REQUESTS) { + throw error; + } else { + throw new HttpException( + getReasonPhrase(StatusCodes.UNAUTHORIZED), + StatusCodes.UNAUTHORIZED + ); } - } catch (err) { - throw new UnauthorizedException('unauthorized', err.message); } } } diff --git a/apps/api/src/app/user/user.controller.ts b/apps/api/src/app/user/user.controller.ts index 14c545192..39e78dcdc 100644 --- a/apps/api/src/app/user/user.controller.ts +++ b/apps/api/src/app/user/user.controller.ts @@ -2,11 +2,7 @@ import { HasPermission } from '@ghostfolio/api/decorators/has-permission.decorat import { HasPermissionGuard } from '@ghostfolio/api/guards/has-permission.guard'; import { PropertyService } from '@ghostfolio/api/services/property/property.service'; import { User, UserSettings } from '@ghostfolio/common/interfaces'; -import { - hasPermission, - hasRole, - permissions -} from '@ghostfolio/common/permissions'; +import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import type { RequestWithUser } from '@ghostfolio/common/types'; import { @@ -63,13 +59,6 @@ export class UserController { public async getUser( @Headers('accept-language') acceptLanguage: string ): Promise { - if (hasRole(this.request.user, 'INACTIVE')) { - throw new HttpException( - getReasonPhrase(StatusCodes.TOO_MANY_REQUESTS), - StatusCodes.TOO_MANY_REQUESTS - ); - } - return this.userService.getUser( this.request.user, acceptLanguage?.split(',')?.[0] diff --git a/apps/client/src/app/core/auth.guard.ts b/apps/client/src/app/core/auth.guard.ts index 52d1e14ab..ee5ed77cd 100644 --- a/apps/client/src/app/core/auth.guard.ts +++ b/apps/client/src/app/core/auth.guard.ts @@ -54,9 +54,10 @@ export class AuthGuard { this.router.navigate(['/' + $localize`register`]); resolve(false); } else if ( - AuthGuard.PUBLIC_PAGE_ROUTES.filter((publicPageRoute) => - state.url.startsWith(publicPageRoute) - )?.length > 0 + AuthGuard.PUBLIC_PAGE_ROUTES.filter((publicPageRoute) => { + const [, url] = state.url.split('/'); + return `/${url}` === publicPageRoute; + })?.length > 0 ) { resolve(true); return EMPTY; From d9c07456cd52acff1d906893eb6b6de1ff76ecc1 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Thu, 2 May 2024 20:32:47 +0200 Subject: [PATCH 177/203] Release 2.78.0 (#3361) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 467738562..bc79a2ddf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.78.0 - 2024-05-02 ### Added diff --git a/package.json b/package.json index 35a66b550..e2bb13468 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.77.1", + "version": "2.78.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 77beaaba082cdc2d7f72605b28465efd29462283 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Fri, 3 May 2024 21:48:46 +0200 Subject: [PATCH 178/203] Refactoring portfolio service (#3365) --- apps/api/src/app/portfolio/portfolio.service.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 10c09a21f..4be9d4e00 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -1604,7 +1604,7 @@ export class PortfolioService { userId = await this.getUserId(impersonationId, userId); const user = await this.userService.user({ id: userId }); - const performanceInformation = await this.getPerformance({ + const { performance } = await this.getPerformance({ impersonationId, userId }); @@ -1694,7 +1694,7 @@ export class PortfolioService { .toNumber(); const netWorth = new Big(balanceInBaseCurrency) - .plus(performanceInformation.performance.currentValue) + .plus(performance.currentValue) .plus(valuables) .plus(excludedAccountsAndActivities) .minus(liabilities) @@ -1704,21 +1704,19 @@ export class PortfolioService { const annualizedPerformancePercent = this.getAnnualizedPerformancePercent({ daysInMarket, - netPerformancePercent: new Big( - performanceInformation.performance.currentNetPerformancePercent - ) + netPerformancePercent: new Big(performance.currentNetPerformancePercent) })?.toNumber(); const annualizedPerformancePercentWithCurrencyEffect = this.getAnnualizedPerformancePercent({ daysInMarket, netPerformancePercent: new Big( - performanceInformation.performance.currentNetPerformancePercentWithCurrencyEffect + performance.currentNetPerformancePercentWithCurrencyEffect ) })?.toNumber(); return { - ...performanceInformation.performance, + ...performance, annualizedPerformancePercent, annualizedPerformancePercentWithCurrencyEffect, cash, @@ -1740,7 +1738,7 @@ export class PortfolioService { filteredValueInPercentage: netWorth ? filteredValueInBaseCurrency.div(netWorth).toNumber() : undefined, - fireWealth: new Big(performanceInformation.performance.currentValue) + fireWealth: new Big(performance.currentValue) .minus(emergencyFundPositionsValueInBaseCurrency) .toNumber(), interest: interest.toNumber(), From 42b70ef56890e640a2d49d03c9ef0039b8050589 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 4 May 2024 07:49:37 +0200 Subject: [PATCH 179/203] Feature/improve performance labels in position detail dialog (#3363) * Improve performance labels (with and without currency effects) * Update changelog --- CHANGELOG.md | 6 + .../position-detail-dialog.component.ts | 16 +- .../position-detail-dialog.html | 69 +++++--- apps/client/src/locales/messages.de.xlf | 156 ++++++++++-------- apps/client/src/locales/messages.es.xlf | 156 ++++++++++-------- apps/client/src/locales/messages.fr.xlf | 156 ++++++++++-------- apps/client/src/locales/messages.it.xlf | 156 ++++++++++-------- apps/client/src/locales/messages.nl.xlf | 156 ++++++++++-------- apps/client/src/locales/messages.pl.xlf | 156 ++++++++++-------- apps/client/src/locales/messages.pt.xlf | 156 ++++++++++-------- apps/client/src/locales/messages.tr.xlf | 156 ++++++++++-------- apps/client/src/locales/messages.xlf | 154 +++++++++-------- apps/client/src/locales/messages.zh.xlf | 156 ++++++++++-------- libs/ui/src/lib/value/value.component.html | 4 +- 14 files changed, 927 insertions(+), 726 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc79a2ddf..8ba54382c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Changed + +- Improved the performance labels (with and without currency effects) in the position detail dialog + ## 2.78.0 - 2024-05-02 ### Added diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts index bb37b9ed5..2a0303686 100644 --- a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts +++ b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts @@ -56,6 +56,8 @@ export class PositionDetailDialog implements OnDestroy, OnInit { public marketPrice: number; public maxPrice: number; public minPrice: number; + public netPerformance: number; + public netPerformancePercent: number; public netPerformancePercentWithCurrencyEffect: number; public netPerformanceWithCurrencyEffect: number; public quantity: number; @@ -104,6 +106,8 @@ export class PositionDetailDialog implements OnDestroy, OnInit { marketPrice, maxPrice, minPrice, + netPerformance, + netPerformancePercent, netPerformancePercentWithCurrencyEffect, netPerformanceWithCurrencyEffect, orders, @@ -126,15 +130,15 @@ export class PositionDetailDialog implements OnDestroy, OnInit { this.feeInBaseCurrency = feeInBaseCurrency; this.firstBuyDate = firstBuyDate; this.historicalDataItems = historicalData.map( - (historicalDataItem) => { + ({ averagePrice, date, marketPrice }) => { this.benchmarkDataItems.push({ - date: historicalDataItem.date, - value: historicalDataItem.averagePrice + date, + value: averagePrice }); return { - date: historicalDataItem.date, - value: historicalDataItem.marketPrice + date, + value: marketPrice }; } ); @@ -142,6 +146,8 @@ export class PositionDetailDialog implements OnDestroy, OnInit { this.marketPrice = marketPrice; this.maxPrice = maxPrice; this.minPrice = minPrice; + this.netPerformance = netPerformance; + this.netPerformancePercent = netPerformancePercent; this.netPerformancePercentWithCurrencyEffect = netPerformancePercentWithCurrencyEffect; this.netPerformanceWithCurrencyEffect = diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html index 537fe104d..9ae432a35 100644 --- a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html +++ b/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html @@ -37,27 +37,58 @@
- Change + @if ( + SymbolProfile?.currency && + data.baseCurrency !== SymbolProfile?.currency + ) { + Change with currency effect + } @else { + Change + }
- Performance + @if ( + SymbolProfile?.currency && + data.baseCurrency !== SymbolProfile?.currency + ) { + Performance with currency effect + } @else { + Performance + }
apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 190 + 221 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 300 + 331 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -138,7 +138,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 7 + 12 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -146,7 +146,7 @@ apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 7 + 12 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -154,7 +154,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 138 + 134 libs/ui/src/lib/activities-table/activities-table.component.html @@ -190,31 +190,31 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 198 + 194 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 199 + 195 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 201 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 263 + 257 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 264 + 258 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 265 + 259 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 260 libs/ui/src/lib/account-balances/account-balances.component.html @@ -338,7 +338,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 270 + 301 @@ -354,7 +354,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 154 + 150 @@ -446,7 +446,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 160 + 156 libs/ui/src/lib/account-balances/account-balances.component.html @@ -466,7 +466,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 81 + 112 @@ -486,11 +486,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 39 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 13 + 22 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -506,7 +506,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 408 + 399 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -530,11 +530,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 33 + 46 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 20 + 29 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -546,7 +546,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 415 + 406 @@ -562,7 +562,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 178 + 209 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -842,7 +842,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 325 + 356 apps/client/src/app/pages/accounts/accounts-page.html @@ -1350,7 +1350,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 134 + 165 @@ -1472,7 +1472,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 146 + 177 apps/client/src/app/pages/features/features-page.html @@ -1480,11 +1480,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 196 + 192 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 261 + 255 @@ -1508,7 +1508,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 239 + 270 apps/client/src/app/pages/public/public-page.html @@ -1528,7 +1528,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 251 + 282 @@ -1540,11 +1540,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 345 + 376 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 363 + 355 libs/ui/src/lib/assistant/assistant.html @@ -1556,7 +1556,7 @@ Datenfehler melden apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 363 + 394 @@ -1576,7 +1576,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 59 + 89 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -2076,7 +2076,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 144 + 140 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2448,7 +2448,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 122 + 120 @@ -2456,11 +2456,11 @@ Anzahl apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 123 + 154 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 183 + 179 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2472,11 +2472,11 @@ Stückpreis apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 203 + 199 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 267 + 261 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2488,11 +2488,11 @@ Gebühr apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 + 280 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 310 + 302 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2512,7 +2512,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 319 + 311 @@ -2532,11 +2532,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 197 + 228 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 334 + 326 @@ -2852,7 +2852,7 @@ Änderung apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 48 + 63 @@ -2860,7 +2860,7 @@ Ø Preis pro Einheit apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 70 + 101 @@ -2868,7 +2868,7 @@ Minimum Preis apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 97 + 128 @@ -2876,7 +2876,7 @@ Maximum Preis apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 113 + 144 @@ -2896,11 +2896,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 206 + 237 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 350 + 342 @@ -2912,7 +2912,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 223 + 254 @@ -2928,7 +2928,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 233 + 264 @@ -2972,7 +2972,7 @@ Projizierter Gesamtbetrag libs/ui/src/lib/fire-calculator/fire-calculator.component.html - 60 + 57 @@ -3924,7 +3924,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 168 + 199 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -4028,7 +4028,7 @@ Ups! Der historische Wechselkurs konnte nicht abgerufen werden vom apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 300 + 292 @@ -4136,7 +4136,7 @@ Plattform bearbeiten apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 2 + 7 @@ -4144,7 +4144,7 @@ Plattform hinzufügen apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 3 + 8 @@ -4160,7 +4160,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 13 + 22 @@ -4184,7 +4184,7 @@ Cash-Bestand aktualisieren apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 110 + 108 @@ -13236,7 +13236,7 @@ Ups! Der historische Wechselkurs konnte nicht abgerufen werden vom apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 232 + 226 @@ -13284,7 +13284,7 @@ Tag bearbeiten apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 2 + 7 @@ -13292,7 +13292,7 @@ Tag hinzufügen apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 3 + 8 @@ -13736,7 +13736,7 @@ Ups, der Cash-Bestand Transfer ist fehlgeschlagen. apps/client/src/app/pages/accounts/accounts-page.component.ts - 308 + 304 @@ -13784,7 +13784,7 @@ Ups! Die historischen Daten konnten nicht geparsed werden. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 235 + 236 @@ -14632,7 +14632,7 @@ Möchtest du diesen Cash-Bestand wirklich löschen? libs/ui/src/lib/account-balances/account-balances.component.ts - 104 + 102 @@ -14656,7 +14656,7 @@ Der aktuelle Marktpreis ist apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 330 + 342 @@ -14704,7 +14704,7 @@ Ups! Der Zugang konnte nicht gewährt werden. apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts - 80 + 88 @@ -15000,7 +15000,7 @@ Aktivität apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 188 + 219 @@ -15008,7 +15008,7 @@ Dividendenrendite apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 156 + 187 @@ -15043,6 +15043,22 @@ 43 + + Change with currency effect + Änderung mit Währungseffekt + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 52 + + + + Performance with currency effect + Performance mit Währungseffekt + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 79 + + diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index 42e5e299a..09dd7c44a 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -107,11 +107,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 190 + 221 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 300 + 331 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -139,7 +139,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 7 + 12 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -147,7 +147,7 @@ apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 7 + 12 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -155,7 +155,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 138 + 134 libs/ui/src/lib/activities-table/activities-table.component.html @@ -191,31 +191,31 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 198 + 194 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 199 + 195 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 201 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 263 + 257 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 264 + 258 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 265 + 259 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 260 libs/ui/src/lib/account-balances/account-balances.component.html @@ -339,7 +339,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 270 + 301 @@ -355,7 +355,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 154 + 150 @@ -447,7 +447,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 160 + 156 libs/ui/src/lib/account-balances/account-balances.component.html @@ -467,7 +467,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 81 + 112 @@ -487,11 +487,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 39 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 13 + 22 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -507,7 +507,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 408 + 399 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -531,11 +531,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 33 + 46 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 20 + 29 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -547,7 +547,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 415 + 406 @@ -563,7 +563,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 178 + 209 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -843,7 +843,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 325 + 356 apps/client/src/app/pages/accounts/accounts-page.html @@ -1351,7 +1351,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 134 + 165 @@ -1470,7 +1470,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 146 + 177 apps/client/src/app/pages/features/features-page.html @@ -1478,11 +1478,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 196 + 192 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 261 + 255 @@ -1506,7 +1506,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 239 + 270 apps/client/src/app/pages/public/public-page.html @@ -1526,7 +1526,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 251 + 282 @@ -1538,11 +1538,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 345 + 376 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 363 + 355 libs/ui/src/lib/assistant/assistant.html @@ -1554,7 +1554,7 @@ Reporta un anomalía de los datos apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 363 + 394 @@ -1574,7 +1574,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 59 + 89 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -2074,7 +2074,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 144 + 140 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2446,7 +2446,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 122 + 120 @@ -2454,11 +2454,11 @@ Cantidad apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 123 + 154 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 183 + 179 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2470,11 +2470,11 @@ Precio unitario apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 203 + 199 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 267 + 261 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2486,11 +2486,11 @@ Comisión apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 + 280 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 310 + 302 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2510,7 +2510,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 319 + 311 @@ -2530,11 +2530,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 197 + 228 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 334 + 326 @@ -2850,7 +2850,7 @@ Modificar apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 48 + 63 @@ -2882,11 +2882,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 206 + 237 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 350 + 342 @@ -2894,7 +2894,7 @@ Precio unitario medio apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 70 + 101 @@ -2902,7 +2902,7 @@ Precio máximo apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 113 + 144 @@ -2938,7 +2938,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 223 + 254 @@ -2954,7 +2954,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 233 + 264 @@ -2962,7 +2962,7 @@ Precio mínimo apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 97 + 128 @@ -2970,7 +2970,7 @@ Importe total previsto libs/ui/src/lib/fire-calculator/fire-calculator.component.html - 60 + 57 @@ -3922,7 +3922,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 168 + 199 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -4026,7 +4026,7 @@ Oops! Could not get the historical exchange rate from apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 300 + 292 @@ -4134,7 +4134,7 @@ Update platform apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 2 + 7 @@ -4142,7 +4142,7 @@ Add platform apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 3 + 8 @@ -4158,7 +4158,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 13 + 22 @@ -4182,7 +4182,7 @@ Update Cash Balance apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 110 + 108 @@ -13234,7 +13234,7 @@ Oops! Could not get the historical exchange rate from apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 232 + 226 @@ -13282,7 +13282,7 @@ Update tag apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 2 + 7 @@ -13290,7 +13290,7 @@ Add tag apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 3 + 8 @@ -13734,7 +13734,7 @@ Oops, cash balance transfer has failed. apps/client/src/app/pages/accounts/accounts-page.component.ts - 308 + 304 @@ -13782,7 +13782,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 235 + 236 @@ -14630,7 +14630,7 @@ Do you really want to delete this account balance? libs/ui/src/lib/account-balances/account-balances.component.ts - 104 + 102 @@ -14654,7 +14654,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 330 + 342 @@ -14702,7 +14702,7 @@ Oops! Could not grant access. apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts - 80 + 88 @@ -14998,7 +14998,7 @@ Activity apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 188 + 219 @@ -15006,7 +15006,7 @@ Dividend Yield apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 156 + 187 @@ -15041,6 +15041,22 @@ 43 + + Change with currency effect + Change with currency effect + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 52 + + + + Performance with currency effect + Performance with currency effect + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 79 + + diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index 3955e6dd8..9042459f8 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -118,11 +118,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 190 + 221 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 300 + 331 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -150,7 +150,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 7 + 12 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -158,7 +158,7 @@ apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 7 + 12 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -166,7 +166,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 138 + 134 libs/ui/src/lib/activities-table/activities-table.component.html @@ -206,7 +206,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 144 + 140 libs/ui/src/lib/activities-table/activities-table.component.html @@ -246,31 +246,31 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 198 + 194 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 199 + 195 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 201 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 263 + 257 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 264 + 258 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 265 + 259 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 260 libs/ui/src/lib/account-balances/account-balances.component.html @@ -386,7 +386,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 270 + 301 @@ -402,7 +402,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 154 + 150 @@ -502,7 +502,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 160 + 156 libs/ui/src/lib/account-balances/account-balances.component.html @@ -522,7 +522,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 81 + 112 @@ -542,11 +542,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 39 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 13 + 22 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -562,7 +562,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 408 + 399 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -586,11 +586,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 33 + 46 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 20 + 29 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -602,7 +602,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 415 + 406 @@ -630,11 +630,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 197 + 228 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 334 + 326 @@ -654,11 +654,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 206 + 237 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 350 + 342 @@ -674,7 +674,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 178 + 209 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -762,7 +762,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 223 + 254 @@ -778,7 +778,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 233 + 264 @@ -794,7 +794,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 239 + 270 apps/client/src/app/pages/public/public-page.html @@ -814,7 +814,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 251 + 282 @@ -838,7 +838,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 319 + 311 @@ -930,11 +930,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 345 + 376 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 363 + 355 libs/ui/src/lib/assistant/assistant.html @@ -1054,7 +1054,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 325 + 356 apps/client/src/app/pages/accounts/accounts-page.html @@ -1090,7 +1090,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 59 + 89 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -1714,7 +1714,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 134 + 165 @@ -1841,7 +1841,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 146 + 177 apps/client/src/app/pages/features/features-page.html @@ -1849,11 +1849,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 196 + 192 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 261 + 255 @@ -1869,7 +1869,7 @@ Différence apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 48 + 63 @@ -1877,7 +1877,7 @@ Prix Unitaire Moyen apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 70 + 101 @@ -1885,7 +1885,7 @@ Prix Minimum apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 97 + 128 @@ -1893,7 +1893,7 @@ Prix Maximum apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 113 + 144 @@ -1901,11 +1901,11 @@ Quantité apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 123 + 154 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 183 + 179 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1917,7 +1917,7 @@ Signaler une Erreur de Données apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 363 + 394 @@ -2673,7 +2673,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 122 + 120 @@ -2681,11 +2681,11 @@ Prix Unitaire apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 203 + 199 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 267 + 261 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2697,11 +2697,11 @@ Frais apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 + 280 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 310 + 302 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3309,7 +3309,7 @@ Montant Total Prévu libs/ui/src/lib/fire-calculator/fire-calculator.component.html - 60 + 57 @@ -3921,7 +3921,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 168 + 199 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -4025,7 +4025,7 @@ Oups ! Nous n'avons pas pu obtenir le taux de change historique à partir de apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 300 + 292 @@ -4133,7 +4133,7 @@ Mettre à jour la Plateforme apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 2 + 7 @@ -4141,7 +4141,7 @@ Ajouter une Plateforme apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 3 + 8 @@ -4157,7 +4157,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 13 + 22 @@ -4181,7 +4181,7 @@ Mettre à jour le Solde apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 110 + 108 @@ -13233,7 +13233,7 @@ Oops! Could not get the historical exchange rate from apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 232 + 226 @@ -13281,7 +13281,7 @@ Update tag apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 2 + 7 @@ -13289,7 +13289,7 @@ Add tag apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 3 + 8 @@ -13733,7 +13733,7 @@ Oops, cash balance transfer has failed. apps/client/src/app/pages/accounts/accounts-page.component.ts - 308 + 304 @@ -13781,7 +13781,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 235 + 236 @@ -14629,7 +14629,7 @@ Do you really want to delete this account balance? libs/ui/src/lib/account-balances/account-balances.component.ts - 104 + 102 @@ -14653,7 +14653,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 330 + 342 @@ -14701,7 +14701,7 @@ Oops! Could not grant access. apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts - 80 + 88 @@ -14997,7 +14997,7 @@ Activity apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 188 + 219 @@ -15005,7 +15005,7 @@ Dividend Yield apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 156 + 187 @@ -15040,6 +15040,22 @@ 43 + + Change with currency effect + Change with currency effect + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 52 + + + + Performance with currency effect + Performance with currency effect + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 79 + + diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index 7aafd8d57..6e141e532 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -107,11 +107,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 190 + 221 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 300 + 331 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -139,7 +139,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 7 + 12 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -147,7 +147,7 @@ apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 7 + 12 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -155,7 +155,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 138 + 134 libs/ui/src/lib/activities-table/activities-table.component.html @@ -191,31 +191,31 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 198 + 194 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 199 + 195 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 201 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 263 + 257 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 264 + 258 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 265 + 259 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 260 libs/ui/src/lib/account-balances/account-balances.component.html @@ -339,7 +339,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 270 + 301 @@ -355,7 +355,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 154 + 150 @@ -447,7 +447,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 160 + 156 libs/ui/src/lib/account-balances/account-balances.component.html @@ -467,7 +467,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 81 + 112 @@ -487,11 +487,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 39 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 13 + 22 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -507,7 +507,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 408 + 399 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -531,11 +531,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 33 + 46 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 20 + 29 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -547,7 +547,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 415 + 406 @@ -563,7 +563,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 178 + 209 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -843,7 +843,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 325 + 356 apps/client/src/app/pages/accounts/accounts-page.html @@ -1351,7 +1351,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 134 + 165 @@ -1470,7 +1470,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 146 + 177 apps/client/src/app/pages/features/features-page.html @@ -1478,11 +1478,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 196 + 192 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 261 + 255 @@ -1506,7 +1506,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 239 + 270 apps/client/src/app/pages/public/public-page.html @@ -1526,7 +1526,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 251 + 282 @@ -1538,11 +1538,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 345 + 376 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 363 + 355 libs/ui/src/lib/assistant/assistant.html @@ -1554,7 +1554,7 @@ Segnala un'anomalia dei dati apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 363 + 394 @@ -1574,7 +1574,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 59 + 89 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -2074,7 +2074,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 144 + 140 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2446,7 +2446,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 122 + 120 @@ -2454,11 +2454,11 @@ Quantità apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 123 + 154 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 183 + 179 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2470,11 +2470,11 @@ Prezzo unitario apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 203 + 199 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 267 + 261 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2486,11 +2486,11 @@ Commissione apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 + 280 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 310 + 302 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2510,7 +2510,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 319 + 311 @@ -2530,11 +2530,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 197 + 228 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 334 + 326 @@ -2850,7 +2850,7 @@ Modifica apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 48 + 63 @@ -2882,11 +2882,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 206 + 237 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 350 + 342 @@ -2894,7 +2894,7 @@ Prezzo unitario medio apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 70 + 101 @@ -2902,7 +2902,7 @@ Prezzo massimo apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 113 + 144 @@ -2938,7 +2938,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 223 + 254 @@ -2954,7 +2954,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 233 + 264 @@ -2962,7 +2962,7 @@ Prezzo minimo apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 97 + 128 @@ -2970,7 +2970,7 @@ Importo totale previsto libs/ui/src/lib/fire-calculator/fire-calculator.component.html - 60 + 57 @@ -3922,7 +3922,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 168 + 199 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -4026,7 +4026,7 @@ Ops! Impossibile ottenere il tasso di cambio storico da apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 300 + 292 @@ -4134,7 +4134,7 @@ Aggiorna la piattaforma apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 2 + 7 @@ -4142,7 +4142,7 @@ Aggiungi la piattaforma apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 3 + 8 @@ -4158,7 +4158,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 13 + 22 @@ -4182,7 +4182,7 @@ Aggiornamento del saldo di cassa apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 110 + 108 @@ -13234,7 +13234,7 @@ Oops! Could not get the historical exchange rate from apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 232 + 226 @@ -13282,7 +13282,7 @@ Update tag apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 2 + 7 @@ -13290,7 +13290,7 @@ Add tag apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 3 + 8 @@ -13734,7 +13734,7 @@ Oops, cash balance transfer has failed. apps/client/src/app/pages/accounts/accounts-page.component.ts - 308 + 304 @@ -13782,7 +13782,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 235 + 236 @@ -14630,7 +14630,7 @@ Do you really want to delete this account balance? libs/ui/src/lib/account-balances/account-balances.component.ts - 104 + 102 @@ -14654,7 +14654,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 330 + 342 @@ -14702,7 +14702,7 @@ Oops! Could not grant access. apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts - 80 + 88 @@ -14998,7 +14998,7 @@ Activity apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 188 + 219 @@ -15006,7 +15006,7 @@ Dividend Yield apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 156 + 187 @@ -15041,6 +15041,22 @@ 43 + + Change with currency effect + Change with currency effect + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 52 + + + + Performance with currency effect + Performance with currency effect + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 79 + + diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index 65a45962a..da29f87e3 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -106,11 +106,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 190 + 221 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 300 + 331 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -138,7 +138,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 7 + 12 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -146,7 +146,7 @@ apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 7 + 12 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -154,7 +154,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 138 + 134 libs/ui/src/lib/activities-table/activities-table.component.html @@ -190,31 +190,31 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 198 + 194 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 199 + 195 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 201 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 263 + 257 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 264 + 258 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 265 + 259 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 260 libs/ui/src/lib/account-balances/account-balances.component.html @@ -338,7 +338,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 270 + 301 @@ -354,7 +354,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 154 + 150 @@ -446,7 +446,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 160 + 156 libs/ui/src/lib/account-balances/account-balances.component.html @@ -466,7 +466,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 81 + 112 @@ -486,11 +486,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 39 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 13 + 22 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -506,7 +506,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 408 + 399 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -530,11 +530,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 33 + 46 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 20 + 29 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -546,7 +546,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 415 + 406 @@ -562,7 +562,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 178 + 209 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -842,7 +842,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 325 + 356 apps/client/src/app/pages/accounts/accounts-page.html @@ -1350,7 +1350,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 134 + 165 @@ -1469,7 +1469,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 146 + 177 apps/client/src/app/pages/features/features-page.html @@ -1477,11 +1477,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 196 + 192 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 261 + 255 @@ -1505,7 +1505,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 239 + 270 apps/client/src/app/pages/public/public-page.html @@ -1525,7 +1525,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 251 + 282 @@ -1537,11 +1537,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 345 + 376 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 363 + 355 libs/ui/src/lib/assistant/assistant.html @@ -1553,7 +1553,7 @@ Gegevensstoring melden apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 363 + 394 @@ -1573,7 +1573,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 59 + 89 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -2073,7 +2073,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 144 + 140 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2445,7 +2445,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 122 + 120 @@ -2453,11 +2453,11 @@ Hoeveelheid apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 123 + 154 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 183 + 179 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2469,11 +2469,11 @@ Prijs per eenheid apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 203 + 199 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 267 + 261 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2485,11 +2485,11 @@ Transactiekosten apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 + 280 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 310 + 302 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2509,7 +2509,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 319 + 311 @@ -2529,11 +2529,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 197 + 228 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 334 + 326 @@ -2849,7 +2849,7 @@ Verandering apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 48 + 63 @@ -2881,11 +2881,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 206 + 237 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 350 + 342 @@ -2893,7 +2893,7 @@ Gemiddelde prijs per eenheid apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 70 + 101 @@ -2901,7 +2901,7 @@ Maximale prijs apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 113 + 144 @@ -2937,7 +2937,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 223 + 254 @@ -2953,7 +2953,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 233 + 264 @@ -2961,7 +2961,7 @@ Minimale prijs apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 97 + 128 @@ -2969,7 +2969,7 @@ Verwacht totaalbedrag libs/ui/src/lib/fire-calculator/fire-calculator.component.html - 60 + 57 @@ -3921,7 +3921,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 168 + 199 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -4025,7 +4025,7 @@ Oeps! Kon de historische wisselkoers niet krijgen van apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 300 + 292 @@ -4133,7 +4133,7 @@ Platform bijwerken apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 2 + 7 @@ -4141,7 +4141,7 @@ Platform toevoegen apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 3 + 8 @@ -4157,7 +4157,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 13 + 22 @@ -4181,7 +4181,7 @@ Saldo bijwerken apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 110 + 108 @@ -13233,7 +13233,7 @@ Oops! Could not get the historical exchange rate from apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 232 + 226 @@ -13281,7 +13281,7 @@ Update tag apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 2 + 7 @@ -13289,7 +13289,7 @@ Add tag apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 3 + 8 @@ -13733,7 +13733,7 @@ Oops, cash balance transfer has failed. apps/client/src/app/pages/accounts/accounts-page.component.ts - 308 + 304 @@ -13781,7 +13781,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 235 + 236 @@ -14629,7 +14629,7 @@ Do you really want to delete this account balance? libs/ui/src/lib/account-balances/account-balances.component.ts - 104 + 102 @@ -14653,7 +14653,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 330 + 342 @@ -14701,7 +14701,7 @@ Oops! Could not grant access. apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts - 80 + 88 @@ -14997,7 +14997,7 @@ Activity apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 188 + 219 @@ -15005,7 +15005,7 @@ Dividend Yield apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 156 + 187 @@ -15040,6 +15040,22 @@ 43 + + Change with currency effect + Change with currency effect + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 52 + + + + Performance with currency effect + Performance with currency effect + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 79 + + diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf index 966be7459..4dec633e4 100644 --- a/apps/client/src/locales/messages.pl.xlf +++ b/apps/client/src/locales/messages.pl.xlf @@ -1622,11 +1622,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 190 + 221 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 300 + 331 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -1682,7 +1682,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 7 + 12 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -1690,7 +1690,7 @@ apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 7 + 12 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1698,7 +1698,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 138 + 134 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1738,7 +1738,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 144 + 140 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1762,31 +1762,31 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 198 + 194 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 199 + 195 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 201 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 263 + 257 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 264 + 258 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 265 + 259 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 260 libs/ui/src/lib/account-balances/account-balances.component.html @@ -1918,7 +1918,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 270 + 301 @@ -1934,7 +1934,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 154 + 150 @@ -2018,7 +2018,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 160 + 156 libs/ui/src/lib/account-balances/account-balances.component.html @@ -2038,7 +2038,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 81 + 112 @@ -2058,11 +2058,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 39 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 13 + 22 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -2078,7 +2078,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 408 + 399 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -2102,11 +2102,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 33 + 46 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 20 + 29 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -2118,7 +2118,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 415 + 406 @@ -2178,11 +2178,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 197 + 228 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 334 + 326 @@ -2202,11 +2202,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 206 + 237 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 350 + 342 @@ -2222,7 +2222,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 178 + 209 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -2298,7 +2298,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 235 + 236 @@ -2342,7 +2342,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 223 + 254 @@ -2358,7 +2358,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 233 + 264 @@ -2374,7 +2374,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 239 + 270 apps/client/src/app/pages/public/public-page.html @@ -2394,7 +2394,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 251 + 282 @@ -2434,7 +2434,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 319 + 311 @@ -2470,7 +2470,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 122 + 120 @@ -2658,7 +2658,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 13 + 22 @@ -2682,7 +2682,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 325 + 356 apps/client/src/app/pages/accounts/accounts-page.html @@ -2706,7 +2706,7 @@ Update platform apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 2 + 7 @@ -2714,7 +2714,7 @@ Add platform apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 3 + 8 @@ -2734,11 +2734,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 345 + 376 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 363 + 355 libs/ui/src/lib/assistant/assistant.html @@ -2766,7 +2766,7 @@ Update tag apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 2 + 7 @@ -2774,7 +2774,7 @@ Add tag apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 3 + 8 @@ -2842,7 +2842,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 59 + 89 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -3296,7 +3296,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 134 + 165 @@ -3324,7 +3324,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 168 + 199 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -3456,7 +3456,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 146 + 177 apps/client/src/app/pages/features/features-page.html @@ -3464,11 +3464,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 196 + 192 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 261 + 255 @@ -3484,7 +3484,7 @@ Change apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 48 + 63 @@ -3492,7 +3492,7 @@ Average Unit Price apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 70 + 101 @@ -3500,7 +3500,7 @@ Minimum Price apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 97 + 128 @@ -3508,7 +3508,7 @@ Maximum Price apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 113 + 144 @@ -3516,11 +3516,11 @@ Quantity apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 123 + 154 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 183 + 179 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3532,7 +3532,7 @@ Report Data Glitch apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 363 + 394 @@ -4140,7 +4140,7 @@ Oops, cash balance transfer has failed. apps/client/src/app/pages/accounts/accounts-page.component.ts - 308 + 304 @@ -5028,7 +5028,7 @@ Update Cash Balance apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 110 + 108 @@ -5036,11 +5036,11 @@ Unit Price apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 203 + 199 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 267 + 261 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5052,7 +5052,7 @@ Oops! Could not get the historical exchange rate from apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 232 + 226 @@ -5060,11 +5060,11 @@ Fee apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 + 280 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 310 + 302 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5076,7 +5076,7 @@ Oops! Could not get the historical exchange rate from apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 300 + 292 @@ -13316,7 +13316,7 @@ Projected Total Amount libs/ui/src/lib/fire-calculator/fire-calculator.component.html - 60 + 57 @@ -14632,7 +14632,7 @@ Do you really want to delete this account balance? libs/ui/src/lib/account-balances/account-balances.component.ts - 104 + 102 @@ -14656,7 +14656,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 330 + 342 @@ -14704,7 +14704,7 @@ Oops! Could not grant access. apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts - 80 + 88 @@ -15000,7 +15000,7 @@ Activity apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 188 + 219 @@ -15008,7 +15008,7 @@ Dividend Yield apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 156 + 187 @@ -15043,6 +15043,22 @@ 43 + + Change with currency effect + Change with currency effect + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 52 + + + + Performance with currency effect + Performance with currency effect + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 79 + + diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index ad6aedb7a..a467edaa5 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -118,11 +118,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 190 + 221 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 300 + 331 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -150,7 +150,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 7 + 12 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -158,7 +158,7 @@ apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 7 + 12 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -166,7 +166,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 138 + 134 libs/ui/src/lib/activities-table/activities-table.component.html @@ -206,7 +206,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 144 + 140 libs/ui/src/lib/activities-table/activities-table.component.html @@ -246,31 +246,31 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 198 + 194 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 199 + 195 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 201 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 263 + 257 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 264 + 258 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 265 + 259 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 260 libs/ui/src/lib/account-balances/account-balances.component.html @@ -386,7 +386,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 270 + 301 @@ -402,7 +402,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 154 + 150 @@ -502,7 +502,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 160 + 156 libs/ui/src/lib/account-balances/account-balances.component.html @@ -522,7 +522,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 81 + 112 @@ -542,11 +542,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 39 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 13 + 22 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -562,7 +562,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 408 + 399 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -586,11 +586,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 33 + 46 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 20 + 29 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -602,7 +602,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 415 + 406 @@ -630,11 +630,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 197 + 228 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 334 + 326 @@ -654,11 +654,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 206 + 237 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 350 + 342 @@ -674,7 +674,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 178 + 209 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -922,7 +922,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 325 + 356 apps/client/src/app/pages/accounts/accounts-page.html @@ -958,7 +958,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 59 + 89 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -1590,7 +1590,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 134 + 165 @@ -1717,7 +1717,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 146 + 177 apps/client/src/app/pages/features/features-page.html @@ -1725,11 +1725,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 196 + 192 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 261 + 255 @@ -1745,7 +1745,7 @@ Alterar apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 48 + 63 @@ -1753,7 +1753,7 @@ Preço Médio por Unidade apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 70 + 101 @@ -1761,7 +1761,7 @@ Preço Mínimo apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 97 + 128 @@ -1769,7 +1769,7 @@ Preço Máximo apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 113 + 144 @@ -1777,11 +1777,11 @@ Quantidade apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 123 + 154 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 183 + 179 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1797,7 +1797,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 223 + 254 @@ -1813,7 +1813,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 233 + 264 @@ -1829,7 +1829,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 239 + 270 apps/client/src/app/pages/public/public-page.html @@ -1849,7 +1849,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 251 + 282 @@ -1861,11 +1861,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 345 + 376 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 363 + 355 libs/ui/src/lib/assistant/assistant.html @@ -1877,7 +1877,7 @@ Dados do Relatório com Problema apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 363 + 394 @@ -2577,7 +2577,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 122 + 120 @@ -2585,11 +2585,11 @@ Preço por Unidade apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 203 + 199 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 267 + 261 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2601,11 +2601,11 @@ Comissão apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 + 280 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 310 + 302 libs/ui/src/lib/activities-table/activities-table.component.html @@ -2625,7 +2625,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 319 + 311 @@ -3181,7 +3181,7 @@ Montante Total Projetado libs/ui/src/lib/fire-calculator/fire-calculator.component.html - 60 + 57 @@ -3921,7 +3921,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 168 + 199 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -4025,7 +4025,7 @@ Oops! Não foi possível obter a taxa de câmbio histórica de apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 300 + 292 @@ -4133,7 +4133,7 @@ Atualizar plataforma apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 2 + 7 @@ -4141,7 +4141,7 @@ Adicionar plataforma apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 3 + 8 @@ -4157,7 +4157,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 13 + 22 @@ -4181,7 +4181,7 @@ Atualizar saldo em Dinheiro apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 110 + 108 @@ -13233,7 +13233,7 @@ Oops! Could not get the historical exchange rate from apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 232 + 226 @@ -13281,7 +13281,7 @@ Update tag apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 2 + 7 @@ -13289,7 +13289,7 @@ Add tag apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 3 + 8 @@ -13733,7 +13733,7 @@ Oops, cash balance transfer has failed. apps/client/src/app/pages/accounts/accounts-page.component.ts - 308 + 304 @@ -13781,7 +13781,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 235 + 236 @@ -14629,7 +14629,7 @@ Do you really want to delete this account balance? libs/ui/src/lib/account-balances/account-balances.component.ts - 104 + 102 @@ -14653,7 +14653,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 330 + 342 @@ -14701,7 +14701,7 @@ Oops! Could not grant access. apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts - 80 + 88 @@ -14997,7 +14997,7 @@ Activity apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 188 + 219 @@ -15005,7 +15005,7 @@ Dividend Yield apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 156 + 187 @@ -15040,6 +15040,22 @@ 43 + + Change with currency effect + Change with currency effect + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 52 + + + + Performance with currency effect + Performance with currency effect + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 79 + + diff --git a/apps/client/src/locales/messages.tr.xlf b/apps/client/src/locales/messages.tr.xlf index af530e9d5..91e97ea12 100644 --- a/apps/client/src/locales/messages.tr.xlf +++ b/apps/client/src/locales/messages.tr.xlf @@ -1614,11 +1614,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 190 + 221 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 300 + 331 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -1646,7 +1646,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 7 + 12 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -1654,7 +1654,7 @@ apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 7 + 12 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1662,7 +1662,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 138 + 134 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1702,7 +1702,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 144 + 140 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1726,31 +1726,31 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 198 + 194 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 199 + 195 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 201 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 263 + 257 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 264 + 258 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 265 + 259 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 260 libs/ui/src/lib/account-balances/account-balances.component.html @@ -1866,7 +1866,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 270 + 301 @@ -1882,7 +1882,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 154 + 150 @@ -1982,7 +1982,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 160 + 156 libs/ui/src/lib/account-balances/account-balances.component.html @@ -2002,7 +2002,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 81 + 112 @@ -2022,11 +2022,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 39 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 13 + 22 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -2042,7 +2042,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 408 + 399 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -2066,11 +2066,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 33 + 46 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 20 + 29 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -2082,7 +2082,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 415 + 406 @@ -2134,11 +2134,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 197 + 228 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 334 + 326 @@ -2158,11 +2158,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 206 + 237 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 350 + 342 @@ -2178,7 +2178,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 178 + 209 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -2274,7 +2274,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 223 + 254 @@ -2290,7 +2290,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 233 + 264 @@ -2306,7 +2306,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 239 + 270 apps/client/src/app/pages/public/public-page.html @@ -2326,7 +2326,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 251 + 282 @@ -2358,7 +2358,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 319 + 311 @@ -2378,7 +2378,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 122 + 120 @@ -2470,11 +2470,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 345 + 376 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 363 + 355 libs/ui/src/lib/assistant/assistant.html @@ -2570,7 +2570,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 13 + 22 @@ -2594,7 +2594,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 325 + 356 apps/client/src/app/pages/accounts/accounts-page.html @@ -2618,7 +2618,7 @@ Platformu Güncelle apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 2 + 7 @@ -2626,7 +2626,7 @@ Platform Ekle apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 3 + 8 @@ -2702,7 +2702,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 59 + 89 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -3126,7 +3126,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 134 + 165 @@ -3281,7 +3281,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 146 + 177 apps/client/src/app/pages/features/features-page.html @@ -3289,11 +3289,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 196 + 192 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 261 + 255 @@ -3309,7 +3309,7 @@ Para Birimi apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 48 + 63 @@ -3317,7 +3317,7 @@ Ortalama Birim Fiyat apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 70 + 101 @@ -3325,7 +3325,7 @@ Asgari Fiyat apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 97 + 128 @@ -3333,7 +3333,7 @@ Azami Fiyat apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 113 + 144 @@ -3341,11 +3341,11 @@ Miktar apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 123 + 154 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 183 + 179 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3361,7 +3361,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 168 + 199 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -3373,7 +3373,7 @@ Rapor Veri Sorunu apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 363 + 394 @@ -4513,7 +4513,7 @@ Nakit Bakiyesini Güncelle apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 110 + 108 @@ -4521,11 +4521,11 @@ Birim Fiyat apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 203 + 199 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 267 + 261 libs/ui/src/lib/activities-table/activities-table.component.html @@ -4537,7 +4537,7 @@ Hay Allah! Geçmiş döviz kuru alınamadı: apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 300 + 292 @@ -4545,11 +4545,11 @@ Komisyon apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 + 280 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 310 + 302 libs/ui/src/lib/activities-table/activities-table.component.html @@ -12737,7 +12737,7 @@ Hesaplanan Toplam Tutar libs/ui/src/lib/fire-calculator/fire-calculator.component.html - 60 + 57 @@ -13241,7 +13241,7 @@ Oops! Could not get the historical exchange rate from apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 232 + 226 @@ -13281,7 +13281,7 @@ Update tag apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 2 + 7 @@ -13289,7 +13289,7 @@ Add tag apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 3 + 8 @@ -13733,7 +13733,7 @@ Oops, cash balance transfer has failed. apps/client/src/app/pages/accounts/accounts-page.component.ts - 308 + 304 @@ -13781,7 +13781,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 235 + 236 @@ -14629,7 +14629,7 @@ Do you really want to delete this account balance? libs/ui/src/lib/account-balances/account-balances.component.ts - 104 + 102 @@ -14653,7 +14653,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 330 + 342 @@ -14701,7 +14701,7 @@ Oops! Could not grant access. apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts - 80 + 88 @@ -14997,7 +14997,7 @@ Activity apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 188 + 219 @@ -15005,7 +15005,7 @@ Dividend Yield apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 156 + 187 @@ -15040,6 +15040,22 @@ 43 + + Change with currency effect + Change with currency effect + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 52 + + + + Performance with currency effect + Performance with currency effect + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 79 + + diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index d12c7f060..2c1e7fa02 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -1590,11 +1590,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 190 + 221 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 300 + 331 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -1654,7 +1654,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 7 + 12 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -1662,7 +1662,7 @@ apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 7 + 12 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1670,7 +1670,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 138 + 134 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1708,7 +1708,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 144 + 140 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1731,31 +1731,31 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 198 + 194 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 199 + 195 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 201 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 263 + 257 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 264 + 258 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 265 + 259 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 260 libs/ui/src/lib/account-balances/account-balances.component.html @@ -1881,7 +1881,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 270 + 301 @@ -1896,7 +1896,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 154 + 150 @@ -1970,7 +1970,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 160 + 156 libs/ui/src/lib/account-balances/account-balances.component.html @@ -1989,7 +1989,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 81 + 112 @@ -2008,11 +2008,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 39 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 13 + 22 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -2028,7 +2028,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 408 + 399 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -2051,11 +2051,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 33 + 46 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 20 + 29 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -2067,7 +2067,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 415 + 406 @@ -2121,11 +2121,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 197 + 228 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 334 + 326 @@ -2144,11 +2144,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 206 + 237 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 350 + 342 @@ -2163,7 +2163,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 178 + 209 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -2231,7 +2231,7 @@ Oops! Could not parse historical data. apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 235 + 236 @@ -2271,7 +2271,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 223 + 254 @@ -2286,7 +2286,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 233 + 264 @@ -2301,7 +2301,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 239 + 270 apps/client/src/app/pages/public/public-page.html @@ -2320,7 +2320,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 251 + 282 @@ -2356,7 +2356,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 319 + 311 @@ -2388,7 +2388,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 122 + 120 @@ -2561,7 +2561,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 13 + 22 @@ -2584,7 +2584,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 325 + 356 apps/client/src/app/pages/accounts/accounts-page.html @@ -2606,14 +2606,14 @@ Update platform apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 2 + 7 Add platform apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 3 + 8 @@ -2631,11 +2631,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 345 + 376 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 363 + 355 libs/ui/src/lib/assistant/assistant.html @@ -2660,14 +2660,14 @@ Update tag apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 2 + 7 Add tag apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 3 + 8 @@ -2727,7 +2727,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 59 + 89 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -3132,7 +3132,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 134 + 165 @@ -3157,7 +3157,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 168 + 199 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -3275,7 +3275,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 146 + 177 apps/client/src/app/pages/features/features-page.html @@ -3283,11 +3283,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 196 + 192 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 261 + 255 @@ -3301,39 +3301,39 @@ Change apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 48 + 63 Average Unit Price apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 70 + 101 Minimum Price apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 97 + 128 Maximum Price apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 113 + 144 Quantity apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 123 + 154 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 183 + 179 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3344,7 +3344,7 @@ Report Data Glitch apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 363 + 394 @@ -3892,7 +3892,7 @@ Oops, cash balance transfer has failed. apps/client/src/app/pages/accounts/accounts-page.component.ts - 308 + 304 @@ -4683,18 +4683,18 @@ Update Cash Balance apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 110 + 108 Unit Price apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 203 + 199 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 267 + 261 libs/ui/src/lib/activities-table/activities-table.component.html @@ -4705,18 +4705,18 @@ Oops! Could not get the historical exchange rate from apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 232 + 226 Fee apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 + 280 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 310 + 302 libs/ui/src/lib/activities-table/activities-table.component.html @@ -4727,7 +4727,7 @@ Oops! Could not get the historical exchange rate from apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 300 + 292 @@ -13456,7 +13456,7 @@ Do you really want to delete this account balance? libs/ui/src/lib/account-balances/account-balances.component.ts - 104 + 102 @@ -13637,7 +13637,7 @@ Projected Total Amount libs/ui/src/lib/fire-calculator/fire-calculator.component.html - 60 + 57 @@ -14076,7 +14076,7 @@ The current market price is apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 330 + 342 @@ -14090,7 +14090,7 @@ Oops! Could not grant access. apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts - 80 + 88 @@ -14374,14 +14374,14 @@ Activity apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 188 + 219 Dividend Yield apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 156 + 187 @@ -14412,6 +14412,20 @@ 43 + + Change with currency effect + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 52 + + + + Performance with currency effect + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 79 + + diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index 36f0ef1bc..0c48eaed2 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -1623,11 +1623,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 190 + 221 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 300 + 331 apps/client/src/app/pages/portfolio/activities/activities-page.html @@ -1691,7 +1691,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 7 + 12 apps/client/src/app/components/admin-tag/admin-tag.component.html @@ -1699,7 +1699,7 @@ apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 7 + 12 apps/client/src/app/pages/accounts/create-or-update-account-dialog/create-or-update-account-dialog.html @@ -1707,7 +1707,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 138 + 134 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1747,7 +1747,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 144 + 140 libs/ui/src/lib/activities-table/activities-table.component.html @@ -1771,31 +1771,31 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 198 + 194 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 199 + 195 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 201 + 197 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 263 + 257 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 264 + 258 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 265 + 259 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 266 + 260 libs/ui/src/lib/account-balances/account-balances.component.html @@ -1927,7 +1927,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 270 + 301 @@ -1943,7 +1943,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 154 + 150 @@ -2027,7 +2027,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 160 + 156 libs/ui/src/lib/account-balances/account-balances.component.html @@ -2047,7 +2047,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 81 + 112 @@ -2067,11 +2067,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 26 + 39 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 13 + 22 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -2087,7 +2087,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 408 + 399 apps/client/src/app/pages/register/show-access-token-dialog/show-access-token-dialog.html @@ -2111,11 +2111,11 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 33 + 46 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 20 + 29 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.html @@ -2127,7 +2127,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 415 + 406 @@ -2187,11 +2187,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 197 + 228 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 334 + 326 @@ -2211,11 +2211,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 206 + 237 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 350 + 342 @@ -2231,7 +2231,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 178 + 209 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -2307,7 +2307,7 @@ 哎呀!无法解析历史数据。 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 235 + 236 @@ -2351,7 +2351,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 223 + 254 @@ -2367,7 +2367,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 233 + 264 @@ -2383,7 +2383,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 239 + 270 apps/client/src/app/pages/public/public-page.html @@ -2403,7 +2403,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 251 + 282 @@ -2443,7 +2443,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 319 + 311 @@ -2479,7 +2479,7 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 122 + 120 @@ -2675,7 +2675,7 @@ apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 13 + 22 @@ -2699,7 +2699,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 325 + 356 apps/client/src/app/pages/accounts/accounts-page.html @@ -2723,7 +2723,7 @@ 更新平台 apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 2 + 7 @@ -2731,7 +2731,7 @@ 添加平台 apps/client/src/app/components/admin-platform/create-or-update-platform-dialog/create-or-update-platform-dialog.html - 3 + 8 @@ -2751,11 +2751,11 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 345 + 376 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 363 + 355 libs/ui/src/lib/assistant/assistant.html @@ -2783,7 +2783,7 @@ 更新标签 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 2 + 7 @@ -2791,7 +2791,7 @@ 添加标签 apps/client/src/app/components/admin-tag/create-or-update-tag-dialog/create-or-update-tag-dialog.html - 3 + 8 @@ -2859,7 +2859,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 59 + 89 libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -3313,7 +3313,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 134 + 165 @@ -3341,7 +3341,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 168 + 199 apps/client/src/app/pages/portfolio/fire/fire-page.html @@ -3473,7 +3473,7 @@ apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 146 + 177 apps/client/src/app/pages/features/features-page.html @@ -3481,11 +3481,11 @@ apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 196 + 192 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 261 + 255 @@ -3501,7 +3501,7 @@ 修改 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 48 + 63 @@ -3509,7 +3509,7 @@ 平均单价 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 70 + 101 @@ -3517,7 +3517,7 @@ 最低价格 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 97 + 128 @@ -3525,7 +3525,7 @@ 最高价格 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 113 + 144 @@ -3533,11 +3533,11 @@ 数量 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 123 + 154 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 183 + 179 libs/ui/src/lib/activities-table/activities-table.component.html @@ -3549,7 +3549,7 @@ 报告数据故障 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 363 + 394 @@ -4157,7 +4157,7 @@ 糟糕,现金余额转账失败。 apps/client/src/app/pages/accounts/accounts-page.component.ts - 308 + 304 @@ -5045,7 +5045,7 @@ 更新现金余额 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 110 + 108 @@ -5053,11 +5053,11 @@ 单价 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 203 + 199 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 267 + 261 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5069,7 +5069,7 @@ 哎呀!无法从以下来源获取历史汇率 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 232 + 226 @@ -5077,11 +5077,11 @@ 费用 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 286 + 280 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 310 + 302 libs/ui/src/lib/activities-table/activities-table.component.html @@ -5093,7 +5093,7 @@ 哎呀!无法获取历史汇率 apps/client/src/app/pages/portfolio/activities/create-or-update-activity-dialog/create-or-update-activity-dialog.html - 300 + 292 @@ -13961,7 +13961,7 @@ 您确实要删除该帐户余额吗? libs/ui/src/lib/account-balances/account-balances.component.ts - 104 + 102 @@ -14165,7 +14165,7 @@ 预计总额 libs/ui/src/lib/fire-calculator/fire-calculator.component.html - 60 + 57 @@ -14665,7 +14665,7 @@ 当前市场价格为 apps/client/src/app/components/admin-market-data/asset-profile-dialog/asset-profile-dialog.component.ts - 330 + 342 @@ -14681,7 +14681,7 @@ 哎呀!无法授予访问权限。 apps/client/src/app/components/user-account-access/create-or-update-access-dialog/create-or-update-access-dialog.component.ts - 80 + 88 @@ -15001,7 +15001,7 @@ 活动 apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 188 + 219 @@ -15009,7 +15009,7 @@ Dividend Yield apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html - 156 + 187 @@ -15044,6 +15044,22 @@ 43 + + Change with currency effect + Change with currency effect + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 52 + + + + Performance with currency effect + Performance with currency effect + + apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + 79 + + diff --git a/libs/ui/src/lib/value/value.component.html b/libs/ui/src/lib/value/value.component.html index 4bdaf06a5..3ebda6e52 100644 --- a/libs/ui/src/lib/value/value.component.html +++ b/libs/ui/src/lib/value/value.component.html @@ -73,13 +73,13 @@ /> -
+
{{ subLabel }}
- + From f3d961bc16bb43356d398ac360059690e4c6dd45 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 4 May 2024 14:11:37 +0200 Subject: [PATCH 180/203] Feature/move holdings table to holdings tab of home page (#3368) * Move holdings table to holdings tab of home page * Deprecate api/v1/portfolio/positions endpoint * Update changelog --- CHANGELOG.md | 1 + .../src/app/portfolio/portfolio.controller.ts | 3 + .../home-holdings/home-holdings.component.ts | 98 +++++----- .../home-holdings/home-holdings.html | 55 +++--- .../home-holdings/home-holdings.module.ts | 8 +- .../interfaces/interfaces.ts | 0 .../position-detail-dialog.component.scss | 0 .../position-detail-dialog.component.ts | 0 .../position-detail-dialog.html | 0 .../position-detail-dialog.module.ts | 0 .../position/position.component.html | 72 -------- .../position/position.component.scss | 13 -- .../components/position/position.component.ts | 40 ---- .../components/position/position.module.ts | 29 --- .../positions/positions.component.html | 35 ---- .../positions/positions.component.scss | 17 -- .../positions/positions.component.ts | 70 ------- .../components/positions/positions.module.ts | 21 --- .../src/app/components/rules/rules.module.ts | 2 - .../pages/home/home-page-routing.module.ts | 5 + .../activities/activities-page.component.ts | 4 +- .../allocations/allocations-page.component.ts | 6 +- .../analysis/analysis-page.component.ts | 6 +- .../holdings/holdings-page-routing.module.ts | 21 --- .../holdings/holdings-page.component.ts | 171 ------------------ .../portfolio/holdings/holdings-page.html | 38 ---- .../holdings/holdings-page.module.ts | 22 --- .../portfolio/holdings/holdings-page.scss | 3 - .../portfolio-page-routing.module.ts | 7 - .../portfolio/portfolio-page.component.ts | 5 - apps/client/src/app/services/data.service.ts | 3 + .../holdings-table.component.ts | 2 +- 32 files changed, 108 insertions(+), 649 deletions(-) rename apps/client/src/app/components/{position => }/position-detail-dialog/interfaces/interfaces.ts (100%) rename apps/client/src/app/components/{position => }/position-detail-dialog/position-detail-dialog.component.scss (100%) rename apps/client/src/app/components/{position => }/position-detail-dialog/position-detail-dialog.component.ts (100%) rename apps/client/src/app/components/{position => }/position-detail-dialog/position-detail-dialog.html (100%) rename apps/client/src/app/components/{position => }/position-detail-dialog/position-detail-dialog.module.ts (100%) delete mode 100644 apps/client/src/app/components/position/position.component.html delete mode 100644 apps/client/src/app/components/position/position.component.scss delete mode 100644 apps/client/src/app/components/position/position.component.ts delete mode 100644 apps/client/src/app/components/position/position.module.ts delete mode 100644 apps/client/src/app/components/positions/positions.component.html delete mode 100644 apps/client/src/app/components/positions/positions.component.scss delete mode 100644 apps/client/src/app/components/positions/positions.component.ts delete mode 100644 apps/client/src/app/components/positions/positions.module.ts delete mode 100644 apps/client/src/app/pages/portfolio/holdings/holdings-page-routing.module.ts delete mode 100644 apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts delete mode 100644 apps/client/src/app/pages/portfolio/holdings/holdings-page.html delete mode 100644 apps/client/src/app/pages/portfolio/holdings/holdings-page.module.ts delete mode 100644 apps/client/src/app/pages/portfolio/holdings/holdings-page.scss diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ba54382c..a744b8e3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Moved the holdings table to the holdings tab of the home page - Improved the performance labels (with and without currency effects) in the position detail dialog ## 2.78.0 - 2024-05-02 diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 0828fb3e4..7aa8e9159 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -490,6 +490,9 @@ export class PortfolioController { return performanceInformation; } + /** + * @deprecated + */ @Get('positions') @UseGuards(AuthGuard('jwt'), HasPermissionGuard) @UseInterceptors(RedactValuesInResponseInterceptor) diff --git a/apps/client/src/app/components/home-holdings/home-holdings.component.ts b/apps/client/src/app/components/home-holdings/home-holdings.component.ts index 9dbf9d9bf..1a556e6f4 100644 --- a/apps/client/src/app/components/home-holdings/home-holdings.component.ts +++ b/apps/client/src/app/components/home-holdings/home-holdings.component.ts @@ -1,11 +1,11 @@ -import { PositionDetailDialog } from '@ghostfolio/client/components/position/position-detail-dialog/position-detail-dialog.component'; -import { ToggleComponent } from '@ghostfolio/client/components/toggle/toggle.component'; +import { PositionDetailDialogParams } from '@ghostfolio/client/components/position-detail-dialog/interfaces/interfaces'; +import { PositionDetailDialog } from '@ghostfolio/client/components/position-detail-dialog/position-detail-dialog.component'; import { DataService } from '@ghostfolio/client/services/data.service'; import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; -import { Position, User } from '@ghostfolio/common/interfaces'; +import { PortfolioPosition, User } from '@ghostfolio/common/interfaces'; import { hasPermission, permissions } from '@ghostfolio/common/permissions'; -import { DateRange } from '@ghostfolio/common/types'; +import { HoldingType, ToggleOption } from '@ghostfolio/common/types'; import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; @@ -15,19 +15,21 @@ import { DeviceDetectorService } from 'ngx-device-detector'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; -import { PositionDetailDialogParams } from '../position/position-detail-dialog/interfaces/interfaces'; - @Component({ selector: 'gf-home-holdings', styleUrls: ['./home-holdings.scss'], templateUrl: './home-holdings.html' }) export class HomeHoldingsComponent implements OnDestroy, OnInit { - public dateRangeOptions = ToggleComponent.DEFAULT_DATE_RANGE_OPTIONS; public deviceType: string; public hasImpersonationId: boolean; public hasPermissionToCreateOrder: boolean; - public positions: Position[]; + public holdings: PortfolioPosition[]; + public holdingType: HoldingType = 'ACTIVE'; + public holdingTypeOptions: ToggleOption[] = [ + { label: $localize`Active`, value: 'ACTIVE' }, + { label: $localize`Closed`, value: 'CLOSED' } + ]; public user: User; private unsubscribeSubject = new Subject(); @@ -56,6 +58,17 @@ export class HomeHoldingsComponent implements OnDestroy, OnInit { }); } }); + } + + public ngOnInit() { + this.deviceType = this.deviceService.getDeviceInfo().deviceType; + + this.impersonationStorageService + .onChangeHasImpersonation() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((impersonationId) => { + this.hasImpersonationId = !!impersonationId; + }); this.userService.stateChanged .pipe(takeUntil(this.unsubscribeSubject)) @@ -68,37 +81,32 @@ export class HomeHoldingsComponent implements OnDestroy, OnInit { permissions.createOrder ); - this.update(); + this.holdings = undefined; + + this.fetchHoldings() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(({ holdings }) => { + this.holdings = holdings; + + this.changeDetectorRef.markForCheck(); + }); + + this.changeDetectorRef.markForCheck(); } }); } - public ngOnInit() { - this.deviceType = this.deviceService.getDeviceInfo().deviceType; + public onChangeHoldingType(aHoldingType: HoldingType) { + this.holdingType = aHoldingType; - this.impersonationStorageService - .onChangeHasImpersonation() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((impersonationId) => { - this.hasImpersonationId = !!impersonationId; - }); - } + this.holdings = undefined; - public onChangeDateRange(dateRange: DateRange) { - this.dataService - .putUserSetting({ dateRange }) + this.fetchHoldings() .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(() => { - this.userService.remove(); - - this.userService - .get() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((user) => { - this.user = user; + .subscribe(({ holdings }) => { + this.holdings = holdings; - this.changeDetectorRef.markForCheck(); - }); + this.changeDetectorRef.markForCheck(); }); } @@ -107,6 +115,19 @@ export class HomeHoldingsComponent implements OnDestroy, OnInit { this.unsubscribeSubject.complete(); } + private fetchHoldings() { + const filters = this.userService.getFilters(); + + if (this.holdingType === 'CLOSED') { + filters.push({ id: 'CLOSED', type: 'HOLDING_TYPE' }); + } + + return this.dataService.fetchPortfolioHoldings({ + filters, + range: this.user?.settings?.dateRange + }); + } + private openPositionDialog({ dataSource, symbol @@ -147,19 +168,4 @@ export class HomeHoldingsComponent implements OnDestroy, OnInit { }); }); } - - private update() { - this.positions = undefined; - - this.dataService - .fetchPositions({ range: this.user?.settings?.dateRange }) - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(({ positions }) => { - this.positions = positions; - - this.changeDetectorRef.markForCheck(); - }); - - this.changeDetectorRef.markForCheck(); - } } diff --git a/apps/client/src/app/components/home-holdings/home-holdings.html b/apps/client/src/app/components/home-holdings/home-holdings.html index 72328eac2..a2bd43636 100644 --- a/apps/client/src/app/components/home-holdings/home-holdings.html +++ b/apps/client/src/app/components/home-holdings/home-holdings.html @@ -1,27 +1,38 @@ -
+
-
- - - - - -
- Manage Activities +
+

Holdings

+
+
+
+
+
+
+ + @if (hasPermissionToCreateOrder && holdings?.length > 0) { + + }
diff --git a/apps/client/src/app/components/home-holdings/home-holdings.module.ts b/apps/client/src/app/components/home-holdings/home-holdings.module.ts index b6fa70e8f..f10adeab2 100644 --- a/apps/client/src/app/components/home-holdings/home-holdings.module.ts +++ b/apps/client/src/app/components/home-holdings/home-holdings.module.ts @@ -1,11 +1,9 @@ -import { GfPositionDetailDialogModule } from '@ghostfolio/client/components/position/position-detail-dialog/position-detail-dialog.module'; -import { GfPositionsModule } from '@ghostfolio/client/components/positions/positions.module'; import { GfToggleModule } from '@ghostfolio/client/components/toggle/toggle.module'; +import { GfHoldingsTableComponent } from '@ghostfolio/ui/holdings-table'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; -import { MatCardModule } from '@angular/material/card'; import { RouterModule } from '@angular/router'; import { HomeHoldingsComponent } from './home-holdings.component'; @@ -14,11 +12,9 @@ import { HomeHoldingsComponent } from './home-holdings.component'; declarations: [HomeHoldingsComponent], imports: [ CommonModule, - GfPositionDetailDialogModule, - GfPositionsModule, + GfHoldingsTableComponent, GfToggleModule, MatButtonModule, - MatCardModule, RouterModule ], schemas: [CUSTOM_ELEMENTS_SCHEMA] diff --git a/apps/client/src/app/components/position/position-detail-dialog/interfaces/interfaces.ts b/apps/client/src/app/components/position-detail-dialog/interfaces/interfaces.ts similarity index 100% rename from apps/client/src/app/components/position/position-detail-dialog/interfaces/interfaces.ts rename to apps/client/src/app/components/position-detail-dialog/interfaces/interfaces.ts diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.scss b/apps/client/src/app/components/position-detail-dialog/position-detail-dialog.component.scss similarity index 100% rename from apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.scss rename to apps/client/src/app/components/position-detail-dialog/position-detail-dialog.component.scss diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts b/apps/client/src/app/components/position-detail-dialog/position-detail-dialog.component.ts similarity index 100% rename from apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.component.ts rename to apps/client/src/app/components/position-detail-dialog/position-detail-dialog.component.ts diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html b/apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html similarity index 100% rename from apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html rename to apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html diff --git a/apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.module.ts b/apps/client/src/app/components/position-detail-dialog/position-detail-dialog.module.ts similarity index 100% rename from apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.module.ts rename to apps/client/src/app/components/position-detail-dialog/position-detail-dialog.module.ts diff --git a/apps/client/src/app/components/position/position.component.html b/apps/client/src/app/components/position/position.component.html deleted file mode 100644 index 4a5ed6f9a..000000000 --- a/apps/client/src/app/components/position/position.component.html +++ /dev/null @@ -1,72 +0,0 @@ - diff --git a/apps/client/src/app/components/position/position.component.scss b/apps/client/src/app/components/position/position.component.scss deleted file mode 100644 index 7044d7795..000000000 --- a/apps/client/src/app/components/position/position.component.scss +++ /dev/null @@ -1,13 +0,0 @@ -:host { - display: block; - - .container { - gf-trend-indicator { - padding-top: 0.15rem; - } - - .chevron { - opacity: 0.33; - } - } -} diff --git a/apps/client/src/app/components/position/position.component.ts b/apps/client/src/app/components/position/position.component.ts deleted file mode 100644 index 3a5fbae81..000000000 --- a/apps/client/src/app/components/position/position.component.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { UNKNOWN_KEY } from '@ghostfolio/common/config'; -import { getLocale } from '@ghostfolio/common/helper'; -import { Position } from '@ghostfolio/common/interfaces'; - -import { - ChangeDetectionStrategy, - Component, - Input, - OnDestroy, - OnInit -} from '@angular/core'; -import { Subject } from 'rxjs'; - -@Component({ - selector: 'gf-position', - changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './position.component.html', - styleUrls: ['./position.component.scss'] -}) -export class PositionComponent implements OnDestroy, OnInit { - @Input() baseCurrency: string; - @Input() deviceType: string; - @Input() isLoading: boolean; - @Input() locale = getLocale(); - @Input() position: Position; - @Input() range: string; - - public unknownKey = UNKNOWN_KEY; - - private unsubscribeSubject = new Subject(); - - public constructor() {} - - public ngOnInit() {} - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } -} diff --git a/apps/client/src/app/components/position/position.module.ts b/apps/client/src/app/components/position/position.module.ts deleted file mode 100644 index 6483e274a..000000000 --- a/apps/client/src/app/components/position/position.module.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; -import { GfTrendIndicatorComponent } from '@ghostfolio/ui/trend-indicator'; -import { GfValueComponent } from '@ghostfolio/ui/value'; - -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { MatDialogModule } from '@angular/material/dialog'; -import { RouterModule } from '@angular/router'; -import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; - -import { GfPositionDetailDialogModule } from './position-detail-dialog/position-detail-dialog.module'; -import { PositionComponent } from './position.component'; - -@NgModule({ - declarations: [PositionComponent], - exports: [PositionComponent], - imports: [ - CommonModule, - GfPositionDetailDialogModule, - GfSymbolModule, - GfTrendIndicatorComponent, - GfValueComponent, - MatDialogModule, - NgxSkeletonLoaderModule, - RouterModule - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfPositionModule {} diff --git a/apps/client/src/app/components/positions/positions.component.html b/apps/client/src/app/components/positions/positions.component.html deleted file mode 100644 index 606c59211..000000000 --- a/apps/client/src/app/components/positions/positions.component.html +++ /dev/null @@ -1,35 +0,0 @@ -
-
-
- - - - - - - - -
- -
-
-
-
-
diff --git a/apps/client/src/app/components/positions/positions.component.scss b/apps/client/src/app/components/positions/positions.component.scss deleted file mode 100644 index d3e8995a1..000000000 --- a/apps/client/src/app/components/positions/positions.component.scss +++ /dev/null @@ -1,17 +0,0 @@ -:host { - display: block; - - gf-position { - &:nth-child(even) { - background-color: rgba(0, 0, 0, var(--gf-theme-alpha-hover)); - } - } -} - -:host-context(.is-dark-theme) { - gf-position { - &:nth-child(even) { - background-color: rgba(255, 255, 255, var(--gf-theme-alpha-hover)); - } - } -} diff --git a/apps/client/src/app/components/positions/positions.component.ts b/apps/client/src/app/components/positions/positions.component.ts deleted file mode 100644 index ab9812462..000000000 --- a/apps/client/src/app/components/positions/positions.component.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { getLocale } from '@ghostfolio/common/helper'; -import { Position } from '@ghostfolio/common/interfaces'; - -import { - ChangeDetectionStrategy, - Component, - Input, - OnChanges, - OnInit -} from '@angular/core'; - -@Component({ - selector: 'gf-positions', - changeDetection: ChangeDetectionStrategy.OnPush, - templateUrl: './positions.component.html', - styleUrls: ['./positions.component.scss'] -}) -export class PositionsComponent implements OnChanges, OnInit { - @Input() baseCurrency: string; - @Input() deviceType: string; - @Input() hasPermissionToCreateOrder: boolean; - @Input() locale = getLocale(); - @Input() positions: Position[]; - @Input() range: string; - - public hasPositions: boolean; - public positionsRest: Position[] = []; - public positionsWithPriority: Position[] = []; - - public constructor() {} - - public ngOnInit() {} - - public ngOnChanges() { - if (this.positions) { - this.hasPositions = this.positions.length > 0; - - if (!this.hasPositions) { - return; - } - - this.positionsRest = []; - this.positionsWithPriority = []; - - for (const portfolioPosition of this.positions) { - if (portfolioPosition.marketState === 'open' || this.range !== '1d') { - // Only show positions where the market is open in today's view - this.positionsWithPriority.push(portfolioPosition); - } else { - this.positionsRest.push(portfolioPosition); - } - } - - this.positionsRest.sort((a, b) => - (a.name || a.symbol)?.toLowerCase() > - (b.name || b.symbol)?.toLowerCase() - ? 1 - : -1 - ); - this.positionsWithPriority.sort((a, b) => - (a.name || a.symbol)?.toLowerCase() > - (b.name || b.symbol)?.toLowerCase() - ? 1 - : -1 - ); - } else { - this.hasPositions = false; - } - } -} diff --git a/apps/client/src/app/components/positions/positions.module.ts b/apps/client/src/app/components/positions/positions.module.ts deleted file mode 100644 index 34bd38b2d..000000000 --- a/apps/client/src/app/components/positions/positions.module.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { GfNoTransactionsInfoComponent } from '@ghostfolio/ui/no-transactions-info'; - -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { MatButtonModule } from '@angular/material/button'; - -import { GfPositionModule } from '../position/position.module'; -import { PositionsComponent } from './positions.component'; - -@NgModule({ - declarations: [PositionsComponent], - exports: [PositionsComponent], - imports: [ - CommonModule, - GfNoTransactionsInfoComponent, - GfPositionModule, - MatButtonModule - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class GfPositionsModule {} diff --git a/apps/client/src/app/components/rules/rules.module.ts b/apps/client/src/app/components/rules/rules.module.ts index 3b82c6ab1..26ed1d83e 100644 --- a/apps/client/src/app/components/rules/rules.module.ts +++ b/apps/client/src/app/components/rules/rules.module.ts @@ -6,7 +6,6 @@ import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; -import { GfPositionModule } from '../position/position.module'; import { RulesComponent } from './rules.component'; @NgModule({ @@ -15,7 +14,6 @@ import { RulesComponent } from './rules.component'; imports: [ CommonModule, GfNoTransactionsInfoComponent, - GfPositionModule, GfRuleModule, MatButtonModule, MatCardModule diff --git a/apps/client/src/app/pages/home/home-page-routing.module.ts b/apps/client/src/app/pages/home/home-page-routing.module.ts index bccfc2f57..f50b55192 100644 --- a/apps/client/src/app/pages/home/home-page-routing.module.ts +++ b/apps/client/src/app/pages/home/home-page-routing.module.ts @@ -22,6 +22,11 @@ const routes: Routes = [ component: HomeHoldingsComponent, title: $localize`Holdings` }, + { + path: 'holdings', + component: HomeHoldingsComponent, + title: $localize`Holdings` + }, { path: 'summary', component: HomeSummaryComponent, diff --git a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts index f6f0feded..6e66bb666 100644 --- a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts @@ -1,8 +1,8 @@ import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto'; import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { UpdateOrderDto } from '@ghostfolio/api/app/order/update-order.dto'; -import { PositionDetailDialogParams } from '@ghostfolio/client/components/position/position-detail-dialog/interfaces/interfaces'; -import { PositionDetailDialog } from '@ghostfolio/client/components/position/position-detail-dialog/position-detail-dialog.component'; +import { PositionDetailDialogParams } from '@ghostfolio/client/components/position-detail-dialog/interfaces/interfaces'; +import { PositionDetailDialog } from '@ghostfolio/client/components/position-detail-dialog/position-detail-dialog.component'; import { DataService } from '@ghostfolio/client/services/data.service'; import { IcsService } from '@ghostfolio/client/services/ics/ics.service'; import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; diff --git a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts index 6d3aed4d3..0172c8094 100644 --- a/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts +++ b/apps/client/src/app/pages/portfolio/allocations/allocations-page.component.ts @@ -1,7 +1,7 @@ import { AccountDetailDialog } from '@ghostfolio/client/components/account-detail-dialog/account-detail-dialog.component'; import { AccountDetailDialogParams } from '@ghostfolio/client/components/account-detail-dialog/interfaces/interfaces'; -import { PositionDetailDialogParams } from '@ghostfolio/client/components/position/position-detail-dialog/interfaces/interfaces'; -import { PositionDetailDialog } from '@ghostfolio/client/components/position/position-detail-dialog/position-detail-dialog.component'; +import { PositionDetailDialogParams } from '@ghostfolio/client/components/position-detail-dialog/interfaces/interfaces'; +import { PositionDetailDialog } from '@ghostfolio/client/components/position-detail-dialog/position-detail-dialog.component'; import { DataService } from '@ghostfolio/client/services/data.service'; import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; @@ -103,7 +103,7 @@ export class AllocationsPageComponent implements OnDestroy, OnInit { private router: Router, private userService: UserService ) { - route.queryParams + this.route.queryParams .pipe(takeUntil(this.unsubscribeSubject)) .subscribe((params) => { if (params['accountId'] && params['accountDetailDialog']) { diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts index 184297b26..4acf6dbb9 100644 --- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts +++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -1,5 +1,5 @@ -import { PositionDetailDialogParams } from '@ghostfolio/client/components/position/position-detail-dialog/interfaces/interfaces'; -import { PositionDetailDialog } from '@ghostfolio/client/components/position/position-detail-dialog/position-detail-dialog.component'; +import { PositionDetailDialogParams } from '@ghostfolio/client/components/position-detail-dialog/interfaces/interfaces'; +import { PositionDetailDialog } from '@ghostfolio/client/components/position-detail-dialog/position-detail-dialog.component'; import { ToggleComponent } from '@ghostfolio/client/components/toggle/toggle.component'; import { DataService } from '@ghostfolio/client/services/data.service'; import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; @@ -80,7 +80,7 @@ export class AnalysisPageComponent implements OnDestroy, OnInit { const { benchmarks } = this.dataService.fetchInfo(); this.benchmarks = benchmarks; - route.queryParams + this.route.queryParams .pipe(takeUntil(this.unsubscribeSubject)) .subscribe((params) => { if ( diff --git a/apps/client/src/app/pages/portfolio/holdings/holdings-page-routing.module.ts b/apps/client/src/app/pages/portfolio/holdings/holdings-page-routing.module.ts deleted file mode 100644 index 94b49a9d0..000000000 --- a/apps/client/src/app/pages/portfolio/holdings/holdings-page-routing.module.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { AuthGuard } from '@ghostfolio/client/core/auth.guard'; - -import { NgModule } from '@angular/core'; -import { RouterModule, Routes } from '@angular/router'; - -import { HoldingsPageComponent } from './holdings-page.component'; - -const routes: Routes = [ - { - canActivate: [AuthGuard], - component: HoldingsPageComponent, - path: '', - title: $localize`Holdings` - } -]; - -@NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] -}) -export class HoldingsPageRoutingModule {} diff --git a/apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts b/apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts deleted file mode 100644 index 107e8f307..000000000 --- a/apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { PositionDetailDialogParams } from '@ghostfolio/client/components/position/position-detail-dialog/interfaces/interfaces'; -import { PositionDetailDialog } from '@ghostfolio/client/components/position/position-detail-dialog/position-detail-dialog.component'; -import { DataService } from '@ghostfolio/client/services/data.service'; -import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; -import { UserService } from '@ghostfolio/client/services/user/user.service'; -import { PortfolioPosition, User } from '@ghostfolio/common/interfaces'; -import { hasPermission, permissions } from '@ghostfolio/common/permissions'; -import { HoldingType, ToggleOption } from '@ghostfolio/common/types'; - -import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; -import { MatDialog } from '@angular/material/dialog'; -import { ActivatedRoute, Router } from '@angular/router'; -import { DataSource } from '@prisma/client'; -import { DeviceDetectorService } from 'ngx-device-detector'; -import { Subject } from 'rxjs'; -import { takeUntil } from 'rxjs/operators'; - -@Component({ - selector: 'gf-holdings-page', - styleUrls: ['./holdings-page.scss'], - templateUrl: './holdings-page.html' -}) -export class HoldingsPageComponent implements OnDestroy, OnInit { - public deviceType: string; - public hasImpersonationId: boolean; - public hasPermissionToCreateOrder: boolean; - public holdings: PortfolioPosition[]; - public holdingType: HoldingType = 'ACTIVE'; - public holdingTypeOptions: ToggleOption[] = [ - { label: $localize`Active`, value: 'ACTIVE' }, - { label: $localize`Closed`, value: 'CLOSED' } - ]; - public user: User; - - private unsubscribeSubject = new Subject(); - - public constructor( - private changeDetectorRef: ChangeDetectorRef, - private dataService: DataService, - private deviceService: DeviceDetectorService, - private dialog: MatDialog, - private impersonationStorageService: ImpersonationStorageService, - private route: ActivatedRoute, - private router: Router, - private userService: UserService - ) { - route.queryParams - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((params) => { - if ( - params['dataSource'] && - params['positionDetailDialog'] && - params['symbol'] - ) { - this.openPositionDialog({ - dataSource: params['dataSource'], - symbol: params['symbol'] - }); - } - }); - } - - public ngOnInit() { - this.deviceType = this.deviceService.getDeviceInfo().deviceType; - - this.impersonationStorageService - .onChangeHasImpersonation() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((impersonationId) => { - this.hasImpersonationId = !!impersonationId; - }); - - this.userService.stateChanged - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((state) => { - if (state?.user) { - this.user = state.user; - - this.hasPermissionToCreateOrder = hasPermission( - this.user.permissions, - permissions.createOrder - ); - - this.holdings = undefined; - - this.fetchHoldings() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(({ holdings }) => { - this.holdings = holdings; - - this.changeDetectorRef.markForCheck(); - }); - - this.changeDetectorRef.markForCheck(); - } - }); - } - - public onChangeHoldingType(aHoldingType: HoldingType) { - this.holdingType = aHoldingType; - - this.holdings = undefined; - - this.fetchHoldings() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(({ holdings }) => { - this.holdings = holdings; - - this.changeDetectorRef.markForCheck(); - }); - } - - public ngOnDestroy() { - this.unsubscribeSubject.next(); - this.unsubscribeSubject.complete(); - } - - private fetchHoldings() { - const filters = this.userService.getFilters(); - - if (this.holdingType === 'CLOSED') { - filters.push({ id: 'CLOSED', type: 'HOLDING_TYPE' }); - } - - return this.dataService.fetchPortfolioHoldings({ - filters, - range: this.user?.settings?.dateRange - }); - } - - private openPositionDialog({ - dataSource, - symbol - }: { - dataSource: DataSource; - symbol: string; - }) { - this.userService - .get() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe((user) => { - this.user = user; - - const dialogRef = this.dialog.open(PositionDetailDialog, { - autoFocus: false, - data: { - dataSource, - symbol, - baseCurrency: this.user?.settings?.baseCurrency, - colorScheme: this.user?.settings?.colorScheme, - deviceType: this.deviceType, - hasImpersonationId: this.hasImpersonationId, - hasPermissionToReportDataGlitch: hasPermission( - this.user?.permissions, - permissions.reportDataGlitch - ), - locale: this.user?.settings?.locale - }, - height: this.deviceType === 'mobile' ? '97.5vh' : '80vh', - width: this.deviceType === 'mobile' ? '100vw' : '50rem' - }); - - dialogRef - .afterClosed() - .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(() => { - this.router.navigate(['.'], { relativeTo: this.route }); - }); - }); - } -} diff --git a/apps/client/src/app/pages/portfolio/holdings/holdings-page.html b/apps/client/src/app/pages/portfolio/holdings/holdings-page.html deleted file mode 100644 index a2bd43636..000000000 --- a/apps/client/src/app/pages/portfolio/holdings/holdings-page.html +++ /dev/null @@ -1,38 +0,0 @@ -
-
-
-

Holdings

-
-
-
-
-
- -
- - @if (hasPermissionToCreateOrder && holdings?.length > 0) { - - } -
-
-
diff --git a/apps/client/src/app/pages/portfolio/holdings/holdings-page.module.ts b/apps/client/src/app/pages/portfolio/holdings/holdings-page.module.ts deleted file mode 100644 index a5040f373..000000000 --- a/apps/client/src/app/pages/portfolio/holdings/holdings-page.module.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { GfToggleModule } from '@ghostfolio/client/components/toggle/toggle.module'; -import { GfHoldingsTableComponent } from '@ghostfolio/ui/holdings-table'; - -import { CommonModule } from '@angular/common'; -import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; -import { MatButtonModule } from '@angular/material/button'; - -import { HoldingsPageRoutingModule } from './holdings-page-routing.module'; -import { HoldingsPageComponent } from './holdings-page.component'; - -@NgModule({ - declarations: [HoldingsPageComponent], - imports: [ - CommonModule, - GfHoldingsTableComponent, - GfToggleModule, - HoldingsPageRoutingModule, - MatButtonModule - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] -}) -export class HoldingsPageModule {} diff --git a/apps/client/src/app/pages/portfolio/holdings/holdings-page.scss b/apps/client/src/app/pages/portfolio/holdings/holdings-page.scss deleted file mode 100644 index 5d4e87f30..000000000 --- a/apps/client/src/app/pages/portfolio/holdings/holdings-page.scss +++ /dev/null @@ -1,3 +0,0 @@ -:host { - display: block; -} diff --git a/apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts b/apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts index d4f93b567..6146c573c 100644 --- a/apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts +++ b/apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts @@ -16,13 +16,6 @@ const routes: Routes = [ (m) => m.AnalysisPageModule ) }, - { - path: 'holdings', - loadChildren: () => - import('./holdings/holdings-page.module').then( - (m) => m.HoldingsPageModule - ) - }, { path: 'activities', loadChildren: () => diff --git a/apps/client/src/app/pages/portfolio/portfolio-page.component.ts b/apps/client/src/app/pages/portfolio/portfolio-page.component.ts index bbd70c1c9..0c980e25b 100644 --- a/apps/client/src/app/pages/portfolio/portfolio-page.component.ts +++ b/apps/client/src/app/pages/portfolio/portfolio-page.component.ts @@ -34,11 +34,6 @@ export class PortfolioPageComponent implements OnDestroy, OnInit { label: $localize`Analysis`, path: ['/portfolio'] }, - { - iconName: 'wallet-outline', - label: $localize`Holdings`, - path: ['/portfolio', 'holdings'] - }, { iconName: 'swap-vertical-outline', label: $localize`Activities`, diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts index 16d104834..d5c1bec00 100644 --- a/apps/client/src/app/services/data.service.ts +++ b/apps/client/src/app/services/data.service.ts @@ -376,6 +376,9 @@ export class DataService { }); } + /** + * @deprecated + */ public fetchPositions({ filters, range diff --git a/libs/ui/src/lib/holdings-table/holdings-table.component.ts b/libs/ui/src/lib/holdings-table/holdings-table.component.ts index 93ac5b6fe..f25239277 100644 --- a/libs/ui/src/lib/holdings-table/holdings-table.component.ts +++ b/libs/ui/src/lib/holdings-table/holdings-table.component.ts @@ -1,5 +1,5 @@ import { GfAssetProfileIconComponent } from '@ghostfolio/client/components/asset-profile-icon/asset-profile-icon.component'; -import { GfPositionDetailDialogModule } from '@ghostfolio/client/components/position/position-detail-dialog/position-detail-dialog.module'; +import { GfPositionDetailDialogModule } from '@ghostfolio/client/components/position-detail-dialog/position-detail-dialog.module'; import { GfSymbolModule } from '@ghostfolio/client/pipes/symbol/symbol.module'; import { getLocale } from '@ghostfolio/common/helper'; import { PortfolioPosition, UniqueAsset } from '@ghostfolio/common/interfaces'; From c1ad483f3329c663ed561b43abd18be618bb9a5c Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 4 May 2024 15:50:47 +0200 Subject: [PATCH 181/203] Improve alignment (#3370) --- libs/ui/src/lib/value/value.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/ui/src/lib/value/value.component.html b/libs/ui/src/lib/value/value.component.html index 3ebda6e52..d1e498bcc 100644 --- a/libs/ui/src/lib/value/value.component.html +++ b/libs/ui/src/lib/value/value.component.html @@ -1,7 +1,7 @@
-
+
Date: Sat, 4 May 2024 15:51:09 +0200 Subject: [PATCH 182/203] Bugfix/fix locale in markets overview (#3369) * Fix locale if no user is logged in * Update changelog --- CHANGELOG.md | 5 +++++ apps/client/src/app/components/home-market/home-market.html | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a744b8e3d..699722298 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Moved the holdings table to the holdings tab of the home page - Improved the performance labels (with and without currency effects) in the position detail dialog +### Fixed + +- Fixed an issue with the benchmarks in the markets overview +- Fixed an issue with the _Fear & Greed Index_ (market mood) in the markets overview + ## 2.78.0 - 2024-05-02 ### Added diff --git a/apps/client/src/app/components/home-market/home-market.html b/apps/client/src/app/components/home-market/home-market.html index 333c612f7..0e9d51336 100644 --- a/apps/client/src/app/components/home-market/home-market.html +++ b/apps/client/src/app/components/home-market/home-market.html @@ -11,7 +11,7 @@ [colorScheme]="user?.settings?.colorScheme" [historicalDataItems]="historicalDataItems" [isAnimated]="true" - [locale]="user?.settings?.locale" + [locale]="user?.settings?.locale || undefined" [showXAxis]="true" [showYAxis]="true" [yMax]="100" @@ -30,7 +30,7 @@
Date: Sat, 4 May 2024 15:53:02 +0200 Subject: [PATCH 183/203] Feature/optimize get porfolio details endpoint (#3366) * Eliminate getPerformance() from getSummary() function * Disable cache for getDetails() * Add hint to portfolio summary * Update changelog --- CHANGELOG.md | 1 + .../src/app/portfolio/portfolio.controller.ts | 30 ++--- .../app/portfolio/portfolio.service.spec.ts | 10 +- .../src/app/portfolio/portfolio.service.ts | 105 +++++++++++------- .../portfolio-performance.component.html | 6 +- .../portfolio-performance.component.ts | 9 +- .../portfolio-summary.component.html | 28 +++-- .../portfolio-summary.component.ts | 4 + .../portfolio-summary.module.ts | 3 +- .../portfolio/analysis/analysis-page.html | 20 ++-- .../portfolio-performance.interface.ts | 20 ++-- libs/ui/src/lib/i18n.ts | 1 + 12 files changed, 137 insertions(+), 100 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 699722298..a9e8fd811 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Moved the holdings table to the holdings tab of the home page - Improved the performance labels (with and without currency effects) in the position detail dialog +- Optimized the calculations of the of the portfolio details endpoint ### Fixed diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 7aa8e9159..4a07cd65b 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -165,21 +165,21 @@ export class PortfolioController { portfolioSummary = nullifyValuesInObject(summary, [ 'cash', 'committedFunds', - 'currentGrossPerformance', - 'currentGrossPerformanceWithCurrencyEffect', - 'currentNetPerformance', - 'currentNetPerformanceWithCurrencyEffect', 'currentNetWorth', - 'currentValue', + 'currentValueInBaseCurrency', 'dividendInBaseCurrency', 'emergencyFund', 'excludedAccountsAndActivities', 'fees', 'filteredValueInBaseCurrency', 'fireWealth', + 'grossPerformance', + 'grossPerformanceWithCurrencyEffect', 'interest', 'items', 'liabilities', + 'netPerformance', + 'netPerformanceWithCurrencyEffect', 'totalBuy', 'totalInvestment', 'totalSell', @@ -449,10 +449,14 @@ export class PortfolioController { .div(performanceInformation.performance.totalInvestment) .toNumber(), valueInPercentage: - performanceInformation.performance.currentValue === 0 + performanceInformation.performance.currentValueInBaseCurrency === + 0 ? 0 : new Big(value) - .div(performanceInformation.performance.currentValue) + .div( + performanceInformation.performance + .currentValueInBaseCurrency + ) .toNumber() }; } @@ -461,12 +465,12 @@ export class PortfolioController { performanceInformation.performance = nullifyValuesInObject( performanceInformation.performance, [ - 'currentGrossPerformance', - 'currentGrossPerformanceWithCurrencyEffect', - 'currentNetPerformance', - 'currentNetPerformanceWithCurrencyEffect', 'currentNetWorth', - 'currentValue', + 'currentValueInBaseCurrency', + 'grossPerformance', + 'grossPerformanceWithCurrencyEffect', + 'netPerformance', + 'netPerformanceWithCurrencyEffect', 'totalInvestment' ] ); @@ -483,7 +487,7 @@ export class PortfolioController { ); performanceInformation.performance = nullifyValuesInObject( performanceInformation.performance, - ['currentNetPerformance', 'currentNetPerformancePercent'] + ['netPerformance'] ); } diff --git a/apps/api/src/app/portfolio/portfolio.service.spec.ts b/apps/api/src/app/portfolio/portfolio.service.spec.ts index 7654b7df3..92970f547 100644 --- a/apps/api/src/app/portfolio/portfolio.service.spec.ts +++ b/apps/api/src/app/portfolio/portfolio.service.spec.ts @@ -27,7 +27,7 @@ describe('PortfolioService', () => { portfolioService .getAnnualizedPerformancePercent({ daysInMarket: NaN, // differenceInDays of date-fns returns NaN for the same day - netPerformancePercent: new Big(0) + netPerformancePercentage: new Big(0) }) .toNumber() ).toEqual(0); @@ -36,7 +36,7 @@ describe('PortfolioService', () => { portfolioService .getAnnualizedPerformancePercent({ daysInMarket: 0, - netPerformancePercent: new Big(0) + netPerformancePercentage: new Big(0) }) .toNumber() ).toEqual(0); @@ -48,7 +48,7 @@ describe('PortfolioService', () => { portfolioService .getAnnualizedPerformancePercent({ daysInMarket: 65, // < 1 year - netPerformancePercent: new Big(0.1025) + netPerformancePercentage: new Big(0.1025) }) .toNumber() ).toBeCloseTo(0.729705); @@ -57,7 +57,7 @@ describe('PortfolioService', () => { portfolioService .getAnnualizedPerformancePercent({ daysInMarket: 365, // 1 year - netPerformancePercent: new Big(0.05) + netPerformancePercentage: new Big(0.05) }) .toNumber() ).toBeCloseTo(0.05); @@ -69,7 +69,7 @@ describe('PortfolioService', () => { portfolioService .getAnnualizedPerformancePercent({ daysInMarket: 575, // > 1 year - netPerformancePercent: new Big(0.2374) + netPerformancePercentage: new Big(0.2374) }) .toNumber() ).toBeCloseTo(0.145); diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 4be9d4e00..a98887ca9 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -208,16 +208,16 @@ export class PortfolioService { public getAnnualizedPerformancePercent({ daysInMarket, - netPerformancePercent + netPerformancePercentage }: { daysInMarket: number; - netPerformancePercent: Big; + netPerformancePercentage: Big; }): Big { if (isNumber(daysInMarket) && daysInMarket > 0) { const exponent = new Big(365).div(daysInMarket).toNumber(); return new Big( - Math.pow(netPerformancePercent.plus(1).toNumber(), exponent) + Math.pow(netPerformancePercentage.plus(1).toNumber(), exponent) ).minus(1); } @@ -360,7 +360,7 @@ export class PortfolioService { userId, calculationType: PerformanceCalculationType.TWR, currency: userCurrency, - hasFilters: filters?.length > 0, + hasFilters: true, // disable cache isExperimentalFeatures: this.request.user?.Settings.settings.isExperimentalFeatures }); @@ -704,7 +704,7 @@ export class PortfolioService { const dividendYieldPercent = this.getAnnualizedPerformancePercent({ daysInMarket: differenceInDays(new Date(), parseDate(firstBuyDate)), - netPerformancePercent: timeWeightedInvestment.eq(0) + netPerformancePercentage: timeWeightedInvestment.eq(0) ? new Big(0) : dividendInBaseCurrency.div(timeWeightedInvestment) }); @@ -712,7 +712,9 @@ export class PortfolioService { const dividendYieldPercentWithCurrencyEffect = this.getAnnualizedPerformancePercent({ daysInMarket: differenceInDays(new Date(), parseDate(firstBuyDate)), - netPerformancePercent: timeWeightedInvestmentWithCurrencyEffect.eq(0) + netPerformancePercentage: timeWeightedInvestmentWithCurrencyEffect.eq( + 0 + ) ? new Big(0) : dividendInBaseCurrency.div( timeWeightedInvestmentWithCurrencyEffect @@ -1108,16 +1110,16 @@ export class PortfolioService { firstOrderDate: undefined, hasErrors: false, performance: { - currentGrossPerformance: 0, - currentGrossPerformancePercent: 0, - currentGrossPerformancePercentWithCurrencyEffect: 0, - currentGrossPerformanceWithCurrencyEffect: 0, - currentNetPerformance: 0, - currentNetPerformancePercent: 0, - currentNetPerformancePercentWithCurrencyEffect: 0, - currentNetPerformanceWithCurrencyEffect: 0, currentNetWorth: 0, - currentValue: 0, + currentValueInBaseCurrency: 0, + grossPerformance: 0, + grossPerformancePercentage: 0, + grossPerformancePercentageWithCurrencyEffect: 0, + grossPerformanceWithCurrencyEffect: 0, + netPerformance: 0, + netPerformancePercentage: 0, + netPerformancePercentageWithCurrencyEffect: 0, + netPerformanceWithCurrencyEffect: 0, totalInvestment: 0 } }; @@ -1152,9 +1154,9 @@ export class PortfolioService { let currentNetPerformance = netPerformance; - let currentNetPerformancePercent = netPerformancePercentage; + let currentNetPerformancePercentage = netPerformancePercentage; - let currentNetPerformancePercentWithCurrencyEffect = + let currentNetPerformancePercentageWithCurrencyEffect = netPerformancePercentageWithCurrencyEffect; let currentNetPerformanceWithCurrencyEffect = @@ -1173,11 +1175,11 @@ export class PortfolioService { if (itemOfToday) { currentNetPerformance = new Big(itemOfToday.netPerformance); - currentNetPerformancePercent = new Big( + currentNetPerformancePercentage = new Big( itemOfToday.netPerformanceInPercentage ).div(100); - currentNetPerformancePercentWithCurrencyEffect = new Big( + currentNetPerformancePercentageWithCurrencyEffect = new Big( itemOfToday.netPerformanceInPercentageWithCurrencyEffect ).div(100); @@ -1195,19 +1197,19 @@ export class PortfolioService { firstOrderDate: parseDate(items[0]?.date), performance: { currentNetWorth, - currentGrossPerformance: grossPerformance.toNumber(), - currentGrossPerformancePercent: grossPerformancePercentage.toNumber(), - currentGrossPerformancePercentWithCurrencyEffect: + currentValueInBaseCurrency: currentValueInBaseCurrency.toNumber(), + grossPerformance: grossPerformance.toNumber(), + grossPerformancePercentage: grossPerformancePercentage.toNumber(), + grossPerformancePercentageWithCurrencyEffect: grossPerformancePercentageWithCurrencyEffect.toNumber(), - currentGrossPerformanceWithCurrencyEffect: + grossPerformanceWithCurrencyEffect: grossPerformanceWithCurrencyEffect.toNumber(), - currentNetPerformance: currentNetPerformance.toNumber(), - currentNetPerformancePercent: currentNetPerformancePercent.toNumber(), - currentNetPerformancePercentWithCurrencyEffect: - currentNetPerformancePercentWithCurrencyEffect.toNumber(), - currentNetPerformanceWithCurrencyEffect: + netPerformance: currentNetPerformance.toNumber(), + netPerformancePercentage: currentNetPerformancePercentage.toNumber(), + netPerformancePercentageWithCurrencyEffect: + currentNetPerformancePercentageWithCurrencyEffect.toNumber(), + netPerformanceWithCurrencyEffect: currentNetPerformanceWithCurrencyEffect.toNumber(), - currentValue: currentValueInBaseCurrency.toNumber(), totalInvestment: totalInvestment.toNumber() } }; @@ -1604,11 +1606,6 @@ export class PortfolioService { userId = await this.getUserId(impersonationId, userId); const user = await this.userService.user({ id: userId }); - const { performance } = await this.getPerformance({ - impersonationId, - userId - }); - const { activities } = await this.orderService.getOrders({ userCurrency, userId, @@ -1626,6 +1623,19 @@ export class PortfolioService { } } + const { + currentValueInBaseCurrency, + grossPerformance, + grossPerformancePercentage, + grossPerformancePercentageWithCurrencyEffect, + grossPerformanceWithCurrencyEffect, + netPerformance, + netPerformancePercentage, + netPerformancePercentageWithCurrencyEffect, + netPerformanceWithCurrencyEffect, + totalInvestment + } = await portfolioCalculator.getSnapshot(); + const dividendInBaseCurrency = await portfolioCalculator.getDividendInBaseCurrency(); @@ -1694,7 +1704,7 @@ export class PortfolioService { .toNumber(); const netWorth = new Big(balanceInBaseCurrency) - .plus(performance.currentValue) + .plus(currentValueInBaseCurrency) .plus(valuables) .plus(excludedAccountsAndActivities) .minus(liabilities) @@ -1704,19 +1714,18 @@ export class PortfolioService { const annualizedPerformancePercent = this.getAnnualizedPerformancePercent({ daysInMarket, - netPerformancePercent: new Big(performance.currentNetPerformancePercent) + netPerformancePercentage: new Big(netPerformancePercentage) })?.toNumber(); const annualizedPerformancePercentWithCurrencyEffect = this.getAnnualizedPerformancePercent({ daysInMarket, - netPerformancePercent: new Big( - performance.currentNetPerformancePercentWithCurrencyEffect + netPerformancePercentage: new Big( + netPerformancePercentageWithCurrencyEffect ) })?.toNumber(); return { - ...performance, annualizedPerformancePercent, annualizedPerformancePercentWithCurrencyEffect, cash, @@ -1725,6 +1734,7 @@ export class PortfolioService { totalBuy, totalSell, committedFunds: committedFunds.toNumber(), + currentValueInBaseCurrency: currentValueInBaseCurrency.toNumber(), dividendInBaseCurrency: dividendInBaseCurrency.toNumber(), emergencyFund: { assets: emergencyFundPositionsValueInBaseCurrency, @@ -1738,15 +1748,28 @@ export class PortfolioService { filteredValueInPercentage: netWorth ? filteredValueInBaseCurrency.div(netWorth).toNumber() : undefined, - fireWealth: new Big(performance.currentValue) + fireWealth: new Big(currentValueInBaseCurrency) .minus(emergencyFundPositionsValueInBaseCurrency) .toNumber(), + grossPerformance: grossPerformance.toNumber(), + grossPerformancePercentage: grossPerformancePercentage.toNumber(), + grossPerformancePercentageWithCurrencyEffect: + grossPerformancePercentageWithCurrencyEffect.toNumber(), + grossPerformanceWithCurrencyEffect: + grossPerformanceWithCurrencyEffect.toNumber(), interest: interest.toNumber(), items: valuables.toNumber(), liabilities: liabilities.toNumber(), + netPerformance: netPerformance.toNumber(), + netPerformancePercentage: netPerformancePercentage.toNumber(), + netPerformancePercentageWithCurrencyEffect: + netPerformancePercentageWithCurrencyEffect.toNumber(), + netPerformanceWithCurrencyEffect: + netPerformanceWithCurrencyEffect.toNumber(), ordersCount: activities.filter(({ type }) => { - return type === 'BUY' || type === 'SELL'; + return ['BUY', 'SELL'].includes(type); }).length, + totalInvestment: totalInvestment.toNumber(), totalValueInBaseCurrency: netWorth }; } diff --git a/apps/client/src/app/components/portfolio-performance/portfolio-performance.component.html b/apps/client/src/app/components/portfolio-performance/portfolio-performance.component.html index 68d191b5c..3ef55f800 100644 --- a/apps/client/src/app/components/portfolio-performance/portfolio-performance.component.html +++ b/apps/client/src/app/components/portfolio-performance/portfolio-performance.component.html @@ -41,9 +41,7 @@ [isCurrency]="true" [locale]="locale" [value]=" - isLoading - ? undefined - : performance?.currentNetPerformanceWithCurrencyEffect + isLoading ? undefined : performance?.netPerformanceWithCurrencyEffect " />
@@ -55,7 +53,7 @@ [value]=" isLoading ? undefined - : performance?.currentNetPerformancePercentWithCurrencyEffect + : performance?.netPerformancePercentageWithCurrencyEffect " />
diff --git a/apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts b/apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts index b76ecb004..4d205b761 100644 --- a/apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts +++ b/apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts @@ -49,12 +49,12 @@ export class PortfolioPerformanceComponent implements OnChanges, OnInit { this.value.nativeElement.innerHTML = ''; } } else { - if (isNumber(this.performance?.currentValue)) { - new CountUp('value', this.performance?.currentValue, { + if (isNumber(this.performance?.currentValueInBaseCurrency)) { + new CountUp('value', this.performance?.currentValueInBaseCurrency, { decimal: getNumberFormatDecimal(this.locale), decimalPlaces: this.deviceType === 'mobile' && - this.performance?.currentValue >= 100000 + this.performance?.currentValueInBaseCurrency >= 100000 ? 0 : 2, duration: 1, @@ -63,8 +63,7 @@ export class PortfolioPerformanceComponent implements OnChanges, OnInit { } else if (this.showDetails === false) { new CountUp( 'value', - this.performance?.currentNetPerformancePercentWithCurrencyEffect * - 100, + this.performance?.netPerformancePercentageWithCurrencyEffect * 100, { decimal: getNumberFormatDecimal(this.locale), decimalPlaces: 2, diff --git a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html index 347767011..6b80e87b6 100644 --- a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html +++ b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html @@ -9,9 +9,19 @@ class="flex-nowrap px-3 py-1 row" [hidden]="summary?.ordersCount === null" > -
+
{{ summary?.ordersCount }} - {summary?.ordersCount, plural, =1 {transaction} other {transactions}} + {summary?.ordersCount, plural, + =1 {activity} + other {activities} + } + + +
@@ -65,9 +75,7 @@ [locale]="locale" [unit]="baseCurrency" [value]=" - isLoading - ? undefined - : summary?.currentGrossPerformanceWithCurrencyEffect + isLoading ? undefined : summary?.grossPerformanceWithCurrencyEffect " />
@@ -91,7 +99,7 @@ [value]=" isLoading ? undefined - : summary?.currentGrossPerformancePercentWithCurrencyEffect + : summary?.grossPerformancePercentageWithCurrencyEffect " />
@@ -121,9 +129,7 @@ [locale]="locale" [unit]="baseCurrency" [value]=" - isLoading - ? undefined - : summary?.currentNetPerformanceWithCurrencyEffect + isLoading ? undefined : summary?.netPerformanceWithCurrencyEffect " />
@@ -147,7 +153,7 @@ [value]=" isLoading ? undefined - : summary?.currentNetPerformancePercentWithCurrencyEffect + : summary?.netPerformancePercentageWithCurrencyEffect " />
@@ -164,7 +170,7 @@ [isCurrency]="true" [locale]="locale" [unit]="baseCurrency" - [value]="isLoading ? undefined : summary?.currentValue" + [value]="isLoading ? undefined : summary?.currentValueInBaseCurrency" />
diff --git a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts index 9ceae5186..020a8fed0 100644 --- a/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts +++ b/apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts @@ -1,5 +1,6 @@ import { getDateFnsLocale, getLocale } from '@ghostfolio/common/helper'; import { PortfolioSummary } from '@ghostfolio/common/interfaces'; +import { translate } from '@ghostfolio/ui/i18n'; import { ChangeDetectionStrategy, @@ -28,6 +29,9 @@ export class PortfolioSummaryComponent implements OnChanges, OnInit { @Output() emergencyFundChanged = new EventEmitter(); + public buyAndSellActivitiesTooltip = translate( + 'BUY_AND_SELL_ACTIVITIES_TOOLTIP' + ); public timeInMarket: string; public constructor() {} diff --git a/apps/client/src/app/components/portfolio-summary/portfolio-summary.module.ts b/apps/client/src/app/components/portfolio-summary/portfolio-summary.module.ts index 603d5271a..b35f1e317 100644 --- a/apps/client/src/app/components/portfolio-summary/portfolio-summary.module.ts +++ b/apps/client/src/app/components/portfolio-summary/portfolio-summary.module.ts @@ -2,13 +2,14 @@ import { GfValueComponent } from '@ghostfolio/ui/value'; import { CommonModule } from '@angular/common'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; +import { MatTooltipModule } from '@angular/material/tooltip'; import { PortfolioSummaryComponent } from './portfolio-summary.component'; @NgModule({ declarations: [PortfolioSummaryComponent], exports: [PortfolioSummaryComponent], - imports: [CommonModule, GfValueComponent], + imports: [CommonModule, GfValueComponent, MatTooltipModule], schemas: [CUSTOM_ELEMENTS_SCHEMA] }) export class GfPortfolioSummaryModule {} diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.html b/apps/client/src/app/pages/portfolio/analysis/analysis-page.html index 5f6acdbe2..191dca06f 100644 --- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.html +++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -42,7 +42,7 @@ [value]=" isLoadingInvestmentChart ? undefined - : performance?.currentNetPerformance + : performance?.netPerformance " />
@@ -61,7 +61,7 @@ [value]=" isLoadingInvestmentChart ? undefined - : performance?.currentNetPerformancePercent + : performance?.netPerformancePercentage " />
@@ -86,10 +86,10 @@ [value]=" isLoadingInvestmentChart ? undefined - : performance?.currentNetPerformance === null + : performance?.netPerformance === null ? null - : performance?.currentNetPerformanceWithCurrencyEffect - - performance?.currentNetPerformance + : performance?.netPerformanceWithCurrencyEffect - + performance?.netPerformance " />
@@ -108,10 +108,10 @@ [value]=" isLoadingInvestmentChart ? undefined - : performance?.currentNetPerformancePercent === null + : performance?.netPerformancePercentage === null ? null - : performance?.currentNetPerformancePercentWithCurrencyEffect - - performance?.currentNetPerformancePercent + : performance?.netPerformancePercentageWithCurrencyEffect - + performance?.netPerformancePercentage " />
@@ -131,7 +131,7 @@ [value]=" isLoadingInvestmentChart ? undefined - : performance?.currentNetPerformanceWithCurrencyEffect + : performance?.netPerformanceWithCurrencyEffect " />
@@ -150,7 +150,7 @@ [value]=" isLoadingInvestmentChart ? undefined - : performance?.currentNetPerformancePercentWithCurrencyEffect + : performance?.netPerformancePercentageWithCurrencyEffect " />
diff --git a/libs/common/src/lib/interfaces/portfolio-performance.interface.ts b/libs/common/src/lib/interfaces/portfolio-performance.interface.ts index 1c6f50b30..9d4ac5fab 100644 --- a/libs/common/src/lib/interfaces/portfolio-performance.interface.ts +++ b/libs/common/src/lib/interfaces/portfolio-performance.interface.ts @@ -1,14 +1,14 @@ export interface PortfolioPerformance { annualizedPerformancePercent?: number; - currentGrossPerformance: number; - currentGrossPerformancePercent: number; - currentGrossPerformancePercentWithCurrencyEffect: number; - currentGrossPerformanceWithCurrencyEffect: number; - currentNetPerformance: number; - currentNetPerformancePercent: number; - currentNetPerformancePercentWithCurrencyEffect: number; - currentNetPerformanceWithCurrencyEffect: number; - currentNetWorth: number; - currentValue: number; + currentNetWorth?: number; + currentValueInBaseCurrency: number; + grossPerformance: number; + grossPerformancePercentage: number; + grossPerformancePercentageWithCurrencyEffect: number; + grossPerformanceWithCurrencyEffect: number; + netPerformance: number; + netPerformancePercentage: number; + netPerformancePercentageWithCurrencyEffect: number; + netPerformanceWithCurrencyEffect: number; totalInvestment: number; } diff --git a/libs/ui/src/lib/i18n.ts b/libs/ui/src/lib/i18n.ts index e1266baa3..51b3cab69 100644 --- a/libs/ui/src/lib/i18n.ts +++ b/libs/ui/src/lib/i18n.ts @@ -5,6 +5,7 @@ const locales = { 'Asia-Pacific': $localize`Asia-Pacific`, ASSET_CLASS: $localize`Asset Class`, ASSET_SUB_CLASS: $localize`Asset Sub Class`, + BUY_AND_SELL_ACTIVITIES_TOOLTIP: $localize`Buy and sell`, CORE: $localize`Core`, DATA_IMPORT_AND_EXPORT_TOOLTIP_BASIC: $localize`Switch to Ghostfolio Premium or Ghostfolio Open Source easily`, DATA_IMPORT_AND_EXPORT_TOOLTIP_OSS: $localize`Switch to Ghostfolio Premium easily`, From 30a64e7fc1cd68f28414e65c4208c09edbe85bb8 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 4 May 2024 15:54:29 +0200 Subject: [PATCH 184/203] Release 2.79.0 (#3371) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9e8fd811..72446d8c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.79.0 - 2024-05-04 ### Changed diff --git a/package.json b/package.json index e2bb13468..362763b4d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.78.0", + "version": "2.79.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 8438a45bcfb9e6a75ff78903adb43bd8fef6b61e Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sat, 4 May 2024 16:32:32 +0200 Subject: [PATCH 185/203] Update changelog (#3372) --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72446d8c8..5535ba45a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Moved the holdings table to the holdings tab of the home page - Improved the performance labels (with and without currency effects) in the position detail dialog -- Optimized the calculations of the of the portfolio details endpoint +- Optimized the calculations of the portfolio details endpoint ### Fixed From 6765191a8cccdfc93e684aa748e15c6b989bae8d Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Sun, 5 May 2024 09:09:57 +0200 Subject: [PATCH 186/203] Bugfix/fix position detail dialog open in holding search of assistant (#3374) * Open position detail dialog (via holding search of assistant) * Update changelog --- CHANGELOG.md | 6 ++ .../src/app/pages/home/home-page.component.ts | 75 +++++++++++++++++++ 2 files changed, 81 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5535ba45a..4332db401 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Fixed + +- Fixed the position detail dialog open functionality when searching for a holding in the assistant + ## 2.79.0 - 2024-05-04 ### Changed diff --git a/apps/client/src/app/pages/home/home-page.component.ts b/apps/client/src/app/pages/home/home-page.component.ts index 3a6a0cb26..8f8386473 100644 --- a/apps/client/src/app/pages/home/home-page.component.ts +++ b/apps/client/src/app/pages/home/home-page.component.ts @@ -1,7 +1,14 @@ +import { PositionDetailDialogParams } from '@ghostfolio/client/components/position-detail-dialog/interfaces/interfaces'; +import { PositionDetailDialog } from '@ghostfolio/client/components/position-detail-dialog/position-detail-dialog.component'; +import { ImpersonationStorageService } from '@ghostfolio/client/services/impersonation-storage.service'; import { UserService } from '@ghostfolio/client/services/user/user.service'; import { TabConfiguration, User } from '@ghostfolio/common/interfaces'; +import { hasPermission, permissions } from '@ghostfolio/common/permissions'; import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { ActivatedRoute, Router } from '@angular/router'; +import { DataSource } from '@prisma/client'; import { DeviceDetectorService } from 'ngx-device-detector'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; @@ -14,6 +21,7 @@ import { takeUntil } from 'rxjs/operators'; }) export class HomePageComponent implements OnDestroy, OnInit { public deviceType: string; + public hasImpersonationId: boolean; public tabs: TabConfiguration[] = []; public user: User; @@ -22,8 +30,27 @@ export class HomePageComponent implements OnDestroy, OnInit { public constructor( private changeDetectorRef: ChangeDetectorRef, private deviceService: DeviceDetectorService, + private dialog: MatDialog, + private impersonationStorageService: ImpersonationStorageService, + private route: ActivatedRoute, + private router: Router, private userService: UserService ) { + this.route.queryParams + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((params) => { + if ( + params['dataSource'] && + params['positionDetailDialog'] && + params['symbol'] + ) { + this.openPositionDialog({ + dataSource: params['dataSource'], + symbol: params['symbol'] + }); + } + }); + this.userService.stateChanged .pipe(takeUntil(this.unsubscribeSubject)) .subscribe((state) => { @@ -59,10 +86,58 @@ export class HomePageComponent implements OnDestroy, OnInit { public ngOnInit() { this.deviceType = this.deviceService.getDeviceInfo().deviceType; + + this.impersonationStorageService + .onChangeHasImpersonation() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((impersonationId) => { + this.hasImpersonationId = !!impersonationId; + }); } public ngOnDestroy() { this.unsubscribeSubject.next(); this.unsubscribeSubject.complete(); } + + private openPositionDialog({ + dataSource, + symbol + }: { + dataSource: DataSource; + symbol: string; + }) { + this.userService + .get() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe((user) => { + this.user = user; + + const dialogRef = this.dialog.open(PositionDetailDialog, { + autoFocus: false, + data: { + dataSource, + symbol, + baseCurrency: this.user?.settings?.baseCurrency, + colorScheme: this.user?.settings?.colorScheme, + deviceType: this.deviceType, + hasImpersonationId: this.hasImpersonationId, + hasPermissionToReportDataGlitch: hasPermission( + this.user?.permissions, + permissions.reportDataGlitch + ), + locale: this.user?.settings?.locale + }, + height: this.deviceType === 'mobile' ? '97.5vh' : '80vh', + width: this.deviceType === 'mobile' ? '100vw' : '50rem' + }); + + dialogRef + .afterClosed() + .pipe(takeUntil(this.unsubscribeSubject)) + .subscribe(() => { + this.router.navigate(['.'], { relativeTo: this.route }); + }); + }); + } } From 378e57c3bc72aa24ac89194532782fce8e2fbe17 Mon Sep 17 00:00:00 2001 From: Colin Seymour Date: Mon, 6 May 2024 16:02:18 +0100 Subject: [PATCH 187/203] Feature/add links to Home Assistant add-on (#3367) * Add links to Home Assistant add-on --- README.md | 2 +- .../src/app/pages/faq/self-hosting/self-hosting-page.html | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index b48fa48db..eaf641544 100644 --- a/README.md +++ b/README.md @@ -142,7 +142,7 @@ docker compose --env-file ./.env -f docker/docker-compose.build.yml up -d ### Home Server Systems (Community) -Ghostfolio is available for various home server systems, including [CasaOS](https://github.com/bigbeartechworld/big-bear-casaos), Home Assistant, [Runtipi](https://www.runtipi.io/docs/apps-available), [TrueCharts](https://truecharts.org/charts/stable/ghostfolio), [Umbrel](https://apps.umbrel.com/app/ghostfolio), and [Unraid](https://unraid.net/community/apps?q=ghostfolio). +Ghostfolio is available for various home server systems, including [CasaOS](https://github.com/bigbeartechworld/big-bear-casaos), [Home Assistant](https://github.com/lildude/ha-addon-ghostfolio), [Runtipi](https://www.runtipi.io/docs/apps-available), [TrueCharts](https://truecharts.org/charts/stable/ghostfolio), [Umbrel](https://apps.umbrel.com/app/ghostfolio), and [Unraid](https://unraid.net/community/apps?q=ghostfolio). ## Development diff --git a/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html b/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html index da6690d58..4445495fd 100644 --- a/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html +++ b/apps/client/src/app/pages/faq/self-hosting/self-hosting-page.html @@ -30,8 +30,10 @@ systems, including CasaOS, Home Assistant, - Runtipi, + >, + Home Assistant, Runtipi, TrueCharts, Umbrel, and From 9b5e350e3babc259228eb292637c4d349a53dae5 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Mon, 6 May 2024 17:03:58 +0200 Subject: [PATCH 188/203] Feature/harmonize log message (#3343) --- apps/api/src/events/portfolio-changed.listener.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/api/src/events/portfolio-changed.listener.ts b/apps/api/src/events/portfolio-changed.listener.ts index 4a6e3d386..fcf47ce6c 100644 --- a/apps/api/src/events/portfolio-changed.listener.ts +++ b/apps/api/src/events/portfolio-changed.listener.ts @@ -12,7 +12,7 @@ export class PortfolioChangedListener { @OnEvent(PortfolioChangedEvent.getName()) handlePortfolioChangedEvent(event: PortfolioChangedEvent) { Logger.log( - `Portfolio of user with id ${event.getUserId()} has changed`, + `Portfolio of user '${event.getUserId()}' has changed`, 'PortfolioChangedListener' ); From 053c7e591eec2ede7d6457b4ff6d52d0c3b1b9a5 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Tue, 7 May 2024 19:00:55 +0200 Subject: [PATCH 189/203] Feature/upgrade ionicons to version 7.4.0 (#3356) * Upgrade ionicons to version 7.4.0 * Update changelog --- CHANGELOG.md | 4 ++++ .../src/app/pages/about/overview/about-overview-page.html | 2 +- package.json | 2 +- yarn.lock | 8 ++++---- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4332db401..e2ec6836f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Changed + +- Upgraded `ionicons` from version `7.3.0` to `7.4.0` + ### Fixed - Fixed the position detail dialog open functionality when searching for a holding in the assistant diff --git a/apps/client/src/app/pages/about/overview/about-overview-page.html b/apps/client/src/app/pages/about/overview/about-overview-page.html index 1a6b6c466..f196b95ba 100644 --- a/apps/client/src/app/pages/about/overview/about-overview-page.html +++ b/apps/client/src/app/pages/about/overview/about-overview-page.html @@ -77,7 +77,7 @@ mat-icon-button title="Follow Ghostfolio on X (formerly Twitter)" > - 𝕏 + Date: Tue, 7 May 2024 20:48:02 +0200 Subject: [PATCH 190/203] Feature/increase number of attempts of queue jobs (#3376) * Increase number of attempts * Update changelog --- CHANGELOG.md | 1 + libs/common/src/lib/config.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2ec6836f..190cf8f21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Increased the number of attempts of queue jobs from `10` to `12` (fail later) - Upgraded `ionicons` from version `7.3.0` to `7.4.0` ### Fixed diff --git a/libs/common/src/lib/config.ts b/libs/common/src/lib/config.ts index 9e438c0f5..c89143d9d 100644 --- a/libs/common/src/lib/config.ts +++ b/libs/common/src/lib/config.ts @@ -66,7 +66,7 @@ export const EMERGENCY_FUND_TAG_ID = '4452656d-9fa4-4bd0-ba38-70492e31d180'; export const GATHER_ASSET_PROFILE_PROCESS = 'GATHER_ASSET_PROFILE'; export const GATHER_ASSET_PROFILE_PROCESS_OPTIONS: JobOptions = { - attempts: 10, + attempts: 12, backoff: { delay: ms('1 minute'), type: 'exponential' @@ -76,7 +76,7 @@ export const GATHER_ASSET_PROFILE_PROCESS_OPTIONS: JobOptions = { export const GATHER_HISTORICAL_MARKET_DATA_PROCESS = 'GATHER_HISTORICAL_MARKET_DATA'; export const GATHER_HISTORICAL_MARKET_DATA_PROCESS_OPTIONS: JobOptions = { - attempts: 10, + attempts: 12, backoff: { delay: ms('1 minute'), type: 'exponential' From 1fd836194f03f82be60ce860f87d490f526348a7 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Wed, 8 May 2024 20:02:50 +0200 Subject: [PATCH 191/203] Feature/add absolute change column to holdings table (#3378) * Add absolute change column * Update changelog --- CHANGELOG.md | 4 +++ .../holdings-table.component.html | 25 ++++++++++++++++++- .../holdings-table.component.ts | 7 +++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 190cf8f21..fe097b380 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Added the absolute change column to the holdings table on the home page + ### Changed - Increased the number of attempts of queue jobs from `10` to `12` (fail later) diff --git a/libs/ui/src/lib/holdings-table/holdings-table.component.html b/libs/ui/src/lib/holdings-table/holdings-table.component.html index 181b120a8..814eefa4f 100644 --- a/libs/ui/src/lib/holdings-table/holdings-table.component.html +++ b/libs/ui/src/lib/holdings-table/holdings-table.component.html @@ -109,7 +109,30 @@ - + + + Change + + +
+ +
+ +
+ + Date: Wed, 8 May 2024 20:04:32 +0200 Subject: [PATCH 192/203] Feature/clean up deprecated GET api/portfolio/positions endpoint (#3373) --- .../portfolio-positions.interface.ts | 5 ---- .../src/app/portfolio/portfolio.controller.ts | 30 ------------------- .../import-activities-dialog.component.ts | 10 +++---- .../analysis/analysis-page.component.ts | 24 +++++++-------- .../portfolio/analysis/analysis-page.html | 24 +++++++-------- apps/client/src/app/services/data.service.ts | 19 ------------ .../src/lib/assistant/assistant.component.ts | 6 ++-- 7 files changed, 30 insertions(+), 88 deletions(-) delete mode 100644 apps/api/src/app/portfolio/interfaces/portfolio-positions.interface.ts diff --git a/apps/api/src/app/portfolio/interfaces/portfolio-positions.interface.ts b/apps/api/src/app/portfolio/interfaces/portfolio-positions.interface.ts deleted file mode 100644 index fa6141a7a..000000000 --- a/apps/api/src/app/portfolio/interfaces/portfolio-positions.interface.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { Position } from '@ghostfolio/common/interfaces'; - -export interface PortfolioPositions { - positions: Position[]; -} diff --git a/apps/api/src/app/portfolio/portfolio.controller.ts b/apps/api/src/app/portfolio/portfolio.controller.ts index 4a07cd65b..ed3c0f174 100644 --- a/apps/api/src/app/portfolio/portfolio.controller.ts +++ b/apps/api/src/app/portfolio/portfolio.controller.ts @@ -52,7 +52,6 @@ import { Big } from 'big.js'; import { StatusCodes, getReasonPhrase } from 'http-status-codes'; import { PortfolioPositionDetail } from './interfaces/portfolio-position-detail.interface'; -import { PortfolioPositions } from './interfaces/portfolio-positions.interface'; import { PortfolioService } from './portfolio.service'; @Controller('portfolio') @@ -494,35 +493,6 @@ export class PortfolioController { return performanceInformation; } - /** - * @deprecated - */ - @Get('positions') - @UseGuards(AuthGuard('jwt'), HasPermissionGuard) - @UseInterceptors(RedactValuesInResponseInterceptor) - @UseInterceptors(TransformDataSourceInResponseInterceptor) - public async getPositions( - @Headers(HEADER_KEY_IMPERSONATION.toLowerCase()) impersonationId: string, - @Query('accounts') filterByAccounts?: string, - @Query('assetClasses') filterByAssetClasses?: string, - @Query('query') filterBySearchQuery?: string, - @Query('range') dateRange: DateRange = 'max', - @Query('tags') filterByTags?: string - ): Promise { - const filters = this.apiService.buildFiltersFromQueryParams({ - filterByAccounts, - filterByAssetClasses, - filterBySearchQuery, - filterByTags - }); - - return this.portfolioService.getPositions({ - dateRange, - filters, - impersonationId - }); - } - @Get('public/:accessId') @UseInterceptors(TransformDataSourceInResponseInterceptor) public async getPublic( diff --git a/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts b/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts index ccc861335..b59994811 100644 --- a/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts @@ -2,7 +2,7 @@ import { CreateAccountDto } from '@ghostfolio/api/app/account/create-account.dto import { Activity } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { DataService } from '@ghostfolio/client/services/data.service'; import { ImportActivitiesService } from '@ghostfolio/client/services/import-activities.service'; -import { Position } from '@ghostfolio/common/interfaces'; +import { PortfolioPosition } from '@ghostfolio/common/interfaces'; import { StepperOrientation, @@ -43,7 +43,7 @@ export class ImportActivitiesDialog implements OnDestroy { public deviceType: string; public dialogTitle = $localize`Import Activities`; public errorMessages: string[] = []; - public holdings: Position[] = []; + public holdings: PortfolioPosition[] = []; public importStep: ImportStep = ImportStep.UPLOAD_FILE; public isLoading = false; public maxSafeInteger = Number.MAX_SAFE_INTEGER; @@ -88,7 +88,7 @@ export class ImportActivitiesDialog implements OnDestroy { this.uniqueAssetForm.get('uniqueAsset').disable(); this.dataService - .fetchPositions({ + .fetchPortfolioHoldings({ filters: [ { id: AssetClass.EQUITY, @@ -98,8 +98,8 @@ export class ImportActivitiesDialog implements OnDestroy { range: 'max' }) .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(({ positions }) => { - this.holdings = sortBy(positions, ({ name }) => { + .subscribe(({ holdings }) => { + this.holdings = sortBy(holdings, ({ name }) => { return name.toLowerCase(); }); this.uniqueAssetForm.get('uniqueAsset').enable(); diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts index 4acf6dbb9..93dfb6517 100644 --- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts +++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.component.ts @@ -8,7 +8,7 @@ import { HistoricalDataItem, PortfolioInvestments, PortfolioPerformance, - Position, + PortfolioPosition, User } from '@ghostfolio/common/interfaces'; import { InvestmentItem } from '@ghostfolio/common/interfaces/investment-item.interface'; @@ -35,7 +35,7 @@ export class AnalysisPageComponent implements OnDestroy, OnInit { public benchmark: Partial; public benchmarkDataItems: HistoricalDataItem[] = []; public benchmarks: Partial[]; - public bottom3: Position[]; + public bottom3: PortfolioPosition[]; public dateRangeOptions = ToggleComponent.DEFAULT_DATE_RANGE_OPTIONS; public daysInMarket: number; public deviceType: string; @@ -60,7 +60,7 @@ export class AnalysisPageComponent implements OnDestroy, OnInit { public performanceDataItemsInPercentage: HistoricalDataItem[]; public portfolioEvolutionDataLabel = $localize`Investment`; public streaks: PortfolioInvestments['streaks']; - public top3: Position[]; + public top3: PortfolioPosition[]; public unitCurrentStreak: string; public unitLongestStreak: string; public user: User; @@ -308,23 +308,23 @@ export class AnalysisPageComponent implements OnDestroy, OnInit { }); this.dataService - .fetchPositions({ + .fetchPortfolioHoldings({ filters: this.userService.getFilters(), range: this.user?.settings?.dateRange }) .pipe(takeUntil(this.unsubscribeSubject)) - .subscribe(({ positions }) => { - const positionsSorted = sortBy( - positions.filter(({ netPerformancePercentageWithCurrencyEffect }) => { - return isNumber(netPerformancePercentageWithCurrencyEffect); + .subscribe(({ holdings }) => { + const holdingsSorted = sortBy( + holdings.filter(({ netPerformancePercentWithCurrencyEffect }) => { + return isNumber(netPerformancePercentWithCurrencyEffect); }), - 'netPerformancePercentageWithCurrencyEffect' + 'netPerformancePercentWithCurrencyEffect' ).reverse(); - this.top3 = positionsSorted.slice(0, 3); + this.top3 = holdingsSorted.slice(0, 3); - if (positions?.length > 3) { - this.bottom3 = positionsSorted.slice(-3).reverse(); + if (holdings?.length > 3) { + this.bottom3 = holdingsSorted.slice(-3).reverse(); } else { this.bottom3 = []; } diff --git a/apps/client/src/app/pages/portfolio/analysis/analysis-page.html b/apps/client/src/app/pages/portfolio/analysis/analysis-page.html index 191dca06f..90cf8bc06 100644 --- a/apps/client/src/app/pages/portfolio/analysis/analysis-page.html +++ b/apps/client/src/app/pages/portfolio/analysis/analysis-page.html @@ -170,17 +170,17 @@
    -
  1. +
  2. -
    {{ position.name }}
    +
    {{ holding.name }}
    @@ -218,17 +216,17 @@
      -
    1. +
    2. -
      {{ position.name }}
      +
      {{ holding.name }}
      diff --git a/apps/client/src/app/services/data.service.ts b/apps/client/src/app/services/data.service.ts index d5c1bec00..4f8615e41 100644 --- a/apps/client/src/app/services/data.service.ts +++ b/apps/client/src/app/services/data.service.ts @@ -6,7 +6,6 @@ import { CreateOrderDto } from '@ghostfolio/api/app/order/create-order.dto'; import { Activities } from '@ghostfolio/api/app/order/interfaces/activities.interface'; import { UpdateOrderDto } from '@ghostfolio/api/app/order/update-order.dto'; import { PortfolioPositionDetail } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-position-detail.interface'; -import { PortfolioPositions } from '@ghostfolio/api/app/portfolio/interfaces/portfolio-positions.interface'; import { LookupItem } from '@ghostfolio/api/app/symbol/interfaces/lookup-item.interface'; import { SymbolItem } from '@ghostfolio/api/app/symbol/interfaces/symbol-item.interface'; import { UserItem } from '@ghostfolio/api/app/user/interfaces/user-item.interface'; @@ -376,24 +375,6 @@ export class DataService { }); } - /** - * @deprecated - */ - public fetchPositions({ - filters, - range - }: { - filters?: Filter[]; - range: DateRange; - }): Observable { - let params = this.buildFiltersAsQueryParams({ filters }); - params = params.append('range', range); - - return this.http.get('/api/v1/portfolio/positions', { - params - }); - } - public fetchSymbols({ includeIndices = false, query diff --git a/libs/ui/src/lib/assistant/assistant.component.ts b/libs/ui/src/lib/assistant/assistant.component.ts index f932fd5c2..101872a86 100644 --- a/libs/ui/src/lib/assistant/assistant.component.ts +++ b/libs/ui/src/lib/assistant/assistant.component.ts @@ -416,7 +416,7 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit { private searchHoldings(aSearchTerm: string): Observable { return this.dataService - .fetchPositions({ + .fetchPortfolioHoldings({ filters: [ { id: aSearchTerm, @@ -429,8 +429,8 @@ export class GfAssistantComponent implements OnChanges, OnDestroy, OnInit { catchError(() => { return EMPTY; }), - map(({ positions }) => { - return positions.map( + map(({ holdings }) => { + return holdings.map( ({ assetSubClass, currency, dataSource, name, symbol }) => { return { currency, From 66bdb374e8d4a511d74d8118f4cdade667b21a3f Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Wed, 8 May 2024 20:04:58 +0200 Subject: [PATCH 193/203] Feature/set icon columns of tables to stick at beginning (#3377) * Set icon columns to stick at the beginning * Update changelog --- CHANGELOG.md | 2 ++ .../ui/src/lib/activities-table/activities-table.component.html | 2 +- libs/ui/src/lib/holdings-table/holdings-table.component.html | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe097b380..7a571b620 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Set the icon column of the activities table to stick at the beginning +- Set the icon column of the holdings table to stick at the beginning - Increased the number of attempts of queue jobs from `10` to `12` (fail later) - Upgraded `ionicons` from version `7.3.0` to `7.4.0` diff --git a/libs/ui/src/lib/activities-table/activities-table.component.html b/libs/ui/src/lib/activities-table/activities-table.component.html index 4a1b1004d..dfa17a28c 100644 --- a/libs/ui/src/lib/activities-table/activities-table.component.html +++ b/libs/ui/src/lib/activities-table/activities-table.component.html @@ -119,7 +119,7 @@ - + - + Date: Wed, 8 May 2024 20:37:53 +0200 Subject: [PATCH 194/203] Update translations (#3384) --- apps/client/src/locales/messages.de.xlf | 296 ++++++++++++------------ apps/client/src/locales/messages.es.xlf | 293 ++++++++++++----------- apps/client/src/locales/messages.fr.xlf | 293 ++++++++++++----------- apps/client/src/locales/messages.it.xlf | 293 ++++++++++++----------- apps/client/src/locales/messages.nl.xlf | 293 ++++++++++++----------- apps/client/src/locales/messages.pl.xlf | 296 ++++++++++++------------ apps/client/src/locales/messages.pt.xlf | 293 ++++++++++++----------- apps/client/src/locales/messages.tr.xlf | 293 ++++++++++++----------- apps/client/src/locales/messages.xlf | 289 +++++++++++------------ apps/client/src/locales/messages.zh.xlf | 296 ++++++++++++------------ 10 files changed, 1428 insertions(+), 1507 deletions(-) diff --git a/apps/client/src/locales/messages.de.xlf b/apps/client/src/locales/messages.de.xlf index 1d368b781..23e492b38 100644 --- a/apps/client/src/locales/messages.de.xlf +++ b/apps/client/src/locales/messages.de.xlf @@ -105,11 +105,11 @@ 134 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 221 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 331 @@ -337,7 +337,7 @@ 34 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 301 @@ -465,7 +465,7 @@ 26 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 112 @@ -561,7 +561,7 @@ 130 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 209 @@ -841,7 +841,7 @@ 257 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 356 @@ -1222,10 +1222,6 @@ Aktivitäten verwalten apps/client/src/app/components/home-holdings/home-holdings.html - 22 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page.html 32 @@ -1330,7 +1326,7 @@ Kauf apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 21 + 31 @@ -1338,7 +1334,7 @@ Verkauf apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 33 + 43 @@ -1346,10 +1342,10 @@ Einlage apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 48 + 58 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 165 @@ -1358,7 +1354,7 @@ Absolute Brutto Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 60 + 70 @@ -1366,29 +1362,7 @@ Brutto Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 77 - - - - - - - - - - - - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 12 - - - - {VAR_PLURAL, plural, =1 {transaction} other {transactions}} - {VAR_PLURAL, plural, =1 {Transaktion} other {Transaktionen}} - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 14 + 85 @@ -1396,7 +1370,7 @@ Absolute Netto Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 116 + 124 @@ -1404,7 +1378,7 @@ Netto Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 133 + 139 @@ -1412,7 +1386,7 @@ Gesamtanlagevermögen apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 159 + 165 @@ -1420,7 +1394,7 @@ Wertsachen apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 172 + 178 @@ -1428,7 +1402,7 @@ Notfallfonds apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 184 + 190 apps/client/src/app/pages/features/features-page.html @@ -1444,7 +1418,7 @@ Kaufkraft apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 231 + 237 @@ -1452,7 +1426,7 @@ Gesamtvermögen apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 278 + 284 @@ -1460,7 +1434,7 @@ Performance pro Jahr apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 290 + 296 @@ -1468,10 +1442,10 @@ Dividenden apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 324 + 330 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 177 @@ -1492,7 +1466,7 @@ Bitte gib den Betrag deines Notfallfonds ein: apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts - 53 + 57 @@ -1507,7 +1481,7 @@ 316 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 270 @@ -1527,7 +1501,7 @@ 327 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 282 @@ -1539,7 +1513,7 @@ 10 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 376 @@ -1555,7 +1529,7 @@ Report Data Glitch Datenfehler melden - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 394 @@ -1575,12 +1549,12 @@ 6 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 89 libs/ui/src/lib/holdings-table/holdings-table.component.html - 119 + 142 @@ -1588,7 +1562,7 @@ Alle anzeigen libs/ui/src/lib/holdings-table/holdings-table.component.html - 174 + 197 @@ -2052,7 +2026,7 @@ Bargeld apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 205 + 211 @@ -2176,7 +2150,7 @@ apps/client/src/app/pages/home/home-page.component.ts - 34 + 61 apps/client/src/app/pages/zen/zen-page-routing.module.ts @@ -2192,11 +2166,11 @@ Märkte apps/client/src/app/pages/home/home-page-routing.module.ts - 33 + 38 apps/client/src/app/pages/home/home-page.component.ts - 49 + 76 apps/client/src/app/pages/markets/markets-page-routing.module.ts @@ -2212,7 +2186,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 49 + 44 @@ -2316,7 +2290,7 @@ Zeitstrahl der Investitionen apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 298 + 294 @@ -2332,7 +2306,7 @@ Verlierer apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 216 + 214 @@ -2375,16 +2349,12 @@ 23 - apps/client/src/app/pages/home/home-page.component.ts - 39 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page-routing.module.ts - 13 + apps/client/src/app/pages/home/home-page-routing.module.ts + 28 - apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 39 + apps/client/src/app/pages/home/home-page.component.ts + 66 apps/client/src/app/pages/zen/zen-page.component.ts @@ -2399,7 +2369,7 @@ 77 - apps/client/src/app/pages/portfolio/holdings/holdings-page.html + apps/client/src/app/components/home-holdings/home-holdings.html 4 @@ -2436,7 +2406,7 @@ Verkauf libs/ui/src/lib/i18n.ts - 36 + 37 @@ -2455,7 +2425,7 @@ Quantity Anzahl - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 154 @@ -2531,7 +2501,7 @@ 232 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 228 @@ -2548,7 +2518,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 44 + 39 @@ -2584,7 +2554,7 @@ apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts - 48 + 41 @@ -2851,15 +2821,19 @@ Change Änderung - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 63 + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 119 + Average Unit Price Ø Preis pro Einheit - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 101 @@ -2867,7 +2841,7 @@ Minimum Price Minimum Preis - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 128 @@ -2875,7 +2849,7 @@ Maximum Price Maximum Preis - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 144 @@ -2895,7 +2869,7 @@ 245 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 237 @@ -2911,7 +2885,7 @@ 174 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 254 @@ -2927,7 +2901,7 @@ 77 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 264 @@ -3000,7 +2974,7 @@ libs/ui/src/lib/i18n.ts - 33 + 34 @@ -3036,7 +3010,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -3048,7 +3022,7 @@ libs/ui/src/lib/i18n.ts - 71 + 72 @@ -3116,7 +3090,7 @@ Von der Analyse ausgenommen apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 243 + 249 @@ -3172,7 +3146,7 @@ Portfolio Wertentwicklung apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 268 + 264 @@ -3204,7 +3178,7 @@ Symbol libs/ui/src/lib/i18n.ts - 24 + 25 @@ -3212,7 +3186,7 @@ Tag libs/ui/src/lib/i18n.ts - 25 + 26 @@ -3220,7 +3194,7 @@ Bargeld libs/ui/src/lib/i18n.ts - 39 + 40 @@ -3228,7 +3202,7 @@ Rohstoff libs/ui/src/lib/i18n.ts - 40 + 41 @@ -3236,7 +3210,7 @@ Beteiligungskapital libs/ui/src/lib/i18n.ts - 41 + 42 @@ -3244,7 +3218,7 @@ Feste Einkünfte libs/ui/src/lib/i18n.ts - 42 + 43 @@ -3252,7 +3226,7 @@ Immobilien libs/ui/src/lib/i18n.ts - 44 + 45 @@ -3260,7 +3234,7 @@ Anleihe libs/ui/src/lib/i18n.ts - 47 + 48 @@ -3268,7 +3242,7 @@ Kryptowährung libs/ui/src/lib/i18n.ts - 48 + 49 @@ -3276,7 +3250,7 @@ ETF libs/ui/src/lib/i18n.ts - 49 + 50 @@ -3284,7 +3258,7 @@ Investmentfonds libs/ui/src/lib/i18n.ts - 50 + 51 @@ -3292,7 +3266,7 @@ Edelmetall libs/ui/src/lib/i18n.ts - 51 + 52 @@ -3300,7 +3274,7 @@ Privates Beteiligungskapital libs/ui/src/lib/i18n.ts - 52 + 53 @@ -3308,7 +3282,7 @@ Aktie libs/ui/src/lib/i18n.ts - 53 + 54 @@ -3316,7 +3290,7 @@ Notfallfonds libs/ui/src/lib/i18n.ts - 12 + 13 @@ -3324,7 +3298,7 @@ Andere libs/ui/src/lib/i18n.ts - 20 + 21 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts @@ -3348,7 +3322,7 @@ Nordamerika libs/ui/src/lib/i18n.ts - 63 + 64 @@ -3356,7 +3330,7 @@ Afrika libs/ui/src/lib/i18n.ts - 60 + 61 @@ -3364,7 +3338,7 @@ Asien libs/ui/src/lib/i18n.ts - 61 + 62 @@ -3372,7 +3346,7 @@ Europa libs/ui/src/lib/i18n.ts - 62 + 63 @@ -3380,7 +3354,7 @@ Ozeanien libs/ui/src/lib/i18n.ts - 64 + 65 @@ -3388,7 +3362,7 @@ Südamerika libs/ui/src/lib/i18n.ts - 65 + 66 @@ -3484,7 +3458,7 @@ Zeitstrahl der Dividenden apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 356 + 352 @@ -3496,7 +3470,7 @@ libs/ui/src/lib/i18n.ts - 31 + 32 @@ -3568,11 +3542,11 @@ Zusammenfassung apps/client/src/app/pages/home/home-page-routing.module.ts - 28 + 33 apps/client/src/app/pages/home/home-page.component.ts - 44 + 71 @@ -3620,7 +3594,7 @@ Kern libs/ui/src/lib/i18n.ts - 8 + 9 @@ -3628,7 +3602,7 @@ Zuwendung libs/ui/src/lib/i18n.ts - 13 + 14 @@ -3636,7 +3610,7 @@ Höheres Risiko libs/ui/src/lib/i18n.ts - 14 + 15 @@ -3644,7 +3618,7 @@ Geringeres Risiko libs/ui/src/lib/i18n.ts - 17 + 18 @@ -3652,7 +3626,7 @@ Altersvorsorge libs/ui/src/lib/i18n.ts - 22 + 23 @@ -3660,7 +3634,7 @@ Satellit libs/ui/src/lib/i18n.ts - 23 + 24 @@ -3920,10 +3894,10 @@ Gebühren apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 100 + 108 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 199 @@ -3980,7 +3954,7 @@ Einfacher Wechsel zu Ghostfolio Premium libs/ui/src/lib/i18n.ts - 10 + 11 @@ -4004,7 +3978,7 @@ Einfacher Wechsel zu Ghostfolio Premium oder Ghostfolio Open Source libs/ui/src/lib/i18n.ts - 9 + 10 @@ -4012,7 +3986,7 @@ Einfacher Wechsel zu Ghostfolio Open Source oder Ghostfolio Basic libs/ui/src/lib/i18n.ts - 11 + 12 @@ -4252,7 +4226,7 @@ Diese Aktivität existiert bereits. libs/ui/src/lib/i18n.ts - 15 + 16 @@ -4344,7 +4318,7 @@ Aktueller Streak apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 319 + 315 @@ -4352,7 +4326,7 @@ Längster Streak apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 328 + 324 @@ -4360,7 +4334,7 @@ Monate libs/ui/src/lib/i18n.ts - 19 + 20 @@ -4368,7 +4342,7 @@ Jahre libs/ui/src/lib/i18n.ts - 27 + 28 @@ -4376,7 +4350,7 @@ Monat libs/ui/src/lib/i18n.ts - 18 + 19 @@ -4384,7 +4358,7 @@ Jahr libs/ui/src/lib/i18n.ts - 26 + 27 @@ -4392,7 +4366,7 @@ Verbindlichkeiten apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 258 + 264 apps/client/src/app/pages/features/features-page.html @@ -4532,7 +4506,7 @@ Verbindlichkeit libs/ui/src/lib/i18n.ts - 35 + 36 @@ -9868,7 +9842,7 @@ Kauf libs/ui/src/lib/i18n.ts - 30 + 31 @@ -9876,7 +9850,7 @@ Wertsache libs/ui/src/lib/i18n.ts - 34 + 35 @@ -9900,7 +9874,7 @@ Anlagevermögen apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 218 + 224 @@ -9908,7 +9882,7 @@ Filtervorlage libs/ui/src/lib/i18n.ts - 21 + 22 @@ -9932,7 +9906,7 @@ Japan libs/ui/src/lib/i18n.ts - 16 + 17 @@ -13244,7 +13218,7 @@ Gebühr libs/ui/src/lib/i18n.ts - 32 + 33 @@ -13252,7 +13226,7 @@ Zins apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 312 + 318 @@ -13760,7 +13734,7 @@ Extreme Angst libs/ui/src/lib/i18n.ts - 68 + 69 @@ -13768,7 +13742,7 @@ Extreme Gier libs/ui/src/lib/i18n.ts - 69 + 70 @@ -13776,7 +13750,7 @@ Neutral libs/ui/src/lib/i18n.ts - 72 + 73 @@ -14732,7 +14706,7 @@ Die Marktdaten sind verzögert für apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts - 82 + 81 @@ -14983,7 +14957,7 @@ Active Aktiv - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 30 @@ -14991,7 +14965,7 @@ Closed Abgeschlossen - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 31 @@ -14999,7 +14973,7 @@ Activity Aktivität - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 219 @@ -15007,7 +14981,7 @@ Dividend Yield Dividendenrendite - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 187 @@ -15040,14 +15014,14 @@ Liquidität libs/ui/src/lib/i18n.ts - 43 + 44 Change with currency effect Änderung mit Währungseffekt - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 52 @@ -15055,10 +15029,26 @@ Performance with currency effect Performance mit Währungseffekt - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 79 + + {VAR_PLURAL, plural, =1 {activity} other {activities}} + {VAR_PLURAL, plural, =1 {Aktivität} other {Aktivitäten}} + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 14 + + + + Buy and sell + Kauf und Verkauf + + libs/ui/src/lib/i18n.ts + 8 + + diff --git a/apps/client/src/locales/messages.es.xlf b/apps/client/src/locales/messages.es.xlf index 09dd7c44a..51edc3b79 100644 --- a/apps/client/src/locales/messages.es.xlf +++ b/apps/client/src/locales/messages.es.xlf @@ -106,11 +106,11 @@ 134 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 221 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 331 @@ -338,7 +338,7 @@ 34 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 301 @@ -466,7 +466,7 @@ 26 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 112 @@ -562,7 +562,7 @@ 130 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 209 @@ -842,7 +842,7 @@ 257 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 356 @@ -1223,10 +1223,6 @@ Gestión de las operaciones apps/client/src/app/components/home-holdings/home-holdings.html - 22 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page.html 32 @@ -1331,7 +1327,7 @@ Compra apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 21 + 31 @@ -1339,7 +1335,7 @@ Venta apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 33 + 43 @@ -1347,10 +1343,10 @@ Inversión apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 48 + 58 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 165 @@ -1359,7 +1355,7 @@ Rendimiento bruto absoluto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 60 + 70 @@ -1367,26 +1363,7 @@ Rendimiento bruto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 77 - - - - - - - - Comisiones por - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 12 - - - - {VAR_PLURAL, plural, =1 {transaction} other {transactions}} - {VAR_PLURAL, plural, =1 {transacción} other {transacciones}} - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 14 + 85 @@ -1394,7 +1371,7 @@ Rendimiento neto absoluto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 116 + 124 @@ -1402,7 +1379,7 @@ Rendimiento neto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 133 + 139 @@ -1410,7 +1387,7 @@ Total de activos apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 159 + 165 @@ -1418,7 +1395,7 @@ Objetos de valor apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 172 + 178 @@ -1426,7 +1403,7 @@ Fondo de emergencia apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 184 + 190 apps/client/src/app/pages/features/features-page.html @@ -1442,7 +1419,7 @@ Capacidad de compra apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 231 + 237 @@ -1450,7 +1427,7 @@ Patrimonio neto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 278 + 284 @@ -1458,7 +1435,7 @@ Rendimiento anualizado apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 290 + 296 @@ -1466,10 +1443,10 @@ Dividendo apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 324 + 330 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 177 @@ -1490,7 +1467,7 @@ Por favor, ingresa la cantidad de tu fondo de emergencia: apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts - 53 + 57 @@ -1505,7 +1482,7 @@ 316 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 270 @@ -1525,7 +1502,7 @@ 327 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 282 @@ -1537,7 +1514,7 @@ 10 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 376 @@ -1553,7 +1530,7 @@ Report Data Glitch Reporta un anomalía de los datos - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 394 @@ -1573,12 +1550,12 @@ 6 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 89 libs/ui/src/lib/holdings-table/holdings-table.component.html - 119 + 142 @@ -1586,7 +1563,7 @@ Mostrar todos libs/ui/src/lib/holdings-table/holdings-table.component.html - 174 + 197 @@ -2050,7 +2027,7 @@ Efectivo apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 205 + 211 @@ -2174,7 +2151,7 @@ apps/client/src/app/pages/home/home-page.component.ts - 34 + 61 apps/client/src/app/pages/zen/zen-page-routing.module.ts @@ -2190,11 +2167,11 @@ Mercados apps/client/src/app/pages/home/home-page-routing.module.ts - 33 + 38 apps/client/src/app/pages/home/home-page.component.ts - 49 + 76 apps/client/src/app/pages/markets/markets-page-routing.module.ts @@ -2210,7 +2187,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 49 + 44 @@ -2314,7 +2291,7 @@ Cronología de la inversión apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 298 + 294 @@ -2330,7 +2307,7 @@ Lo peor apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 216 + 214 @@ -2373,16 +2350,12 @@ 23 - apps/client/src/app/pages/home/home-page.component.ts - 39 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page-routing.module.ts - 13 + apps/client/src/app/pages/home/home-page-routing.module.ts + 28 - apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 39 + apps/client/src/app/pages/home/home-page.component.ts + 66 apps/client/src/app/pages/zen/zen-page.component.ts @@ -2397,7 +2370,7 @@ 77 - apps/client/src/app/pages/portfolio/holdings/holdings-page.html + apps/client/src/app/components/home-holdings/home-holdings.html 4 @@ -2434,7 +2407,7 @@ Venta libs/ui/src/lib/i18n.ts - 36 + 37 @@ -2453,7 +2426,7 @@ Quantity Cantidad - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 154 @@ -2529,7 +2502,7 @@ 232 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 228 @@ -2546,7 +2519,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 44 + 39 @@ -2582,7 +2555,7 @@ apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts - 48 + 41 @@ -2849,9 +2822,13 @@ Change Modificar - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 63 + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 119 + Developed Markets @@ -2881,7 +2858,7 @@ 245 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 237 @@ -2893,7 +2870,7 @@ Average Unit Price Precio unitario medio - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 101 @@ -2901,7 +2878,7 @@ Maximum Price Precio máximo - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 144 @@ -2937,7 +2914,7 @@ 174 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 254 @@ -2953,7 +2930,7 @@ 77 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 264 @@ -2961,7 +2938,7 @@ Minimum Price Precio mínimo - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 128 @@ -2990,7 +2967,7 @@ libs/ui/src/lib/i18n.ts - 33 + 34 @@ -3034,7 +3011,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -3046,7 +3023,7 @@ libs/ui/src/lib/i18n.ts - 71 + 72 @@ -3114,7 +3091,7 @@ Excluido del análisis apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 243 + 249 @@ -3170,7 +3147,7 @@ Evolución cartera apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 268 + 264 @@ -3202,7 +3179,7 @@ Símbolo libs/ui/src/lib/i18n.ts - 24 + 25 @@ -3210,7 +3187,7 @@ Etiqueta libs/ui/src/lib/i18n.ts - 25 + 26 @@ -3218,7 +3195,7 @@ Efectivo libs/ui/src/lib/i18n.ts - 39 + 40 @@ -3226,7 +3203,7 @@ Bien libs/ui/src/lib/i18n.ts - 40 + 41 @@ -3234,7 +3211,7 @@ Capital libs/ui/src/lib/i18n.ts - 41 + 42 @@ -3242,7 +3219,7 @@ Renta fija libs/ui/src/lib/i18n.ts - 42 + 43 @@ -3250,7 +3227,7 @@ Propiedad inmobiliaria libs/ui/src/lib/i18n.ts - 44 + 45 @@ -3258,7 +3235,7 @@ Bono libs/ui/src/lib/i18n.ts - 47 + 48 @@ -3266,7 +3243,7 @@ Criptomoneda libs/ui/src/lib/i18n.ts - 48 + 49 @@ -3274,7 +3251,7 @@ ETF libs/ui/src/lib/i18n.ts - 49 + 50 @@ -3282,7 +3259,7 @@ Fondo de inversión libs/ui/src/lib/i18n.ts - 50 + 51 @@ -3290,7 +3267,7 @@ Metal precioso libs/ui/src/lib/i18n.ts - 51 + 52 @@ -3298,7 +3275,7 @@ Capital riesgo libs/ui/src/lib/i18n.ts - 52 + 53 @@ -3306,7 +3283,7 @@ Acción libs/ui/src/lib/i18n.ts - 53 + 54 @@ -3314,7 +3291,7 @@ Fondo de emergencia libs/ui/src/lib/i18n.ts - 12 + 13 @@ -3322,7 +3299,7 @@ Otros libs/ui/src/lib/i18n.ts - 20 + 21 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts @@ -3346,7 +3323,7 @@ América del Norte libs/ui/src/lib/i18n.ts - 63 + 64 @@ -3354,7 +3331,7 @@ África libs/ui/src/lib/i18n.ts - 60 + 61 @@ -3362,7 +3339,7 @@ Asia libs/ui/src/lib/i18n.ts - 61 + 62 @@ -3370,7 +3347,7 @@ Europa libs/ui/src/lib/i18n.ts - 62 + 63 @@ -3378,7 +3355,7 @@ Oceanía libs/ui/src/lib/i18n.ts - 64 + 65 @@ -3386,7 +3363,7 @@ América del Sur libs/ui/src/lib/i18n.ts - 65 + 66 @@ -3486,7 +3463,7 @@ libs/ui/src/lib/i18n.ts - 31 + 32 @@ -3494,7 +3471,7 @@ Dividend Timeline apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 356 + 352 @@ -3566,11 +3543,11 @@ Summary apps/client/src/app/pages/home/home-page-routing.module.ts - 28 + 33 apps/client/src/app/pages/home/home-page.component.ts - 44 + 71 @@ -3618,7 +3595,7 @@ Core libs/ui/src/lib/i18n.ts - 8 + 9 @@ -3626,7 +3603,7 @@ Grant libs/ui/src/lib/i18n.ts - 13 + 14 @@ -3634,7 +3611,7 @@ Higher Risk libs/ui/src/lib/i18n.ts - 14 + 15 @@ -3642,7 +3619,7 @@ Lower Risk libs/ui/src/lib/i18n.ts - 17 + 18 @@ -3650,7 +3627,7 @@ Retirement Provision libs/ui/src/lib/i18n.ts - 22 + 23 @@ -3658,7 +3635,7 @@ Satellite libs/ui/src/lib/i18n.ts - 23 + 24 @@ -3918,10 +3895,10 @@ Fees apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 100 + 108 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 199 @@ -3978,7 +3955,7 @@ Switch to Ghostfolio Premium easily libs/ui/src/lib/i18n.ts - 10 + 11 @@ -4002,7 +3979,7 @@ Switch to Ghostfolio Premium or Ghostfolio Open Source easily libs/ui/src/lib/i18n.ts - 9 + 10 @@ -4010,7 +3987,7 @@ Switch to Ghostfolio Open Source or Ghostfolio Basic easily libs/ui/src/lib/i18n.ts - 11 + 12 @@ -4250,7 +4227,7 @@ This activity already exists. libs/ui/src/lib/i18n.ts - 15 + 16 @@ -4342,7 +4319,7 @@ Current Streak apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 319 + 315 @@ -4350,7 +4327,7 @@ Longest Streak apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 328 + 324 @@ -4358,7 +4335,7 @@ Months libs/ui/src/lib/i18n.ts - 19 + 20 @@ -4366,7 +4343,7 @@ Years libs/ui/src/lib/i18n.ts - 27 + 28 @@ -4374,7 +4351,7 @@ Month libs/ui/src/lib/i18n.ts - 18 + 19 @@ -4382,7 +4359,7 @@ Year libs/ui/src/lib/i18n.ts - 26 + 27 @@ -4390,7 +4367,7 @@ Liabilities apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 258 + 264 apps/client/src/app/pages/features/features-page.html @@ -4530,7 +4507,7 @@ Liability libs/ui/src/lib/i18n.ts - 35 + 36 @@ -9866,7 +9843,7 @@ Buy libs/ui/src/lib/i18n.ts - 30 + 31 @@ -9874,7 +9851,7 @@ Valuable libs/ui/src/lib/i18n.ts - 34 + 35 @@ -9898,7 +9875,7 @@ Assets apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 218 + 224 @@ -9906,7 +9883,7 @@ Preset libs/ui/src/lib/i18n.ts - 21 + 22 @@ -9930,7 +9907,7 @@ Japan libs/ui/src/lib/i18n.ts - 16 + 17 @@ -13242,7 +13219,7 @@ Fee libs/ui/src/lib/i18n.ts - 32 + 33 @@ -13250,7 +13227,7 @@ Interest apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 312 + 318 @@ -13758,7 +13735,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 68 + 69 @@ -13766,7 +13743,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 69 + 70 @@ -13774,7 +13751,7 @@ Neutral libs/ui/src/lib/i18n.ts - 72 + 73 @@ -14730,7 +14707,7 @@ Market data is delayed for apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts - 82 + 81 @@ -14981,7 +14958,7 @@ Active Active - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 30 @@ -14989,7 +14966,7 @@ Closed Closed - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 31 @@ -14997,7 +14974,7 @@ Activity Activity - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 219 @@ -15005,7 +14982,7 @@ Dividend Yield Dividend Yield - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 187 @@ -15038,14 +15015,14 @@ Liquidity libs/ui/src/lib/i18n.ts - 43 + 44 Change with currency effect Change with currency effect - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 52 @@ -15053,10 +15030,26 @@ Performance with currency effect Performance with currency effect - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 79 + + {VAR_PLURAL, plural, =1 {activity} other {activities}} + {VAR_PLURAL, plural, =1 {activity} other {activities}} + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 14 + + + + Buy and sell + Buy and sell + + libs/ui/src/lib/i18n.ts + 8 + + diff --git a/apps/client/src/locales/messages.fr.xlf b/apps/client/src/locales/messages.fr.xlf index 9042459f8..198523c74 100644 --- a/apps/client/src/locales/messages.fr.xlf +++ b/apps/client/src/locales/messages.fr.xlf @@ -117,11 +117,11 @@ 134 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 221 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 331 @@ -385,7 +385,7 @@ 34 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 301 @@ -521,7 +521,7 @@ 26 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 112 @@ -629,7 +629,7 @@ 232 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 228 @@ -653,7 +653,7 @@ 245 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 237 @@ -673,7 +673,7 @@ 130 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 209 @@ -761,7 +761,7 @@ 174 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 254 @@ -777,7 +777,7 @@ 77 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 264 @@ -793,7 +793,7 @@ 316 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 270 @@ -813,7 +813,7 @@ 327 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 282 @@ -929,7 +929,7 @@ 10 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 376 @@ -1053,7 +1053,7 @@ 257 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 356 @@ -1089,12 +1089,12 @@ 6 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 89 libs/ui/src/lib/holdings-table/holdings-table.component.html - 119 + 142 @@ -1114,7 +1114,7 @@ apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts - 48 + 41 @@ -1534,10 +1534,6 @@ Gérer les Activités apps/client/src/app/components/home-holdings/home-holdings.html - 22 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page.html 32 @@ -1550,7 +1546,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -1562,7 +1558,7 @@ libs/ui/src/lib/i18n.ts - 71 + 72 @@ -1694,7 +1690,7 @@ Achat apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 21 + 31 @@ -1702,7 +1698,7 @@ Vente apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 33 + 43 @@ -1710,10 +1706,10 @@ Investissement apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 48 + 58 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 165 @@ -1722,7 +1718,7 @@ Performance Absolue Brute apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 60 + 70 @@ -1730,26 +1726,7 @@ Performance Brute apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 77 - - - - - - - - Frais pour - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 12 - - - - {VAR_PLURAL, plural, =1 {transaction} other {transactions}} - {VAR_PLURAL, plural, =1 {transaction} autres {transactions}} - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 14 + 85 @@ -1757,7 +1734,7 @@ Performance Absolue Nette apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 116 + 124 @@ -1765,7 +1742,7 @@ Performance nette apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 133 + 139 @@ -1773,7 +1750,7 @@ Actifs Totaux apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 159 + 165 @@ -1781,7 +1758,7 @@ Biens apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 172 + 178 @@ -1789,7 +1766,7 @@ Fonds d'Urgence apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 184 + 190 apps/client/src/app/pages/features/features-page.html @@ -1805,7 +1782,7 @@ Pouvoir d'Achat apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 231 + 237 @@ -1813,7 +1790,7 @@ Exclus de l'Analyse apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 243 + 249 @@ -1821,7 +1798,7 @@ Fortune apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 278 + 284 @@ -1829,7 +1806,7 @@ Performance annualisée apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 290 + 296 @@ -1837,10 +1814,10 @@ Dividende apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 324 + 330 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 177 @@ -1861,22 +1838,26 @@ Veuillez entrer le montant de votre fonds d'urgence : apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts - 53 + 57 Change Différence - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 63 + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 119 + Average Unit Price Prix Unitaire Moyen - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 101 @@ -1884,7 +1865,7 @@ Minimum Price Prix Minimum - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 128 @@ -1892,7 +1873,7 @@ Maximum Price Prix Maximum - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 144 @@ -1900,7 +1881,7 @@ Quantity Quantité - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 154 @@ -1916,7 +1897,7 @@ Report Data Glitch Signaler une Erreur de Données - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 394 @@ -2405,7 +2386,7 @@ Cash apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 205 + 211 @@ -2580,16 +2561,12 @@ 23 - apps/client/src/app/pages/home/home-page.component.ts - 39 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page-routing.module.ts - 13 + apps/client/src/app/pages/home/home-page-routing.module.ts + 28 - apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 39 + apps/client/src/app/pages/home/home-page.component.ts + 66 apps/client/src/app/pages/zen/zen-page.component.ts @@ -2601,11 +2578,11 @@ Résumé apps/client/src/app/pages/home/home-page-routing.module.ts - 28 + 33 apps/client/src/app/pages/home/home-page.component.ts - 44 + 71 @@ -2613,11 +2590,11 @@ Marchés apps/client/src/app/pages/home/home-page-routing.module.ts - 33 + 38 apps/client/src/app/pages/home/home-page.component.ts - 49 + 76 apps/client/src/app/pages/markets/markets-page-routing.module.ts @@ -2633,7 +2610,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 44 + 39 @@ -2661,7 +2638,7 @@ Vente libs/ui/src/lib/i18n.ts - 36 + 37 @@ -2777,7 +2754,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 49 + 44 @@ -2921,7 +2898,7 @@ libs/ui/src/lib/i18n.ts - 31 + 32 @@ -2961,7 +2938,7 @@ Bas apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 216 + 214 @@ -2969,7 +2946,7 @@ Évolution du Portefeuille apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 268 + 264 @@ -2977,7 +2954,7 @@ Historique des Investissements apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 298 + 294 @@ -2985,7 +2962,7 @@ Historique des Dividendes apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 356 + 352 @@ -3028,7 +3005,7 @@ 77 - apps/client/src/app/pages/portfolio/holdings/holdings-page.html + apps/client/src/app/components/home-holdings/home-holdings.html 4 @@ -3197,7 +3174,7 @@ apps/client/src/app/pages/home/home-page.component.ts - 34 + 61 apps/client/src/app/pages/zen/zen-page-routing.module.ts @@ -3321,7 +3298,7 @@ libs/ui/src/lib/i18n.ts - 33 + 34 @@ -3345,7 +3322,7 @@ Montrer tout libs/ui/src/lib/holdings-table/holdings-table.component.html - 174 + 197 @@ -3377,7 +3354,7 @@ Fonds d'Urgence libs/ui/src/lib/i18n.ts - 12 + 13 @@ -3385,7 +3362,7 @@ Autre libs/ui/src/lib/i18n.ts - 20 + 21 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts @@ -3397,7 +3374,7 @@ Symbole libs/ui/src/lib/i18n.ts - 24 + 25 @@ -3405,7 +3382,7 @@ Étiquette libs/ui/src/lib/i18n.ts - 25 + 26 @@ -3413,7 +3390,7 @@ Cash libs/ui/src/lib/i18n.ts - 39 + 40 @@ -3421,7 +3398,7 @@ Marchandise libs/ui/src/lib/i18n.ts - 40 + 41 @@ -3429,7 +3406,7 @@ Capital libs/ui/src/lib/i18n.ts - 41 + 42 @@ -3437,7 +3414,7 @@ Revenu Fixe libs/ui/src/lib/i18n.ts - 42 + 43 @@ -3445,7 +3422,7 @@ Immobilier libs/ui/src/lib/i18n.ts - 44 + 45 @@ -3453,7 +3430,7 @@ Obligation libs/ui/src/lib/i18n.ts - 47 + 48 @@ -3461,7 +3438,7 @@ Cryptomonnaie libs/ui/src/lib/i18n.ts - 48 + 49 @@ -3469,7 +3446,7 @@ ETF libs/ui/src/lib/i18n.ts - 49 + 50 @@ -3477,7 +3454,7 @@ SICAV libs/ui/src/lib/i18n.ts - 50 + 51 @@ -3485,7 +3462,7 @@ Métal Précieux libs/ui/src/lib/i18n.ts - 51 + 52 @@ -3493,7 +3470,7 @@ Capital Propre libs/ui/src/lib/i18n.ts - 52 + 53 @@ -3501,7 +3478,7 @@ Action libs/ui/src/lib/i18n.ts - 53 + 54 @@ -3509,7 +3486,7 @@ Afrique libs/ui/src/lib/i18n.ts - 60 + 61 @@ -3517,7 +3494,7 @@ Asie libs/ui/src/lib/i18n.ts - 61 + 62 @@ -3525,7 +3502,7 @@ Europe libs/ui/src/lib/i18n.ts - 62 + 63 @@ -3533,7 +3510,7 @@ Amérique du Nord libs/ui/src/lib/i18n.ts - 63 + 64 @@ -3541,7 +3518,7 @@ Océanie libs/ui/src/lib/i18n.ts - 64 + 65 @@ -3549,7 +3526,7 @@ Amérique du Sud libs/ui/src/lib/i18n.ts - 65 + 66 @@ -3617,7 +3594,7 @@ Core libs/ui/src/lib/i18n.ts - 8 + 9 @@ -3625,7 +3602,7 @@ Donner libs/ui/src/lib/i18n.ts - 13 + 14 @@ -3633,7 +3610,7 @@ Risque élevé libs/ui/src/lib/i18n.ts - 14 + 15 @@ -3641,7 +3618,7 @@ Risque faible libs/ui/src/lib/i18n.ts - 17 + 18 @@ -3649,7 +3626,7 @@ Réserve pour retraite libs/ui/src/lib/i18n.ts - 22 + 23 @@ -3657,7 +3634,7 @@ Satellite libs/ui/src/lib/i18n.ts - 23 + 24 @@ -3917,10 +3894,10 @@ Frais apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 100 + 108 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 199 @@ -3977,7 +3954,7 @@ Passez à Ghostfolio Premium facilement libs/ui/src/lib/i18n.ts - 10 + 11 @@ -4001,7 +3978,7 @@ Passez à Ghostfolio Premium ou Ghostfolio Open Source facilement libs/ui/src/lib/i18n.ts - 9 + 10 @@ -4009,7 +3986,7 @@ Passez à Ghostfolio Open Source ou Ghostfolio Basic facilement libs/ui/src/lib/i18n.ts - 11 + 12 @@ -4249,7 +4226,7 @@ Cette activité existe déjà. libs/ui/src/lib/i18n.ts - 15 + 16 @@ -4341,7 +4318,7 @@ Série en cours apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 319 + 315 @@ -4349,7 +4326,7 @@ Série la plus longue apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 328 + 324 @@ -4357,7 +4334,7 @@ Mois libs/ui/src/lib/i18n.ts - 19 + 20 @@ -4365,7 +4342,7 @@ Années libs/ui/src/lib/i18n.ts - 27 + 28 @@ -4373,7 +4350,7 @@ Mois libs/ui/src/lib/i18n.ts - 18 + 19 @@ -4381,7 +4358,7 @@ Année libs/ui/src/lib/i18n.ts - 26 + 27 @@ -4389,7 +4366,7 @@ Dettes apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 258 + 264 apps/client/src/app/pages/features/features-page.html @@ -4529,7 +4506,7 @@ Dette libs/ui/src/lib/i18n.ts - 35 + 36 @@ -9865,7 +9842,7 @@ Buy libs/ui/src/lib/i18n.ts - 30 + 31 @@ -9873,7 +9850,7 @@ Valuable libs/ui/src/lib/i18n.ts - 34 + 35 @@ -9897,7 +9874,7 @@ Assets apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 218 + 224 @@ -9905,7 +9882,7 @@ Preset libs/ui/src/lib/i18n.ts - 21 + 22 @@ -9929,7 +9906,7 @@ Japan libs/ui/src/lib/i18n.ts - 16 + 17 @@ -13241,7 +13218,7 @@ Fee libs/ui/src/lib/i18n.ts - 32 + 33 @@ -13249,7 +13226,7 @@ Interest apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 312 + 318 @@ -13757,7 +13734,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 68 + 69 @@ -13765,7 +13742,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 69 + 70 @@ -13773,7 +13750,7 @@ Neutral libs/ui/src/lib/i18n.ts - 72 + 73 @@ -14729,7 +14706,7 @@ Market data is delayed for apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts - 82 + 81 @@ -14980,7 +14957,7 @@ Active Active - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 30 @@ -14988,7 +14965,7 @@ Closed Closed - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 31 @@ -14996,7 +14973,7 @@ Activity Activity - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 219 @@ -15004,7 +14981,7 @@ Dividend Yield Dividend Yield - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 187 @@ -15037,14 +15014,14 @@ Liquidity libs/ui/src/lib/i18n.ts - 43 + 44 Change with currency effect Change with currency effect - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 52 @@ -15052,10 +15029,26 @@ Performance with currency effect Performance with currency effect - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 79 + + {VAR_PLURAL, plural, =1 {activity} other {activities}} + {VAR_PLURAL, plural, =1 {activity} other {activities}} + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 14 + + + + Buy and sell + Buy and sell + + libs/ui/src/lib/i18n.ts + 8 + + diff --git a/apps/client/src/locales/messages.it.xlf b/apps/client/src/locales/messages.it.xlf index 6e141e532..2589c8146 100644 --- a/apps/client/src/locales/messages.it.xlf +++ b/apps/client/src/locales/messages.it.xlf @@ -106,11 +106,11 @@ 134 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 221 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 331 @@ -338,7 +338,7 @@ 34 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 301 @@ -466,7 +466,7 @@ 26 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 112 @@ -562,7 +562,7 @@ 130 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 209 @@ -842,7 +842,7 @@ 257 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 356 @@ -1223,10 +1223,6 @@ Gestione delle attività apps/client/src/app/components/home-holdings/home-holdings.html - 22 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page.html 32 @@ -1331,7 +1327,7 @@ Compra apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 21 + 31 @@ -1339,7 +1335,7 @@ Vendi apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 33 + 43 @@ -1347,10 +1343,10 @@ Investimento apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 48 + 58 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 165 @@ -1359,7 +1355,7 @@ Prestazioni lorde assolute apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 60 + 70 @@ -1367,26 +1363,7 @@ Prestazioni lorde apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 77 - - - - - - - - Commissioni per - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 12 - - - - {VAR_PLURAL, plural, =1 {transaction} other {transactions}} - {VAR_PLURAL, plural, =1 {transazione} other {transazioni}} - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 14 + 85 @@ -1394,7 +1371,7 @@ Prestazioni nette assolute apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 116 + 124 @@ -1402,7 +1379,7 @@ Prestazioni nette apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 133 + 139 @@ -1410,7 +1387,7 @@ Asset totali apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 159 + 165 @@ -1418,7 +1395,7 @@ Oggetti di valore apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 172 + 178 @@ -1426,7 +1403,7 @@ Fondo di emergenza apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 184 + 190 apps/client/src/app/pages/features/features-page.html @@ -1442,7 +1419,7 @@ Potere d'acquisto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 231 + 237 @@ -1450,7 +1427,7 @@ Patrimonio netto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 278 + 284 @@ -1458,7 +1435,7 @@ Prestazioni annualizzate apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 290 + 296 @@ -1466,10 +1443,10 @@ Dividendo apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 324 + 330 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 177 @@ -1490,7 +1467,7 @@ Inserisci l'importo del tuo fondo di emergenza: apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts - 53 + 57 @@ -1505,7 +1482,7 @@ 316 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 270 @@ -1525,7 +1502,7 @@ 327 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 282 @@ -1537,7 +1514,7 @@ 10 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 376 @@ -1553,7 +1530,7 @@ Report Data Glitch Segnala un'anomalia dei dati - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 394 @@ -1573,12 +1550,12 @@ 6 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 89 libs/ui/src/lib/holdings-table/holdings-table.component.html - 119 + 142 @@ -1586,7 +1563,7 @@ Mostra tutti libs/ui/src/lib/holdings-table/holdings-table.component.html - 174 + 197 @@ -2050,7 +2027,7 @@ Contanti apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 205 + 211 @@ -2174,7 +2151,7 @@ apps/client/src/app/pages/home/home-page.component.ts - 34 + 61 apps/client/src/app/pages/zen/zen-page-routing.module.ts @@ -2190,11 +2167,11 @@ Mercati apps/client/src/app/pages/home/home-page-routing.module.ts - 33 + 38 apps/client/src/app/pages/home/home-page.component.ts - 49 + 76 apps/client/src/app/pages/markets/markets-page-routing.module.ts @@ -2210,7 +2187,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 49 + 44 @@ -2314,7 +2291,7 @@ Cronologia degli investimenti apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 298 + 294 @@ -2330,7 +2307,7 @@ In basso apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 216 + 214 @@ -2373,16 +2350,12 @@ 23 - apps/client/src/app/pages/home/home-page.component.ts - 39 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page-routing.module.ts - 13 + apps/client/src/app/pages/home/home-page-routing.module.ts + 28 - apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 39 + apps/client/src/app/pages/home/home-page.component.ts + 66 apps/client/src/app/pages/zen/zen-page.component.ts @@ -2397,7 +2370,7 @@ 77 - apps/client/src/app/pages/portfolio/holdings/holdings-page.html + apps/client/src/app/components/home-holdings/home-holdings.html 4 @@ -2434,7 +2407,7 @@ Vendi libs/ui/src/lib/i18n.ts - 36 + 37 @@ -2453,7 +2426,7 @@ Quantity Quantità - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 154 @@ -2529,7 +2502,7 @@ 232 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 228 @@ -2546,7 +2519,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 44 + 39 @@ -2582,7 +2555,7 @@ apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts - 48 + 41 @@ -2849,9 +2822,13 @@ Change Modifica - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 63 + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 119 + Developed Markets @@ -2881,7 +2858,7 @@ 245 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 237 @@ -2893,7 +2870,7 @@ Average Unit Price Prezzo unitario medio - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 101 @@ -2901,7 +2878,7 @@ Maximum Price Prezzo massimo - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 144 @@ -2937,7 +2914,7 @@ 174 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 254 @@ -2953,7 +2930,7 @@ 77 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 264 @@ -2961,7 +2938,7 @@ Minimum Price Prezzo minimo - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 128 @@ -2990,7 +2967,7 @@ libs/ui/src/lib/i18n.ts - 33 + 34 @@ -3034,7 +3011,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -3046,7 +3023,7 @@ libs/ui/src/lib/i18n.ts - 71 + 72 @@ -3114,7 +3091,7 @@ Escluso dall'analisi apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 243 + 249 @@ -3170,7 +3147,7 @@ Evoluzione del portafoglio apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 268 + 264 @@ -3202,7 +3179,7 @@ Simbolo libs/ui/src/lib/i18n.ts - 24 + 25 @@ -3210,7 +3187,7 @@ Etichetta libs/ui/src/lib/i18n.ts - 25 + 26 @@ -3218,7 +3195,7 @@ Contanti libs/ui/src/lib/i18n.ts - 39 + 40 @@ -3226,7 +3203,7 @@ Materia prima libs/ui/src/lib/i18n.ts - 40 + 41 @@ -3234,7 +3211,7 @@ Azione ordinaria libs/ui/src/lib/i18n.ts - 41 + 42 @@ -3242,7 +3219,7 @@ Reddito fisso libs/ui/src/lib/i18n.ts - 42 + 43 @@ -3250,7 +3227,7 @@ Immobiliare libs/ui/src/lib/i18n.ts - 44 + 45 @@ -3258,7 +3235,7 @@ Obbligazioni libs/ui/src/lib/i18n.ts - 47 + 48 @@ -3266,7 +3243,7 @@ Criptovaluta libs/ui/src/lib/i18n.ts - 48 + 49 @@ -3274,7 +3251,7 @@ ETF libs/ui/src/lib/i18n.ts - 49 + 50 @@ -3282,7 +3259,7 @@ Fondo comune di investimento libs/ui/src/lib/i18n.ts - 50 + 51 @@ -3290,7 +3267,7 @@ Metalli preziosi libs/ui/src/lib/i18n.ts - 51 + 52 @@ -3298,7 +3275,7 @@ Azione ordinaria privata libs/ui/src/lib/i18n.ts - 52 + 53 @@ -3306,7 +3283,7 @@ Azione libs/ui/src/lib/i18n.ts - 53 + 54 @@ -3314,7 +3291,7 @@ Fondo di emergenza libs/ui/src/lib/i18n.ts - 12 + 13 @@ -3322,7 +3299,7 @@ Altro libs/ui/src/lib/i18n.ts - 20 + 21 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts @@ -3346,7 +3323,7 @@ Nord America libs/ui/src/lib/i18n.ts - 63 + 64 @@ -3354,7 +3331,7 @@ Africa libs/ui/src/lib/i18n.ts - 60 + 61 @@ -3362,7 +3339,7 @@ Asia libs/ui/src/lib/i18n.ts - 61 + 62 @@ -3370,7 +3347,7 @@ Europa libs/ui/src/lib/i18n.ts - 62 + 63 @@ -3378,7 +3355,7 @@ Oceania libs/ui/src/lib/i18n.ts - 64 + 65 @@ -3386,7 +3363,7 @@ Sud America libs/ui/src/lib/i18n.ts - 65 + 66 @@ -3486,7 +3463,7 @@ libs/ui/src/lib/i18n.ts - 31 + 32 @@ -3494,7 +3471,7 @@ Cronologia dei dividendi apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 356 + 352 @@ -3566,11 +3543,11 @@ Summario apps/client/src/app/pages/home/home-page-routing.module.ts - 28 + 33 apps/client/src/app/pages/home/home-page.component.ts - 44 + 71 @@ -3618,7 +3595,7 @@ Nucleo libs/ui/src/lib/i18n.ts - 8 + 9 @@ -3626,7 +3603,7 @@ Sovvenzione libs/ui/src/lib/i18n.ts - 13 + 14 @@ -3634,7 +3611,7 @@ Rischio più elevato libs/ui/src/lib/i18n.ts - 14 + 15 @@ -3642,7 +3619,7 @@ Rischio inferiore libs/ui/src/lib/i18n.ts - 17 + 18 @@ -3650,7 +3627,7 @@ Fondo pensione libs/ui/src/lib/i18n.ts - 22 + 23 @@ -3658,7 +3635,7 @@ Satellite libs/ui/src/lib/i18n.ts - 23 + 24 @@ -3918,10 +3895,10 @@ Commissioni apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 100 + 108 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 199 @@ -3978,7 +3955,7 @@ Passa facilmente a Ghostfolio Premium libs/ui/src/lib/i18n.ts - 10 + 11 @@ -4002,7 +3979,7 @@ Passa facilmente a Ghostfolio Premium o Ghostfolio Open Source libs/ui/src/lib/i18n.ts - 9 + 10 @@ -4010,7 +3987,7 @@ Passa facilmente a Ghostfolio Open Source o a Ghostfolio Basic libs/ui/src/lib/i18n.ts - 11 + 12 @@ -4250,7 +4227,7 @@ Questa attività esiste già. libs/ui/src/lib/i18n.ts - 15 + 16 @@ -4342,7 +4319,7 @@ Serie attuale apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 319 + 315 @@ -4350,7 +4327,7 @@ Serie più lunga apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 328 + 324 @@ -4358,7 +4335,7 @@ Mesi libs/ui/src/lib/i18n.ts - 19 + 20 @@ -4366,7 +4343,7 @@ Anni libs/ui/src/lib/i18n.ts - 27 + 28 @@ -4374,7 +4351,7 @@ Mese libs/ui/src/lib/i18n.ts - 18 + 19 @@ -4382,7 +4359,7 @@ Anno libs/ui/src/lib/i18n.ts - 26 + 27 @@ -4390,7 +4367,7 @@ Passività apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 258 + 264 apps/client/src/app/pages/features/features-page.html @@ -4530,7 +4507,7 @@ Passività libs/ui/src/lib/i18n.ts - 35 + 36 @@ -9866,7 +9843,7 @@ Compra libs/ui/src/lib/i18n.ts - 30 + 31 @@ -9874,7 +9851,7 @@ Prezioso libs/ui/src/lib/i18n.ts - 34 + 35 @@ -9898,7 +9875,7 @@ Asset apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 218 + 224 @@ -9906,7 +9883,7 @@ Preimpostato libs/ui/src/lib/i18n.ts - 21 + 22 @@ -9930,7 +9907,7 @@ Giappone libs/ui/src/lib/i18n.ts - 16 + 17 @@ -13242,7 +13219,7 @@ Fee libs/ui/src/lib/i18n.ts - 32 + 33 @@ -13250,7 +13227,7 @@ Interest apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 312 + 318 @@ -13758,7 +13735,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 68 + 69 @@ -13766,7 +13743,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 69 + 70 @@ -13774,7 +13751,7 @@ Neutral libs/ui/src/lib/i18n.ts - 72 + 73 @@ -14730,7 +14707,7 @@ Market data is delayed for apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts - 82 + 81 @@ -14981,7 +14958,7 @@ Active Active - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 30 @@ -14989,7 +14966,7 @@ Closed Closed - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 31 @@ -14997,7 +14974,7 @@ Activity Activity - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 219 @@ -15005,7 +14982,7 @@ Dividend Yield Dividend Yield - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 187 @@ -15038,14 +15015,14 @@ Liquidity libs/ui/src/lib/i18n.ts - 43 + 44 Change with currency effect Change with currency effect - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 52 @@ -15053,10 +15030,26 @@ Performance with currency effect Performance with currency effect - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 79 + + {VAR_PLURAL, plural, =1 {activity} other {activities}} + {VAR_PLURAL, plural, =1 {activity} other {activities}} + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 14 + + + + Buy and sell + Buy and sell + + libs/ui/src/lib/i18n.ts + 8 + + diff --git a/apps/client/src/locales/messages.nl.xlf b/apps/client/src/locales/messages.nl.xlf index da29f87e3..620200f74 100644 --- a/apps/client/src/locales/messages.nl.xlf +++ b/apps/client/src/locales/messages.nl.xlf @@ -105,11 +105,11 @@ 134 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 221 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 331 @@ -337,7 +337,7 @@ 34 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 301 @@ -465,7 +465,7 @@ 26 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 112 @@ -561,7 +561,7 @@ 130 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 209 @@ -841,7 +841,7 @@ 257 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 356 @@ -1222,10 +1222,6 @@ Activiteiten beheren apps/client/src/app/components/home-holdings/home-holdings.html - 22 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page.html 32 @@ -1330,7 +1326,7 @@ Kopen apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 21 + 31 @@ -1338,7 +1334,7 @@ Verkopen apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 33 + 43 @@ -1346,10 +1342,10 @@ Belegging apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 48 + 58 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 165 @@ -1358,7 +1354,7 @@ Absoluut bruto rendement apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 60 + 70 @@ -1366,26 +1362,7 @@ Bruto rendement apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 77 - - - - - - - - Transactiekosten voor - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 12 - - - - {VAR_PLURAL, plural, =1 {transaction} other {transactions}} - {VAR_PLURAL, plural, =1 {transaction} other {transactions}} - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 14 + 85 @@ -1393,7 +1370,7 @@ Absoluut netto rendement apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 116 + 124 @@ -1401,7 +1378,7 @@ Netto rendement apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 133 + 139 @@ -1409,7 +1386,7 @@ Totaal Activa apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 159 + 165 @@ -1417,7 +1394,7 @@ Kostbaarheden apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 172 + 178 @@ -1425,7 +1402,7 @@ Noodfonds apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 184 + 190 apps/client/src/app/pages/features/features-page.html @@ -1441,7 +1418,7 @@ Koopkracht apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 231 + 237 @@ -1449,7 +1426,7 @@ Netto waarde apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 278 + 284 @@ -1457,7 +1434,7 @@ Rendement per jaar apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 290 + 296 @@ -1465,10 +1442,10 @@ Dividend apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 324 + 330 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 177 @@ -1489,7 +1466,7 @@ Voer het bedrag van je noodfonds in: apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts - 53 + 57 @@ -1504,7 +1481,7 @@ 316 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 270 @@ -1524,7 +1501,7 @@ 327 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 282 @@ -1536,7 +1513,7 @@ 10 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 376 @@ -1552,7 +1529,7 @@ Report Data Glitch Gegevensstoring melden - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 394 @@ -1572,12 +1549,12 @@ 6 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 89 libs/ui/src/lib/holdings-table/holdings-table.component.html - 119 + 142 @@ -1585,7 +1562,7 @@ Toon alle libs/ui/src/lib/holdings-table/holdings-table.component.html - 174 + 197 @@ -2049,7 +2026,7 @@ Contant geld apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 205 + 211 @@ -2173,7 +2150,7 @@ apps/client/src/app/pages/home/home-page.component.ts - 34 + 61 apps/client/src/app/pages/zen/zen-page-routing.module.ts @@ -2189,11 +2166,11 @@ Markten apps/client/src/app/pages/home/home-page-routing.module.ts - 33 + 38 apps/client/src/app/pages/home/home-page.component.ts - 49 + 76 apps/client/src/app/pages/markets/markets-page-routing.module.ts @@ -2209,7 +2186,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 49 + 44 @@ -2313,7 +2290,7 @@ Tijdlijn investeringen apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 298 + 294 @@ -2329,7 +2306,7 @@ Verliezers apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 216 + 214 @@ -2372,16 +2349,12 @@ 23 - apps/client/src/app/pages/home/home-page.component.ts - 39 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page-routing.module.ts - 13 + apps/client/src/app/pages/home/home-page-routing.module.ts + 28 - apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 39 + apps/client/src/app/pages/home/home-page.component.ts + 66 apps/client/src/app/pages/zen/zen-page.component.ts @@ -2396,7 +2369,7 @@ 77 - apps/client/src/app/pages/portfolio/holdings/holdings-page.html + apps/client/src/app/components/home-holdings/home-holdings.html 4 @@ -2433,7 +2406,7 @@ Verkopen libs/ui/src/lib/i18n.ts - 36 + 37 @@ -2452,7 +2425,7 @@ Quantity Hoeveelheid - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 154 @@ -2528,7 +2501,7 @@ 232 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 228 @@ -2545,7 +2518,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 44 + 39 @@ -2581,7 +2554,7 @@ apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts - 48 + 41 @@ -2848,9 +2821,13 @@ Change Verandering - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 63 + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 119 + Developed Markets @@ -2880,7 +2857,7 @@ 245 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 237 @@ -2892,7 +2869,7 @@ Average Unit Price Gemiddelde prijs per eenheid - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 101 @@ -2900,7 +2877,7 @@ Maximum Price Maximale prijs - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 144 @@ -2936,7 +2913,7 @@ 174 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 254 @@ -2952,7 +2929,7 @@ 77 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 264 @@ -2960,7 +2937,7 @@ Minimum Price Minimale prijs - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 128 @@ -2989,7 +2966,7 @@ libs/ui/src/lib/i18n.ts - 33 + 34 @@ -3033,7 +3010,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -3045,7 +3022,7 @@ libs/ui/src/lib/i18n.ts - 71 + 72 @@ -3113,7 +3090,7 @@ Uitgesloten van analyse apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 243 + 249 @@ -3169,7 +3146,7 @@ Waardeontwikkeling van portefeuille apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 268 + 264 @@ -3201,7 +3178,7 @@ Symbool libs/ui/src/lib/i18n.ts - 24 + 25 @@ -3209,7 +3186,7 @@ Label libs/ui/src/lib/i18n.ts - 25 + 26 @@ -3217,7 +3194,7 @@ Contant geld libs/ui/src/lib/i18n.ts - 39 + 40 @@ -3225,7 +3202,7 @@ Grondstof libs/ui/src/lib/i18n.ts - 40 + 41 @@ -3233,7 +3210,7 @@ Equity libs/ui/src/lib/i18n.ts - 41 + 42 @@ -3241,7 +3218,7 @@ Vast inkomen libs/ui/src/lib/i18n.ts - 42 + 43 @@ -3249,7 +3226,7 @@ Vastgoed libs/ui/src/lib/i18n.ts - 44 + 45 @@ -3257,7 +3234,7 @@ Obligatie libs/ui/src/lib/i18n.ts - 47 + 48 @@ -3265,7 +3242,7 @@ Cryptovaluta libs/ui/src/lib/i18n.ts - 48 + 49 @@ -3273,7 +3250,7 @@ ETF libs/ui/src/lib/i18n.ts - 49 + 50 @@ -3281,7 +3258,7 @@ Beleggingsfonds libs/ui/src/lib/i18n.ts - 50 + 51 @@ -3289,7 +3266,7 @@ Edelmetaal libs/ui/src/lib/i18n.ts - 51 + 52 @@ -3297,7 +3274,7 @@ Private equity libs/ui/src/lib/i18n.ts - 52 + 53 @@ -3305,7 +3282,7 @@ Aandeel libs/ui/src/lib/i18n.ts - 53 + 54 @@ -3313,7 +3290,7 @@ Noodfonds libs/ui/src/lib/i18n.ts - 12 + 13 @@ -3321,7 +3298,7 @@ Anders libs/ui/src/lib/i18n.ts - 20 + 21 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts @@ -3345,7 +3322,7 @@ Noord-Amerika libs/ui/src/lib/i18n.ts - 63 + 64 @@ -3353,7 +3330,7 @@ Afrika libs/ui/src/lib/i18n.ts - 60 + 61 @@ -3361,7 +3338,7 @@ Azië libs/ui/src/lib/i18n.ts - 61 + 62 @@ -3369,7 +3346,7 @@ Europa libs/ui/src/lib/i18n.ts - 62 + 63 @@ -3377,7 +3354,7 @@ Oceanië libs/ui/src/lib/i18n.ts - 64 + 65 @@ -3385,7 +3362,7 @@ Zuid-Amerika libs/ui/src/lib/i18n.ts - 65 + 66 @@ -3485,7 +3462,7 @@ libs/ui/src/lib/i18n.ts - 31 + 32 @@ -3493,7 +3470,7 @@ Tijdlijn dividend apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 356 + 352 @@ -3565,11 +3542,11 @@ Samenvatting apps/client/src/app/pages/home/home-page-routing.module.ts - 28 + 33 apps/client/src/app/pages/home/home-page.component.ts - 44 + 71 @@ -3617,7 +3594,7 @@ Kern libs/ui/src/lib/i18n.ts - 8 + 9 @@ -3625,7 +3602,7 @@ Toelage libs/ui/src/lib/i18n.ts - 13 + 14 @@ -3633,7 +3610,7 @@ Hoger risico libs/ui/src/lib/i18n.ts - 14 + 15 @@ -3641,7 +3618,7 @@ Lager risico libs/ui/src/lib/i18n.ts - 17 + 18 @@ -3649,7 +3626,7 @@ Pensioen libs/ui/src/lib/i18n.ts - 22 + 23 @@ -3657,7 +3634,7 @@ Satelliet libs/ui/src/lib/i18n.ts - 23 + 24 @@ -3917,10 +3894,10 @@ Kosten apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 100 + 108 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 199 @@ -3977,7 +3954,7 @@ Eenvoudig overstappen naar Ghostfolio Premium libs/ui/src/lib/i18n.ts - 10 + 11 @@ -4001,7 +3978,7 @@ Eenvoudig overstappen naar Ghostfolio Premium of Ghostfolio Open Source libs/ui/src/lib/i18n.ts - 9 + 10 @@ -4009,7 +3986,7 @@ Eenvoudig overstappen naar Ghostfolio Open Source of Ghostfolio Basic libs/ui/src/lib/i18n.ts - 11 + 12 @@ -4249,7 +4226,7 @@ Deze activiteit bestaat al. libs/ui/src/lib/i18n.ts - 15 + 16 @@ -4341,7 +4318,7 @@ Huidige reeks apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 319 + 315 @@ -4349,7 +4326,7 @@ Langste reeks apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 328 + 324 @@ -4357,7 +4334,7 @@ Maanden libs/ui/src/lib/i18n.ts - 19 + 20 @@ -4365,7 +4342,7 @@ Jaren libs/ui/src/lib/i18n.ts - 27 + 28 @@ -4373,7 +4350,7 @@ Maand libs/ui/src/lib/i18n.ts - 18 + 19 @@ -4381,7 +4358,7 @@ Jaar libs/ui/src/lib/i18n.ts - 26 + 27 @@ -4389,7 +4366,7 @@ Verplichtingen apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 258 + 264 apps/client/src/app/pages/features/features-page.html @@ -4529,7 +4506,7 @@ Verplichtingen libs/ui/src/lib/i18n.ts - 35 + 36 @@ -9865,7 +9842,7 @@ Koop libs/ui/src/lib/i18n.ts - 30 + 31 @@ -9873,7 +9850,7 @@ Waardevol libs/ui/src/lib/i18n.ts - 34 + 35 @@ -9897,7 +9874,7 @@ Assets apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 218 + 224 @@ -9905,7 +9882,7 @@ Voorinstelling libs/ui/src/lib/i18n.ts - 21 + 22 @@ -9929,7 +9906,7 @@ Japan libs/ui/src/lib/i18n.ts - 16 + 17 @@ -13241,7 +13218,7 @@ Fee libs/ui/src/lib/i18n.ts - 32 + 33 @@ -13249,7 +13226,7 @@ Interest apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 312 + 318 @@ -13757,7 +13734,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 68 + 69 @@ -13765,7 +13742,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 69 + 70 @@ -13773,7 +13750,7 @@ Neutral libs/ui/src/lib/i18n.ts - 72 + 73 @@ -14729,7 +14706,7 @@ Market data is delayed for apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts - 82 + 81 @@ -14980,7 +14957,7 @@ Active Active - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 30 @@ -14988,7 +14965,7 @@ Closed Closed - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 31 @@ -14996,7 +14973,7 @@ Activity Activity - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 219 @@ -15004,7 +14981,7 @@ Dividend Yield Dividend Yield - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 187 @@ -15037,14 +15014,14 @@ Liquidity libs/ui/src/lib/i18n.ts - 43 + 44 Change with currency effect Change with currency effect - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 52 @@ -15052,10 +15029,26 @@ Performance with currency effect Performance with currency effect - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 79 + + {VAR_PLURAL, plural, =1 {activity} other {activities}} + {VAR_PLURAL, plural, =1 {activity} other {activities}} + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 14 + + + + Buy and sell + Buy and sell + + libs/ui/src/lib/i18n.ts + 8 + + diff --git a/apps/client/src/locales/messages.pl.xlf b/apps/client/src/locales/messages.pl.xlf index 4dec633e4..4ea586194 100644 --- a/apps/client/src/locales/messages.pl.xlf +++ b/apps/client/src/locales/messages.pl.xlf @@ -1621,11 +1621,11 @@ 134 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 221 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 331 @@ -1917,7 +1917,7 @@ 34 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 301 @@ -2037,7 +2037,7 @@ 26 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 112 @@ -2177,7 +2177,7 @@ 232 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 228 @@ -2201,7 +2201,7 @@ 245 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 237 @@ -2221,7 +2221,7 @@ 130 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 209 @@ -2341,7 +2341,7 @@ 174 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 254 @@ -2357,7 +2357,7 @@ 77 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 264 @@ -2373,7 +2373,7 @@ 316 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 270 @@ -2393,7 +2393,7 @@ 327 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 282 @@ -2681,7 +2681,7 @@ 257 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 356 @@ -2733,7 +2733,7 @@ 10 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 376 @@ -2841,12 +2841,12 @@ 6 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 89 libs/ui/src/lib/holdings-table/holdings-table.component.html - 119 + 142 @@ -2874,7 +2874,7 @@ apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts - 48 + 41 @@ -3010,10 +3010,6 @@ Manage Activities apps/client/src/app/components/home-holdings/home-holdings.html - 22 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page.html 32 @@ -3026,7 +3022,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -3038,7 +3034,7 @@ libs/ui/src/lib/i18n.ts - 71 + 72 @@ -3249,34 +3245,12 @@ 3 - - - - - - - - - - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 12 - - - - {VAR_PLURAL, plural, =1 {transaction} other {transactions}} - {VAR_PLURAL, plural, =1 {transaction} other {transactions}} - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 14 - - Buy Buy apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 21 + 31 @@ -3284,7 +3258,7 @@ Sell apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 33 + 43 @@ -3292,10 +3266,10 @@ Investment apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 48 + 58 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 165 @@ -3304,7 +3278,7 @@ Absolute Gross Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 60 + 70 @@ -3312,7 +3286,7 @@ Gross Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 77 + 85 @@ -3320,10 +3294,10 @@ Fees apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 100 + 108 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 199 @@ -3336,7 +3310,7 @@ Absolute Net Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 116 + 124 @@ -3344,7 +3318,7 @@ Net Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 133 + 139 @@ -3352,7 +3326,7 @@ Total Assets apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 159 + 165 @@ -3360,7 +3334,7 @@ Valuables apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 172 + 178 @@ -3368,7 +3342,7 @@ Emergency Fund apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 184 + 190 apps/client/src/app/pages/features/features-page.html @@ -3384,7 +3358,7 @@ Cash apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 205 + 211 @@ -3392,7 +3366,7 @@ Assets apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 218 + 224 @@ -3400,7 +3374,7 @@ Buying Power apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 231 + 237 @@ -3408,7 +3382,7 @@ Excluded from Analysis apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 243 + 249 @@ -3416,7 +3390,7 @@ Liabilities apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 258 + 264 apps/client/src/app/pages/features/features-page.html @@ -3428,7 +3402,7 @@ Net Worth apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 278 + 284 @@ -3436,7 +3410,7 @@ Annualized Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 290 + 296 @@ -3444,7 +3418,7 @@ Interest apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 312 + 318 @@ -3452,10 +3426,10 @@ Dividend apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 324 + 330 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 177 @@ -3476,22 +3450,26 @@ Please enter the amount of your emergency fund: apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts - 53 + 57 Change Change - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 63 + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 119 + Average Unit Price Average Unit Price - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 101 @@ -3499,7 +3477,7 @@ Minimum Price Minimum Price - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 128 @@ -3507,7 +3485,7 @@ Maximum Price Maximum Price - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 144 @@ -3515,7 +3493,7 @@ Quantity Quantity - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 154 @@ -3531,7 +3509,7 @@ Report Data Glitch Report Data Glitch - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 394 @@ -4252,7 +4230,7 @@ apps/client/src/app/pages/home/home-page.component.ts - 34 + 61 apps/client/src/app/pages/zen/zen-page-routing.module.ts @@ -4455,16 +4433,12 @@ 23 - apps/client/src/app/pages/home/home-page.component.ts - 39 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page-routing.module.ts - 13 + apps/client/src/app/pages/home/home-page-routing.module.ts + 28 - apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 39 + apps/client/src/app/pages/home/home-page.component.ts + 66 apps/client/src/app/pages/zen/zen-page.component.ts @@ -4476,11 +4450,11 @@ Summary apps/client/src/app/pages/home/home-page-routing.module.ts - 28 + 33 apps/client/src/app/pages/home/home-page.component.ts - 44 + 71 @@ -4488,11 +4462,11 @@ Markets apps/client/src/app/pages/home/home-page-routing.module.ts - 33 + 38 apps/client/src/app/pages/home/home-page.component.ts - 49 + 76 apps/client/src/app/pages/markets/markets-page-routing.module.ts @@ -4940,7 +4914,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 44 + 39 @@ -5204,7 +5178,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 49 + 44 @@ -5384,7 +5358,7 @@ libs/ui/src/lib/i18n.ts - 31 + 32 @@ -5432,7 +5406,7 @@ Bottom apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 216 + 214 @@ -5440,7 +5414,7 @@ Portfolio Evolution apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 268 + 264 @@ -5448,7 +5422,7 @@ Investment Timeline apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 298 + 294 @@ -5456,7 +5430,7 @@ Current Streak apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 319 + 315 @@ -5464,7 +5438,7 @@ Longest Streak apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 328 + 324 @@ -5472,7 +5446,7 @@ Dividend Timeline apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 356 + 352 @@ -5539,7 +5513,7 @@ 77 - apps/client/src/app/pages/portfolio/holdings/holdings-page.html + apps/client/src/app/components/home-holdings/home-holdings.html 4 @@ -13328,7 +13302,7 @@ libs/ui/src/lib/i18n.ts - 33 + 34 @@ -13352,7 +13326,7 @@ Show all libs/ui/src/lib/holdings-table/holdings-table.component.html - 174 + 197 @@ -13392,7 +13366,7 @@ Core libs/ui/src/lib/i18n.ts - 8 + 9 @@ -13400,7 +13374,7 @@ Switch to Ghostfolio Premium or Ghostfolio Open Source easily libs/ui/src/lib/i18n.ts - 9 + 10 @@ -13408,7 +13382,7 @@ Switch to Ghostfolio Premium easily libs/ui/src/lib/i18n.ts - 10 + 11 @@ -13416,7 +13390,7 @@ Switch to Ghostfolio Open Source or Ghostfolio Basic easily libs/ui/src/lib/i18n.ts - 11 + 12 @@ -13424,7 +13398,7 @@ Emergency Fund libs/ui/src/lib/i18n.ts - 12 + 13 @@ -13432,7 +13406,7 @@ Grant libs/ui/src/lib/i18n.ts - 13 + 14 @@ -13440,7 +13414,7 @@ Higher Risk libs/ui/src/lib/i18n.ts - 14 + 15 @@ -13448,7 +13422,7 @@ This activity already exists. libs/ui/src/lib/i18n.ts - 15 + 16 @@ -13456,7 +13430,7 @@ Japan libs/ui/src/lib/i18n.ts - 16 + 17 @@ -13464,7 +13438,7 @@ Lower Risk libs/ui/src/lib/i18n.ts - 17 + 18 @@ -13472,7 +13446,7 @@ Month libs/ui/src/lib/i18n.ts - 18 + 19 @@ -13480,7 +13454,7 @@ Months libs/ui/src/lib/i18n.ts - 19 + 20 @@ -13488,7 +13462,7 @@ Other libs/ui/src/lib/i18n.ts - 20 + 21 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts @@ -13500,7 +13474,7 @@ Preset libs/ui/src/lib/i18n.ts - 21 + 22 @@ -13508,7 +13482,7 @@ Retirement Provision libs/ui/src/lib/i18n.ts - 22 + 23 @@ -13516,7 +13490,7 @@ Satellite libs/ui/src/lib/i18n.ts - 23 + 24 @@ -13524,7 +13498,7 @@ Symbol libs/ui/src/lib/i18n.ts - 24 + 25 @@ -13532,7 +13506,7 @@ Tag libs/ui/src/lib/i18n.ts - 25 + 26 @@ -13540,7 +13514,7 @@ Year libs/ui/src/lib/i18n.ts - 26 + 27 @@ -13548,7 +13522,7 @@ Years libs/ui/src/lib/i18n.ts - 27 + 28 @@ -13556,7 +13530,7 @@ Buy libs/ui/src/lib/i18n.ts - 30 + 31 @@ -13564,7 +13538,7 @@ Fee libs/ui/src/lib/i18n.ts - 32 + 33 @@ -13572,7 +13546,7 @@ Valuable libs/ui/src/lib/i18n.ts - 34 + 35 @@ -13580,7 +13554,7 @@ Liability libs/ui/src/lib/i18n.ts - 35 + 36 @@ -13588,7 +13562,7 @@ Sell libs/ui/src/lib/i18n.ts - 36 + 37 @@ -13596,7 +13570,7 @@ Cash libs/ui/src/lib/i18n.ts - 39 + 40 @@ -13604,7 +13578,7 @@ Commodity libs/ui/src/lib/i18n.ts - 40 + 41 @@ -13612,7 +13586,7 @@ Equity libs/ui/src/lib/i18n.ts - 41 + 42 @@ -13620,7 +13594,7 @@ Fixed Income libs/ui/src/lib/i18n.ts - 42 + 43 @@ -13628,7 +13602,7 @@ Real Estate libs/ui/src/lib/i18n.ts - 44 + 45 @@ -13636,7 +13610,7 @@ Bond libs/ui/src/lib/i18n.ts - 47 + 48 @@ -13644,7 +13618,7 @@ Cryptocurrency libs/ui/src/lib/i18n.ts - 48 + 49 @@ -13652,7 +13626,7 @@ ETF libs/ui/src/lib/i18n.ts - 49 + 50 @@ -13660,7 +13634,7 @@ Mutual Fund libs/ui/src/lib/i18n.ts - 50 + 51 @@ -13668,7 +13642,7 @@ Precious Metal libs/ui/src/lib/i18n.ts - 51 + 52 @@ -13676,7 +13650,7 @@ Private Equity libs/ui/src/lib/i18n.ts - 52 + 53 @@ -13684,7 +13658,7 @@ Stock libs/ui/src/lib/i18n.ts - 53 + 54 @@ -13692,7 +13666,7 @@ Africa libs/ui/src/lib/i18n.ts - 60 + 61 @@ -13700,7 +13674,7 @@ Asia libs/ui/src/lib/i18n.ts - 61 + 62 @@ -13708,7 +13682,7 @@ Europe libs/ui/src/lib/i18n.ts - 62 + 63 @@ -13716,7 +13690,7 @@ North America libs/ui/src/lib/i18n.ts - 63 + 64 @@ -13724,7 +13698,7 @@ Oceania libs/ui/src/lib/i18n.ts - 64 + 65 @@ -13732,7 +13706,7 @@ South America libs/ui/src/lib/i18n.ts - 65 + 66 @@ -13740,7 +13714,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 68 + 69 @@ -13748,7 +13722,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 69 + 70 @@ -13756,7 +13730,7 @@ Neutral libs/ui/src/lib/i18n.ts - 72 + 73 @@ -14732,7 +14706,7 @@ Market data is delayed for apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts - 82 + 81 @@ -14983,7 +14957,7 @@ Active Active - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 30 @@ -14991,7 +14965,7 @@ Closed Closed - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 31 @@ -14999,7 +14973,7 @@ Activity Activity - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 219 @@ -15007,7 +14981,7 @@ Dividend Yield Dividend Yield - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 187 @@ -15040,14 +15014,14 @@ Liquidity libs/ui/src/lib/i18n.ts - 43 + 44 Change with currency effect Change with currency effect - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 52 @@ -15055,10 +15029,26 @@ Performance with currency effect Performance with currency effect - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 79 + + {VAR_PLURAL, plural, =1 {activity} other {activities}} + {VAR_PLURAL, plural, =1 {activity} other {activities}} + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 14 + + + + Buy and sell + Buy and sell + + libs/ui/src/lib/i18n.ts + 8 + + diff --git a/apps/client/src/locales/messages.pt.xlf b/apps/client/src/locales/messages.pt.xlf index a467edaa5..1709130f0 100644 --- a/apps/client/src/locales/messages.pt.xlf +++ b/apps/client/src/locales/messages.pt.xlf @@ -117,11 +117,11 @@ 134 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 221 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 331 @@ -385,7 +385,7 @@ 34 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 301 @@ -521,7 +521,7 @@ 26 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 112 @@ -629,7 +629,7 @@ 232 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 228 @@ -653,7 +653,7 @@ 245 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 237 @@ -673,7 +673,7 @@ 130 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 209 @@ -921,7 +921,7 @@ 257 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 356 @@ -957,12 +957,12 @@ 6 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 89 libs/ui/src/lib/holdings-table/holdings-table.component.html - 119 + 142 @@ -982,7 +982,7 @@ apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts - 48 + 41 @@ -1402,10 +1402,6 @@ Gerir Atividades apps/client/src/app/components/home-holdings/home-holdings.html - 22 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page.html 32 @@ -1418,7 +1414,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -1430,7 +1426,7 @@ libs/ui/src/lib/i18n.ts - 71 + 72 @@ -1570,7 +1566,7 @@ Compra apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 21 + 31 @@ -1578,7 +1574,7 @@ Venda apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 33 + 43 @@ -1586,10 +1582,10 @@ Investimento apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 48 + 58 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 165 @@ -1598,7 +1594,7 @@ Desempenho Bruto Absoluto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 60 + 70 @@ -1606,26 +1602,7 @@ Desempenho Bruto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 77 - - - - - - - - Taxas para - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 12 - - - - {VAR_PLURAL, plural, =1 {transaction} other {transactions}} - {VAR_PLURAL, plural, =1 {transação} other {transações}} - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 14 + 85 @@ -1633,7 +1610,7 @@ Desempenho Líquido Absoluto apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 116 + 124 @@ -1641,7 +1618,7 @@ Desempenho Líquido apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 133 + 139 @@ -1649,7 +1626,7 @@ Ativos Totais apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 159 + 165 @@ -1657,7 +1634,7 @@ Bens de valor apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 172 + 178 @@ -1665,7 +1642,7 @@ Fundo de Emergência apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 184 + 190 apps/client/src/app/pages/features/features-page.html @@ -1681,7 +1658,7 @@ Poder de Compra apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 231 + 237 @@ -1689,7 +1666,7 @@ Excluído da Análise apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 243 + 249 @@ -1697,7 +1674,7 @@ Valor Líquido apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 278 + 284 @@ -1705,7 +1682,7 @@ Desempenho Anual apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 290 + 296 @@ -1713,10 +1690,10 @@ Dividendo apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 324 + 330 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 177 @@ -1737,22 +1714,26 @@ Por favor, insira o valor do seu fundo de emergência: apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts - 53 + 57 Change Alterar - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 63 + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 119 + Average Unit Price Preço Médio por Unidade - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 101 @@ -1760,7 +1741,7 @@ Minimum Price Preço Mínimo - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 128 @@ -1768,7 +1749,7 @@ Maximum Price Preço Máximo - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 144 @@ -1776,7 +1757,7 @@ Quantity Quantidade - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 154 @@ -1796,7 +1777,7 @@ 174 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 254 @@ -1812,7 +1793,7 @@ 77 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 264 @@ -1828,7 +1809,7 @@ 316 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 270 @@ -1848,7 +1829,7 @@ 327 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 282 @@ -1860,7 +1841,7 @@ 10 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 376 @@ -1876,7 +1857,7 @@ Report Data Glitch Dados do Relatório com Problema - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 394 @@ -1893,7 +1874,7 @@ Mostrar tudo libs/ui/src/lib/holdings-table/holdings-table.component.html - 174 + 197 @@ -2349,7 +2330,7 @@ Dinheiro apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 205 + 211 @@ -2501,7 +2482,7 @@ apps/client/src/app/pages/home/home-page.component.ts - 34 + 61 apps/client/src/app/pages/zen/zen-page-routing.module.ts @@ -2517,11 +2498,11 @@ Mercados apps/client/src/app/pages/home/home-page-routing.module.ts - 33 + 38 apps/client/src/app/pages/home/home-page.component.ts - 49 + 76 apps/client/src/app/pages/markets/markets-page-routing.module.ts @@ -2537,7 +2518,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 44 + 39 @@ -2565,7 +2546,7 @@ Venda libs/ui/src/lib/i18n.ts - 36 + 37 @@ -2673,7 +2654,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 49 + 44 @@ -2837,7 +2818,7 @@ Fundo apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 216 + 214 @@ -2845,7 +2826,7 @@ Evolução do Portefólio apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 268 + 264 @@ -2853,7 +2834,7 @@ Cronograma de Investimento apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 298 + 294 @@ -2896,16 +2877,12 @@ 23 - apps/client/src/app/pages/home/home-page.component.ts - 39 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page-routing.module.ts - 13 + apps/client/src/app/pages/home/home-page-routing.module.ts + 28 - apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 39 + apps/client/src/app/pages/home/home-page.component.ts + 66 apps/client/src/app/pages/zen/zen-page.component.ts @@ -2920,7 +2897,7 @@ 77 - apps/client/src/app/pages/portfolio/holdings/holdings-page.html + apps/client/src/app/components/home-holdings/home-holdings.html 4 @@ -3193,7 +3170,7 @@ libs/ui/src/lib/i18n.ts - 33 + 34 @@ -3225,7 +3202,7 @@ Fundo de Emergência libs/ui/src/lib/i18n.ts - 12 + 13 @@ -3233,7 +3210,7 @@ Outro libs/ui/src/lib/i18n.ts - 20 + 21 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts @@ -3245,7 +3222,7 @@ Símbolo libs/ui/src/lib/i18n.ts - 24 + 25 @@ -3253,7 +3230,7 @@ Marcador libs/ui/src/lib/i18n.ts - 25 + 26 @@ -3261,7 +3238,7 @@ Dinheiro libs/ui/src/lib/i18n.ts - 39 + 40 @@ -3269,7 +3246,7 @@ Matéria-prima libs/ui/src/lib/i18n.ts - 40 + 41 @@ -3277,7 +3254,7 @@ Ações libs/ui/src/lib/i18n.ts - 41 + 42 @@ -3285,7 +3262,7 @@ Rendimento Fixo libs/ui/src/lib/i18n.ts - 42 + 43 @@ -3293,7 +3270,7 @@ Imobiliário libs/ui/src/lib/i18n.ts - 44 + 45 @@ -3301,7 +3278,7 @@ Obrigação libs/ui/src/lib/i18n.ts - 47 + 48 @@ -3309,7 +3286,7 @@ Criptomoedas libs/ui/src/lib/i18n.ts - 48 + 49 @@ -3317,7 +3294,7 @@ ETF libs/ui/src/lib/i18n.ts - 49 + 50 @@ -3325,7 +3302,7 @@ Fundo de Investimento libs/ui/src/lib/i18n.ts - 50 + 51 @@ -3333,7 +3310,7 @@ Metal Precioso libs/ui/src/lib/i18n.ts - 51 + 52 @@ -3341,7 +3318,7 @@ Private Equity libs/ui/src/lib/i18n.ts - 52 + 53 @@ -3349,7 +3326,7 @@ Ação libs/ui/src/lib/i18n.ts - 53 + 54 @@ -3357,7 +3334,7 @@ África libs/ui/src/lib/i18n.ts - 60 + 61 @@ -3365,7 +3342,7 @@ Ásia libs/ui/src/lib/i18n.ts - 61 + 62 @@ -3373,7 +3350,7 @@ Europa libs/ui/src/lib/i18n.ts - 62 + 63 @@ -3381,7 +3358,7 @@ América do Norte libs/ui/src/lib/i18n.ts - 63 + 64 @@ -3389,7 +3366,7 @@ Oceânia libs/ui/src/lib/i18n.ts - 64 + 65 @@ -3397,7 +3374,7 @@ América do Sul libs/ui/src/lib/i18n.ts - 65 + 66 @@ -3513,11 +3490,11 @@ Sumário apps/client/src/app/pages/home/home-page-routing.module.ts - 28 + 33 apps/client/src/app/pages/home/home-page.component.ts - 44 + 71 @@ -3553,7 +3530,7 @@ libs/ui/src/lib/i18n.ts - 31 + 32 @@ -3561,7 +3538,7 @@ Cronograma de Dividendos apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 356 + 352 @@ -3617,7 +3594,7 @@ Núcleo libs/ui/src/lib/i18n.ts - 8 + 9 @@ -3625,7 +3602,7 @@ Conceder libs/ui/src/lib/i18n.ts - 13 + 14 @@ -3633,7 +3610,7 @@ Risco mais Elevado libs/ui/src/lib/i18n.ts - 14 + 15 @@ -3641,7 +3618,7 @@ Risco menos Elevado libs/ui/src/lib/i18n.ts - 17 + 18 @@ -3649,7 +3626,7 @@ Provisão de Reforma libs/ui/src/lib/i18n.ts - 22 + 23 @@ -3657,7 +3634,7 @@ Satélite libs/ui/src/lib/i18n.ts - 23 + 24 @@ -3917,10 +3894,10 @@ Taxas apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 100 + 108 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 199 @@ -3977,7 +3954,7 @@ Mude para o Ghostfolio Premium facilmente libs/ui/src/lib/i18n.ts - 10 + 11 @@ -4001,7 +3978,7 @@ Mude para o Ghostfolio Premium ou Ghostfolio Open Source facilmente libs/ui/src/lib/i18n.ts - 9 + 10 @@ -4009,7 +3986,7 @@ Mude para o Ghostfolio Open Source ou Ghostfolio Basic facilmente libs/ui/src/lib/i18n.ts - 11 + 12 @@ -4249,7 +4226,7 @@ Essa atividade já existe. libs/ui/src/lib/i18n.ts - 15 + 16 @@ -4341,7 +4318,7 @@ Série Atual apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 319 + 315 @@ -4349,7 +4326,7 @@ Série mais Longa apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 328 + 324 @@ -4357,7 +4334,7 @@ Meses libs/ui/src/lib/i18n.ts - 19 + 20 @@ -4365,7 +4342,7 @@ Anos libs/ui/src/lib/i18n.ts - 27 + 28 @@ -4373,7 +4350,7 @@ Mês libs/ui/src/lib/i18n.ts - 18 + 19 @@ -4381,7 +4358,7 @@ Ano libs/ui/src/lib/i18n.ts - 26 + 27 @@ -4389,7 +4366,7 @@ Liabilities apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 258 + 264 apps/client/src/app/pages/features/features-page.html @@ -4529,7 +4506,7 @@ Liability libs/ui/src/lib/i18n.ts - 35 + 36 @@ -9865,7 +9842,7 @@ Buy libs/ui/src/lib/i18n.ts - 30 + 31 @@ -9873,7 +9850,7 @@ Valuable libs/ui/src/lib/i18n.ts - 34 + 35 @@ -9897,7 +9874,7 @@ Assets apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 218 + 224 @@ -9905,7 +9882,7 @@ Preset libs/ui/src/lib/i18n.ts - 21 + 22 @@ -9929,7 +9906,7 @@ Japan libs/ui/src/lib/i18n.ts - 16 + 17 @@ -13241,7 +13218,7 @@ Fee libs/ui/src/lib/i18n.ts - 32 + 33 @@ -13249,7 +13226,7 @@ Interest apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 312 + 318 @@ -13757,7 +13734,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 68 + 69 @@ -13765,7 +13742,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 69 + 70 @@ -13773,7 +13750,7 @@ Neutral libs/ui/src/lib/i18n.ts - 72 + 73 @@ -14729,7 +14706,7 @@ Market data is delayed for apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts - 82 + 81 @@ -14980,7 +14957,7 @@ Active Active - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 30 @@ -14988,7 +14965,7 @@ Closed Closed - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 31 @@ -14996,7 +14973,7 @@ Activity Activity - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 219 @@ -15004,7 +14981,7 @@ Dividend Yield Dividend Yield - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 187 @@ -15037,14 +15014,14 @@ Liquidity libs/ui/src/lib/i18n.ts - 43 + 44 Change with currency effect Change with currency effect - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 52 @@ -15052,10 +15029,26 @@ Performance with currency effect Performance with currency effect - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 79 + + {VAR_PLURAL, plural, =1 {activity} other {activities}} + {VAR_PLURAL, plural, =1 {activity} other {activities}} + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 14 + + + + Buy and sell + Buy and sell + + libs/ui/src/lib/i18n.ts + 8 + + diff --git a/apps/client/src/locales/messages.tr.xlf b/apps/client/src/locales/messages.tr.xlf index 91e97ea12..95fba4c70 100644 --- a/apps/client/src/locales/messages.tr.xlf +++ b/apps/client/src/locales/messages.tr.xlf @@ -1613,11 +1613,11 @@ 134 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 221 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 331 @@ -1865,7 +1865,7 @@ 34 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 301 @@ -2001,7 +2001,7 @@ 26 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 112 @@ -2133,7 +2133,7 @@ 232 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 228 @@ -2157,7 +2157,7 @@ 245 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 237 @@ -2177,7 +2177,7 @@ 130 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 209 @@ -2273,7 +2273,7 @@ 174 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 254 @@ -2289,7 +2289,7 @@ 77 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 264 @@ -2305,7 +2305,7 @@ 316 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 270 @@ -2325,7 +2325,7 @@ 327 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 282 @@ -2469,7 +2469,7 @@ 10 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 376 @@ -2593,7 +2593,7 @@ 257 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 356 @@ -2701,12 +2701,12 @@ 6 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 89 libs/ui/src/lib/holdings-table/holdings-table.component.html - 119 + 142 @@ -2734,7 +2734,7 @@ apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts - 48 + 41 @@ -2862,10 +2862,6 @@ İşlemleri Yönet apps/client/src/app/components/home-holdings/home-holdings.html - 22 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page.html 32 @@ -2878,7 +2874,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -2890,7 +2886,7 @@ libs/ui/src/lib/i18n.ts - 71 + 72 @@ -3106,7 +3102,7 @@ Al apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 21 + 31 @@ -3114,7 +3110,7 @@ Sat apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 33 + 43 @@ -3122,10 +3118,10 @@ Yatırım apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 48 + 58 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 165 @@ -3134,7 +3130,7 @@ Toplam Brüt Performans apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 60 + 70 @@ -3142,26 +3138,7 @@ Brüt Performans apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 77 - - - - - - - - için komisyon tutarı - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 12 - - - - {VAR_PLURAL, plural, =1 {transaction} other {transactions}} - {VAR_PLURAL, plural, =1 {transaction} other {transactions}} - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 14 + 85 @@ -3169,7 +3146,7 @@ Toplam Net Performans apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 116 + 124 @@ -3177,7 +3154,7 @@ Net Performans apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 133 + 139 @@ -3185,7 +3162,7 @@ Toplam Varlıklar apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 159 + 165 @@ -3193,7 +3170,7 @@ Yatırım Varlıkları apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 172 + 178 @@ -3201,7 +3178,7 @@ Acil Durum Yedeği apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 184 + 190 apps/client/src/app/pages/features/features-page.html @@ -3217,7 +3194,7 @@ Nakit apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 205 + 211 @@ -3225,7 +3202,7 @@ Varlıklar apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 218 + 224 @@ -3233,7 +3210,7 @@ Alım Limiti apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 231 + 237 @@ -3241,7 +3218,7 @@ Analize Dahil Edilmemiştir. apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 243 + 249 @@ -3249,7 +3226,7 @@ Yükümlülükler apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 258 + 264 apps/client/src/app/pages/features/features-page.html @@ -3261,7 +3238,7 @@ Toplam Varlık apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 278 + 284 @@ -3269,7 +3246,7 @@ Yıllıklandırılmış Performans apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 290 + 296 @@ -3277,10 +3254,10 @@ Temettü apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 324 + 330 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 177 @@ -3301,22 +3278,26 @@ Lütfen acil durum yedeği meblağını giriniz: apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts - 53 + 57 Change Para Birimi - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 63 + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 119 + Average Unit Price Ortalama Birim Fiyat - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 101 @@ -3324,7 +3305,7 @@ Minimum Price Asgari Fiyat - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 128 @@ -3332,7 +3313,7 @@ Maximum Price Azami Fiyat - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 144 @@ -3340,7 +3321,7 @@ Quantity Miktar - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 154 @@ -3357,10 +3338,10 @@ Komisyon apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 100 + 108 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 199 @@ -3372,7 +3353,7 @@ Report Data Glitch Rapor Veri Sorunu - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 394 @@ -3801,7 +3782,7 @@ apps/client/src/app/pages/home/home-page.component.ts - 34 + 61 apps/client/src/app/pages/zen/zen-page-routing.module.ts @@ -4016,16 +3997,12 @@ 23 - apps/client/src/app/pages/home/home-page.component.ts - 39 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page-routing.module.ts - 13 + apps/client/src/app/pages/home/home-page-routing.module.ts + 28 - apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 39 + apps/client/src/app/pages/home/home-page.component.ts + 66 apps/client/src/app/pages/zen/zen-page.component.ts @@ -4037,11 +4014,11 @@ Özet apps/client/src/app/pages/home/home-page-routing.module.ts - 28 + 33 apps/client/src/app/pages/home/home-page.component.ts - 44 + 71 @@ -4049,11 +4026,11 @@ Piyasalar apps/client/src/app/pages/home/home-page-routing.module.ts - 33 + 38 apps/client/src/app/pages/home/home-page.component.ts - 49 + 76 apps/client/src/app/pages/markets/markets-page-routing.module.ts @@ -4449,7 +4426,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 44 + 39 @@ -4689,7 +4666,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 49 + 44 @@ -4869,7 +4846,7 @@ libs/ui/src/lib/i18n.ts - 31 + 32 @@ -4917,7 +4894,7 @@ Alt apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 216 + 214 @@ -4925,7 +4902,7 @@ Portföyün Gelişimi apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 268 + 264 @@ -4933,7 +4910,7 @@ Yatırım Zaman Çizelgesi apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 298 + 294 @@ -4941,7 +4918,7 @@ Güncel Seri apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 319 + 315 @@ -4949,7 +4926,7 @@ En Uzun Seri apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 328 + 324 @@ -4957,7 +4934,7 @@ Temettü Zaman Çizelgesi apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 356 + 352 @@ -5000,7 +4977,7 @@ 77 - apps/client/src/app/pages/portfolio/holdings/holdings-page.html + apps/client/src/app/components/home-holdings/home-holdings.html 4 @@ -12749,7 +12726,7 @@ libs/ui/src/lib/i18n.ts - 33 + 34 @@ -12773,7 +12750,7 @@ Tümünü göster libs/ui/src/lib/holdings-table/holdings-table.component.html - 174 + 197 @@ -12813,7 +12790,7 @@ Core libs/ui/src/lib/i18n.ts - 8 + 9 @@ -12821,7 +12798,7 @@ Switch to Ghostfolio Premium or Ghostfolio Open Source easily libs/ui/src/lib/i18n.ts - 9 + 10 @@ -12829,7 +12806,7 @@ Switch to Ghostfolio Premium easily libs/ui/src/lib/i18n.ts - 10 + 11 @@ -12837,7 +12814,7 @@ Switch to Ghostfolio Open Source or Ghostfolio Basic easily libs/ui/src/lib/i18n.ts - 11 + 12 @@ -12845,7 +12822,7 @@ Emergency Fund libs/ui/src/lib/i18n.ts - 12 + 13 @@ -12853,7 +12830,7 @@ Grant libs/ui/src/lib/i18n.ts - 13 + 14 @@ -12861,7 +12838,7 @@ Higher Risk libs/ui/src/lib/i18n.ts - 14 + 15 @@ -12869,7 +12846,7 @@ This activity already exists. libs/ui/src/lib/i18n.ts - 15 + 16 @@ -12877,7 +12854,7 @@ Japan libs/ui/src/lib/i18n.ts - 16 + 17 @@ -12885,7 +12862,7 @@ Lower Risk libs/ui/src/lib/i18n.ts - 17 + 18 @@ -12893,7 +12870,7 @@ Month libs/ui/src/lib/i18n.ts - 18 + 19 @@ -12901,7 +12878,7 @@ Months libs/ui/src/lib/i18n.ts - 19 + 20 @@ -12909,7 +12886,7 @@ Other libs/ui/src/lib/i18n.ts - 20 + 21 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts @@ -12921,7 +12898,7 @@ Preset libs/ui/src/lib/i18n.ts - 21 + 22 @@ -12929,7 +12906,7 @@ Retirement Provision libs/ui/src/lib/i18n.ts - 22 + 23 @@ -12937,7 +12914,7 @@ Satellite libs/ui/src/lib/i18n.ts - 23 + 24 @@ -12945,7 +12922,7 @@ Symbol libs/ui/src/lib/i18n.ts - 24 + 25 @@ -12953,7 +12930,7 @@ Tag libs/ui/src/lib/i18n.ts - 25 + 26 @@ -12961,7 +12938,7 @@ Yıl libs/ui/src/lib/i18n.ts - 26 + 27 @@ -12969,7 +12946,7 @@ Years libs/ui/src/lib/i18n.ts - 27 + 28 @@ -12977,7 +12954,7 @@ Buy libs/ui/src/lib/i18n.ts - 30 + 31 @@ -12985,7 +12962,7 @@ Valuable libs/ui/src/lib/i18n.ts - 34 + 35 @@ -12993,7 +12970,7 @@ Liability libs/ui/src/lib/i18n.ts - 35 + 36 @@ -13001,7 +12978,7 @@ Sell libs/ui/src/lib/i18n.ts - 36 + 37 @@ -13009,7 +12986,7 @@ Cash libs/ui/src/lib/i18n.ts - 39 + 40 @@ -13017,7 +12994,7 @@ Commodity libs/ui/src/lib/i18n.ts - 40 + 41 @@ -13025,7 +13002,7 @@ Equity libs/ui/src/lib/i18n.ts - 41 + 42 @@ -13033,7 +13010,7 @@ Fixed Income libs/ui/src/lib/i18n.ts - 42 + 43 @@ -13041,7 +13018,7 @@ Real Estate libs/ui/src/lib/i18n.ts - 44 + 45 @@ -13049,7 +13026,7 @@ Bond libs/ui/src/lib/i18n.ts - 47 + 48 @@ -13057,7 +13034,7 @@ Cryptocurrency libs/ui/src/lib/i18n.ts - 48 + 49 @@ -13065,7 +13042,7 @@ ETF libs/ui/src/lib/i18n.ts - 49 + 50 @@ -13073,7 +13050,7 @@ Mutual Fund libs/ui/src/lib/i18n.ts - 50 + 51 @@ -13081,7 +13058,7 @@ Precious Metal libs/ui/src/lib/i18n.ts - 51 + 52 @@ -13089,7 +13066,7 @@ Private Equity libs/ui/src/lib/i18n.ts - 52 + 53 @@ -13097,7 +13074,7 @@ Stock libs/ui/src/lib/i18n.ts - 53 + 54 @@ -13105,7 +13082,7 @@ Africa libs/ui/src/lib/i18n.ts - 60 + 61 @@ -13113,7 +13090,7 @@ Asia libs/ui/src/lib/i18n.ts - 61 + 62 @@ -13121,7 +13098,7 @@ Europe libs/ui/src/lib/i18n.ts - 62 + 63 @@ -13129,7 +13106,7 @@ North America libs/ui/src/lib/i18n.ts - 63 + 64 @@ -13137,7 +13114,7 @@ Oceania libs/ui/src/lib/i18n.ts - 64 + 65 @@ -13145,7 +13122,7 @@ South America libs/ui/src/lib/i18n.ts - 65 + 66 @@ -13181,7 +13158,7 @@ Interest apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 312 + 318 @@ -13257,7 +13234,7 @@ Fee libs/ui/src/lib/i18n.ts - 32 + 33 @@ -13757,7 +13734,7 @@ Extreme Fear libs/ui/src/lib/i18n.ts - 68 + 69 @@ -13765,7 +13742,7 @@ Extreme Greed libs/ui/src/lib/i18n.ts - 69 + 70 @@ -13773,7 +13750,7 @@ Neutral libs/ui/src/lib/i18n.ts - 72 + 73 @@ -14729,7 +14706,7 @@ Market data is delayed for apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts - 82 + 81 @@ -14980,7 +14957,7 @@ Active Active - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 30 @@ -14988,7 +14965,7 @@ Closed Closed - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 31 @@ -14996,7 +14973,7 @@ Activity Activity - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 219 @@ -15004,7 +14981,7 @@ Dividend Yield Dividend Yield - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 187 @@ -15037,14 +15014,14 @@ Liquidity libs/ui/src/lib/i18n.ts - 43 + 44 Change with currency effect Change with currency effect - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 52 @@ -15052,10 +15029,26 @@ Performance with currency effect Performance with currency effect - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 79 + + {VAR_PLURAL, plural, =1 {activity} other {activities}} + {VAR_PLURAL, plural, =1 {activity} other {activities}} + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 14 + + + + Buy and sell + Buy and sell + + libs/ui/src/lib/i18n.ts + 8 + + diff --git a/apps/client/src/locales/messages.xlf b/apps/client/src/locales/messages.xlf index 2c1e7fa02..b7eaa7131 100644 --- a/apps/client/src/locales/messages.xlf +++ b/apps/client/src/locales/messages.xlf @@ -1589,11 +1589,11 @@ 134 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 221 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 331 @@ -1880,7 +1880,7 @@ 34 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 301 @@ -1988,7 +1988,7 @@ 26 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 112 @@ -2120,7 +2120,7 @@ 232 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 228 @@ -2143,7 +2143,7 @@ 245 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 237 @@ -2162,7 +2162,7 @@ 130 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 209 @@ -2270,7 +2270,7 @@ 174 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 254 @@ -2285,7 +2285,7 @@ 77 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 264 @@ -2300,7 +2300,7 @@ 316 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 270 @@ -2319,7 +2319,7 @@ 327 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 282 @@ -2583,7 +2583,7 @@ 257 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 356 @@ -2630,7 +2630,7 @@ 10 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 376 @@ -2726,12 +2726,12 @@ 6 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 89 libs/ui/src/lib/holdings-table/holdings-table.component.html - 119 + 142 @@ -2756,7 +2756,7 @@ apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts - 48 + 41 @@ -2878,10 +2878,6 @@ Manage Activities apps/client/src/app/components/home-holdings/home-holdings.html - 22 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page.html 32 @@ -2893,7 +2889,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -2904,7 +2900,7 @@ libs/ui/src/lib/i18n.ts - 71 + 72 @@ -3093,45 +3089,28 @@ 3 - - - - - - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 12 - - - - {VAR_PLURAL, plural, =1 {transaction} other {transactions}} - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 14 - - Buy apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 21 + 31 Sell apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 33 + 43 Investment apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 48 + 58 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 165 @@ -3139,24 +3118,24 @@ Absolute Gross Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 60 + 70 Gross Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 77 + 85 Fees apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 100 + 108 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 199 @@ -3168,35 +3147,35 @@ Absolute Net Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 116 + 124 Net Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 133 + 139 Total Assets apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 159 + 165 Valuables apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 172 + 178 Emergency Fund apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 184 + 190 apps/client/src/app/pages/features/features-page.html @@ -3211,35 +3190,35 @@ Cash apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 205 + 211 Assets apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 218 + 224 Buying Power apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 231 + 237 Excluded from Analysis apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 243 + 249 Liabilities apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 258 + 264 apps/client/src/app/pages/features/features-page.html @@ -3250,31 +3229,31 @@ Net Worth apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 278 + 284 Annualized Performance apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 290 + 296 Interest apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 312 + 318 Dividend apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 324 + 330 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 177 @@ -3294,41 +3273,45 @@ Please enter the amount of your emergency fund: apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts - 53 + 57 Change - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 63 + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 119 + Average Unit Price - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 101 Minimum Price - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 128 Maximum Price - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 144 Quantity - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 154 @@ -3343,7 +3326,7 @@ Report Data Glitch - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 394 @@ -3993,7 +3976,7 @@ apps/client/src/app/pages/home/home-page.component.ts - 34 + 61 apps/client/src/app/pages/zen/zen-page-routing.module.ts @@ -4174,16 +4157,12 @@ 23 - apps/client/src/app/pages/home/home-page.component.ts - 39 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page-routing.module.ts - 13 + apps/client/src/app/pages/home/home-page-routing.module.ts + 28 - apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 39 + apps/client/src/app/pages/home/home-page.component.ts + 66 apps/client/src/app/pages/zen/zen-page.component.ts @@ -4194,22 +4173,22 @@ Summary apps/client/src/app/pages/home/home-page-routing.module.ts - 28 + 33 apps/client/src/app/pages/home/home-page.component.ts - 44 + 71 Markets apps/client/src/app/pages/home/home-page-routing.module.ts - 33 + 38 apps/client/src/app/pages/home/home-page.component.ts - 49 + 76 apps/client/src/app/pages/markets/markets-page-routing.module.ts @@ -4605,7 +4584,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 44 + 39 @@ -4840,7 +4819,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 49 + 44 @@ -5001,7 +4980,7 @@ libs/ui/src/lib/i18n.ts - 31 + 32 @@ -5043,42 +5022,42 @@ Bottom apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 216 + 214 Portfolio Evolution apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 268 + 264 Investment Timeline apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 298 + 294 Current Streak apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 319 + 315 Longest Streak apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 328 + 324 Dividend Timeline apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 356 + 352 @@ -5137,7 +5116,7 @@ 77 - apps/client/src/app/pages/portfolio/holdings/holdings-page.html + apps/client/src/app/components/home-holdings/home-holdings.html 4 @@ -13648,7 +13627,7 @@ libs/ui/src/lib/i18n.ts - 33 + 34 @@ -13669,7 +13648,7 @@ Show all libs/ui/src/lib/holdings-table/holdings-table.component.html - 174 + 197 @@ -13704,91 +13683,91 @@ Core libs/ui/src/lib/i18n.ts - 8 + 9 Switch to Ghostfolio Premium or Ghostfolio Open Source easily libs/ui/src/lib/i18n.ts - 9 + 10 Switch to Ghostfolio Premium easily libs/ui/src/lib/i18n.ts - 10 + 11 Switch to Ghostfolio Open Source or Ghostfolio Basic easily libs/ui/src/lib/i18n.ts - 11 + 12 Emergency Fund libs/ui/src/lib/i18n.ts - 12 + 13 Grant libs/ui/src/lib/i18n.ts - 13 + 14 Higher Risk libs/ui/src/lib/i18n.ts - 14 + 15 This activity already exists. libs/ui/src/lib/i18n.ts - 15 + 16 Japan libs/ui/src/lib/i18n.ts - 16 + 17 Lower Risk libs/ui/src/lib/i18n.ts - 17 + 18 Month libs/ui/src/lib/i18n.ts - 18 + 19 Months libs/ui/src/lib/i18n.ts - 19 + 20 Other libs/ui/src/lib/i18n.ts - 20 + 21 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts @@ -13799,231 +13778,231 @@ Preset libs/ui/src/lib/i18n.ts - 21 + 22 Retirement Provision libs/ui/src/lib/i18n.ts - 22 + 23 Satellite libs/ui/src/lib/i18n.ts - 23 + 24 Symbol libs/ui/src/lib/i18n.ts - 24 + 25 Tag libs/ui/src/lib/i18n.ts - 25 + 26 Year libs/ui/src/lib/i18n.ts - 26 + 27 Years libs/ui/src/lib/i18n.ts - 27 + 28 Buy libs/ui/src/lib/i18n.ts - 30 + 31 Fee libs/ui/src/lib/i18n.ts - 32 + 33 Valuable libs/ui/src/lib/i18n.ts - 34 + 35 Liability libs/ui/src/lib/i18n.ts - 35 + 36 Sell libs/ui/src/lib/i18n.ts - 36 + 37 Cash libs/ui/src/lib/i18n.ts - 39 + 40 Commodity libs/ui/src/lib/i18n.ts - 40 + 41 Equity libs/ui/src/lib/i18n.ts - 41 + 42 Fixed Income libs/ui/src/lib/i18n.ts - 42 + 43 Real Estate libs/ui/src/lib/i18n.ts - 44 + 45 Bond libs/ui/src/lib/i18n.ts - 47 + 48 Cryptocurrency libs/ui/src/lib/i18n.ts - 48 + 49 ETF libs/ui/src/lib/i18n.ts - 49 + 50 Mutual Fund libs/ui/src/lib/i18n.ts - 50 + 51 Precious Metal libs/ui/src/lib/i18n.ts - 51 + 52 Private Equity libs/ui/src/lib/i18n.ts - 52 + 53 Stock libs/ui/src/lib/i18n.ts - 53 + 54 Africa libs/ui/src/lib/i18n.ts - 60 + 61 Asia libs/ui/src/lib/i18n.ts - 61 + 62 Europe libs/ui/src/lib/i18n.ts - 62 + 63 North America libs/ui/src/lib/i18n.ts - 63 + 64 Oceania libs/ui/src/lib/i18n.ts - 64 + 65 South America libs/ui/src/lib/i18n.ts - 65 + 66 Extreme Fear libs/ui/src/lib/i18n.ts - 68 + 69 Extreme Greed libs/ui/src/lib/i18n.ts - 69 + 70 Neutral libs/ui/src/lib/i18n.ts - 72 + 73 @@ -14137,7 +14116,7 @@ Market data is delayed for apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts - 82 + 81 @@ -14359,28 +14338,28 @@ Closed - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 31 Active - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 30 Activity - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 219 Dividend Yield - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 187 @@ -14409,23 +14388,37 @@ Liquidity libs/ui/src/lib/i18n.ts - 43 + 44 Change with currency effect - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 52 Performance with currency effect - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 79 + + Buy and sell + + libs/ui/src/lib/i18n.ts + 8 + + + + {VAR_PLURAL, plural, =1 {activity} other {activities}} + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 14 + + diff --git a/apps/client/src/locales/messages.zh.xlf b/apps/client/src/locales/messages.zh.xlf index 0c48eaed2..3f792b054 100644 --- a/apps/client/src/locales/messages.zh.xlf +++ b/apps/client/src/locales/messages.zh.xlf @@ -1622,11 +1622,11 @@ 134 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 221 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 331 @@ -1926,7 +1926,7 @@ 34 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 301 @@ -2046,7 +2046,7 @@ 26 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 112 @@ -2186,7 +2186,7 @@ 232 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 228 @@ -2210,7 +2210,7 @@ 245 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 237 @@ -2230,7 +2230,7 @@ 130 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 209 @@ -2350,7 +2350,7 @@ 174 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 254 @@ -2366,7 +2366,7 @@ 77 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 264 @@ -2382,7 +2382,7 @@ 316 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 270 @@ -2402,7 +2402,7 @@ 327 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 282 @@ -2698,7 +2698,7 @@ 257 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 356 @@ -2750,7 +2750,7 @@ 10 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 376 @@ -2858,12 +2858,12 @@ 6 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 89 libs/ui/src/lib/holdings-table/holdings-table.component.html - 119 + 142 @@ -2891,7 +2891,7 @@ apps/client/src/app/pages/portfolio/portfolio-page-routing.module.ts - 48 + 41 @@ -3027,10 +3027,6 @@ 管理活动 apps/client/src/app/components/home-holdings/home-holdings.html - 22 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page.html 32 @@ -3043,7 +3039,7 @@ libs/ui/src/lib/i18n.ts - 70 + 71 @@ -3055,7 +3051,7 @@ libs/ui/src/lib/i18n.ts - 71 + 72 @@ -3266,34 +3262,12 @@ 3 - - - - - - - - - - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 12 - - - - {VAR_PLURAL, plural, =1 {transaction} other {transactions}} - {VAR_PLURAL,复数,=1 {交易} 其他{交易}} - - apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 14 - - Buy apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 21 + 31 @@ -3301,7 +3275,7 @@ apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 33 + 43 @@ -3309,10 +3283,10 @@ 投资 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 48 + 58 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 165 @@ -3321,7 +3295,7 @@ 绝对总业绩 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 60 + 70 @@ -3329,7 +3303,7 @@ 总表现 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 77 + 85 @@ -3337,10 +3311,10 @@ 费用 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 100 + 108 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 199 @@ -3353,7 +3327,7 @@ 绝对净绩效 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 116 + 124 @@ -3361,7 +3335,7 @@ 净绩效 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 133 + 139 @@ -3369,7 +3343,7 @@ 总资产 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 159 + 165 @@ -3377,7 +3351,7 @@ 贵重物品 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 172 + 178 @@ -3385,7 +3359,7 @@ 应急基金 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 184 + 190 apps/client/src/app/pages/features/features-page.html @@ -3401,7 +3375,7 @@ 现金 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 205 + 211 @@ -3409,7 +3383,7 @@ 资产 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 218 + 224 @@ -3417,7 +3391,7 @@ 购买力 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 231 + 237 @@ -3425,7 +3399,7 @@ 从分析中排除 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 243 + 249 @@ -3433,7 +3407,7 @@ 负债 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 258 + 264 apps/client/src/app/pages/features/features-page.html @@ -3445,7 +3419,7 @@ 净值 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 278 + 284 @@ -3453,7 +3427,7 @@ 年化业绩 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 290 + 296 @@ -3461,7 +3435,7 @@ 利息 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 312 + 318 @@ -3469,10 +3443,10 @@ 股息 apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html - 324 + 330 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 177 @@ -3493,22 +3467,26 @@ 请输入您的应急基金金额: apps/client/src/app/components/portfolio-summary/portfolio-summary.component.ts - 53 + 57 Change 修改 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 63 + + libs/ui/src/lib/holdings-table/holdings-table.component.html + 119 + Average Unit Price 平均单价 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 101 @@ -3516,7 +3494,7 @@ Minimum Price 最低价格 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 128 @@ -3524,7 +3502,7 @@ Maximum Price 最高价格 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 144 @@ -3532,7 +3510,7 @@ Quantity 数量 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 154 @@ -3548,7 +3526,7 @@ Report Data Glitch 报告数据故障 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 394 @@ -4269,7 +4247,7 @@ apps/client/src/app/pages/home/home-page.component.ts - 34 + 61 apps/client/src/app/pages/zen/zen-page-routing.module.ts @@ -4472,16 +4450,12 @@ 23 - apps/client/src/app/pages/home/home-page.component.ts - 39 - - - apps/client/src/app/pages/portfolio/holdings/holdings-page-routing.module.ts - 13 + apps/client/src/app/pages/home/home-page-routing.module.ts + 28 - apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 39 + apps/client/src/app/pages/home/home-page.component.ts + 66 apps/client/src/app/pages/zen/zen-page.component.ts @@ -4493,11 +4467,11 @@ 概括 apps/client/src/app/pages/home/home-page-routing.module.ts - 28 + 33 apps/client/src/app/pages/home/home-page.component.ts - 44 + 71 @@ -4505,11 +4479,11 @@ 市场 apps/client/src/app/pages/home/home-page-routing.module.ts - 33 + 38 apps/client/src/app/pages/home/home-page.component.ts - 49 + 76 apps/client/src/app/pages/markets/markets-page-routing.module.ts @@ -4957,7 +4931,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 44 + 39 @@ -5221,7 +5195,7 @@ apps/client/src/app/pages/portfolio/portfolio-page.component.ts - 49 + 44 @@ -5401,7 +5375,7 @@ libs/ui/src/lib/i18n.ts - 31 + 32 @@ -5449,7 +5423,7 @@ 底部 apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 216 + 214 @@ -5457,7 +5431,7 @@ 投资组合演变 apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 268 + 264 @@ -5465,7 +5439,7 @@ 投资时间表 apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 298 + 294 @@ -5473,7 +5447,7 @@ 当前连胜 apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 319 + 315 @@ -5481,7 +5455,7 @@ 最长连续纪录 apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 328 + 324 @@ -5489,7 +5463,7 @@ 股息时间表 apps/client/src/app/pages/portfolio/analysis/analysis-page.html - 356 + 352 @@ -5556,7 +5530,7 @@ 77 - apps/client/src/app/pages/portfolio/holdings/holdings-page.html + apps/client/src/app/components/home-holdings/home-holdings.html 4 @@ -14177,7 +14151,7 @@ libs/ui/src/lib/i18n.ts - 33 + 34 @@ -14201,7 +14175,7 @@ 显示所有 libs/ui/src/lib/holdings-table/holdings-table.component.html - 174 + 197 @@ -14241,7 +14215,7 @@ 核心 libs/ui/src/lib/i18n.ts - 8 + 9 @@ -14249,7 +14223,7 @@ 轻松切换到 Ghostfolio Premium 或 Ghostfolio Open Source libs/ui/src/lib/i18n.ts - 9 + 10 @@ -14257,7 +14231,7 @@ 轻松切换到 Ghostfolio Premium libs/ui/src/lib/i18n.ts - 10 + 11 @@ -14265,7 +14239,7 @@ 轻松切换到 Ghostfolio Open Source 或 Ghostfolio Basic libs/ui/src/lib/i18n.ts - 11 + 12 @@ -14273,7 +14247,7 @@ 应急基金 libs/ui/src/lib/i18n.ts - 12 + 13 @@ -14281,7 +14255,7 @@ 授予 libs/ui/src/lib/i18n.ts - 13 + 14 @@ -14289,7 +14263,7 @@ 风险较高 libs/ui/src/lib/i18n.ts - 14 + 15 @@ -14297,7 +14271,7 @@ 这项活动已经存在。 libs/ui/src/lib/i18n.ts - 15 + 16 @@ -14305,7 +14279,7 @@ 日本 libs/ui/src/lib/i18n.ts - 16 + 17 @@ -14313,7 +14287,7 @@ 降低风险 libs/ui/src/lib/i18n.ts - 17 + 18 @@ -14321,7 +14295,7 @@ libs/ui/src/lib/i18n.ts - 18 + 19 @@ -14329,7 +14303,7 @@ 几个月 libs/ui/src/lib/i18n.ts - 19 + 20 @@ -14337,7 +14311,7 @@ 其他 libs/ui/src/lib/i18n.ts - 20 + 21 libs/ui/src/lib/portfolio-proportion-chart/portfolio-proportion-chart.component.ts @@ -14349,7 +14323,7 @@ 预设 libs/ui/src/lib/i18n.ts - 21 + 22 @@ -14357,7 +14331,7 @@ 退休金 libs/ui/src/lib/i18n.ts - 22 + 23 @@ -14365,7 +14339,7 @@ 卫星 libs/ui/src/lib/i18n.ts - 23 + 24 @@ -14373,7 +14347,7 @@ 符号 libs/ui/src/lib/i18n.ts - 24 + 25 @@ -14381,7 +14355,7 @@ 标签 libs/ui/src/lib/i18n.ts - 25 + 26 @@ -14389,7 +14363,7 @@ libs/ui/src/lib/i18n.ts - 26 + 27 @@ -14397,7 +14371,7 @@ libs/ui/src/lib/i18n.ts - 27 + 28 @@ -14405,7 +14379,7 @@ libs/ui/src/lib/i18n.ts - 30 + 31 @@ -14413,7 +14387,7 @@ 费用 libs/ui/src/lib/i18n.ts - 32 + 33 @@ -14421,7 +14395,7 @@ 有价值的 libs/ui/src/lib/i18n.ts - 34 + 35 @@ -14429,7 +14403,7 @@ 责任 libs/ui/src/lib/i18n.ts - 35 + 36 @@ -14437,7 +14411,7 @@ libs/ui/src/lib/i18n.ts - 36 + 37 @@ -14445,7 +14419,7 @@ 现金 libs/ui/src/lib/i18n.ts - 39 + 40 @@ -14453,7 +14427,7 @@ 商品 libs/ui/src/lib/i18n.ts - 40 + 41 @@ -14461,7 +14435,7 @@ 公平 libs/ui/src/lib/i18n.ts - 41 + 42 @@ -14469,7 +14443,7 @@ 固定收入 libs/ui/src/lib/i18n.ts - 42 + 43 @@ -14477,7 +14451,7 @@ 房地产 libs/ui/src/lib/i18n.ts - 44 + 45 @@ -14485,7 +14459,7 @@ 纽带 libs/ui/src/lib/i18n.ts - 47 + 48 @@ -14493,7 +14467,7 @@ 加密货币 libs/ui/src/lib/i18n.ts - 48 + 49 @@ -14501,7 +14475,7 @@ 交易所交易基金 libs/ui/src/lib/i18n.ts - 49 + 50 @@ -14509,7 +14483,7 @@ 共同基金 libs/ui/src/lib/i18n.ts - 50 + 51 @@ -14517,7 +14491,7 @@ 贵金属 libs/ui/src/lib/i18n.ts - 51 + 52 @@ -14525,7 +14499,7 @@ 私人产权 libs/ui/src/lib/i18n.ts - 52 + 53 @@ -14533,7 +14507,7 @@ 库存 libs/ui/src/lib/i18n.ts - 53 + 54 @@ -14541,7 +14515,7 @@ 非洲 libs/ui/src/lib/i18n.ts - 60 + 61 @@ -14549,7 +14523,7 @@ 亚洲 libs/ui/src/lib/i18n.ts - 61 + 62 @@ -14557,7 +14531,7 @@ 欧洲 libs/ui/src/lib/i18n.ts - 62 + 63 @@ -14565,7 +14539,7 @@ 北美 libs/ui/src/lib/i18n.ts - 63 + 64 @@ -14573,7 +14547,7 @@ 大洋洲 libs/ui/src/lib/i18n.ts - 64 + 65 @@ -14581,7 +14555,7 @@ 南美洲 libs/ui/src/lib/i18n.ts - 65 + 66 @@ -14589,7 +14563,7 @@ 极度恐惧 libs/ui/src/lib/i18n.ts - 68 + 69 @@ -14597,7 +14571,7 @@ 极度贪婪 libs/ui/src/lib/i18n.ts - 69 + 70 @@ -14605,7 +14579,7 @@ 中性的 libs/ui/src/lib/i18n.ts - 72 + 73 @@ -14733,7 +14707,7 @@ 市场数据延迟 apps/client/src/app/components/portfolio-performance/portfolio-performance.component.ts - 82 + 81 @@ -14984,7 +14958,7 @@ Closed 关闭 - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 31 @@ -14992,7 +14966,7 @@ Active 积极的 - apps/client/src/app/pages/portfolio/holdings/holdings-page.component.ts + apps/client/src/app/components/home-holdings/home-holdings.component.ts 30 @@ -15000,7 +14974,7 @@ Activity 活动 - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 219 @@ -15008,7 +14982,7 @@ Dividend Yield Dividend Yield - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 187 @@ -15041,14 +15015,14 @@ Liquidity libs/ui/src/lib/i18n.ts - 43 + 44 Change with currency effect Change with currency effect - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 52 @@ -15056,10 +15030,26 @@ Performance with currency effect Performance with currency effect - apps/client/src/app/components/position/position-detail-dialog/position-detail-dialog.html + apps/client/src/app/components/position-detail-dialog/position-detail-dialog.html 79 + + {VAR_PLURAL, plural, =1 {activity} other {activities}} + {VAR_PLURAL, plural, =1 {activity} other {activities}} + + apps/client/src/app/components/portfolio-summary/portfolio-summary.component.html + 14 + + + + Buy and sell + Buy and sell + + libs/ui/src/lib/i18n.ts + 8 + + From 74f432390348c74dca05b37cb6309bdacfa9e4fa Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Wed, 8 May 2024 20:54:13 +0200 Subject: [PATCH 195/203] Feature/increase spacing around floating action buttons (#3385) * Increase spacing around floating action buttons * Update changelog --- CHANGELOG.md | 1 + .../admin-market-data/admin-market-data.component.ts | 1 + .../user-account-access.component.ts | 1 + .../app/pages/accounts/accounts-page.component.ts | 2 +- .../activities/activities-page.component.ts | 1 + apps/client/src/styles.scss | 12 ++++++++---- 6 files changed, 13 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a571b620..98001e25e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Increased the spacing around the floating action buttons (FAB) - Set the icon column of the activities table to stick at the beginning - Set the icon column of the holdings table to stick at the beginning - Increased the number of attempts of queue jobs from `10` to `12` (fail later) diff --git a/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts b/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts index 0ccf85701..61f11c9bd 100644 --- a/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts +++ b/apps/client/src/app/components/admin-market-data/admin-market-data.component.ts @@ -38,6 +38,7 @@ import { CreateAssetProfileDialogParams } from './create-asset-profile-dialog/in @Component({ changeDetection: ChangeDetectionStrategy.OnPush, + host: { class: 'has-fab' }, selector: 'gf-admin-market-data', styleUrls: ['./admin-market-data.scss'], templateUrl: './admin-market-data.html' diff --git a/apps/client/src/app/components/user-account-access/user-account-access.component.ts b/apps/client/src/app/components/user-account-access/user-account-access.component.ts index b2ee5ae59..d36c31632 100644 --- a/apps/client/src/app/components/user-account-access/user-account-access.component.ts +++ b/apps/client/src/app/components/user-account-access/user-account-access.component.ts @@ -21,6 +21,7 @@ import { CreateOrUpdateAccessDialog } from './create-or-update-access-dialog/cre @Component({ changeDetection: ChangeDetectionStrategy.OnPush, + host: { class: 'has-fab' }, selector: 'gf-user-account-access', styleUrls: ['./user-account-access.scss'], templateUrl: './user-account-access.html' diff --git a/apps/client/src/app/pages/accounts/accounts-page.component.ts b/apps/client/src/app/pages/accounts/accounts-page.component.ts index e445863b4..244333243 100644 --- a/apps/client/src/app/pages/accounts/accounts-page.component.ts +++ b/apps/client/src/app/pages/accounts/accounts-page.component.ts @@ -21,7 +21,7 @@ import { CreateOrUpdateAccountDialog } from './create-or-update-account-dialog/c import { TransferBalanceDialog } from './transfer-balance/transfer-balance-dialog.component'; @Component({ - host: { class: 'page' }, + host: { class: 'has-fab page' }, selector: 'gf-accounts-page', styleUrls: ['./accounts-page.scss'], templateUrl: './accounts-page.html' diff --git a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts index 6e66bb666..f75bc260b 100644 --- a/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts +++ b/apps/client/src/app/pages/portfolio/activities/activities-page.component.ts @@ -29,6 +29,7 @@ import { ImportActivitiesDialog } from './import-activities-dialog/import-activi import { ImportActivitiesDialogParams } from './import-activities-dialog/interfaces/interfaces'; @Component({ + host: { class: 'has-fab' }, selector: 'gf-activities-page', styleUrls: ['./activities-page.scss'], templateUrl: './activities-page.html' diff --git a/apps/client/src/styles.scss b/apps/client/src/styles.scss index 6d3cffff2..ce18789b2 100644 --- a/apps/client/src/styles.scss +++ b/apps/client/src/styles.scss @@ -387,6 +387,10 @@ ngx-skeleton-loader { @include gf-table; } +.has-fab { + padding-bottom: 3rem !important; +} + .has-info-message { .page.has-tabs { height: calc(100svh - 2 * var(--mat-toolbar-standard-height)); @@ -543,6 +547,10 @@ ngx-skeleton-loader { --mdc-tab-indicator-active-indicator-color: transparent; } + .mat-mdc-tab-nav-panel { + padding: 2rem 0; + } + @media (max-width: 575.98px) { .mat-mdc-tab-link { --mdc-secondary-navigation-tab-container-height: 3rem; @@ -567,10 +575,6 @@ ngx-skeleton-loader { } } } - - .mat-mdc-tab-nav-panel { - padding: 2rem 0; - } } } } From 80464c78467f232d2d466d576db871b0da966d12 Mon Sep 17 00:00:00 2001 From: Thomas Kaul <4159106+dtslvr@users.noreply.github.com> Date: Wed, 8 May 2024 20:55:39 +0200 Subject: [PATCH 196/203] Release 2.80.0 (#3386) --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 98001e25e..64b3e5467 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## Unreleased +## 2.80.0 - 2024-05-08 ### Added diff --git a/package.json b/package.json index f99d9b57c..dd7355bd5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ghostfolio", - "version": "2.79.0", + "version": "2.80.0", "homepage": "https://ghostfol.io", "license": "AGPL-3.0", "repository": "https://github.com/ghostfolio/ghostfolio", From 3db848fc067dc25046043a5de6c49db5bda6c070 Mon Sep 17 00:00:00 2001 From: Dan Date: Thu, 9 May 2024 10:11:59 +0200 Subject: [PATCH 197/203] Yarn install --- yarn.lock | 6172 ++++++++++++++++++++++++----------------------------- 1 file changed, 2766 insertions(+), 3406 deletions(-) diff --git a/yarn.lock b/yarn.lock index 90681070f..7de918d28 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,11 +2,6 @@ # yarn lockfile v1 -"@aashutoshrathi/word-wrap@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" - integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== - "@adobe/css-tools@^4.0.1": version "4.3.2" resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.2.tgz#a6abc715fb6884851fca9dad37fc34739a04fd11" @@ -181,6 +176,18 @@ rxjs "7.8.1" source-map "0.7.4" +"@angular-devkit/core@17.3.7": + version "17.3.7" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-17.3.7.tgz#553b456cf9747eecdb1f7389127057bc5cb9f8e4" + integrity sha512-qpZ7BShyqS/Jqld36E7kL02cyb2pjn1Az1p9439SbP8nsvJgYlsyjwYK2Kmcn/Wi+TZGIKxkqxgBBw9vqGgeJw== + dependencies: + ajv "8.12.0" + ajv-formats "2.1.1" + jsonc-parser "3.2.1" + picomatch "4.0.1" + rxjs "7.8.1" + source-map "0.7.4" + "@angular-devkit/schematics@16.0.1": version "16.0.1" resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-16.0.1.tgz#d49387e9e41c9cce98b155da51b0e193333dd178" @@ -203,17 +210,6 @@ ora "5.4.1" rxjs "7.8.1" -"@angular-devkit/schematics@17.0.0", "@angular-devkit/schematics@^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0": - version "17.0.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-17.0.0.tgz#bfcc09a1bd145ef978f92d660df89a11e69468d4" - integrity sha512-LD7fjDORuBf139/oJ/gSwbIzQPfsm6Y67s1FD+XLi0QXaRt6dw4r7BMD08l1r//oPQofNgbEH4coGVO4NdCL/A== - dependencies: - "@angular-devkit/core" "17.0.0" - jsonc-parser "3.2.0" - magic-string "0.30.5" - ora "5.4.1" - rxjs "7.8.1" - "@angular-devkit/schematics@17.3.3": version "17.3.3" resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-17.3.3.tgz#223d8ffd27e6daaf63a3161dbe8c849860541bf1" @@ -236,6 +232,28 @@ ora "5.4.1" rxjs "7.8.1" +"@angular-devkit/schematics@17.3.7": + version "17.3.7" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-17.3.7.tgz#0b964b9216d51e7706656fdc0643fd9716461902" + integrity sha512-d7NKSwstdxYLYmPsbcYO3GOFNfXxXwOyHxSqDa1JNKoSzMdbLj4tvlCpfXw0ThNM7gioMx8aLBaaH1ac+yk06Q== + dependencies: + "@angular-devkit/core" "17.3.7" + jsonc-parser "3.2.1" + magic-string "0.30.8" + ora "5.4.1" + rxjs "7.8.1" + +"@angular-devkit/schematics@^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0": + version "17.0.0" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-17.0.0.tgz#bfcc09a1bd145ef978f92d660df89a11e69468d4" + integrity sha512-LD7fjDORuBf139/oJ/gSwbIzQPfsm6Y67s1FD+XLi0QXaRt6dw4r7BMD08l1r//oPQofNgbEH4coGVO4NdCL/A== + dependencies: + "@angular-devkit/core" "17.0.0" + jsonc-parser "3.2.0" + magic-string "0.30.5" + ora "5.4.1" + rxjs "7.8.1" + "@angular-eslint/bundled-angular-compiler@17.3.0": version "17.3.0" resolved "https://registry.yarnpkg.com/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-17.3.0.tgz#08b8b1bebbb677a1f208b56516fc9177a289d212" @@ -505,7 +523,7 @@ "@babel/highlight" "^7.23.4" chalk "^2.4.2" -"@babel/code-frame@^7.24.1": +"@babel/code-frame@^7.24.2": version "7.24.2" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.2.tgz#718b4b19841809a58b29b68cde80bc5e1aa6d9ae" integrity sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ== @@ -513,16 +531,21 @@ "@babel/highlight" "^7.24.2" picocolors "^1.0.0" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.21.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9", "@babel/compat-data@^7.23.2": +"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.21.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.2.tgz#6a12ced93455827037bfb5ed8492820d60fc32cc" integrity sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ== -"@babel/compat-data@^7.23.3", "@babel/compat-data@^7.23.5": +"@babel/compat-data@^7.23.5": version "7.23.5" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== +"@babel/compat-data@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.4.tgz#6f102372e9094f25d908ca0d34fc74c74606059a" + integrity sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ== + "@babel/core@7.23.9": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.9.tgz#b028820718000f267870822fec434820e9b1e4d1" @@ -607,6 +630,27 @@ json5 "^2.2.3" semver "^6.3.1" +"@babel/core@^7.23.9": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.5.tgz#15ab5b98e101972d171aeef92ac70d8d6718f06a" + integrity sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.24.2" + "@babel/generator" "^7.24.5" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-module-transforms" "^7.24.5" + "@babel/helpers" "^7.24.5" + "@babel/parser" "^7.24.5" + "@babel/template" "^7.24.0" + "@babel/traverse" "^7.24.5" + "@babel/types" "^7.24.5" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + "@babel/core@~7.21.0": version "7.21.8" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.8.tgz#2a8c7f0f53d60100ba4c32470ba0281c92aa9aa4" @@ -657,12 +701,12 @@ "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" -"@babel/generator@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.1.tgz#e67e06f68568a4ebf194d1c6014235344f0476d0" - integrity sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A== +"@babel/generator@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.5.tgz#e5afc068f932f05616b66713e28d0f04e99daeb3" + integrity sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA== dependencies: - "@babel/types" "^7.24.0" + "@babel/types" "^7.24.5" "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" jsesc "^2.5.1" @@ -684,14 +728,14 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.22.15", "@babel/helper-builder-binary-assignment-operator-visitor@^7.22.5": +"@babel/helper-builder-binary-assignment-operator-visitor@^7.22.15": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz#5426b109cf3ad47b91120f8328d8ab1be8b0b956" integrity sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw== dependencies: "@babel/types" "^7.22.15" -"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.21.5", "@babel/helper-compilation-targets@^7.22.15", "@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6": +"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.21.5", "@babel/helper-compilation-targets@^7.22.15", "@babel/helper-compilation-targets@^7.22.6": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== @@ -713,7 +757,7 @@ lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.22.11", "@babel/helper-create-class-features-plugin@^7.22.15", "@babel/helper-create-class-features-plugin@^7.22.5": +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz#97a61b385e57fe458496fad19f8e63b63c867de4" integrity sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg== @@ -728,18 +772,19 @@ "@babel/helper-split-export-declaration" "^7.22.6" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.23.6": - version "7.23.10" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.10.tgz#25d55fafbaea31fd0e723820bb6cc3df72edf7ea" - integrity sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw== +"@babel/helper-create-class-features-plugin@^7.24.1", "@babel/helper-create-class-features-plugin@^7.24.4", "@babel/helper-create-class-features-plugin@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.5.tgz#7d19da92c7e0cd8d11c09af2ce1b8e7512a6e723" + integrity sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g== + dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" "@babel/helper-environment-visitor" "^7.22.20" "@babel/helper-function-name" "^7.23.0" - "@babel/helper-member-expression-to-functions" "^7.23.0" + "@babel/helper-member-expression-to-functions" "^7.24.5" "@babel/helper-optimise-call-expression" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.20" + "@babel/helper-replace-supers" "^7.24.1" "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-split-export-declaration" "^7.24.5" semver "^6.3.1" "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.15", "@babel/helper-create-regexp-features-plugin@^7.22.5": @@ -763,10 +808,10 @@ resolve "^1.14.2" semver "^6.1.2" -"@babel/helper-define-polyfill-provider@^0.4.3": - version "0.4.3" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz#a71c10f7146d809f4a256c373f462d9bba8cf6ba" - integrity sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug== +"@babel/helper-define-polyfill-provider@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz#465805b7361f461e86c680f1de21eaf88c25901b" + integrity sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q== dependencies: "@babel/helper-compilation-targets" "^7.22.6" "@babel/helper-plugin-utils" "^7.22.5" @@ -774,10 +819,10 @@ lodash.debounce "^4.0.8" resolve "^1.14.2" -"@babel/helper-define-polyfill-provider@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz#465805b7361f461e86c680f1de21eaf88c25901b" - integrity sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q== +"@babel/helper-define-polyfill-provider@^0.6.1", "@babel/helper-define-polyfill-provider@^0.6.2": + version "0.6.2" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz#18594f789c3594acb24cfdb4a7f7b7d2e8bd912d" + integrity sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ== dependencies: "@babel/helper-compilation-targets" "^7.22.6" "@babel/helper-plugin-utils" "^7.22.5" @@ -805,41 +850,30 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-member-expression-to-functions@^7.22.15", "@babel/helper-member-expression-to-functions@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz#9263e88cc5e41d39ec18c9a3e0eced59a3e7d366" - integrity sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA== - dependencies: - "@babel/types" "^7.23.0" - -"@babel/helper-module-imports@^7.22.15", "@babel/helper-module-imports@^7.22.5": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" - integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== +"@babel/helper-member-expression-to-functions@^7.22.15", "@babel/helper-member-expression-to-functions@^7.23.0", "@babel/helper-member-expression-to-functions@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.5.tgz#5981e131d5c7003c7d1fa1ad49e86c9b097ec475" + integrity sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA== dependencies: - "@babel/types" "^7.22.15" + "@babel/types" "^7.24.5" -"@babel/helper-module-transforms@^7.21.5", "@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz#3ec246457f6c842c0aee62a01f60739906f7047e" - integrity sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw== +"@babel/helper-module-imports@^7.22.15", "@babel/helper-module-imports@^7.24.1", "@babel/helper-module-imports@^7.24.3": + version "7.24.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.3.tgz#6ac476e6d168c7c23ff3ba3cf4f7841d46ac8128" + integrity sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg== dependencies: - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-module-imports" "^7.22.15" - "@babel/helper-simple-access" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/helper-validator-identifier" "^7.22.20" + "@babel/types" "^7.24.0" -"@babel/helper-module-transforms@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" - integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== +"@babel/helper-module-transforms@^7.21.5", "@babel/helper-module-transforms@^7.23.0", "@babel/helper-module-transforms@^7.23.3", "@babel/helper-module-transforms@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.24.5.tgz#ea6c5e33f7b262a0ae762fd5986355c45f54a545" + integrity sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A== dependencies: "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-module-imports" "^7.22.15" - "@babel/helper-simple-access" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/helper-validator-identifier" "^7.22.20" + "@babel/helper-module-imports" "^7.24.3" + "@babel/helper-simple-access" "^7.24.5" + "@babel/helper-split-export-declaration" "^7.24.5" + "@babel/helper-validator-identifier" "^7.24.5" "@babel/helper-optimise-call-expression@^7.22.5": version "7.22.5" @@ -848,17 +882,12 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.21.5", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" - integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== - -"@babel/helper-plugin-utils@^7.24.0": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz#945681931a52f15ce879fd5b86ce2dae6d3d7f2a" - integrity sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.21.5", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.0", "@babel/helper-plugin-utils@^7.24.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.5.tgz#a924607dd254a65695e5bd209b98b902b3b2f11a" + integrity sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ== -"@babel/helper-remap-async-to-generator@^7.18.9", "@babel/helper-remap-async-to-generator@^7.22.20", "@babel/helper-remap-async-to-generator@^7.22.5": +"@babel/helper-remap-async-to-generator@^7.18.9", "@babel/helper-remap-async-to-generator@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz#7b68e1cb4fa964d2996fd063723fb48eca8498e0" integrity sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw== @@ -867,16 +896,7 @@ "@babel/helper-environment-visitor" "^7.22.20" "@babel/helper-wrap-function" "^7.22.20" -"@babel/helper-replace-supers@^7.22.20", "@babel/helper-replace-supers@^7.22.5", "@babel/helper-replace-supers@^7.22.9": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz#e37d367123ca98fe455a9887734ed2e16eb7a793" - integrity sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw== - dependencies: - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-member-expression-to-functions" "^7.22.15" - "@babel/helper-optimise-call-expression" "^7.22.5" - -"@babel/helper-replace-supers@^7.24.1": +"@babel/helper-replace-supers@^7.22.9", "@babel/helper-replace-supers@^7.24.1": version "7.24.1" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz#7085bd19d4a0b7ed8f405c1ed73ccb70f323abc1" integrity sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ== @@ -885,12 +905,12 @@ "@babel/helper-member-expression-to-functions" "^7.23.0" "@babel/helper-optimise-call-expression" "^7.22.5" -"@babel/helper-simple-access@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" - integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== +"@babel/helper-simple-access@^7.22.5", "@babel/helper-simple-access@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.24.5.tgz#50da5b72f58c16b07fbd992810be6049478e85ba" + integrity sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ== dependencies: - "@babel/types" "^7.22.5" + "@babel/types" "^7.24.5" "@babel/helper-skip-transparent-expression-wrappers@^7.20.0", "@babel/helper-skip-transparent-expression-wrappers@^7.22.5": version "7.22.5" @@ -899,175 +919,104 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-split-export-declaration@7.22.6", "@babel/helper-split-export-declaration@^7.18.6", "@babel/helper-split-export-declaration@^7.22.6": +"@babel/helper-split-export-declaration@7.22.6": version "7.22.6" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== dependencies: "@babel/types" "^7.22.5" -"@babel/helper-string-parser@^7.21.5", "@babel/helper-string-parser@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" - integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== - -"@babel/helper-string-parser@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" - integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== +"@babel/helper-split-export-declaration@^7.18.6", "@babel/helper-split-export-declaration@^7.22.6", "@babel/helper-split-export-declaration@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz#b9a67f06a46b0b339323617c8c6213b9055a78b6" + integrity sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q== + dependencies: + "@babel/types" "^7.24.5" -"@babel/helper-validator-identifier@^7.16.7", "@babel/helper-validator-identifier@^7.19.1", "@babel/helper-validator-identifier@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" - integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== +"@babel/helper-string-parser@^7.21.5", "@babel/helper-string-parser@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz#f99c36d3593db9540705d0739a1f10b5e20c696e" + integrity sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ== -"@babel/helper-validator-option@^7.21.0", "@babel/helper-validator-option@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" - integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== +"@babel/helper-validator-identifier@^7.16.7", "@babel/helper-validator-identifier@^7.19.1", "@babel/helper-validator-identifier@^7.22.20", "@babel/helper-validator-identifier@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz#918b1a7fa23056603506370089bd990d8720db62" + integrity sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA== -"@babel/helper-validator-option@^7.23.5": +"@babel/helper-validator-option@^7.21.0", "@babel/helper-validator-option@^7.22.15", "@babel/helper-validator-option@^7.23.5": version "7.23.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== "@babel/helper-wrap-function@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz#15352b0b9bfb10fc9c76f79f6342c00e3411a569" - integrity sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw== - dependencies: - "@babel/helper-function-name" "^7.22.5" - "@babel/template" "^7.22.15" - "@babel/types" "^7.22.19" - -"@babel/helpers@^7.21.5", "@babel/helpers@^7.23.2": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.2.tgz#2832549a6e37d484286e15ba36a5330483cac767" - integrity sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ== - dependencies: - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.2" - "@babel/types" "^7.23.0" - -"@babel/helpers@^7.23.6": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.6.tgz#d03af2ee5fb34691eec0cda90f5ecbb4d4da145a" - integrity sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA== - dependencies: - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.6" - "@babel/types" "^7.23.6" - -"@babel/helpers@^7.23.9": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.1.tgz#183e44714b9eba36c3038e442516587b1e0a1a94" - integrity sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg== + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.24.5.tgz#335f934c0962e2c1ed1fb9d79e06a56115067c09" + integrity sha512-/xxzuNvgRl4/HLNKvnFwdhdgN3cpLxgLROeLDl83Yx0AJ1SGvq1ak0OszTOjDfiB8Vx03eJbeDWh9r+jCCWttw== dependencies: + "@babel/helper-function-name" "^7.23.0" "@babel/template" "^7.24.0" - "@babel/traverse" "^7.24.1" - "@babel/types" "^7.24.0" + "@babel/types" "^7.24.5" -"@babel/helpers@^7.24.0": - version "7.24.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.4.tgz#dc00907fd0d95da74563c142ef4cd21f2cb856b6" - integrity sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw== +"@babel/helpers@^7.21.5", "@babel/helpers@^7.23.2", "@babel/helpers@^7.23.6", "@babel/helpers@^7.23.9", "@babel/helpers@^7.24.0", "@babel/helpers@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.5.tgz#fedeb87eeafa62b621160402181ad8585a22a40a" + integrity sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q== dependencies: "@babel/template" "^7.24.0" - "@babel/traverse" "^7.24.1" - "@babel/types" "^7.24.0" - -"@babel/highlight@^7.22.13": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" - integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== - dependencies: - "@babel/helper-validator-identifier" "^7.22.20" - chalk "^2.4.2" - js-tokens "^4.0.0" - -"@babel/highlight@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" - integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== - dependencies: - "@babel/helper-validator-identifier" "^7.22.20" - chalk "^2.4.2" - js-tokens "^4.0.0" + "@babel/traverse" "^7.24.5" + "@babel/types" "^7.24.5" -"@babel/highlight@^7.24.2": - version "7.24.2" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.2.tgz#3f539503efc83d3c59080a10e6634306e0370d26" - integrity sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA== +"@babel/highlight@^7.22.13", "@babel/highlight@^7.23.4", "@babel/highlight@^7.24.2": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.5.tgz#bc0613f98e1dd0720e99b2a9ee3760194a704b6e" + integrity sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw== dependencies: - "@babel/helper-validator-identifier" "^7.22.20" + "@babel/helper-validator-identifier" "^7.24.5" chalk "^2.4.2" js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.13.16", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.21.5", "@babel/parser@^7.21.8", "@babel/parser@^7.22.15", "@babel/parser@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" - integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== - -"@babel/parser@^7.20.5", "@babel/parser@^7.23.6": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.6.tgz#ba1c9e512bda72a47e285ae42aff9d2a635a9e3b" - integrity sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ== - -"@babel/parser@^7.23.9": - version "7.23.9" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.9.tgz#7b903b6149b0f8fa7ad564af646c4c38a77fc44b" - integrity sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA== - -"@babel/parser@^7.24.0", "@babel/parser@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.1.tgz#1e416d3627393fab1cb5b0f2f1796a100ae9133a" - integrity sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg== +"@babel/parser@^7.1.0", "@babel/parser@^7.13.16", "@babel/parser@^7.14.7", "@babel/parser@^7.20.5", "@babel/parser@^7.20.7", "@babel/parser@^7.21.5", "@babel/parser@^7.21.8", "@babel/parser@^7.23.0", "@babel/parser@^7.23.6", "@babel/parser@^7.23.9", "@babel/parser@^7.24.0", "@babel/parser@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.5.tgz#4a4d5ab4315579e5398a82dcf636ca80c3392790" + integrity sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg== "@babel/parser@~7.21.2": version "7.21.9" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.9.tgz#ab18ea3b85b4bc33ba98a8d4c2032c557d23cf14" integrity sha512-q5PNg/Bi1OpGgx5jYlvWZwAorZepEudDMCLtj967aeS7WMont7dUZI46M2XwcIQqvUlMxWfdLFu4S/qSxeUu5g== -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz#02dc8a03f613ed5fdc29fb2f728397c78146c962" - integrity sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz#5cd1c87ba9380d0afb78469292c954fee5d2411a" - integrity sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ== +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.5.tgz#4c3685eb9cd790bcad2843900fe0250c91ccf895" + integrity sha512-LdXRi1wEMTrHVR4Zc9F8OewC3vdm5h4QB6L71zy6StmYeqGi1b3ttIO8UC+BfZKcH9jdr4aI249rBkm+3+YvHw== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.24.5" -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.20.7", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.15.tgz#2aeb91d337d4e1a1e7ce85b76a37f5301781200f" - integrity sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.23.3", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.24.1.tgz#b645d9ba8c2bc5b7af50f0fe949f9edbeb07c8cf" + integrity sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/plugin-transform-optional-chaining" "^7.22.15" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz#f6652bb16b94f8f9c20c50941e16e9756898dc5d" - integrity sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.20.7", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.23.3", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.1.tgz#da8261f2697f0f41b0855b91d3a20a1fbfd271d3" + integrity sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/plugin-transform-optional-chaining" "^7.23.3" + "@babel/plugin-transform-optional-chaining" "^7.24.1" -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.23.7": - version "7.23.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz#516462a95d10a9618f197d39ad291a9b47ae1d7b" - integrity sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw== +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.23.7", "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.24.1.tgz#1181d9685984c91d657b8ddf14f0487a6bab2988" + integrity sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw== dependencies: "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-proposal-async-generator-functions@^7.20.7": version "7.20.7" @@ -1097,15 +1046,13 @@ "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-proposal-decorators@^7.22.7": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.23.2.tgz#0b345a5754f48309fa50b7cd99075ef0295b12c8" - integrity sha512-eR0gJQc830fJVGz37oKLvt9W9uUIQSAovUl0e9sJ3YeO09dlcoBVYD3CLrjCj4qHdXmfiyTyFt8yeQYSN5fxLg== + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.24.1.tgz#bab2b9e174a2680f0a80f341f3ec70f809f8bb4b" + integrity sha512-zPEvzFijn+hRvJuX2Vu3KbEBN39LN3f7tW3MQO2LsIs57B26KU+kUc82BdAktS1VCM6libzh45eKGI65lg0cpA== dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.20" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/plugin-syntax-decorators" "^7.22.10" + "@babel/helper-create-class-features-plugin" "^7.24.1" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-decorators" "^7.24.1" "@babel/plugin-proposal-dynamic-import@^7.18.6": version "7.18.6" @@ -1242,12 +1189,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-decorators@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.22.10.tgz#7d83ea04d893c442b78ebf4c3cbac59a7211deff" - integrity sha512-z1KTVemBjnz+kSEilAsI4lbkPOl5TvJH7YDSY1CTIzvLWJ+KHXp+mRe8VPmfnyvqOPqar1V2gid2PleKzRUstQ== +"@babel/plugin-syntax-decorators@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.24.1.tgz#71d9ad06063a6ac5430db126b5df48c70ee885fa" + integrity sha512-05RJdO/cCrtVWuAaSn1tS3bH8jbsJa/Y1uD186u6J4C/1mnHFxseeuWpsqr9anvo7TUulev7tm7GDwRV+VuhDw== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" @@ -1263,47 +1210,26 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-flow@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.22.5.tgz#163b820b9e7696ce134df3ee716d9c0c98035859" - integrity sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-syntax-flow@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.23.3.tgz#084564e0f3cc21ea6c70c44cff984a1c0509729a" - integrity sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-syntax-import-assertions@^7.20.0", "@babel/plugin-syntax-import-assertions@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz#07d252e2aa0bc6125567f742cd58619cb14dce98" - integrity sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-syntax-import-assertions@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz#9c05a7f592982aff1a2768260ad84bcd3f0c77fc" - integrity sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw== +"@babel/plugin-syntax-flow@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.24.1.tgz#875c25e3428d7896c87589765fc8b9d32f24bd8d" + integrity sha512-sxi2kLTI5DeW5vDtMUsk4mTPwvlUDbjOnoWayhynCwrw4QXRld4QEYwqzY8JmQXaJUtgUuCIurtSRH5sn4c7mA== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-syntax-import-attributes@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz#ab840248d834410b829f569f5262b9e517555ecb" - integrity sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg== +"@babel/plugin-syntax-import-assertions@^7.20.0", "@babel/plugin-syntax-import-assertions@^7.23.3", "@babel/plugin-syntax-import-assertions@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.1.tgz#db3aad724153a00eaac115a3fb898de544e34971" + integrity sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-syntax-import-attributes@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz#992aee922cf04512461d7dae3ff6951b90a2dc06" - integrity sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA== +"@babel/plugin-syntax-import-attributes@^7.23.3", "@babel/plugin-syntax-import-attributes@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.1.tgz#c66b966c63b714c4eec508fcf5763b1f2d381093" + integrity sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-syntax-import-meta@^7.10.4", "@babel/plugin-syntax-import-meta@^7.8.3": version "7.10.4" @@ -1319,19 +1245,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.22.5", "@babel/plugin-syntax-jsx@^7.7.2": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" - integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-syntax-jsx@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz#8f2e4f8a9b5f9aa16067e142c1ac9cd9f810f473" - integrity sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg== +"@babel/plugin-syntax-jsx@^7.24.1", "@babel/plugin-syntax-jsx@^7.7.2": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.1.tgz#3f6ca04b8c841811dbc3c5c5f837934e0d626c10" + integrity sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" @@ -1389,19 +1308,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.22.5", "@babel/plugin-syntax-typescript@^7.3.3", "@babel/plugin-syntax-typescript@^7.7.2": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz#aac8d383b062c5072c647a31ef990c1d0af90272" - integrity sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-syntax-typescript@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz#24f460c85dbbc983cd2b9c4994178bcc01df958f" - integrity sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ== +"@babel/plugin-syntax-typescript@^7.24.1", "@babel/plugin-syntax-typescript@^7.3.3", "@babel/plugin-syntax-typescript@^7.7.2": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.1.tgz#b3bcc51f396d15f3591683f90239de143c076844" + integrity sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-syntax-unicode-sets-regex@^7.18.6": version "7.18.6" @@ -1411,19 +1323,12 @@ "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-arrow-functions@^7.21.5", "@babel/plugin-transform-arrow-functions@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz#e5ba566d0c58a5b2ba2a8b795450641950b71958" - integrity sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-arrow-functions@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz#94c6dcfd731af90f27a79509f9ab7fb2120fc38b" - integrity sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ== +"@babel/plugin-transform-arrow-functions@^7.21.5", "@babel/plugin-transform-arrow-functions@^7.23.3", "@babel/plugin-transform-arrow-functions@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.1.tgz#2bf263617060c9cc45bcdbf492b8cc805082bf27" + integrity sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-transform-async-generator-functions@7.23.9": version "7.23.9" @@ -1435,27 +1340,7 @@ "@babel/helper-remap-async-to-generator" "^7.22.20" "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-transform-async-generator-functions@^7.23.2": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.2.tgz#054afe290d64c6f576f371ccc321772c8ea87ebb" - integrity sha512-BBYVGxbDVHfoeXbOwcagAkOQAm9NxoTdMGfTqghu1GrvadSaw6iW3Je6IcL5PNOw8VwjxqBECXy50/iCQSY/lQ== - dependencies: - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-remap-async-to-generator" "^7.22.20" - "@babel/plugin-syntax-async-generators" "^7.8.4" - -"@babel/plugin-transform-async-generator-functions@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz#93ac8e3531f347fba519b4703f9ff2a75c6ae27a" - integrity sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw== - dependencies: - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-remap-async-to-generator" "^7.22.20" - "@babel/plugin-syntax-async-generators" "^7.8.4" - -"@babel/plugin-transform-async-generator-functions@^7.23.9": +"@babel/plugin-transform-async-generator-functions@^7.23.9", "@babel/plugin-transform-async-generator-functions@^7.24.3": version "7.24.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.24.3.tgz#8fa7ae481b100768cc9842c8617808c5352b8b89" integrity sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg== @@ -1465,7 +1350,7 @@ "@babel/helper-remap-async-to-generator" "^7.22.20" "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-transform-async-to-generator@7.23.3", "@babel/plugin-transform-async-to-generator@^7.23.3": +"@babel/plugin-transform-async-to-generator@7.23.3": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz#d1f513c7a8a506d43f47df2bf25f9254b0b051fa" integrity sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw== @@ -1474,391 +1359,187 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-remap-async-to-generator" "^7.22.20" -"@babel/plugin-transform-async-to-generator@^7.20.7", "@babel/plugin-transform-async-to-generator@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz#c7a85f44e46f8952f6d27fe57c2ed3cc084c3775" - integrity sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ== +"@babel/plugin-transform-async-to-generator@^7.20.7", "@babel/plugin-transform-async-to-generator@^7.23.3", "@babel/plugin-transform-async-to-generator@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.1.tgz#0e220703b89f2216800ce7b1c53cb0cf521c37f4" + integrity sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw== dependencies: - "@babel/helper-module-imports" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-remap-async-to-generator" "^7.22.5" + "@babel/helper-module-imports" "^7.24.1" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-remap-async-to-generator" "^7.22.20" -"@babel/plugin-transform-block-scoped-functions@^7.18.6", "@babel/plugin-transform-block-scoped-functions@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz#27978075bfaeb9fa586d3cb63a3d30c1de580024" - integrity sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA== +"@babel/plugin-transform-block-scoped-functions@^7.18.6", "@babel/plugin-transform-block-scoped-functions@^7.23.3", "@babel/plugin-transform-block-scoped-functions@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.1.tgz#1c94799e20fcd5c4d4589523bbc57b7692979380" + integrity sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-block-scoped-functions@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz#fe1177d715fb569663095e04f3598525d98e8c77" - integrity sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A== +"@babel/plugin-transform-block-scoping@^7.21.0", "@babel/plugin-transform-block-scoping@^7.23.4", "@babel/plugin-transform-block-scoping@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.5.tgz#89574191397f85661d6f748d4b89ee4d9ee69a2a" + integrity sha512-sMfBc3OxghjC95BkYrYocHL3NaOplrcaunblzwXhGmlPwpmfsxr4vK+mBBt49r+S240vahmv+kUxkeKgs+haCw== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.5" -"@babel/plugin-transform-block-scoping@^7.21.0", "@babel/plugin-transform-block-scoping@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.0.tgz#8744d02c6c264d82e1a4bc5d2d501fd8aff6f022" - integrity sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g== +"@babel/plugin-transform-class-properties@^7.22.5", "@babel/plugin-transform-class-properties@^7.23.3", "@babel/plugin-transform-class-properties@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.24.1.tgz#bcbf1aef6ba6085cfddec9fc8d58871cf011fc29" + integrity sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.24.1" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-block-scoping@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz#b2d38589531c6c80fbe25e6b58e763622d2d3cf5" - integrity sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw== +"@babel/plugin-transform-class-static-block@^7.23.4", "@babel/plugin-transform-class-static-block@^7.24.4": + version "7.24.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.4.tgz#1a4653c0cf8ac46441ec406dece6e9bc590356a4" + integrity sha512-B8q7Pz870Hz/q9UgP8InNpY01CSLDSCyqX7zcRuv3FcPl87A2G17lASroHWaCtbdIcbYzOZ7kWmXFKbijMSmFg== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.24.4" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-class-static-block" "^7.14.5" -"@babel/plugin-transform-class-properties@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz#97a56e31ad8c9dc06a0b3710ce7803d5a48cca77" - integrity sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ== +"@babel/plugin-transform-classes@^7.21.0", "@babel/plugin-transform-classes@^7.23.8", "@babel/plugin-transform-classes@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.5.tgz#05e04a09df49a46348299a0e24bfd7e901129339" + integrity sha512-gWkLP25DFj2dwe9Ck8uwMOpko4YsqyfZJrOmqqcegeDYEbp7rmn4U6UQZNj08UF6MaX39XenSpKRCvpDRBtZ7Q== dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-plugin-utils" "^7.24.5" + "@babel/helper-replace-supers" "^7.24.1" + "@babel/helper-split-export-declaration" "^7.24.5" + globals "^11.1.0" -"@babel/plugin-transform-class-properties@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz#35c377db11ca92a785a718b6aa4e3ed1eb65dc48" - integrity sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-class-static-block@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz#dc8cc6e498f55692ac6b4b89e56d87cec766c974" - integrity sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.11" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - -"@babel/plugin-transform-class-static-block@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz#2a202c8787a8964dd11dfcedf994d36bfc844ab5" - integrity sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - -"@babel/plugin-transform-classes@^7.21.0", "@babel/plugin-transform-classes@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.15.tgz#aaf4753aee262a232bbc95451b4bdf9599c65a0b" - integrity sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" - "@babel/helper-optimise-call-expression" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.9" - "@babel/helper-split-export-declaration" "^7.22.6" - globals "^11.1.0" - -"@babel/plugin-transform-classes@^7.23.5", "@babel/plugin-transform-classes@^7.23.8": - version "7.23.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz#d08ae096c240347badd68cdf1b6d1624a6435d92" - integrity sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg== - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-compilation-targets" "^7.23.6" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-function-name" "^7.23.0" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.20" - "@babel/helper-split-export-declaration" "^7.22.6" - globals "^11.1.0" - -"@babel/plugin-transform-classes@^7.23.8": +"@babel/plugin-transform-computed-properties@^7.21.5", "@babel/plugin-transform-computed-properties@^7.23.3", "@babel/plugin-transform-computed-properties@^7.24.1": version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz#5bc8fc160ed96378184bc10042af47f50884dcb1" - integrity sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q== + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.1.tgz#bc7e787f8e021eccfb677af5f13c29a9934ed8a7" + integrity sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw== dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-compilation-targets" "^7.23.6" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-function-name" "^7.23.0" "@babel/helper-plugin-utils" "^7.24.0" - "@babel/helper-replace-supers" "^7.24.1" - "@babel/helper-split-export-declaration" "^7.22.6" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.21.5", "@babel/plugin-transform-computed-properties@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz#cd1e994bf9f316bd1c2dafcd02063ec261bb3869" - integrity sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/template" "^7.22.5" - -"@babel/plugin-transform-computed-properties@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz#652e69561fcc9d2b50ba4f7ac7f60dcf65e86474" - integrity sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/template" "^7.22.15" - -"@babel/plugin-transform-destructuring@^7.21.3", "@babel/plugin-transform-destructuring@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.0.tgz#6447aa686be48b32eaf65a73e0e2c0bd010a266c" - integrity sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-destructuring@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz#8c9ee68228b12ae3dff986e56ed1ba4f3c446311" - integrity sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/template" "^7.24.0" -"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.22.5", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz#dbb4f0e45766eb544e193fb00e65a1dd3b2a4165" - integrity sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw== +"@babel/plugin-transform-destructuring@^7.21.3", "@babel/plugin-transform-destructuring@^7.23.3", "@babel/plugin-transform-destructuring@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.5.tgz#80843ee6a520f7362686d1a97a7b53544ede453c" + integrity sha512-SZuuLyfxvsm+Ah57I/i1HVjveBENYK9ue8MJ7qkc7ndoNjqquJiElzA7f5yaAXjyW2hKojosOTAQQRX50bPSVg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.5" -"@babel/plugin-transform-dotall-regex@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz#3f7af6054882ede89c378d0cf889b854a993da50" - integrity sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ== +"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.23.3", "@babel/plugin-transform-dotall-regex@^7.24.1", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.1.tgz#d56913d2f12795cc9930801b84c6f8c47513ac13" + integrity sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-duplicate-keys@^7.18.9", "@babel/plugin-transform-duplicate-keys@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz#b6e6428d9416f5f0bba19c70d1e6e7e0b88ab285" - integrity sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-duplicate-keys@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz#664706ca0a5dfe8d066537f99032fc1dc8b720ce" - integrity sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-dynamic-import@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz#2c7722d2a5c01839eaf31518c6ff96d408e447aa" - integrity sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA== +"@babel/plugin-transform-duplicate-keys@^7.18.9", "@babel/plugin-transform-duplicate-keys@^7.23.3", "@babel/plugin-transform-duplicate-keys@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.1.tgz#5347a797fe82b8d09749d10e9f5b83665adbca88" + integrity sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-dynamic-import@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz#c7629e7254011ac3630d47d7f34ddd40ca535143" - integrity sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ== +"@babel/plugin-transform-dynamic-import@^7.23.4", "@babel/plugin-transform-dynamic-import@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.1.tgz#2a5a49959201970dd09a5fca856cb651e44439dd" + integrity sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-syntax-dynamic-import" "^7.8.3" -"@babel/plugin-transform-exponentiation-operator@^7.18.6", "@babel/plugin-transform-exponentiation-operator@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz#402432ad544a1f9a480da865fda26be653e48f6a" - integrity sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-exponentiation-operator@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz#ea0d978f6b9232ba4722f3dbecdd18f450babd18" - integrity sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ== +"@babel/plugin-transform-exponentiation-operator@^7.18.6", "@babel/plugin-transform-exponentiation-operator@^7.23.3", "@babel/plugin-transform-exponentiation-operator@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.1.tgz#6650ebeb5bd5c012d5f5f90a26613a08162e8ba4" + integrity sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw== dependencies: "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-export-namespace-from@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz#b3c84c8f19880b6c7440108f8929caf6056db26c" - integrity sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-export-namespace-from@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz#084c7b25e9a5c8271e987a08cf85807b80283191" - integrity sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ== +"@babel/plugin-transform-export-namespace-from@^7.23.4", "@babel/plugin-transform-export-namespace-from@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.1.tgz#f033541fc036e3efb2dcb58eedafd4f6b8078acd" + integrity sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-transform-flow-strip-types@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.22.5.tgz#0bb17110c7bf5b35a60754b2f00c58302381dee2" - integrity sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-flow" "^7.22.5" - -"@babel/plugin-transform-flow-strip-types@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.23.3.tgz#cfa7ca159cc3306fab526fc67091556b51af26ff" - integrity sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-flow" "^7.23.3" - -"@babel/plugin-transform-for-of@^7.21.5", "@babel/plugin-transform-for-of@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.15.tgz#f64b4ccc3a4f131a996388fae7680b472b306b29" - integrity sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA== +"@babel/plugin-transform-flow-strip-types@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.24.1.tgz#fa8d0a146506ea195da1671d38eed459242b2dcc" + integrity sha512-iIYPIWt3dUmUKKE10s3W+jsQ3icFkw0JyRVyY1B7G4yK/nngAOHLVx8xlhA6b/Jzl/Y0nis8gjqhqKtRDQqHWQ== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/plugin-syntax-flow" "^7.24.1" -"@babel/plugin-transform-for-of@^7.23.6": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz#81c37e24171b37b370ba6aaffa7ac86bcb46f94e" - integrity sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw== +"@babel/plugin-transform-for-of@^7.21.5", "@babel/plugin-transform-for-of@^7.23.6", "@babel/plugin-transform-for-of@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.1.tgz#67448446b67ab6c091360ce3717e7d3a59e202fd" + integrity sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" -"@babel/plugin-transform-function-name@^7.18.9", "@babel/plugin-transform-function-name@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz#935189af68b01898e0d6d99658db6b164205c143" - integrity sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg== - dependencies: - "@babel/helper-compilation-targets" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-function-name@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz#8f424fcd862bf84cb9a1a6b42bc2f47ed630f8dc" - integrity sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw== +"@babel/plugin-transform-function-name@^7.18.9", "@babel/plugin-transform-function-name@^7.23.3", "@babel/plugin-transform-function-name@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.24.1.tgz#8cba6f7730626cc4dfe4ca2fa516215a0592b361" + integrity sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA== dependencies: - "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-compilation-targets" "^7.23.6" "@babel/helper-function-name" "^7.23.0" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-json-strings@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz#689a34e1eed1928a40954e37f74509f48af67835" - integrity sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-json-strings@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz#a871d9b6bd171976efad2e43e694c961ffa3714d" - integrity sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg== +"@babel/plugin-transform-json-strings@^7.23.4", "@babel/plugin-transform-json-strings@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.1.tgz#08e6369b62ab3e8a7b61089151b161180c8299f7" + integrity sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-transform-literals@^7.18.9", "@babel/plugin-transform-literals@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz#e9341f4b5a167952576e23db8d435849b1dd7920" - integrity sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-literals@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz#8214665f00506ead73de157eba233e7381f3beb4" - integrity sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-logical-assignment-operators@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz#24c522a61688bde045b7d9bc3c2597a4d948fc9c" - integrity sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ== +"@babel/plugin-transform-literals@^7.18.9", "@babel/plugin-transform-literals@^7.23.3", "@babel/plugin-transform-literals@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.24.1.tgz#0a1982297af83e6b3c94972686067df588c5c096" + integrity sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-logical-assignment-operators@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz#e599f82c51d55fac725f62ce55d3a0886279ecb5" - integrity sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg== +"@babel/plugin-transform-logical-assignment-operators@^7.23.4", "@babel/plugin-transform-logical-assignment-operators@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.1.tgz#719d8aded1aa94b8fb34e3a785ae8518e24cfa40" + integrity sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-transform-member-expression-literals@^7.18.6", "@babel/plugin-transform-member-expression-literals@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz#4fcc9050eded981a468347dd374539ed3e058def" - integrity sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-member-expression-literals@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz#e37b3f0502289f477ac0e776b05a833d853cabcc" - integrity sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-modules-amd@^7.20.11", "@babel/plugin-transform-modules-amd@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.0.tgz#05b2bc43373faa6d30ca89214731f76f966f3b88" - integrity sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw== +"@babel/plugin-transform-member-expression-literals@^7.18.6", "@babel/plugin-transform-member-expression-literals@^7.23.3", "@babel/plugin-transform-member-expression-literals@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.1.tgz#896d23601c92f437af8b01371ad34beb75df4489" + integrity sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg== dependencies: - "@babel/helper-module-transforms" "^7.23.0" - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-modules-amd@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz#e19b55436a1416829df0a1afc495deedfae17f7d" - integrity sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw== +"@babel/plugin-transform-modules-amd@^7.20.11", "@babel/plugin-transform-modules-amd@^7.23.3", "@babel/plugin-transform-modules-amd@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.1.tgz#b6d829ed15258536977e9c7cc6437814871ffa39" + integrity sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ== dependencies: "@babel/helper-module-transforms" "^7.23.3" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-modules-commonjs@^7.13.8", "@babel/plugin-transform-modules-commonjs@^7.21.5", "@babel/plugin-transform-modules-commonjs@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz#b3dba4757133b2762c00f4f94590cf6d52602481" - integrity sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ== - dependencies: - "@babel/helper-module-transforms" "^7.23.0" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-modules-commonjs@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz#661ae831b9577e52be57dd8356b734f9700b53b4" - integrity sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA== +"@babel/plugin-transform-modules-commonjs@^7.13.8", "@babel/plugin-transform-modules-commonjs@^7.21.5", "@babel/plugin-transform-modules-commonjs@^7.23.0", "@babel/plugin-transform-modules-commonjs@^7.23.3", "@babel/plugin-transform-modules-commonjs@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz#e71ba1d0d69e049a22bf90b3867e263823d3f1b9" + integrity sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw== dependencies: "@babel/helper-module-transforms" "^7.23.3" - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/helper-simple-access" "^7.22.5" -"@babel/plugin-transform-modules-systemjs@^7.20.11", "@babel/plugin-transform-modules-systemjs@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.0.tgz#77591e126f3ff4132a40595a6cccd00a6b60d160" - integrity sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg== - dependencies: - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-module-transforms" "^7.23.0" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-identifier" "^7.22.20" - -"@babel/plugin-transform-modules-systemjs@^7.23.3", "@babel/plugin-transform-modules-systemjs@^7.23.9": - version "7.23.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz#105d3ed46e4a21d257f83a2f9e2ee4203ceda6be" - integrity sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw== - dependencies: - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-module-transforms" "^7.23.3" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-identifier" "^7.22.20" - -"@babel/plugin-transform-modules-systemjs@^7.23.9": +"@babel/plugin-transform-modules-systemjs@^7.20.11", "@babel/plugin-transform-modules-systemjs@^7.23.9", "@babel/plugin-transform-modules-systemjs@^7.24.1": version "7.24.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.24.1.tgz#2b9625a3d4e445babac9788daec39094e6b11e3e" integrity sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA== @@ -1868,21 +1549,13 @@ "@babel/helper-plugin-utils" "^7.24.0" "@babel/helper-validator-identifier" "^7.22.20" -"@babel/plugin-transform-modules-umd@^7.18.6", "@babel/plugin-transform-modules-umd@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz#4694ae40a87b1745e3775b6a7fe96400315d4f98" - integrity sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ== - dependencies: - "@babel/helper-module-transforms" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-modules-umd@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz#5d4395fccd071dfefe6585a4411aa7d6b7d769e9" - integrity sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg== +"@babel/plugin-transform-modules-umd@^7.18.6", "@babel/plugin-transform-modules-umd@^7.23.3", "@babel/plugin-transform-modules-umd@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.1.tgz#69220c66653a19cf2c0872b9c762b9a48b8bebef" + integrity sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg== dependencies: "@babel/helper-module-transforms" "^7.23.3" - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-transform-named-capturing-groups-regex@^7.20.5", "@babel/plugin-transform-named-capturing-groups-regex@^7.22.5": version "7.22.5" @@ -1892,234 +1565,110 @@ "@babel/helper-create-regexp-features-plugin" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-new-target@^7.18.6", "@babel/plugin-transform-new-target@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz#1b248acea54ce44ea06dfd37247ba089fcf9758d" - integrity sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-new-target@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz#5491bb78ed6ac87e990957cea367eab781c4d980" - integrity sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-nullish-coalescing-operator@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz#debef6c8ba795f5ac67cd861a81b744c5d38d9fc" - integrity sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg== +"@babel/plugin-transform-new-target@^7.18.6", "@babel/plugin-transform-new-target@^7.23.3", "@babel/plugin-transform-new-target@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.1.tgz#29c59988fa3d0157de1c871a28cd83096363cc34" + integrity sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-nullish-coalescing-operator@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz#45556aad123fc6e52189ea749e33ce090637346e" - integrity sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA== +"@babel/plugin-transform-nullish-coalescing-operator@^7.22.11", "@babel/plugin-transform-nullish-coalescing-operator@^7.23.4", "@babel/plugin-transform-nullish-coalescing-operator@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz#0cd494bb97cb07d428bd651632cb9d4140513988" + integrity sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-transform-numeric-separator@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz#498d77dc45a6c6db74bb829c02a01c1d719cbfbd" - integrity sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - -"@babel/plugin-transform-numeric-separator@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz#03d08e3691e405804ecdd19dd278a40cca531f29" - integrity sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q== +"@babel/plugin-transform-numeric-separator@^7.23.4", "@babel/plugin-transform-numeric-separator@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.1.tgz#5bc019ce5b3435c1cadf37215e55e433d674d4e8" + integrity sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-transform-object-rest-spread@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.15.tgz#21a95db166be59b91cde48775310c0df6e1da56f" - integrity sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q== +"@babel/plugin-transform-object-rest-spread@^7.24.0", "@babel/plugin-transform-object-rest-spread@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.5.tgz#f91bbcb092ff957c54b4091c86bda8372f0b10ef" + integrity sha512-7EauQHszLGM3ay7a161tTQH7fj+3vVM/gThlz5HpFtnygTxjrlvoeq7MPVA1Vy9Q555OB8SnAOsMkLShNkkrHA== dependencies: - "@babel/compat-data" "^7.22.9" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.22.15" - -"@babel/plugin-transform-object-rest-spread@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz#2b9c2d26bf62710460bdc0d1730d4f1048361b83" - integrity sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g== - dependencies: - "@babel/compat-data" "^7.23.3" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-plugin-utils" "^7.24.5" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.23.3" + "@babel/plugin-transform-parameters" "^7.24.5" -"@babel/plugin-transform-object-rest-spread@^7.24.0": +"@babel/plugin-transform-object-super@^7.18.6", "@babel/plugin-transform-object-super@^7.23.3", "@babel/plugin-transform-object-super@^7.24.1": version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz#5a3ce73caf0e7871a02e1c31e8b473093af241ff" - integrity sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA== + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.1.tgz#e71d6ab13483cca89ed95a474f542bbfc20a0520" + integrity sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ== dependencies: - "@babel/helper-compilation-targets" "^7.23.6" "@babel/helper-plugin-utils" "^7.24.0" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.24.1" - -"@babel/plugin-transform-object-super@^7.18.6", "@babel/plugin-transform-object-super@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz#794a8d2fcb5d0835af722173c1a9d704f44e218c" - integrity sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.5" - -"@babel/plugin-transform-object-super@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz#81fdb636dcb306dd2e4e8fd80db5b2362ed2ebcd" - integrity sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.20" - -"@babel/plugin-transform-optional-catch-binding@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz#461cc4f578a127bb055527b3e77404cad38c08e0" - integrity sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/helper-replace-supers" "^7.24.1" -"@babel/plugin-transform-optional-catch-binding@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz#318066de6dacce7d92fa244ae475aa8d91778017" - integrity sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A== +"@babel/plugin-transform-optional-catch-binding@^7.23.4", "@babel/plugin-transform-optional-catch-binding@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.1.tgz#92a3d0efe847ba722f1a4508669b23134669e2da" + integrity sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-transform-optional-chaining@^7.22.15", "@babel/plugin-transform-optional-chaining@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.0.tgz#73ff5fc1cf98f542f09f29c0631647d8ad0be158" - integrity sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g== +"@babel/plugin-transform-optional-chaining@^7.23.0", "@babel/plugin-transform-optional-chaining@^7.23.4", "@babel/plugin-transform-optional-chaining@^7.24.1", "@babel/plugin-transform-optional-chaining@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.5.tgz#a6334bebd7f9dd3df37447880d0bd64b778e600f" + integrity sha512-xWCkmwKT+ihmA6l7SSTpk8e4qQl/274iNbSKRRS8mpqFR32ksy36+a+LWY8OXCCEefF8WFlnOHVsaDI2231wBg== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.5" "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-transform-optional-chaining@^7.23.3", "@babel/plugin-transform-optional-chaining@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz#6acf61203bdfc4de9d4e52e64490aeb3e52bd017" - integrity sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - -"@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.21.3", "@babel/plugin-transform-parameters@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.15.tgz#719ca82a01d177af358df64a514d64c2e3edb114" - integrity sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-parameters@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz#83ef5d1baf4b1072fa6e54b2b0999a7b2527e2af" - integrity sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw== +"@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.21.3", "@babel/plugin-transform-parameters@^7.23.3", "@babel/plugin-transform-parameters@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.5.tgz#5c3b23f3a6b8fed090f9b98f2926896d3153cc62" + integrity sha512-9Co00MqZ2aoky+4j2jhofErthm6QVLKbpQrvz20c3CH9KQCLHyNB+t2ya4/UrRpQGR+Wrwjg9foopoeSdnHOkA== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.5" -"@babel/plugin-transform-parameters@^7.24.1": +"@babel/plugin-transform-private-methods@^7.22.5", "@babel/plugin-transform-private-methods@^7.23.3", "@babel/plugin-transform-private-methods@^7.24.1": version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz#983c15d114da190506c75b616ceb0f817afcc510" - integrity sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg== + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz#a0faa1ae87eff077e1e47a5ec81c3aef383dc15a" + integrity sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw== dependencies: + "@babel/helper-create-class-features-plugin" "^7.24.1" "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-private-methods@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz#21c8af791f76674420a147ae62e9935d790f8722" - integrity sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-private-methods@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz#b2d7a3c97e278bfe59137a978d53b2c2e038c0e4" - integrity sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-private-property-in-object@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz#ad45c4fc440e9cb84c718ed0906d96cf40f9a4e1" - integrity sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ== +"@babel/plugin-transform-private-property-in-object@^7.23.4", "@babel/plugin-transform-private-property-in-object@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.5.tgz#f5d1fcad36e30c960134cb479f1ca98a5b06eda5" + integrity sha512-JM4MHZqnWR04jPMujQDTBVRnqxpLLpx2tkn7iPn+Hmsc0Gnb79yvRWOkvqFOx3Z7P7VxiRIR22c4eGSNj87OBQ== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-create-class-features-plugin" "^7.22.11" - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.24.5" + "@babel/helper-plugin-utils" "^7.24.5" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-transform-private-property-in-object@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz#3ec711d05d6608fd173d9b8de39872d8dbf68bf5" - integrity sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-create-class-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - -"@babel/plugin-transform-property-literals@^7.18.6", "@babel/plugin-transform-property-literals@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz#b5ddabd73a4f7f26cd0e20f5db48290b88732766" - integrity sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-property-literals@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz#54518f14ac4755d22b92162e4a852d308a560875" - integrity sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-regenerator@^7.21.5", "@babel/plugin-transform-regenerator@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz#8ceef3bd7375c4db7652878b0241b2be5d0c3cca" - integrity sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw== +"@babel/plugin-transform-property-literals@^7.18.6", "@babel/plugin-transform-property-literals@^7.23.3", "@babel/plugin-transform-property-literals@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.1.tgz#d6a9aeab96f03749f4eebeb0b6ea8e90ec958825" + integrity sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - regenerator-transform "^0.15.2" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-regenerator@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz#141afd4a2057298602069fce7f2dc5173e6c561c" - integrity sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ== +"@babel/plugin-transform-regenerator@^7.21.5", "@babel/plugin-transform-regenerator@^7.23.3", "@babel/plugin-transform-regenerator@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.1.tgz#625b7545bae52363bdc1fbbdc7252b5046409c8c" + integrity sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" regenerator-transform "^0.15.2" -"@babel/plugin-transform-reserved-words@^7.18.6", "@babel/plugin-transform-reserved-words@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz#832cd35b81c287c4bcd09ce03e22199641f964fb" - integrity sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-reserved-words@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz#4130dcee12bd3dd5705c587947eb715da12efac8" - integrity sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg== +"@babel/plugin-transform-reserved-words@^7.18.6", "@babel/plugin-transform-reserved-words@^7.23.3", "@babel/plugin-transform-reserved-words@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.1.tgz#8de729f5ecbaaf5cf83b67de13bad38a21be57c1" + integrity sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-transform-runtime@7.24.0": version "7.24.0" @@ -2133,352 +1682,103 @@ babel-plugin-polyfill-regenerator "^0.5.5" semver "^6.3.1" -"@babel/plugin-transform-runtime@^7.22.9": - version "7.23.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.9.tgz#2c64d0680fc8e09e1dfe8fd5c646fe72abd82004" - integrity sha512-A7clW3a0aSjm3ONU9o2HAILSegJCYlEZmOhmBRReVtIpY/Z/p7yIZ+wR41Z+UipwdGuqwtID/V/dOdZXjwi9gQ== +"@babel/plugin-transform-runtime@^7.23.2": + version "7.24.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.24.3.tgz#dc58ad4a31810a890550365cc922e1ff5acb5d7f" + integrity sha512-J0BuRPNlNqlMTRJ72eVptpt9VcInbxO6iP3jaxr+1NPhC0UkKL+6oeX6VXMEYdADnuqmMmsBspt4d5w8Y/TCbQ== dependencies: - "@babel/helper-module-imports" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - babel-plugin-polyfill-corejs2 "^0.4.8" - babel-plugin-polyfill-corejs3 "^0.9.0" - babel-plugin-polyfill-regenerator "^0.5.5" + "@babel/helper-module-imports" "^7.24.3" + "@babel/helper-plugin-utils" "^7.24.0" + babel-plugin-polyfill-corejs2 "^0.4.10" + babel-plugin-polyfill-corejs3 "^0.10.1" + babel-plugin-polyfill-regenerator "^0.6.1" semver "^6.3.1" -"@babel/plugin-transform-shorthand-properties@^7.18.6", "@babel/plugin-transform-shorthand-properties@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz#6e277654be82b5559fc4b9f58088507c24f0c624" - integrity sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-shorthand-properties@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz#97d82a39b0e0c24f8a981568a8ed851745f59210" - integrity sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-spread@^7.20.7", "@babel/plugin-transform-spread@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz#6487fd29f229c95e284ba6c98d65eafb893fea6b" - integrity sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg== +"@babel/plugin-transform-shorthand-properties@^7.18.6", "@babel/plugin-transform-shorthand-properties@^7.23.3", "@babel/plugin-transform-shorthand-properties@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.1.tgz#ba9a09144cf55d35ec6b93a32253becad8ee5b55" + integrity sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-spread@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz#41d17aacb12bde55168403c6f2d6bdca563d362c" - integrity sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg== +"@babel/plugin-transform-spread@^7.20.7", "@babel/plugin-transform-spread@^7.23.3", "@babel/plugin-transform-spread@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.1.tgz#a1acf9152cbf690e4da0ba10790b3ac7d2b2b391" + integrity sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" -"@babel/plugin-transform-sticky-regex@^7.18.6", "@babel/plugin-transform-sticky-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz#295aba1595bfc8197abd02eae5fc288c0deb26aa" - integrity sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-sticky-regex@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz#dec45588ab4a723cb579c609b294a3d1bd22ff04" - integrity sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-template-literals@^7.18.9", "@babel/plugin-transform-template-literals@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz#8f38cf291e5f7a8e60e9f733193f0bcc10909bff" - integrity sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-template-literals@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz#5f0f028eb14e50b5d0f76be57f90045757539d07" - integrity sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-typeof-symbol@^7.18.9", "@babel/plugin-transform-typeof-symbol@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz#5e2ba478da4b603af8673ff7c54f75a97b716b34" - integrity sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-typeof-symbol@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz#9dfab97acc87495c0c449014eb9c547d8966bca4" - integrity sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-typescript@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.15.tgz#15adef906451d86349eb4b8764865c960eb54127" - integrity sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-create-class-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-typescript" "^7.22.5" - -"@babel/plugin-transform-typescript@^7.23.3": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz#aa36a94e5da8d94339ae3a4e22d40ed287feb34c" - integrity sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-create-class-features-plugin" "^7.23.6" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-typescript" "^7.23.3" - -"@babel/plugin-transform-unicode-escapes@^7.21.5", "@babel/plugin-transform-unicode-escapes@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz#c723f380f40a2b2f57a62df24c9005834c8616d9" - integrity sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-unicode-escapes@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz#1f66d16cab01fab98d784867d24f70c1ca65b925" - integrity sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-unicode-property-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz#098898f74d5c1e86660dc112057b2d11227f1c81" - integrity sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-unicode-property-regex@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz#19e234129e5ffa7205010feec0d94c251083d7ad" - integrity sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-transform-unicode-regex@^7.18.6", "@babel/plugin-transform-unicode-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz#ce7e7bb3ef208c4ff67e02a22816656256d7a183" - integrity sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg== +"@babel/plugin-transform-sticky-regex@^7.18.6", "@babel/plugin-transform-sticky-regex@^7.23.3", "@babel/plugin-transform-sticky-regex@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.1.tgz#f03e672912c6e203ed8d6e0271d9c2113dc031b9" + integrity sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-unicode-regex@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz#26897708d8f42654ca4ce1b73e96140fbad879dc" - integrity sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw== +"@babel/plugin-transform-template-literals@^7.18.9", "@babel/plugin-transform-template-literals@^7.23.3", "@babel/plugin-transform-template-literals@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.1.tgz#15e2166873a30d8617e3e2ccadb86643d327aab7" + integrity sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-unicode-sets-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz#77788060e511b708ffc7d42fdfbc5b37c3004e91" - integrity sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg== +"@babel/plugin-transform-typeof-symbol@^7.18.9", "@babel/plugin-transform-typeof-symbol@^7.23.3", "@babel/plugin-transform-typeof-symbol@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.5.tgz#703cace5ef74155fb5eecab63cbfc39bdd25fe12" + integrity sha512-UTGnhYVZtTAjdwOTzT+sCyXmTn8AhaxOS/MjG9REclZ6ULHWF9KoCZur0HSGU7hk8PdBFKKbYe6+gqdXWz84Jg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.5" -"@babel/plugin-transform-unicode-sets-regex@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz#4fb6f0a719c2c5859d11f6b55a050cc987f3799e" - integrity sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/preset-env@7.24.0": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.24.0.tgz#11536a7f4b977294f0bdfad780f01a8ac8e183fc" - integrity sha512-ZxPEzV9IgvGn73iK0E6VB9/95Nd7aMFpbE0l8KQFDG70cOV9IxRP7Y2FUPmlK0v6ImlLqYX50iuZ3ZTVhOF2lA== - dependencies: - "@babel/compat-data" "^7.23.5" - "@babel/helper-compilation-targets" "^7.23.6" - "@babel/helper-plugin-utils" "^7.24.0" - "@babel/helper-validator-option" "^7.23.5" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.23.3" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.23.3" - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.23.7" - "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.23.3" - "@babel/plugin-syntax-import-attributes" "^7.23.3" - "@babel/plugin-syntax-import-meta" "^7.10.4" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" - "@babel/plugin-transform-arrow-functions" "^7.23.3" - "@babel/plugin-transform-async-generator-functions" "^7.23.9" - "@babel/plugin-transform-async-to-generator" "^7.23.3" - "@babel/plugin-transform-block-scoped-functions" "^7.23.3" - "@babel/plugin-transform-block-scoping" "^7.23.4" - "@babel/plugin-transform-class-properties" "^7.23.3" - "@babel/plugin-transform-class-static-block" "^7.23.4" - "@babel/plugin-transform-classes" "^7.23.8" - "@babel/plugin-transform-computed-properties" "^7.23.3" - "@babel/plugin-transform-destructuring" "^7.23.3" - "@babel/plugin-transform-dotall-regex" "^7.23.3" - "@babel/plugin-transform-duplicate-keys" "^7.23.3" - "@babel/plugin-transform-dynamic-import" "^7.23.4" - "@babel/plugin-transform-exponentiation-operator" "^7.23.3" - "@babel/plugin-transform-export-namespace-from" "^7.23.4" - "@babel/plugin-transform-for-of" "^7.23.6" - "@babel/plugin-transform-function-name" "^7.23.3" - "@babel/plugin-transform-json-strings" "^7.23.4" - "@babel/plugin-transform-literals" "^7.23.3" - "@babel/plugin-transform-logical-assignment-operators" "^7.23.4" - "@babel/plugin-transform-member-expression-literals" "^7.23.3" - "@babel/plugin-transform-modules-amd" "^7.23.3" - "@babel/plugin-transform-modules-commonjs" "^7.23.3" - "@babel/plugin-transform-modules-systemjs" "^7.23.9" - "@babel/plugin-transform-modules-umd" "^7.23.3" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" - "@babel/plugin-transform-new-target" "^7.23.3" - "@babel/plugin-transform-nullish-coalescing-operator" "^7.23.4" - "@babel/plugin-transform-numeric-separator" "^7.23.4" - "@babel/plugin-transform-object-rest-spread" "^7.24.0" - "@babel/plugin-transform-object-super" "^7.23.3" - "@babel/plugin-transform-optional-catch-binding" "^7.23.4" - "@babel/plugin-transform-optional-chaining" "^7.23.4" - "@babel/plugin-transform-parameters" "^7.23.3" - "@babel/plugin-transform-private-methods" "^7.23.3" - "@babel/plugin-transform-private-property-in-object" "^7.23.4" - "@babel/plugin-transform-property-literals" "^7.23.3" - "@babel/plugin-transform-regenerator" "^7.23.3" - "@babel/plugin-transform-reserved-words" "^7.23.3" - "@babel/plugin-transform-shorthand-properties" "^7.23.3" - "@babel/plugin-transform-spread" "^7.23.3" - "@babel/plugin-transform-sticky-regex" "^7.23.3" - "@babel/plugin-transform-template-literals" "^7.23.3" - "@babel/plugin-transform-typeof-symbol" "^7.23.3" - "@babel/plugin-transform-unicode-escapes" "^7.23.3" - "@babel/plugin-transform-unicode-property-regex" "^7.23.3" - "@babel/plugin-transform-unicode-regex" "^7.23.3" - "@babel/plugin-transform-unicode-sets-regex" "^7.23.3" - "@babel/preset-modules" "0.1.6-no-external-plugins" - babel-plugin-polyfill-corejs2 "^0.4.8" - babel-plugin-polyfill-corejs3 "^0.9.0" - babel-plugin-polyfill-regenerator "^0.5.5" - core-js-compat "^3.31.0" - semver "^6.3.1" +"@babel/plugin-transform-typescript@^7.24.1": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.24.5.tgz#bcba979e462120dc06a75bd34c473a04781931b8" + integrity sha512-E0VWu/hk83BIFUWnsKZ4D81KXjN5L3MobvevOHErASk9IPwKHOkTgvqzvNo1yP/ePJWqqK2SpUR5z+KQbl6NVw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.24.5" + "@babel/helper-plugin-utils" "^7.24.5" + "@babel/plugin-syntax-typescript" "^7.24.1" -"@babel/preset-env@^7.20.2": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.23.2.tgz#1f22be0ff0e121113260337dbc3e58fafce8d059" - integrity sha512-BW3gsuDD+rvHL2VO2SjAUNTBe5YrjsTiDyqamPDWY723na3/yPQ65X5oQkFVJZ0o50/2d+svm1rkPoJeR1KxVQ== +"@babel/plugin-transform-unicode-escapes@^7.21.5", "@babel/plugin-transform-unicode-escapes@^7.23.3", "@babel/plugin-transform-unicode-escapes@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.1.tgz#fb3fa16676549ac7c7449db9b342614985c2a3a4" + integrity sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw== dependencies: - "@babel/compat-data" "^7.23.2" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.22.15" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.22.15" - "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.22.5" - "@babel/plugin-syntax-import-attributes" "^7.22.5" - "@babel/plugin-syntax-import-meta" "^7.10.4" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" - "@babel/plugin-transform-arrow-functions" "^7.22.5" - "@babel/plugin-transform-async-generator-functions" "^7.23.2" - "@babel/plugin-transform-async-to-generator" "^7.22.5" - "@babel/plugin-transform-block-scoped-functions" "^7.22.5" - "@babel/plugin-transform-block-scoping" "^7.23.0" - "@babel/plugin-transform-class-properties" "^7.22.5" - "@babel/plugin-transform-class-static-block" "^7.22.11" - "@babel/plugin-transform-classes" "^7.22.15" - "@babel/plugin-transform-computed-properties" "^7.22.5" - "@babel/plugin-transform-destructuring" "^7.23.0" - "@babel/plugin-transform-dotall-regex" "^7.22.5" - "@babel/plugin-transform-duplicate-keys" "^7.22.5" - "@babel/plugin-transform-dynamic-import" "^7.22.11" - "@babel/plugin-transform-exponentiation-operator" "^7.22.5" - "@babel/plugin-transform-export-namespace-from" "^7.22.11" - "@babel/plugin-transform-for-of" "^7.22.15" - "@babel/plugin-transform-function-name" "^7.22.5" - "@babel/plugin-transform-json-strings" "^7.22.11" - "@babel/plugin-transform-literals" "^7.22.5" - "@babel/plugin-transform-logical-assignment-operators" "^7.22.11" - "@babel/plugin-transform-member-expression-literals" "^7.22.5" - "@babel/plugin-transform-modules-amd" "^7.23.0" - "@babel/plugin-transform-modules-commonjs" "^7.23.0" - "@babel/plugin-transform-modules-systemjs" "^7.23.0" - "@babel/plugin-transform-modules-umd" "^7.22.5" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" - "@babel/plugin-transform-new-target" "^7.22.5" - "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.11" - "@babel/plugin-transform-numeric-separator" "^7.22.11" - "@babel/plugin-transform-object-rest-spread" "^7.22.15" - "@babel/plugin-transform-object-super" "^7.22.5" - "@babel/plugin-transform-optional-catch-binding" "^7.22.11" - "@babel/plugin-transform-optional-chaining" "^7.23.0" - "@babel/plugin-transform-parameters" "^7.22.15" - "@babel/plugin-transform-private-methods" "^7.22.5" - "@babel/plugin-transform-private-property-in-object" "^7.22.11" - "@babel/plugin-transform-property-literals" "^7.22.5" - "@babel/plugin-transform-regenerator" "^7.22.10" - "@babel/plugin-transform-reserved-words" "^7.22.5" - "@babel/plugin-transform-shorthand-properties" "^7.22.5" - "@babel/plugin-transform-spread" "^7.22.5" - "@babel/plugin-transform-sticky-regex" "^7.22.5" - "@babel/plugin-transform-template-literals" "^7.22.5" - "@babel/plugin-transform-typeof-symbol" "^7.22.5" - "@babel/plugin-transform-unicode-escapes" "^7.22.10" - "@babel/plugin-transform-unicode-property-regex" "^7.22.5" - "@babel/plugin-transform-unicode-regex" "^7.22.5" - "@babel/plugin-transform-unicode-sets-regex" "^7.22.5" - "@babel/preset-modules" "0.1.6-no-external-plugins" - "@babel/types" "^7.23.0" - babel-plugin-polyfill-corejs2 "^0.4.6" - babel-plugin-polyfill-corejs3 "^0.8.5" - babel-plugin-polyfill-regenerator "^0.5.3" - core-js-compat "^3.31.0" - semver "^6.3.1" + "@babel/helper-plugin-utils" "^7.24.0" -"@babel/preset-env@^7.22.9", "@babel/preset-env@^7.23.2": - version "7.23.9" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.23.9.tgz#beace3b7994560ed6bf78e4ae2073dff45387669" - integrity sha512-3kBGTNBBk9DQiPoXYS0g0BYlwTQYUTifqgKTjxUwEUkduRT2QOa0FPGBJ+NROQhGyYO5BuTJwGvBnqKDykac6A== +"@babel/plugin-transform-unicode-property-regex@^7.23.3", "@babel/plugin-transform-unicode-property-regex@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.1.tgz#56704fd4d99da81e5e9f0c0c93cabd91dbc4889e" + integrity sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-unicode-regex@^7.18.6", "@babel/plugin-transform-unicode-regex@^7.23.3", "@babel/plugin-transform-unicode-regex@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.1.tgz#57c3c191d68f998ac46b708380c1ce4d13536385" + integrity sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/plugin-transform-unicode-sets-regex@^7.23.3", "@babel/plugin-transform-unicode-sets-regex@^7.24.1": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.24.1.tgz#c1ea175b02afcffc9cf57a9c4658326625165b7f" + integrity sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.24.0" + +"@babel/preset-env@7.24.0": + version "7.24.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.24.0.tgz#11536a7f4b977294f0bdfad780f01a8ac8e183fc" + integrity sha512-ZxPEzV9IgvGn73iK0E6VB9/95Nd7aMFpbE0l8KQFDG70cOV9IxRP7Y2FUPmlK0v6ImlLqYX50iuZ3ZTVhOF2lA== dependencies: "@babel/compat-data" "^7.23.5" "@babel/helper-compilation-targets" "^7.23.6" - "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-plugin-utils" "^7.24.0" "@babel/helper-validator-option" "^7.23.5" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.23.3" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.23.3" @@ -2531,7 +1831,7 @@ "@babel/plugin-transform-new-target" "^7.23.3" "@babel/plugin-transform-nullish-coalescing-operator" "^7.23.4" "@babel/plugin-transform-numeric-separator" "^7.23.4" - "@babel/plugin-transform-object-rest-spread" "^7.23.4" + "@babel/plugin-transform-object-rest-spread" "^7.24.0" "@babel/plugin-transform-object-super" "^7.23.3" "@babel/plugin-transform-optional-catch-binding" "^7.23.4" "@babel/plugin-transform-optional-chaining" "^7.23.4" @@ -2557,6 +1857,93 @@ core-js-compat "^3.31.0" semver "^6.3.1" +"@babel/preset-env@^7.20.2", "@babel/preset-env@^7.23.2": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.24.5.tgz#6a9ac90bd5a5a9dae502af60dfc58c190551bbcd" + integrity sha512-UGK2ifKtcC8i5AI4cH+sbLLuLc2ktYSFJgBAXorKAsHUZmrQ1q6aQ6i3BvU24wWs2AAKqQB6kq3N9V9Gw1HiMQ== + dependencies: + "@babel/compat-data" "^7.24.4" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-plugin-utils" "^7.24.5" + "@babel/helper-validator-option" "^7.23.5" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.24.5" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.24.1" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.24.1" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.24.1" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-import-assertions" "^7.24.1" + "@babel/plugin-syntax-import-attributes" "^7.24.1" + "@babel/plugin-syntax-import-meta" "^7.10.4" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.24.1" + "@babel/plugin-transform-async-generator-functions" "^7.24.3" + "@babel/plugin-transform-async-to-generator" "^7.24.1" + "@babel/plugin-transform-block-scoped-functions" "^7.24.1" + "@babel/plugin-transform-block-scoping" "^7.24.5" + "@babel/plugin-transform-class-properties" "^7.24.1" + "@babel/plugin-transform-class-static-block" "^7.24.4" + "@babel/plugin-transform-classes" "^7.24.5" + "@babel/plugin-transform-computed-properties" "^7.24.1" + "@babel/plugin-transform-destructuring" "^7.24.5" + "@babel/plugin-transform-dotall-regex" "^7.24.1" + "@babel/plugin-transform-duplicate-keys" "^7.24.1" + "@babel/plugin-transform-dynamic-import" "^7.24.1" + "@babel/plugin-transform-exponentiation-operator" "^7.24.1" + "@babel/plugin-transform-export-namespace-from" "^7.24.1" + "@babel/plugin-transform-for-of" "^7.24.1" + "@babel/plugin-transform-function-name" "^7.24.1" + "@babel/plugin-transform-json-strings" "^7.24.1" + "@babel/plugin-transform-literals" "^7.24.1" + "@babel/plugin-transform-logical-assignment-operators" "^7.24.1" + "@babel/plugin-transform-member-expression-literals" "^7.24.1" + "@babel/plugin-transform-modules-amd" "^7.24.1" + "@babel/plugin-transform-modules-commonjs" "^7.24.1" + "@babel/plugin-transform-modules-systemjs" "^7.24.1" + "@babel/plugin-transform-modules-umd" "^7.24.1" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" + "@babel/plugin-transform-new-target" "^7.24.1" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.24.1" + "@babel/plugin-transform-numeric-separator" "^7.24.1" + "@babel/plugin-transform-object-rest-spread" "^7.24.5" + "@babel/plugin-transform-object-super" "^7.24.1" + "@babel/plugin-transform-optional-catch-binding" "^7.24.1" + "@babel/plugin-transform-optional-chaining" "^7.24.5" + "@babel/plugin-transform-parameters" "^7.24.5" + "@babel/plugin-transform-private-methods" "^7.24.1" + "@babel/plugin-transform-private-property-in-object" "^7.24.5" + "@babel/plugin-transform-property-literals" "^7.24.1" + "@babel/plugin-transform-regenerator" "^7.24.1" + "@babel/plugin-transform-reserved-words" "^7.24.1" + "@babel/plugin-transform-shorthand-properties" "^7.24.1" + "@babel/plugin-transform-spread" "^7.24.1" + "@babel/plugin-transform-sticky-regex" "^7.24.1" + "@babel/plugin-transform-template-literals" "^7.24.1" + "@babel/plugin-transform-typeof-symbol" "^7.24.5" + "@babel/plugin-transform-unicode-escapes" "^7.24.1" + "@babel/plugin-transform-unicode-property-regex" "^7.24.1" + "@babel/plugin-transform-unicode-regex" "^7.24.1" + "@babel/plugin-transform-unicode-sets-regex" "^7.24.1" + "@babel/preset-modules" "0.1.6-no-external-plugins" + babel-plugin-polyfill-corejs2 "^0.4.10" + babel-plugin-polyfill-corejs3 "^0.10.4" + babel-plugin-polyfill-regenerator "^0.6.1" + core-js-compat "^3.31.0" + semver "^6.3.1" + "@babel/preset-env@~7.21.0": version "7.21.5" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.21.5.tgz#db2089d99efd2297716f018aeead815ac3decffb" @@ -2639,23 +2026,14 @@ core-js-compat "^3.25.1" semver "^6.3.0" -"@babel/preset-flow@^7.13.13": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.22.15.tgz#30318deb9b3ebd9f5738e96da03a531e0cd3165d" - integrity sha512-dB5aIMqpkgbTfN5vDdTRPzjqtWiZcRESNR88QYnoPR+bmdYoluOzMX9tQerTv0XzSgZYctPfO1oc0N5zdog1ew== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-transform-flow-strip-types" "^7.22.5" - -"@babel/preset-flow@^7.22.15": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.23.3.tgz#8084e08b9ccec287bd077ab288b286fab96ffab1" - integrity sha512-7yn6hl8RIv+KNk6iIrGZ+D06VhVY35wLVf23Cz/mMu1zOr7u4MMP4j0nZ9tLf8+4ZFpnib8cFYgB/oYg9hfswA== +"@babel/preset-flow@^7.13.13", "@babel/preset-flow@^7.22.15": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.24.1.tgz#da7196c20c2d7dd4e98cfd8b192fe53b5eb6f0bb" + integrity sha512-sWCV2G9pcqZf+JHyv/RyqEIpFypxdCSxWIxQjpdaQxenNog7cN1pr76hg8u0Fz8Qgg0H4ETkGcJnXL8d4j0PPA== dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-transform-flow-strip-types" "^7.23.3" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-validator-option" "^7.23.5" + "@babel/plugin-transform-flow-strip-types" "^7.24.1" "@babel/preset-modules@0.1.6-no-external-plugins": version "0.1.6-no-external-plugins" @@ -2677,40 +2055,18 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/preset-typescript@^7.13.0", "@babel/preset-typescript@^7.22.5": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.23.2.tgz#c8de488130b7081f7e1482936ad3de5b018beef4" - integrity sha512-u4UJc1XsS1GhIGteM8rnGiIvf9rJpiVgMEeCnwlLA7WJPC+jcXWJAGxYmeqs5hOZD8BbAfnV5ezBOxQbb4OUxA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-syntax-jsx" "^7.22.5" - "@babel/plugin-transform-modules-commonjs" "^7.23.0" - "@babel/plugin-transform-typescript" "^7.22.15" - -"@babel/preset-typescript@^7.23.0": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz#14534b34ed5b6d435aa05f1ae1c5e7adcc01d913" - integrity sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-syntax-jsx" "^7.23.3" - "@babel/plugin-transform-modules-commonjs" "^7.23.3" - "@babel/plugin-transform-typescript" "^7.23.3" - -"@babel/register@^7.13.16": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.22.15.tgz#c2c294a361d59f5fa7bcc8b97ef7319c32ecaec7" - integrity sha512-V3Q3EqoQdn65RCgTLwauZaTfd1ShhwPmbBv+1dkZV/HpCGMKVyn6oFcRlI7RaKqiDQjX2Qd3AuoEguBgdjIKlg== +"@babel/preset-typescript@^7.13.0", "@babel/preset-typescript@^7.22.5", "@babel/preset-typescript@^7.23.0": + version "7.24.1" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.24.1.tgz#89bdf13a3149a17b3b2a2c9c62547f06db8845ec" + integrity sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ== dependencies: - clone-deep "^4.0.1" - find-cache-dir "^2.0.0" - make-dir "^2.1.0" - pirates "^4.0.5" - source-map-support "^0.5.16" + "@babel/helper-plugin-utils" "^7.24.0" + "@babel/helper-validator-option" "^7.23.5" + "@babel/plugin-syntax-jsx" "^7.24.1" + "@babel/plugin-transform-modules-commonjs" "^7.24.1" + "@babel/plugin-transform-typescript" "^7.24.1" -"@babel/register@^7.22.15": +"@babel/register@^7.13.16", "@babel/register@^7.22.15": version "7.23.7" resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.23.7.tgz#485a5e7951939d21304cae4af1719fdb887bc038" integrity sha512-EjJeB6+kvpk+Y5DAkEAmbOBEFkh9OASx0huoEkqYTFxAZHzOAX2Oh5uwAUuL2rUddqfM0SA+KPXV2TbzoZ2kvQ== @@ -2734,31 +2090,13 @@ regenerator-runtime "^0.14.0" "@babel/runtime@^7.13.10", "@babel/runtime@^7.17.8", "@babel/runtime@^7.22.6", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" - integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg== + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.5.tgz#230946857c053a36ccc66e1dd03b17dd0c4ed02c" + integrity sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g== dependencies: regenerator-runtime "^0.14.0" -"@babel/template@^7.20.7", "@babel/template@^7.22.15", "@babel/template@^7.22.5", "@babel/template@^7.3.3": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" - integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== - dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/parser" "^7.22.15" - "@babel/types" "^7.22.15" - -"@babel/template@^7.23.9": - version "7.23.9" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.23.9.tgz#f881d0487cba2828d3259dcb9ef5005a9731011a" - integrity sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA== - dependencies: - "@babel/code-frame" "^7.23.5" - "@babel/parser" "^7.23.9" - "@babel/types" "^7.23.9" - -"@babel/template@^7.24.0": +"@babel/template@^7.20.7", "@babel/template@^7.22.15", "@babel/template@^7.23.9", "@babel/template@^7.24.0", "@babel/template@^7.3.3": version "7.24.0" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.0.tgz#c6a524aa93a4a05d66aaf31654258fae69d87d50" integrity sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA== @@ -2767,7 +2105,7 @@ "@babel/parser" "^7.24.0" "@babel/types" "^7.24.0" -"@babel/traverse@7.23.2", "@babel/traverse@^7.16.0", "@babel/traverse@^7.21.5", "@babel/traverse@^7.23.2": +"@babel/traverse@7.23.2": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== @@ -2783,51 +2121,19 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/traverse@^7.23.6": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.6.tgz#b53526a2367a0dd6edc423637f3d2d0f2521abc5" - integrity sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ== - dependencies: - "@babel/code-frame" "^7.23.5" - "@babel/generator" "^7.23.6" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-function-name" "^7.23.0" - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.23.6" - "@babel/types" "^7.23.6" - debug "^4.3.1" - globals "^11.1.0" - -"@babel/traverse@^7.23.9": - version "7.23.9" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.9.tgz#2f9d6aead6b564669394c5ce0f9302bb65b9d950" - integrity sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg== - dependencies: - "@babel/code-frame" "^7.23.5" - "@babel/generator" "^7.23.6" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-function-name" "^7.23.0" - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.23.9" - "@babel/types" "^7.23.9" - debug "^4.3.1" - globals "^11.1.0" - -"@babel/traverse@^7.24.0", "@babel/traverse@^7.24.1": - version "7.24.1" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.1.tgz#d65c36ac9dd17282175d1e4a3c49d5b7988f530c" - integrity sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ== +"@babel/traverse@^7.16.0", "@babel/traverse@^7.21.5", "@babel/traverse@^7.23.2", "@babel/traverse@^7.23.6", "@babel/traverse@^7.23.9", "@babel/traverse@^7.24.0", "@babel/traverse@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.5.tgz#972aa0bc45f16983bf64aa1f877b2dd0eea7e6f8" + integrity sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA== dependencies: - "@babel/code-frame" "^7.24.1" - "@babel/generator" "^7.24.1" + "@babel/code-frame" "^7.24.2" + "@babel/generator" "^7.24.5" "@babel/helper-environment-visitor" "^7.22.20" "@babel/helper-function-name" "^7.23.0" "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.24.1" - "@babel/types" "^7.24.0" + "@babel/helper-split-export-declaration" "^7.24.5" + "@babel/parser" "^7.24.5" + "@babel/types" "^7.24.5" debug "^4.3.1" globals "^11.1.0" @@ -2855,40 +2161,13 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.21.5", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" - integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== - dependencies: - "@babel/helper-string-parser" "^7.22.5" - "@babel/helper-validator-identifier" "^7.22.20" - to-fast-properties "^2.0.0" - -"@babel/types@^7.17.0", "@babel/types@^7.23.6": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.6.tgz#be33fdb151e1f5a56877d704492c240fc71c7ccd" - integrity sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg== - dependencies: - "@babel/helper-string-parser" "^7.23.4" - "@babel/helper-validator-identifier" "^7.22.20" - to-fast-properties "^2.0.0" - -"@babel/types@^7.23.9": - version "7.23.9" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.9.tgz#1dd7b59a9a2b5c87f8b41e52770b5ecbf492e002" - integrity sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q== - dependencies: - "@babel/helper-string-parser" "^7.23.4" - "@babel/helper-validator-identifier" "^7.22.20" - to-fast-properties "^2.0.0" - -"@babel/types@^7.24.0": - version "7.24.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.0.tgz#3b951f435a92e7333eba05b7566fd297960ea1bf" - integrity sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w== +"@babel/types@^7.0.0", "@babel/types@^7.17.0", "@babel/types@^7.20.7", "@babel/types@^7.21.5", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.6", "@babel/types@^7.23.9", "@babel/types@^7.24.0", "@babel/types@^7.24.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.24.5.tgz#7661930afc638a5383eb0c4aee59b74f38db84d7" + integrity sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ== dependencies: - "@babel/helper-string-parser" "^7.23.4" - "@babel/helper-validator-identifier" "^7.22.20" + "@babel/helper-string-parser" "^7.24.1" + "@babel/helper-validator-identifier" "^7.24.5" to-fast-properties "^2.0.0" "@babel/types@~7.21.2": @@ -3037,10 +2316,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.1.tgz#eafa8775019b3650a77e8310ba4dbd17ca7af6d5" integrity sha512-m55cpeupQ2DbuRGQMMZDzbv9J9PgVelPjlcmM5kxHnrBdBx6REaEd7LamYV7Dm8N7rCyR/XwU6rVP8ploKtIkA== -"@esbuild/aix-ppc64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537" - integrity sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g== +"@esbuild/aix-ppc64@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.1.tgz#044268dc9ca4dc67f8d4aad8f51cfb894bfd7114" + integrity sha512-O7yppwipkXvnEPjzkSXJRk2g4bS8sUx9p9oXHq9MU/U7lxUzZVsnFZMDTmeeX9bfQxrFcvOacl/ENgOh0WP9pA== "@esbuild/android-arm64@0.17.19": version "0.17.19" @@ -3062,10 +2341,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.1.tgz#68791afa389550736f682c15b963a4f37ec2f5f6" integrity sha512-hCnXNF0HM6AjowP+Zou0ZJMWWa1VkD77BXe959zERgGJBBxB+sV+J9f/rcjeg2c5bsukD/n17RKWXGFCO5dD5A== -"@esbuild/android-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz#db1c9202a5bc92ea04c7b6840f1bbe09ebf9e6b9" - integrity sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg== +"@esbuild/android-arm64@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.1.tgz#76aacd934449e541f05b66d5ec8cbff96ec2ae81" + integrity sha512-jXhccq6es+onw7x8MxoFnm820mz7sGa9J14kLADclmiEUH4fyj+FjR6t0M93RgtlI/awHWhtF0Wgfhqgf9gDZA== "@esbuild/android-arm@0.17.19": version "0.17.19" @@ -3087,10 +2366,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.1.tgz#38c91d8ee8d5196f7fbbdf4f0061415dde3a473a" integrity sha512-4j0+G27/2ZXGWR5okcJi7pQYhmkVgb4D7UKwxcqrjhvp5TKWx3cUjgB1CGj1mfdmJBQ9VnUGgUhign+FPF2Zgw== -"@esbuild/android-arm@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz#3b488c49aee9d491c2c8f98a909b785870d6e995" - integrity sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w== +"@esbuild/android-arm@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.1.tgz#8247c5aef933a212bca261290f6e43a9dca07cc5" + integrity sha512-hh3jKWikdnTtHCglDAeVO3Oyh8MaH8xZUaWMiCCvJ9/c3NtPqZq+CACOlGTxhddypXhl+8B45SeceYBfB/e8Ow== "@esbuild/android-x64@0.17.19": version "0.17.19" @@ -3112,10 +2391,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.1.tgz#93f6190ce997b313669c20edbf3645fc6c8d8f22" integrity sha512-MSfZMBoAsnhpS+2yMFYIQUPs8Z19ajwfuaSZx+tSl09xrHZCjbeXXMsUF/0oq7ojxYEpsSo4c0SfjxOYXRbpaA== -"@esbuild/android-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz#3b1628029e5576249d2b2d766696e50768449f98" - integrity sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg== +"@esbuild/android-x64@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.1.tgz#80cbfa35412299edefbc4ab78064f0b66e448008" + integrity sha512-NPObtlBh4jQHE01gJeucqEhdoD/4ya2owSIS8lZYS58aR0x7oZo9lB2lVFxgTANSa5MGCBeoQtr+yA9oKCGPvA== "@esbuild/darwin-arm64@0.17.19": version "0.17.19" @@ -3137,10 +2416,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.1.tgz#0d391f2e81fda833fe609182cc2fbb65e03a3c46" integrity sha512-Ylk6rzgMD8klUklGPzS414UQLa5NPXZD5tf8JmQU8GQrj6BrFA/Ic9tb2zRe1kOZyCbGl+e8VMbDRazCEBqPvA== -"@esbuild/darwin-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz#6e8517a045ddd86ae30c6608c8475ebc0c4000bb" - integrity sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA== +"@esbuild/darwin-arm64@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.1.tgz#154167fb9e54017dac4b343f8e5e25c9d9324036" + integrity sha512-BLT7TDzqsVlQRmJfO/FirzKlzmDpBWwmCUlyggfzUwg1cAxVxeA4O6b1XkMInlxISdfPAOunV9zXjvh5x99Heg== "@esbuild/darwin-x64@0.17.19": version "0.17.19" @@ -3162,10 +2441,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.1.tgz#92504077424584684862f483a2242cfde4055ba2" integrity sha512-pFIfj7U2w5sMp52wTY1XVOdoxw+GDwy9FsK3OFz4BpMAjvZVs0dT1VXs8aQm22nhwoIWUmIRaE+4xow8xfIDZA== -"@esbuild/darwin-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz#90ed098e1f9dd8a9381695b207e1cff45540a0d0" - integrity sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA== +"@esbuild/darwin-x64@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.1.tgz#db971502c9fa204906b89e489810c902bf6d9afb" + integrity sha512-D3h3wBQmeS/vp93O4B+SWsXB8HvRDwMyhTNhBd8yMbh5wN/2pPWRW5o/hM3EKgk9bdKd9594lMGoTCTiglQGRQ== "@esbuild/freebsd-arm64@0.17.19": version "0.17.19" @@ -3187,10 +2466,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.1.tgz#a1646fa6ba87029c67ac8a102bb34384b9290774" integrity sha512-UyW1WZvHDuM4xDz0jWun4qtQFauNdXjXOtIy7SYdf7pbxSWWVlqhnR/T2TpX6LX5NI62spt0a3ldIIEkPM6RHw== -"@esbuild/freebsd-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz#d71502d1ee89a1130327e890364666c760a2a911" - integrity sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw== +"@esbuild/freebsd-arm64@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.1.tgz#f0f3bc20c23af999bd696099a324dceb66d77761" + integrity sha512-/uVdqqpNKXIxT6TyS/oSK4XE4xWOqp6fh4B5tgAwozkyWdylcX+W4YF2v6SKsL4wCQ5h1bnaSNjWPXG/2hp8AQ== "@esbuild/freebsd-x64@0.17.19": version "0.17.19" @@ -3212,10 +2491,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.1.tgz#41c9243ab2b3254ea7fb512f71ffdb341562e951" integrity sha512-itPwCw5C+Jh/c624vcDd9kRCCZVpzpQn8dtwoYIt2TJF3S9xJLiRohnnNrKwREvcZYx0n8sCSbvGH349XkcQeg== -"@esbuild/freebsd-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz#aa5ea58d9c1dd9af688b8b6f63ef0d3d60cea53c" - integrity sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw== +"@esbuild/freebsd-x64@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.1.tgz#d36af9085edb34244b41e5a57640e6b4452cbec2" + integrity sha512-paAkKN1n1jJitw+dAoR27TdCzxRl1FOEITx3h201R6NoXUojpMzgMLdkXVgCvaCSCqwYkeGLoe9UVNRDKSvQgw== "@esbuild/linux-arm64@0.17.19": version "0.17.19" @@ -3237,10 +2516,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.1.tgz#f3c1e1269fbc9eedd9591a5bdd32bf707a883156" integrity sha512-cX8WdlF6Cnvw/DO9/X7XLH2J6CkBnz7Twjpk56cshk9sjYVcuh4sXQBy5bmTwzBjNVZze2yaV1vtcJS04LbN8w== -"@esbuild/linux-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz#055b63725df678379b0f6db9d0fa85463755b2e5" - integrity sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A== +"@esbuild/linux-arm64@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.1.tgz#9d2ad42eea33b2a9571f13e7ecc39ee9d3ff0c6d" + integrity sha512-G65d08YoH00TL7Xg4LaL3gLV21bpoAhQ+r31NUu013YB7KK0fyXIt05VbsJtpqh/6wWxoLJZOvQHYnodRrnbUQ== "@esbuild/linux-arm@0.17.19": version "0.17.19" @@ -3262,10 +2541,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.1.tgz#4503ca7001a8ee99589c072801ce9d7540717a21" integrity sha512-LojC28v3+IhIbfQ+Vu4Ut5n3wKcgTu6POKIHN9Wpt0HnfgUGlBuyDDQR4jWZUZFyYLiz4RBBBmfU6sNfn6RhLw== -"@esbuild/linux-arm@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz#76b3b98cb1f87936fbc37f073efabad49dcd889c" - integrity sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg== +"@esbuild/linux-arm@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.1.tgz#d6f7c5873479dd97148bef3e3a7f09d486642883" + integrity sha512-tRHnxWJnvNnDpNVnsyDhr1DIQZUfCXlHSCDohbXFqmg9W4kKR7g8LmA3kzcwbuxbRMKeit8ladnCabU5f2traA== "@esbuild/linux-ia32@0.17.19": version "0.17.19" @@ -3287,10 +2566,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.1.tgz#98c474e3e0cbb5bcbdd8561a6e65d18f5767ce48" integrity sha512-4H/sQCy1mnnGkUt/xszaLlYJVTz3W9ep52xEefGtd6yXDQbz/5fZE5dFLUgsPdbUOQANcVUa5iO6g3nyy5BJiw== -"@esbuild/linux-ia32@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz#c0e5e787c285264e5dfc7a79f04b8b4eefdad7fa" - integrity sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig== +"@esbuild/linux-ia32@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.1.tgz#8f2aef34a31c8d16dbce0b8679021f4881f38efe" + integrity sha512-tt/54LqNNAqCz++QhxoqB9+XqdsaZOtFD/srEhHYwBd3ZUOepmR1Eeot8bS+Q7BiEvy9vvKbtpHf+r6q8hF5UA== "@esbuild/linux-loong64@0.17.19": version "0.17.19" @@ -3312,10 +2591,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.1.tgz#a8097d28d14b9165c725fe58fc438f80decd2f33" integrity sha512-c0jgtB+sRHCciVXlyjDcWb2FUuzlGVRwGXgI+3WqKOIuoo8AmZAddzeOHeYLtD+dmtHw3B4Xo9wAUdjlfW5yYA== -"@esbuild/linux-loong64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz#a6184e62bd7cdc63e0c0448b83801001653219c5" - integrity sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ== +"@esbuild/linux-loong64@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.1.tgz#44461ea2388efbafa6cf12b2bc1407a5388da066" + integrity sha512-MhNalK6r0nZD0q8VzUBPwheHzXPr9wronqmZrewLfP7ui9Fv1tdPmg6e7A8lmg0ziQCziSDHxh3cyRt4YMhGnQ== "@esbuild/linux-mips64el@0.17.19": version "0.17.19" @@ -3337,10 +2616,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.1.tgz#c44f6f0d7d017c41ad3bb15bfdb69b690656b5ea" integrity sha512-TgFyCfIxSujyuqdZKDZ3yTwWiGv+KnlOeXXitCQ+trDODJ+ZtGOzLkSWngynP0HZnTsDyBbPy7GWVXWaEl6lhA== -"@esbuild/linux-mips64el@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz#d08e39ce86f45ef8fc88549d29c62b8acf5649aa" - integrity sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA== +"@esbuild/linux-mips64el@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.1.tgz#754d533a4fef4b0790d82bfe1e82d6876f18370e" + integrity sha512-YCKVY7Zen5rwZV+nZczOhFmHaeIxR4Zn3jcmNH53LbgF6IKRwmrMywqDrg4SiSNApEefkAbPSIzN39FC8VsxPg== "@esbuild/linux-ppc64@0.17.19": version "0.17.19" @@ -3362,10 +2641,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.1.tgz#0765a55389a99237b3c84227948c6e47eba96f0d" integrity sha512-b+yuD1IUeL+Y93PmFZDZFIElwbmFfIKLKlYI8M6tRyzE6u7oEP7onGk0vZRh8wfVGC2dZoy0EqX1V8qok4qHaw== -"@esbuild/linux-ppc64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz#8d252f0b7756ffd6d1cbde5ea67ff8fd20437f20" - integrity sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg== +"@esbuild/linux-ppc64@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.1.tgz#2aafcfe2826c7d5d2e3c41eb8934e6368a7cada5" + integrity sha512-bw7bcQ+270IOzDV4mcsKAnDtAFqKO0jVv3IgRSd8iM0ac3L8amvCrujRVt1ajBTJcpDaFhIX+lCNRKteoDSLig== "@esbuild/linux-riscv64@0.17.19": version "0.17.19" @@ -3387,10 +2666,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.1.tgz#e4153b032288e3095ddf4c8be07893781b309a7e" integrity sha512-wpDlpE0oRKZwX+GfomcALcouqjjV8MIX8DyTrxfyCfXxoKQSDm45CZr9fanJ4F6ckD4yDEPT98SrjvLwIqUCgg== -"@esbuild/linux-riscv64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz#19f6dcdb14409dae607f66ca1181dd4e9db81300" - integrity sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg== +"@esbuild/linux-riscv64@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.1.tgz#481ceaf5939d14fb25da62a385b5e6c2096a3370" + integrity sha512-ARmDRNkcOGOm1AqUBSwRVDfDeD9hGYRfkudP2QdoonBz1ucWVnfBPfy7H4JPI14eYtZruRSczJxyu7SRYDVOcg== "@esbuild/linux-s390x@0.17.19": version "0.17.19" @@ -3412,10 +2691,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.1.tgz#b9ab8af6e4b73b26d63c1c426d7669a5d53eb5a7" integrity sha512-5BepC2Au80EohQ2dBpyTquqGCES7++p7G+7lXe1bAIvMdXm4YYcEfZtQrP4gaoZ96Wv1Ute61CEHFU7h4FMueQ== -"@esbuild/linux-s390x@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz#3c830c90f1a5d7dd1473d5595ea4ebb920988685" - integrity sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ== +"@esbuild/linux-s390x@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.1.tgz#e25b97005e4c82540d1bc7af88e333fb55142570" + integrity sha512-o73TcUNMuoTZlhwFdsgr8SfQtmMV58sbgq6gQq9G1xUiYnHMTmJbwq65RzMx89l0iya69lR4bxBgtWiiOyDQZA== "@esbuild/linux-x64@0.17.19": version "0.17.19" @@ -3437,10 +2716,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.1.tgz#0b25da17ac38c3e11cdd06ca3691d4d6bef2755f" integrity sha512-5gRPk7pKuaIB+tmH+yKd2aQTRpqlf1E4f/mC+tawIm/CGJemZcHZpp2ic8oD83nKgUPMEd0fNanrnFljiruuyA== -"@esbuild/linux-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz#86eca35203afc0d9de0694c64ec0ab0a378f6fff" - integrity sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw== +"@esbuild/linux-x64@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.21.1.tgz#a05a61d0a0cbb03baa6db12cd8164c1e5265ffb2" + integrity sha512-da4/1mBJwwgJkbj4fMH7SOXq2zapgTo0LKXX1VUZ0Dxr+e8N0WbS80nSZ5+zf3lvpf8qxrkZdqkOqFfm57gXwA== "@esbuild/netbsd-x64@0.17.19": version "0.17.19" @@ -3462,10 +2741,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.1.tgz#3148e48406cd0d4f7ba1e0bf3f4d77d548c98407" integrity sha512-4fL68JdrLV2nVW2AaWZBv3XEm3Ae3NZn/7qy2KGAt3dexAgSVT+Hc97JKSZnqezgMlv9x6KV0ZkZY7UO5cNLCg== -"@esbuild/netbsd-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz#e771c8eb0e0f6e1877ffd4220036b98aed5915e6" - integrity sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ== +"@esbuild/netbsd-x64@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.1.tgz#e298f854e8999563f2e4668bd542678c46be4b53" + integrity sha512-CPWs0HTFe5woTJN5eKPvgraUoRHrCtzlYIAv9wBC+FAyagBSaf+UdZrjwYyTGnwPGkThV4OCI7XibZOnPvONVw== "@esbuild/openbsd-x64@0.17.19": version "0.17.19" @@ -3487,10 +2766,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.1.tgz#7b73e852986a9750192626d377ac96ac2b749b76" integrity sha512-GhRuXlvRE+twf2ES+8REbeCb/zeikNqwD3+6S5y5/x+DYbAQUNl0HNBs4RQJqrechS4v4MruEr8ZtAin/hK5iw== -"@esbuild/openbsd-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz#9a795ae4b4e37e674f0f4d716f3e226dd7c39baf" - integrity sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ== +"@esbuild/openbsd-x64@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.1.tgz#640d34de1e3c6bc3ff64e0379aae00ede3608f14" + integrity sha512-xxhTm5QtzNLc24R0hEkcH+zCx/o49AsdFZ0Cy5zSd/5tOj4X2g3/2AJB625NoadUuc4A8B3TenLJoYdWYOYCew== "@esbuild/sunos-x64@0.17.19": version "0.17.19" @@ -3512,10 +2791,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.1.tgz#402a441cdac2eee98d8be378c7bc23e00c1861c5" integrity sha512-ZnWEyCM0G1Ex6JtsygvC3KUUrlDXqOihw8RicRuQAzw+c4f1D66YlPNNV3rkjVW90zXVsHwZYWbJh3v+oQFM9Q== -"@esbuild/sunos-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz#7df23b61a497b8ac189def6e25a95673caedb03f" - integrity sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w== +"@esbuild/sunos-x64@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.1.tgz#f53cb1cdcbf05b3320e147ddb85ec2b1cf2b6cfc" + integrity sha512-CWibXszpWys1pYmbr9UiKAkX6x+Sxw8HWtw1dRESK1dLW5fFJ6rMDVw0o8MbadusvVQx1a8xuOxnHXT941Hp1A== "@esbuild/win32-arm64@0.17.19": version "0.17.19" @@ -3537,10 +2816,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.1.tgz#36c4e311085806a6a0c5fc54d1ac4d7b27e94d7b" integrity sha512-QZ6gXue0vVQY2Oon9WyLFCdSuYbXSoxaZrPuJ4c20j6ICedfsDilNPYfHLlMH7vGfU5DQR0czHLmJvH4Nzis/A== -"@esbuild/win32-arm64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz#f1ae5abf9ca052ae11c1bc806fb4c0f519bacf90" - integrity sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ== +"@esbuild/win32-arm64@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.1.tgz#df4f44f9b4fec9598c0ec2c34fec9c568c8ab85d" + integrity sha512-jb5B4k+xkytGbGUS4T+Z89cQJ9DJ4lozGRSV+hhfmCPpfJ3880O31Q1srPCimm+V6UCbnigqD10EgDNgjvjerQ== "@esbuild/win32-ia32@0.17.19": version "0.17.19" @@ -3562,10 +2841,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.1.tgz#0cf933be3fb9dc58b45d149559fe03e9e22b54fe" integrity sha512-HzcJa1NcSWTAU0MJIxOho8JftNp9YALui3o+Ny7hCh0v5f90nprly1U3Sj1Ldj/CvKKdvvFsCRvDkpsEMp4DNw== -"@esbuild/win32-ia32@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz#241fe62c34d8e8461cd708277813e1d0ba55ce23" - integrity sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ== +"@esbuild/win32-ia32@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.1.tgz#a57edbd9905db9f957327ae0facfbf406a80a4e4" + integrity sha512-PgyFvjJhXqHn1uxPhyN1wZ6dIomKjiLUQh1LjFvjiV1JmnkZ/oMPrfeEAZg5R/1ftz4LZWZr02kefNIQ5SKREQ== "@esbuild/win32-x64@0.17.19": version "0.17.19" @@ -3587,10 +2866,10 @@ resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.1.tgz#77583b6ea54cee7c1410ebbd54051b6a3fcbd8ba" integrity sha512-0MBh53o6XtI6ctDnRMeQ+xoCN8kD2qI1rY1KgF/xdWQwoFeKou7puvDfV8/Wv4Ctx2rRpET/gGdz3YlNtNACSA== -"@esbuild/win32-x64@0.20.2": - version "0.20.2" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz#9c907b21e30a52db959ba4f80bb01a0cc403d5cc" - integrity sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ== +"@esbuild/win32-x64@0.21.1": + version "0.21.1" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.1.tgz#eb86553d90e86a8c174b96650fdb4c60f2de16a7" + integrity sha512-W9NttRZQR5ehAiqHGDnvfDaGmQOm6Fi4vSlce8mjM75x//XKuVAByohlEX6N17yZnVXxQFuh4fDRunP8ca6bfA== "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" @@ -3624,44 +2903,49 @@ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.56.0.tgz#ef20350fec605a7f7035a01764731b2de0f3782b" integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A== +"@eslint/js@8.57.0": + version "8.57.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f" + integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g== + "@fal-works/esbuild-plugin-global-externals@^2.1.2": version "2.1.2" resolved "https://registry.yarnpkg.com/@fal-works/esbuild-plugin-global-externals/-/esbuild-plugin-global-externals-2.1.2.tgz#c05ed35ad82df8e6ac616c68b92c2282bd083ba4" integrity sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ== -"@floating-ui/core@^1.4.2": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.0.tgz#5c05c60d5ae2d05101c3021c1a2a350ddc027f8c" - integrity sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg== +"@floating-ui/core@^1.0.0": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.1.tgz#a4e6fef1b069cda533cbc7a4998c083a37f37573" + integrity sha512-42UH54oPZHPdRHdw6BgoBD6cg/eVTmVrFcgeRDM3jbO7uxSoipVcmcIGFcA5jmOHO5apcyvBhkSKES3fQJnu7A== dependencies: - "@floating-ui/utils" "^0.1.3" + "@floating-ui/utils" "^0.2.0" -"@floating-ui/dom@^1.5.1": - version "1.5.3" - resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.5.3.tgz#54e50efcb432c06c23cd33de2b575102005436fa" - integrity sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA== +"@floating-ui/dom@^1.0.0": + version "1.6.5" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.5.tgz#323f065c003f1d3ecf0ff16d2c2c4d38979f4cb9" + integrity sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw== dependencies: - "@floating-ui/core" "^1.4.2" - "@floating-ui/utils" "^0.1.3" + "@floating-ui/core" "^1.0.0" + "@floating-ui/utils" "^0.2.0" "@floating-ui/react-dom@^2.0.0": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.2.tgz#fab244d64db08e6bed7be4b5fcce65315ef44d20" - integrity sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ== + version "2.0.9" + resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.9.tgz#264ba8b061000baa132b5910f0427a6acf7ad7ce" + integrity sha512-q0umO0+LQK4+p6aGyvzASqKbKOJcAHJ7ycE9CuUvfx3s9zTHWmGJTPOIlM/hmSBfUfg/XfY5YhLBLR/LHwShQQ== dependencies: - "@floating-ui/dom" "^1.5.1" + "@floating-ui/dom" "^1.0.0" -"@floating-ui/utils@^0.1.3": - version "0.1.6" - resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.1.6.tgz#22958c042e10b67463997bd6ea7115fe28cbcaf9" - integrity sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A== +"@floating-ui/utils@^0.2.0": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.2.tgz#d8bae93ac8b815b2bd7a98078cf91e2724ef11e5" + integrity sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw== "@hexagon/base64@^1.1.27": version "1.1.28" resolved "https://registry.yarnpkg.com/@hexagon/base64/-/base64-1.1.28.tgz#7d306a97f1423829be5b27c9d388fe50e3099d48" integrity sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw== -"@humanwhocodes/config-array@^0.11.13": +"@humanwhocodes/config-array@^0.11.13", "@humanwhocodes/config-array@^0.11.14": version "0.11.14" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg== @@ -3676,9 +2960,9 @@ integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== "@humanwhocodes/object-schema@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz#d9fae00a2d5cb40f92cfe64b47ad749fbc38f917" - integrity sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw== + version "2.0.3" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" + integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== "@internationalized/number@3.5.0": version "3.5.0" @@ -3715,7 +2999,7 @@ js-yaml "^3.13.1" resolve-from "^5.0.0" -"@istanbuljs/schema@^0.1.2": +"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": version "0.1.3" resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== @@ -3912,16 +3196,7 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" -"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" - integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/gen-mapping@^0.3.5": +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2", "@jridgewell/gen-mapping@^0.3.5": version "0.3.5" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== @@ -3931,14 +3206,9 @@ "@jridgewell/trace-mapping" "^0.3.24" "@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" - integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== - -"@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== "@jridgewell/set-array@^1.2.1": version "1.2.1" @@ -3946,12 +3216,12 @@ integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== "@jridgewell/source-map@^0.3.3": - version "0.3.5" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" - integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== + version "0.3.6" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.6.tgz#9d71ca886e32502eb9362c9a74a46787c36df81a" + integrity sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ== dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": version "1.4.15" @@ -3966,15 +3236,7 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.20" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" - integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - -"@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.9": version "0.3.25" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== @@ -3993,9 +3255,9 @@ integrity sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw== "@leichtgewicht/ip-codec@^2.0.1": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" - integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== + version "2.0.5" + resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz#4fc56c15c580b9adb7dc3c333a134e540b44bfb1" + integrity sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw== "@levischuck/tiny-cbor@^0.2.2": version "0.2.2" @@ -4764,11 +4026,11 @@ tar-fs "^2.1.1" "@nestjs/bull-shared@^10.0.1": - version "10.0.1" - resolved "https://registry.yarnpkg.com/@nestjs/bull-shared/-/bull-shared-10.0.1.tgz#381656aebbb6a03a94e9568e434977bcc373e91c" - integrity sha512-8Td36l2i5x9+iQWjPB5Bd5+6u5Eangb5DclNcwrdwKqvd28xE92MSW97P4JV52C2kxrTjZwx8ck/wObAwtpQPw== + version "10.1.1" + resolved "https://registry.yarnpkg.com/@nestjs/bull-shared/-/bull-shared-10.1.1.tgz#f2e20e9726819a86efcddbb1aeef28ed91206185" + integrity sha512-su7eThDrSz1oQagEi8l+1CyZ7N6nMgmyAX0DuZoXqT1KEVEDqGX7x80RlPVF60m/8SYOskckGMjJROSfNQcErw== dependencies: - tslib "2.6.0" + tslib "2.6.2" "@nestjs/bull@10.0.1": version "10.0.1" @@ -4892,6 +4154,7 @@ version "17.3.5" resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-17.3.5.tgz#5f1a8d6e59e8fb37b8f1a4fe69116d9f46f2102f" integrity sha512-0heI0yHUckdGI8uywu/wkp24KR/tdYMKYJOaYIU+9JydyN1zJRpbR7x0thddl7+k/zu2ZGbfFdv1779Ecw/xdA== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -4914,41 +4177,41 @@ fastq "^1.6.0" "@npmcli/agent@^2.0.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@npmcli/agent/-/agent-2.2.0.tgz#e81f00fdb2a670750ff7731bbefb47ecbf0ccf44" - integrity sha512-2yThA1Es98orMkpSLVqlDZAMPK3jHJhifP2gnNUdk1754uZ8yI5c+ulCoVG+WlntQA6MzhrURMXjSd9Z7dJ2/Q== + version "2.2.2" + resolved "https://registry.yarnpkg.com/@npmcli/agent/-/agent-2.2.2.tgz#967604918e62f620a648c7975461c9c9e74fc5d5" + integrity sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og== dependencies: agent-base "^7.1.0" http-proxy-agent "^7.0.0" https-proxy-agent "^7.0.1" lru-cache "^10.0.1" - socks-proxy-agent "^8.0.1" + socks-proxy-agent "^8.0.3" "@npmcli/fs@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.0.tgz#233d43a25a91d68c3a863ba0da6a3f00924a173e" - integrity sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w== + version "3.1.1" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.1.tgz#59cdaa5adca95d135fc00f2bb53f5771575ce726" + integrity sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg== dependencies: semver "^7.3.5" "@npmcli/git@^5.0.0": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-5.0.3.tgz#ad3ede0994bcf716ddb63d361f3ea16cb72d878c" - integrity sha512-UZp9NwK+AynTrKvHn5k3KviW/hA5eENmFsu3iAPe7sWRt0lFUdsY/wXIYjpDFe7cdSNwOIzbObfwgt6eL5/2zw== + version "5.0.7" + resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-5.0.7.tgz#7ff675e33b4dc0b0adb1f0c4aa302109efc06463" + integrity sha512-WaOVvto604d5IpdCRV2KjQu8PzkfE96d50CQGKgywXh2GxXmDeUO5EWcBC4V57uFyrNqx83+MewuJh3WTR3xPA== dependencies: "@npmcli/promise-spawn" "^7.0.0" lru-cache "^10.0.1" npm-pick-manifest "^9.0.0" - proc-log "^3.0.0" + proc-log "^4.0.0" promise-inflight "^1.0.1" promise-retry "^2.0.1" semver "^7.3.5" which "^4.0.0" "@npmcli/installed-package-contents@^2.0.1": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz#bfd817eccd9e8df200919e73f57f9e3d9e4f9e33" - integrity sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ== + version "2.1.0" + resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-2.1.0.tgz#63048e5f6e40947a3a88dcbcb4fd9b76fdd37c17" + integrity sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w== dependencies: npm-bundled "^3.0.0" npm-normalize-package-bin "^3.0.0" @@ -4958,22 +4221,40 @@ resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz#101b2d0490ef1aa20ed460e4c0813f0db560545a" integrity sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA== +"@npmcli/package-json@^5.0.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@npmcli/package-json/-/package-json-5.1.0.tgz#10d117b5fb175acc14c70901a151c52deffc843e" + integrity sha512-1aL4TuVrLS9sf8quCLerU3H9J4vtCtgu8VauYozrmEyU57i/EdKleCnsQ7vpnABIH6c9mnTxcH5sFkO3BlV8wQ== + dependencies: + "@npmcli/git" "^5.0.0" + glob "^10.2.2" + hosted-git-info "^7.0.0" + json-parse-even-better-errors "^3.0.0" + normalize-package-data "^6.0.0" + proc-log "^4.0.0" + semver "^7.5.3" + "@npmcli/promise-spawn@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-7.0.0.tgz#fd1c64ed4ff2341e503e1f390c62640a6540df09" - integrity sha512-wBqcGsMELZna0jDblGd7UXgOby45TQaMWmbFwWX+SEotk4HV6zG2t6rT9siyLhPk4P6YYqgfL1UO8nMWDBVJXQ== + version "7.0.2" + resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-7.0.2.tgz#1d53d34ffeb5d151bfa8ec661bcccda8bbdfd532" + integrity sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ== dependencies: which "^4.0.0" +"@npmcli/redact@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@npmcli/redact/-/redact-1.1.0.tgz#78e53a6a34f013543a73827a07ebdc3a6f10454b" + integrity sha512-PfnWuOkQgu7gCbnSsAisaX7hKOdZ4wSAhAzH3/ph5dSGau52kCRrMMGbiSQLwyTZpgldkZ49b0brkOr1AzGBHQ== + "@npmcli/run-script@^7.0.0": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-7.0.2.tgz#497e7f058799497889df65900c711312252276d3" - integrity sha512-Omu0rpA8WXvcGeY6DDzyRoY1i5DkCBkzyJ+m2u7PD6quzb0TvSqdIPOkTn8ZBOj7LbbcbMfZ3c5skwSu6m8y2w== + version "7.0.4" + resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-7.0.4.tgz#9f29aaf4bfcf57f7de2a9e28d1ef091d14b2e6eb" + integrity sha512-9ApYM/3+rBt9V80aYg6tZfzj3UWdiYyCt7gJUD1VJKvWF5nwKDSICXbYIQbspFTq6TOpbsEtIC0LArB8d9PFmg== dependencies: "@npmcli/node-gyp" "^3.0.0" + "@npmcli/package-json" "^5.0.0" "@npmcli/promise-spawn" "^7.0.0" node-gyp "^10.0.0" - read-package-json-fast "^3.0.0" which "^4.0.0" "@nrwl/angular@18.3.3": @@ -5093,7 +4374,6 @@ "@phenomnomnominal/tsquery" "~5.0.1" "@typescript-eslint/type-utils" "^7.3.0" chalk "^4.1.0" - enquirer "^2.3.6" find-cache-dir "^3.3.2" ignore "^5.0.4" magic-string "~0.30.2" @@ -5115,7 +4395,7 @@ "@nx/js" "18.3.3" "@phenomnomnominal/tsquery" "~5.0.1" detect-port "^1.5.1" - semver "7.5.3" + semver "^7.5.3" tslib "^2.3.0" "@nx/devkit@18.3.3": @@ -5127,9 +4407,10 @@ ejs "^3.1.7" enquirer "~2.3.6" ignore "^5.0.4" - semver "7.5.3" + semver "^7.5.3" tmp "~0.2.1" tslib "^2.3.0" + yargs-parser "21.1.1" "@nx/eslint-plugin@18.3.3": version "18.3.3" @@ -5144,7 +4425,7 @@ chalk "^4.1.0" confusing-browser-globals "^1.0.9" jsonc-eslint-parser "^2.1.0" - semver "7.5.3" + semver "^7.5.3" tslib "^2.3.0" "@nx/eslint@18.3.3": @@ -5175,6 +4456,7 @@ jest-config "^29.4.1" jest-resolve "^29.4.1" jest-util "^29.4.1" + minimatch "9.0.3" resolve.exports "1.1.0" tslib "^2.3.0" yargs-parser "21.1.1" @@ -5184,10 +4466,11 @@ resolved "https://registry.yarnpkg.com/@nx/js/-/js-18.3.3.tgz#977968160d6edc11f320bc0f654b52d36a9101ac" integrity sha512-e8u56oG0mlTVz48EeH0C7txX0GeLYN0o4mK1LDAMIHQa4tKefNfwrdqHaZBiVqFOPopeFtqi8s0kqce5prwCaw== dependencies: - "@babel/core" "^7.22.9" + "@babel/core" "^7.23.2" "@babel/plugin-proposal-decorators" "^7.22.7" - "@babel/plugin-transform-runtime" "^7.22.9" - "@babel/preset-env" "^7.22.9" + "@babel/plugin-transform-class-properties" "^7.22.5" + "@babel/plugin-transform-runtime" "^7.23.2" + "@babel/preset-env" "^7.23.2" "@babel/preset-typescript" "^7.22.5" "@babel/runtime" "^7.22.6" "@nrwl/js" "18.3.3" @@ -5204,11 +4487,11 @@ fs-extra "^11.1.0" ignore "^5.0.4" js-tokens "^4.0.0" - minimatch "3.0.5" + minimatch "9.0.3" npm-package-arg "11.0.1" npm-run-path "^4.0.1" ora "5.3.0" - semver "7.5.3" + semver "^7.5.3" source-map-support "0.5.19" ts-node "10.9.1" tsconfig-paths "^4.1.2" @@ -5308,7 +4591,7 @@ "@nx/eslint" "18.3.3" "@nx/js" "18.3.3" "@phenomnomnominal/tsquery" "~5.0.1" - semver "7.5.3" + semver "^7.5.3" tslib "^2.3.0" "@nx/web@18.3.3": @@ -5777,70 +5060,85 @@ dependencies: "@babel/runtime" "^7.13.10" -"@rollup/rollup-android-arm-eabi@4.10.0": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.10.0.tgz#786eaf6372be2fc209cc957c14aa9d3ff8fefe6a" - integrity sha512-/MeDQmcD96nVoRumKUljsYOLqfv1YFJps+0pTrb2Z9Nl/w5qNUysMaWQsrd1mvAlNT4yza1iVyIu4Q4AgF6V3A== - -"@rollup/rollup-android-arm64@4.10.0": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.10.0.tgz#0114a042fd6396f4f3233e6171fd5b61a36ed539" - integrity sha512-lvu0jK97mZDJdpZKDnZI93I0Om8lSDaiPx3OiCk0RXn3E8CMPJNS/wxjAvSJJzhhZpfjXsjLWL8LnS6qET4VNQ== - -"@rollup/rollup-darwin-arm64@4.10.0": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.10.0.tgz#944d007c1dc71a8c9174d11671c0c34bd74a2c81" - integrity sha512-uFpayx8I8tyOvDkD7X6n0PriDRWxcqEjqgtlxnUA/G9oS93ur9aZ8c8BEpzFmsed1TH5WZNG5IONB8IiW90TQg== - -"@rollup/rollup-darwin-x64@4.10.0": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.10.0.tgz#1d08cb4521a058d7736ab1c7fe988daf034a2598" - integrity sha512-nIdCX03qFKoR/MwQegQBK+qZoSpO3LESurVAC6s6jazLA1Mpmgzo3Nj3H1vydXp/JM29bkCiuF7tDuToj4+U9Q== - -"@rollup/rollup-linux-arm-gnueabihf@4.10.0": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.10.0.tgz#4763eec1591bf0e99a54ad3d1ef39cb268ed7b19" - integrity sha512-Fz7a+y5sYhYZMQFRkOyCs4PLhICAnxRX/GnWYReaAoruUzuRtcf+Qnw+T0CoAWbHCuz2gBUwmWnUgQ67fb3FYw== - -"@rollup/rollup-linux-arm64-gnu@4.10.0": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.10.0.tgz#e6dae70c53ace836973526c41803b877cffc6f7b" - integrity sha512-yPtF9jIix88orwfTi0lJiqINnlWo6p93MtZEoaehZnmCzEmLL0eqjA3eGVeyQhMtxdV+Mlsgfwhh0+M/k1/V7Q== - -"@rollup/rollup-linux-arm64-musl@4.10.0": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.10.0.tgz#5692e1a0feba0cc4a933864961afc3211177d242" - integrity sha512-9GW9yA30ib+vfFiwjX+N7PnjTnCMiUffhWj4vkG4ukYv1kJ4T9gHNg8zw+ChsOccM27G9yXrEtMScf1LaCuoWQ== - -"@rollup/rollup-linux-riscv64-gnu@4.10.0": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.10.0.tgz#fbe3d80f7a7ac54a8847f5bddd1bc6f7b9ccb65f" - integrity sha512-X1ES+V4bMq2ws5fF4zHornxebNxMXye0ZZjUrzOrf7UMx1d6wMQtfcchZ8SqUnQPPHdOyOLW6fTcUiFgHFadRA== - -"@rollup/rollup-linux-x64-gnu@4.10.0": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.10.0.tgz#3f06b55ccf173446d390d0306643dff62ec99807" - integrity sha512-w/5OpT2EnI/Xvypw4FIhV34jmNqU5PZjZue2l2Y3ty1Ootm3SqhI+AmfhlUYGBTd9JnpneZCDnt3uNOiOBkMyw== - -"@rollup/rollup-linux-x64-musl@4.10.0": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.10.0.tgz#e4ac9b27041c83d7faab6205f62763103eb317ba" - integrity sha512-q/meftEe3QlwQiGYxD9rWwB21DoKQ9Q8wA40of/of6yGHhZuGfZO0c3WYkN9dNlopHlNT3mf5BPsUSxoPuVQaw== - -"@rollup/rollup-win32-arm64-msvc@4.10.0": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.10.0.tgz#6ad0d4fb0066f240778ee3f61eecf7aa0357f883" - integrity sha512-NrR6667wlUfP0BHaEIKgYM/2va+Oj+RjZSASbBMnszM9k+1AmliRjHc3lJIiOehtSSjqYiO7R6KLNrWOX+YNSQ== - -"@rollup/rollup-win32-ia32-msvc@4.10.0": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.10.0.tgz#29d50292381311cc8d3623e73b427b7e2e40a653" - integrity sha512-FV0Tpt84LPYDduIDcXvEC7HKtyXxdvhdAOvOeWMWbQNulxViH2O07QXkT/FffX4FqEI02jEbCJbr+YcuKdyyMg== - -"@rollup/rollup-win32-x64-msvc@4.10.0": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.10.0.tgz#4eedd01af3a82c1acb0fe6d837ebf339c4cbf839" - integrity sha512-OZoJd+o5TaTSQeFFQ6WjFCiltiYVjIdsXxwu/XZ8qRpsvMQr4UsVrE5UyT9RIvsnuF47DqkJKhhVZ2Q9YW9IpQ== +"@rollup/rollup-android-arm-eabi@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz#1a32112822660ee104c5dd3a7c595e26100d4c2d" + integrity sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ== + +"@rollup/rollup-android-arm64@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz#5aeef206d65ff4db423f3a93f71af91b28662c5b" + integrity sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw== + +"@rollup/rollup-darwin-arm64@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz#6b66aaf003c70454c292cd5f0236ebdc6ffbdf1a" + integrity sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw== + +"@rollup/rollup-darwin-x64@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz#f64fc51ed12b19f883131ccbcea59fc68cbd6c0b" + integrity sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ== + +"@rollup/rollup-linux-arm-gnueabihf@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz#1a7641111be67c10111f7122d1e375d1226cbf14" + integrity sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A== + +"@rollup/rollup-linux-arm-musleabihf@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz#c93fd632923e0fee25aacd2ae414288d0b7455bb" + integrity sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg== + +"@rollup/rollup-linux-arm64-gnu@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz#fa531425dd21d058a630947527b4612d9d0b4a4a" + integrity sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A== + +"@rollup/rollup-linux-arm64-musl@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz#8acc16f095ceea5854caf7b07e73f7d1802ac5af" + integrity sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA== + +"@rollup/rollup-linux-powerpc64le-gnu@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz#94e69a8499b5cf368911b83a44bb230782aeb571" + integrity sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ== + +"@rollup/rollup-linux-riscv64-gnu@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz#7ef1c781c7e59e85a6ce261cc95d7f1e0b56db0f" + integrity sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg== + +"@rollup/rollup-linux-s390x-gnu@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz#f15775841c3232fca9b78cd25a7a0512c694b354" + integrity sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g== + +"@rollup/rollup-linux-x64-gnu@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz#b521d271798d037ad70c9f85dd97d25f8a52e811" + integrity sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ== + +"@rollup/rollup-linux-x64-musl@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz#9254019cc4baac35800991315d133cc9fd1bf385" + integrity sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q== + +"@rollup/rollup-win32-arm64-msvc@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz#27f65a89f6f52ee9426ec11e3571038e4671790f" + integrity sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA== + +"@rollup/rollup-win32-ia32-msvc@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz#a2fbf8246ed0bb014f078ca34ae6b377a90cb411" + integrity sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ== + +"@rollup/rollup-win32-x64-msvc@4.17.2": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz#5a2d08b81e8064b34242d5cc9973ef8dd1e60503" + integrity sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w== "@samverschueren/stream-to-observable@^0.3.0": version "0.3.1" @@ -5868,57 +5166,59 @@ jsonc-parser "3.2.1" "@schematics/angular@^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0": - version "17.0.0" - resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-17.0.0.tgz#63ddf8bfbb3b117fe7a355bd22b43d2c9ff7f0ee" - integrity sha512-9jKU5x/WzaBsfSkUowK1X74FqtMXa6+A60XgW4ACO8i6fwKfPeS+tIrAieeYOX80/njBh7I5CvcpHmWA2SbcXQ== + version "17.3.7" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-17.3.7.tgz#0e033e9a999ffcfc24cb2ce36529b5b5d5241312" + integrity sha512-HaJroKaberriP4wFefTTSVFrtU9GMvnG3I6ELbOteOyKMH7o2V91FXGJDJ5KnIiLRlBmC30G3r+9Ybc/rtAYkw== dependencies: - "@angular-devkit/core" "17.0.0" - "@angular-devkit/schematics" "17.0.0" - jsonc-parser "3.2.0" + "@angular-devkit/core" "17.3.7" + "@angular-devkit/schematics" "17.3.7" + jsonc-parser "3.2.1" -"@sigstore/bundle@^2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@sigstore/bundle/-/bundle-2.2.0.tgz#e3f555a5c503fe176d8d1e0e829b00f842502e46" - integrity sha512-5VI58qgNs76RDrwXNhpmyN/jKpq9evV/7f1XrcqcAfvxDl5SeVY/I5Rmfe96ULAV7/FK5dge9RBKGBJPhL1WsQ== +"@sigstore/bundle@^2.3.0", "@sigstore/bundle@^2.3.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@sigstore/bundle/-/bundle-2.3.1.tgz#f6cdc67c8400e58ca27f0ef495b27a9327512073" + integrity sha512-eqV17lO3EIFqCWK3969Rz+J8MYrRZKw9IBHpSo6DEcEX2c+uzDFOgHE9f2MnyDpfs48LFO4hXmk9KhQ74JzU1g== dependencies: - "@sigstore/protobuf-specs" "^0.3.0" + "@sigstore/protobuf-specs" "^0.3.1" -"@sigstore/core@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@sigstore/core/-/core-1.0.0.tgz#0fcdb32d191d4145a70cb837061185353b3b08e3" - integrity sha512-dW2qjbWLRKGu6MIDUTBuJwXCnR8zivcSpf5inUzk7y84zqy/dji0/uahppoIgMoKeR+6pUZucrwHfkQQtiG9Rw== +"@sigstore/core@^1.0.0", "@sigstore/core@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@sigstore/core/-/core-1.1.0.tgz#5583d8f7ffe599fa0a89f2bf289301a5af262380" + integrity sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg== -"@sigstore/protobuf-specs@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@sigstore/protobuf-specs/-/protobuf-specs-0.3.0.tgz#bdcc773671f625bb81591bca86ec5314d57297f3" - integrity sha512-zxiQ66JFOjVvP9hbhGj/F/qNdsZfkGb/dVXSanNRNuAzMlr4MC95voPUBX8//ZNnmv3uSYzdfR/JSkrgvZTGxA== +"@sigstore/protobuf-specs@^0.3.0", "@sigstore/protobuf-specs@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@sigstore/protobuf-specs/-/protobuf-specs-0.3.1.tgz#7095819fa7c5743efde48a858c37b30fab190a09" + integrity sha512-aIL8Z9NsMr3C64jyQzE0XlkEyBLpgEJJFDHLVVStkFV5Q3Il/r/YtY6NJWKQ4cy4AE7spP1IX5Jq7VCAxHHMfQ== -"@sigstore/sign@^2.2.3": - version "2.2.3" - resolved "https://registry.yarnpkg.com/@sigstore/sign/-/sign-2.2.3.tgz#f07bcd2cfee654fade867db44ae260f1a0142ba4" - integrity sha512-LqlA+ffyN02yC7RKszCdMTS6bldZnIodiox+IkT8B2f8oRYXCB3LQ9roXeiEL21m64CVH1wyveYAORfD65WoSw== +"@sigstore/sign@^2.3.0": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@sigstore/sign/-/sign-2.3.1.tgz#4fc4e6faee5689b5e9d42e97f1207273b7dd7b7f" + integrity sha512-YZ71wKIOweC8ViUeZXboz0iPLqMkskxuoeN/D1CEpAyZvEepbX9oRMIoO6a/DxUqO1VEaqmcmmqzSiqtOsvSmw== dependencies: - "@sigstore/bundle" "^2.2.0" + "@sigstore/bundle" "^2.3.0" "@sigstore/core" "^1.0.0" - "@sigstore/protobuf-specs" "^0.3.0" - make-fetch-happen "^13.0.0" + "@sigstore/protobuf-specs" "^0.3.1" + make-fetch-happen "^13.0.1" + proc-log "^4.2.0" + promise-retry "^2.0.1" "@sigstore/tuf@^2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@sigstore/tuf/-/tuf-2.3.1.tgz#86ff3c3c907e271696c88de0108d9063a8cbcc45" - integrity sha512-9Iv40z652td/QbV0o5n/x25H9w6IYRt2pIGbTX55yFDYlApDQn/6YZomjz6+KBx69rXHLzHcbtTS586mDdFD+Q== + version "2.3.3" + resolved "https://registry.yarnpkg.com/@sigstore/tuf/-/tuf-2.3.3.tgz#be416424d5133b61f1adcc75df72136bf1dfe1ff" + integrity sha512-agQhHNkIddXFslkudjV88vTXiAMEyUtso3at6ZHUNJ1agZb7Ze6VW/PddHipdWBu1t+8OWLW5X5yZOPiOnaWJQ== dependencies: "@sigstore/protobuf-specs" "^0.3.0" - tuf-js "^2.2.0" + tuf-js "^2.2.1" -"@sigstore/verify@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@sigstore/verify/-/verify-1.1.0.tgz#ab617c5dc0bc09ead7f101a848f4870af2d84374" - integrity sha512-1fTqnqyTBWvV7cftUUFtDcHPdSox0N3Ub7C0lRyReYx4zZUlNTZjCV+HPy4Lre+r45dV7Qx5JLKvqqsgxuyYfg== +"@sigstore/verify@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@sigstore/verify/-/verify-1.2.0.tgz#48549186305d8a5e471a3a304cf4cb3e0c99dde7" + integrity sha512-hQF60nc9yab+Csi4AyoAmilGNfpXT+EXdBgFkP9OgPwIBPwyqVf7JAWPtmqrrrneTmAT6ojv7OlH1f6Ix5BG4Q== dependencies: - "@sigstore/bundle" "^2.2.0" - "@sigstore/core" "^1.0.0" - "@sigstore/protobuf-specs" "^0.3.0" + "@sigstore/bundle" "^2.3.1" + "@sigstore/core" "^1.1.0" + "@sigstore/protobuf-specs" "^0.3.1" "@simplewebauthn/browser@9.0.1": version "9.0.1" @@ -5958,9 +5258,9 @@ integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== "@sinonjs/commons@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.0.tgz#beb434fe875d965265e04722ccfc21df7f755d72" - integrity sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA== + version "3.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd" + integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ== dependencies: type-detect "4.0.8" @@ -5972,9 +5272,9 @@ "@sinonjs/commons" "^3.0.0" "@stencil/core@^4.0.3": - version "4.13.0" - resolved "https://registry.yarnpkg.com/@stencil/core/-/core-4.13.0.tgz#31654b9c601ce8b74194903fe28ed4bcb66b576e" - integrity sha512-gg+gtBWekQ08mDja8GVAUHNu+rrFhQaKZDvfhnS3l/5JbYiJddTimuDPPhuc0sR0JZL1iRdJTJSa+JbvmnQ1cQ== + version "4.18.0" + resolved "https://registry.yarnpkg.com/@stencil/core/-/core-4.18.0.tgz#944d75c735f692517803904f8d43003307e1a2cb" + integrity sha512-cN+nvjy0L8KyYq7N1bmswN/AcBustFlsAxfyPQ+fd3m98lPo53jNKIxKve1ZQ4ZmzSzYO7alDhZvjIesM0rl7w== "@storybook/addon-actions@7.6.5": version "7.6.5" @@ -6640,17 +5940,10 @@ dependencies: lodash "^4.17.15" -"@storybook/csf@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.1.tgz#abccc8c3e49aed0a6a7e87beb0d1c262b1921c06" - integrity sha512-4hE3AlNVxR60Wc5KSC68ASYzUobjPqtSKyhV6G+ge0FIXU55N5nTY7dXGRZHQGDBPq+XqchMkIdlkHPRs8nTHg== - dependencies: - type-fest "^2.19.0" - -"@storybook/csf@^0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.2.tgz#8e7452f0097507f5841b5ade3f5da1525bc9afb2" - integrity sha512-ePrvE/pS1vsKR9Xr+o+YwdqNgHUyXvg+1Xjx0h9LrVx7Zq4zNe06pd63F5EvzTbCbJsHj7GHr9tkiaqm7U8WRA== +"@storybook/csf@^0.1.0", "@storybook/csf@^0.1.2": + version "0.1.7" + resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.7.tgz#dcc6c16a353bc09c8c619ba1a23ba93b2aab0b9d" + integrity sha512-53JeLZBibjQxi0Ep+/AJTfxlofJlxy1jXcSKENlnKxHjWEYyHQCumMP5yTFjf7vhNnMjEpV3zx6t23ssFiGRyw== dependencies: type-fest "^2.19.0" @@ -6857,91 +6150,93 @@ resolved "https://registry.yarnpkg.com/@stripe/stripe-js/-/stripe-js-1.47.0.tgz#48626a2e43302330aa826ce498a2d9761db4053d" integrity sha512-jKSClqEIKS2MbPCXlSsseDSZyJ3dVrfUrYMz5LBY1o9iS2tfKbpTZACt8r2g+xyQozI+uHr76pVTyFsmBKA4Mg== -"@swc/core-darwin-arm64@1.3.95": - version "1.3.95" - resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.95.tgz#e6b6363fc0a22ee3cd9a63130d2042d5027aae2c" - integrity sha512-VAuBAP3MNetO/yBIBzvorUXq7lUBwhfpJxYViSxyluMwtoQDhE/XWN598TWMwMl1ZuImb56d7eUsuFdjgY7pJw== - -"@swc/core-darwin-x64@1.3.95": - version "1.3.95" - resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.3.95.tgz#7911a03f4e0f9359710d3d6ad1dba7b5569efe5d" - integrity sha512-20vF2rvUsN98zGLZc+dsEdHvLoCuiYq/1B+TDeE4oolgTFDmI1jKO+m44PzWjYtKGU9QR95sZ6r/uec0QC5O4Q== - -"@swc/core-linux-arm-gnueabihf@1.3.95": - version "1.3.95" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.95.tgz#95a2c9fc6849df9f1944957669c82c559d65b24f" - integrity sha512-oEudEM8PST1MRNGs+zu0cx5i9uP8TsLE4/L9HHrS07Ck0RJ3DCj3O2fU832nmLe2QxnAGPwBpSO9FntLfOiWEQ== - -"@swc/core-linux-arm64-gnu@1.3.95": - version "1.3.95" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.95.tgz#1914d42041469582e3cc56619890edbcc54e83d6" - integrity sha512-pIhFI+cuC1aYg+0NAPxwT/VRb32f2ia8oGxUjQR6aJg65gLkUYQzdwuUmpMtFR2WVf7WVFYxUnjo4UyMuyh3ng== - -"@swc/core-linux-arm64-musl@1.3.95": - version "1.3.95" - resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.95.tgz#8d73822a5807575a572d6a2d6cb64587a9f19ce6" - integrity sha512-ZpbTr+QZDT4OPJfjPAmScqdKKaT+wGurvMU5AhxLaf85DuL8HwUwwlL0n1oLieLc47DwIJEMuKQkYhXMqmJHlg== - -"@swc/core-linux-x64-gnu@1.3.95": - version "1.3.95" - resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.95.tgz#80467727ec11da3de49e6be2abf735964a808483" - integrity sha512-n9SuHEFtdfSJ+sHdNXNRuIOVprB8nbsz+08apKfdo4lEKq6IIPBBAk5kVhPhkjmg2dFVHVo4Tr/OHXM1tzWCCw== - -"@swc/core-linux-x64-musl@1.3.95": - version "1.3.95" - resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.95.tgz#675a53ac037846bd1bb9840a95ebcb5289265d3b" - integrity sha512-L1JrVlsXU3LC0WwmVnMK9HrOT2uhHahAoPNMJnZQpc18a0paO9fqifPG8M/HjNRffMUXR199G/phJsf326UvVg== - -"@swc/core-win32-arm64-msvc@1.3.95": - version "1.3.95" - resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.95.tgz#7f0b5d0d0a090c5c625bbc54ffaf427d861c068a" - integrity sha512-YaP4x/aZbUyNdqCBpC2zL8b8n58MEpOUpmOIZK6G1SxGi+2ENht7gs7+iXpWPc0sy7X3YPKmSWMAuui0h8lgAA== - -"@swc/core-win32-ia32-msvc@1.3.95": - version "1.3.95" - resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.95.tgz#06e2778549a37f0b505b24fd8f40c1c038e29f3e" - integrity sha512-w0u3HI916zT4BC/57gOd+AwAEjXeUlQbGJ9H4p/gzs1zkSHtoDQghVUNy3n/ZKp9KFod/95cA8mbVF9t1+6epQ== - -"@swc/core-win32-x64-msvc@1.3.95": - version "1.3.95" - resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.95.tgz#40f6b131e84ba6ed97f516edf0f9d5a766c0da64" - integrity sha512-5RGnMt0S6gg4Gc6QtPUJ3Qs9Un4sKqccEzgH/tj7V/DVTJwKdnBKxFZfgQ34OR2Zpz7zGOn889xwsFVXspVWNA== +"@swc/core-darwin-arm64@1.5.5": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-arm64/-/core-darwin-arm64-1.5.5.tgz#65b40093f622ec811713d2e2ebcdf8a39ae2e91d" + integrity sha512-Ol5ZwZYdTOZsv2NwjcT/qVVALKzVFeh+IJ4GNarr3P99+38Dkwi81OqCI1o/WaDXQYKAQC/V+CzMbkEuJJfq9Q== + +"@swc/core-darwin-x64@1.5.5": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.5.5.tgz#4e16d5fb55d8f3fa7d95df85e9cfbb5d57a7ac9e" + integrity sha512-XHWpKBIPKYLgh5/lV2PYjO84lkzf5JR51kjiloyz2Pa9HIV8tHoAP8bYdJwm4nUp2I7KcEh3pPH0AVu5LpxMKw== + +"@swc/core-linux-arm-gnueabihf@1.5.5": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.5.5.tgz#ab3fbac59b7c527fa5da115a96f3c87e07737686" + integrity sha512-vtoWNCWAe+CNSqtqIwFnIH48qgPPlUZKoQ4EVFeMM+7/kDi6SeNxoh5TierJs5bKAWxD49VkPvRoWFCk6V62mA== + +"@swc/core-linux-arm64-gnu@1.5.5": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.5.5.tgz#fcfb1d97f8e8ac6bd495aaaa0d15f8dfdb33b76b" + integrity sha512-L4l7M78U6h/rCAxId+y5Vu+1KfDRF6dJZtitFcaT293guiUQFwJv8gLxI4Jh5wFtZ0fYd0QaCuvh2Ip79CzGMg== + +"@swc/core-linux-arm64-musl@1.5.5": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.5.5.tgz#e8678d350500b3784bb125bef4eb97db1e388442" + integrity sha512-DkzJc13ukXa7oJpyn24BjIgsiOybYrc+IxjsQyfNlDrrs1QXP4elStcpkD02SsIuSyHjZV8Hw2HFBMQB3OHPrA== + +"@swc/core-linux-x64-gnu@1.5.5": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.5.5.tgz#e68406379d55447217a4ac1a79ffc7ce1e251b29" + integrity sha512-kj4ZwWJGeBEUzHrRQP2VudN+kkkYH7OI1dPVDc6kWQx5X4329JeKOas4qY0l7gDVjBbRwN9IbbPI6TIn2KfAug== + +"@swc/core-linux-x64-musl@1.5.5": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.5.5.tgz#40e439aeb265c3cc63526c51f4e89f6492092159" + integrity sha512-6pTorCs4mYhPhYtC4jNOnhGgjNd3DZcRoZ9P0tzXXP69aCbYjvlgNH/NRvAROp9AaVFeZ7a7PmCWb6+Rbe7NKg== + +"@swc/core-win32-arm64-msvc@1.5.5": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.5.5.tgz#efdd773a9e7ecc49bb246362a45dfc389f1fbfe0" + integrity sha512-o0/9pstmEjwZyrY/bA+mymF0zH7E+GT/XCVqdKeWW9Wn3gTTyWa5MZnrFgI2THQ+AXwdglMB/Zo76ARQPaz/+A== + +"@swc/core-win32-ia32-msvc@1.5.5": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.5.5.tgz#02082adef99bfa0101c6c94b04be636e39ed567f" + integrity sha512-B+nypUwsmCuaH6RtKWgiPCb+ENjxstJPPJeMJvBqlJqyCaIkZzN4M07Ozi3xVv1VG21SRkd6G3xIqRoalrNc0Q== + +"@swc/core-win32-x64-msvc@1.5.5": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.5.5.tgz#699217ea438eb3b533b73d982659891d9aae7379" + integrity sha512-ry83ki9ZX0Q+GWGnqc2J618Z+FvKE8Ajn42F8EYi8Wj0q6Jz3mj+pJzgzakk2INm2ldEZ+FaRPipn4ozsZDcBg== "@swc/core@^1.3.82": - version "1.3.95" - resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.3.95.tgz#2743b8460e6f29385e3dbe49f3f66277ab233536" - integrity sha512-PMrNeuqIusq9DPDooV3FfNEbZuTu5jKAc04N3Hm6Uk2Fl49cqElLFQ4xvl4qDmVDz97n3n/C1RE0/f6WyGPEiA== + version "1.5.5" + resolved "https://registry.yarnpkg.com/@swc/core/-/core-1.5.5.tgz#e7b7ae4323d15ba990a0ffde135a849ffddec69d" + integrity sha512-M8O22EEgdSONLd+7KRrXj8pn+RdAZZ7ISnPjE9KCQQlI0kkFNEquWR+uFdlFxQfwlyCe/Zb6uGXGDvtcov4IMg== dependencies: - "@swc/counter" "^0.1.1" + "@swc/counter" "^0.1.2" "@swc/types" "^0.1.5" optionalDependencies: - "@swc/core-darwin-arm64" "1.3.95" - "@swc/core-darwin-x64" "1.3.95" - "@swc/core-linux-arm-gnueabihf" "1.3.95" - "@swc/core-linux-arm64-gnu" "1.3.95" - "@swc/core-linux-arm64-musl" "1.3.95" - "@swc/core-linux-x64-gnu" "1.3.95" - "@swc/core-linux-x64-musl" "1.3.95" - "@swc/core-win32-arm64-msvc" "1.3.95" - "@swc/core-win32-ia32-msvc" "1.3.95" - "@swc/core-win32-x64-msvc" "1.3.95" - -"@swc/counter@^0.1.1": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@swc/counter/-/counter-0.1.2.tgz#bf06d0770e47c6f1102270b744e17b934586985e" - integrity sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw== + "@swc/core-darwin-arm64" "1.5.5" + "@swc/core-darwin-x64" "1.5.5" + "@swc/core-linux-arm-gnueabihf" "1.5.5" + "@swc/core-linux-arm64-gnu" "1.5.5" + "@swc/core-linux-arm64-musl" "1.5.5" + "@swc/core-linux-x64-gnu" "1.5.5" + "@swc/core-linux-x64-musl" "1.5.5" + "@swc/core-win32-arm64-msvc" "1.5.5" + "@swc/core-win32-ia32-msvc" "1.5.5" + "@swc/core-win32-x64-msvc" "1.5.5" + +"@swc/counter@^0.1.2", "@swc/counter@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@swc/counter/-/counter-0.1.3.tgz#cc7463bd02949611c6329596fccd2b0ec782b0e9" + integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ== "@swc/helpers@^0.5.0": - version "0.5.3" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.3.tgz#98c6da1e196f5f08f977658b80d6bd941b5f294f" - integrity sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A== + version "0.5.11" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.11.tgz#5bab8c660a6e23c13b2d23fcd1ee44a2db1b0cb7" + integrity sha512-YNlnKRWF2sVojTpIyzwou9XoTNbzbzONwRhOoniEioF1AtaitTvVZblaQRrAzChWQ1bLYyYSWzM18y4WwgzJ+A== dependencies: tslib "^2.4.0" "@swc/types@^0.1.5": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@swc/types/-/types-0.1.5.tgz#043b731d4f56a79b4897a3de1af35e75d56bc63a" - integrity sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw== + version "0.1.6" + resolved "https://registry.yarnpkg.com/@swc/types/-/types-0.1.6.tgz#2f13f748995b247d146de2784d3eb7195410faba" + integrity sha512-/JLo/l2JsT/LRd80C3HfbmVpxOAJ11FO2RCEslFrgzLltoP9j8XIbsyDcfCt2WWyX+CM96rBoNM+IToAkFOugg== + dependencies: + "@swc/counter" "^0.1.3" "@szmarczak/http-timer@^4.0.5": version "4.0.6" @@ -6973,9 +6268,9 @@ integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== "@tsconfig/node10@^1.0.7": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" - integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.11.tgz#6ee46400685f130e278128c7b38b7e031ff5b2f2" + integrity sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw== "@tsconfig/node12@^1.0.7": version "1.0.11" @@ -6997,15 +6292,15 @@ resolved "https://registry.yarnpkg.com/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz#a52f61a3d7374833fca945b2549bc30a2dd40d0a" integrity sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA== -"@tufjs/models@2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@tufjs/models/-/models-2.0.0.tgz#c7ab241cf11dd29deb213d6817dabb8c99ce0863" - integrity sha512-c8nj8BaOExmZKO2DXhDfegyhSGcG9E/mPN3U13L+/PsoWm1uaGiHHjxqSHQiasDBQwDA3aHuw9+9spYAP1qvvg== +"@tufjs/models@2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@tufjs/models/-/models-2.0.1.tgz#e429714e753b6c2469af3212e7f320a6973c2812" + integrity sha512-92F7/SFyufn4DXsha9+QfKnN03JGqtMFMXgSHbZOo8JG59WkTni7UzAouNQDf7AuP9OAMxVOPQcqG3sB7w+kkg== dependencies: "@tufjs/canonical-json" "2.0.0" - minimatch "^9.0.3" + minimatch "^9.0.4" -"@types/babel__core@7.20.5": +"@types/babel__core@7.20.5", "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": version "7.20.5" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== @@ -7016,36 +6311,25 @@ "@types/babel__template" "*" "@types/babel__traverse" "*" -"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": - version "7.20.3" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.3.tgz#d5625a50b6f18244425a1359a858c73d70340778" - integrity sha512-54fjTSeSHwfan8AyHWrKbfBWiEUrNTZsUwPTDSNaaP1QDQIZbeNUg3a59E9D+375MzUw/x1vx2/0F5LBz+AeYA== - dependencies: - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" - "@types/babel__generator@*": - version "7.6.6" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.6.tgz#676f89f67dc8ddaae923f70ebc5f1fa800c031a8" - integrity sha512-66BXMKb/sUWbMdBNdMvajU7i/44RkrA3z/Yt1c7R5xejt8qh84iU54yUWCtm0QwGJlDcf/gg4zd/x4mpLAlb/w== + version "7.6.8" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" + integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== dependencies: "@babel/types" "^7.0.0" "@types/babel__template@*": - version "7.4.3" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.3.tgz#db9ac539a2fe05cfe9e168b24f360701bde41f5f" - integrity sha512-ciwyCLeuRfxboZ4isgdNZi/tkt06m8Tw6uGbBSBgWrnnZGNXiEyM27xc/PjXGQLqlZ6ylbgHMnm7ccF9tCkOeQ== + version "7.4.4" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.20.3" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.3.tgz#a971aa47441b28ef17884ff945d0551265a2d058" - integrity sha512-Lsh766rGEFbaxMIDH7Qa+Yha8cMVI3qAK6CHt3OR0YfxOIn5Z54iHiyDRycHrBqeIiqGa20Kpsv1cavfBKkRSw== + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.5.tgz#7b7502be0aa80cc4ef22978846b983edaafcd4dd" + integrity sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ== dependencies: "@babel/types" "^7.20.7" @@ -7055,9 +6339,9 @@ integrity sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA== "@types/body-parser@*": - version "1.19.4" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.4.tgz#78ad68f1f79eb851aa3634db0c7f57f6f601b462" - integrity sha512-N7UDG0/xiPQa2D/XrVJXjkWbpqHCd2sBaB32ggRF2l83RhPfamgKGF8gwwqyksS95qUS5ZYF9aF+lLPRlwI2UA== + version "1.19.5" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" + integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== dependencies: "@types/connect" "*" "@types/node" "*" @@ -7071,9 +6355,9 @@ "@types/node" "*" "@types/bonjour@^3.5.9": - version "3.5.12" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.12.tgz#49badafb988e6c433ca675a5fd769b93b7649fc8" - integrity sha512-ky0kWSqXVxSqgqJvPIkgFkcn4C8MnRog308Ou8xBBIVo39OmUFy+jqNe0nPwLCDFxUpmT9EvT91YzOJgkDRcFg== + version "3.5.13" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.13.tgz#adf90ce1a105e81dd1f9c61fdc5afda1bfb92956" + integrity sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ== dependencies: "@types/node" "*" @@ -7093,16 +6377,16 @@ "@types/responselike" "^1.0.0" "@types/color-convert@*": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@types/color-convert/-/color-convert-2.0.2.tgz#a5fa5da9b866732f8bf86b01964869011e2a2356" - integrity sha512-KGRIgCxwcgazts4MXRCikPbIMzBpjfdgEZSy8TRHU/gtg+f9sOfHdtK8unPfxIoBtyd2aTTwINVLSNENlC8U8A== + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/color-convert/-/color-convert-2.0.3.tgz#e93f5c991eda87a945058b47044f5f0008b0dce9" + integrity sha512-2Q6wzrNiuEvYxVQqhh7sXM2mhIhvZR/Paq4FdsQkOMgWsCIkKvSGj8Le1/XalulrmgOzPMqNa0ix+ePY4hTrfg== dependencies: "@types/color-name" "*" "@types/color-name@*": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.2.tgz#bdeeb6fdcb78969033767951ab0cb26c7514a658" - integrity sha512-JWO/ZyxTKk0bLuOhAavGjnwLR73rUE7qzACnU7gMeyA/gdrSHm2xJwqNPipw2MtaZUaqQ2UG/q7pP6AQiZ8mqw== + version "1.1.4" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.4.tgz#e002611ff627347818d440a05e81650e9a4053b8" + integrity sha512-hulKeREDdLFesGQjl96+4aoJSHY5b2GRjagzzcqCfIrWhe5vkCqIvrLbqzBaI1q94Vg8DNJZZqTR5ocdWmWclg== "@types/color@3.0.3": version "3.0.3" @@ -7112,24 +6396,24 @@ "@types/color-convert" "*" "@types/connect-history-api-fallback@^1.3.5": - version "1.5.2" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.2.tgz#acf51e088b3bb6507f7b093bd2b0de20940179cc" - integrity sha512-gX2j9x+NzSh4zOhnRPSdPPmTepS4DfxES0AvIFv3jGv5QyeAJf6u6dY5/BAoAJU9Qq1uTvwOku8SSC2GnCRl6Q== + version "1.5.4" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz#7de71645a103056b48ac3ce07b3520b819c1d5b3" + integrity sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw== dependencies: "@types/express-serve-static-core" "*" "@types/node" "*" "@types/connect@*": - version "3.4.37" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.37.tgz#c66a96689fd3127c8772eb3e9e5c6028ec1a9af5" - integrity sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q== + version "3.4.38" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== dependencies: "@types/node" "*" "@types/cross-spawn@^6.0.2": - version "6.0.4" - resolved "https://registry.yarnpkg.com/@types/cross-spawn/-/cross-spawn-6.0.4.tgz#e658d29e2308a01f48b7b30fd8cdf07aeb2e5a82" - integrity sha512-GGLpeThc2Bu8FBGmVn76ZU3lix17qZensEI4/MPty0aZpm2CHfgEMis31pf5X5EiudYKcPAsWciAsCALoPo5dw== + version "6.0.6" + resolved "https://registry.yarnpkg.com/@types/cross-spawn/-/cross-spawn-6.0.6.tgz#0163d0b79a6f85409e0decb8dcca17147f81fd22" + integrity sha512-fXRhhUkG4H3TQk5dBhQ7m/JDdSNHKwR2BBia62lhwEIq9xGiQKLxd6LymNhn47SjXhsUEPmxi+PKw2OkW4LLjA== dependencies: "@types/node" "*" @@ -7158,9 +6442,9 @@ "@types/ms" "*" "@types/detect-port@^1.3.0": - version "1.3.4" - resolved "https://registry.yarnpkg.com/@types/detect-port/-/detect-port-1.3.4.tgz#cd34ab0f26391f5b9c5c9bb4c9e370dfbf9e4d05" - integrity sha512-HveFGabu3IwATqwLelcp6UZ1MIzSFwk+qswC9luzzHufqAwhs22l7KkINDLWRfXxIPTYnSZ1DuQBEgeVPgUOSA== + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/detect-port/-/detect-port-1.3.5.tgz#deecde143245989dee0e82115f3caba5ee0ea747" + integrity sha512-Rf3/lB9WkDfIL9eEKaSYKc+1L/rNVYBjThk22JTqQw0YozXarX8YljFAz+HCoC6h4B4KwCMsBPZHaFezwT4BNA== "@types/doctrine@^0.0.3": version "0.0.3" @@ -7168,45 +6452,40 @@ integrity sha512-w5jZ0ee+HaPOaX25X2/2oGR/7rgAQSYII7X7pp0m9KgBfMP7uKfMfTvcpl5Dj+eDBbpxKGiqE+flqDr6XTd2RA== "@types/ejs@^3.1.1": - version "3.1.4" - resolved "https://registry.yarnpkg.com/@types/ejs/-/ejs-3.1.4.tgz#b9919c89767493b6443f85994ae6be6e49011b5c" - integrity sha512-fnM/NjByiWdSRJRrmGxgqOSAnmOnsvX1QcNYk5TVyIIj+7ZqOKMb9gQa4OIl/lil2w/8TiTWV+nz3q8yqxez/w== + version "3.1.5" + resolved "https://registry.yarnpkg.com/@types/ejs/-/ejs-3.1.5.tgz#49d738257cc73bafe45c13cb8ff240683b4d5117" + integrity sha512-nv+GSx77ZtXiJzwKdsASqi+YQ5Z7vwHsTP0JY2SiQgjGckkBRKZnk8nIM+7oUZ1VCtuTz0+By4qVR7fqzp/Dfg== "@types/emscripten@^1.39.6": - version "1.39.9" - resolved "https://registry.yarnpkg.com/@types/emscripten/-/emscripten-1.39.9.tgz#cbe73a8d153fc714a2e3177fbda2d7332d45efa7" - integrity sha512-ILdWj4XYtNOqxJaW22NEQx2gJsLfV5ncxYhhGX1a1H1lXl2Ta0gUz7QOnOoF1xQbJwWDjImi8gXN9mKdIf6n9g== + version "1.39.11" + resolved "https://registry.yarnpkg.com/@types/emscripten/-/emscripten-1.39.11.tgz#8f8c40cb831a2406c0ee5b0c6e847b3bf659c2e3" + integrity sha512-dOeX2BeNA7j6BTEqJQL3ut0bRCfsyQMd5i4FT8JfHfYhAOuJPCGh0dQFbxVJxUyQ+75x6enhDdndGb624/QszA== "@types/eslint-scope@^3.7.3": - version "3.7.6" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.6.tgz#585578b368ed170e67de8aae7b93f54a1b2fdc26" - integrity sha512-zfM4ipmxVKWdxtDaJ3MP3pBurDXOCoyjvlpE3u6Qzrmw4BPbfm4/ambIeTk/r/J0iq/+2/xp0Fmt+gFvXJY2PQ== + version "3.7.7" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" + integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== dependencies: "@types/eslint" "*" "@types/estree" "*" "@types/eslint@*": - version "8.44.6" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.6.tgz#60e564551966dd255f4c01c459f0b4fb87068603" - integrity sha512-P6bY56TVmX8y9J87jHNgQh43h6VVU+6H7oN7hgvivV81K2XY8qJZ5vqPy/HdUoVIelii2kChYVzQanlswPWVFw== + version "8.56.10" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.56.10.tgz#eb2370a73bf04a901eeba8f22595c7ee0f7eb58d" + integrity sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ== dependencies: "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*", "@types/estree@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.3.tgz#2be19e759a3dd18c79f9f436bd7363556c1a73dd" - integrity sha512-CS2rOaoQ/eAgAfcTfq6amKG7bsN+EMcgGY4FAFQdvSj2y1ixvOZTUA9mOtCai7E1SYu283XNw7urKK30nP3wkQ== - -"@types/estree@1.0.5", "@types/estree@^1.0.5": +"@types/estree@*", "@types/estree@1.0.5", "@types/estree@^1.0.5": version "1.0.5" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": - version "4.17.39" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.39.tgz#2107afc0a4b035e6cb00accac3bdf2d76ae408c8" - integrity sha512-BiEUfAiGCOllomsRAZOiMFP7LAnrifHpt56pc4Z7l9K6ACyN06Ns1JLMBxwkfLOjJRlSf06NwWsT7yzfpaVpyQ== + version "4.19.0" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.0.tgz#3ae8ab3767d98d0b682cda063c3339e1e86ccfaa" + integrity sha512-bGyep3JqPCRry1wq+O5n7oiBgGWmeIJXPjXXCo8EK0u8duZGSYar7cGqd3ML2JUsLGeB7fmc06KYo9fLGWqPvQ== dependencies: "@types/node" "*" "@types/qs" "*" @@ -7214,9 +6493,9 @@ "@types/send" "*" "@types/express@*", "@types/express@^4.17.13", "@types/express@^4.7.0": - version "4.17.20" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.20.tgz#e7c9b40276d29e38a4e3564d7a3d65911e2aa433" - integrity sha512-rOaqlkgEvOW495xErXMsmyX3WKBInbhG5eqojXYi3cGUaLoRDlXa5d52fkfWZT963AZ3v2eZ4MbKE6WpDAGVsw== + version "4.17.21" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" + integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== dependencies: "@types/body-parser" "*" "@types/express-serve-static-core" "^4.17.33" @@ -7250,9 +6529,9 @@ integrity sha512-7N+mDtZ1pmya2RRFPPl4KYc2TRgiqCNBLUZfyrKfER+u751JgCO+C24/LzF70UmUm/zhHUbzRZ5mtfaxekQ1ZQ== "@types/graceful-fs@^4.1.3": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.8.tgz#417e461e4dc79d957dc3107f45fe4973b09c2915" - integrity sha512-NhRH7YzWq8WiNKVavKPBmtLYZHxNY19Hh+az28O/phfp68CF45pMFud+ZzJ8ewnxnC5smIdF3dqFeiSUQ5I+pw== + version "4.1.9" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" + integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== dependencies: "@types/node" "*" @@ -7262,38 +6541,38 @@ integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== "@types/http-cache-semantics@*": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz#a3ff232bf7d5c55f38e4e45693eda2ebb545794d" - integrity sha512-V46MYLFp08Wf2mmaBhvgjStM3tPa+2GAdy/iqoX+noX1//zje2x4XmrIU0cAwyClATsTmahbtoQ2EwP7I5WSiA== + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" + integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== "@types/http-errors@*": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.3.tgz#c54e61f79b3947d040f150abd58f71efb422ff62" - integrity sha512-pP0P/9BnCj1OVvQR2lF41EkDG/lWWnDyA203b/4Fmi2eTyORnBtcDoKDwjWQthELrBvWkMOrvSOnZ8OVlW6tXA== + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" + integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== "@types/http-proxy@^1.17.8": - version "1.17.13" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.13.tgz#dd3a4da550580eb0557d4c7128a2ff1d1a38d465" - integrity sha512-GkhdWcMNiR5QSQRYnJ+/oXzu0+7JJEPC8vkWXK351BkhjraZF+1W13CUYARUvX9+NqIU2n6YHA4iwywsc/M6Sw== + version "1.17.14" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.14.tgz#57f8ccaa1c1c3780644f8a94f9c6b5000b5e2eec" + integrity sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w== dependencies: "@types/node" "*" "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#fdfdd69fa16d530047d9963635bd77c71a08c068" - integrity sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ== + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== "@types/istanbul-lib-report@*": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.2.tgz#394798d5f727402eb5ec99eb9618ffcd2b7645a1" - integrity sha512-8toY6FgdltSdONav1XtUHl4LN1yTmLza+EuDazb/fEmRNCwjyqNVIQWs2IfC74IqjHkREs/nQ2FWq5kZU9IC0w== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" + integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== dependencies: "@types/istanbul-lib-coverage" "*" "@types/istanbul-reports@^3.0.0": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.3.tgz#0313e2608e6d6955d195f55361ddeebd4b74c6e7" - integrity sha512-1nESsePMBlf0RPRffLZi5ujYh7IH1BWL4y9pr+Bn3cJBdxz+RTP8bUFljLz9HvzhhOSWKdyBZ4DIivdL6rvgZg== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" + integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== dependencies: "@types/istanbul-lib-report" "*" @@ -7314,12 +6593,7 @@ "@types/tough-cookie" "*" parse5 "^7.0.0" -"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.14" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.14.tgz#74a97a5573980802f32c8e47b663530ab3b6b7d1" - integrity sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw== - -"@types/json-schema@^7.0.12": +"@types/json-schema@*", "@types/json-schema@^7.0.12", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -7330,9 +6604,9 @@ integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== "@types/jsonfile@*": - version "6.1.3" - resolved "https://registry.yarnpkg.com/@types/jsonfile/-/jsonfile-6.1.3.tgz#683d447b413119393e913ecd414a2bc0e5d0f4b9" - integrity sha512-/yqTk2SZ1wIezK0hiRZD7RuSf4B3whFxFamB1kGStv+8zlWScTMcHanzfc0XKWs5vA1TkHeckBlOyM8jxU8nHA== + version "6.1.4" + resolved "https://registry.yarnpkg.com/@types/jsonfile/-/jsonfile-6.1.4.tgz#614afec1a1164e7d670b4a7ad64df3e7beb7b702" + integrity sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ== dependencies: "@types/node" "*" @@ -7356,9 +6630,9 @@ integrity sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA== "@types/lodash@^4.14.167": - version "4.14.200" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.200.tgz#435b6035c7eba9cdf1e039af8212c9e9281e7149" - integrity sha512-YI/M/4HRImtNf3pJgbF+W6FrXovqj+T+/HpENLTooK9PnkacBsDpeP3IpHab40CClUfhNmdM2WTNP2sa2dni5Q== + version "4.17.1" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.1.tgz#0fabfcf2f2127ef73b119d98452bd317c4a17eb8" + integrity sha512-X+2qazGS3jxLAIz5JDXDzglAF3KpijdhFxlf/V1+hEsOUc+HnWi81L/uv/EvGuV90WY+7mPGFCUDGfQC3Gj95Q== "@types/mdast@^3.0.0": version "3.0.15" @@ -7368,24 +6642,19 @@ "@types/unist" "^2" "@types/mdx@^2.0.0": - version "2.0.9" - resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.9.tgz#80971e367bb884350ab5b2ce8fc06b34960170e7" - integrity sha512-OKMdj17y8Cs+k1r0XFyp59ChSOwf8ODGtMQ4mnpfz5eFDk1aO41yN3pSKGuvVzmWAkFp37seubY1tzOVpwfWwg== + version "2.0.13" + resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.13.tgz#68f6877043d377092890ff5b298152b0a21671bd" + integrity sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw== "@types/mime-types@^2.1.0": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@types/mime-types/-/mime-types-2.1.3.tgz#0688436864f87a0c8e33ca12be60cd791cc24b36" - integrity sha512-bvxCbHeeS7quxS7uOJShyoOQj/BfLabhF6mk9Rmr+2MRfW8W1yxyyL/0GTxLFTHen41GrIw4K3D4DrLouhb8vg== - -"@types/mime@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.3.tgz#886674659ce55fe7c6c06ec5ca7c0eb276a08f91" - integrity sha512-i8MBln35l856k5iOhKk2XJ4SeAWg75mLIpZB4v6imOagKL6twsukBZGDMNhdOVk7yRFTMPpfILocMos59Q1otQ== + version "2.1.4" + resolved "https://registry.yarnpkg.com/@types/mime-types/-/mime-types-2.1.4.tgz#93a1933e24fed4fb9e4adc5963a63efcbb3317a2" + integrity sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w== "@types/mime@^1": - version "1.3.4" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.4.tgz#a4ed836e069491414bab92c31fdea9e557aca0d9" - integrity sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw== + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== "@types/minimatch@^5.1.2": version "5.1.2" @@ -7398,24 +6667,24 @@ integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== "@types/node-fetch@^2.5.7", "@types/node-fetch@^2.6.4": - version "2.6.7" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.7.tgz#a1abe2ce24228b58ad97f99480fdcf9bbc6ab16d" - integrity sha512-lX17GZVpJ/fuCjguZ5b3TjEbSENxmEk1B2z02yoXSK9WMEWRivhdSY73wWMn6bpcCDAOh6qAdktpKHIlkDk2lg== + version "2.6.11" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.11.tgz#9b39b78665dae0e82a08f02f4967d62c66f95d24" + integrity sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g== dependencies: "@types/node" "*" form-data "^4.0.0" "@types/node-forge@^1.3.0": - version "1.3.8" - resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.8.tgz#044ad98354ff309a031a55a40ad122f3be1ac2bb" - integrity sha512-vGXshY9vim9CJjrpcS5raqSjEfKlJcWy2HNdgUasR66fAnVEYarrf1ULV4nfvpC1nZq/moA9qyqBcu83x+Jlrg== + version "1.3.11" + resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.11.tgz#0972ea538ddb0f4d9c2fa0ec5db5724773a604da" + integrity sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ== dependencies: "@types/node" "*" "@types/node@*", "@types/node@>=8.1.0": - version "20.8.9" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.9.tgz#646390b4fab269abce59c308fc286dcd818a2b08" - integrity sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg== + version "20.12.11" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.11.tgz#c4ef00d3507000d17690643278a60dc55a9dc9be" + integrity sha512-vDg9PZ/zi+Nqp6boSOT7plNuthRugEKixDv5sFTIpkE89MmNtEArAShI4mxuX2+UrLEe9pxC1vm2cjm9YlWbJw== dependencies: undici-types "~5.26.4" @@ -7425,33 +6694,33 @@ integrity sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw== "@types/node@^16.0.0": - version "16.18.59" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.59.tgz#4cdbd631be6d9be266a96fb17b5d0d7ad6bbe26c" - integrity sha512-PJ1w2cNeKUEdey4LiPra0ZuxZFOGvetswE8qHRriV/sUkL5Al4tTmPV9D2+Y/TPIxTHHgxTfRjZVKWhPw/ORhQ== + version "16.18.97" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.97.tgz#d7926a8030f0d714d555b4550c0cc7731495cfe5" + integrity sha512-4muilE1Lbfn57unR+/nT9AFjWk0MtWi5muwCEJqnOvfRQDbSfLCUdN7vCIg8TYuaANfhLOV85ve+FNpiUsbSRg== "@types/node@^18.0.0": - version "18.18.7" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.18.7.tgz#bb3a7068dc4ba421b6968f2a259298b3a4e129e8" - integrity sha512-bw+lEsxis6eqJYW8Ql6+yTqkE6RuFtsQPSe5JxXbqYRFQEER5aJA9a5UH9igqDWm3X4iLHIKOHlnAXLM4mi7uQ== + version "18.19.33" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.33.tgz#98cd286a1b8a5e11aa06623210240bcc28e95c48" + integrity sha512-NR9+KrpSajr2qBVp/Yt5TU/rp+b5Mayi3+OlMlcg2cVCfRmcG5PWZ7S4+MG9PZ5gWBoc9Pd0BKSRViuBCRPu0A== dependencies: undici-types "~5.26.4" "@types/normalize-package-data@^2.4.0": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.3.tgz#291c243e4b94dbfbc0c0ee26b7666f1d5c030e2c" - integrity sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg== + version "2.4.4" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" + integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== "@types/npmlog@^4.1.2": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.5.tgz#41f1b95437f9c86cbb326bb07f0d5683f905bf4f" - integrity sha512-Fl3TEbwPoR7V1z6CMJ18whXOUkOYqF5eCkGKTir2VuevdLYUmcwj9mQdvXzuY0oagZBbsy0J7df41jn+ZcwGRA== + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.6.tgz#792341665000209ee76997df8a16300fda6d77cb" + integrity sha512-0l3z16vnlJGl2Mi/rgJFrdwfLZ4jfNYgE6ZShEpjqhHuGTqdEzNles03NpYHwUMVYZa+Tj46UxKIEpE78lQ3DQ== dependencies: "@types/node" "*" "@types/oauth@*": - version "0.9.3" - resolved "https://registry.yarnpkg.com/@types/oauth/-/oauth-0.9.3.tgz#4be90beb6c4a23e1a1614c966a165af1ef5e5e0d" - integrity sha512-avZiwxSz/WS6EaEjhchzXKgWtlGGYGnEVJoHuQuDLHf7gIW1Gmm9eIxOMuJ6umQNNKZkJ3Uy+C/rLzEvL3I8Sw== + version "0.9.4" + resolved "https://registry.yarnpkg.com/@types/oauth/-/oauth-0.9.4.tgz#dcbab5efa2f34f312b915f80685760ccc8111e0a" + integrity sha512-qk9orhti499fq5XxKCCEbd0OzdPZuancneyse3KtR+vgMiHRbh+mn8M4G6t64ob/Fg+GZGpa565MF/2dKWY32A== dependencies: "@types/node" "*" @@ -7463,9 +6732,9 @@ "@types/node" "*" "@types/parse-json@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.1.tgz#27f7559836ad796cea31acb63163b203756a5b4e" - integrity sha512-3YmXzzPAdOTVljVMkTMBdBEvlOLg2cDQaDhnnhT3nT9uDbnJzjWhKlzb+desT12Y7tGqaN6d+AbozcKzyL36Ng== + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" + integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== "@types/passport-google-oauth20@2.0.11": version "2.0.11" @@ -7477,35 +6746,35 @@ "@types/passport-oauth2" "*" "@types/passport-oauth2@*": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@types/passport-oauth2/-/passport-oauth2-1.4.14.tgz#6982575b960eb7f001e28103ac3562349f1cded3" - integrity sha512-wZBvnRwqdvm35l1Jn9ebYm2Q7UtxYIdBu1PjoKXMoxJytniVjXxYJmrlDXn5fMZROWbJbnEnp1XSDANqtvMdGQ== + version "1.4.16" + resolved "https://registry.yarnpkg.com/@types/passport-oauth2/-/passport-oauth2-1.4.16.tgz#59189a9d69783a63d7fb92d19cd28f96c95740af" + integrity sha512-Sdr0rpAdkiidUOtyaapGgvXyMjqYlMTFHRy7gtJtzr0/ysEIa72N3j2FSHIRc14h29g1+dzDl8IW2WT2Mu29vQ== dependencies: "@types/express" "*" "@types/oauth" "*" "@types/passport" "*" "@types/passport@*": - version "1.0.14" - resolved "https://registry.yarnpkg.com/@types/passport/-/passport-1.0.14.tgz#7ca891b04ae08d7ca4dbf30fece7c86174a16db9" - integrity sha512-D6p2ygR2S7Cq5PO7iUaEIQu/5WrM0tONu6Lxgk0C9r3lafQIlVpWCo3V/KI9To3OqHBxcfQaOeK+8AvwW5RYmw== + version "1.0.16" + resolved "https://registry.yarnpkg.com/@types/passport/-/passport-1.0.16.tgz#5a2918b180a16924c4d75c31254c31cdca5ce6cf" + integrity sha512-FD0qD5hbPWQzaM0wHUnJ/T0BBCJBxCeemtnCwc/ThhTg3x9jfrAcRUmj5Dopza+MfFS9acTe3wk7rcVnRIp/0A== dependencies: "@types/express" "*" "@types/pretty-hrtime@^1.0.0": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.2.tgz#9b6e102bc2e1eea1c1c7fadf144483ce2687f233" - integrity sha512-vyv9knII8XeW8TnXDcGH7HqG6FeR56ESN6ExM34d/U8Zvs3xuG34euV6CVyB7KEYI7Ts4lQM8b4NL72e7UadnA== + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#ee1bd8c9f7a01b3445786aad0ef23aba5f511a44" + integrity sha512-nj39q0wAIdhwn7DGUyT9irmsKK1tV0bd5WFEhgpqNTMFZ8cE+jieuTphCW0tfdm47S2zVT5mr09B28b1chmQMA== "@types/prop-types@*": - version "15.7.9" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.9.tgz#b6f785caa7ea1fe4414d9df42ee0ab67f23d8a6d" - integrity sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g== + version "15.7.12" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6" + integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q== "@types/qs@*", "@types/qs@^6.9.5": - version "6.9.9" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.9.tgz#66f7b26288f6799d279edf13da7ccd40d2fa9197" - integrity sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg== + version "6.9.15" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.15.tgz#adde8a060ec9c305a82de1babc1056e73bd64dce" + integrity sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg== "@types/ramda@0.29.3": version "0.29.3" @@ -7515,39 +6784,38 @@ types-ramda "^0.29.4" "@types/range-parser@*": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.6.tgz#7cb33992049fd7340d5b10c0098e104184dfcd2a" - integrity sha512-+0autS93xyXizIYiyL02FCY8N+KkKPhILhcUSA276HxzreZ16kl+cmwvV2qAM/PuCCwPXzOXOWhiPcw20uSFcA== + version "1.2.7" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" + integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== "@types/react-dom@^16.9.14": - version "16.9.21" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.21.tgz#4f937ae64f39c2766401750e069319224348306c" - integrity sha512-QdKxI502bJXRfFR8/pH0iCyt51EcPf1+hgCIZKJ9SBunj0NZpKK5j1FDoCGeGj/6ROK8gUesj41V3C64Rz2kHw== + version "16.9.24" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.24.tgz#4d193d7d011267fca842e8a10a2d738f92ec5c30" + integrity sha512-Gcmq2JTDheyWn/1eteqyzzWKSqDjYU6KYsIvH7thb7CR5OYInAWOX+7WnKf6PaU/cbdOc4szJItcDEJO7UGmfA== dependencies: "@types/react" "^16" "@types/react@>=16": - version "18.2.33" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.33.tgz#055356243dc4350a9ee6c6a2c07c5cae12e38877" - integrity sha512-v+I7S+hu3PIBoVkKGpSYYpiBT1ijqEzWpzQD62/jm4K74hPpSP7FF9BnKG6+fg2+62weJYkkBWDJlZt5JO/9hg== + version "18.3.1" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.1.tgz#fed43985caa834a2084d002e4771e15dfcbdbe8e" + integrity sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw== dependencies: "@types/prop-types" "*" - "@types/scheduler" "*" csstype "^3.0.2" "@types/react@^16", "@types/react@^16.14.34": - version "16.14.50" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.50.tgz#ec9c30f2f0c7d9aa748949536d88e3439526a25d" - integrity sha512-7TWZ/HjhXsRK3BbhSFxTinbSft3sUXJAU3ONngT0rpcKJaIOlxkRke4bidqQTopUbEv1ApC5nlSEkIpX43MkTg== + version "16.14.60" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.60.tgz#f7ab62a329b82826f12d02bc8031d4ef4b5e0d81" + integrity sha512-wIFmnczGsTcgwCBeIYOuy2mdXEiKZ5znU/jNOnMZPQyCcIxauMGWlX0TNG4lZ7NxRKj7YUIZRneJQSSdB2jKgg== dependencies: "@types/prop-types" "*" - "@types/scheduler" "*" + "@types/scheduler" "^0.16" csstype "^3.0.2" "@types/responselike@^1.0.0": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.2.tgz#8de1b0477fd7c12df77e50832fa51701a8414bd6" - integrity sha512-/4YQT5Kp6HxUDb4yhRkm0bJ7TbjvTddqX7PZ5hz6qV3pxSo72f/6YPRo+Mu2DU307tm9IioO69l7uAwn5XNcFA== + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.3.tgz#cc29706f0a397cfe6df89debfe4bf5cea159db50" + integrity sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw== dependencies: "@types/node" "*" @@ -7556,44 +6824,39 @@ resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== -"@types/scheduler@*": - version "0.16.5" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.5.tgz#4751153abbf8d6199babb345a52e1eb4167d64af" - integrity sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw== - -"@types/semver@^7.3.12", "@types/semver@^7.3.4": - version "7.5.4" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.4.tgz#0a41252ad431c473158b22f9bfb9a63df7541cff" - integrity sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ== +"@types/scheduler@^0.16": + version "0.16.8" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" + integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== -"@types/semver@^7.5.0": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.5.tgz#deed5ab7019756c9c90ea86139106b0346223f35" - integrity sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg== +"@types/semver@^7.3.12", "@types/semver@^7.3.4", "@types/semver@^7.5.0", "@types/semver@^7.5.8": + version "7.5.8" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" + integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== "@types/send@*": - version "0.17.3" - resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.3.tgz#81b2ea5a3a18aad357405af2d643ccbe5a09020b" - integrity sha512-/7fKxvKUoETxjFUsuFlPB9YndePpxxRAOfGC/yJdc9kTjTeP5kRCTzfnE8kPUKCeyiyIZu0YQ76s50hCedI1ug== + version "0.17.4" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" + integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== dependencies: "@types/mime" "^1" "@types/node" "*" "@types/serve-index@^1.9.1": - version "1.9.3" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.3.tgz#af9403916eb6fbf7d6ec6f47b2a4c46eb3222cc9" - integrity sha512-4KG+yMEuvDPRrYq5fyVm/I2uqAJSAwZK9VSa+Zf+zUq9/oxSSvy3kkIqyL+jjStv6UCVi8/Aho0NHtB1Fwosrg== + version "1.9.4" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.4.tgz#e6ae13d5053cb06ed36392110b4f9a49ac4ec898" + integrity sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug== dependencies: "@types/express" "*" "@types/serve-static@*", "@types/serve-static@^1.13.10": - version "1.15.4" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.4.tgz#44b5895a68ca637f06c229119e1c774ca88f81b2" - integrity sha512-aqqNfs1XTF0HDrFdlY//+SGUxmdSUbjeRXb5iaZc3x0/vMbYmdw9qvOgHWOyyLFxSSRnUuP5+724zBgfw8/WAw== + version "1.15.7" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.7.tgz#22174bbd74fb97fe303109738e9b5c2f3064f714" + integrity sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw== dependencies: "@types/http-errors" "*" - "@types/mime" "*" "@types/node" "*" + "@types/send" "*" "@types/sinonjs__fake-timers@^6.0.1": version "6.0.4" @@ -7601,68 +6864,63 @@ integrity sha512-IFQTJARgMUBF+xVd2b+hIgXWrZEjND3vJtRCvIelcFB5SIXfjV4bOHbHJ0eXKh+0COrBRc8MqteKAz/j88rE0A== "@types/sizzle@^2.3.2": - version "2.3.5" - resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.5.tgz#d93dd29cdcd5801d90be968073b09a6b370780e4" - integrity sha512-tAe4Q+OLFOA/AMD+0lq8ovp8t3ysxAOeaScnfNdZpUxaGl51ZMDEITxkvFl1STudQ58mz6gzVGl9VhMKhwRnZQ== + version "2.3.8" + resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.8.tgz#518609aefb797da19bf222feb199e8f653ff7627" + integrity sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg== "@types/sockjs@^0.3.33": - version "0.3.35" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.35.tgz#f4a568c73d2a8071944bd6ffdca0d4e66810cd21" - integrity sha512-tIF57KB+ZvOBpAQwSaACfEu7htponHXaFzP7RfKYgsOS0NoYnn+9+jzp7bbq4fWerizI3dTB4NfAZoyeQKWJLw== + version "0.3.36" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535" + integrity sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q== dependencies: "@types/node" "*" "@types/stack-utils@^2.0.0": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.2.tgz#01284dde9ef4e6d8cef6422798d9a3ad18a66f8b" - integrity sha512-g7CK9nHdwjK2n0ymT2CW698FuWJRIx+RP6embAzZ2Qi8/ilIrA1Imt2LVSeHUzKvpoi7BhmmQcXz95eS0f2JXw== + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" + integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== "@types/tough-cookie@*", "@types/tough-cookie@^4.0.2": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.4.tgz#cf2f0c7c51b985b6afecea73eb2cd65421ecb717" - integrity sha512-95Sfz4nvMAb0Nl9DTxN3j64adfwfbBPEYq14VN7zT5J5O2M9V6iZMIIQU1U+pJyl9agHYHNCqhCXgyEtIRRa5A== + version "4.0.5" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304" + integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA== -"@types/unist@^2": +"@types/unist@^2", "@types/unist@^2.0.0": version "2.0.10" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.10.tgz#04ffa7f406ab628f7f7e97ca23e290cd8ab15efc" integrity sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA== -"@types/unist@^2.0.0": - version "2.0.9" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.9.tgz#72e164381659a49557b0a078b28308f2c6a3e1ce" - integrity sha512-zC0iXxAv1C1ERURduJueYzkzZ2zaGyc+P2c95hgkikHPr3z8EdUZOlgEQ5X0DRmwDZn+hekycQnoeiiRVrmilQ== - "@types/uuid@^9.0.1": version "9.0.8" resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== "@types/validator@^13.7.10": - version "13.11.5" - resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.11.5.tgz#1911964fd5556b08d3479d1ded977c06f89a44a7" - integrity sha512-xW4qsT4UIYILu+7ZrBnfQdBYniZrMLYYK3wN9M/NdeIHgBN5pZI2/8Q7UfdWIcr5RLJv/OGENsx91JIpUUoC7Q== + version "13.11.9" + resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.11.9.tgz#adfe96520b437a0eaa798a475877bf2f75ee402d" + integrity sha512-FCTsikRozryfayPuiI46QzH3fnrOoctTjvOYZkho9BTFLCOZ2rgZJHMOVgCOfttjPJcgOx52EpkY0CMfy87MIw== "@types/webpack-env@^1.18.0": - version "1.18.3" - resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.3.tgz#e81f769199a5609c751f34fcc6f6095ceac7831f" - integrity sha512-v4CH6FLBCftYGFAswDhzFLjKgucXsOkIf5Mzl8ZZhEtC6oye9whFInNPKszNB9AvX7JEZMtpXxWctih6addP+Q== + version "1.18.5" + resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.5.tgz#eccda0b04fe024bed505881e2e532f9c119169bf" + integrity sha512-wz7kjjRRj8/Lty4B+Kr0LN6Ypc/3SymeCCGSbaXp2leH0ZVg/PriNiOwNj4bD4uphI7A8NXS4b6Gl373sfO5mA== "@types/ws@^8.5.5": - version "8.5.8" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.8.tgz#13efec7bd439d0bdf2af93030804a94f163b1430" - integrity sha512-flUksGIQCnJd6sZ1l5dqCEG/ksaoAg/eUwiLAGTJQcfgvZJKF++Ta4bJA6A5aPSJmsr+xlseHn4KLgVlNnvPTg== + version "8.5.10" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.10.tgz#4acfb517970853fa6574a3a6886791d04a396787" + integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== dependencies: "@types/node" "*" "@types/yargs-parser@*": - version "21.0.2" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.2.tgz#7bd04c5da378496ef1695a1008bf8f71847a8b8b" - integrity sha512-5qcvofLPbfjmBfKaLfj/+f+Sbd6pN4zl7w7VSVI5uz7m9QZTuB2aZAa2uo1wHFBNN2x6g/SoTkXmd8mQnQF2Cw== + version "21.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== "@types/yargs@^17.0.8": - version "17.0.29" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.29.tgz#06aabc72497b798c643c812a8b561537fea760cf" - integrity sha512-nacjqA3ee9zRF/++a3FUY1suHTFKZeHba2n8WeDw9cCVdmzmHpIxyzOJBcpHvvEmS8E9KqWlSnWHUkOrkhWcvA== + version "17.0.32" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.32.tgz#030774723a2f7faafebf645f4e5a48371dca6229" + integrity sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog== dependencies: "@types/yargs-parser" "*" @@ -7718,13 +6976,13 @@ "@typescript-eslint/types" "7.2.0" "@typescript-eslint/visitor-keys" "7.2.0" -"@typescript-eslint/scope-manager@7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.5.0.tgz#70f0a7361430ab1043a5f97386da2a0d8b2f4d56" - integrity sha512-Z1r7uJY0MDeUlql9XJ6kRVgk/sP11sr3HKXn268HZyqL7i4cEfrdFuSSY/0tUqT37l5zT0tJOsuDP16kio85iA== +"@typescript-eslint/scope-manager@7.8.0": + version "7.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz#bb19096d11ec6b87fb6640d921df19b813e02047" + integrity sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g== dependencies: - "@typescript-eslint/types" "7.5.0" - "@typescript-eslint/visitor-keys" "7.5.0" + "@typescript-eslint/types" "7.8.0" + "@typescript-eslint/visitor-keys" "7.8.0" "@typescript-eslint/type-utils@6.21.0": version "6.21.0" @@ -7747,14 +7005,14 @@ ts-api-utils "^1.0.1" "@typescript-eslint/type-utils@^7.3.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.5.0.tgz#a8faa403232da3a3901655387c7082111f692cf9" - integrity sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw== + version "7.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz#9de166f182a6e4d1c5da76e94880e91831e3e26f" + integrity sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A== dependencies: - "@typescript-eslint/typescript-estree" "7.5.0" - "@typescript-eslint/utils" "7.5.0" + "@typescript-eslint/typescript-estree" "7.8.0" + "@typescript-eslint/utils" "7.8.0" debug "^4.3.4" - tsutils "^3.21.0" + ts-api-utils "^1.3.0" "@typescript-eslint/types@5.62.0": version "5.62.0" @@ -7771,10 +7029,10 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.2.0.tgz#0feb685f16de320e8520f13cca30779c8b7c403f" integrity sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA== -"@typescript-eslint/types@7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.5.0.tgz#0a284bcdef3cb850ec9fd57992df9f29d6bde1bc" - integrity sha512-tv5B4IHeAdhR7uS4+bf8Ov3k793VEVHd45viRRkehIUZxm0WF82VPiLgHzA/Xl4TGPg1ZD49vfxBKFPecD5/mg== +"@typescript-eslint/types@7.8.0": + version "7.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.8.0.tgz#1fd2577b3ad883b769546e2d1ef379f929a7091d" + integrity sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw== "@typescript-eslint/typescript-estree@5.62.0": version "5.62.0" @@ -7817,19 +7075,19 @@ semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/typescript-estree@7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.5.0.tgz#aa5031c511874420f6b5edd90f8e4021525ee776" - integrity sha512-YklQQfe0Rv2PZEueLTUffiQGKQneiIEKKnfIqPIOxgM9lKSZFCjT5Ad4VqRKj/U4+kQE3fa8YQpskViL7WjdPQ== +"@typescript-eslint/typescript-estree@7.8.0": + version "7.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz#b028a9226860b66e623c1ee55cc2464b95d2987c" + integrity sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg== dependencies: - "@typescript-eslint/types" "7.5.0" - "@typescript-eslint/visitor-keys" "7.5.0" + "@typescript-eslint/types" "7.8.0" + "@typescript-eslint/visitor-keys" "7.8.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" - minimatch "9.0.3" - semver "^7.5.4" - ts-api-utils "^1.0.1" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" "@typescript-eslint/utils@6.21.0": version "6.21.0" @@ -7857,18 +7115,18 @@ "@typescript-eslint/typescript-estree" "7.2.0" semver "^7.5.4" -"@typescript-eslint/utils@7.5.0", "@typescript-eslint/utils@^7.3.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.5.0.tgz#bbd963647fbbe9ffea033f42c0fb7e89bb19c858" - integrity sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw== +"@typescript-eslint/utils@7.8.0", "@typescript-eslint/utils@^7.3.0": + version "7.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.8.0.tgz#57a79f9c0c0740ead2f622e444cfaeeb9fd047cd" + integrity sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@types/json-schema" "^7.0.12" - "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "7.5.0" - "@typescript-eslint/types" "7.5.0" - "@typescript-eslint/typescript-estree" "7.5.0" - semver "^7.5.4" + "@types/json-schema" "^7.0.15" + "@types/semver" "^7.5.8" + "@typescript-eslint/scope-manager" "7.8.0" + "@typescript-eslint/types" "7.8.0" + "@typescript-eslint/typescript-estree" "7.8.0" + semver "^7.6.0" "@typescript-eslint/utils@^5.45.0": version "5.62.0" @@ -7908,13 +7166,13 @@ "@typescript-eslint/types" "7.2.0" eslint-visitor-keys "^3.4.1" -"@typescript-eslint/visitor-keys@7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.5.0.tgz#8abcac66f93ef20b093e87a400c2d21e3a6d55ee" - integrity sha512-mcuHM/QircmA6O7fy6nn2w/3ditQkj+SgtOc8DW3uQ10Yfj42amm2i+6F2K4YAOPNNTmE6iM1ynM6lrSwdendA== +"@typescript-eslint/visitor-keys@7.8.0": + version "7.8.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz#7285aab991da8bee411a42edbd5db760d22fdd91" + integrity sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA== dependencies: - "@typescript-eslint/types" "7.5.0" - eslint-visitor-keys "^3.4.1" + "@typescript-eslint/types" "7.8.0" + eslint-visitor-keys "^3.4.3" "@ungap/structured-clone@^1.2.0": version "1.2.0" @@ -7926,10 +7184,10 @@ resolved "https://registry.yarnpkg.com/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.1.0.tgz#8b840305a6b48e8764803435ec0c716fa27d3802" integrity sha512-wO4Dk/rm8u7RNhOf95ZzcEmC9rYOncYgvq4z3duaJrCgjN8BxAnDVyndanfcJZ0O6XZzHz6Q0hTimxTg8Y9g/A== -"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" - integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== +"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.11.5", "@webassemblyjs/ast@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" + integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== dependencies: "@webassemblyjs/helper-numbers" "1.11.6" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" @@ -7944,10 +7202,10 @@ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== -"@webassemblyjs/helper-buffer@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz#b66d73c43e296fd5e88006f18524feb0f2c7c093" - integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== +"@webassemblyjs/helper-buffer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz#6df20d272ea5439bf20ab3492b7fb70e9bfcb3f6" + integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw== "@webassemblyjs/helper-numbers@1.11.6": version "1.11.6" @@ -7963,15 +7221,15 @@ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== -"@webassemblyjs/helper-wasm-section@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz#ff97f3863c55ee7f580fd5c41a381e9def4aa577" - integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== +"@webassemblyjs/helper-wasm-section@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf" + integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g== dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-gen" "1.12.1" "@webassemblyjs/ieee754@1.11.6": version "1.11.6" @@ -7992,59 +7250,59 @@ resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== -"@webassemblyjs/wasm-edit@^1.11.5": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz#c72fa8220524c9b416249f3d94c2958dfe70ceab" - integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== +"@webassemblyjs/wasm-edit@^1.11.5", "@webassemblyjs/wasm-edit@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" + integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g== dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/helper-wasm-section" "1.11.6" - "@webassemblyjs/wasm-gen" "1.11.6" - "@webassemblyjs/wasm-opt" "1.11.6" - "@webassemblyjs/wasm-parser" "1.11.6" - "@webassemblyjs/wast-printer" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-opt" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" + "@webassemblyjs/wast-printer" "1.12.1" -"@webassemblyjs/wasm-gen@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz#fb5283e0e8b4551cc4e9c3c0d7184a65faf7c268" - integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== +"@webassemblyjs/wasm-gen@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547" + integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w== dependencies: - "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/ast" "1.12.1" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" "@webassemblyjs/ieee754" "1.11.6" "@webassemblyjs/leb128" "1.11.6" "@webassemblyjs/utf8" "1.11.6" -"@webassemblyjs/wasm-opt@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz#d9a22d651248422ca498b09aa3232a81041487c2" - integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== +"@webassemblyjs/wasm-opt@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5" + integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg== dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-buffer" "1.11.6" - "@webassemblyjs/wasm-gen" "1.11.6" - "@webassemblyjs/wasm-parser" "1.11.6" + "@webassemblyjs/ast" "1.12.1" + "@webassemblyjs/helper-buffer" "1.12.1" + "@webassemblyjs/wasm-gen" "1.12.1" + "@webassemblyjs/wasm-parser" "1.12.1" -"@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz#bb85378c527df824004812bbdb784eea539174a1" - integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== +"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.11.5", "@webassemblyjs/wasm-parser@^1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937" + integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== dependencies: - "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/ast" "1.12.1" "@webassemblyjs/helper-api-error" "1.11.6" "@webassemblyjs/helper-wasm-bytecode" "1.11.6" "@webassemblyjs/ieee754" "1.11.6" "@webassemblyjs/leb128" "1.11.6" "@webassemblyjs/utf8" "1.11.6" -"@webassemblyjs/wast-printer@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz#a7bf8dd7e362aeb1668ff43f35cb849f188eff20" - integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== +"@webassemblyjs/wast-printer@1.12.1": + version "1.12.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz#bcecf661d7d1abdaf989d8341a4833e33e2b31ac" + integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA== dependencies: - "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/ast" "1.12.1" "@xtuc/long" "4.2.2" "@xtuc/ieee754@^1.2.0": @@ -8143,26 +7401,16 @@ acorn-jsx@^5.3.2: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn-walk@^8.0.0: +acorn-walk@^8.0.0, acorn-walk@^8.0.2, acorn-walk@^8.1.1: version "8.3.2" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== -acorn-walk@^8.0.2, acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -acorn@^8.0.4: +acorn@^8.0.4, acorn@^8.1.0, acorn@^8.11.3, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.1, acorn@^8.8.2, acorn@^8.9.0: version "8.11.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== -acorn@^8.1.0, acorn@^8.10.0, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.1, acorn@^8.8.2, acorn@^8.9.0: - version "8.10.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" - integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== - address@^1.0.1: version "1.2.2" resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" @@ -8188,10 +7436,10 @@ agent-base@6: dependencies: debug "4" -agent-base@^7.0.2, agent-base@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.0.tgz#536802b76bc0b34aa50195eb2442276d613e3434" - integrity sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg== +agent-base@^7.0.2, agent-base@^7.1.0, agent-base@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.1.tgz#bdbded7dfb096b751a2a087eeeb9664725b2e317" + integrity sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA== dependencies: debug "^4.3.4" @@ -8232,7 +7480,7 @@ ajv@8.10.0: require-from-string "^2.0.2" uri-js "^4.2.2" -ajv@8.12.0, ajv@^8.0.0, ajv@^8.9.0: +ajv@8.12.0: version "8.12.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== @@ -8252,6 +7500,16 @@ ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^8.0.0, ajv@^8.12.0, ajv@^8.9.0: + version "8.13.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.13.0.tgz#a3939eaec9fb80d217ddf0c3376948c023f28c91" + integrity sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA== + dependencies: + fast-deep-equal "^3.1.3" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.4.1" + alphavantage@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/alphavantage/-/alphavantage-2.2.0.tgz#a07829c91bdc089cfe84a521aff389673a652ac7" @@ -8401,9 +7659,9 @@ argparse@^2.0.1: integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== aria-hidden@^1.1.1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.3.tgz#14aeb7fb692bbb72d69bebfa47279c1fd725e954" - integrity sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ== + version "1.2.4" + resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.4.tgz#b78e383fdbc04d05762c78b4a25a501e736c4522" + integrity sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A== dependencies: tslib "^2.0.0" @@ -8422,33 +7680,29 @@ aria-query@^3.0.0: ast-types-flow "0.0.7" commander "^2.11.0" -array-buffer-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" - integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== +array-buffer-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz#1e5583ec16763540a27ae52eed99ff899223568f" + integrity sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg== dependencies: - call-bind "^1.0.2" - is-array-buffer "^3.0.1" + call-bind "^1.0.5" + is-array-buffer "^3.0.4" array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== -array-flatten@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" - integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== - array-includes@^3.1.7: - version "3.1.7" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" - integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== + version "3.1.8" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.8.tgz#5e370cbe172fdd5dd6530c1d4aadda25281ba97d" + integrity sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" + get-intrinsic "^1.2.4" is-string "^1.0.7" array-timsort@^1.0.3: @@ -8466,26 +7720,16 @@ array-union@^3.0.1: resolved "https://registry.yarnpkg.com/array-union/-/array-union-3.0.1.tgz#da52630d327f8b88cfbfb57728e2af5cd9b6b975" integrity sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw== -array.prototype.filter@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array.prototype.filter/-/array.prototype.filter-1.0.3.tgz#423771edeb417ff5914111fff4277ea0624c0d0e" - integrity sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-array-method-boxes-properly "^1.0.0" - is-string "^1.0.7" - array.prototype.findlastindex@^1.2.3: - version "1.2.4" - resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.4.tgz#d1c50f0b3a9da191981ff8942a0aedd82794404f" - integrity sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ== + version "1.2.5" + resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz#8c35a755c72908719453f87145ca011e39334d0d" + integrity sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ== dependencies: - call-bind "^1.0.5" + call-bind "^1.0.7" define-properties "^1.2.1" - es-abstract "^1.22.3" + es-abstract "^1.23.2" es-errors "^1.3.0" + es-object-atoms "^1.0.0" es-shim-unscopables "^1.0.2" array.prototype.flat@^1.3.2: @@ -8508,17 +7752,18 @@ array.prototype.flatmap@^1.3.2: es-abstract "^1.22.1" es-shim-unscopables "^1.0.0" -arraybuffer.prototype.slice@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz#98bd561953e3e74bb34938e77647179dfe6e9f12" - integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== +arraybuffer.prototype.slice@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz#097972f4255e41bc3425e37dc3f6421cf9aefde6" + integrity sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A== dependencies: - array-buffer-byte-length "^1.0.0" - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-array-buffer "^3.0.2" + array-buffer-byte-length "^1.0.1" + call-bind "^1.0.5" + define-properties "^1.2.1" + es-abstract "^1.22.3" + es-errors "^1.2.1" + get-intrinsic "^1.2.3" + is-array-buffer "^3.0.4" is-shared-array-buffer "^1.0.2" arrify@^2.0.0: @@ -8547,7 +7792,7 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== -assert@^2.0.0, assert@^2.1.0: +assert@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/assert/-/assert-2.1.0.tgz#6d92a238d05dc02e7427c881fb8be81c8448b2dd" integrity sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw== @@ -8595,9 +7840,9 @@ async@^2.6.4: lodash "^4.17.14" async@^3.2.0, async@^3.2.3: - version "3.2.4" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" - integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== + version "3.2.5" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" + integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== asynckit@^0.4.0: version "0.4.0" @@ -8622,21 +7867,23 @@ autoprefixer@10.4.18: postcss-value-parser "^4.2.0" autoprefixer@^10.4.9: - version "10.4.16" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.16.tgz#fad1411024d8670880bdece3970aa72e3572feb8" - integrity sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ== + version "10.4.19" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.19.tgz#ad25a856e82ee9d7898c59583c1afeb3fa65f89f" + integrity sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew== dependencies: - browserslist "^4.21.10" - caniuse-lite "^1.0.30001538" - fraction.js "^4.3.6" + browserslist "^4.23.0" + caniuse-lite "^1.0.30001599" + fraction.js "^4.3.7" normalize-range "^0.1.2" picocolors "^1.0.0" postcss-value-parser "^4.2.0" -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== +available-typed-arrays@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" + integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== + dependencies: + possible-typed-array-names "^1.0.0" await-lock@^2.2.2: version "2.2.2" @@ -8660,12 +7907,12 @@ axios@^0.21.4: dependencies: follow-redirects "^1.14.0" -axios@^1.5.1: - version "1.6.7" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.7.tgz#7b48c2e27c96f9c68a2f8f31e2ab19f59b06b0a7" - integrity sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA== +axios@^1.6.0: + version "1.6.8" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.8.tgz#66d294951f5d988a00e87a0ffb955316a619ea66" + integrity sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ== dependencies: - follow-redirects "^1.15.4" + follow-redirects "^1.15.6" form-data "^4.0.0" proxy-from-env "^1.1.0" @@ -8757,23 +8004,22 @@ babel-plugin-polyfill-corejs2@^0.3.3: "@babel/helper-define-polyfill-provider" "^0.3.3" semver "^6.1.1" -babel-plugin-polyfill-corejs2@^0.4.6: - version "0.4.6" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz#b2df0251d8e99f229a8e60fc4efa9a68b41c8313" - integrity sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q== +babel-plugin-polyfill-corejs2@^0.4.10, babel-plugin-polyfill-corejs2@^0.4.8: + version "0.4.11" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.11.tgz#30320dfe3ffe1a336c15afdcdafd6fd615b25e33" + integrity sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q== dependencies: "@babel/compat-data" "^7.22.6" - "@babel/helper-define-polyfill-provider" "^0.4.3" + "@babel/helper-define-polyfill-provider" "^0.6.2" semver "^6.3.1" -babel-plugin-polyfill-corejs2@^0.4.8: - version "0.4.8" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz#dbcc3c8ca758a290d47c3c6a490d59429b0d2269" - integrity sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg== +babel-plugin-polyfill-corejs3@^0.10.1, babel-plugin-polyfill-corejs3@^0.10.4: + version "0.10.4" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.4.tgz#789ac82405ad664c20476d0233b485281deb9c77" + integrity sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg== dependencies: - "@babel/compat-data" "^7.22.6" - "@babel/helper-define-polyfill-provider" "^0.5.0" - semver "^6.3.1" + "@babel/helper-define-polyfill-provider" "^0.6.1" + core-js-compat "^3.36.1" babel-plugin-polyfill-corejs3@^0.6.0: version "0.6.0" @@ -8783,14 +8029,6 @@ babel-plugin-polyfill-corejs3@^0.6.0: "@babel/helper-define-polyfill-provider" "^0.3.3" core-js-compat "^3.25.1" -babel-plugin-polyfill-corejs3@^0.8.5: - version "0.8.6" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz#25c2d20002da91fe328ff89095c85a391d6856cf" - integrity sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.4.3" - core-js-compat "^3.33.1" - babel-plugin-polyfill-corejs3@^0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz#9eea32349d94556c2ad3ab9b82ebb27d4bf04a81" @@ -8806,13 +8044,6 @@ babel-plugin-polyfill-regenerator@^0.4.1: dependencies: "@babel/helper-define-polyfill-provider" "^0.3.3" -babel-plugin-polyfill-regenerator@^0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz#d4c49e4b44614607c13fb769bcd85c72bb26a4a5" - integrity sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.4.3" - babel-plugin-polyfill-regenerator@^0.5.5: version "0.5.5" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz#8b0c8fc6434239e5d7b8a9d1f832bb2b0310f06a" @@ -8820,6 +8051,13 @@ babel-plugin-polyfill-regenerator@^0.5.5: dependencies: "@babel/helper-define-polyfill-provider" "^0.5.0" +babel-plugin-polyfill-regenerator@^0.6.1: + version "0.6.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.2.tgz#addc47e240edd1da1058ebda03021f382bba785e" + integrity sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.6.2" + babel-plugin-transform-typescript-metadata@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/babel-plugin-transform-typescript-metadata/-/babel-plugin-transform-typescript-metadata-0.3.2.tgz#7a327842d8c36ffe07ee1b5276434e56c297c9b7" @@ -8907,9 +8145,9 @@ better-opn@^3.0.2: open "^8.0.4" big-integer@^1.6.44: - version "1.6.51" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" - integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== + version "1.6.52" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" + integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== big.js@6.2.1: version "6.2.1" @@ -8927,9 +8165,9 @@ bignumber.js@^9.0.0: integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + version "2.3.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" + integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== bl@^4.0.3, bl@^4.1.0: version "4.1.0" @@ -8987,12 +8225,10 @@ body-parser@1.20.2: unpipe "1.0.0" bonjour-service@^1.0.11: - version "1.1.1" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.1.1.tgz#960948fa0e0153f5d26743ab15baf8e33752c135" - integrity sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg== + version "1.2.1" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.2.1.tgz#eb41b3085183df3321da1264719fbada12478d02" + integrity sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw== dependencies: - array-flatten "^2.1.2" - dns-equal "^1.0.0" fast-deep-equal "^3.1.3" multicast-dns "^7.2.5" @@ -9074,27 +8310,7 @@ browserify-zlib@^0.1.4: dependencies: pako "~0.2.0" -browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.21.10, browserslist@^4.21.4, browserslist@^4.21.5, browserslist@^4.21.9, browserslist@^4.22.1: - version "4.22.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.1.tgz#ba91958d1a59b87dab6fed8dfbcb3da5e2e9c619" - integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ== - dependencies: - caniuse-lite "^1.0.30001541" - electron-to-chromium "^1.4.535" - node-releases "^2.0.13" - update-browserslist-db "^1.0.13" - -browserslist@^4.22.2: - version "4.23.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" - integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== - dependencies: - caniuse-lite "^1.0.30001587" - electron-to-chromium "^1.4.668" - node-releases "^2.0.14" - update-browserslist-db "^1.0.13" - -browserslist@^4.23.0: +browserslist@^4.0.0, browserslist@^4.21.10, browserslist@^4.21.4, browserslist@^4.21.5, browserslist@^4.21.9, browserslist@^4.22.2, browserslist@^4.23.0: version "4.23.0" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== @@ -9141,13 +8357,6 @@ buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" -builtins@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.0.1.tgz#87f6db9ab0458be728564fa81d876d8d74552fa9" - integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ== - dependencies: - semver "^7.0.0" - bull@4.10.4: version "4.10.4" resolved "https://registry.yarnpkg.com/bull/-/bull-4.10.4.tgz#db39ee0c3bfbe3b76f1f35db800501de5bba4f84" @@ -9180,16 +8389,16 @@ bytes@3.1.2: integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== cacache@^18.0.0: - version "18.0.0" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-18.0.0.tgz#17a9ecd6e1be2564ebe6cdca5f7cfed2bfeb6ddc" - integrity sha512-I7mVOPl3PUCeRub1U8YoGz2Lqv9WOBpobZ8RyWFXmReuILz+3OAyTa5oH3QPdtKZD7N0Yk00aLfzn0qvp8dZ1w== + version "18.0.3" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-18.0.3.tgz#864e2c18414e1e141ae8763f31e46c2cb96d1b21" + integrity sha512-qXCd4rh6I07cnDqh8V48/94Tc/WSfj+o3Gn6NZ0aZovS255bUx8O13uKxRFd2eWG0xgsco7+YItQNPaa5E85hg== dependencies: "@npmcli/fs" "^3.1.0" fs-minipass "^3.0.0" glob "^10.2.2" lru-cache "^10.0.1" minipass "^7.0.3" - minipass-collect "^1.0.2" + minipass-collect "^2.0.1" minipass-flush "^1.0.5" minipass-pipeline "^1.2.4" p-map "^4.0.0" @@ -9231,21 +8440,12 @@ cacheable-request@^7.0.2: normalize-url "^6.0.1" responselike "^2.0.0" -cachedir@^2.3.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.4.0.tgz#7fef9cf7367233d7c88068fe6e34ed0d355a610d" - integrity sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ== - -call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" - integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== - dependencies: - function-bind "^1.1.2" - get-intrinsic "^1.2.1" - set-function-length "^1.1.1" +cachedir@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.4.0.tgz#7fef9cf7367233d7c88068fe6e34ed0d355a610d" + integrity sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ== -call-bind@^1.0.7: +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== @@ -9289,10 +8489,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001538, caniuse-lite@^1.0.30001541, caniuse-lite@^1.0.30001565, caniuse-lite@^1.0.30001587, caniuse-lite@^1.0.30001591: - version "1.0.30001610" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001610.tgz" - integrity sha512-QFutAY4NgaelojVMjY63o6XlZyORPaLfyMnsl3HgnWdJUcX6K0oaJymHjH8PT5Gk7sTm8rvC/c5COUQKXqmOMA== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001587, caniuse-lite@^1.0.30001591, caniuse-lite@^1.0.30001599: + version "1.0.30001617" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001617.tgz#809bc25f3f5027ceb33142a7d6c40759d7a901eb" + integrity sha512-mLyjzNI9I+Pix8zwcrpxEbGlfqOkF9kM3ptzmKNw5tizSyYwMe+nGLTqMK9cO+0E+Bh6TsBxNAaHWEM8xwSsmA== case-sensitive-paths-webpack-plugin@^2.4.0: version "2.4.0" @@ -9404,10 +8604,10 @@ cheerio@1.0.0-rc.12: parse5 "^7.0.0" parse5-htmlparser2-tree-adapter "^7.0.0" -"chokidar@>=3.0.0 <4.0.0", chokidar@^3.0.0, chokidar@^3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.0.0, chokidar@^3.5.3, chokidar@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== dependencies: anymatch "~3.1.2" braces "~3.0.2" @@ -9444,10 +8644,17 @@ ci-info@^3.2.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== +citty@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/citty/-/citty-0.1.6.tgz#0f7904da1ed4625e1a9ea7e0fa780981aab7c5e4" + integrity sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ== + dependencies: + consola "^3.2.3" + cjs-module-lexer@^1.0.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" - integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + version "1.3.1" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz#c485341ae8fd999ca4ee5af2d7a1c9ae01e0099c" + integrity sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q== class-transformer@0.5.1: version "0.5.1" @@ -9464,9 +8671,9 @@ class-validator@0.14.0: validator "^13.7.0" clean-css@^5.2.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.2.tgz#70ecc7d4d4114921f5d298349ff86a31a9975224" - integrity sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww== + version "5.3.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.3.tgz#b330653cd3bd6b75009cc25c714cae7b93351ccd" + integrity sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg== dependencies: source-map "~0.6.0" @@ -9507,14 +8714,14 @@ cli-spinners@2.6.1: integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== cli-spinners@^2.5.0: - version "2.9.1" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.1.tgz#9c0b9dad69a6d47cbb4333c14319b060ed395a35" - integrity sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ== + version "2.9.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" + integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== cli-table3@^0.6.1, cli-table3@~0.6.0: - version "0.6.3" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.3.tgz#61ab765aac156b52f222954ffc607a6f01dbeeb2" - integrity sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg== + version "0.6.4" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.4.tgz#d1c536b8a3f2e7bec58f67ac9e5769b1b30088b0" + integrity sha512-Lm3L0p+/npIQWNIiyF/nAn7T5dnOwR3xNTHXYEBFBFVPXzCVNZ5lqEC/1eo/EVfpDsQ1I+TX4ORPQgp+UI0CRw== dependencies: string-width "^4.2.0" optionalDependencies: @@ -9657,12 +8864,12 @@ color@4.2.3: color-convert "^2.0.1" color-string "^1.9.0" -colord@^2.9.1: +colord@^2.9.3: version "2.9.3" resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== -colorette@^2.0.10, colorette@^2.0.20: +colorette@^2.0.10: version "2.0.20" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== @@ -9783,6 +8990,11 @@ consola@^2.15.0: resolved "https://registry.yarnpkg.com/consola/-/consola-2.15.3.tgz#2e11f98d6a4be71ff72e0bdf07bd23e12cb61550" integrity sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw== +consola@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/consola/-/consola-3.2.3.tgz#0741857aa88cfa0d6fd53f1cff0375136e98502f" + integrity sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ== + console-control-strings@^1.0.0, console-control-strings@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" @@ -9825,6 +9037,11 @@ cookie@0.5.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cookie@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== + copy-anything@^2.0.1: version "2.0.6" resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-2.0.6.tgz#092454ea9584a7b7ad5573062b2a87f5900fc480" @@ -9856,19 +9073,12 @@ copy-webpack-plugin@^10.2.4: schema-utils "^4.0.0" serialize-javascript "^6.0.0" -core-js-compat@^3.25.1, core-js-compat@^3.31.0, core-js-compat@^3.33.1: - version "3.33.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.33.1.tgz#debe80464107d75419e00c2ee29f35982118ff84" - integrity sha512-6pYKNOgD/j/bkC5xS5IIg6bncid3rfrI42oBH1SQJbsmYPKF7rhzcFzYCcxYMmNQQ0rCEB8WqpW7QHndOggaeQ== - dependencies: - browserslist "^4.22.1" - -core-js-compat@^3.34.0: - version "3.35.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.35.1.tgz#215247d7edb9e830efa4218ff719beb2803555e2" - integrity sha512-sftHa5qUJY3rs9Zht1WEnmkvXputCyDBczPnr7QDgL8n3qrF3CMXY4VPSYtOLLiOUJcah2WNXREd48iOl6mQIw== +core-js-compat@^3.25.1, core-js-compat@^3.31.0, core-js-compat@^3.34.0, core-js-compat@^3.36.1: + version "3.37.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.37.0.tgz#d9570e544163779bb4dff1031c7972f44918dc73" + integrity sha512-vYq4L+T8aS5UuFg4UwDhc7YNRWVeVZwltad9C/jV3R2LgVOpS9BDr7l/WL6BN0dbV3k1XejPTHqqEzJgsa0frA== dependencies: - browserslist "^4.22.2" + browserslist "^4.23.0" core-util-is@1.0.2: version "1.0.2" @@ -9900,13 +9110,6 @@ cose-base@^1.0.0: dependencies: layout-base "^1.0.0" -cose-base@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cose-base/-/cose-base-2.2.0.tgz#1c395c35b6e10bb83f9769ca8b817d614add5c01" - integrity sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g== - dependencies: - layout-base "^2.0.0" - cosmiconfig@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" @@ -10027,10 +9230,10 @@ crypto-random-string@^2.0.0: resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== -css-declaration-sorter@^6.3.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz#28beac7c20bad7f1775be3a7129d7eae409a3a71" - integrity sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g== +css-declaration-sorter@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-7.2.0.tgz#6dec1c9523bc4a643e088aab8f09e67a54961024" + integrity sha512-h70rUM+3PNFuaBDTLe8wF/cdWu+dOZmb7pJt8Z2sedYbAcQVQV/tEchueg3GWxwqS0cxtbxmaHEdkNACqcvsow== css-loader@6.10.0: version "6.10.0" @@ -10047,18 +9250,18 @@ css-loader@6.10.0: semver "^7.5.4" css-loader@^6.4.0, css-loader@^6.7.1: - version "6.8.1" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.8.1.tgz#0f8f52699f60f5e679eab4ec0fcd68b8e8a50a88" - integrity sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g== + version "6.11.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.11.0.tgz#33bae3bf6363d0a7c2cf9031c96c744ff54d85ba" + integrity sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g== dependencies: icss-utils "^5.1.0" - postcss "^8.4.21" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.3" - postcss-modules-scope "^3.0.0" + postcss "^8.4.33" + postcss-modules-extract-imports "^3.1.0" + postcss-modules-local-by-default "^4.0.5" + postcss-modules-scope "^3.2.0" postcss-modules-values "^4.0.0" postcss-value-parser "^4.2.0" - semver "^7.3.8" + semver "^7.5.4" css-minimizer-webpack-plugin@^5.0.0: version "5.0.1" @@ -10102,7 +9305,7 @@ css-selector-tokenizer@^0.7.1: cssesc "^3.0.0" fastparse "^1.1.2" -css-tree@^2.2.1: +css-tree@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw== @@ -10135,53 +9338,54 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano-preset-default@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-6.0.1.tgz#2a93247140d214ddb9f46bc6a3562fa9177fe301" - integrity sha512-7VzyFZ5zEB1+l1nToKyrRkuaJIx0zi/1npjvZfbBwbtNTzhLtlvYraK/7/uqmX2Wb2aQtd983uuGw79jAjLSuQ== - dependencies: - css-declaration-sorter "^6.3.1" - cssnano-utils "^4.0.0" - postcss-calc "^9.0.0" - postcss-colormin "^6.0.0" - postcss-convert-values "^6.0.0" - postcss-discard-comments "^6.0.0" - postcss-discard-duplicates "^6.0.0" - postcss-discard-empty "^6.0.0" - postcss-discard-overridden "^6.0.0" - postcss-merge-longhand "^6.0.0" - postcss-merge-rules "^6.0.1" - postcss-minify-font-values "^6.0.0" - postcss-minify-gradients "^6.0.0" - postcss-minify-params "^6.0.0" - postcss-minify-selectors "^6.0.0" - postcss-normalize-charset "^6.0.0" - postcss-normalize-display-values "^6.0.0" - postcss-normalize-positions "^6.0.0" - postcss-normalize-repeat-style "^6.0.0" - postcss-normalize-string "^6.0.0" - postcss-normalize-timing-functions "^6.0.0" - postcss-normalize-unicode "^6.0.0" - postcss-normalize-url "^6.0.0" - postcss-normalize-whitespace "^6.0.0" - postcss-ordered-values "^6.0.0" - postcss-reduce-initial "^6.0.0" - postcss-reduce-transforms "^6.0.0" - postcss-svgo "^6.0.0" - postcss-unique-selectors "^6.0.0" - -cssnano-utils@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-4.0.0.tgz#d1da885ec04003ab19505ff0e62e029708d36b08" - integrity sha512-Z39TLP+1E0KUcd7LGyF4qMfu8ZufI0rDzhdyAMsa/8UyNUU8wpS0fhdBxbQbv32r64ea00h4878gommRVg2BHw== +cssnano-preset-default@^6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz#adf4b89b975aa775f2750c89dbaf199bbd9da35e" + integrity sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg== + dependencies: + browserslist "^4.23.0" + css-declaration-sorter "^7.2.0" + cssnano-utils "^4.0.2" + postcss-calc "^9.0.1" + postcss-colormin "^6.1.0" + postcss-convert-values "^6.1.0" + postcss-discard-comments "^6.0.2" + postcss-discard-duplicates "^6.0.3" + postcss-discard-empty "^6.0.3" + postcss-discard-overridden "^6.0.2" + postcss-merge-longhand "^6.0.5" + postcss-merge-rules "^6.1.1" + postcss-minify-font-values "^6.1.0" + postcss-minify-gradients "^6.0.3" + postcss-minify-params "^6.1.0" + postcss-minify-selectors "^6.0.4" + postcss-normalize-charset "^6.0.2" + postcss-normalize-display-values "^6.0.2" + postcss-normalize-positions "^6.0.2" + postcss-normalize-repeat-style "^6.0.2" + postcss-normalize-string "^6.0.2" + postcss-normalize-timing-functions "^6.0.2" + postcss-normalize-unicode "^6.1.0" + postcss-normalize-url "^6.0.2" + postcss-normalize-whitespace "^6.0.2" + postcss-ordered-values "^6.0.2" + postcss-reduce-initial "^6.1.0" + postcss-reduce-transforms "^6.0.2" + postcss-svgo "^6.0.3" + postcss-unique-selectors "^6.0.4" + +cssnano-utils@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-4.0.2.tgz#56f61c126cd0f11f2eef1596239d730d9fceff3c" + integrity sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ== cssnano@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-6.0.1.tgz#87c38c4cd47049c735ab756d7e77ac3ca855c008" - integrity sha512-fVO1JdJ0LSdIGJq68eIxOqFpIJrZqXUsBt8fkrBcztCQqAjQD51OhZp7tc0ImcbwXD4k7ny84QTV90nZhmqbkg== + version "6.1.2" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-6.1.2.tgz#4bd19e505bd37ee7cf0dc902d3d869f6d79c66b8" + integrity sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA== dependencies: - cssnano-preset-default "^6.0.1" - lilconfig "^2.1.0" + cssnano-preset-default "^6.1.2" + lilconfig "^3.1.1" csso@^5.0.5: version "5.0.5" @@ -10208,9 +9412,9 @@ cssstyle@^2.3.0: cssom "~0.3.6" csstype@^3.0.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" - integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== + version "3.1.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" + integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== cypress@6.2.1: version "6.2.1" @@ -10263,20 +9467,10 @@ cytoscape-cose-bilkent@^4.1.0: dependencies: cose-base "^1.0.0" -cytoscape-fcose@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz#e4d6f6490df4fab58ae9cea9e5c3ab8d7472f471" - integrity sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ== - dependencies: - cose-base "^2.2.0" - -cytoscape@^3.23.0: - version "3.26.0" - resolved "https://registry.yarnpkg.com/cytoscape/-/cytoscape-3.26.0.tgz#b4c6961445fd51e1fd3cca83c3ffe924d9a8abc9" - integrity sha512-IV+crL+KBcrCnVVUCZW+zRRRFUZQcrtdOPXki+o4CFUWLdAEYvuZLcBSJC9EBK++suamERKzeY7roq2hdovV3w== - dependencies: - heap "^0.2.6" - lodash "^4.17.21" +cytoscape@^3.28.1: + version "3.29.2" + resolved "https://registry.yarnpkg.com/cytoscape/-/cytoscape-3.29.2.tgz#c99f42513c80a75e2e94858add32896c860202ac" + integrity sha512-2G1ycU28Nh7OHT9rkXRLpCDP30MKH1dXJORZuBhtEhEW7pKwgPi77ImqlCWinouyE1PNepIOGZBOrE84DG7LyQ== "d3-array@1 - 2": version "2.12.1" @@ -10383,9 +9577,9 @@ d3-force@3: integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== d3-geo@3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-3.1.0.tgz#74fd54e1f4cebd5185ac2039217a98d39b0a4c0e" - integrity sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA== + version "3.1.1" + resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-3.1.1.tgz#6027cf51246f9b2ebd64f99e01dc7c3364033a4d" + integrity sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q== dependencies: d3-array "2.5.0 - 3" @@ -10435,9 +9629,9 @@ d3-sankey@^0.12.3: d3-shape "^1.2.0" d3-scale-chromatic@3: - version "3.0.0" - resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz#15b4ceb8ca2bb0dcb6d1a641ee03d59c3b62376a" - integrity sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g== + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz#34c39da298b23c20e02f1a4b239bd0f22e7f1314" + integrity sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ== dependencies: d3-color "1 - 3" d3-interpolate "1 - 3" @@ -10514,9 +9708,9 @@ d3-zoom@3: d3-transition "2 - 3" d3@^7.4.0, d3@^7.8.2: - version "7.8.5" - resolved "https://registry.yarnpkg.com/d3/-/d3-7.8.5.tgz#fde4b760d4486cdb6f0cc8e2cbff318af844635c" - integrity sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA== + version "7.9.0" + resolved "https://registry.yarnpkg.com/d3/-/d3-7.9.0.tgz#579e7acb3d749caf8860bd1741ae8d371070cd5d" + integrity sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA== dependencies: d3-array "3" d3-axis "3" @@ -10578,6 +9772,33 @@ data-urls@^3.0.2: whatwg-mimetype "^3.0.0" whatwg-url "^11.0.0" +data-view-buffer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.1.tgz#8ea6326efec17a2e42620696e671d7d5a8bc66b2" + integrity sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +data-view-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz#90721ca95ff280677eb793749fce1011347669e2" + integrity sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ== + dependencies: + call-bind "^1.0.7" + es-errors "^1.3.0" + is-data-view "^1.0.1" + +data-view-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz#5e0bbfb4828ed2d1b9b400cd8a7d119bca0ff18a" + integrity sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA== + dependencies: + call-bind "^1.0.6" + es-errors "^1.3.0" + is-data-view "^1.0.1" + date-fns@2.29.3: version "2.29.3" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.29.3.tgz#27402d2fc67eb442b511b70bbdf98e6411cd68a8" @@ -10589,9 +9810,9 @@ date-fns@^1.27.2: integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== dayjs@^1.11.7: - version "1.11.10" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" - integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ== + version "1.11.11" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.11.tgz#dfe0e9d54c5f8b68ccf8ca5f72ac603e7e5ed59e" + integrity sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg== debounce@^1.2.1: version "1.2.1" @@ -10612,7 +9833,7 @@ debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, d dependencies: ms "2.1.2" -debug@^3.1.0, debug@^3.2.6, debug@^3.2.7: +debug@^3.1.0, debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -10644,9 +9865,9 @@ decompress-response@^6.0.0: mimic-response "^3.1.0" dedent@^1.0.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.1.tgz#4f3fc94c8b711e9bb2800d185cd6ad20f2a90aff" - integrity sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg== + version "1.5.3" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a" + integrity sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ== deep-is@^0.1.3, deep-is@~0.1.3: version "0.1.4" @@ -10685,16 +9906,7 @@ defer-to-connect@^2.0.0: resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== -define-data-property@^1.0.1, define-data-property@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" - integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== - dependencies: - get-intrinsic "^1.2.1" - gopd "^1.0.1" - has-property-descriptors "^1.0.0" - -define-data-property@^1.1.4: +define-data-property@^1.0.1, define-data-property@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== @@ -10708,7 +9920,7 @@ define-lazy-prop@^2.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== -define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0, define-properties@^1.2.1: +define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== @@ -10717,10 +9929,10 @@ define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0, de has-property-descriptors "^1.0.0" object-keys "^1.1.1" -defu@^6.1.2: - version "6.1.3" - resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.3.tgz#6d7f56bc61668e844f9f593ace66fd67ef1205fd" - integrity sha512-Vy2wmG3NTkmHNg/kzpuvHhkqeIx3ODWqasgCRbKtbXEN0G+HpEEv9BtJLp7ZG1CZloFaC41Ah3ZFbq7aqCqMeQ== +defu@^6.1.4: + version "6.1.4" + resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479" + integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg== del@^6.0.0: version "6.1.1" @@ -10737,11 +9949,11 @@ del@^6.0.0: slash "^3.0.0" delaunator@5: - version "5.0.0" - resolved "https://registry.yarnpkg.com/delaunator/-/delaunator-5.0.0.tgz#60f052b28bd91c9b4566850ebf7756efe821d81b" - integrity sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw== + version "5.0.1" + resolved "https://registry.yarnpkg.com/delaunator/-/delaunator-5.0.1.tgz#39032b08053923e924d6094fe2cde1a99cc51278" + integrity sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw== dependencies: - robust-predicates "^3.0.0" + robust-predicates "^3.0.2" delayed-stream@~1.0.0: version "1.0.0" @@ -10821,9 +10033,9 @@ detect-package-manager@^2.0.1: execa "^5.1.1" detect-port@^1.3.0, detect-port@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.5.1.tgz#451ca9b6eaf20451acb0799b8ab40dff7718727b" - integrity sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ== + version "1.6.1" + resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.6.1.tgz#45e4073997c5f292b957cb678fb0bb8ed4250a67" + integrity sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q== dependencies: address "^1.0.1" debug "4" @@ -10839,9 +10051,9 @@ diff@^4.0.1: integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== diff@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40" - integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== + version "5.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531" + integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== dir-glob@^3.0.1: version "3.0.1" @@ -10850,11 +10062,6 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" -dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== - dns-packet@^5.2.2: version "5.6.1" resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.6.1.tgz#ae888ad425a9d1478a0674256ab866de1012cf2f" @@ -10928,9 +10135,9 @@ domhandler@^5.0.2, domhandler@^5.0.3: domelementtype "^2.3.0" dompurify@^3.0.5: - version "3.0.6" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.6.tgz#925ebd576d54a9531b5d76f0a5bef32548351dae" - integrity sha512-ilkD8YEnnGh1zJ240uJsW7AzE+2qpbOUYjacomn3AvJ6J4JhKGSZ2nh4wUIXPZrEPppaCLx5jFe8T89Rk8tQ7w== + version "3.1.2" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.1.2.tgz#d1e158457e00666ab40c9c3d8aab57586a072bd1" + integrity sha512-hLGGBI1tw5N8qTELr3blKjAML/LY4ANxksbS612UiJyDfyf/2D092Pvm+S7pmeTGJRqvlJkFzBoHBQKgQlOQVg== domutils@^2.5.2, domutils@^2.8.0: version "2.8.0" @@ -10968,10 +10175,15 @@ dotenv@16.1.4: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.1.4.tgz#67ac1a10cd9c25f5ba604e4e08bc77c0ebe0ca8c" integrity sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw== -dotenv@^16.0.0, dotenv@~16.3.1: - version "16.3.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" - integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== +dotenv@^16.0.0: + version "16.4.5" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" + integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== + +dotenv@~16.3.1: + version "16.3.2" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.2.tgz#3cb611ce5a63002dbabf7c281bc331f69d28f03f" + integrity sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ== duplexer@^0.1.1, duplexer@^0.1.2: version "0.1.2" @@ -11014,36 +10226,26 @@ ee-first@1.1.1: integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== ejs@^3.1.7, ejs@^3.1.8: - version "3.1.9" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" - integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== + version "3.1.10" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" + integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== dependencies: jake "^10.8.5" -electron-to-chromium@^1.4.535: - version "1.4.567" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.567.tgz#c92e8fbc2bd15df3068d92571733a218a5413add" - integrity sha512-8KR114CAYQ4/r5EIEsOmOMqQ9j0MRbJZR3aXD/KFA8RuKzyoUB4XrUCg+l8RUGqTVQgKNIgTpjaG8YHRPAbX2w== - -electron-to-chromium@^1.4.668: - version "1.4.673" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.673.tgz#1f077d9a095761804aec7ec6346c3f4b69b56534" - integrity sha512-zjqzx4N7xGdl5468G+vcgzDhaHkaYgVcf9MqgexcTqsl2UHSCmOj/Bi3HAprg4BZCpC7HyD8a6nZl6QAZf72gw== - electron-to-chromium@^1.4.668: - version "1.4.729" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.729.tgz#8477d21e2a50993781950885b2731d92ad532c00" - integrity sha512-bx7+5Saea/qu14kmPTDHQxkp2UnziG3iajUQu3BxFvCOnpAJdDbMV4rSl+EqFDkkpNNVUFlR1kDfpL59xfy1HA== + version "1.4.761" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.761.tgz#d1bdf8c50a254f8a756641bb1ac48bb52e4d0ec3" + integrity sha512-PIbxpiJGx6Bb8dQaonNc6CGTRlVntdLg/2nMa1YhnrwYOORY9a3ZgGN0UQYE6lAcj/lkyduJN7BPt/JiY+jAQQ== elegant-spinner@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" integrity sha512-B+ZM+RXvRqQaAmkMlO/oSe5nMUOaUnyfGYCEHoR8wrXsZR2mA0XVibsxV1bvTwxdRWah1PkQqso2EzhILGHtEQ== -elkjs@^0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/elkjs/-/elkjs-0.8.2.tgz#c37763c5a3e24e042e318455e0147c912a7c248e" - integrity sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ== +elkjs@^0.9.0: + version "0.9.3" + resolved "https://registry.yarnpkg.com/elkjs/-/elkjs-0.9.3.tgz#16711f8ceb09f1b12b99e971b138a8384a529161" + integrity sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ== emittery@^0.13.1: version "0.13.1" @@ -11089,22 +10291,14 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: dependencies: once "^1.4.0" -enhanced-resolve@^5.0.0, enhanced-resolve@^5.15.0, enhanced-resolve@^5.7.0: - version "5.15.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" - integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== +enhanced-resolve@^5.0.0, enhanced-resolve@^5.15.0, enhanced-resolve@^5.16.0, enhanced-resolve@^5.7.0: + version "5.16.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz#e8bc63d51b826d6f1cbc0a150ecb5a8b0c62e567" + integrity sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" -enquirer@^2.3.6: - version "2.4.1" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" - integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== - dependencies: - ansi-colors "^4.1.1" - strip-ansi "^6.0.1" - enquirer@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" @@ -11135,9 +10329,9 @@ envalid@7.3.1: tslib "2.3.1" envinfo@^7.7.3: - version "7.10.0" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.10.0.tgz#55146e3909cc5fe63c22da63fb15b05aeac35b13" - integrity sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw== + version "7.13.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.13.0.tgz#81fbb81e5da35d74e814941aeab7c325a606fb31" + integrity sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q== err-code@^2.0.2: version "2.0.3" @@ -11158,55 +10352,57 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.22.1, es-abstract@^1.22.3: - version "1.22.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" - integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== +es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.2: + version "1.23.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.3.tgz#8f0c5a35cd215312573c5a27c87dfd6c881a0aa0" + integrity sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A== dependencies: - array-buffer-byte-length "^1.0.0" - arraybuffer.prototype.slice "^1.0.2" - available-typed-arrays "^1.0.5" - call-bind "^1.0.5" - es-set-tostringtag "^2.0.1" + array-buffer-byte-length "^1.0.1" + arraybuffer.prototype.slice "^1.0.3" + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" + data-view-buffer "^1.0.1" + data-view-byte-length "^1.0.1" + data-view-byte-offset "^1.0.0" + es-define-property "^1.0.0" + es-errors "^1.3.0" + es-object-atoms "^1.0.0" + es-set-tostringtag "^2.0.3" es-to-primitive "^1.2.1" function.prototype.name "^1.1.6" - get-intrinsic "^1.2.2" - get-symbol-description "^1.0.0" + get-intrinsic "^1.2.4" + get-symbol-description "^1.0.2" globalthis "^1.0.3" gopd "^1.0.1" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" + has-property-descriptors "^1.0.2" + has-proto "^1.0.3" has-symbols "^1.0.3" - hasown "^2.0.0" - internal-slot "^1.0.5" - is-array-buffer "^3.0.2" + hasown "^2.0.2" + internal-slot "^1.0.7" + is-array-buffer "^3.0.4" is-callable "^1.2.7" - is-negative-zero "^2.0.2" + is-data-view "^1.0.1" + is-negative-zero "^2.0.3" is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" + is-shared-array-buffer "^1.0.3" is-string "^1.0.7" - is-typed-array "^1.1.12" + is-typed-array "^1.1.13" is-weakref "^1.0.2" object-inspect "^1.13.1" object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.5.1" - safe-array-concat "^1.0.1" - safe-regex-test "^1.0.0" - string.prototype.trim "^1.2.8" - string.prototype.trimend "^1.0.7" - string.prototype.trimstart "^1.0.7" - typed-array-buffer "^1.0.0" - typed-array-byte-length "^1.0.0" - typed-array-byte-offset "^1.0.0" - typed-array-length "^1.0.4" + object.assign "^4.1.5" + regexp.prototype.flags "^1.5.2" + safe-array-concat "^1.1.2" + safe-regex-test "^1.0.3" + string.prototype.trim "^1.2.9" + string.prototype.trimend "^1.0.8" + string.prototype.trimstart "^1.0.8" + typed-array-buffer "^1.0.2" + typed-array-byte-length "^1.0.1" + typed-array-byte-offset "^1.0.2" + typed-array-length "^1.0.6" unbox-primitive "^1.0.2" - which-typed-array "^1.1.13" - -es-array-method-boxes-properly@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" - integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== + which-typed-array "^1.1.15" es-define-property@^1.0.0: version "1.0.0" @@ -11215,29 +10411,31 @@ es-define-property@^1.0.0: dependencies: get-intrinsic "^1.2.4" -es-errors@^1.0.0, es-errors@^1.3.0: +es-errors@^1.2.1, es-errors@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== -es-module-lexer@^1.2.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.1.tgz#c1b0dd5ada807a3b3155315911f364dc4e909db1" - integrity sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q== +es-module-lexer@^1.2.1, es-module-lexer@^1.4.1: + version "1.5.2" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.5.2.tgz#00b423304f2500ac59359cc9b6844951f372d497" + integrity sha512-l60ETUTmLqbVbVHv1J4/qj+M8nq7AwMzEcg3kmJDt9dCNrTk+yHcYFf/Kw75pMDwd9mPcIGCG5LcS20SxYRzFA== -es-module-lexer@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.4.1.tgz#41ea21b43908fe6a287ffcbe4300f790555331f5" - integrity sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w== +es-object-atoms@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.0.0.tgz#ddb55cd47ac2e240701260bc2a8e31ecb643d941" + integrity sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw== + dependencies: + es-errors "^1.3.0" -es-set-tostringtag@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" - integrity sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q== +es-set-tostringtag@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz#8bb60f0a440c2e4281962428438d58545af39777" + integrity sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ== dependencies: - get-intrinsic "^1.2.2" - has-tostringtag "^1.0.0" - hasown "^2.0.0" + get-intrinsic "^1.2.4" + has-tostringtag "^1.0.2" + hasown "^2.0.1" es-shim-unscopables@^1.0.0, es-shim-unscopables@^1.0.2: version "1.0.2" @@ -11273,9 +10471,9 @@ esbuild-wasm@0.20.1: integrity sha512-6v/WJubRsjxBbQdz6izgvx7LsVFvVaGmSdwrFHmEzoVgfXL89hkKPoQHsnVI2ngOkcBUQT9kmAM1hVL1k/Av4A== esbuild-wasm@>=0.15.13: - version "0.20.2" - resolved "https://registry.yarnpkg.com/esbuild-wasm/-/esbuild-wasm-0.20.2.tgz#bbee2a729776b0b88b765c014f161b627435c5b6" - integrity sha512-7o6nmsEqlcXJXMNqnx5K+M4w4OPx7yTFXQHcJyeP3SkXb8p2T8N9E1ayK4vd/qDBepH6fuPoZwiFvZm8x5qv+w== + version "0.21.1" + resolved "https://registry.yarnpkg.com/esbuild-wasm/-/esbuild-wasm-0.21.1.tgz#f436956629ed01d753e06b9806dc938860a01d37" + integrity sha512-ysEyOGsgFji6Vkh1R2C0A2QxglvKun84aOGB1JJXiLnwt8HWktI7mc/CaCnQ+nwZmLBe2IjmmBpe/mStTzYTsw== esbuild@0.20.1: version "0.20.1" @@ -11307,33 +10505,33 @@ esbuild@0.20.1: "@esbuild/win32-x64" "0.20.1" esbuild@>=0.15.13: - version "0.20.2" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.20.2.tgz#9d6b2386561766ee6b5a55196c6d766d28c87ea1" - integrity sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g== + version "0.21.1" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.21.1.tgz#3d6f199f6ec849158278c6632f438463bab88c38" + integrity sha512-GPqx+FX7mdqulCeQ4TsGZQ3djBJkx5k7zBGtqt9ycVlWNg8llJ4RO9n2vciu8BN2zAEs6lPbPl0asZsAh7oWzg== optionalDependencies: - "@esbuild/aix-ppc64" "0.20.2" - "@esbuild/android-arm" "0.20.2" - "@esbuild/android-arm64" "0.20.2" - "@esbuild/android-x64" "0.20.2" - "@esbuild/darwin-arm64" "0.20.2" - "@esbuild/darwin-x64" "0.20.2" - "@esbuild/freebsd-arm64" "0.20.2" - "@esbuild/freebsd-x64" "0.20.2" - "@esbuild/linux-arm" "0.20.2" - "@esbuild/linux-arm64" "0.20.2" - "@esbuild/linux-ia32" "0.20.2" - "@esbuild/linux-loong64" "0.20.2" - "@esbuild/linux-mips64el" "0.20.2" - "@esbuild/linux-ppc64" "0.20.2" - "@esbuild/linux-riscv64" "0.20.2" - "@esbuild/linux-s390x" "0.20.2" - "@esbuild/linux-x64" "0.20.2" - "@esbuild/netbsd-x64" "0.20.2" - "@esbuild/openbsd-x64" "0.20.2" - "@esbuild/sunos-x64" "0.20.2" - "@esbuild/win32-arm64" "0.20.2" - "@esbuild/win32-ia32" "0.20.2" - "@esbuild/win32-x64" "0.20.2" + "@esbuild/aix-ppc64" "0.21.1" + "@esbuild/android-arm" "0.21.1" + "@esbuild/android-arm64" "0.21.1" + "@esbuild/android-x64" "0.21.1" + "@esbuild/darwin-arm64" "0.21.1" + "@esbuild/darwin-x64" "0.21.1" + "@esbuild/freebsd-arm64" "0.21.1" + "@esbuild/freebsd-x64" "0.21.1" + "@esbuild/linux-arm" "0.21.1" + "@esbuild/linux-arm64" "0.21.1" + "@esbuild/linux-ia32" "0.21.1" + "@esbuild/linux-loong64" "0.21.1" + "@esbuild/linux-mips64el" "0.21.1" + "@esbuild/linux-ppc64" "0.21.1" + "@esbuild/linux-riscv64" "0.21.1" + "@esbuild/linux-s390x" "0.21.1" + "@esbuild/linux-x64" "0.21.1" + "@esbuild/netbsd-x64" "0.21.1" + "@esbuild/openbsd-x64" "0.21.1" + "@esbuild/sunos-x64" "0.21.1" + "@esbuild/win32-arm64" "0.21.1" + "@esbuild/win32-ia32" "0.21.1" + "@esbuild/win32-x64" "0.21.1" esbuild@^0.17.0: version "0.17.19" @@ -11420,10 +10618,10 @@ esbuild@^0.19.3: "@esbuild/win32-ia32" "0.19.12" "@esbuild/win32-x64" "0.19.12" -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escalade@^3.1.1, escalade@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" + integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== escape-html@~1.0.3: version "1.0.3" @@ -11483,9 +10681,9 @@ eslint-import-resolver-node@^0.3.9: resolve "^1.22.4" eslint-module-utils@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" - integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== + version "2.8.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz#52f2404300c3bd33deece9d7372fb337cc1d7c34" + integrity sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q== dependencies: debug "^3.2.7" @@ -11546,9 +10744,9 @@ eslint-scope@^7.2.2: estraverse "^5.2.0" eslint-scope@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.0.0.tgz#7b6b067599c436404ce856cd2c47331464603a4a" - integrity sha512-zj3Byw6jX4TcFCJmxOzLt6iol5FAr9xQyZZSQjEzW2UiCJXLwXdRIKCYVFftnpZckaC9Ps9xlC7jB8tSeWWOaw== + version "8.0.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.0.1.tgz#a9601e4b81a0b9171657c343fb13111688963cfc" + integrity sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" @@ -11602,6 +10800,50 @@ eslint@8.56.0: strip-ansi "^6.0.1" text-table "^0.2.0" +eslint@^8.0.0: + version "8.57.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.0.tgz#c786a6fd0e0b68941aaf624596fb987089195668" + integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.4" + "@eslint/js" "8.57.0" + "@humanwhocodes/config-array" "^0.11.14" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + "@ungap/structured-clone" "^1.2.0" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + espree@^9.0.0, espree@^9.6.0, espree@^9.6.1: version "9.6.1" resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" @@ -11705,6 +10947,21 @@ execa@^5.0.0, execa@^5.1.1: signal-exit "^3.0.3" strip-final-newline "^2.0.0" +execa@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-8.0.1.tgz#51f6a5943b580f963c3ca9c6321796db8cc39b8c" + integrity sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^8.0.1" + human-signals "^5.0.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^4.1.0" + strip-final-newline "^3.0.0" + executable@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" @@ -11738,7 +10995,7 @@ exponential-backoff@^3.1.1: resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== -express@4.18.2, express@^4.17.3: +express@4.18.2: version "4.18.2" resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== @@ -11775,6 +11032,43 @@ express@4.18.2, express@^4.17.3: utils-merge "1.0.1" vary "~1.1.2" +express@^4.17.3: + version "4.19.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" + integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.2" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.6.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + extend@^3.0.0, extend@^3.0.2, extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -11825,7 +11119,7 @@ fast-glob@3.2.7: merge2 "^1.3.0" micromatch "^4.0.4" -fast-glob@3.3.2: +fast-glob@3.3.2, fast-glob@^3.2.11, fast-glob@^3.2.12, fast-glob@^3.2.7, fast-glob@^3.2.9, fast-glob@^3.3.0: version "3.3.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== @@ -11836,17 +11130,6 @@ fast-glob@3.3.2: merge2 "^1.3.0" micromatch "^4.0.4" -fast-glob@^3.2.11, fast-glob@^3.2.12, fast-glob@^3.2.7, fast-glob@^3.2.9, fast-glob@^3.3.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" - integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -11873,9 +11156,9 @@ fastparse@^1.1.2: integrity sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ== fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== dependencies: reusify "^1.0.4" @@ -12037,9 +11320,9 @@ find-up@^6.3.0: path-exists "^5.0.0" flat-cache@^3.0.4: - version "3.1.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.1.1.tgz#a02a15fdec25a8f844ff7cc658f03dd99eb4609b" - integrity sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q== + version "3.2.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== dependencies: flatted "^3.2.9" keyv "^4.5.3" @@ -12051,16 +11334,16 @@ flat@^5.0.2: integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== flatted@^3.2.9: - version "3.2.9" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" - integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== + version "3.3.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" + integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== flow-parser@0.*: - version "0.219.5" - resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.219.5.tgz#bff08036bd8f2aa7ebfd54a580dc418e37bc9c0e" - integrity sha512-lHx/cl2XjopBx/ma9RYhG7FGj2JLKacoBwtI3leOp8AwRDPGwu6bzJoaCMfIl/sq14KdtY5MGzd5q6nKfGzcuQ== + version "0.235.1" + resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.235.1.tgz#469c70adfa3c156f3a1792e7b6d7017f01f45f1d" + integrity sha512-s04193L4JE+ntEcQXbD6jxRRlyj9QXcgEl2W6xSjH4l9x4b0eHoCHfbYHjqf9LdZFUiM5LhgpiqsvLj/AyOyYQ== -follow-redirects@^1.0.0, follow-redirects@^1.14.0, follow-redirects@^1.15.4: +follow-redirects@^1.0.0, follow-redirects@^1.14.0, follow-redirects@^1.15.6: version "1.15.6" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== @@ -12144,7 +11427,7 @@ forwarded@0.2.0: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== -fraction.js@^4.3.6, fraction.js@^4.3.7: +fraction.js@^4.3.7: version "4.3.7" resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7" integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew== @@ -12159,7 +11442,7 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-extra@11.1.1, fs-extra@^11.1.0: +fs-extra@11.1.1: version "11.1.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== @@ -12177,6 +11460,15 @@ fs-extra@^10.0.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs-extra@^11.1.0: + version "11.2.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-extra@^9.0.1: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" @@ -12202,9 +11494,9 @@ fs-minipass@^3.0.0: minipass "^7.0.3" fs-monkey@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.5.tgz#fe450175f0db0d7ea758102e1d84096acb925788" - integrity sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew== + version "1.0.6" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.6.tgz#8ead082953e88d992cf3ff844faa907b26756da2" + integrity sha512-b1FMfwetIKymC0eioW7mTywihSQE4oLzQn1dB6rZB5fx/3NpNEdAWeCSMB+60/AeT0TCXsxzAlcYVEFCTAksWg== fs.realpath@^1.0.0: version "1.0.0" @@ -12280,17 +11572,7 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" - integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== - dependencies: - function-bind "^1.1.2" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - -get-intrinsic@^1.2.4: +get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== @@ -12307,9 +11589,9 @@ get-nonce@^1.0.0: integrity sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q== get-npm-tarball-url@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/get-npm-tarball-url/-/get-npm-tarball-url-2.0.3.tgz#67dff908d699e9e2182530ae6e939a93e5f8dfdb" - integrity sha512-R/PW6RqyaBQNWYaSyfrh54/qtcnOp22FHCCiRhSSZj0FP3KQWCsxxt0DzIdVTbwTqe9CtQfvl/FPD4UIPt4pqw== + version "2.1.0" + resolved "https://registry.yarnpkg.com/get-npm-tarball-url/-/get-npm-tarball-url-2.1.0.tgz#cbd6bb25884622bc3191c761466c93ac83343213" + integrity sha512-ro+DiMu5DXgRBabqXupW38h7WPZ9+Ad8UjwhvsmmN8w1sU7ab0nzAXvVZ4kqYg57OrqomRtJvepX5/xvFKNtjA== get-package-type@^0.1.0: version "0.1.0" @@ -12333,13 +11615,19 @@ get-stream@^6.0.0: resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== +get-stream@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-8.0.1.tgz#def9dfd71742cd7754a7761ed43749a27d02eca2" + integrity sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA== + +get-symbol-description@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.2.tgz#533744d5aa20aca4e079c8e5daf7fd44202821f5" + integrity sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" + call-bind "^1.0.5" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" getos@^3.2.1: version "3.2.1" @@ -12356,16 +11644,17 @@ getpass@^0.1.1: assert-plus "^1.0.0" giget@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/giget/-/giget-1.1.3.tgz#574ed901031eafa732347a7990d84bfa6484c51a" - integrity sha512-zHuCeqtfgqgDwvXlR84UNgnJDuUHQcNI5OqWqFxxuk2BshuKbYhJWdxBsEo4PvKqoGh23lUAIvBNpChMLv7/9Q== - dependencies: - colorette "^2.0.20" - defu "^6.1.2" - https-proxy-agent "^7.0.2" - mri "^1.2.0" - node-fetch-native "^1.4.0" - pathe "^1.1.1" + version "1.2.3" + resolved "https://registry.yarnpkg.com/giget/-/giget-1.2.3.tgz#ef6845d1140e89adad595f7f3bb60aa31c672cb6" + integrity sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA== + dependencies: + citty "^0.1.6" + consola "^3.2.3" + defu "^6.1.4" + node-fetch-native "^1.6.3" + nypm "^0.3.8" + ohash "^1.1.3" + pathe "^1.1.2" tar "^6.2.0" github-slugger@^1.0.0: @@ -12399,28 +11688,16 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@7.1.4: - version "7.1.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" - integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - glob@^10.0.0, glob@^10.2.2, glob@^10.3.10: - version "10.3.10" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" - integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== + version "10.3.12" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.12.tgz#3a65c363c2e9998d220338e88a5f6ac97302960b" + integrity sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg== dependencies: foreground-child "^3.1.0" - jackspeak "^2.3.5" + jackspeak "^2.3.6" minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry "^1.10.1" + minipass "^7.0.4" + path-scurry "^1.10.2" glob@^7.0.0, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.2.3" @@ -12458,18 +11735,19 @@ globals@^11.1.0: integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^13.19.0, globals@^13.20.0: - version "13.23.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.23.0.tgz#ef31673c926a0976e1f61dab4dca57e0c0a8af02" - integrity sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA== + version "13.24.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" + integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== dependencies: type-fest "^0.20.2" globalthis@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" - integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + version "1.0.4" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236" + integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== dependencies: - define-properties "^1.1.3" + define-properties "^1.2.1" + gopd "^1.0.1" globby@^11.0.1, globby@^11.0.2, globby@^11.1.0: version "11.1.0" @@ -12568,7 +11846,7 @@ got@11.8.6: p-cancelable "^2.0.0" responselike "^2.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -12655,46 +11933,39 @@ has-own-prop@^2.0.0: resolved "https://registry.yarnpkg.com/has-own-prop/-/has-own-prop-2.0.0.tgz#f0f95d58f65804f5d218db32563bb85b8e0417af" integrity sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ== -has-property-descriptors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" - integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== - dependencies: - get-intrinsic "^1.2.2" - -has-property-descriptors@^1.0.2: +has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== dependencies: es-define-property "^1.0.0" -has-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" - integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== +has-proto@^1.0.1, has-proto@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" + integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== has-symbols@^1.0.2, has-symbols@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== +has-tostringtag@^1.0.0, has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== dependencies: - has-symbols "^1.0.2" + has-symbols "^1.0.3" has-unicode@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== -hasown@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" - integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== +hasown@^2.0.0, hasown@^2.0.1, hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== dependencies: function-bind "^1.1.2" @@ -12703,11 +11974,6 @@ he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -heap@^0.2.6: - version "0.2.7" - resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc" - integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg== - helmet@7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/helmet/-/helmet-7.0.0.tgz#ac3011ba82fa2467f58075afa58a49427ba6212d" @@ -12719,9 +11985,9 @@ hosted-git-info@^2.1.4: integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== hosted-git-info@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-7.0.1.tgz#9985fcb2700467fecf7f33a4d4874e30680b5322" - integrity sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA== + version "7.0.2" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-7.0.2.tgz#9b751acac097757667f30114607ef7b661ff4f17" + integrity sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w== dependencies: lru-cache "^10.0.1" @@ -12743,9 +12009,9 @@ html-encoding-sniffer@^3.0.0: whatwg-encoding "^2.0.0" html-entities@^2.1.0, html-entities@^2.3.2: - version "2.4.0" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.4.0.tgz#edd0cee70402584c8c76cc2c0556db09d1f45061" - integrity sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ== + version "2.5.2" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.5.2.tgz#201a3cf95d3a15be7099521620d19dfb4f65359f" + integrity sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA== html-escaper@^2.0.0, html-escaper@^2.0.2: version "2.0.2" @@ -12766,9 +12032,9 @@ html-minifier-terser@^6.0.2: terser "^5.10.0" html-webpack-plugin@^5.5.0: - version "5.5.3" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz#72270f4a78e222b5825b296e5e3e1328ad525a3e" - integrity sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg== + version "5.6.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz#50a8fa6709245608cb00e811eacecb8e0d7b7ea0" + integrity sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw== dependencies: "@types/html-minifier-terser" "^6.0.0" html-minifier-terser "^6.0.2" @@ -12842,9 +12108,9 @@ http-proxy-agent@^5.0.0: debug "4" http-proxy-agent@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz#e9096c5afd071a3fce56e6252bb321583c124673" - integrity sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ== + version "7.0.2" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e" + integrity sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig== dependencies: agent-base "^7.1.0" debug "^4.3.4" @@ -12910,7 +12176,7 @@ http2-wrapper@^1.0.0-beta.5.2: quick-lru "^5.1.1" resolve-alpn "^1.0.0" -https-proxy-agent@7.0.4: +https-proxy-agent@7.0.4, https-proxy-agent@^7.0.1: version "7.0.4" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz#8e97b841a029ad8ddc8731f26595bad868cb4168" integrity sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg== @@ -12934,14 +12200,6 @@ https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1: agent-base "6" debug "4" -https-proxy-agent@^7.0.1, https-proxy-agent@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz#e2645b846b90e96c6e6f347fb5b2e41f1590b09b" - integrity sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA== - dependencies: - agent-base "^7.0.2" - debug "4" - human-signals@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" @@ -12952,6 +12210,11 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +human-signals@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28" + integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== + iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -12988,17 +12251,17 @@ ieee754@^1.1.13: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -ignore-walk@^6.0.0: - version "6.0.3" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.3.tgz#0fcdb6decaccda35e308a7b0948645dd9523b7bb" - integrity sha512-C7FfFoTA+bI10qfeydT8aZbvr91vAEU+2W5BZUlzPec47oNb07SsOfwYrtxuvOYdUApPP/Qlh4DtAO51Ekk2QA== +ignore-walk@^6.0.4: + version "6.0.5" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.5.tgz#ef8d61eab7da169078723d1f82833b36e200b0dd" + integrity sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A== dependencies: minimatch "^9.0.0" ignore@^5.0.4, ignore@^5.1.9, ignore@^5.2.0, ignore@^5.2.4: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + version "5.3.1" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== image-size@~0.5.0: version "0.5.5" @@ -13006,9 +12269,9 @@ image-size@~0.5.0: integrity sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ== immutable@^4.0.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f" - integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA== + version "4.3.5" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.5.tgz#f8b436e66d59f99760dc577f5c99a4fd2a5cc5a0" + integrity sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw== import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" @@ -13090,12 +12353,12 @@ inquirer@9.2.15: strip-ansi "^6.0.1" wrap-ansi "^6.2.0" -internal-slot@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" - integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== +internal-slot@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.7.tgz#c06dcca3ed874249881007b0a5523b172a190802" + integrity sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g== dependencies: - get-intrinsic "^1.2.2" + es-errors "^1.3.0" hasown "^2.0.0" side-channel "^1.0.4" @@ -13129,9 +12392,9 @@ ionicons@7.4.0: "@stencil/core" "^4.0.3" ioredis@^5.0.0: - version "5.3.2" - resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.3.2.tgz#9139f596f62fc9c72d873353ac5395bcf05709f7" - integrity sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA== + version "5.4.1" + resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.4.1.tgz#1c56b70b759f01465913887375ed809134296f40" + integrity sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA== dependencies: "@ioredis/commands" "^1.1.1" cluster-key-slot "^1.1.0" @@ -13143,10 +12406,18 @@ ioredis@^5.0.0: redis-parser "^3.0.0" standard-as-callback "^2.1.0" +ip-address@^9.0.5: + version "9.0.5" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a" + integrity sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g== + dependencies: + jsbn "1.1.0" + sprintf-js "^1.1.3" + ip@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" - integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + version "2.0.1" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105" + integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ== ipaddr.js@1.9.1: version "1.9.1" @@ -13154,9 +12425,9 @@ ipaddr.js@1.9.1: integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== ipaddr.js@^2.0.1, ipaddr.js@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.1.0.tgz#2119bc447ff8c257753b196fc5f1ce08a4cdf39f" - integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.2.0.tgz#d33fa7bac284f4de7af949638c9d68157c6b92e8" + integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA== is-absolute-url@^3.0.0: version "3.0.3" @@ -13171,14 +12442,13 @@ is-arguments@^1.0.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" - integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== +is-array-buffer@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.4.tgz#7a1f92b3d61edd2bc65d24f130530ea93d7fae98" + integrity sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw== dependencies: call-bind "^1.0.2" - get-intrinsic "^1.2.0" - is-typed-array "^1.1.10" + get-intrinsic "^1.2.1" is-arrayish@^0.2.1: version "0.2.1" @@ -13231,6 +12501,13 @@ is-core-module@^2.13.0, is-core-module@^2.13.1, is-core-module@^2.8.1: dependencies: hasown "^2.0.0" +is-data-view@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-data-view/-/is-data-view-1.0.1.tgz#4b4d3a511b70f3dc26d42c03ca9ca515d847759f" + integrity sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w== + dependencies: + is-typed-array "^1.1.13" + is-date-object@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" @@ -13320,10 +12597,10 @@ is-nan@^1.3.2: call-bind "^1.0.0" define-properties "^1.1.3" -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== +is-negative-zero@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747" + integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw== is-number-object@^1.0.4: version "1.0.7" @@ -13389,12 +12666,12 @@ is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== +is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz#1237f1cba059cdb62431d378dcc37d9680181688" + integrity sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg== dependencies: - call-bind "^1.0.2" + call-bind "^1.0.7" is-stream@^1.1.0: version "1.1.0" @@ -13406,6 +12683,11 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + is-string@^1.0.5, is-string@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" @@ -13420,12 +12702,12 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" -is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.3, is-typed-array@^1.1.9: - version "1.1.12" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" - integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== +is-typed-array@^1.1.13, is-typed-array@^1.1.3: + version "1.1.13" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229" + integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw== dependencies: - which-typed-array "^1.1.11" + which-typed-array "^1.1.14" is-typedarray@~1.0.0: version "1.0.0" @@ -13500,9 +12782,9 @@ isstream@~0.1.2: integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" - integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + version "3.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== istanbul-lib-instrument@^5.0.4: version "5.2.1" @@ -13516,13 +12798,13 @@ istanbul-lib-instrument@^5.0.4: semver "^6.3.0" istanbul-lib-instrument@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz#71e87707e8041428732518c6fb5211761753fbdf" - integrity sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA== + version "6.0.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz#91655936cf7380e4e473383081e38478b69993b1" + integrity sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw== dependencies: - "@babel/core" "^7.12.3" - "@babel/parser" "^7.14.7" - "@istanbuljs/schema" "^0.1.2" + "@babel/core" "^7.23.9" + "@babel/parser" "^7.23.9" + "@istanbuljs/schema" "^0.1.3" istanbul-lib-coverage "^3.2.0" semver "^7.5.4" @@ -13545,9 +12827,9 @@ istanbul-lib-source-maps@^4.0.0: source-map "^0.6.1" istanbul-reports@^3.1.3: - version "3.1.6" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz#2544bcab4768154281a2f0870471902704ccaa1a" - integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== + version "3.1.7" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.7.tgz#daed12b9e1dca518e15c056e1e537e741280fa0b" + integrity sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" @@ -13557,7 +12839,7 @@ iterare@1.2.1: resolved "https://registry.yarnpkg.com/iterare/-/iterare-1.2.1.tgz#139c400ff7363690e33abffa33cbba8920f00042" integrity sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q== -jackspeak@^2.3.5: +jackspeak@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== @@ -13567,9 +12849,9 @@ jackspeak@^2.3.5: "@pkgjs/parseargs" "^0.11.0" jake@^10.8.5: - version "10.8.7" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" - integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== + version "10.9.1" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.1.tgz#8dc96b7fcc41cb19aa502af506da4e1d56f5e62b" + integrity sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w== dependencies: async "^3.2.3" chalk "^4.0.2" @@ -14020,6 +13302,11 @@ js-yaml@^3.10.0, js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +jsbn@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" + integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A== + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -14051,9 +13338,9 @@ jscodeshift@^0.14.0: write-file-atomic "^2.3.0" jscodeshift@^0.15.1: - version "0.15.1" - resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.15.1.tgz#6c7a9572acdfa4f54098e958f71a05716a4e546b" - integrity sha512-hIJfxUy8Rt4HkJn/zZPU9ChKfKZM1342waJ1QC2e2YsPcWhM+3BJ4dcfQCzArTrk1jJeNLB341H+qOcEHRxJZg== + version "0.15.2" + resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.15.2.tgz#145563860360b4819a558c75c545f39683e5a0be" + integrity sha512-FquR7Okgmc4Sd0aEDwqho3rEiKR3BdvuG9jfdHjLJ6JQoWSMpavug3AoIfnfWhxFlf+5pzQh8qjqz0DWFrNQzA== dependencies: "@babel/core" "^7.23.0" "@babel/parser" "^7.23.0" @@ -14136,9 +13423,9 @@ json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-parse-even-better-errors@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz#2cb2ee33069a78870a0c7e3da560026b89669cf7" - integrity sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA== + version "3.0.2" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz#b43d35e89c0f3be6b5fbbe9dc6c82467b30c28da" + integrity sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ== json-schema-traverse@^0.4.1: version "0.4.1" @@ -14304,10 +13591,10 @@ karma-source-map-support@1.4.0: dependencies: source-map-support "^0.5.5" -katex@^0.16.0: - version "0.16.9" - resolved "https://registry.yarnpkg.com/katex/-/katex-0.16.9.tgz#bc62d8f7abfea6e181250f85a56e4ef292dcb1fa" - integrity sha512-fsSYjWS0EEOwvy81j3vRA8TEAhQhKiqO+FQaKWp0m39qwOzHVBgAUBIXWj1pB+O2W3fIpNa6Y9KSKCVbfPhyAQ== +katex@^0.16.0, katex@^0.16.9: + version "0.16.10" + resolved "https://registry.yarnpkg.com/katex/-/katex-0.16.10.tgz#6f81b71ac37ff4ec7556861160f53bc5f058b185" + integrity sha512-ZiqaC04tp2O5utMsl2TEZTXxa6WSC4yo0fv5ML++D3QZv/vx2Mct0mTlRx3O+uUkjfuAgOkzsCmq5MiUEsDDdA== dependencies: commander "^8.3.0" @@ -14356,11 +13643,6 @@ layout-base@^1.0.0: resolved "https://registry.yarnpkg.com/layout-base/-/layout-base-1.0.2.tgz#1291e296883c322a9dd4c5dd82063721b53e26e2" integrity sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg== -layout-base@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/layout-base/-/layout-base-2.0.1.tgz#d0337913586c90f9c2c075292069f5c2da5dd285" - integrity sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg== - lazy-ass@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/lazy-ass/-/lazy-ass-1.6.0.tgz#7999655e8646c17f089fdd187d150d3324d54513" @@ -14438,9 +13720,9 @@ levn@~0.3.0: type-check "~0.3.2" libphonenumber-js@^1.10.14: - version "1.10.48" - resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.10.48.tgz#3c426b4aa21dfe3210bfbda47d208acffa3631bf" - integrity sha512-Vvcgt4+o8+puIBJZLdMshPYx9nRN3/kTT7HPtOyfYrSQuN9PGBF1KUv0g07fjNzt4E4GuA7FnsLb+WeAMzyRQg== + version "1.11.1" + resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.11.1.tgz#2596683e1876bfee74082bb49339fe0a85ae34f9" + integrity sha512-Wze1LPwcnzvcKGcRHFGFECTaLzxOtujwpf924difr5zniyYv1C2PiW0419qDR7m8lKDxsImu5mwxFuXhXpjmvw== license-webpack-plugin@4.0.2, license-webpack-plugin@^4.0.2: version "4.0.2" @@ -14449,10 +13731,10 @@ license-webpack-plugin@4.0.2, license-webpack-plugin@^4.0.2: dependencies: webpack-sources "^3.0.0" -lilconfig@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" - integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== +lilconfig@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.1.tgz#9d8a246fa753106cfc205fd2d77042faca56e5e3" + integrity sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ== lines-and-columns@^1.1.6: version "1.2.4" @@ -14460,9 +13742,9 @@ lines-and-columns@^1.1.6: integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== lines-and-columns@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.3.tgz#b2f0badedb556b747020ab8ea7f0373e22efac1b" - integrity sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w== + version "2.0.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.4.tgz#d00318855905d2660d8c0822e3f5a4715855fc42" + integrity sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A== listr-silent-renderer@^1.1.1: version "1.1.1" @@ -14681,10 +13963,10 @@ lru-cache@6.0.0, lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^10.0.1, "lru-cache@^9.1.1 || ^10.0.0": - version "10.0.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" - integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== +lru-cache@^10.0.1, lru-cache@^10.2.0: + version "10.2.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.2.tgz#48206bc114c1252940c41b25b41af5b545aca878" + integrity sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ== lru-cache@^5.1.1: version "5.1.1" @@ -14694,9 +13976,9 @@ lru-cache@^5.1.1: yallist "^3.0.2" luxon@^3.2.1: - version "3.4.3" - resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.4.3.tgz#8ddf0358a9492267ffec6a13675fbaab5551315d" - integrity sha512-tFWBiv3h7z+T/tDaoxA8rqTxy1CHV6gHS//QdaH4pulbq/JuBSGgQspQQqcgnwdAx6pNI7cmvz5Sv/addzHmUg== + version "3.4.4" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.4.4.tgz#cf20dc27dc532ba41a169c43fdcc0063601577af" + integrity sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA== magic-string@0.30.0: version "0.30.0" @@ -14705,7 +13987,7 @@ magic-string@0.30.0: dependencies: "@jridgewell/sourcemap-codec" "^1.4.13" -magic-string@0.30.5, magic-string@~0.30.2: +magic-string@0.30.5: version "0.30.5" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.5.tgz#1994d980bd1c8835dc6e78db7cbd4ae4f24746f9" integrity sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA== @@ -14719,6 +14001,13 @@ magic-string@0.30.8: dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" +magic-string@^0.30.5, magic-string@~0.30.2: + version "0.30.10" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.10.tgz#123d9c41a0cb5640c892b041d4cfb3bd0aa4b39e" + integrity sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ== + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.15" + make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" @@ -14746,10 +14035,10 @@ make-error@1.x, make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -make-fetch-happen@^13.0.0: - version "13.0.0" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-13.0.0.tgz#705d6f6cbd7faecb8eac2432f551e49475bfedf0" - integrity sha512-7ThobcL8brtGo9CavByQrQi+23aIfgYU++wg4B87AIS8Rb2ZBt/MEaDqzA00Xwv/jUjAjYkLHjVolYuTLKda2A== +make-fetch-happen@^13.0.0, make-fetch-happen@^13.0.1: + version "13.0.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz#273ba2f78f45e1f3a6dca91cede87d9fa4821e36" + integrity sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA== dependencies: "@npmcli/agent" "^2.0.0" cacache "^18.0.0" @@ -14760,6 +14049,7 @@ make-fetch-happen@^13.0.0: minipass-flush "^1.0.5" minipass-pipeline "^1.2.4" negotiator "^0.6.3" + proc-log "^4.2.0" promise-retry "^2.0.1" ssri "^10.0.0" @@ -14776,9 +14066,9 @@ map-or-similar@^1.5.0: integrity sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg== markdown-to-jsx@^7.1.8: - version "7.3.2" - resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-7.3.2.tgz#f286b4d112dad3028acc1e77dfe1f653b347e131" - integrity sha512-B+28F5ucp83aQm+OxNrPkS8z0tMKaeHiy0lHJs3LqCyDQFtWuenaIrkaVTgAm1pf1AU85LXltva86hlaT17i8Q== + version "7.4.7" + resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-7.4.7.tgz#740ee7ec933865ef5cc683a0992797685a75e2ee" + integrity sha512-0+ls1IQZdU6cwM1yu0ZjjiVWYtkbExSyUIFU2ZeDIFuZM1W42Mh4OlJ4nb4apX4H8smxDHRdFaoIVJGwfv5hkg== marked@9.1.6: version "9.1.6" @@ -14867,22 +14157,22 @@ merge2@^1.3.0, merge2@^1.4.1: integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== mermaid@^10.6.0: - version "10.6.1" - resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-10.6.1.tgz#701f4160484137a417770ce757ce1887a98c00fc" - integrity sha512-Hky0/RpOw/1il9X8AvzOEChfJtVvmXm+y7JML5C//ePYMy0/9jCEmW1E1g86x9oDfW9+iVEdTV/i+M6KWRNs4A== + version "10.9.0" + resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-10.9.0.tgz#4d1272fbe434bd8f3c2c150554dc8a23a9bf9361" + integrity sha512-swZju0hFox/B/qoLKK0rOxxgh8Cf7rJSfAUc1u8fezVihYMvrJAS45GzAxTVf4Q+xn9uMgitBcmWk7nWGXOs/g== dependencies: "@braintree/sanitize-url" "^6.0.1" "@types/d3-scale" "^4.0.3" "@types/d3-scale-chromatic" "^3.0.0" - cytoscape "^3.23.0" + cytoscape "^3.28.1" cytoscape-cose-bilkent "^4.1.0" - cytoscape-fcose "^2.1.0" d3 "^7.4.0" d3-sankey "^0.12.3" dagre-d3-es "7.0.10" dayjs "^1.11.7" dompurify "^3.0.5" - elkjs "^0.8.2" + elkjs "^0.9.0" + katex "^0.16.9" khroma "^2.0.0" lodash-es "^4.17.21" mdast-util-from-markdown "^1.3.0" @@ -15131,6 +14421,11 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + mimic-response@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" @@ -15161,14 +14456,7 @@ minimalistic-assert@^1.0.0: resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@3.0.5: - version "3.0.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.5.tgz#4da8f1290ee0f0f8e83d60ca69f8f134068604a3" - integrity sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@9.0.3, minimatch@^9.0.0, minimatch@^9.0.1, minimatch@^9.0.3: +minimatch@9.0.3: version "9.0.3" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== @@ -15189,22 +14477,29 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" +minimatch@^9.0.0, minimatch@^9.0.1, minimatch@^9.0.4: + version "9.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.4.tgz#8e49c731d1749cbec05050ee5145147b32496a51" + integrity sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -minipass-collect@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" - integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== +minipass-collect@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-2.0.1.tgz#1621bc77e12258a12c60d34e2276ec5c20680863" + integrity sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw== dependencies: - minipass "^3.0.0" + minipass "^7.0.3" minipass-fetch@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.4.tgz#4d4d9b9f34053af6c6e597a64be8e66e42bf45b7" - integrity sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg== + version "3.0.5" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.5.tgz#f0f97e40580affc4a35cc4a1349f05ae36cb1e4c" + integrity sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg== dependencies: minipass "^7.0.3" minipass-sized "^1.0.3" @@ -15253,10 +14548,10 @@ minipass@^5.0.0: resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.2, minipass@^7.0.3: - version "7.0.4" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" - integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.2, minipass@^7.0.3, minipass@^7.0.4: + version "7.1.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.0.tgz#b545f84af94e567386770159302ca113469c80b8" + integrity sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig== minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" @@ -15284,11 +14579,11 @@ mkdirp@^1.0.3: integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== moment@^2.27.0: - version "2.29.4" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" - integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== + version "2.30.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae" + integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how== -mri@^1.1.0, mri@^1.2.0: +mri@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== @@ -15370,12 +14665,7 @@ mute-stream@1.0.0: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== -nanoid@^3.3.1, nanoid@^3.3.6: - version "3.3.6" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" - integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== - -nanoid@^3.3.7: +nanoid@^3.3.1, nanoid@^3.3.7: version "3.3.7" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== @@ -15386,11 +14676,10 @@ natural-compare@^1.4.0: integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== needle@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/needle/-/needle-3.2.0.tgz#07d240ebcabfd65c76c03afae7f6defe6469df44" - integrity sha512-oUvzXnyLiVyVGoianLijF9O/RecZUf7TkBfimjGrLM4eQhXyeJwM6GeAWccwfQ9aa4gMCZKqhAOuLaMIcQxajQ== + version "3.3.1" + resolved "https://registry.yarnpkg.com/needle/-/needle-3.3.1.tgz#63f75aec580c2e77e209f3f324e2cdf3d29bd049" + integrity sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q== dependencies: - debug "^3.2.6" iconv-lite "^0.6.3" sax "^1.2.4" @@ -15483,10 +14772,10 @@ node-dir@^0.1.17: dependencies: minimatch "^3.0.2" -node-fetch-native@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.4.0.tgz#fbe8ac033cb6aa44bd106b5e4fd2b6277ba70fa1" - integrity sha512-F5kfEj95kX8tkDhUCYdV8dg3/8Olx/94zB8+ZNthFs6Bz31UpUi8Xh40TN3thLwXgrwXry1pEg9lJ++tLWTcqA== +node-fetch-native@^1.6.3: + version "1.6.4" + resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.6.4.tgz#679fc8fd8111266d47d7e72c379f1bed9acff06e" + integrity sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ== node-fetch@^2.0.0, node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.6.7: version "2.7.0" @@ -15506,14 +14795,14 @@ node-gyp-build-optional-packages@5.0.7: integrity sha512-YlCCc6Wffkx0kHkmam79GKvDQ6x+QZkMjFGrIMxgFNILFvGSbCp2fCBC55pGTT9gVaz8Na5CLmxt/urtzRv36w== node-gyp-build@^4.2.2: - version "4.6.1" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.1.tgz#24b6d075e5e391b8d5539d98c7fc5c210cac8a3e" - integrity sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ== + version "4.8.1" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.1.tgz#976d3ad905e71b76086f4f0b0d3637fe79b6cda5" + integrity sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw== node-gyp@^10.0.0: - version "10.0.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-10.0.1.tgz#205514fc19e5830fa991e4a689f9e81af377a966" - integrity sha512-gg3/bHehQfZivQVfqIyy8wTdSymF9yTyP4CJifK73imyNMU8AIGQE2pUa7dNWfmMeG9cDVF2eehiRMv0LC1iAg== + version "10.1.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-10.1.0.tgz#75e6f223f2acb4026866c26a2ead6aab75a8ca7e" + integrity sha512-B4J5M1cABxPc5PwfjhbV5hoy2DP9p8lFXASnEN6hugXOa61416tnTZ29x9sSwAd0o99XNIcpvDDy1swAExsVKA== dependencies: env-paths "^2.2.0" exponential-backoff "^3.1.1" @@ -15536,11 +14825,6 @@ node-machine-id@1.1.12: resolved "https://registry.yarnpkg.com/node-machine-id/-/node-machine-id-1.1.12.tgz#37904eee1e59b320bb9c5d6c0a59f3b469cb6267" integrity sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ== -node-releases@^2.0.13: - version "2.0.13" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" - integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== - node-releases@^2.0.14: version "2.0.14" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" @@ -15552,9 +14836,9 @@ non-layered-tidy-tree-layout@^2.0.2: integrity sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw== nopt@^7.0.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-7.2.0.tgz#067378c68116f602f552876194fd11f1292503d7" - integrity sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA== + version "7.2.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-7.2.1.tgz#1cac0eab9b8e97c9093338446eddd40b2c8ca1e7" + integrity sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w== dependencies: abbrev "^2.0.0" @@ -15569,9 +14853,9 @@ normalize-package-data@^2.5.0: validate-npm-package-license "^3.0.1" normalize-package-data@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-6.0.0.tgz#68a96b3c11edd462af7189c837b6b1064a484196" - integrity sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg== + version "6.0.1" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-6.0.1.tgz#fa69e9452210f0fabf4d79ee08d0c2870c51ed88" + integrity sha512-6rvCfeRW+OEZagAB4lMLSNuTNYZWLVtKccK79VSTf//yTY5VOCgcpH80O+bZK8Neps7pUnd5G+QlMg1yV/2iZQ== dependencies: hosted-git-info "^7.0.0" is-core-module "^2.8.1" @@ -15594,9 +14878,9 @@ normalize-url@^6.0.1: integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== npm-bundled@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-3.0.0.tgz#7e8e2f8bb26b794265028491be60321a25a39db7" - integrity sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ== + version "3.0.1" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-3.0.1.tgz#cca73e15560237696254b10170d8f86dad62da25" + integrity sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ== dependencies: npm-normalize-package-bin "^3.0.0" @@ -15612,7 +14896,7 @@ npm-normalize-package-bin@^3.0.0: resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz#25447e32a9a7de1f51362c61a559233b89947832" integrity sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ== -npm-package-arg@11.0.1, npm-package-arg@^11.0.0: +npm-package-arg@11.0.1: version "11.0.1" resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-11.0.1.tgz#f208b0022c29240a1c532a449bdde3f0a4708ebc" integrity sha512-M7s1BD4NxdAvBKUPqqRW957Xwcl/4Zvo8Aj+ANrzvIPzGJZElrH7Z//rSaec2ORcND6FHHLnZeY8qgTpXDMFQQ== @@ -15622,14 +14906,24 @@ npm-package-arg@11.0.1, npm-package-arg@^11.0.0: semver "^7.3.5" validate-npm-package-name "^5.0.0" +npm-package-arg@^11.0.0: + version "11.0.2" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-11.0.2.tgz#1ef8006c4a9e9204ddde403035f7ff7d718251ca" + integrity sha512-IGN0IAwmhDJwy13Wc8k+4PEbTPhpJnMtfR53ZbOyjkvmEcLS4nCwp6mvMWjS5sUjeiW3mpx6cHmuhKEu9XmcQw== + dependencies: + hosted-git-info "^7.0.0" + proc-log "^4.0.0" + semver "^7.3.5" + validate-npm-package-name "^5.0.0" + npm-packlist@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-8.0.0.tgz#4e7f51fe1d5e69b19508ed8dc6cd3ae2e7b38c17" - integrity sha512-ErAGFB5kJUciPy1mmx/C2YFbvxoJ0QJ9uwkCZOeR6CqLLISPZBOiFModAbSXnjjlwW5lOhuhXva+fURsSGJqyw== + version "8.0.2" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-8.0.2.tgz#5b8d1d906d96d21c85ebbeed2cf54147477c8478" + integrity sha512-shYrPFIS/JLP4oQmAwDyk5HcyysKW8/JLTEA32S0Z5TzvpaeeX2yMFfoK1fjEBnCBvVyIB/Jj/GBFdm0wsgzbA== dependencies: - ignore-walk "^6.0.0" + ignore-walk "^6.0.4" -npm-pick-manifest@9.0.0, npm-pick-manifest@^9.0.0: +npm-pick-manifest@9.0.0: version "9.0.0" resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-9.0.0.tgz#f87a4c134504a2c7931f2bb8733126e3c3bb7e8f" integrity sha512-VfvRSs/b6n9ol4Qb+bDwNGUXutpy76x6MARw/XssevE0TnctIKcmklJZM5Z7nqs5z5aW+0S63pgCNbpkUNNXBg== @@ -15639,18 +14933,29 @@ npm-pick-manifest@9.0.0, npm-pick-manifest@^9.0.0: npm-package-arg "^11.0.0" semver "^7.3.5" +npm-pick-manifest@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-9.0.1.tgz#c90658bd726fe5bca9d2869f3e99359b8fcda046" + integrity sha512-Udm1f0l2nXb3wxDpKjfohwgdFUSV50UVwzEIpDXVsbDMXVIEF81a/i0UhuQbhrPMMmdiq3+YMFLFIRVLs3hxQw== + dependencies: + npm-install-checks "^6.0.0" + npm-normalize-package-bin "^3.0.0" + npm-package-arg "^11.0.0" + semver "^7.3.5" + npm-registry-fetch@^16.0.0: - version "16.1.0" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-16.1.0.tgz#10227b7b36c97bc1cf2902a24e4f710cfe62803c" - integrity sha512-PQCELXKt8Azvxnt5Y85GseQDJJlglTFM9L9U9gkv2y4e9s0k3GVDdOx3YoB6gm2Do0hlkzC39iCGXby+Wve1Bw== + version "16.2.1" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-16.2.1.tgz#c367df2d770f915da069ff19fd31762f4bca3ef1" + integrity sha512-8l+7jxhim55S85fjiDGJ1rZXBWGtRLi1OSb4Z3BPLObPuIaeKRlPRiYMSHU4/81ck3t71Z+UwDDl47gcpmfQQA== dependencies: + "@npmcli/redact" "^1.1.0" make-fetch-happen "^13.0.0" minipass "^7.0.2" minipass-fetch "^3.0.0" minipass-json-stream "^1.0.1" minizlib "^2.1.2" npm-package-arg "^11.0.0" - proc-log "^3.0.0" + proc-log "^4.0.0" npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" @@ -15659,6 +14964,13 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +npm-run-path@^5.1.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.3.0.tgz#e23353d0ebb9317f174e93417e4a4d82d0249e9f" + integrity sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ== + dependencies: + path-key "^4.0.0" + npmlog@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" @@ -15682,9 +14994,9 @@ number-is-nan@^1.0.0: integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== nwsapi@^2.2.2: - version "2.2.7" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.7.tgz#738e0707d3128cb750dddcfe90e4610482df0f30" - integrity sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ== + version "2.2.9" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.9.tgz#7f3303218372db2e9f27c27766bcfc59ae7e61c6" + integrity sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg== nx@18.3.3: version "18.3.3" @@ -15695,7 +15007,7 @@ nx@18.3.3: "@yarnpkg/lockfile" "^1.1.0" "@yarnpkg/parsers" "3.0.0-rc.46" "@zkochan/js-yaml" "0.0.6" - axios "^1.5.1" + axios "^1.6.0" chalk "^4.1.0" cli-cursor "3.1.0" cli-spinners "2.6.1" @@ -15706,24 +15018,23 @@ nx@18.3.3: figures "3.2.0" flat "^5.0.2" fs-extra "^11.1.0" - glob "7.1.4" ignore "^5.0.4" jest-diff "^29.4.1" js-yaml "4.1.0" jsonc-parser "3.2.0" lines-and-columns "~2.0.3" - minimatch "3.0.5" + minimatch "9.0.3" node-machine-id "1.1.12" npm-run-path "^4.0.1" open "^8.4.0" - semver "7.5.3" + ora "5.3.0" + semver "^7.5.3" string-width "^4.2.3" strong-log-transformer "^2.1.0" tar-stream "~2.2.0" tmp "~0.2.1" tsconfig-paths "^4.1.2" tslib "^2.3.0" - v8-compile-cache "2.3.0" yargs "^17.6.2" yargs-parser "21.1.1" optionalDependencies: @@ -15738,78 +15049,93 @@ nx@18.3.3: "@nx/nx-win32-arm64-msvc" "18.3.3" "@nx/nx-win32-x64-msvc" "18.3.3" -oauth@0.9.x: - version "0.9.15" - resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" - integrity sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA== +nypm@^0.3.8: + version "0.3.8" + resolved "https://registry.yarnpkg.com/nypm/-/nypm-0.3.8.tgz#a16b078b161be5885351e72cf0b97326973722bf" + integrity sha512-IGWlC6So2xv6V4cIDmoV0SwwWx7zLG086gyqkyumteH2fIgCAM4nDVFB2iDRszDvmdSVW9xb1N+2KjQ6C7d4og== + dependencies: + citty "^0.1.6" + consola "^3.2.3" + execa "^8.0.1" + pathe "^1.1.2" + ufo "^1.4.0" + +oauth@0.10.x: + version "0.10.0" + resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.10.0.tgz#3551c4c9b95c53ea437e1e21e46b649482339c58" + integrity sha512-1orQ9MT1vHFGQxhuy7E/0gECD3fd2fCC+PIX+/jgmU/gI3EpRocXtmtvxCO5x3WZ443FLTLFWNDjl5MPJf9u+Q== object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -object-inspect@^1.13.1, object-inspect@^1.9.0: +object-inspect@^1.13.1: version "1.13.1" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== object-is@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" - integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + version "1.1.6" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.6.tgz#1a6a53aed2dd8f7e6775ff870bea58545956ab07" + integrity sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" + call-bind "^1.0.7" + define-properties "^1.2.1" object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== +object.assign@^4.1.4, object.assign@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" + integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" + call-bind "^1.0.5" + define-properties "^1.2.1" has-symbols "^1.0.3" object-keys "^1.1.1" object.fromentries@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" - integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== + version "2.0.8" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.8.tgz#f7195d8a9b97bd95cbc1999ea939ecd1a2b00c65" + integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.2" + es-object-atoms "^1.0.0" object.groupby@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.2.tgz#494800ff5bab78fd0eff2835ec859066e00192ec" - integrity sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw== + version "1.0.3" + resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.3.tgz#9b125c36238129f6f7b61954a1e7176148d5002e" + integrity sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ== dependencies: - array.prototype.filter "^1.0.3" - call-bind "^1.0.5" + call-bind "^1.0.7" define-properties "^1.2.1" - es-abstract "^1.22.3" - es-errors "^1.0.0" + es-abstract "^1.23.2" object.values@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" - integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== + version "1.2.0" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.0.tgz#65405a9d92cee68ac2d303002e0b8470a4d9ab1b" + integrity sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" obuf@^1.0.0, obuf@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== +ohash@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/ohash/-/ohash-1.1.3.tgz#f12c3c50bfe7271ce3fd1097d42568122ccdcf07" + integrity sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw== + on-finished@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" @@ -15848,6 +15174,13 @@ onetime@^5.1.0, onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + open@8.4.2, open@^8.0.4, open@^8.0.9, open@^8.4.0: version "8.4.2" resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" @@ -15883,16 +15216,16 @@ optionator@^0.8.1: word-wrap "~1.2.3" optionator@^0.9.3: - version "0.9.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" - integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + version "0.9.4" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" + integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== dependencies: - "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" + word-wrap "^1.2.5" ora@5.3.0: version "5.3.0" @@ -16141,12 +15474,12 @@ passport-jwt@4.0.0: passport-strategy "^1.0.0" passport-oauth2@1.x.x: - version "1.7.0" - resolved "https://registry.yarnpkg.com/passport-oauth2/-/passport-oauth2-1.7.0.tgz#5c4766c8531ac45ffe9ec2c09de9809e2c841fc4" - integrity sha512-j2gf34szdTF2Onw3+76alNnaAExlUmHvkc7cL+cmaS5NzHzDP/BvFHJruueQ9XAeNOdpI+CH+PWid8RA7KCwAQ== + version "1.8.0" + resolved "https://registry.yarnpkg.com/passport-oauth2/-/passport-oauth2-1.8.0.tgz#55725771d160f09bbb191828d5e3d559eee079c8" + integrity sha512-cjsQbOrXIDE4P8nNb3FQRCCmJJ/utnFKEz2NX209f7KOHPoX18gF7gBzBbLLsj2/je4KrgiwLLGjf0lm9rtTBA== dependencies: base64url "3.x.x" - oauth "0.9.x" + oauth "0.10.x" passport-strategy "1.x.x" uid2 "0.0.x" utils-merge "1.x.x" @@ -16195,17 +15528,22 @@ path-key@^3.0.0, path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-scurry@^1.10.1: - version "1.10.1" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" - integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== +path-scurry@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.2.tgz#8f6357eb1239d5fa1da8b9f70e9c080675458ba7" + integrity sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA== dependencies: - lru-cache "^9.1.1 || ^10.0.0" + lru-cache "^10.2.0" minipass "^5.0.0 || ^6.0.2 || ^7.0.0" path-to-regexp@0.1.7: @@ -16228,10 +15566,10 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -pathe@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.1.tgz#1dd31d382b974ba69809adc9a7a347e65d84829a" - integrity sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q== +pathe@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.2.tgz#6c4cb47a945692e48a1ddd6e4094d170516437ec" + integrity sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ== pause@0.0.1: version "0.0.1" @@ -16294,7 +15632,7 @@ pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== -pirates@^4.0.4, pirates@^4.0.5, pirates@^4.0.6: +pirates@^4.0.4, pirates@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== @@ -16340,9 +15678,9 @@ pluralize@8.0.0: integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== polished@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/polished/-/polished-4.2.2.tgz#2529bb7c3198945373c52e34618c8fe7b1aa84d1" - integrity sha512-Sz2Lkdxz6F2Pgnpi9U5Ng/WdWAUZxmHrNPoVlm3aAemxoy2Qy7LGjQg4uf8qKelDAUW94F4np3iH2YPf2qefcQ== + version "4.3.1" + resolved "https://registry.yarnpkg.com/polished/-/polished-4.3.1.tgz#5a00ae32715609f83d89f6f31d0f0261c6170548" + integrity sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA== dependencies: "@babel/runtime" "^7.17.8" @@ -16355,7 +15693,12 @@ portfinder@^1.0.28: debug "^3.2.7" mkdirp "^0.5.6" -postcss-calc@^9.0.0: +possible-typed-array-names@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" + integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== + +postcss-calc@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-9.0.1.tgz#a744fd592438a93d6de0f1434c572670361eb6c6" integrity sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ== @@ -16363,43 +15706,43 @@ postcss-calc@^9.0.0: postcss-selector-parser "^6.0.11" postcss-value-parser "^4.2.0" -postcss-colormin@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-6.0.0.tgz#d4250652e952e1c0aca70c66942da93d3cdeaafe" - integrity sha512-EuO+bAUmutWoZYgHn2T1dG1pPqHU6L4TjzPlu4t1wZGXQ/fxV16xg2EJmYi0z+6r+MGV1yvpx1BHkUaRrPa2bw== +postcss-colormin@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-6.1.0.tgz#076e8d3fb291fbff7b10e6b063be9da42ff6488d" + integrity sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw== dependencies: - browserslist "^4.21.4" + browserslist "^4.23.0" caniuse-api "^3.0.0" - colord "^2.9.1" + colord "^2.9.3" postcss-value-parser "^4.2.0" -postcss-convert-values@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-6.0.0.tgz#ec94a954957e5c3f78f0e8f65dfcda95280b8996" - integrity sha512-U5D8QhVwqT++ecmy8rnTb+RL9n/B806UVaS3m60lqle4YDFcpbS3ae5bTQIh3wOGUSDHSEtMYLs/38dNG7EYFw== +postcss-convert-values@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz#3498387f8efedb817cbc63901d45bd1ceaa40f48" + integrity sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w== dependencies: - browserslist "^4.21.4" + browserslist "^4.23.0" postcss-value-parser "^4.2.0" -postcss-discard-comments@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-6.0.0.tgz#9ca335e8b68919f301b24ba47dde226a42e535fe" - integrity sha512-p2skSGqzPMZkEQvJsgnkBhCn8gI7NzRH2683EEjrIkoMiwRELx68yoUJ3q3DGSGuQ8Ug9Gsn+OuDr46yfO+eFw== +postcss-discard-comments@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz#e768dcfdc33e0216380623652b0a4f69f4678b6c" + integrity sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw== -postcss-discard-duplicates@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.0.tgz#c26177a6c33070922e67e9a92c0fd23d443d1355" - integrity sha512-bU1SXIizMLtDW4oSsi5C/xHKbhLlhek/0/yCnoMQany9k3nPBq+Ctsv/9oMmyqbR96HYHxZcHyK2HR5P/mqoGA== +postcss-discard-duplicates@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz#d121e893c38dc58a67277f75bb58ba43fce4c3eb" + integrity sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw== -postcss-discard-empty@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-6.0.0.tgz#06c1c4fce09e22d2a99e667c8550eb8a3a1b9aee" - integrity sha512-b+h1S1VT6dNhpcg+LpyiUrdnEZfICF0my7HAKgJixJLW7BnNmpRH34+uw/etf5AhOlIhIAuXApSzzDzMI9K/gQ== +postcss-discard-empty@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz#ee39c327219bb70473a066f772621f81435a79d9" + integrity sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ== -postcss-discard-overridden@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-6.0.0.tgz#49c5262db14e975e349692d9024442de7cd8e234" - integrity sha512-4VELwssYXDFigPYAZ8vL4yX4mUepF/oCBeeIT4OXsJPYOtvJumyz9WflmJWTfDwCUcpDR+z0zvCWBXgTx35SVw== +postcss-discard-overridden@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz#4e9f9c62ecd2df46e8fdb44dc17e189776572e2d" + integrity sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ== postcss-import@~14.1.0: version "14.1.0" @@ -16433,90 +15776,74 @@ postcss-media-query-parser@^0.2.3: resolved "https://registry.yarnpkg.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244" integrity sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig== -postcss-merge-longhand@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-6.0.0.tgz#6f627b27db939bce316eaa97e22400267e798d69" - integrity sha512-4VSfd1lvGkLTLYcxFuISDtWUfFS4zXe0FpF149AyziftPFQIWxjvFSKhA4MIxMe4XM3yTDgQMbSNgzIVxChbIg== +postcss-merge-longhand@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz#ba8a8d473617c34a36abbea8dda2b215750a065a" + integrity sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w== dependencies: postcss-value-parser "^4.2.0" - stylehacks "^6.0.0" + stylehacks "^6.1.1" -postcss-merge-rules@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-6.0.1.tgz#39f165746404e646c0f5c510222ccde4824a86aa" - integrity sha512-a4tlmJIQo9SCjcfiCcCMg/ZCEe0XTkl/xK0XHBs955GWg9xDX3NwP9pwZ78QUOWB8/0XCjZeJn98Dae0zg6AAw== +postcss-merge-rules@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz#7aa539dceddab56019469c0edd7d22b64c3dea9d" + integrity sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ== dependencies: - browserslist "^4.21.4" + browserslist "^4.23.0" caniuse-api "^3.0.0" - cssnano-utils "^4.0.0" - postcss-selector-parser "^6.0.5" + cssnano-utils "^4.0.2" + postcss-selector-parser "^6.0.16" -postcss-minify-font-values@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-6.0.0.tgz#68d4a028f9fa5f61701974724b2cc9445d8e6070" - integrity sha512-zNRAVtyh5E8ndZEYXA4WS8ZYsAp798HiIQ1V2UF/C/munLp2r1UGHwf1+6JFu7hdEhJFN+W1WJQKBrtjhFgEnA== +postcss-minify-font-values@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz#a0e574c02ee3f299be2846369211f3b957ea4c59" + integrity sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg== dependencies: postcss-value-parser "^4.2.0" -postcss-minify-gradients@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-6.0.0.tgz#22b5c88cc63091dadbad34e31ff958404d51d679" - integrity sha512-wO0F6YfVAR+K1xVxF53ueZJza3L+R3E6cp0VwuXJQejnNUH0DjcAFe3JEBeTY1dLwGa0NlDWueCA1VlEfiKgAA== +postcss-minify-gradients@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz#ca3eb55a7bdb48a1e187a55c6377be918743dbd6" + integrity sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q== dependencies: - colord "^2.9.1" - cssnano-utils "^4.0.0" + colord "^2.9.3" + cssnano-utils "^4.0.2" postcss-value-parser "^4.2.0" -postcss-minify-params@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-6.0.0.tgz#2b3a85a9e3b990d7a16866f430f5fd1d5961b539" - integrity sha512-Fz/wMQDveiS0n5JPcvsMeyNXOIMrwF88n7196puSuQSWSa+/Ofc1gDOSY2xi8+A4PqB5dlYCKk/WfqKqsI+ReQ== +postcss-minify-params@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz#54551dec77b9a45a29c3cb5953bf7325a399ba08" + integrity sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA== dependencies: - browserslist "^4.21.4" - cssnano-utils "^4.0.0" + browserslist "^4.23.0" + cssnano-utils "^4.0.2" postcss-value-parser "^4.2.0" -postcss-minify-selectors@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-6.0.0.tgz#5046c5e8680a586e5a0cad52cc9aa36d6be5bda2" - integrity sha512-ec/q9JNCOC2CRDNnypipGfOhbYPuUkewGwLnbv6omue/PSASbHSU7s6uSQ0tcFRVv731oMIx8k0SP4ZX6be/0g== +postcss-minify-selectors@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz#197f7d72e6dd19eed47916d575d69dc38b396aff" + integrity sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ== dependencies: - postcss-selector-parser "^6.0.5" - -postcss-modules-extract-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" - integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + postcss-selector-parser "^6.0.16" -postcss-modules-local-by-default@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz#b08eb4f083050708998ba2c6061b50c2870ca524" - integrity sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA== - dependencies: - icss-utils "^5.0.0" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.1.0" +postcss-modules-extract-imports@^3.0.0, postcss-modules-extract-imports@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz#b4497cb85a9c0c4b5aabeb759bb25e8d89f15002" + integrity sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q== -postcss-modules-local-by-default@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz#7cbed92abd312b94aaea85b68226d3dec39a14e6" - integrity sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q== +postcss-modules-local-by-default@^4.0.4, postcss-modules-local-by-default@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz#f1b9bd757a8edf4d8556e8d0f4f894260e3df78f" + integrity sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw== dependencies: icss-utils "^5.0.0" postcss-selector-parser "^6.0.2" postcss-value-parser "^4.1.0" -postcss-modules-scope@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" - integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== - dependencies: - postcss-selector-parser "^6.0.4" - -postcss-modules-scope@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.1.1.tgz#32cfab55e84887c079a19bbb215e721d683ef134" - integrity sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA== +postcss-modules-scope@^3.1.1, postcss-modules-scope@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz#a43d28289a169ce2c15c00c4e64c0858e43457d5" + integrity sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ== dependencies: postcss-selector-parser "^6.0.4" @@ -16527,113 +15854,113 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-normalize-charset@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-6.0.0.tgz#36cc12457259064969fb96f84df491652a4b0975" - integrity sha512-cqundwChbu8yO/gSWkuFDmKrCZ2vJzDAocheT2JTd0sFNA4HMGoKMfbk2B+J0OmO0t5GUkiAkSM5yF2rSLUjgQ== +postcss-normalize-charset@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz#1ec25c435057a8001dac942942a95ffe66f721e1" + integrity sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ== -postcss-normalize-display-values@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.0.tgz#8d2961415078644d8c6bbbdaf9a2fdd60f546cd4" - integrity sha512-Qyt5kMrvy7dJRO3OjF7zkotGfuYALETZE+4lk66sziWSPzlBEt7FrUshV6VLECkI4EN8Z863O6Nci4NXQGNzYw== +postcss-normalize-display-values@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz#54f02764fed0b288d5363cbb140d6950dbbdd535" + integrity sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg== dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-positions@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-6.0.0.tgz#25b96df99a69f8925f730eaee0be74416865e301" - integrity sha512-mPCzhSV8+30FZyWhxi6UoVRYd3ZBJgTRly4hOkaSifo0H+pjDYcii/aVT4YE6QpOil15a5uiv6ftnY3rm0igPg== +postcss-normalize-positions@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz#e982d284ec878b9b819796266f640852dbbb723a" + integrity sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q== dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-repeat-style@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.0.tgz#ddf30ad8762feb5b1eb97f39f251acd7b8353299" - integrity sha512-50W5JWEBiOOAez2AKBh4kRFm2uhrT3O1Uwdxz7k24aKtbD83vqmcVG7zoIwo6xI2FZ/HDlbrCopXhLeTpQib1A== +postcss-normalize-repeat-style@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz#f8006942fd0617c73f049dd8b6201c3a3040ecf3" + integrity sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ== dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-string@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-6.0.0.tgz#948282647a51e409d69dde7910f0ac2ff97cb5d8" - integrity sha512-KWkIB7TrPOiqb8ZZz6homet2KWKJwIlysF5ICPZrXAylGe2hzX/HSf4NTX2rRPJMAtlRsj/yfkrWGavFuB+c0w== +postcss-normalize-string@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz#e3cc6ad5c95581acd1fc8774b309dd7c06e5e363" + integrity sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ== dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-timing-functions@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.0.tgz#5f13e650b8c43351989fc5de694525cc2539841c" - integrity sha512-tpIXWciXBp5CiFs8sem90IWlw76FV4oi6QEWfQwyeREVwUy39VSeSqjAT7X0Qw650yAimYW5gkl2Gd871N5SQg== +postcss-normalize-timing-functions@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz#40cb8726cef999de984527cbd9d1db1f3e9062c0" + integrity sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA== dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-unicode@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-6.0.0.tgz#741b3310f874616bdcf07764f5503695d3604730" - integrity sha512-ui5crYkb5ubEUDugDc786L/Me+DXp2dLg3fVJbqyAl0VPkAeALyAijF2zOsnZyaS1HyfPuMH0DwyY18VMFVNkg== +postcss-normalize-unicode@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz#aaf8bbd34c306e230777e80f7f12a4b7d27ce06e" + integrity sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg== dependencies: - browserslist "^4.21.4" + browserslist "^4.23.0" postcss-value-parser "^4.2.0" -postcss-normalize-url@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-6.0.0.tgz#d0a31e962a16401fb7deb7754b397a323fb650b4" - integrity sha512-98mvh2QzIPbb02YDIrYvAg4OUzGH7s1ZgHlD3fIdTHLgPLRpv1ZTKJDnSAKr4Rt21ZQFzwhGMXxpXlfrUBKFHw== +postcss-normalize-url@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz#292792386be51a8de9a454cb7b5c58ae22db0f79" + integrity sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ== dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-whitespace@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.0.tgz#accb961caa42e25ca4179b60855b79b1f7129d4d" - integrity sha512-7cfE1AyLiK0+ZBG6FmLziJzqQCpTQY+8XjMhMAz8WSBSCsCNNUKujgIgjCAmDT3cJ+3zjTXFkoD15ZPsckArVw== +postcss-normalize-whitespace@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz#fbb009e6ebd312f8b2efb225c2fcc7cf32b400cd" + integrity sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q== dependencies: postcss-value-parser "^4.2.0" -postcss-ordered-values@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-6.0.0.tgz#374704cdff25560d44061d17ba3c6308837a3218" - integrity sha512-K36XzUDpvfG/nWkjs6d1hRBydeIxGpKS2+n+ywlKPzx1nMYDYpoGbcjhj5AwVYJK1qV2/SDoDEnHzlPD6s3nMg== +postcss-ordered-values@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz#366bb663919707093451ab70c3f99c05672aaae5" + integrity sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q== dependencies: - cssnano-utils "^4.0.0" + cssnano-utils "^4.0.2" postcss-value-parser "^4.2.0" -postcss-reduce-initial@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-6.0.0.tgz#7d16e83e60e27e2fa42f56ec0b426f1da332eca7" - integrity sha512-s2UOnidpVuXu6JiiI5U+fV2jamAw5YNA9Fdi/GRK0zLDLCfXmSGqQtzpUPtfN66RtCbb9fFHoyZdQaxOB3WxVA== +postcss-reduce-initial@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz#4401297d8e35cb6e92c8e9586963e267105586ba" + integrity sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw== dependencies: - browserslist "^4.21.4" + browserslist "^4.23.0" caniuse-api "^3.0.0" -postcss-reduce-transforms@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.0.tgz#28ff2601a6d9b96a2f039b3501526e1f4d584a46" - integrity sha512-FQ9f6xM1homnuy1wLe9lP1wujzxnwt1EwiigtWwuyf8FsqqXUDUp2Ulxf9A5yjlUOTdCJO6lonYjg1mgqIIi2w== +postcss-reduce-transforms@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz#6fa2c586bdc091a7373caeee4be75a0f3e12965d" + integrity sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA== dependencies: postcss-value-parser "^4.2.0" -postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5: - version "6.0.13" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b" - integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== +postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.16, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: + version "6.0.16" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz#3b88b9f5c5abd989ef4e2fc9ec8eedd34b20fb04" + integrity sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" -postcss-svgo@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-6.0.0.tgz#7b18742d38d4505a0455bbe70d52b49f00eaf69d" - integrity sha512-r9zvj/wGAoAIodn84dR/kFqwhINp5YsJkLoujybWG59grR/IHx+uQ2Zo+IcOwM0jskfYX3R0mo+1Kip1VSNcvw== +postcss-svgo@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-6.0.3.tgz#1d6e180d6df1fa8a3b30b729aaa9161e94f04eaa" + integrity sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g== dependencies: postcss-value-parser "^4.2.0" - svgo "^3.0.2" + svgo "^3.2.0" -postcss-unique-selectors@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-6.0.0.tgz#c94e9b0f7bffb1203894e42294b5a1b3fb34fbe1" - integrity sha512-EPQzpZNxOxP7777t73RQpZE5e9TrnCrkvp7AH7a0l89JmZiPnS82y216JowHXwpBCQitfyxrof9TK3rYbi7/Yw== +postcss-unique-selectors@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz#983ab308896b4bf3f2baaf2336e14e52c11a2088" + integrity sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg== dependencies: - postcss-selector-parser "^6.0.5" + postcss-selector-parser "^6.0.16" postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: version "4.2.0" @@ -16649,25 +15976,7 @@ postcss@8.4.35: picocolors "^1.0.0" source-map-js "^1.0.2" -postcss@^8.2.14, postcss@^8.4.14, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.24: - version "8.4.31" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d" - integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== - dependencies: - nanoid "^3.3.6" - picocolors "^1.0.0" - source-map-js "^1.0.2" - -postcss@^8.4.33: - version "8.4.37" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.37.tgz#4505f992cd0c20e03d25f13b31901640b2db731a" - integrity sha512-7iB/v/r7Woof0glKLH8b1SPHrsX7uhdO+Geb41QpF/+mWZHU3uxxSlN+UXGVit1PawOYDToO+AbZzhBzWRDwbQ== - dependencies: - nanoid "^3.3.7" - picocolors "^1.0.0" - source-map-js "^1.2.0" - -postcss@^8.4.35: +postcss@^8.2.14, postcss@^8.4.14, postcss@^8.4.23, postcss@^8.4.24, postcss@^8.4.33, postcss@^8.4.35: version "8.4.38" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e" integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== @@ -16745,6 +16054,11 @@ proc-log@^3.0.0: resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-3.0.0.tgz#fb05ef83ccd64fd7b20bbe9c8c1070fc08338dd8" integrity sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A== +proc-log@^4.0.0, proc-log@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-4.2.0.tgz#b6f461e4026e75fdfe228b265e9f7a00779d7034" + integrity sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA== + process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -16835,9 +16149,9 @@ punycode@^1.4.1: integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== punycode@^2.1.0, punycode@^2.1.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== puppeteer-core@^2.1.1: version "2.1.1" @@ -16856,9 +16170,9 @@ puppeteer-core@^2.1.1: ws "^6.1.0" pure-rand@^6.0.0: - version "6.0.4" - resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.4.tgz#50b737f6a925468679bff00ad20eade53f37d5c7" - integrity sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA== + version "6.1.0" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2" + integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA== pvtsutils@^1.3.2, pvtsutils@^1.3.5: version "1.3.5" @@ -16880,11 +16194,11 @@ qs@6.11.0: side-channel "^1.0.4" qs@^6.10.0, qs@^6.11.0, qs@^6.11.2, qs@^6.4.0: - version "6.11.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" - integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== + version "6.12.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.12.1.tgz#39422111ca7cbdb70425541cba20c7d7b216599a" + integrity sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ== dependencies: - side-channel "^1.0.4" + side-channel "^1.0.6" qs@~6.10.3: version "6.10.5" @@ -16964,14 +16278,14 @@ react-dom@18.2.0: scheduler "^0.23.0" react-is@^18.0.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" + integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== react-remove-scroll-bar@^2.3.3: - version "2.3.4" - resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz#53e272d7a5cb8242990c7f144c44d8bd8ab5afd9" - integrity sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A== + version "2.3.6" + resolved "https://registry.yarnpkg.com/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.6.tgz#3e585e9d163be84a010180b18721e851ac81a29c" + integrity sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g== dependencies: react-style-singleton "^2.2.1" tslib "^2.0.0" @@ -17019,9 +16333,9 @@ read-package-json-fast@^3.0.0: npm-normalize-package-bin "^3.0.0" read-package-json@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-7.0.0.tgz#d605c9dcf6bc5856da24204aa4e9518ee9714be0" - integrity sha512-uL4Z10OKV4p6vbdvIXB+OzhInYtIozl/VxUBPgNkBuUi2DeRonnuspmaVAMcrkmfjKGNmRndyQAbE7/AmzGwFg== + version "7.0.1" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-7.0.1.tgz#8b5f6aab97a796cfb436516ade24c011d10964a9" + integrity sha512-8PcDiZ8DXUjLf687Ol4BR8Bpm2umR7vhoZOzNRt+uxD9GpBh/K+CAAALVIiYFknmvlmyg7hM7BSNUXPaCCqd0Q== dependencies: glob "^10.2.2" json-parse-even-better-errors "^3.0.0" @@ -17087,14 +16401,14 @@ recast@^0.21.0: tslib "^2.0.1" recast@^0.23.1, recast@^0.23.3: - version "0.23.4" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.23.4.tgz#ca1bac7bfd3011ea5a28dfecb5df678559fb1ddf" - integrity sha512-qtEDqIZGVcSZCHniWwZWbRy79Dc6Wp3kT/UmDA2RJKBPg7+7k51aQBZirHmUGn5uvHf2rg8DkjizrN26k61ATw== + version "0.23.6" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.23.6.tgz#198fba74f66143a30acc81929302d214ce4e3bfa" + integrity sha512-9FHoNjX1yjuesMwuthAmPKabxYQdOgihFYmT5ebXfYGBcnqXZf3WOVz+5foEZ8Y83P4ZY6yQD5GMmtV+pgCCAQ== dependencies: - assert "^2.0.0" ast-types "^0.16.1" esprima "~4.0.0" source-map "~0.6.1" + tiny-invariant "^1.3.3" tslib "^2.0.1" rechoir@^0.6.2: @@ -17137,9 +16451,9 @@ reflect-metadata@0.1.13: integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== reflect-metadata@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.2.1.tgz#8d5513c0f5ef2b4b9c3865287f3c0940c1f67f74" - integrity sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw== + version "0.2.2" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.2.2.tgz#400c845b6cba87a21f2c65c4aeb158f4fa4d9c5b" + integrity sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q== regenerate-unicode-properties@^10.1.0: version "10.1.1" @@ -17154,9 +16468,9 @@ regenerate@^1.4.2: integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== regenerator-runtime@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" - integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== regenerator-transform@^0.15.2: version "0.15.2" @@ -17166,18 +16480,19 @@ regenerator-transform@^0.15.2: "@babel/runtime" "^7.8.4" regex-parser@^2.2.11: - version "2.2.11" - resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" - integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== + version "2.3.0" + resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.3.0.tgz#4bb61461b1a19b8b913f3960364bb57887f920ee" + integrity sha512-TVILVSz2jY5D47F4mA4MppkBrafEaiUWJO/TcZHEIuI13AqoZMkK1WMA4Om1YkYbTx+9Ki1/tSUXbceyr9saRg== -regexp.prototype.flags@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" - integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== +regexp.prototype.flags@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz#138f644a3350f981a858c44f6bb1a61ff59be334" + integrity sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - set-function-name "^2.0.0" + call-bind "^1.0.6" + define-properties "^1.2.1" + es-errors "^1.3.0" + set-function-name "^2.0.1" regexpu-core@^5.3.1: version "5.3.2" @@ -17380,7 +16695,7 @@ rimraf@^2.6.1: dependencies: glob "^7.1.3" -rimraf@^3.0.0, rimraf@^3.0.2: +rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== @@ -17394,31 +16709,34 @@ rimraf@~2.6.2: dependencies: glob "^7.1.3" -robust-predicates@^3.0.0: +robust-predicates@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-3.0.2.tgz#d5b28528c4824d20fc48df1928d41d9efa1ad771" integrity sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg== rollup@^4.2.0: - version "4.10.0" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.10.0.tgz#244c2cb54a8de004a949fe6036a0801be9060456" - integrity sha512-t2v9G2AKxcQ8yrG+WGxctBes1AomT0M4ND7jTFBCVPXQ/WFTvNSefIrNSmLKhIKBrvN8SG+CZslimJcT3W2u2g== + version "4.17.2" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.17.2.tgz#26d1785d0144122277fdb20ab3a24729ae68301f" + integrity sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ== dependencies: "@types/estree" "1.0.5" optionalDependencies: - "@rollup/rollup-android-arm-eabi" "4.10.0" - "@rollup/rollup-android-arm64" "4.10.0" - "@rollup/rollup-darwin-arm64" "4.10.0" - "@rollup/rollup-darwin-x64" "4.10.0" - "@rollup/rollup-linux-arm-gnueabihf" "4.10.0" - "@rollup/rollup-linux-arm64-gnu" "4.10.0" - "@rollup/rollup-linux-arm64-musl" "4.10.0" - "@rollup/rollup-linux-riscv64-gnu" "4.10.0" - "@rollup/rollup-linux-x64-gnu" "4.10.0" - "@rollup/rollup-linux-x64-musl" "4.10.0" - "@rollup/rollup-win32-arm64-msvc" "4.10.0" - "@rollup/rollup-win32-ia32-msvc" "4.10.0" - "@rollup/rollup-win32-x64-msvc" "4.10.0" + "@rollup/rollup-android-arm-eabi" "4.17.2" + "@rollup/rollup-android-arm64" "4.17.2" + "@rollup/rollup-darwin-arm64" "4.17.2" + "@rollup/rollup-darwin-x64" "4.17.2" + "@rollup/rollup-linux-arm-gnueabihf" "4.17.2" + "@rollup/rollup-linux-arm-musleabihf" "4.17.2" + "@rollup/rollup-linux-arm64-gnu" "4.17.2" + "@rollup/rollup-linux-arm64-musl" "4.17.2" + "@rollup/rollup-linux-powerpc64le-gnu" "4.17.2" + "@rollup/rollup-linux-riscv64-gnu" "4.17.2" + "@rollup/rollup-linux-s390x-gnu" "4.17.2" + "@rollup/rollup-linux-x64-gnu" "4.17.2" + "@rollup/rollup-linux-x64-musl" "4.17.2" + "@rollup/rollup-win32-arm64-msvc" "4.17.2" + "@rollup/rollup-win32-ia32-msvc" "4.17.2" + "@rollup/rollup-win32-x64-msvc" "4.17.2" fsevents "~2.3.2" run-async@^3.0.0: @@ -17452,13 +16770,13 @@ sade@^1.7.3: dependencies: mri "^1.1.0" -safe-array-concat@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c" - integrity sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q== +safe-array-concat@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.2.tgz#81d77ee0c4e8b863635227c721278dd524c20edb" + integrity sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" + call-bind "^1.0.7" + get-intrinsic "^1.2.4" has-symbols "^1.0.3" isarray "^2.0.5" @@ -17477,13 +16795,13 @@ safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -safe-regex-test@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" - integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== +safe-regex-test@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz#a5b4c0f06e0ab50ea2c395c14d8371232924c377" + integrity sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" + call-bind "^1.0.6" + es-errors "^1.3.0" is-regex "^1.1.4" "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: @@ -17521,9 +16839,9 @@ sass@1.71.1: source-map-js ">=0.6.2 <2.0.0" sass@^1.42.1: - version "1.69.5" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.69.5.tgz#23e18d1c757a35f2e52cc81871060b9ad653dfde" - integrity sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ== + version "1.77.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.77.0.tgz#e736c69aff9fae4a4e6dae60a979eee9c942f321" + integrity sha512-eGj4HNfXqBWtSnvItNkn7B6icqH14i3CiCGbzMKs3BAPTq62pp9NBYsBgyN4cA+qssqo9r26lW4JSvlaUUWbgw== dependencies: chokidar ">=3.0.0 <4.0.0" immutable "^4.0.0" @@ -17547,9 +16865,9 @@ saxes@^6.0.0: xmlchars "^2.2.0" scheduler@^0.23.0: - version "0.23.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" - integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== + version "0.23.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" + integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== dependencies: loose-envify "^1.1.0" @@ -17614,12 +16932,10 @@ semver@7.6.0: dependencies: lru-cache "^6.0.0" -semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" +semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0: + version "7.6.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.1.tgz#60bfe090bf907a25aa8119a72b9f90ef7ca281b2" + integrity sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA== semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0, semver@^6.3.1: version "6.3.1" @@ -17651,9 +16967,9 @@ send@0.18.0: statuses "2.0.1" serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" - integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== + version "6.0.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== dependencies: randombytes "^2.1.0" @@ -17696,16 +17012,6 @@ set-blocking@^2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== -set-function-length@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" - integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== - dependencies: - define-data-property "^1.1.1" - get-intrinsic "^1.2.1" - gopd "^1.0.1" - has-property-descriptors "^1.0.0" - set-function-length@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" @@ -17718,14 +17024,15 @@ set-function-length@^1.2.1: gopd "^1.0.1" has-property-descriptors "^1.0.2" -set-function-name@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" - integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== +set-function-name@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.2.tgz#16a705c5a0dc2f5e638ca96d8a8cd4e1c2b90985" + integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== dependencies: - define-data-property "^1.0.1" + define-data-property "^1.1.4" + es-errors "^1.3.0" functions-have-names "^1.2.3" - has-property-descriptors "^1.0.0" + has-property-descriptors "^1.0.2" setprototypeof@1.1.0: version "1.1.0" @@ -17778,36 +17085,37 @@ shx@0.3.4: minimist "^1.2.3" shelljs "^0.8.5" -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== +side-channel@^1.0.4, side-channel@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" + integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" + call-bind "^1.0.7" + es-errors "^1.3.0" + get-intrinsic "^1.2.4" + object-inspect "^1.13.1" signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -signal-exit@^4.0.1: +signal-exit@^4.0.1, signal-exit@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== sigstore@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/sigstore/-/sigstore-2.2.2.tgz#5e4ff39febeae9e0679bafa22180cb0f445a7e35" - integrity sha512-2A3WvXkQurhuMgORgT60r6pOWiCOO5LlEqY2ADxGBDGVYLSo5HN0uLtb68YpVpuL/Vi8mLTe7+0Dx2Fq8lLqEg== + version "2.3.0" + resolved "https://registry.yarnpkg.com/sigstore/-/sigstore-2.3.0.tgz#c56b32818d4dc989f6ea3c0897f4d9bff5d14bed" + integrity sha512-q+o8L2ebiWD1AxD17eglf1pFrl9jtW7FHa0ygqY6EKvibK8JHyq9Z26v9MZXeDiw+RbfOJ9j2v70M10Hd6E06A== dependencies: - "@sigstore/bundle" "^2.2.0" + "@sigstore/bundle" "^2.3.1" "@sigstore/core" "^1.0.0" - "@sigstore/protobuf-specs" "^0.3.0" - "@sigstore/sign" "^2.2.3" + "@sigstore/protobuf-specs" "^0.3.1" + "@sigstore/sign" "^2.3.0" "@sigstore/tuf" "^2.3.1" - "@sigstore/verify" "^1.1.0" + "@sigstore/verify" "^1.2.0" simple-cbor@^0.4.1: version "0.4.1" @@ -17878,29 +17186,24 @@ sockjs@^0.3.24: uuid "^8.3.2" websocket-driver "^0.7.4" -socks-proxy-agent@^8.0.1: - version "8.0.2" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz#5acbd7be7baf18c46a3f293a840109a430a640ad" - integrity sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g== +socks-proxy-agent@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.3.tgz#6b2da3d77364fde6292e810b496cb70440b9b89d" + integrity sha512-VNegTZKhuGq5vSD6XNKlbqWhyt/40CgoEw8XxD6dhnm8Jq9IEa3nIa4HwnM8XOqU0CdB0BwWVXusqiFXfHB3+A== dependencies: - agent-base "^7.0.2" + agent-base "^7.1.1" debug "^4.3.4" socks "^2.7.1" socks@^2.7.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" - integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== + version "2.8.3" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.3.tgz#1ebd0f09c52ba95a09750afe3f3f9f724a800cb5" + integrity sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw== dependencies: - ip "^2.0.0" + ip-address "^9.0.5" smart-buffer "^4.2.0" -"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" - integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== - -source-map-js@^1.2.0: +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2, source-map-js@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== @@ -17975,9 +17278,9 @@ spdx-correct@^3.0.0: spdx-license-ids "^3.0.0" spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + version "2.5.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz#5d607d27fc806f66d7b64a766650fa890f04ed66" + integrity sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w== spdx-expression-parse@^3.0.0: version "3.0.1" @@ -17988,9 +17291,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.16" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz#a14f64e0954f6e25cc6587bd4f392522db0d998f" - integrity sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw== + version "3.0.17" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.17.tgz#887da8aa73218e51a1d917502d79863161a93f9c" + integrity sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg== spdy-transport@^3.0.0: version "3.0.0" @@ -18015,7 +17318,7 @@ spdy@^4.0.2: select-hose "^2.0.0" spdy-transport "^3.0.0" -sprintf-js@^1.1.2: +sprintf-js@^1.1.2, sprintf-js@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a" integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA== @@ -18041,9 +17344,9 @@ sshpk@^1.14.1: tweetnacl "~0.14.0" ssri@^10.0.0: - version "10.0.5" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.5.tgz#e49efcd6e36385196cb515d3a2ad6c3f0265ef8c" - integrity sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A== + version "10.0.6" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.6.tgz#a8aade2de60ba2bce8688e3fa349bad05c7dc1e5" + integrity sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ== dependencies: minipass "^7.0.3" @@ -18077,9 +17380,9 @@ statuses@2.0.1: integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== store2@^2.14.2: - version "2.14.2" - resolved "https://registry.yarnpkg.com/store2/-/store2-2.14.2.tgz#56138d200f9fe5f582ad63bc2704dbc0e4a45068" - integrity sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w== + version "2.14.3" + resolved "https://registry.yarnpkg.com/store2/-/store2-2.14.3.tgz#24077d7ba110711864e4f691d2af941ec533deb5" + integrity sha512-4QcZ+yx7nzEFiV4BMLnr/pRa5HYzNITX2ri0Zh6sT9EyQHbBHacC6YigllUPU9X3D0f/22QCgfokpKs52YRrUg== storybook@7.0.9: version "7.0.9" @@ -18089,9 +17392,9 @@ storybook@7.0.9: "@storybook/cli" "7.0.9" stream-shift@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" - integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + version "1.0.3" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.3.tgz#85b8fab4d71010fc3ba8772e8046cc49b8a3864b" + integrity sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ== streamsearch@^1.1.0: version "1.1.0" @@ -18141,32 +17444,33 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -string.prototype.trim@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" - integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== +string.prototype.trim@^1.2.9: + version "1.2.9" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz#b6fa326d72d2c78b6df02f7759c73f8f6274faa4" + integrity sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-abstract "^1.23.0" + es-object-atoms "^1.0.0" -string.prototype.trimend@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" - integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== +string.prototype.trimend@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz#3651b8513719e8a9f48de7f2f77640b26652b229" + integrity sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" -string.prototype.trimstart@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" - integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== +string.prototype.trimstart@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz#7ee834dda8c7c17eff3118472bb35bfedaa34dde" + integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg== dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" + call-bind "^1.0.7" + define-properties "^1.2.1" + es-object-atoms "^1.0.0" string_decoder@^1.1.1: version "1.3.0" @@ -18225,6 +17529,11 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + strip-json-comments@^3.0.1, strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" @@ -18248,22 +17557,22 @@ strong-log-transformer@^2.1.0: through "^2.3.4" style-loader@^3.3.0, style-loader@^3.3.1: - version "3.3.3" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.3.tgz#bba8daac19930169c0c9c96706749a597ae3acff" - integrity sha512-53BiGLXAcll9maCYtZi2RCQZKa8NQQai5C4horqKyRmHj9H7QmcUyucrH+4KW/gBQbXM2AsB0axoEcFZPlfPcw== + version "3.3.4" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.4.tgz#f30f786c36db03a45cbd55b6a70d930c479090e7" + integrity sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w== -stylehacks@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-6.0.0.tgz#9fdd7c217660dae0f62e14d51c89f6c01b3cb738" - integrity sha512-+UT589qhHPwz6mTlCLSt/vMNTJx8dopeJlZAlBMJPWA3ORqu6wmQY7FBXf+qD+FsqoBJODyqNxOUP3jdntFRdw== +stylehacks@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-6.1.1.tgz#543f91c10d17d00a440430362d419f79c25545a6" + integrity sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg== dependencies: - browserslist "^4.21.4" - postcss-selector-parser "^6.0.4" + browserslist "^4.23.0" + postcss-selector-parser "^6.0.16" stylis@^4.1.3: - version "4.3.0" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.0.tgz#abe305a669fc3d8777e10eefcfc73ad861c5588c" - integrity sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ== + version "4.3.2" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.2.tgz#8f76b70777dd53eb669c6f58c997bf0a9972e444" + integrity sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg== stylus-loader@^7.1.0: version "7.1.3" @@ -18327,22 +17636,25 @@ svgmap@2.6.0: dependencies: svg-pan-zoom "^3.6.1" -svgo@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-3.0.2.tgz#5e99eeea42c68ee0dc46aa16da093838c262fe0a" - integrity sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ== +svgo@^3.2.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-3.3.1.tgz#27f7b40017eeaff227b6f9caea646b1c242319f5" + integrity sha512-xQQTIGRl3gHTO2PFlZFLl+Xwofj+CMOPitfoByGBNAniQnY6SbGgd31u3C8RTqdlqZqYNl9Sb83VXbimVHcU6w== dependencies: "@trysound/sax" "0.2.0" commander "^7.2.0" css-select "^5.1.0" - css-tree "^2.2.1" + css-tree "^2.3.1" + css-what "^6.1.0" csso "^5.0.5" picocolors "^1.0.0" swc-loader@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/swc-loader/-/swc-loader-0.2.3.tgz#6792f1c2e4c9ae9bf9b933b3e010210e270c186d" - integrity sha512-D1p6XXURfSPleZZA/Lipb3A8pZ17fP4NObZvFCDjK/OKljroqDpPmsBdTraWhVBqUNpcWBQY1imWdoPScRlQ7A== + version "0.2.6" + resolved "https://registry.yarnpkg.com/swc-loader/-/swc-loader-0.2.6.tgz#bf0cba8eeff34bb19620ead81d1277fefaec6bc8" + integrity sha512-9Zi9UP2YmDpgmQVbyOPJClY0dwf58JDyDMQ7uRc4krmc72twNI2fvlBWHLqVekBpPc7h5NJkGVT1zNDxFrqhvg== + dependencies: + "@swc/counter" "^0.1.3" symbol-observable@4.0.0: version "4.0.0" @@ -18391,9 +17703,9 @@ tar-stream@^2.1.4, tar-stream@~2.2.0: readable-stream "^3.1.1" tar@^6.1.11, tar@^6.1.2, tar@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" - integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ== + version "6.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" + integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" @@ -18432,18 +17744,7 @@ tempy@^1.0.1: type-fest "^0.16.0" unique-string "^2.0.0" -terser-webpack-plugin@^5.3.1, terser-webpack-plugin@^5.3.3, terser-webpack-plugin@^5.3.7: - version "5.3.9" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1" - integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== - dependencies: - "@jridgewell/trace-mapping" "^0.3.17" - jest-worker "^27.4.5" - schema-utils "^3.1.1" - serialize-javascript "^6.0.1" - terser "^5.16.8" - -terser-webpack-plugin@^5.3.10: +terser-webpack-plugin@^5.3.1, terser-webpack-plugin@^5.3.10, terser-webpack-plugin@^5.3.3: version "5.3.10" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== @@ -18464,20 +17765,10 @@ terser@5.29.1: commander "^2.20.0" source-map-support "~0.5.20" -terser@^5.10.0, terser@^5.16.8: - version "5.22.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.22.0.tgz#4f18103f84c5c9437aafb7a14918273310a8a49d" - integrity sha512-hHZVLgRA2z4NWcN6aS5rQDc+7Dcy58HOf2zbYwmFcQ+ua3h6eEFf5lIDKTzbWwlazPyOZsFQO8V80/IjVNExEw== - dependencies: - "@jridgewell/source-map" "^0.3.3" - acorn "^8.8.2" - commander "^2.20.0" - source-map-support "~0.5.20" - -terser@^5.26.0: - version "5.29.2" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.29.2.tgz#c17d573ce1da1b30f21a877bffd5655dd86fdb35" - integrity sha512-ZiGkhUBIM+7LwkNjXYJq8svgkd+QK3UUr0wJqY4MieaezBSAIPgbSPZyIx0idM6XWK5CMzSWa8MJIzmRcB8Caw== +terser@^5.10.0, terser@^5.26.0: + version "5.31.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.31.0.tgz#06eef86f17007dbad4593f11a574c7f5eb02c6a1" + integrity sha512-Q1JFAoUKE5IMfI4Z/lkE/E6+SwgzO+x4tq4v1AyBLRj8VSYvRO6A/rQrPg1yud4g0En9EKI1TvFRF2tQFcoUkg== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -18499,9 +17790,9 @@ text-table@^0.2.0: integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== throttleit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" - integrity sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g== + version "1.0.1" + resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.1.tgz#304ec51631c3b770c65c6c6f76938b384000f4d5" + integrity sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ== through2@^2.0.3: version "2.0.5" @@ -18526,10 +17817,10 @@ tiny-emitter@^2.0.0: resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== -tiny-invariant@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" - integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== +tiny-invariant@^1.3.1, tiny-invariant@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127" + integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== tmp@^0.0.33: version "0.0.33" @@ -18539,11 +17830,9 @@ tmp@^0.0.33: os-tmpdir "~1.0.2" tmp@~0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" + version "0.2.3" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" + integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w== tmpl@1.0.5: version "1.0.5" @@ -18563,9 +17852,9 @@ to-regex-range@^5.0.1: is-number "^7.0.0" tocbot@^4.20.1: - version "4.21.2" - resolved "https://registry.yarnpkg.com/tocbot/-/tocbot-4.21.2.tgz#7ae513d73dddb80f126724160bd6f72bf8638edb" - integrity sha512-R5Muhi/TUu4i4snWVrMgNoXyJm2f8sJfdgIkQvqb+cuIXQEIMAiWGWgCgYXHqX4+XiS/Bnm7IYZ9Zy6NVe6lhw== + version "4.27.20" + resolved "https://registry.yarnpkg.com/tocbot/-/tocbot-4.27.20.tgz#c7ba627585894fa306d65b08f53f624949becf19" + integrity sha512-6M78FT20+FA5edtx7KowLvhG3gbZ6GRcEkL/0b2TcPbn6Ba+1ayI3SEVxe25zjkWGs0jd04InImaO81Hd8Hukw== toidentifier@1.0.1: version "1.0.1" @@ -18585,9 +17874,9 @@ tough-cookie-file-store@^2.0.3: tough-cookie "^4.0.0" tough-cookie@^4.0.0, tough-cookie@^4.1.2, tough-cookie@^4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" - integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== + version "4.1.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36" + integrity sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag== dependencies: psl "^1.1.33" punycode "^2.1.1" @@ -18611,10 +17900,10 @@ tree-kill@1.2.2: resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== -ts-api-utils@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" - integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== +ts-api-utils@^1.0.1, ts-api-utils@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" + integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== ts-dedent@^2.0.0, ts-dedent@^2.2.0: version "2.2.0" @@ -18636,9 +17925,9 @@ ts-jest@29.1.0: yargs-parser "^21.0.1" ts-jest@^29.0.0: - version "29.1.1" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.1.tgz#f58fe62c63caf7bfcc5cc6472082f79180f0815b" - integrity sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA== + version "29.1.2" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.2.tgz#7613d8c81c43c8cb312c6904027257e814c40e09" + integrity sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g== dependencies: bs-logger "0.x" fast-json-stable-stringify "2.x" @@ -18650,9 +17939,9 @@ ts-jest@^29.0.0: yargs-parser "^21.0.1" ts-loader@^9.3.1: - version "9.5.0" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.5.0.tgz#f0a51dda37cc4d8e43e6cb14edebbc599b0c3aa2" - integrity sha512-LLlB/pkB4q9mW2yLdFMnK3dEHbrBjeZTYguaaIfusyojBgAGf5kF+O6KcWqiGzWqHk0LBsoolrp4VftEURhybg== + version "9.5.1" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.5.1.tgz#63d5912a86312f1fbe32cef0859fb8b2193d9b89" + integrity sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg== dependencies: chalk "^4.1.0" enhanced-resolve "^5.0.0" @@ -18660,7 +17949,7 @@ ts-loader@^9.3.1: semver "^7.3.4" source-map "^0.7.4" -ts-node@10.9.1, ts-node@^10.8.2: +ts-node@10.9.1: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== @@ -18679,6 +17968,25 @@ ts-node@10.9.1, ts-node@^10.8.2: v8-compile-cache-lib "^3.0.1" yn "3.1.1" +ts-node@^10.8.2: + version "10.9.2" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" + integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + ts-toolbelt@^9.6.0: version "9.6.0" resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz#50a25426cfed500d4a09bd1b3afb6f28879edfd5" @@ -18753,14 +18061,14 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" -tuf-js@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-2.2.0.tgz#4daaa8620ba7545501d04dfa933c98abbcc959b9" - integrity sha512-ZSDngmP1z6zw+FIkIBjvOp/II/mIub/O7Pp12j1WNsiCpg5R5wAc//i555bBQsE44O94btLt0xM/Zr2LQjwdCg== +tuf-js@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-2.2.1.tgz#fdd8794b644af1a75c7aaa2b197ddffeb2911b56" + integrity sha512-GwIJau9XaA8nLVbUXsN3IlFi7WmQ48gBUrl3FTkkL/XLu/POhBzfmX9hd33FNMX1qAsfl6ozO1iMmW9NC8YniA== dependencies: - "@tufjs/models" "2.0.0" + "@tufjs/models" "2.0.1" debug "^4.3.4" - make-fetch-happen "^13.0.0" + make-fetch-happen "^13.0.1" tunnel-agent@^0.6.0: version "0.6.0" @@ -18841,44 +18149,49 @@ type-is@^1.6.4, type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" -typed-array-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" - integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== +typed-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz#1867c5d83b20fcb5ccf32649e5e2fc7424474ff3" + integrity sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - is-typed-array "^1.1.10" + call-bind "^1.0.7" + es-errors "^1.3.0" + is-typed-array "^1.1.13" -typed-array-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" - integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== +typed-array-byte-length@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz#d92972d3cff99a3fa2e765a28fcdc0f1d89dec67" + integrity sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw== dependencies: - call-bind "^1.0.2" + call-bind "^1.0.7" for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" -typed-array-byte-offset@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" - integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== +typed-array-byte-offset@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz#f9ec1acb9259f395093e4567eb3c28a580d02063" + integrity sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA== dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" -typed-array-length@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" - integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== +typed-array-length@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.6.tgz#57155207c76e64a3457482dfdc1c9d1d3c4c73a3" + integrity sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g== dependencies: - call-bind "^1.0.2" + call-bind "^1.0.7" for-each "^0.3.3" - is-typed-array "^1.1.9" + gopd "^1.0.1" + has-proto "^1.0.3" + is-typed-array "^1.1.13" + possible-typed-array-names "^1.0.0" typed-assert@^1.0.8: version "1.0.9" @@ -18891,21 +18204,26 @@ typedarray@^0.0.6: integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== types-ramda@^0.29.4: - version "0.29.5" - resolved "https://registry.yarnpkg.com/types-ramda/-/types-ramda-0.29.5.tgz#1cb0488d39eb72723a8f95af9b6dfe483e4f34a7" - integrity sha512-u+bAYXHDPJR+amB0qMrMU/NXRB2PG8QqpO2v6j7yK/0mPZhlaaZj++ynYjnVpkPEpCkZEGxNpWY3X7qyLCGE3w== + version "0.29.10" + resolved "https://registry.yarnpkg.com/types-ramda/-/types-ramda-0.29.10.tgz#820432905b820301c74f6396f07aa2359b41cde4" + integrity sha512-5PJiW/eiTPyXXBYGZOYGezMl6qj7keBiZheRwfjJZY26QPHsNrjfJnz0mru6oeqqoTHOni893Jfd6zyUXfQRWg== dependencies: ts-toolbelt "^9.6.0" -typescript@5.4.4, typescript@~5.4.2: +typescript@5.4.4: version "5.4.4" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.4.tgz#eb2471e7b0a5f1377523700a21669dce30c2d952" integrity sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw== -typescript@~5.1.3: - version "5.1.6" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" - integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== +typescript@~5.4.2: + version "5.4.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611" + integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== + +ufo@^1.4.0: + version "1.5.3" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.5.3.tgz#3325bd3c977b6c6cd3160bf4ff52989adc9d3344" + integrity sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw== uglify-js@^3.1.4: version "3.17.4" @@ -19040,9 +18358,9 @@ universalify@^0.2.0: integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" @@ -19050,14 +18368,14 @@ unpipe@1.0.0, unpipe@~1.0.0: integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== unplugin@^1.3.1: - version "1.5.0" - resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-1.5.0.tgz#8938ae84defe62afc7757df9ca05d27160f6c20c" - integrity sha512-9ZdRwbh/4gcm1JTOkp9lAkIDrtOyOxgHmY7cjuwI8L/2RTikMcVG25GsZwNAgRuap3iDw2jeq7eoqtAsz5rW3A== + version "1.10.1" + resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-1.10.1.tgz#8ceda065dc71bc67d923dea0920f05c67f2cd68c" + integrity sha512-d6Mhq8RJeGA8UfKCu54Um4lFA0eSaRa3XxdAJg8tIdxbu1ubW0hBCZUL7yI2uGyYCRndvbK8FLHzqy2XKfeMsg== dependencies: - acorn "^8.10.0" - chokidar "^3.5.3" + acorn "^8.11.3" + chokidar "^3.6.0" webpack-sources "^3.2.3" - webpack-virtual-modules "^0.5.0" + webpack-virtual-modules "^0.6.1" untildify@^4.0.0: version "4.0.0" @@ -19065,14 +18383,14 @@ untildify@^4.0.0: integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== update-browserslist-db@^1.0.13: - version "1.0.13" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" - integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== + version "1.0.15" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.15.tgz#60ed9f8cba4a728b7ecf7356f641a31e3a691d97" + integrity sha512-K9HWH62x3/EalU1U6sjSZiylm9C8tgq2mSvshZpqc7QE69RaA2qjhkW2HlNA0tFpEbtyFz7HTqbSdN4MSwUodA== dependencies: - escalade "^3.1.1" + escalade "^3.1.2" picocolors "^1.0.0" -uri-js@^4.2.2: +uri-js@^4.2.2, uri-js@^4.4.1: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== @@ -19101,9 +18419,9 @@ url@^0.11.0: qs "^6.11.2" use-callback-ref@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.0.tgz#772199899b9c9a50526fedc4993fc7fa1f7e32d5" - integrity sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w== + version "1.3.2" + resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.2.tgz#6134c7f6ff76e2be0b56c809b17a650c942b1693" + integrity sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA== dependencies: tslib "^2.0.0" @@ -19178,15 +18496,10 @@ v8-compile-cache-lib@^3.0.1: resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== -v8-compile-cache@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - v8-to-istanbul@^9.0.1: - version "9.1.3" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz#ea456604101cd18005ac2cae3cdd1aa058a6306b" - integrity sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg== + version "9.2.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz#2ed7644a245cddd83d4e087b9b33b3e62dfd10ad" + integrity sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA== dependencies: "@jridgewell/trace-mapping" "^0.3.12" "@types/istanbul-lib-coverage" "^2.0.1" @@ -19201,16 +18514,14 @@ validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: spdx-expression-parse "^3.0.0" validate-npm-package-name@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz#f16afd48318e6f90a1ec101377fa0384cfc8c713" - integrity sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ== - dependencies: - builtins "^5.0.0" + version "5.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz#a316573e9b49f3ccd90dbb6eb52b3f06c6d604e8" + integrity sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ== validator@^13.7.0: - version "13.11.0" - resolved "https://registry.yarnpkg.com/validator/-/validator-13.11.0.tgz#23ab3fd59290c61248364eabf4067f04955fbb1b" - integrity sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ== + version "13.12.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.12.0.tgz#7d78e76ba85504da3fee4fd1922b385914d4b35f" + integrity sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg== vary@^1, vary@~1.1.2: version "1.1.2" @@ -19251,7 +18562,7 @@ walker@^1.0.8: dependencies: makeerror "1.0.12" -watchpack@2.4.0, watchpack@^2.2.0, watchpack@^2.4.0: +watchpack@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== @@ -19259,6 +18570,14 @@ watchpack@2.4.0, watchpack@^2.2.0, watchpack@^2.4.0: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" +watchpack@^2.2.0, watchpack@^2.4.0, watchpack@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.1.tgz#29308f2cac150fa8e4c92f90e0ec954a9fed7fff" + integrity sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + wbuf@^1.1.0, wbuf@^1.7.3: version "1.7.3" resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" @@ -19274,9 +18593,9 @@ wcwidth@^1.0.0, wcwidth@^1.0.1: defaults "^1.0.3" web-worker@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/web-worker/-/web-worker-1.2.0.tgz#5d85a04a7fbc1e7db58f66595d7a3ac7c9c180da" - integrity sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA== + version "1.3.0" + resolved "https://registry.yarnpkg.com/web-worker/-/web-worker-1.3.0.tgz#e5f2df5c7fe356755a5fb8f8410d4312627e6776" + integrity sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA== webidl-conversions@^3.0.0: version "3.0.1" @@ -19318,10 +18637,10 @@ webpack-dev-middleware@6.1.2: range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-middleware@^5.3.1: - version "5.3.3" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" - integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== +webpack-dev-middleware@^5.3.1, webpack-dev-middleware@^5.3.4: + version "5.3.4" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz#eb7b39281cbce10e104eb2b8bf2b63fce49a3517" + integrity sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q== dependencies: colorette "^2.0.10" memfs "^3.4.3" @@ -19330,9 +18649,9 @@ webpack-dev-middleware@^5.3.1: schema-utils "^4.0.0" webpack-dev-middleware@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-6.1.1.tgz#6bbc257ec83ae15522de7a62f995630efde7cc3d" - integrity sha512-y51HrHaFeeWir0YO4f0g+9GwZawuigzcAdRNon6jErXy/SqV/+O6eaVAzDqE6t3e3NpGeR5CS+cCDaTC+V3yEQ== + version "6.1.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-6.1.3.tgz#79f4103f8c898564c9e96c3a9c2422de50f249bc" + integrity sha512-A4ChP0Qj8oGociTs6UdlRUGANIGrCDL3y+pmQMc+dSsraXHCatFpmMey4mYELA+juqwUqwQsUgJJISXl1KWmiw== dependencies: colorette "^2.0.10" memfs "^3.4.12" @@ -19340,7 +18659,7 @@ webpack-dev-middleware@^6.1.1: range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@4.15.1, webpack-dev-server@^4.9.3: +webpack-dev-server@4.15.1: version "4.15.1" resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz#8944b29c12760b3a45bdaa70799b17cb91b03df7" integrity sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA== @@ -19376,10 +18695,46 @@ webpack-dev-server@4.15.1, webpack-dev-server@^4.9.3: webpack-dev-middleware "^5.3.1" ws "^8.13.0" +webpack-dev-server@^4.9.3: + version "4.15.2" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz#9e0c70a42a012560860adb186986da1248333173" + integrity sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" + "@types/serve-index" "^1.9.1" + "@types/serve-static" "^1.13.10" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.5.5" + ansi-html-community "^0.0.8" + bonjour-service "^1.0.11" + chokidar "^3.5.3" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^2.0.0" + default-gateway "^6.0.3" + express "^4.17.3" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.3" + ipaddr.js "^2.0.1" + launch-editor "^2.6.0" + open "^8.0.9" + p-retry "^4.5.0" + rimraf "^3.0.2" + schema-utils "^4.0.0" + selfsigned "^2.1.1" + serve-index "^1.9.1" + sockjs "^0.3.24" + spdy "^4.0.2" + webpack-dev-middleware "^5.3.4" + ws "^8.13.0" + webpack-hot-middleware@^2.25.1: - version "2.25.4" - resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.4.tgz#d8bc9e9cb664fc3105c8e83d2b9ed436bee4e193" - integrity sha512-IRmTspuHM06aZh98OhBJtqLpeWFM8FXJS5UYpKYxCJzyFoyWj1w6VGFfomZU7OPA55dMLrQK0pRT1eQ3PACr4w== + version "2.26.1" + resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.26.1.tgz#87214f1e3f9f3acab9271fef9e6ed7b637d719c0" + integrity sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A== dependencies: ansi-html-community "0.0.8" html-entities "^2.1.0" @@ -19416,34 +18771,39 @@ webpack-virtual-modules@^0.5.0: resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.5.0.tgz#362f14738a56dae107937ab98ea7062e8bdd3b6c" integrity sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw== +webpack-virtual-modules@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.1.tgz#ac6fdb9c5adb8caecd82ec241c9631b7a3681b6f" + integrity sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg== + webpack@5, webpack@^5.80.0: - version "5.89.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.89.0.tgz#56b8bf9a34356e93a6625770006490bf3a7f32dc" - integrity sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw== + version "5.91.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.91.0.tgz#ffa92c1c618d18c878f06892bbdc3373c71a01d9" + integrity sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw== dependencies: "@types/eslint-scope" "^3.7.3" - "@types/estree" "^1.0.0" - "@webassemblyjs/ast" "^1.11.5" - "@webassemblyjs/wasm-edit" "^1.11.5" - "@webassemblyjs/wasm-parser" "^1.11.5" + "@types/estree" "^1.0.5" + "@webassemblyjs/ast" "^1.12.1" + "@webassemblyjs/wasm-edit" "^1.12.1" + "@webassemblyjs/wasm-parser" "^1.12.1" acorn "^8.7.1" acorn-import-assertions "^1.9.0" - browserslist "^4.14.5" + browserslist "^4.21.10" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.15.0" + enhanced-resolve "^5.16.0" es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" + graceful-fs "^4.2.11" json-parse-even-better-errors "^2.3.1" loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" schema-utils "^3.2.0" tapable "^2.1.1" - terser-webpack-plugin "^5.3.7" - watchpack "^2.4.0" + terser-webpack-plugin "^5.3.10" + watchpack "^2.4.1" webpack-sources "^3.2.3" webpack@5.90.3: @@ -19529,16 +18889,16 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" -which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.2: - version "1.1.13" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" - integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== +which-typed-array@^1.1.14, which-typed-array@^1.1.15, which-typed-array@^1.1.2: + version "1.1.15" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.15.tgz#264859e9b11a649b388bfaaf4f767df1f779b38d" + integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA== dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.4" + available-typed-arrays "^1.0.7" + call-bind "^1.0.7" for-each "^0.3.3" gopd "^1.0.1" - has-tostringtag "^1.0.0" + has-tostringtag "^1.0.2" which@^2.0.1: version "2.0.2" @@ -19573,7 +18933,7 @@ wildcard@^2.0.0: resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== -word-wrap@~1.2.3: +word-wrap@^1.2.5, word-wrap@~1.2.3: version "1.2.5" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== @@ -19653,9 +19013,9 @@ ws@^7.3.1: integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== ws@^8.11.0, ws@^8.13.0, ws@^8.2.3: - version "8.14.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" - integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== + version "8.17.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.0.tgz#d145d18eca2ed25aaf791a183903f7be5e295fea" + integrity sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow== xml-name-validator@^4.0.0: version "4.0.0" From be153d34e5fa5e1bc07467ae3359a59395fee780 Mon Sep 17 00:00:00 2001 From: Dan Date: Thu, 9 May 2024 11:48:51 +0200 Subject: [PATCH 198/203] Latest Updates --- migrations.json | 185 ++++++ package.json | 32 +- yarn.lock | 1473 +++++++++++++++++++++-------------------------- 3 files changed, 868 insertions(+), 822 deletions(-) create mode 100644 migrations.json diff --git a/migrations.json b/migrations.json new file mode 100644 index 000000000..2285c2256 --- /dev/null +++ b/migrations.json @@ -0,0 +1,185 @@ +{ + "migrations": [ + { + "cli": "nx", + "version": "17.3.0-beta.6", + "description": "Updates the nx wrapper.", + "implementation": "./src/migrations/update-17-3-0/update-nxw", + "package": "nx", + "name": "17.3.0-update-nx-wrapper" + }, + { + "cli": "nx", + "version": "18.0.0-beta.2", + "description": "Updates nx.json to disabled adding plugins when generating projects in an existing Nx workspace", + "implementation": "./src/migrations/update-18-0-0/disable-crystal-for-existing-workspaces", + "x-repair-skip": true, + "package": "nx", + "name": "18.0.0-disable-adding-plugins-for-existing-workspaces" + }, + { + "version": "18.1.0-beta.3", + "description": "Moves affected.defaultBase to defaultBase in `nx.json`", + "implementation": "./src/migrations/update-17-2-0/move-default-base", + "package": "nx", + "name": "move-default-base-to-nx-json-root" + }, + { + "cli": "nx", + "version": "18.1.0-beta.3", + "description": "Update to Cypress ^13.6.6 if the workspace is using Cypress v13 to ensure workspaces don't use v13.6.5 which has an issue when verifying Cypress.", + "implementation": "./src/migrations/update-18-1-0/update-cypress-version-13-6-6", + "package": "@nx/cypress", + "name": "update-cypress-version-13-6-6" + }, + { + "cli": "nx", + "version": "17.2.6-beta.1", + "description": "Rename workspace rules from @nx/workspace/name to @nx/workspace-name", + "implementation": "./src/migrations/update-17-2-6-rename-workspace-rules/rename-workspace-rules", + "package": "@nx/eslint-plugin", + "name": "update-17-2-6-rename-workspace-rules" + }, + { + "version": "17.1.0-beta.2", + "description": "Move jest executor options to nx.json targetDefaults", + "implementation": "./src/migrations/update-17-1-0/move-options-to-target-defaults", + "package": "@nx/jest", + "name": "move-options-to-target-defaults" + }, + { + "cli": "nx", + "version": "17.1.0-beta.5", + "requires": { + "@angular/core": ">=17.0.0" + }, + "description": "Update the @angular/cli package version to ~17.0.0.", + "factory": "./src/migrations/update-17-1-0/update-angular-cli", + "package": "@nx/angular", + "name": "update-angular-cli-version-17-0-0" + }, + { + "cli": "nx", + "version": "17.1.0-beta.5", + "requires": { + "@angular/core": ">=17.0.0" + }, + "description": "Rename 'browserTarget' to 'buildTarget'.", + "factory": "./src/migrations/update-17-1-0/browser-target-to-build-target", + "package": "@nx/angular", + "name": "rename-browser-target-to-build-target" + }, + { + "cli": "nx", + "version": "17.1.0-beta.5", + "requires": { + "@angular/core": ">=17.0.0" + }, + "description": "Replace usages of '@nguniversal/builders' with '@angular-devkit/build-angular'.", + "factory": "./src/migrations/update-17-1-0/replace-nguniversal-builders", + "package": "@nx/angular", + "name": "replace-nguniversal-builders" + }, + { + "cli": "nx", + "version": "17.1.0-beta.5", + "requires": { + "@angular/core": ">=17.0.0" + }, + "description": "Replace usages of '@nguniversal/' packages with '@angular/ssr'.", + "factory": "./src/migrations/update-17-1-0/replace-nguniversal-engines", + "package": "@nx/angular", + "name": "replace-nguniversal-engines" + }, + { + "cli": "nx", + "version": "17.1.0-beta.5", + "requires": { + "@angular/core": ">=17.0.0" + }, + "description": "Replace the deep imports from 'zone.js/dist/zone' and 'zone.js/dist/zone-testing' with 'zone.js' and 'zone.js/testing'.", + "factory": "./src/migrations/update-17-1-0/update-zone-js-deep-import", + "package": "@nx/angular", + "name": "update-zone-js-deep-import" + }, + { + "cli": "nx", + "version": "17.2.0-beta.2", + "description": "Rename '@nx/angular:webpack-dev-server' executor to '@nx/angular:dev-server'", + "factory": "./src/migrations/update-17-2-0/rename-webpack-dev-server", + "package": "@nx/angular", + "name": "rename-webpack-dev-server-executor" + }, + { + "cli": "nx", + "version": "17.3.0-beta.10", + "requires": { + "@angular/core": ">=17.1.0" + }, + "description": "Update the @angular/cli package version to ~17.1.0.", + "factory": "./src/migrations/update-17-3-0/update-angular-cli", + "package": "@nx/angular", + "name": "update-angular-cli-version-17-1-0" + }, + { + "cli": "nx", + "version": "17.3.0-beta.10", + "requires": { + "@angular/core": ">=17.1.0" + }, + "description": "Add 'browser-sync' as dev dependency when '@angular-devkit/build-angular:ssr-dev-server' or '@nx/angular:module-federation-dev-ssr' is used.", + "factory": "./src/migrations/update-17-3-0/add-browser-sync-dependency", + "package": "@nx/angular", + "name": "add-browser-sync-dependency" + }, + { + "cli": "nx", + "version": "17.3.0-beta.10", + "requires": { + "@angular/core": ">=17.1.0" + }, + "description": "Add 'autoprefixer' as dev dependency when '@nx/angular:ng-packagr-lite' or '@nx/angular:package` is used.", + "factory": "./src/migrations/update-17-3-0/add-autoprefixer-dependency", + "package": "@nx/angular", + "name": "add-autoprefixer-dependency" + }, + { + "cli": "nx", + "version": "18.0.0-beta.0", + "description": "Add NX_MF_DEV_SERVER_STATIC_REMOTES to inputs for task hashing when '@nx/angular:webpack-browser' is used for Module Federation.", + "factory": "./src/migrations/update-18-0-0/add-mf-env-var-to-target-defaults", + "package": "@nx/angular", + "name": "add-module-federation-env-var-to-target-defaults" + }, + { + "cli": "nx", + "version": "18.1.0-beta.1", + "requires": { + "@angular/core": ">=17.2.0" + }, + "description": "Update the @angular/cli package version to ~17.2.0.", + "factory": "./src/migrations/update-18-1-0/update-angular-cli", + "package": "@nx/angular", + "name": "update-angular-cli-version-17-2-0" + }, + { + "cli": "nx", + "version": "18.1.1-beta.0", + "description": "Ensure targetDefaults inputs for task hashing when '@nx/angular:webpack-browser' is used are correct for Module Federation.", + "factory": "./src/migrations/update-18-1-1/fix-target-defaults-inputs", + "package": "@nx/angular", + "name": "fix-target-defaults-for-webpack-browser" + }, + { + "cli": "nx", + "version": "18.2.0-beta.0", + "requires": { + "@angular/core": ">=17.3.0" + }, + "description": "Update the @angular/cli package version to ~17.3.0.", + "factory": "./src/migrations/update-18-2-0/update-angular-cli", + "package": "@nx/angular", + "name": "update-angular-cli-version-17-3-0" + } + ] +} diff --git a/package.json b/package.json index 1dddba400..22bc16b61 100644 --- a/package.json +++ b/package.json @@ -153,21 +153,21 @@ "@angular/pwa": "17.3.5", "@nestjs/schematics": "10.0.1", "@nestjs/testing": "10.1.3", - "@nx/angular": "18.3.3", - "@nx/cypress": "18.3.3", - "@nx/eslint-plugin": "18.3.3", - "@nx/jest": "18.3.3", - "@nx/js": "18.3.3", - "@nx/nest": "18.3.3", - "@nx/node": "18.3.3", - "@nx/storybook": "18.3.3", - "@nx/web": "18.3.3", - "@nx/workspace": "18.3.3", + "@nx/angular": "19.0.1", + "@nx/cypress": "19.0.1", + "@nx/eslint-plugin": "19.0.1", + "@nx/jest": "19.0.1", + "@nx/js": "19.0.1", + "@nx/nest": "19.0.1", + "@nx/node": "19.0.1", + "@nx/storybook": "19.0.1", + "@nx/web": "19.0.1", + "@nx/workspace": "19.0.1", "@schematics/angular": "17.3.3", "@simplewebauthn/types": "9.0.1", - "@storybook/addon-essentials": "7.6.5", - "@storybook/angular": "7.6.5", - "@storybook/core-server": "7.6.5", + "@storybook/addon-essentials": "7.5.3", + "@storybook/angular": "7.5.3", + "@storybook/core-server": "7.5.3", "@trivago/prettier-plugin-sort-imports": "4.3.0", "@types/big.js": "6.2.2", "@types/body-parser": "1.19.2", @@ -176,7 +176,7 @@ "@types/google-spreadsheet": "3.1.5", "@types/jest": "29.4.4", "@types/lodash": "4.17.0", - "@types/node": "20.4.2", + "@types/node": "^18.16.9", "@types/papaparse": "5.3.7", "@types/passport-google-oauth20": "2.0.11", "@typescript-eslint/eslint-plugin": "6.21.0", @@ -190,8 +190,8 @@ "eslint-plugin-storybook": "0.6.15", "jest": "29.4.3", "jest-environment-jsdom": "29.4.3", - "jest-preset-angular": "14.0.3", - "nx": "18.3.3", + "jest-preset-angular": "14.0.4", + "nx": "19.0.1", "prettier": "3.2.5", "prettier-plugin-organize-attributes": "1.0.0", "react": "18.2.0", diff --git a/yarn.lock b/yarn.lock index 7de918d28..ed8a46ee0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3,11 +3,11 @@ "@adobe/css-tools@^4.0.1": - version "4.3.2" - resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.2.tgz#a6abc715fb6884851fca9dad37fc34739a04fd11" - integrity sha512-DA5a1C0gD/pLOvhv33YMrbf2FK3oUzwNl9oOJqE4XVjuEtt6XIakRcsd7eLiOSPkp1kTRQGICTA8cKra/vFbjw== + version "4.3.3" + resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.3.tgz#90749bde8b89cd41764224f5aac29cd4138f75ff" + integrity sha512-rE0Pygv0sEZ4vBWHlAgJLGDU7Pm8xoO6p3wsEceb7GYAjScrOHpEo8KK/eVkAcnSM+slAEtXjA2JpdjLp4fJQQ== -"@ampproject/remapping@2.3.0": +"@ampproject/remapping@2.3.0", "@ampproject/remapping@^2.2.0": version "2.3.0" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== @@ -15,14 +15,6 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" -"@ampproject/remapping@^2.2.0": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" - integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== - dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" - "@angular-devkit/architect@0.1703.5": version "0.1703.5" resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1703.5.tgz#2e6e534c99fd99d53034237d64de6317f24af52a" @@ -32,11 +24,11 @@ rxjs "7.8.1" "@angular-devkit/architect@^0.1301.0 || ^0.1401.0 || ^0.1501.0 || ^0.1601.0 || ^0.1700.0": - version "0.1700.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1700.0.tgz#419d59be6f8bc0068f8d495d7e28f4f47cfdb2ce" - integrity sha512-whi7HvOjv1J3He9f+H8xNJWKyjAmWuWNl8gxNW6EZP/XLcrOu+/5QT4bPtXQBRIL/avZuc++5sNQS+kReaNCig== + version "0.1700.10" + resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1700.10.tgz#cf3bb2dfca17bb7d78639b7e55e13bb16627fa62" + integrity sha512-JD/3jkdN1jrFMIDEk9grKdbjutIoxUDMRazq1LZooWjTkzlYk09i/s6HwvIPao7zvxJfelD6asTPspgkjOMP5A== dependencies: - "@angular-devkit/core" "17.0.0" + "@angular-devkit/core" "17.0.10" rxjs "7.8.1" "@angular-devkit/build-angular@17.3.5": @@ -140,10 +132,10 @@ rxjs "7.8.1" source-map "0.7.4" -"@angular-devkit/core@17.0.0", "@angular-devkit/core@^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0": - version "17.0.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-17.0.0.tgz#99cd048cca37cf4d0cb60a3b6871e19449a8006a" - integrity sha512-QUu3LnEi4A8t733v2+I0sLtyBJx3Q7zdTAhaauCbxbFhDid0cbYm8hYsyG/njor1irTPxSJbn6UoetVkwUQZxg== +"@angular-devkit/core@17.0.10": + version "17.0.10" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-17.0.10.tgz#dce8b3cd4b90d694ed5ccf405c8f25e45938b310" + integrity sha512-93N6oHnmtRt0hL3AXxvnk47sN1rHndfj+pqI5haEY41AGWzIWv9cSBsqlM0PWltNpo6VivcExZESvbLJ71wqbQ== dependencies: ajv "8.12.0" ajv-formats "2.1.1" @@ -176,7 +168,7 @@ rxjs "7.8.1" source-map "0.7.4" -"@angular-devkit/core@17.3.7": +"@angular-devkit/core@17.3.7", "@angular-devkit/core@^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0": version "17.3.7" resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-17.3.7.tgz#553b456cf9747eecdb1f7389127057bc5cb9f8e4" integrity sha512-qpZ7BShyqS/Jqld36E7kL02cyb2pjn1Az1p9439SbP8nsvJgYlsyjwYK2Kmcn/Wi+TZGIKxkqxgBBw9vqGgeJw== @@ -232,7 +224,7 @@ ora "5.4.1" rxjs "7.8.1" -"@angular-devkit/schematics@17.3.7": +"@angular-devkit/schematics@17.3.7", "@angular-devkit/schematics@^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0": version "17.3.7" resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-17.3.7.tgz#0b964b9216d51e7706656fdc0643fd9716461902" integrity sha512-d7NKSwstdxYLYmPsbcYO3GOFNfXxXwOyHxSqDa1JNKoSzMdbLj4tvlCpfXw0ThNM7gioMx8aLBaaH1ac+yk06Q== @@ -243,17 +235,6 @@ ora "5.4.1" rxjs "7.8.1" -"@angular-devkit/schematics@^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0": - version "17.0.0" - resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-17.0.0.tgz#bfcc09a1bd145ef978f92d660df89a11e69468d4" - integrity sha512-LD7fjDORuBf139/oJ/gSwbIzQPfsm6Y67s1FD+XLi0QXaRt6dw4r7BMD08l1r//oPQofNgbEH4coGVO4NdCL/A== - dependencies: - "@angular-devkit/core" "17.0.0" - jsonc-parser "3.2.0" - magic-string "0.30.5" - ora "5.4.1" - rxjs "7.8.1" - "@angular-eslint/bundled-angular-compiler@17.3.0": version "17.3.0" resolved "https://registry.yarnpkg.com/@angular-eslint/bundled-angular-compiler/-/bundled-angular-compiler-17.3.0.tgz#08b8b1bebbb677a1f208b56516fc9177a289d212" @@ -507,23 +488,7 @@ dependencies: default-browser-id "3.0.0" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.21.4", "@babel/code-frame@^7.22.13": - version "7.22.13" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" - integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== - dependencies: - "@babel/highlight" "^7.22.13" - chalk "^2.4.2" - -"@babel/code-frame@^7.23.5": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" - integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== - dependencies: - "@babel/highlight" "^7.23.4" - chalk "^2.4.2" - -"@babel/code-frame@^7.24.2": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.21.4", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.24.2": version "7.24.2" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.2.tgz#718b4b19841809a58b29b68cde80bc5e1aa6d9ae" integrity sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ== @@ -531,17 +496,7 @@ "@babel/highlight" "^7.24.2" picocolors "^1.0.0" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.21.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.2.tgz#6a12ced93455827037bfb5ed8492820d60fc32cc" - integrity sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ== - -"@babel/compat-data@^7.23.5": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" - integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== - -"@babel/compat-data@^7.24.4": +"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.21.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.23.5", "@babel/compat-data@^7.24.4": version "7.24.4" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.24.4.tgz#6f102372e9094f25d908ca0d34fc74c74606059a" integrity sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ== @@ -588,49 +543,7 @@ json5 "^2.2.3" semver "^6.3.1" -"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.13.16", "@babel/core@^7.20.2": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.2.tgz#ed10df0d580fff67c5f3ee70fd22e2e4c90a9f94" - integrity sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.22.13" - "@babel/generator" "^7.23.0" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-module-transforms" "^7.23.0" - "@babel/helpers" "^7.23.2" - "@babel/parser" "^7.23.0" - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.2" - "@babel/types" "^7.23.0" - convert-source-map "^2.0.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.3" - semver "^6.3.1" - -"@babel/core@^7.23.0", "@babel/core@^7.23.2": - version "7.23.6" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.6.tgz#8be77cd77c55baadcc1eae1c33df90ab6d2151d4" - integrity sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.23.5" - "@babel/generator" "^7.23.6" - "@babel/helper-compilation-targets" "^7.23.6" - "@babel/helper-module-transforms" "^7.23.3" - "@babel/helpers" "^7.23.6" - "@babel/parser" "^7.23.6" - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.6" - "@babel/types" "^7.23.6" - convert-source-map "^2.0.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.3" - semver "^6.3.1" - -"@babel/core@^7.23.9": +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.13.16", "@babel/core@^7.20.2", "@babel/core@^7.22.0", "@babel/core@^7.22.9", "@babel/core@^7.23.2", "@babel/core@^7.23.9": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.24.5.tgz#15ab5b98e101972d171aeef92ac70d8d6718f06a" integrity sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA== @@ -681,7 +594,7 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@7.23.6", "@babel/generator@^7.23.6": +"@babel/generator@7.23.6": version "7.23.6" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.6.tgz#9e1fca4811c77a10580d17d26b57b036133f3c2e" integrity sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw== @@ -691,17 +604,7 @@ "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" -"@babel/generator@^7.21.5", "@babel/generator@^7.23.0", "@babel/generator@^7.7.2": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" - integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== - dependencies: - "@babel/types" "^7.23.0" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - -"@babel/generator@^7.24.5": +"@babel/generator@^7.21.5", "@babel/generator@^7.22.9", "@babel/generator@^7.23.0", "@babel/generator@^7.23.6", "@babel/generator@^7.24.5", "@babel/generator@^7.7.2": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.24.5.tgz#e5afc068f932f05616b66713e28d0f04e99daeb3" integrity sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA== @@ -735,18 +638,7 @@ dependencies: "@babel/types" "^7.22.15" -"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.21.5", "@babel/helper-compilation-targets@^7.22.15", "@babel/helper-compilation-targets@^7.22.6": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" - integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== - dependencies: - "@babel/compat-data" "^7.22.9" - "@babel/helper-validator-option" "^7.22.15" - browserslist "^4.21.9" - lru-cache "^5.1.1" - semver "^6.3.1" - -"@babel/helper-compilation-targets@^7.23.6": +"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.21.5", "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.23.6": version "7.23.6" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ== @@ -757,22 +649,7 @@ lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz#97a61b385e57fe458496fad19f8e63b63c867de4" - integrity sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" - "@babel/helper-member-expression-to-functions" "^7.22.15" - "@babel/helper-optimise-call-expression" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - semver "^6.3.1" - -"@babel/helper-create-class-features-plugin@^7.24.1", "@babel/helper-create-class-features-plugin@^7.24.4", "@babel/helper-create-class-features-plugin@^7.24.5": +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.24.1", "@babel/helper-create-class-features-plugin@^7.24.4", "@babel/helper-create-class-features-plugin@^7.24.5": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.5.tgz#7d19da92c7e0cd8d11c09af2ce1b8e7512a6e723" integrity sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g== @@ -830,12 +707,12 @@ lodash.debounce "^4.0.8" resolve "^1.14.2" -"@babel/helper-environment-visitor@^7.18.9", "@babel/helper-environment-visitor@^7.21.5", "@babel/helper-environment-visitor@^7.22.20", "@babel/helper-environment-visitor@^7.22.5": +"@babel/helper-environment-visitor@^7.18.9", "@babel/helper-environment-visitor@^7.21.5", "@babel/helper-environment-visitor@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== -"@babel/helper-function-name@^7.21.0", "@babel/helper-function-name@^7.22.5", "@babel/helper-function-name@^7.23.0": +"@babel/helper-function-name@^7.21.0", "@babel/helper-function-name@^7.23.0": version "7.23.0" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== @@ -850,7 +727,7 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-member-expression-to-functions@^7.22.15", "@babel/helper-member-expression-to-functions@^7.23.0", "@babel/helper-member-expression-to-functions@^7.24.5": +"@babel/helper-member-expression-to-functions@^7.23.0", "@babel/helper-member-expression-to-functions@^7.24.5": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.5.tgz#5981e131d5c7003c7d1fa1ad49e86c9b097ec475" integrity sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA== @@ -864,7 +741,7 @@ dependencies: "@babel/types" "^7.24.0" -"@babel/helper-module-transforms@^7.21.5", "@babel/helper-module-transforms@^7.23.0", "@babel/helper-module-transforms@^7.23.3", "@babel/helper-module-transforms@^7.24.5": +"@babel/helper-module-transforms@^7.21.5", "@babel/helper-module-transforms@^7.23.3", "@babel/helper-module-transforms@^7.24.5": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.24.5.tgz#ea6c5e33f7b262a0ae762fd5986355c45f54a545" integrity sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A== @@ -896,7 +773,7 @@ "@babel/helper-environment-visitor" "^7.22.20" "@babel/helper-wrap-function" "^7.22.20" -"@babel/helper-replace-supers@^7.22.9", "@babel/helper-replace-supers@^7.24.1": +"@babel/helper-replace-supers@^7.24.1": version "7.24.1" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.24.1.tgz#7085bd19d4a0b7ed8f405c1ed73ccb70f323abc1" integrity sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ== @@ -943,7 +820,7 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz#918b1a7fa23056603506370089bd990d8720db62" integrity sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA== -"@babel/helper-validator-option@^7.21.0", "@babel/helper-validator-option@^7.22.15", "@babel/helper-validator-option@^7.23.5": +"@babel/helper-validator-option@^7.21.0", "@babel/helper-validator-option@^7.23.5": version "7.23.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== @@ -957,7 +834,7 @@ "@babel/template" "^7.24.0" "@babel/types" "^7.24.5" -"@babel/helpers@^7.21.5", "@babel/helpers@^7.23.2", "@babel/helpers@^7.23.6", "@babel/helpers@^7.23.9", "@babel/helpers@^7.24.0", "@babel/helpers@^7.24.5": +"@babel/helpers@^7.21.5", "@babel/helpers@^7.23.9", "@babel/helpers@^7.24.0", "@babel/helpers@^7.24.5": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.24.5.tgz#fedeb87eeafa62b621160402181ad8585a22a40a" integrity sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q== @@ -966,7 +843,7 @@ "@babel/traverse" "^7.24.5" "@babel/types" "^7.24.5" -"@babel/highlight@^7.22.13", "@babel/highlight@^7.23.4", "@babel/highlight@^7.24.2": +"@babel/highlight@^7.24.2": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.5.tgz#bc0613f98e1dd0720e99b2a9ee3760194a704b6e" integrity sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw== @@ -976,7 +853,7 @@ js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.13.16", "@babel/parser@^7.14.7", "@babel/parser@^7.20.5", "@babel/parser@^7.20.7", "@babel/parser@^7.21.5", "@babel/parser@^7.21.8", "@babel/parser@^7.23.0", "@babel/parser@^7.23.6", "@babel/parser@^7.23.9", "@babel/parser@^7.24.0", "@babel/parser@^7.24.5": +"@babel/parser@^7.1.0", "@babel/parser@^7.13.16", "@babel/parser@^7.14.7", "@babel/parser@^7.20.5", "@babel/parser@^7.20.7", "@babel/parser@^7.21.5", "@babel/parser@^7.21.8", "@babel/parser@^7.22.7", "@babel/parser@^7.23.0", "@babel/parser@^7.23.9", "@babel/parser@^7.24.0", "@babel/parser@^7.24.5": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.24.5.tgz#4a4d5ab4315579e5398a82dcf636ca80c3392790" integrity sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg== @@ -1530,7 +1407,7 @@ "@babel/helper-module-transforms" "^7.23.3" "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-modules-commonjs@^7.13.8", "@babel/plugin-transform-modules-commonjs@^7.21.5", "@babel/plugin-transform-modules-commonjs@^7.23.0", "@babel/plugin-transform-modules-commonjs@^7.23.3", "@babel/plugin-transform-modules-commonjs@^7.24.1": +"@babel/plugin-transform-modules-commonjs@^7.13.8", "@babel/plugin-transform-modules-commonjs@^7.21.5", "@babel/plugin-transform-modules-commonjs@^7.23.3", "@babel/plugin-transform-modules-commonjs@^7.24.1": version "7.24.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.1.tgz#e71ba1d0d69e049a22bf90b3867e263823d3f1b9" integrity sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw== @@ -1572,7 +1449,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.24.0" -"@babel/plugin-transform-nullish-coalescing-operator@^7.22.11", "@babel/plugin-transform-nullish-coalescing-operator@^7.23.4", "@babel/plugin-transform-nullish-coalescing-operator@^7.24.1": +"@babel/plugin-transform-nullish-coalescing-operator@^7.23.4", "@babel/plugin-transform-nullish-coalescing-operator@^7.24.1": version "7.24.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.1.tgz#0cd494bb97cb07d428bd651632cb9d4140513988" integrity sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw== @@ -1614,7 +1491,7 @@ "@babel/helper-plugin-utils" "^7.24.0" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-transform-optional-chaining@^7.23.0", "@babel/plugin-transform-optional-chaining@^7.23.4", "@babel/plugin-transform-optional-chaining@^7.24.1", "@babel/plugin-transform-optional-chaining@^7.24.5": +"@babel/plugin-transform-optional-chaining@^7.23.4", "@babel/plugin-transform-optional-chaining@^7.24.1", "@babel/plugin-transform-optional-chaining@^7.24.5": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.5.tgz#a6334bebd7f9dd3df37447880d0bd64b778e600f" integrity sha512-xWCkmwKT+ihmA6l7SSTpk8e4qQl/274iNbSKRRS8mpqFR32ksy36+a+LWY8OXCCEefF8WFlnOHVsaDI2231wBg== @@ -1630,7 +1507,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.24.5" -"@babel/plugin-transform-private-methods@^7.22.5", "@babel/plugin-transform-private-methods@^7.23.3", "@babel/plugin-transform-private-methods@^7.24.1": +"@babel/plugin-transform-private-methods@^7.23.3", "@babel/plugin-transform-private-methods@^7.24.1": version "7.24.1" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.24.1.tgz#a0faa1ae87eff077e1e47a5ec81c3aef383dc15a" integrity sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw== @@ -1857,7 +1734,7 @@ core-js-compat "^3.31.0" semver "^6.3.1" -"@babel/preset-env@^7.20.2", "@babel/preset-env@^7.23.2": +"@babel/preset-env@^7.20.2", "@babel/preset-env@^7.22.9", "@babel/preset-env@^7.23.2": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.24.5.tgz#6a9ac90bd5a5a9dae502af60dfc58c190551bbcd" integrity sha512-UGK2ifKtcC8i5AI4cH+sbLLuLc2ktYSFJgBAXorKAsHUZmrQ1q6aQ6i3BvU24wWs2AAKqQB6kq3N9V9Gw1HiMQ== @@ -2026,7 +1903,7 @@ core-js-compat "^3.25.1" semver "^6.3.0" -"@babel/preset-flow@^7.13.13", "@babel/preset-flow@^7.22.15": +"@babel/preset-flow@^7.13.13": version "7.24.1" resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.24.1.tgz#da7196c20c2d7dd4e98cfd8b192fe53b5eb6f0bb" integrity sha512-sWCV2G9pcqZf+JHyv/RyqEIpFypxdCSxWIxQjpdaQxenNog7cN1pr76hg8u0Fz8Qgg0H4ETkGcJnXL8d4j0PPA== @@ -2055,7 +1932,7 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/preset-typescript@^7.13.0", "@babel/preset-typescript@^7.22.5", "@babel/preset-typescript@^7.23.0": +"@babel/preset-typescript@^7.13.0", "@babel/preset-typescript@^7.22.5": version "7.24.1" resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.24.1.tgz#89bdf13a3149a17b3b2a2c9c62547f06db8845ec" integrity sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ== @@ -2066,7 +1943,7 @@ "@babel/plugin-transform-modules-commonjs" "^7.24.1" "@babel/plugin-transform-typescript" "^7.24.1" -"@babel/register@^7.13.16", "@babel/register@^7.22.15": +"@babel/register@^7.13.16": version "7.23.7" resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.23.7.tgz#485a5e7951939d21304cae4af1719fdb887bc038" integrity sha512-EjJeB6+kvpk+Y5DAkEAmbOBEFkh9OASx0huoEkqYTFxAZHzOAX2Oh5uwAUuL2rUddqfM0SA+KPXV2TbzoZ2kvQ== @@ -2121,7 +1998,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/traverse@^7.16.0", "@babel/traverse@^7.21.5", "@babel/traverse@^7.23.2", "@babel/traverse@^7.23.6", "@babel/traverse@^7.23.9", "@babel/traverse@^7.24.0", "@babel/traverse@^7.24.5": +"@babel/traverse@^7.16.0", "@babel/traverse@^7.21.5", "@babel/traverse@^7.22.8", "@babel/traverse@^7.23.9", "@babel/traverse@^7.24.0", "@babel/traverse@^7.24.5": version "7.24.5" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.24.5.tgz#972aa0bc45f16983bf64aa1f877b2dd0eea7e6f8" integrity sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA== @@ -3196,7 +3073,7 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" -"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2", "@jridgewell/gen-mapping@^0.3.5": +"@jridgewell/gen-mapping@^0.3.2", "@jridgewell/gen-mapping@^0.3.5": version "0.3.5" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== @@ -3236,7 +3113,7 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": version "0.3.25" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== @@ -4257,98 +4134,98 @@ node-gyp "^10.0.0" which "^4.0.0" -"@nrwl/angular@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nrwl/angular/-/angular-18.3.3.tgz#63d7b65e4d96637d7361d018ec56d061595cb0d4" - integrity sha512-pQsxy58DZBVna3qeJH+osdiRBpx+FCAnCz5kogO6EmRsM17zP4zGpgijVHorAI4EjCNhl2vWa3X/bZ8yQIFBpg== +"@nrwl/angular@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nrwl/angular/-/angular-19.0.1.tgz#6ceae5032162d55822dba9af6b199e2e0484bf8e" + integrity sha512-60fah5nhxW7l7yU/c7zOjm2WGbXAAsu6jwmYprTw3wKgT30euY8fqgzxGLdDhN87YSj5pYFSImLiGO2xwLNFsw== dependencies: - "@nx/angular" "18.3.3" + "@nx/angular" "19.0.1" tslib "^2.3.0" -"@nrwl/cypress@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nrwl/cypress/-/cypress-18.3.3.tgz#3b85e45169c3aff23ea46e19835956a355111b22" - integrity sha512-CsoPFX+iLwvc/+Im/zZsk3FP8c8epBMmI8GNvZFnDZe8J9bdBmtlxp8/Yh3LdUw8ycmPGPvW7eggv31yNZmT+Q== +"@nrwl/cypress@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nrwl/cypress/-/cypress-19.0.1.tgz#be304d208af1687db93fe1e3e80d54e08fda627f" + integrity sha512-joHM8qilPgyKgf8vL6MdZnkJ2zbjZjdz0TkFt+YqAitOXxOCviIsEvitLED2AV/zKLtgWWT9e4EinNefNHwv+w== dependencies: - "@nx/cypress" "18.3.3" + "@nx/cypress" "19.0.1" -"@nrwl/devkit@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-18.3.3.tgz#9ec5575afe6d14b17acd5e8da4e98a0de27704c6" - integrity sha512-3zZLE1vfwsNie7qjVUt9lqaM1slU0RTr/dW+Yt/2lxe8Peu6f8bnCM1Pf3kSlzoxQroctfocRtVHFXJsAuAt4g== +"@nrwl/devkit@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-19.0.1.tgz#552f84cff3263a340e267e77eaf0f1c5cc70c969" + integrity sha512-6mYYEAHI/OOEoVjMB50cho6YxtwdZmxhPywkEGSxvkSwqRcsMpKuIqgJ7bhFlWEW2+mH7Vpc+aaJ+olRwFgBXQ== dependencies: - "@nx/devkit" "18.3.3" + "@nx/devkit" "19.0.1" -"@nrwl/eslint-plugin-nx@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nrwl/eslint-plugin-nx/-/eslint-plugin-nx-18.3.3.tgz#b41316daa9ac7f55379cb4510767f7a865c920a6" - integrity sha512-ARqwcA2n2NN+8ATrooZtPbaW5fb9WSjDFZaI8RdphMXFnPrEkZnMpbrjFpLTj+wc1R6hIgTcYbli6fv4Gfbo3Q== +"@nrwl/eslint-plugin-nx@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nrwl/eslint-plugin-nx/-/eslint-plugin-nx-19.0.1.tgz#2b6f22e515d9f4e270a0adddba1a60a2374eef6b" + integrity sha512-jPAf9JpODNjTg2f18MYIXXoJ0+J7XIEuol2qfatu4X0fO9WHRIuln61H8hdWFul93BBXZd+w5NBew8XKu4yyGQ== dependencies: - "@nx/eslint-plugin" "18.3.3" + "@nx/eslint-plugin" "19.0.1" -"@nrwl/jest@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nrwl/jest/-/jest-18.3.3.tgz#6d75e59c47be007cbe4b78c23fd3e08fe954ed68" - integrity sha512-BPI0mIbmjTHFb0/qtMND59ECld7gorV+SEVLwf4BLl7SWumVB2gLAA2+yx71cvF1jO4R5Ndi2FrBwBC9E2Va5Q== +"@nrwl/jest@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nrwl/jest/-/jest-19.0.1.tgz#8198ba455cd8b17f5aec99a249142c9804f8f49c" + integrity sha512-TBiE9JJbndre1KO98j14RKUd6jzsB2zr/l3LP2w6+5SUmpdGEOGVYlJ91+gi/Xz3r0P75AJALMnmo/hfAYpyHg== dependencies: - "@nx/jest" "18.3.3" + "@nx/jest" "19.0.1" -"@nrwl/js@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nrwl/js/-/js-18.3.3.tgz#e1a83fb43541cd06752aced6dd7ad932d0c1afa1" - integrity sha512-7Wtv5kpeMWUDBUFu5go49HM/S8vDrtMOvZf9xnUcnjsFDReWe8XIEkTWudZDbzID3X4T6WQAftzj2Ov6k566lQ== +"@nrwl/js@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nrwl/js/-/js-19.0.1.tgz#7308e5dde96b34894a8a3b164699440b020074a2" + integrity sha512-B1ePjLUL46tqPGDZ1kLjxNAEqjKxdyaoCVJqWFnk8cEdsJyGbrG3uy9BSA1FFNuWq/lc4tDkvzkRPw0UnPV1rA== dependencies: - "@nx/js" "18.3.3" + "@nx/js" "19.0.1" -"@nrwl/nest@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nrwl/nest/-/nest-18.3.3.tgz#28709e32ef4cef6db06a9e219de46ae9b9f40378" - integrity sha512-LIyCiS73O58n7NRWT/SnuA8xHWDu4ANLd9fvguyAzXk1TcPekFvTo6zpY+iu0lkxJ7RfvZHVDGC90bIFSyV9YA== +"@nrwl/nest@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nrwl/nest/-/nest-19.0.1.tgz#97b2f3fe7832a917c85ddc32eec3e6f581c11984" + integrity sha512-GK8zDGUwdcOWnDBoPyvx4NM7NGQnRXXpyEP+pYKFL7cmED6Qpu5+dNLYpGCwg8TWUxVXBK1IAX8N22XG/xirGA== dependencies: - "@nx/nest" "18.3.3" + "@nx/nest" "19.0.1" -"@nrwl/node@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nrwl/node/-/node-18.3.3.tgz#eb0850a8e7877332550d7e06e7c959d0842b25e2" - integrity sha512-87PXppPqI/jOl6swYVdQi8RBveOF7Oqmqw9m9eEbts6U2bazPipKTwBO4E9afkz3GMqaxe+d2H794JqH05Mr8w== +"@nrwl/node@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nrwl/node/-/node-19.0.1.tgz#2e6ad7fae0f11780c56f562249e8074e3c895a7a" + integrity sha512-YPae7nllepiDUefcIzCF9bpE5BwyAPTmkrJAzkrwQPeLP+xbZFux2mvCKmfVrlUKE8Vnnl3MZ+ghcKFXaf6KAg== dependencies: - "@nx/node" "18.3.3" + "@nx/node" "19.0.1" -"@nrwl/storybook@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nrwl/storybook/-/storybook-18.3.3.tgz#80c60ef3975150127a9b09e2d7b79900cd962af0" - integrity sha512-i8mZoJz9CTT7hmXJxgqlz8u4nm48S4XTZLH5nARXcArjoiojUQTQnRr8iDZlJsZxa3+kHTMCJVyQ5WQUC6+Uog== +"@nrwl/storybook@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nrwl/storybook/-/storybook-19.0.1.tgz#13d8f33164dae49ab6c752bd95a27804460a2af9" + integrity sha512-qG+A1ekCHOUMeeG5Bx3U10K9iLu3mGlfPxEPx80vuwDzl5tfR1cHn4Ldf4nAl5AdHnb2WqCDLaOMncV3Cl6nMw== dependencies: - "@nx/storybook" "18.3.3" + "@nx/storybook" "19.0.1" -"@nrwl/tao@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-18.3.3.tgz#2d0c60d233f2cc07c85ba08126dd46f21dda1ef0" - integrity sha512-f/PUDLpSMEObiLQ5sIDySJM+5DxSCNunkxxbY1R9rmQ1cFcgrHaXIHQqbSj91mMa3mmtbKACk8u1LbI+oQV0Tg== +"@nrwl/tao@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-19.0.1.tgz#b1d08797905ecb387b0ee36c75343985a11d65ea" + integrity sha512-DrpZPLidBJy/oA8IVfLhXTzkxq9fT4Ua+gtmOl+VLsKJymnbcgOejX8u13eoy3hSaymKT9X+mcnmFr0LkqMS2A== dependencies: - nx "18.3.3" + nx "19.0.1" tslib "^2.3.0" -"@nrwl/web@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nrwl/web/-/web-18.3.3.tgz#3e31d086fef5aa1e68ac5af9d5c27592ef2fe39d" - integrity sha512-EuEht/tk9VHLKxjVMEh96wu8WNkRFRabpmLBc++pp2bEaoxz8Qm2xDO+sOU3Wp4zGNx/qQVxA1kKMZCjVjk75g== +"@nrwl/web@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nrwl/web/-/web-19.0.1.tgz#91c54ca9d0e60e23232f064547e64e914d443dc7" + integrity sha512-AmwlzsgbTU1kGh2ASquGpswe21j0XyyBLm55fSXjNjUCz1TlTEBY4jlV/mxrrxqs5UJ5kY2vV0QwDam+hLfRxQ== dependencies: - "@nx/web" "18.3.3" + "@nx/web" "19.0.1" -"@nrwl/webpack@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nrwl/webpack/-/webpack-18.3.3.tgz#0c29dc1561c9b8e613313fd02f805be72515dfa6" - integrity sha512-E/8vr1qAFSan1FnewvLBRBHYIaPG9dxZeYKRcQvcDx+Jf2oPyJNYI+9kkoNxEZg9FeFJMShK2x8YBgwB+ivH5A== +"@nrwl/webpack@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nrwl/webpack/-/webpack-19.0.1.tgz#9d738e16c80c4c3127c0d2ecc71667c2b26a231a" + integrity sha512-qNRtOCz3jID2H5JZmDzmhCVNu6InBNZAwb8lzFWTt0+foJ71kft6jTJxauErAsEKIfIc4okren8X975me7W1WA== dependencies: - "@nx/webpack" "18.3.3" + "@nx/webpack" "19.0.1" -"@nrwl/workspace@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nrwl/workspace/-/workspace-18.3.3.tgz#291ecda3c4fddcb534f0cc6b7c7796a21483ae49" - integrity sha512-9Giuec9l3PpS8mekD00W9kBIKmWRpQSkp+/RvYmc+7kKtVC+Uj/kc68exBOanVgq6zKzYrn+FqHWHGWnHxp+ww== +"@nrwl/workspace@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nrwl/workspace/-/workspace-19.0.1.tgz#c476f869aec112fbb5e37f2350ee14a1321461e1" + integrity sha512-lOfBYLdKmR3ouG7f/ZUmFGUqCcriJCcJqg3X4Z5SqHuhmwasUz23w70H0mq6O2DZuT2IqRwHPJKICuQNHT/Xfw== dependencies: - "@nx/workspace" "18.3.3" + "@nx/workspace" "19.0.1" "@nuxtjs/opencollective@0.3.2": version "0.3.2" @@ -4359,18 +4236,18 @@ consola "^2.15.0" node-fetch "^2.6.1" -"@nx/angular@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/angular/-/angular-18.3.3.tgz#3648480ddec56e2ca54caed7482eb941b60df3e4" - integrity sha512-KAWpIxd+cNAjSNaArHzJGavES6hBJApE6KVgg3lJwSThkjgTy6loEC4mw8VAQaSlHVx/OEQcbebC1LPkJadG9w== - dependencies: - "@nrwl/angular" "18.3.3" - "@nx/devkit" "18.3.3" - "@nx/eslint" "18.3.3" - "@nx/js" "18.3.3" - "@nx/web" "18.3.3" - "@nx/webpack" "18.3.3" - "@nx/workspace" "18.3.3" +"@nx/angular@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/angular/-/angular-19.0.1.tgz#be2004d5bdfddf7a41d4ba28d74762bb98546163" + integrity sha512-ohO5YqFr5uQ0xEYaYw+hiEQZf/uDQn9oosXtDN7uVrZGndpfNk7k2u0apy3MvJ6JvKLEPutqLiJOC0oqp6zSRA== + dependencies: + "@nrwl/angular" "19.0.1" + "@nx/devkit" "19.0.1" + "@nx/eslint" "19.0.1" + "@nx/js" "19.0.1" + "@nx/web" "19.0.1" + "@nx/webpack" "19.0.1" + "@nx/workspace" "19.0.1" "@phenomnomnominal/tsquery" "~5.0.1" "@typescript-eslint/type-utils" "^7.3.0" chalk "^4.1.0" @@ -4384,42 +4261,42 @@ webpack "^5.80.0" webpack-merge "^5.8.0" -"@nx/cypress@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/cypress/-/cypress-18.3.3.tgz#d0af052f421312018b0d0ddc3476cd4a31ca748f" - integrity sha512-ou7Q6XXM9zIiWFVojZwnnFFJxx4iKACWvusfCOIwJ3zcel1vtamWHffRp2Z9WjdBDxy26Ax/DM+lZj4t6hQRmA== +"@nx/cypress@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/cypress/-/cypress-19.0.1.tgz#b1a32fa0703cba082b33255f66bd24884906061e" + integrity sha512-Lgjv8C/NJEVUo5nUrvJmur9f4qRgS7S0Pe829UR4fldA50ildZCs9mxc1aTG5vBzzwQzPnkUEDvPa/gD7f0JJQ== dependencies: - "@nrwl/cypress" "18.3.3" - "@nx/devkit" "18.3.3" - "@nx/eslint" "18.3.3" - "@nx/js" "18.3.3" + "@nrwl/cypress" "19.0.1" + "@nx/devkit" "19.0.1" + "@nx/eslint" "19.0.1" + "@nx/js" "19.0.1" "@phenomnomnominal/tsquery" "~5.0.1" detect-port "^1.5.1" - semver "^7.5.3" tslib "^2.3.0" -"@nx/devkit@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/devkit/-/devkit-18.3.3.tgz#2ec37855020da74ad1e77b51711b057b3cb12fec" - integrity sha512-FtkZ6mA5//vEA5lcbT80m080ROVacHYV5F1peztTRA+IY2JZGJoqx425kn5ylDO8aCSAIAwcn2qIdhI8BnpG3Q== +"@nx/devkit@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/devkit/-/devkit-19.0.1.tgz#bd106b0b40f963d0efc92fa10c2d262bff85b60f" + integrity sha512-whEUgASqCiD94/ZGrSxkl7mLcIeYuQ5YbT79De+sIXWtBNFI2CqNHJX3/nOwrO/tO2Z88Wg6PM9PL6EiysYwjQ== dependencies: - "@nrwl/devkit" "18.3.3" + "@nrwl/devkit" "19.0.1" ejs "^3.1.7" enquirer "~2.3.6" ignore "^5.0.4" + minimatch "9.0.3" semver "^7.5.3" tmp "~0.2.1" tslib "^2.3.0" yargs-parser "21.1.1" -"@nx/eslint-plugin@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/eslint-plugin/-/eslint-plugin-18.3.3.tgz#0410261cf7f1a227eefbe2a979c9482ad9c19894" - integrity sha512-ww3r8VRlzJXOBRG+qCTd+VXHRKxiIrOH+cIokTtuzGrnCXWEMSPO5Ts6z/Jsbb0xAcfZ39WUnxuDZdKbp4aHqA== +"@nx/eslint-plugin@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/eslint-plugin/-/eslint-plugin-19.0.1.tgz#22175649c25d66b68a5815d2fd691260e9787292" + integrity sha512-dbNdTkIoajpKADup3kj5LbWPWNLoZ0oltayZMb2MGorVpMrubrAXUHiDx+nmBGQ6DKCbn1eFFjI6qTIhVsH18w== dependencies: - "@nrwl/eslint-plugin-nx" "18.3.3" - "@nx/devkit" "18.3.3" - "@nx/js" "18.3.3" + "@nrwl/eslint-plugin-nx" "19.0.1" + "@nx/devkit" "19.0.1" + "@nx/js" "19.0.1" "@typescript-eslint/type-utils" "^7.3.0" "@typescript-eslint/utils" "^7.3.0" chalk "^4.1.0" @@ -4428,28 +4305,28 @@ semver "^7.5.3" tslib "^2.3.0" -"@nx/eslint@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/eslint/-/eslint-18.3.3.tgz#ce28b4240e0558333dee08c824d8f82d72a11159" - integrity sha512-cvJjyykTEtQN08b5wQFelD/cbye7Nl5zFVESs+mn9/ezCukjAgP9seOk39nchKykRBAm7zzA1xZOB9thNqw9aA== +"@nx/eslint@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/eslint/-/eslint-19.0.1.tgz#e42959aa11c6508c83bdcf7c63d9ffb45b0d017b" + integrity sha512-KRxWqrDy5ilUOFcYrVa3fgi0f2kPC3oUDXo8NQ9+O8AHTGQjHWcMs8btvGXhpJq9mBkR0RC7zpfNsbitGzYgpA== dependencies: - "@nx/devkit" "18.3.3" - "@nx/js" "18.3.3" - "@nx/linter" "18.3.3" + "@nx/devkit" "19.0.1" + "@nx/js" "19.0.1" + "@nx/linter" "19.0.1" eslint "^8.0.0" tslib "^2.3.0" typescript "~5.4.2" -"@nx/jest@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/jest/-/jest-18.3.3.tgz#4a25f77169d0e630cb9b5f49bd0cde1faf0aae31" - integrity sha512-AwkwYSJqu0vrDFMxKAc3lb0yHZFhsD8rX6rMMwe/fZMlAYml9FvGCp/ixWpcRWIo/1t3pxiF3Vejk9+oq/Avfw== +"@nx/jest@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/jest/-/jest-19.0.1.tgz#ffcfd7cf9779edb884975fac92918f63ce80b665" + integrity sha512-M9R3PKC2kkhXZt7/w+h6o/2eafg/n1Gqpp3uUt2/88tyK8ciqHtfWqtpqZP9VUuMznnluKQzdanHTAlzOI01lQ== dependencies: "@jest/reporters" "^29.4.1" "@jest/test-result" "^29.4.1" - "@nrwl/jest" "18.3.3" - "@nx/devkit" "18.3.3" - "@nx/js" "18.3.3" + "@nrwl/jest" "19.0.1" + "@nx/devkit" "19.0.1" + "@nx/js" "19.0.1" "@phenomnomnominal/tsquery" "~5.0.1" chalk "^4.1.0" identity-obj-proxy "3.0.0" @@ -4461,10 +4338,10 @@ tslib "^2.3.0" yargs-parser "21.1.1" -"@nx/js@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/js/-/js-18.3.3.tgz#977968160d6edc11f320bc0f654b52d36a9101ac" - integrity sha512-e8u56oG0mlTVz48EeH0C7txX0GeLYN0o4mK1LDAMIHQa4tKefNfwrdqHaZBiVqFOPopeFtqi8s0kqce5prwCaw== +"@nx/js@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/js/-/js-19.0.1.tgz#d6cd4f1b0bcea675e8d62f5581151680a89abb82" + integrity sha512-pBDJj91l+RiCTnzA4bFcu++GY4XmbvvWrlh3jJtEL1lQhfAQWsDkGKdJMaViLsG3W38PvEwsoERxl0NDNgPC/A== dependencies: "@babel/core" "^7.23.2" "@babel/plugin-proposal-decorators" "^7.22.7" @@ -4473,10 +4350,9 @@ "@babel/preset-env" "^7.23.2" "@babel/preset-typescript" "^7.22.5" "@babel/runtime" "^7.22.6" - "@nrwl/js" "18.3.3" - "@nx/devkit" "18.3.3" - "@nx/workspace" "18.3.3" - "@phenomnomnominal/tsquery" "~5.0.1" + "@nrwl/js" "19.0.1" + "@nx/devkit" "19.0.1" + "@nx/workspace" "19.0.1" babel-plugin-const-enum "^1.0.1" babel-plugin-macros "^2.8.0" babel-plugin-transform-typescript-metadata "^0.3.1" @@ -4497,125 +4373,125 @@ tsconfig-paths "^4.1.2" tslib "^2.3.0" -"@nx/linter@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/linter/-/linter-18.3.3.tgz#ae861fb7d10c4f1dcdb4389f5b9f25aecab6fee0" - integrity sha512-5HmAN/8jZ2scrA0OiJSUdBPhIjwIHecK8AK7TxYX4fg1VJ3VcpknV8pWcETuNoBW8WlgF1RX2RW7Gog7vjf+Ww== +"@nx/linter@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/linter/-/linter-19.0.1.tgz#336f4a19662cf14720908e486b8ce1a3fc3e2aa3" + integrity sha512-4zfRhEAuJ8yd0JAQg+v69y79MxHOWkPG0/bjCDmkSRyg57JOQTCI/0VV5o3UFrb/nZ1Fi7gzFSkaACqenK6kwg== dependencies: - "@nx/eslint" "18.3.3" + "@nx/eslint" "19.0.1" -"@nx/nest@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/nest/-/nest-18.3.3.tgz#16fe7ba6d1f8634ffae58b8e6dda4132ef112c5e" - integrity sha512-e2uPVBsewdLkgf9ncAxN/UEln3ygc1lyy8LTfR5X0Gzx3CUPiayDfd9OxZaxnDFi7Jpu89dpckMO8NhAIBvheA== +"@nx/nest@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/nest/-/nest-19.0.1.tgz#b1bb12d2f8dbbcb1cbe102be01c8d5ca690d4bee" + integrity sha512-1xqg8jOi9rW3mfG1doJBlzfOjW1m5lgxCqdX6rZKi9vn23Nom5PGhsg9GHwrmrERc6qP1th4FZPooSmwroYrAQ== dependencies: "@nestjs/schematics" "^9.1.0" - "@nrwl/nest" "18.3.3" - "@nx/devkit" "18.3.3" - "@nx/eslint" "18.3.3" - "@nx/js" "18.3.3" - "@nx/node" "18.3.3" + "@nrwl/nest" "19.0.1" + "@nx/devkit" "19.0.1" + "@nx/eslint" "19.0.1" + "@nx/js" "19.0.1" + "@nx/node" "19.0.1" "@phenomnomnominal/tsquery" "~5.0.1" tslib "^2.3.0" -"@nx/node@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/node/-/node-18.3.3.tgz#a000284eb88dc58cbb4dad9909c1e0a930560c61" - integrity sha512-OoeRuuvqrdEH8AsFKrJ91lnDVL9mlqvLzUy9D5PZCYspjCesc7Tmt7Xmbu3VEGzhQPilqZz4hVfXH6MLE7TvqA== +"@nx/node@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/node/-/node-19.0.1.tgz#cc485801e18729e719aded4445cc7cfb505ec022" + integrity sha512-KIJhSEQEoKE02jY6fJDtKq/GbzwleIVUlDMxshm1ovMsQLkA4RI1ZZZ66kjMi5l3roJ7/tvMgMRvqAIaF+76sQ== dependencies: - "@nrwl/node" "18.3.3" - "@nx/devkit" "18.3.3" - "@nx/eslint" "18.3.3" - "@nx/jest" "18.3.3" - "@nx/js" "18.3.3" + "@nrwl/node" "19.0.1" + "@nx/devkit" "19.0.1" + "@nx/eslint" "19.0.1" + "@nx/jest" "19.0.1" + "@nx/js" "19.0.1" tslib "^2.3.0" -"@nx/nx-darwin-arm64@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-18.3.3.tgz#dcdbcfe2796bbe3f1dfd61bce81389b05a50e69b" - integrity sha512-NpA2/7o1uUuaocMYopX9muxKif9HlGfWaXo2UeiR918usF6xri4aUqweZbaXVc9iqCAEbVMWUsjaLYGKPXHAjw== - -"@nx/nx-darwin-x64@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-18.3.3.tgz#aa7bdd1a3ea0bb81682422b805914efccab3b179" - integrity sha512-aydPLbc7DeceJ6szRf6DLT4ERoPvwfWyFiGXdAlEZYWhjEuNZLeG8K6jA3yHeWltKfX/qJqhnyKbnubBNzBKlQ== - -"@nx/nx-freebsd-x64@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/nx-freebsd-x64/-/nx-freebsd-x64-18.3.3.tgz#331f5dbb56c90b08e99c1ce9ff51e0c5b956f030" - integrity sha512-sEYEWsK/fwC1l7wzls7RNOjhmrooH0lK0mpgj1vDXesLBSZ7k+pddAqaHFECN4QXBSbHZI2PWOEhbnIH+Errsg== - -"@nx/nx-linux-arm-gnueabihf@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-18.3.3.tgz#d66d4787f5cfc56b5a7aa9a0453174b96b4729a8" - integrity sha512-B9GGMkrrzwiAfvew22x85ITO9TiNxbgRbKJQWQaoopNpXrnSWpY8WTNxpDT24fwV1qdQfsPKcY3F4O0NOUgPRA== - -"@nx/nx-linux-arm64-gnu@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-18.3.3.tgz#2ab08df1d052a55d4a52ba910fe41c25701d5361" - integrity sha512-1EucHf5/0JeqZmhritqkpEdOcdo9Dl32gpFvhNfS6kCAYmaDlEl4zqedz3VIoj4C7+C0pV3mcRO9qB9H7GM5bQ== - -"@nx/nx-linux-arm64-musl@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-18.3.3.tgz#69376454bb9759c376d0a90aa876dfff6bbf4d15" - integrity sha512-HPgOgnYYLPVCBEaAkSEGPGzZqTDCiyCAF/qtvx5z0f1U/hZYb1ubgxw70ogY82Cafr7X4gQBz5k4/ZCnoCXlOQ== - -"@nx/nx-linux-x64-gnu@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-18.3.3.tgz#0b8ba8ec0c2371f0df462742460d52d63b1cc715" - integrity sha512-FgYTQ3VEE6EUOGtJT9riRK8IBwPGFjKS+N2mudQJn2bB/9IumUvVRYQUIX08gqGLlqZPO6uUUhUjwZY8SnjRLQ== - -"@nx/nx-linux-x64-musl@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-18.3.3.tgz#c96d6f8d2d94b99ac8da723077ebbc92f833beea" - integrity sha512-QnWjGViR1Wj9gJXa1RJ9mXyy2/JzQ7NF2C4ulTYSH5St1HoxhkfnLsV0+uNLFEV9PSZq+2BfxmQuT8Appefv1A== - -"@nx/nx-win32-arm64-msvc@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-18.3.3.tgz#0d2c7396e7a063849edbd6e3d34ea81445c389b5" - integrity sha512-Xn3LUaPsF8QkEYUVV3lc693NTCMWrfZBFXTy1cQpvLzQ+idsXQ/EGWoq93cIM3Nc2YWyblT2hHHelb8dHCZAlw== - -"@nx/nx-win32-x64-msvc@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-18.3.3.tgz#ea1a60ae1ffe805529d5cb95e7b28e6b8ae24621" - integrity sha512-t8HvOnQEiaaoTFOOIrql30NPhIwDFO7jg0Jtz3Tbneulh7ceswJp71yFHsRGGrYZ23Tgg+Sna6M9qLRGzlRGkg== - -"@nx/storybook@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/storybook/-/storybook-18.3.3.tgz#4fa01568e3189984d14bae217281f16e2cea5f4e" - integrity sha512-wqca3J20F9HakmPBzq9fwmcZ25LFNb9iWnSngXMgDXjRizbjZrXrCkpyiZe3qlYzhoCNN9oYlUsbas3dec/lwA== - dependencies: - "@nrwl/storybook" "18.3.3" - "@nx/cypress" "18.3.3" - "@nx/devkit" "18.3.3" - "@nx/eslint" "18.3.3" - "@nx/js" "18.3.3" +"@nx/nx-darwin-arm64@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-19.0.1.tgz#92b8b08c7507570e83af3c270433bd1474a6f471" + integrity sha512-LYjrQ5lDKlXV/QHlubTp0of9JjcjrZ1heafu8jn+ieabGAnZ4Aow1amg/hjF5yKYDYJbCR9DhOMv9JJ1tkPa1w== + +"@nx/nx-darwin-x64@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-19.0.1.tgz#df78cfbf40069c948adf177e887723952ec1edb3" + integrity sha512-i7IqDRiGhU9NkOrhBMudLXcYsQv9mkPUOU8BECWk5qaeXK5LLXkroNVK5fsvOPaDtQci58VoeXQeZHxOl5Om/w== + +"@nx/nx-freebsd-x64@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/nx-freebsd-x64/-/nx-freebsd-x64-19.0.1.tgz#905ddb36d2779ee466013fe01035162f4d39f38b" + integrity sha512-2zaDWAyJXu+hkMhzoC/I/HTFISVoTwP76YTdaJG8JIfF7Ns/AZXZMzAtPNjL/I5Pgq/7brn6CpUExSYINxORrQ== + +"@nx/nx-linux-arm-gnueabihf@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-19.0.1.tgz#e79f718f462f7f6796581e1fb0281af17e26feb7" + integrity sha512-gZXphCxoaRIpAS+ZzjJgtCrRjDdbBoeOvaDRpmhKyUyAk9Z7Sgh9F+FyaT3TkV2ZVZJipzO5xcLIFCkTDS6CCQ== + +"@nx/nx-linux-arm64-gnu@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-19.0.1.tgz#85d0036a4df0c9294f7c4124135c0208590cf0de" + integrity sha512-W4o+V1S2N/0pLiyIavt/pcei9vOzScpGmd35UoDwtEKXIAifeJZbA6LtsTTmP/8o43TNYL3HALBcLnECt0m0iA== + +"@nx/nx-linux-arm64-musl@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-19.0.1.tgz#467ee408656500e5c33d5fea3ec6b8e42cb1f326" + integrity sha512-sm/bqAQXVjT9cF4oKIN+lmC0LIP4W1QDBJb4ZSoWqVcww+4fsPb3M95Egv5QbzHZOjEeRdIXRdLnWt1CRpP1eA== + +"@nx/nx-linux-x64-gnu@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-19.0.1.tgz#6a6c03dd2bb0fe17966f43fc05175458ec8dfed5" + integrity sha512-P+J2PaU2oNy5l8JSkt3DaqCa/psvL+gqKufofHoWNmRkXZM5zzJI1yVyagoKviG3vB4K2vBp6KyEFSmjBw2y9Q== + +"@nx/nx-linux-x64-musl@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-19.0.1.tgz#0bad1ca6f056f442b41b44b06fd981f0d5db9053" + integrity sha512-rIqsHeK4dZM8nd7IzwgS5yYgtYbSQkExVlY4kkEn1p5RgJ5N2jiZR4FrGQr6KYNBWyfOjjv5hKUlfqTb5xfNew== + +"@nx/nx-win32-arm64-msvc@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-19.0.1.tgz#5061cbb649b7f50d032f23cc097cf3ea87c28c95" + integrity sha512-eOeYLYIuI386y/3OOUOLjDI+WU5IdfcOcN27Dt26poRjsiBoi4a19B0Kmu2l7DGwOHTPIv0ktkcCloSGyB2ycg== + +"@nx/nx-win32-x64-msvc@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-19.0.1.tgz#e7241b65162d6b3c63e3459c753137331ffbd335" + integrity sha512-6N5P9an5QDnHyXS0Ai/yP2kG7ESlzwiZdFdPnF5azJ520OdVRpj8wklACqq5usbxg1SufusBs5RI5HA5/mzXSw== + +"@nx/storybook@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/storybook/-/storybook-19.0.1.tgz#59898f51a3a76366945c6fedd0e9c910cdcde8be" + integrity sha512-zfukVQCb+UCamPKTlWVjz7C3aGEXBU6/BPy44fQQU8iaFjYWQWx+Hq37J1goLAcwJxW/xh9ONMkXhDrX88EBqQ== + dependencies: + "@nrwl/storybook" "19.0.1" + "@nx/cypress" "19.0.1" + "@nx/devkit" "19.0.1" + "@nx/eslint" "19.0.1" + "@nx/js" "19.0.1" "@phenomnomnominal/tsquery" "~5.0.1" semver "^7.5.3" tslib "^2.3.0" -"@nx/web@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/web/-/web-18.3.3.tgz#99e6952942b3e43bc52ba444f6933dd279f49a6a" - integrity sha512-/NfQirVd2Ncq2if+1n8DaxNQF0OLaFaDag7qm5pDWJnjXFNh8N7NGZQRry2k/bTSfSc8gN+KJjqSMLAUNNtKgQ== +"@nx/web@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/web/-/web-19.0.1.tgz#d91211777133fd565aa79ad543a49639f4db536c" + integrity sha512-j9jNygKDyjzN3Tq5DWEGCYAptjf35g2z7TGPOH37kGyCMg3dM36LRPFctWtpwsea/yML09bL+tj+yRBcFRgRVg== dependencies: - "@nrwl/web" "18.3.3" - "@nx/devkit" "18.3.3" - "@nx/js" "18.3.3" + "@nrwl/web" "19.0.1" + "@nx/devkit" "19.0.1" + "@nx/js" "19.0.1" chalk "^4.1.0" detect-port "^1.5.1" http-server "^14.1.0" tslib "^2.3.0" -"@nx/webpack@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/webpack/-/webpack-18.3.3.tgz#2b13c08c99821a413edd4ff7749936871ae6ae32" - integrity sha512-DPs8wfmYe/mEZCQ/TQgUqb/zgXY8hevR23d8bDkYjB3Akjk4OOF3QpQ2OXQ4c+Jf0ckGnQYOg6XAkE682UZqzg== +"@nx/webpack@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/webpack/-/webpack-19.0.1.tgz#d4f50007f5c4ec14185ad44426d3c0dd63e424a5" + integrity sha512-m1J5z0ut/XKX+kA5ICUw5Aix5YMGLVTXshWQdYmz79jpCWQ7OoPHjXXmEeXHLS9o1vsRO8S8o2C2yz+rc+7mYA== dependencies: "@babel/core" "^7.23.2" - "@nrwl/webpack" "18.3.3" - "@nx/devkit" "18.3.3" - "@nx/js" "18.3.3" + "@nrwl/webpack" "19.0.1" + "@nx/devkit" "19.0.1" + "@nx/js" "19.0.1" ajv "^8.12.0" autoprefixer "^10.4.9" babel-loader "^9.1.2" @@ -4650,16 +4526,16 @@ webpack-node-externals "^3.0.0" webpack-subresource-integrity "^5.1.0" -"@nx/workspace@18.3.3": - version "18.3.3" - resolved "https://registry.yarnpkg.com/@nx/workspace/-/workspace-18.3.3.tgz#bae369fe9d6c8aca425222ec53f797bcacd715e6" - integrity sha512-SUJJKzOUuNnclpHHde6f6nlF+pQwMjeF026jFpWDFaNzdsADhhRulkz0GLRXB9kKszvzz2JKde9WBWnKrFZ2IQ== +"@nx/workspace@19.0.1": + version "19.0.1" + resolved "https://registry.yarnpkg.com/@nx/workspace/-/workspace-19.0.1.tgz#cbc7fadc8ff29b7d6a0ec70ff3efe298f4805c76" + integrity sha512-w3FH+0ioyS97lIQqnzuXWIcJHF651igrB3hLw3c/qR82AbFYoakb73PFgdpr2fGf/Xf0kdKRROT2cvp/am2tog== dependencies: - "@nrwl/workspace" "18.3.3" - "@nx/devkit" "18.3.3" + "@nrwl/workspace" "19.0.1" + "@nx/devkit" "19.0.1" chalk "^4.1.0" enquirer "~2.3.6" - nx "18.3.3" + nx "19.0.1" tslib "^2.3.0" yargs-parser "21.1.1" @@ -5276,134 +5152,189 @@ resolved "https://registry.yarnpkg.com/@stencil/core/-/core-4.18.0.tgz#944d75c735f692517803904f8d43003307e1a2cb" integrity sha512-cN+nvjy0L8KyYq7N1bmswN/AcBustFlsAxfyPQ+fd3m98lPo53jNKIxKve1ZQ4ZmzSzYO7alDhZvjIesM0rl7w== -"@storybook/addon-actions@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-7.6.5.tgz#276ed222cc038423cd5ee80441f88544a2663311" - integrity sha512-lW/m9YcaNfBZk+TZLxyzHdd563mBWpsUIveOKYjcPdl/q0FblWWZrRsFHqwLK1ldZ4AZXs8J/47G8CBr6Ew2uQ== +"@storybook/addon-actions@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-7.5.3.tgz#e0d0d819488d1d19918b23469b3ea6610fee5f07" + integrity sha512-v3yL6Eq/jCiXfA24JjRdbEQUuorms6tmrywaKcd1tAy4Ftgof0KHB4tTcTyiajrI5bh6PVJoRBkE8IDqmNAHkA== dependencies: - "@storybook/core-events" "7.6.5" + "@storybook/client-logger" "7.5.3" + "@storybook/components" "7.5.3" + "@storybook/core-events" "7.5.3" "@storybook/global" "^5.0.0" - "@types/uuid" "^9.0.1" + "@storybook/manager-api" "7.5.3" + "@storybook/preview-api" "7.5.3" + "@storybook/theming" "7.5.3" + "@storybook/types" "7.5.3" dequal "^2.0.2" + lodash "^4.17.21" polished "^4.2.2" + prop-types "^15.7.2" + react-inspector "^6.0.0" + telejson "^7.2.0" + ts-dedent "^2.0.0" uuid "^9.0.0" -"@storybook/addon-backgrounds@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-7.6.5.tgz#0b65a2163309b3768540301353e14878e27b7dcb" - integrity sha512-wZZOL19vg4TTRtOTl71XKqPe5hQx3XUh9Fle0wOi91FiFrBdqusrppnyS89wPS8RQG5lXEOFEUvYcMmdCcdZfw== +"@storybook/addon-backgrounds@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-7.5.3.tgz#a6aa9df791220cff6290e7f93e04c546063f5407" + integrity sha512-UCOVd4UNIL5FRiwi9nyiWFocn/7ewwS6bIWnq66AaHg/sv92YwsPmgQJn0DMBGDOvUAWpiHdVsZNOTX6nvw4gA== dependencies: + "@storybook/client-logger" "7.5.3" + "@storybook/components" "7.5.3" + "@storybook/core-events" "7.5.3" "@storybook/global" "^5.0.0" + "@storybook/manager-api" "7.5.3" + "@storybook/preview-api" "7.5.3" + "@storybook/theming" "7.5.3" + "@storybook/types" "7.5.3" memoizerific "^1.11.3" ts-dedent "^2.0.0" -"@storybook/addon-controls@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-7.6.5.tgz#1d7467da3d9d2eba7d325366ccbcd60d73803a5b" - integrity sha512-EdSZ2pYf74mOXZGGJ22lrDvdvL0YKc95iWv9FFEhUFOloMy/0OZPB2ybYmd2KVCy3SeIE4Zfeiw8pDXdCUniOQ== - dependencies: - "@storybook/blocks" "7.6.5" +"@storybook/addon-controls@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-7.5.3.tgz#03ce5a31603b360fe906cefb3fe4945ef7188e62" + integrity sha512-KEuU4X5Xr6cJI9xrzOUVGEmUf1iHPfK7cj0GACKv0GElsdIsQryv+OZ7gRnvmNax/e2hm2t9cJcFxB24/p6rVg== + dependencies: + "@storybook/blocks" "7.5.3" + "@storybook/client-logger" "7.5.3" + "@storybook/components" "7.5.3" + "@storybook/core-common" "7.5.3" + "@storybook/core-events" "7.5.3" + "@storybook/manager-api" "7.5.3" + "@storybook/node-logger" "7.5.3" + "@storybook/preview-api" "7.5.3" + "@storybook/theming" "7.5.3" + "@storybook/types" "7.5.3" lodash "^4.17.21" ts-dedent "^2.0.0" -"@storybook/addon-docs@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-7.6.5.tgz#60a658deb589db73c20dff4b1d8c6b30b4e22232" - integrity sha512-D9tZyD41IujCHiPYdfS2bKtZRJPNwO4EydzyqODXppomluhFbY3uTEaf0H1UFnJLQxWNXZ7rr3aS0V3O6yu8pA== +"@storybook/addon-docs@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-7.5.3.tgz#36c28c9a54b28e3b4b1450e821d65e07be6da45b" + integrity sha512-JVQ6iCXKESij/SbE4Wq47dkSSgBRulvA8SUf8NWL5m9qpiHrg0lPSERHfoTLiB5uC/JwF0OKIlhxoWl+zCmtYg== dependencies: "@jest/transform" "^29.3.1" "@mdx-js/react" "^2.1.5" - "@storybook/blocks" "7.6.5" - "@storybook/client-logger" "7.6.5" - "@storybook/components" "7.6.5" - "@storybook/csf-plugin" "7.6.5" - "@storybook/csf-tools" "7.6.5" + "@storybook/blocks" "7.5.3" + "@storybook/client-logger" "7.5.3" + "@storybook/components" "7.5.3" + "@storybook/csf-plugin" "7.5.3" + "@storybook/csf-tools" "7.5.3" "@storybook/global" "^5.0.0" "@storybook/mdx2-csf" "^1.0.0" - "@storybook/node-logger" "7.6.5" - "@storybook/postinstall" "7.6.5" - "@storybook/preview-api" "7.6.5" - "@storybook/react-dom-shim" "7.6.5" - "@storybook/theming" "7.6.5" - "@storybook/types" "7.6.5" + "@storybook/node-logger" "7.5.3" + "@storybook/postinstall" "7.5.3" + "@storybook/preview-api" "7.5.3" + "@storybook/react-dom-shim" "7.5.3" + "@storybook/theming" "7.5.3" + "@storybook/types" "7.5.3" fs-extra "^11.1.0" remark-external-links "^8.0.0" remark-slug "^6.0.0" ts-dedent "^2.0.0" -"@storybook/addon-essentials@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-essentials/-/addon-essentials-7.6.5.tgz#0b785b58205eada1aa8374f2cba6bc39530147e9" - integrity sha512-VCLj1JAEpGoqF5iFJOo1CZFFck/tg4m/98DLdQuNuXvxT6jqaF0NI9UUQuJLIGteDCR7NKRbTFc1hV3/Ev+Ziw== - dependencies: - "@storybook/addon-actions" "7.6.5" - "@storybook/addon-backgrounds" "7.6.5" - "@storybook/addon-controls" "7.6.5" - "@storybook/addon-docs" "7.6.5" - "@storybook/addon-highlight" "7.6.5" - "@storybook/addon-measure" "7.6.5" - "@storybook/addon-outline" "7.6.5" - "@storybook/addon-toolbars" "7.6.5" - "@storybook/addon-viewport" "7.6.5" - "@storybook/core-common" "7.6.5" - "@storybook/manager-api" "7.6.5" - "@storybook/node-logger" "7.6.5" - "@storybook/preview-api" "7.6.5" +"@storybook/addon-essentials@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-essentials/-/addon-essentials-7.5.3.tgz#e6e3ea266181b42e15b4c57fc303adc238c102a4" + integrity sha512-PYj6swEI4nEzIbOTyHJB8u3K8ABYKoaW8XB5emMwsnrzB/TN7auHVhze2bQ/+ax5wyPKZpArPjxbWlSHtSws+A== + dependencies: + "@storybook/addon-actions" "7.5.3" + "@storybook/addon-backgrounds" "7.5.3" + "@storybook/addon-controls" "7.5.3" + "@storybook/addon-docs" "7.5.3" + "@storybook/addon-highlight" "7.5.3" + "@storybook/addon-measure" "7.5.3" + "@storybook/addon-outline" "7.5.3" + "@storybook/addon-toolbars" "7.5.3" + "@storybook/addon-viewport" "7.5.3" + "@storybook/core-common" "7.5.3" + "@storybook/manager-api" "7.5.3" + "@storybook/node-logger" "7.5.3" + "@storybook/preview-api" "7.5.3" ts-dedent "^2.0.0" -"@storybook/addon-highlight@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-highlight/-/addon-highlight-7.6.5.tgz#588818963c48cc1d0f06a20323e72e3f0077b7c4" - integrity sha512-CxzmIb30F9nLPQwT0lCPYhOAwGlGF4IkgkO8hYA7VfGCGUkJZEyyN/YkP/ZCUSdCIRChDBouR3KiFFd4mDFKzg== +"@storybook/addon-highlight@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-highlight/-/addon-highlight-7.5.3.tgz#ff1041aa1e9d76100ce6fb0b11e0d30078f858f7" + integrity sha512-jb+aNRhj+tFK7EqqTlNCjGkTrkWqWHGdD1ubgnj29v8XhRuCR9YboPS+306KYwBEkuF4kNCHZofLiEBPf6nCJg== dependencies: + "@storybook/core-events" "7.5.3" "@storybook/global" "^5.0.0" + "@storybook/preview-api" "7.5.3" -"@storybook/addon-measure@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-measure/-/addon-measure-7.6.5.tgz#f1b70c83166cfaa851808c9d73dca8e639860fc0" - integrity sha512-tlUudVQSrA+bwI4dhO8J7nYHtYdylcBZ86ybnqMmdTthsnyc7jnaFVQwbb6bbQJpPxvEvoNds5bVGUFocuvymQ== +"@storybook/addon-measure@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-measure/-/addon-measure-7.5.3.tgz#9cfc34d88807afba6bc36990aef26be8ca8f8567" + integrity sha512-fun9BqUTGXgcMpcbX9wUowGDkjCL8oKasZbjp/MvGM3vPTM6HQdwzHTLJGPBnmJ1xK92NhwFRs0BrQX6uF1yrg== dependencies: + "@storybook/client-logger" "7.5.3" + "@storybook/components" "7.5.3" + "@storybook/core-events" "7.5.3" "@storybook/global" "^5.0.0" + "@storybook/manager-api" "7.5.3" + "@storybook/preview-api" "7.5.3" + "@storybook/types" "7.5.3" tiny-invariant "^1.3.1" -"@storybook/addon-outline@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-outline/-/addon-outline-7.6.5.tgz#ad6ba7ce32e9fb2621c79a18dca7a791edbf5b85" - integrity sha512-P7X4+Z9L/l/RZW9UvvM+iuK2SUHD22KPc+dbYOifRXDovUqhfmcKVh1CUqTDMyZrg2ZAbropehMz1eI9BlQfxg== +"@storybook/addon-outline@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-outline/-/addon-outline-7.5.3.tgz#8b42758349ab07b5d39bf7e1b9cb2f83e173824a" + integrity sha512-c9vCi1SCGrtWr8qaOu/1GNWlrlrpl2lg4F9r+xtYf/KopenI3jSMz0YeTfmepZGAl+6Yc2Ywhm60jgpQ6SKciA== dependencies: + "@storybook/client-logger" "7.5.3" + "@storybook/components" "7.5.3" + "@storybook/core-events" "7.5.3" "@storybook/global" "^5.0.0" + "@storybook/manager-api" "7.5.3" + "@storybook/preview-api" "7.5.3" + "@storybook/types" "7.5.3" ts-dedent "^2.0.0" -"@storybook/addon-toolbars@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-toolbars/-/addon-toolbars-7.6.5.tgz#a7e49640daad1b45926e453e36d8d8fecd88becf" - integrity sha512-/zqWbVNE/SHc8I5Prnd2Q8U57RGEIYvHfeXjfkuLcE2Quc4Iss4x/9eU7SKu4jm+IOO2s0wlN6HcqI3XEf2XxA== - -"@storybook/addon-viewport@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-7.6.5.tgz#c6472679828b0a77c0db12662e42d18f8999a6f5" - integrity sha512-9ghKTaduIUvQ6oShmWLuwMeTjtMR4RgKeKHrTJ7THMqvE/ydDPCYeL7ugF65ocXZSEz/QmxdK7uL686ZMKsqNA== - dependencies: +"@storybook/addon-toolbars@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-toolbars/-/addon-toolbars-7.5.3.tgz#754e818935f08f05d4e06aefafe40a1080c4d575" + integrity sha512-KdLr4sGMJzhtjNTNE2ocfu58yOHHUyZ/cI3BTp7a0gq9YbUpHmC3XTNr26/yOYYrdjkiMD26XusJUjXe+/V2xw== + dependencies: + "@storybook/client-logger" "7.5.3" + "@storybook/components" "7.5.3" + "@storybook/manager-api" "7.5.3" + "@storybook/preview-api" "7.5.3" + "@storybook/theming" "7.5.3" + +"@storybook/addon-viewport@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-7.5.3.tgz#05fb97114d0186977e25a5a448dea5fba66042ce" + integrity sha512-gT2XX0NNBrzSs1nrxadl6LnvcwgN7z2R0LzTK8/hxvx4D0EnXrV3feXLzjewr8ZYjzfEeSpO+W+bQTVNm3fNsg== + dependencies: + "@storybook/client-logger" "7.5.3" + "@storybook/components" "7.5.3" + "@storybook/core-events" "7.5.3" + "@storybook/global" "^5.0.0" + "@storybook/manager-api" "7.5.3" + "@storybook/preview-api" "7.5.3" + "@storybook/theming" "7.5.3" memoizerific "^1.11.3" - -"@storybook/angular@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/angular/-/angular-7.6.5.tgz#9692892719fd092326be0b11fb6f4306e3d8b5da" - integrity sha512-Q+diFi5ct4aHSegBLlryzNs4/WpefaMG1kVs9if9CvOu/286Pr0UMF75ldb3b+6ORIxe88vxdmLLs4idH+MjMQ== - dependencies: - "@storybook/builder-webpack5" "7.6.5" - "@storybook/cli" "7.6.5" - "@storybook/client-logger" "7.6.5" - "@storybook/core-common" "7.6.5" - "@storybook/core-events" "7.6.5" - "@storybook/core-server" "7.6.5" - "@storybook/core-webpack" "7.6.5" - "@storybook/docs-tools" "7.6.5" + prop-types "^15.7.2" + +"@storybook/angular@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/angular/-/angular-7.5.3.tgz#870d2b95efbdbce5cbbb361d14a2994120c0e07d" + integrity sha512-wGyebTb7hhdrhEopouFIsBS8SM/5nlTwxilaYbs9Cg3elSmsJyI3uLCHEeGKYupnzokQzP3xElWjwT2VYyW0fQ== + dependencies: + "@storybook/builder-webpack5" "7.5.3" + "@storybook/cli" "7.5.3" + "@storybook/client-logger" "7.5.3" + "@storybook/core-common" "7.5.3" + "@storybook/core-events" "7.5.3" + "@storybook/core-server" "7.5.3" + "@storybook/core-webpack" "7.5.3" + "@storybook/docs-tools" "7.5.3" "@storybook/global" "^5.0.0" - "@storybook/node-logger" "7.6.5" - "@storybook/preview-api" "7.6.5" - "@storybook/telemetry" "7.6.5" - "@storybook/types" "7.6.5" + "@storybook/manager-api" "7.5.3" + "@storybook/node-logger" "7.5.3" + "@storybook/preview-api" "7.5.3" + "@storybook/telemetry" "7.5.3" + "@storybook/types" "7.5.3" "@types/node" "^18.0.0" "@types/react" "^16.14.34" "@types/react-dom" "^16.9.14" @@ -5418,22 +5349,22 @@ util-deprecate "^1.0.2" webpack "5" -"@storybook/blocks@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/blocks/-/blocks-7.6.5.tgz#402b99d7b6047c8eec75147b20f0878e14db8d73" - integrity sha512-/NjuYkPks5w9lKn47KLgVC5cBkwfc+ERAp0CY0Xe//BQJkP+bcI8lE8d9Qc9IXFbOTvYEULeQrFgCkesk5BmLg== - dependencies: - "@storybook/channels" "7.6.5" - "@storybook/client-logger" "7.6.5" - "@storybook/components" "7.6.5" - "@storybook/core-events" "7.6.5" - "@storybook/csf" "^0.1.2" - "@storybook/docs-tools" "7.6.5" +"@storybook/blocks@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/blocks/-/blocks-7.5.3.tgz#be754f60a91e95b8c72cbeadf9c5c7e7ab78920f" + integrity sha512-Z8yF820v78clQWkwG5OA5qugbQn7rtutq9XCsd03NDB+IEfDaTFQAZG8gs62ZX2ZaXAJsqJSr/mL9oURzXto2A== + dependencies: + "@storybook/channels" "7.5.3" + "@storybook/client-logger" "7.5.3" + "@storybook/components" "7.5.3" + "@storybook/core-events" "7.5.3" + "@storybook/csf" "^0.1.0" + "@storybook/docs-tools" "7.5.3" "@storybook/global" "^5.0.0" - "@storybook/manager-api" "7.6.5" - "@storybook/preview-api" "7.6.5" - "@storybook/theming" "7.6.5" - "@storybook/types" "7.6.5" + "@storybook/manager-api" "7.5.3" + "@storybook/preview-api" "7.5.3" + "@storybook/theming" "7.5.3" + "@storybook/types" "7.5.3" "@types/lodash" "^4.14.167" color-convert "^2.0.1" dequal "^2.0.2" @@ -5469,15 +5400,15 @@ process "^0.11.10" util "^0.12.4" -"@storybook/builder-manager@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/builder-manager/-/builder-manager-7.6.5.tgz#bf02a89c56522f89d652aa050d9934f8bdd1d79c" - integrity sha512-FQyI+tfzMam2XKXq7k921YVafIJs9Vqvos5qx8vyRnRffo55UU8tgunwjGn0PswtbMm6sThVqE0C0ZzVr7RG8A== +"@storybook/builder-manager@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/builder-manager/-/builder-manager-7.5.3.tgz#dc667fd6d450988bc33c246686822a87c1b95558" + integrity sha512-uf4Vyj8ofHaq94m065SMvFKak1XrrxgI83VZAxc2QjiPcbRwcVOZd+wcKFdZydqqA6FlBDdJrU+k9INA4Qkfcw== dependencies: "@fal-works/esbuild-plugin-global-externals" "^2.1.2" - "@storybook/core-common" "7.6.5" - "@storybook/manager" "7.6.5" - "@storybook/node-logger" "7.6.5" + "@storybook/core-common" "7.5.3" + "@storybook/manager" "7.5.3" + "@storybook/node-logger" "7.5.3" "@types/ejs" "^3.1.1" "@types/find-cache-dir" "^3.2.1" "@yarnpkg/esbuild-plugin-pnp" "^3.0.0-rc.10" @@ -5491,34 +5422,33 @@ process "^0.11.10" util "^0.12.4" -"@storybook/builder-webpack5@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/builder-webpack5/-/builder-webpack5-7.6.5.tgz#c5eb2d5282df4c97c56d71f77203e2db03aced93" - integrity sha512-Lf4jVHGTQRSLIcgXHG2webiFlNwEV8uo2CmDucU2IDV9p3NdloyOmCou40G6Du1hobBTflx8Zj2j9n3A5/+0GA== - dependencies: - "@babel/core" "^7.23.2" - "@storybook/channels" "7.6.5" - "@storybook/client-logger" "7.6.5" - "@storybook/core-common" "7.6.5" - "@storybook/core-events" "7.6.5" - "@storybook/core-webpack" "7.6.5" - "@storybook/node-logger" "7.6.5" - "@storybook/preview" "7.6.5" - "@storybook/preview-api" "7.6.5" +"@storybook/builder-webpack5@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/builder-webpack5/-/builder-webpack5-7.5.3.tgz#7f392cae845c9c3c7de6e04045c531f8f70048e1" + integrity sha512-a2kHXFT61AV1+OPNTqXCsYk7Wk4XSqjAOQkSxWc1HK+kyMT+lahO4U06slji6XAVuXc/KY+naNUoaOfpB1hKVw== + dependencies: + "@babel/core" "^7.22.0" + "@storybook/channels" "7.5.3" + "@storybook/client-logger" "7.5.3" + "@storybook/core-common" "7.5.3" + "@storybook/core-events" "7.5.3" + "@storybook/core-webpack" "7.5.3" + "@storybook/node-logger" "7.5.3" + "@storybook/preview" "7.5.3" + "@storybook/preview-api" "7.5.3" "@swc/core" "^1.3.82" "@types/node" "^18.0.0" "@types/semver" "^7.3.4" babel-loader "^9.0.0" + babel-plugin-named-exports-order "^0.0.2" browser-assert "^1.2.1" case-sensitive-paths-webpack-plugin "^2.4.0" constants-browserify "^1.0.0" css-loader "^6.7.1" - es-module-lexer "^1.4.1" express "^4.17.3" fork-ts-checker-webpack-plugin "^8.0.0" fs-extra "^11.1.0" html-webpack-plugin "^5.5.0" - magic-string "^0.30.5" path-browserify "^1.0.1" process "^0.11.10" semver "^7.3.7" @@ -5551,13 +5481,13 @@ resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-7.0.9.tgz#0308c6a714daf1088228b554fd56dc72f2921b76" integrity sha512-LF/Mkr0/+VOawEAospLGUcfZIPak3yV/ZjEAe/lubvLPJ6s2FFOjDUsyDIa2oM4ZE9TI6AGVN51kddVToelM8A== -"@storybook/channels@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-7.6.5.tgz#cd2c977052bc83b6d4980fe2d2e0da5c91eadd68" - integrity sha512-FIlNkyfQy9uHoJfAFL2/wO3ASGJELFvBzURBE2rcEF/TS7GcUiqWnBfiDxAbwSEjSOm2F0eEq3UXhaZEjpJHDw== +"@storybook/channels@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-7.5.3.tgz#cbd178b0778f3484b970d0fd0edd294db6969e0f" + integrity sha512-dhWuV2o2lmxH0RKuzND8jxYzvSQTSmpE13P0IT/k8+I1up/rSNYOBQJT6SalakcNWXFAMXguo/8E7ApmnKKcEw== dependencies: - "@storybook/client-logger" "7.6.5" - "@storybook/core-events" "7.6.5" + "@storybook/client-logger" "7.5.3" + "@storybook/core-events" "7.5.3" "@storybook/global" "^5.0.0" qs "^6.10.0" telejson "^7.2.0" @@ -5607,23 +5537,23 @@ ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/cli@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/cli/-/cli-7.6.5.tgz#7ef55649e3a407544060f5edeb2c93425caebfb2" - integrity sha512-w+Y8dx5oCLQVESOVmpsQuFksr/ewARKrnSKl9kwnVMN4sMgjOgoZ3zmV66J7SKexvwyuwlOjf840pmEglGdPPg== +"@storybook/cli@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/cli/-/cli-7.5.3.tgz#127ae3bcad169bf8c3eb3e1e6c9d587ad5f57e81" + integrity sha512-XysHSnknZTAcTbQ0bQsbfv5J8ifHpOBsmXjk1HCA05E9WGGrn9JrQRCfpDUQJ6O6UWq0bpMqzP8gFLWXFE7hug== dependencies: - "@babel/core" "^7.23.2" - "@babel/preset-env" "^7.23.2" - "@babel/types" "^7.23.0" + "@babel/core" "^7.22.9" + "@babel/preset-env" "^7.22.9" + "@babel/types" "^7.22.5" "@ndelangen/get-tarball" "^3.0.7" - "@storybook/codemod" "7.6.5" - "@storybook/core-common" "7.6.5" - "@storybook/core-events" "7.6.5" - "@storybook/core-server" "7.6.5" - "@storybook/csf-tools" "7.6.5" - "@storybook/node-logger" "7.6.5" - "@storybook/telemetry" "7.6.5" - "@storybook/types" "7.6.5" + "@storybook/codemod" "7.5.3" + "@storybook/core-common" "7.5.3" + "@storybook/core-events" "7.5.3" + "@storybook/core-server" "7.5.3" + "@storybook/csf-tools" "7.5.3" + "@storybook/node-logger" "7.5.3" + "@storybook/telemetry" "7.5.3" + "@storybook/types" "7.5.3" "@types/semver" "^7.3.4" "@yarnpkg/fslib" "2.10.3" "@yarnpkg/libzip" "2.3.0" @@ -5640,7 +5570,7 @@ get-port "^5.1.1" giget "^1.0.0" globby "^11.0.2" - jscodeshift "^0.15.1" + jscodeshift "^0.14.0" leven "^3.1.0" ora "^5.4.1" prettier "^2.8.0" @@ -5661,10 +5591,10 @@ dependencies: "@storybook/global" "^5.0.0" -"@storybook/client-logger@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-7.6.5.tgz#a9d11ce436134884ecfec908e8bb4a970e233789" - integrity sha512-S5aROWgssqg7tcs9lgW5wmCAz4SxMAtioiyVj5oFecmPCbQtFVIAREYzeoxE4GfJL+plrfRkum4BzziANn8EhQ== +"@storybook/client-logger@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-7.5.3.tgz#5a33a8a1785dbe6beff60654bc8947724c0cd62e" + integrity sha512-vUFYALypjix5FoJ5M/XUP6KmyTnQJNW1poHdW7WXUVSg+lBM6E5eAtjTm0hdxNNDH8KSrdy24nCLra5h0X0BWg== dependencies: "@storybook/global" "^5.0.0" @@ -5687,38 +5617,38 @@ prettier "^2.8.0" recast "^0.23.1" -"@storybook/codemod@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/codemod/-/codemod-7.6.5.tgz#7ae6245f02ed9b95f1c6a525a6fb877710f28132" - integrity sha512-K5C9ltBClZ0aSyujGt3RJFtRicrUZy8nzhHrcADUj27rrQD26jH/p+Y05jWKj9JcI8SyMg978GN5X/1aw2Y31A== +"@storybook/codemod@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/codemod/-/codemod-7.5.3.tgz#8a294b8d12f304a2a9db902848977147394d451c" + integrity sha512-gzycFdqnF4drUjfzMTrLNHqi2jkw1lDeACUzQdug5uWxynZKAvMTHAgU0q9wvoYRR9Xhq8PhfKtXtYCCj2Er4Q== dependencies: - "@babel/core" "^7.23.2" - "@babel/preset-env" "^7.23.2" - "@babel/types" "^7.23.0" - "@storybook/csf" "^0.1.2" - "@storybook/csf-tools" "7.6.5" - "@storybook/node-logger" "7.6.5" - "@storybook/types" "7.6.5" + "@babel/core" "^7.22.9" + "@babel/preset-env" "^7.22.9" + "@babel/types" "^7.22.5" + "@storybook/csf" "^0.1.0" + "@storybook/csf-tools" "7.5.3" + "@storybook/node-logger" "7.5.3" + "@storybook/types" "7.5.3" "@types/cross-spawn" "^6.0.2" cross-spawn "^7.0.3" globby "^11.0.2" - jscodeshift "^0.15.1" + jscodeshift "^0.14.0" lodash "^4.17.21" prettier "^2.8.0" recast "^0.23.1" -"@storybook/components@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/components/-/components-7.6.5.tgz#188a7f9ba75b04e7414b4b720d274700df286323" - integrity sha512-w4ZucbBBZ+NKMWlJKVj2I/bMBBq7gzDp9lzc4+8QaQ3vUPXKqc1ilIPYo/7UR5oxwDVMZocmMSgl9L8lvf7+Mw== +"@storybook/components@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-7.5.3.tgz#3fa282252e02973ead9f537f5ae3b5aeee5be4c4" + integrity sha512-M3+cjvEsDGLUx8RvK5wyF6/13LNlUnKbMgiDE8Sxk/v/WPpyhOAIh/B8VmrU1psahS61Jd4MTkFmLf1cWau1vw== dependencies: "@radix-ui/react-select" "^1.2.2" "@radix-ui/react-toolbar" "^1.0.4" - "@storybook/client-logger" "7.6.5" - "@storybook/csf" "^0.1.2" + "@storybook/client-logger" "7.5.3" + "@storybook/csf" "^0.1.0" "@storybook/global" "^5.0.0" - "@storybook/theming" "7.6.5" - "@storybook/types" "7.6.5" + "@storybook/theming" "7.5.3" + "@storybook/types" "7.5.3" memoizerific "^1.11.3" use-resize-observer "^9.1.0" util-deprecate "^1.0.2" @@ -5748,14 +5678,14 @@ resolve-from "^5.0.0" ts-dedent "^2.0.0" -"@storybook/core-common@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/core-common/-/core-common-7.6.5.tgz#51bda38a722507de5adfe2b05a82f4404188e898" - integrity sha512-z4EgzZSIVbID6Ib0jhh3jimKeaDWU8OOhoZYfn3galFmgQWowWOv1oMgipWiXfRLWw9DaLFQiCHIdLANH+VO2g== +"@storybook/core-common@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/core-common/-/core-common-7.5.3.tgz#baaf4cb8e2e29ebd74626ee8cd5971f337ac4e23" + integrity sha512-WGMwjtVUxUzFwQz7Mgs0gLuNebIGNV55dCdZgurx2/y6QOkJ2v8D0b3iL+xKMV4B5Nwoc2DsM418Y+Hy3UQd+w== dependencies: - "@storybook/core-events" "7.6.5" - "@storybook/node-logger" "7.6.5" - "@storybook/types" "7.6.5" + "@storybook/core-events" "7.5.3" + "@storybook/node-logger" "7.5.3" + "@storybook/types" "7.5.3" "@types/find-cache-dir" "^3.2.1" "@types/node" "^18.0.0" "@types/node-fetch" "^2.6.4" @@ -5782,10 +5712,10 @@ resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.0.9.tgz#4aa5913cfa3ccb40b83bf4ffbb6ef832aa8f5402" integrity sha512-xJiyX7Gq/TgDdBv+8KbfTJ4Sc7fCMeIEUqWTtnYCHWB7Mp6Iui37+caDX3aGQRTz7FVgb7aL5QkQES9Ihc1+dg== -"@storybook/core-events@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.6.5.tgz#bcac8a2625c1f63d290d4ca0b70bb7a953939750" - integrity sha512-zk2q/qicYXAzHA4oV3GDbIql+Kd4TOHUgDE8e4jPCOPp856z2ScqEKUAbiJizs6eEJOH4nW9Db1kuzgrBVEykQ== +"@storybook/core-events@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.5.3.tgz#210089576844569a914cc0cd1e07119bac6eb0e4" + integrity sha512-DFOpyQ22JD5C1oeOFzL8wlqSWZzrqgDfDbUGP8xdO4wJu+FVTxnnWN6ZYLdTPB1u27DOhd7TzjQMfLDHLu7kbQ== dependencies: ts-dedent "^2.0.0" @@ -5837,26 +5767,26 @@ watchpack "^2.2.0" ws "^8.2.3" -"@storybook/core-server@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/core-server/-/core-server-7.6.5.tgz#266b650a5dd7917faf1d23119b16ea5637e87fc8" - integrity sha512-BfKzK/ObTjUcPvE5/r1pogCifM/4nLRhOUYJl7XekwHkOQwn19e6H3/ku1W3jDoYXBu642Dc9X7l/ERjKTqxFg== +"@storybook/core-server@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/core-server/-/core-server-7.5.3.tgz#23ea0757d6ffc0e9acc269b58efd7f75f5d781f6" + integrity sha512-Gmq1w7ulN/VIeTDboNcb6GNM+S8T0SqhJUqeoHzn0vLGnzxeuYRJ0V3ZJhGZiJfSmCNqYAjC8QUBf6uU1gLipw== dependencies: "@aw-web-design/x-default-browser" "1.4.126" "@discoveryjs/json-ext" "^0.5.3" - "@storybook/builder-manager" "7.6.5" - "@storybook/channels" "7.6.5" - "@storybook/core-common" "7.6.5" - "@storybook/core-events" "7.6.5" - "@storybook/csf" "^0.1.2" - "@storybook/csf-tools" "7.6.5" + "@storybook/builder-manager" "7.5.3" + "@storybook/channels" "7.5.3" + "@storybook/core-common" "7.5.3" + "@storybook/core-events" "7.5.3" + "@storybook/csf" "^0.1.0" + "@storybook/csf-tools" "7.5.3" "@storybook/docs-mdx" "^0.1.0" "@storybook/global" "^5.0.0" - "@storybook/manager" "7.6.5" - "@storybook/node-logger" "7.6.5" - "@storybook/preview-api" "7.6.5" - "@storybook/telemetry" "7.6.5" - "@storybook/types" "7.6.5" + "@storybook/manager" "7.5.3" + "@storybook/node-logger" "7.5.3" + "@storybook/preview-api" "7.5.3" + "@storybook/telemetry" "7.5.3" + "@storybook/types" "7.5.3" "@types/detect-port" "^1.3.0" "@types/node" "^18.0.0" "@types/pretty-hrtime" "^1.0.0" @@ -5884,23 +5814,23 @@ watchpack "^2.2.0" ws "^8.2.3" -"@storybook/core-webpack@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/core-webpack/-/core-webpack-7.6.5.tgz#05f58b11cacaa51e6f5e02943640491ee5977737" - integrity sha512-if5ixN2W3e8vwYvgFHq+k0FOSVwgolbPRLDeOToPXHAJjH/TmgGEANZLFAVVwEzsS4KOfRGJQ48KzF0knTsqzA== +"@storybook/core-webpack@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/core-webpack/-/core-webpack-7.5.3.tgz#40da9419c71d6e0134a4309cf0ed6f034baf5bdd" + integrity sha512-dhC94VeLwyPtZ2gvEND6J4alMaiFDsK8lJCYPNAahUr56f3nRDyVibE7prd94sAlfrdind1g5slP9VMP8cX+uQ== dependencies: - "@storybook/core-common" "7.6.5" - "@storybook/node-logger" "7.6.5" - "@storybook/types" "7.6.5" + "@storybook/core-common" "7.5.3" + "@storybook/node-logger" "7.5.3" + "@storybook/types" "7.5.3" "@types/node" "^18.0.0" ts-dedent "^2.0.0" -"@storybook/csf-plugin@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/csf-plugin/-/csf-plugin-7.6.5.tgz#1a0ae37c692d182d9efa6435f7543952997d035c" - integrity sha512-iQ8Y/Qq1IUhHRddjDVicWJA2sM7OZA1FR97OvWUT2240WjCuQSCfy32JD8TQlYjqXgEolJeLPv3zW4qH5om4LQ== +"@storybook/csf-plugin@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/csf-plugin/-/csf-plugin-7.5.3.tgz#803197a2042323323528014878e9f9f0cc50c193" + integrity sha512-yQ3S/IOT08Y7XTnlc3SPkrJKZ6Xld6liAlHn+ddjge4oZa0hUqwYLb+piXUhFMfL6Ij65cj4hu3vMbw89azIhg== dependencies: - "@storybook/csf-tools" "7.6.5" + "@storybook/csf-tools" "7.5.3" unplugin "^1.3.1" "@storybook/csf-tools@7.0.9": @@ -5918,17 +5848,17 @@ recast "^0.23.1" ts-dedent "^2.0.0" -"@storybook/csf-tools@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/csf-tools/-/csf-tools-7.6.5.tgz#8e9e98f600ee651e8b63524662ce5a8a6a155fdf" - integrity sha512-1iaCh7nt+WE7Q5UwRhLLc5flMNoAV/vBr0tvDSCKiHaO+D3dZzlZOe/U+S6wegdyN2QNcvT2xs179CcrX6Qp6w== +"@storybook/csf-tools@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/csf-tools/-/csf-tools-7.5.3.tgz#1b2a393b3402a4c2fdfb2eb4eb90c63463c106ae" + integrity sha512-676C3ISn7FQJKjb3DBWXhjGN2OQEv4s71dx+5D0TlmswDCOOGS8dYFjP8wVx51+mAIE8CROAw7vLHLtVKU7SwQ== dependencies: - "@babel/generator" "^7.23.0" - "@babel/parser" "^7.23.0" - "@babel/traverse" "^7.23.2" - "@babel/types" "^7.23.0" - "@storybook/csf" "^0.1.2" - "@storybook/types" "7.6.5" + "@babel/generator" "^7.22.9" + "@babel/parser" "^7.22.7" + "@babel/traverse" "^7.22.8" + "@babel/types" "^7.22.5" + "@storybook/csf" "^0.1.0" + "@storybook/types" "7.5.3" fs-extra "^11.1.0" recast "^0.23.1" ts-dedent "^2.0.0" @@ -5940,7 +5870,7 @@ dependencies: lodash "^4.17.15" -"@storybook/csf@^0.1.0", "@storybook/csf@^0.1.2": +"@storybook/csf@^0.1.0": version "0.1.7" resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.7.tgz#dcc6c16a353bc09c8c619ba1a23ba93b2aab0b9d" integrity sha512-53JeLZBibjQxi0Ep+/AJTfxlofJlxy1jXcSKENlnKxHjWEYyHQCumMP5yTFjf7vhNnMjEpV3zx6t23ssFiGRyw== @@ -5952,16 +5882,15 @@ resolved "https://registry.yarnpkg.com/@storybook/docs-mdx/-/docs-mdx-0.1.0.tgz#33ba0e39d1461caf048b57db354b2cc410705316" integrity sha512-JDaBR9lwVY4eSH5W8EGHrhODjygPd6QImRbwjAuJNEnY0Vw4ie3bPkeGfnacB3OBW6u/agqPv2aRlR46JcAQLg== -"@storybook/docs-tools@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/docs-tools/-/docs-tools-7.6.5.tgz#9ae11a592dec958004468c4aafbe7c1d73d054f0" - integrity sha512-UyHkHu5Af6jMpYsR4lZ69D32GQGeA0pLAn7jaBbQndgAjBdK1ykZcifiUC7Wz1hG7+YpuYspEGuDEddOh+X8FQ== +"@storybook/docs-tools@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/docs-tools/-/docs-tools-7.5.3.tgz#1d1aec4a7546d70a2273ad99814a1dbecb8e80f7" + integrity sha512-f20EUQlwamcSPrOFn42fj9gpkZIDNCZkC3N19yGzLYiE4UMyaYQgRl18oLvqd3M6aBm6UW6SCoIIgeaOViBSqg== dependencies: - "@storybook/core-common" "7.6.5" - "@storybook/preview-api" "7.6.5" - "@storybook/types" "7.6.5" + "@storybook/core-common" "7.5.3" + "@storybook/preview-api" "7.5.3" + "@storybook/types" "7.5.3" "@types/doctrine" "^0.0.3" - assert "^2.1.0" doctrine "^3.0.0" lodash "^4.17.21" @@ -5970,19 +5899,19 @@ resolved "https://registry.yarnpkg.com/@storybook/global/-/global-5.0.0.tgz#b793d34b94f572c1d7d9e0f44fac4e0dbc9572ed" integrity sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ== -"@storybook/manager-api@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/manager-api/-/manager-api-7.6.5.tgz#6ddcf6ee3903c119ca1a3fbd41d4fdbf15e5d73a" - integrity sha512-tE3OShOcs6A3XtI3NJd6hYQOZLaP++Fn0dCtowBwYh/vS1EN/AyroVmL97tsxn1DZTyoRt0GidwbB6dvLMBOwA== +"@storybook/manager-api@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/manager-api/-/manager-api-7.5.3.tgz#6e9e791a8996631dc77f3a0cecc34ce4f4869647" + integrity sha512-d8mVLr/5BEG4bAS2ZeqYTy/aX4jPEpZHdcLaWoB4mAM+PAL9wcWsirUyApKtDVYLITJf/hd8bb2Dm2ok6E45gA== dependencies: - "@storybook/channels" "7.6.5" - "@storybook/client-logger" "7.6.5" - "@storybook/core-events" "7.6.5" - "@storybook/csf" "^0.1.2" + "@storybook/channels" "7.5.3" + "@storybook/client-logger" "7.5.3" + "@storybook/core-events" "7.5.3" + "@storybook/csf" "^0.1.0" "@storybook/global" "^5.0.0" - "@storybook/router" "7.6.5" - "@storybook/theming" "7.6.5" - "@storybook/types" "7.6.5" + "@storybook/router" "7.5.3" + "@storybook/theming" "7.5.3" + "@storybook/types" "7.5.3" dequal "^2.0.2" lodash "^4.17.21" memoizerific "^1.11.3" @@ -5996,10 +5925,10 @@ resolved "https://registry.yarnpkg.com/@storybook/manager/-/manager-7.0.9.tgz#7bc1e8d38f719365c3523cb39341e2ced6275070" integrity sha512-fyUb9DhTCnWBxjVQR0oTnXPStyIZh4DhQ1oXKEYKtV6ZeS+Qw4yXRDgciVXv6ifIBAdSEZOJ0o869c6NUt0iVQ== -"@storybook/manager@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/manager/-/manager-7.6.5.tgz#0a662f8020bc0ea94ec7e3897dcbbf798af56aaf" - integrity sha512-y1KLH0O1PGPyMxGMvOhppzFSO7r4ibjTve5iqsI0JZwxUjNuBKRLYbrhXdAyC2iacvxYNrHgevae1k9XdD+FQw== +"@storybook/manager@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/manager/-/manager-7.5.3.tgz#e185fc056546c19d255cdc26b6f2698e04d3f8ab" + integrity sha512-3ZZrHYcXWAQXpDQZBvKyScGgQaAaBc63i+KC2mXqzTdXuJhVDUiylvqLRprBnrEprgePQLFrxGC2JSHUwH7dqg== "@storybook/mdx2-csf@^1.0.0": version "1.1.0" @@ -6016,15 +5945,15 @@ npmlog "^5.0.1" pretty-hrtime "^1.0.3" -"@storybook/node-logger@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-7.6.5.tgz#2836bcf90f34672535fb2d13d9799357d8e1cbc8" - integrity sha512-xKw6IH1wLkIssekdBv3bd13xYKUF1t8EwqDR8BYcN8AVjZlqJMTifssqG4bYV+G/B7J3tz4ugJ5nmtWg6RQ0Qw== +"@storybook/node-logger@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-7.5.3.tgz#23133787f5b3427cef7301e10c6caf9132969fc1" + integrity sha512-7ZZDw/q3hakBj1FngsBjaHNIBguYAWojp7R1fFTvwkeunCi21EUzZjRBcqp10kB6BP3/NLX32bIQknsCWD76rQ== -"@storybook/postinstall@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/postinstall/-/postinstall-7.6.5.tgz#24132c67b3b563b155bf76444b5c1279bd56b26a" - integrity sha512-12WxfpqGKsk7GQ3KWiZSbamsYK8vtRmhOTkavZ9IQkcJ/zuVfmqK80/Mds+njJMudUPzuREuSFGWACczo17EDA== +"@storybook/postinstall@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/postinstall/-/postinstall-7.5.3.tgz#66b9add9e315646dde2289d77c87118c3c8596a6" + integrity sha512-r+H3xGMu2A9yOSsygc3bDFhku8wpOZF3SqO19B7eAML12viHwUtYfyGL74svw4TMcKukyQ+KPn5QsSG+4bjZMg== "@storybook/preview-api@7.0.9": version "7.0.9" @@ -6047,17 +5976,17 @@ ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/preview-api@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.6.5.tgz#fe2a84d2538a6450395e715a6691926a45d3cdfa" - integrity sha512-9XzuDXXgNuA6dDZ3DXsUwEG6ElxeTbzLuYuzcjtS1FusSICZ2iYmxfS0GfSud9MjPPYOJYoSOvMdIHjorjgByA== +"@storybook/preview-api@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.5.3.tgz#eaf70f9b6888d0dac42ce39a296afd6acacf6156" + integrity sha512-LNmEf7oBRnZ1wG3bQ+P+TO29+NN5pSDJiAA6FabZBrtIVm+psc2lxBCDQvFYyAFzQSlt60toGKNW8+RfFNdR5Q== dependencies: - "@storybook/channels" "7.6.5" - "@storybook/client-logger" "7.6.5" - "@storybook/core-events" "7.6.5" - "@storybook/csf" "^0.1.2" + "@storybook/channels" "7.5.3" + "@storybook/client-logger" "7.5.3" + "@storybook/core-events" "7.5.3" + "@storybook/csf" "^0.1.0" "@storybook/global" "^5.0.0" - "@storybook/types" "7.6.5" + "@storybook/types" "7.5.3" "@types/qs" "^6.9.5" dequal "^2.0.2" lodash "^4.17.21" @@ -6067,22 +5996,22 @@ ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/preview@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/preview/-/preview-7.6.5.tgz#d86bfe0b528f238fee8a4384a49eb24945d5c5dc" - integrity sha512-zmLa7C7yFGTYhgGZXoecdww9rx0Z5HpNi/GDBRWoNSK+FEdE8Jj2jF5NJ2ncldtYIyegz9ku29JFMKbhMj9K5Q== +"@storybook/preview@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/preview/-/preview-7.5.3.tgz#9abe434ea9fb280a7d2141b72be2958f7eb9cc5b" + integrity sha512-Hf90NlLaSrdMZXPOHDCMPjTywVrQKK0e5CtzqWx/ZQz91JDINxJD+sGj2wZU+wuBtQcTtlsXc9OewlJ+9ETwIw== -"@storybook/react-dom-shim@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/react-dom-shim/-/react-dom-shim-7.6.5.tgz#070bbce6b49b97991a21ce99dba78cff7ba7377f" - integrity sha512-Qp3N3zENdvx20ikHmz5yI03z+mAWF8bUAwUofqXarVtZUkBNtvfTfUwgAezOAF0eClClH+ktIziIKd976tLSPw== +"@storybook/react-dom-shim@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/react-dom-shim/-/react-dom-shim-7.5.3.tgz#54fc7bda589be5f630738fd08d2a37d5bb7815fa" + integrity sha512-9aNcKdhoP36jMrcXgfzE9jVg/SpqPpWnUJM70upYoZXytG2wQSPtawLHHyC6kycvTzwncyfF3rwUnOFBB8zmig== -"@storybook/router@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/router/-/router-7.6.5.tgz#9dfc5f8844e254fc14524373d48e0c357f3ca553" - integrity sha512-QiTC86gRuoepzzmS6HNJZTwfz/n27NcqtaVEIxJi1Yvsx2/kLa9NkRhylNkfTuZ1gEry9stAlKWanMsB2aKyjQ== +"@storybook/router@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/router/-/router-7.5.3.tgz#e024ad96bc4bbf7250239921a251e828729e4747" + integrity sha512-/iNYCFore7R5n6eFHbBYoB0P2/sybTVpA+uXTNUd3UEt7Ro6CEslTaFTEiH2RVQwOkceBp/NpyWon74xZuXhMg== dependencies: - "@storybook/client-logger" "7.6.5" + "@storybook/client-logger" "7.5.3" memoizerific "^1.11.3" qs "^6.10.0" @@ -6101,27 +6030,27 @@ nanoid "^3.3.1" read-pkg-up "^7.0.1" -"@storybook/telemetry@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/telemetry/-/telemetry-7.6.5.tgz#e4ed139f86e196434a20f9bee27ce290a7d32441" - integrity sha512-FiLRh9k9LoGphqgBqPYySWdGqplihiZyDwqdo+Qs19RcQ/eiKg0W7fdA09nStcdcsHmDl/1cMfRhz9KUiMtwOw== +"@storybook/telemetry@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/telemetry/-/telemetry-7.5.3.tgz#67d77c5cb33360c6f483a7cc89897fea160ca446" + integrity sha512-X6alII3o0jCb5xALuw+qcWmvyrbhlkmPeNZ6ZQXknOfB4DkwponFdWN5y6W7yGvr01xa5QBepJRV79isl97d8g== dependencies: - "@storybook/client-logger" "7.6.5" - "@storybook/core-common" "7.6.5" - "@storybook/csf-tools" "7.6.5" + "@storybook/client-logger" "7.5.3" + "@storybook/core-common" "7.5.3" + "@storybook/csf-tools" "7.5.3" chalk "^4.1.0" detect-package-manager "^2.0.1" fetch-retry "^5.0.2" fs-extra "^11.1.0" read-pkg-up "^7.0.1" -"@storybook/theming@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-7.6.5.tgz#b73e81c6ca8b136d38bbb3bf4cd0d7a4e373d813" - integrity sha512-RpcWT0YEgiobO41McVPDfQQHHFnjyr1sJnNTPJIvOUgSfURdgSj17mQVxtD5xcXcPWUdle5UhIOrCixHbL/NNw== +"@storybook/theming@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-7.5.3.tgz#bbcf547c8b3ec1e59e641c58155a44781d5f310d" + integrity sha512-Cjmthe1MAk0z4RKCZ7m72gAD8YD0zTAH97z5ryM1Qv84QXjiCQ143fGOmYz1xEQdNFpOThPcwW6FEccLHTkVcg== dependencies: "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" - "@storybook/client-logger" "7.6.5" + "@storybook/client-logger" "7.5.3" "@storybook/global" "^5.0.0" memoizerific "^1.11.3" @@ -6135,12 +6064,12 @@ "@types/express" "^4.7.0" file-system-cache "^2.0.0" -"@storybook/types@7.6.5": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@storybook/types/-/types-7.6.5.tgz#25c20d6bb350117f740b7f1f138f354f25d506bc" - integrity sha512-Q757v+fYZZSaEpks/zDL5YgXRozxkgKakXFc+BoQHK5q5sVhJ+0jvpLJiAQAniIIaMIkqY/G24Kd6Uo6UdKBCg== +"@storybook/types@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/types/-/types-7.5.3.tgz#be956805dafc09fa9a7a3dd4e0e5097ef08e4fd4" + integrity sha512-iu5W0Kdd6nysN5CPkY4GRl+0BpxRTdSfBIJak7mb6xCIHSB5t1tw4BOuqMQ5EgpikRY3MWJ4gY647QkWBX3MNQ== dependencies: - "@storybook/channels" "7.6.5" + "@storybook/channels" "7.5.3" "@types/babel__core" "^7.0.0" "@types/express" "^4.7.0" file-system-cache "2.3.0" @@ -6688,17 +6617,12 @@ dependencies: undici-types "~5.26.4" -"@types/node@20.4.2": - version "20.4.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.2.tgz#129cc9ae69f93824f92fac653eebfb4812ab4af9" - integrity sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw== - "@types/node@^16.0.0": version "16.18.97" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.97.tgz#d7926a8030f0d714d555b4550c0cc7731495cfe5" integrity sha512-4muilE1Lbfn57unR+/nT9AFjWk0MtWi5muwCEJqnOvfRQDbSfLCUdN7vCIg8TYuaANfhLOV85ve+FNpiUsbSRg== -"@types/node@^18.0.0": +"@types/node@^18.0.0", "@types/node@^18.16.9": version "18.19.33" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.33.tgz#98cd286a1b8a5e11aa06623210240bcc28e95c48" integrity sha512-NR9+KrpSajr2qBVp/Yt5TU/rp+b5Mayi3+OlMlcg2cVCfRmcG5PWZ7S4+MG9PZ5gWBoc9Pd0BKSRViuBCRPu0A== @@ -6890,11 +6814,6 @@ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.10.tgz#04ffa7f406ab628f7f7e97ca23e290cd8ab15efc" integrity sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA== -"@types/uuid@^9.0.1": - version "9.0.8" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" - integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== - "@types/validator@^13.7.10": version "13.11.9" resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.11.9.tgz#adfe96520b437a0eaa798a475877bf2f75ee402d" @@ -7792,17 +7711,6 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== -assert@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/assert/-/assert-2.1.0.tgz#6d92a238d05dc02e7427c881fb8be81c8448b2dd" - integrity sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw== - dependencies: - call-bind "^1.0.2" - is-nan "^1.3.2" - object-is "^1.1.5" - object.assign "^4.1.4" - util "^0.12.5" - ast-types-flow@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" @@ -7995,6 +7903,11 @@ babel-plugin-macros@^2.8.0: cosmiconfig "^6.0.0" resolve "^1.12.0" +babel-plugin-named-exports-order@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/babel-plugin-named-exports-order/-/babel-plugin-named-exports-order-0.0.2.tgz#ae14909521cf9606094a2048239d69847540cb09" + integrity sha512-OgOYHOLoRK+/mvXU9imKHlG6GkPLYrUCvFXG/CM93R/aNNO8pOOF4aS+S8CCHMDQoNSeiOYEZb/G6RwL95Jktw== + babel-plugin-polyfill-corejs2@^0.3.3: version "0.3.3" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz#5d1bd3836d0a19e1b84bbf2d9640ccb6f951c122" @@ -8310,7 +8223,7 @@ browserify-zlib@^0.1.4: dependencies: pako "~0.2.0" -browserslist@^4.0.0, browserslist@^4.21.10, browserslist@^4.21.4, browserslist@^4.21.5, browserslist@^4.21.9, browserslist@^4.22.2, browserslist@^4.23.0: +browserslist@^4.0.0, browserslist@^4.21.10, browserslist@^4.21.4, browserslist@^4.21.5, browserslist@^4.22.2, browserslist@^4.23.0: version "4.23.0" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.0.tgz#8f3acc2bbe73af7213399430890f86c63a5674ab" integrity sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ== @@ -8445,7 +8358,7 @@ cachedir@^2.3.0: resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.4.0.tgz#7fef9cf7367233d7c88068fe6e34ed0d355a610d" integrity sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ== -call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: +call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== @@ -9920,7 +9833,7 @@ define-lazy-prop@^2.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== -define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: +define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== @@ -10416,7 +10329,7 @@ es-errors@^1.2.1, es-errors@^1.3.0: resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== -es-module-lexer@^1.2.1, es-module-lexer@^1.4.1: +es-module-lexer@^1.2.1: version "1.5.2" resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.5.2.tgz#00b423304f2500ac59359cc9b6844951f372d497" integrity sha512-l60ETUTmLqbVbVHv1J4/qj+M8nq7AwMzEcg3kmJDt9dCNrTk+yHcYFf/Kw75pMDwd9mPcIGCG5LcS20SxYRzFA== @@ -12589,14 +12502,6 @@ is-lambda@^1.0.1: resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== -is-nan@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" - integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - is-negative-zero@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747" @@ -13082,10 +12987,10 @@ jest-pnp-resolver@^1.2.2: resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== -jest-preset-angular@14.0.3: - version "14.0.3" - resolved "https://registry.yarnpkg.com/jest-preset-angular/-/jest-preset-angular-14.0.3.tgz#ce78451a61bad0e4828bd75dd36542ad5bf48dac" - integrity sha512-usgBL7x0rXMnMSx8iEFeOozj50W6fp+YAmQcQBUdAXhN+PAXRy4UXL6I/rfcAOU09rnnq7RKsLsmhpp/fFEuag== +jest-preset-angular@14.0.4: + version "14.0.4" + resolved "https://registry.yarnpkg.com/jest-preset-angular/-/jest-preset-angular-14.0.4.tgz#4745033c58c86ad3d8dd16450d67563703285bd5" + integrity sha512-O4WhVRdfiN9TtJMbJbuVJxD3zn6fyOF2Pqvu12fvEVR6FxCN1S1POfR2nU1fRdP+rQZv7iiW+ttxsy+qkE8iCw== dependencies: bs-logger "^0.2.6" esbuild-wasm ">=0.15.13" @@ -13337,32 +13242,6 @@ jscodeshift@^0.14.0: temp "^0.8.4" write-file-atomic "^2.3.0" -jscodeshift@^0.15.1: - version "0.15.2" - resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.15.2.tgz#145563860360b4819a558c75c545f39683e5a0be" - integrity sha512-FquR7Okgmc4Sd0aEDwqho3rEiKR3BdvuG9jfdHjLJ6JQoWSMpavug3AoIfnfWhxFlf+5pzQh8qjqz0DWFrNQzA== - dependencies: - "@babel/core" "^7.23.0" - "@babel/parser" "^7.23.0" - "@babel/plugin-transform-class-properties" "^7.22.5" - "@babel/plugin-transform-modules-commonjs" "^7.23.0" - "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.11" - "@babel/plugin-transform-optional-chaining" "^7.23.0" - "@babel/plugin-transform-private-methods" "^7.22.5" - "@babel/preset-flow" "^7.22.15" - "@babel/preset-typescript" "^7.23.0" - "@babel/register" "^7.22.15" - babel-core "^7.0.0-bridge.0" - chalk "^4.1.2" - flow-parser "0.*" - graceful-fs "^4.2.4" - micromatch "^4.0.4" - neo-async "^2.5.0" - node-dir "^0.1.17" - recast "^0.23.3" - temp "^0.8.4" - write-file-atomic "^2.3.0" - jsdom@^20.0.0: version "20.0.3" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-20.0.3.tgz#886a41ba1d4726f67a8858028c99489fed6ad4db" @@ -13937,7 +13816,7 @@ log-update@^2.3.0: cli-cursor "^2.0.0" wrap-ansi "^3.0.1" -loose-envify@^1.0.0, loose-envify@^1.1.0: +loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -13963,7 +13842,7 @@ lru-cache@6.0.0, lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^10.0.1, lru-cache@^10.2.0: +lru-cache@^10.0.1, lru-cache@^10.2.0, lru-cache@^10.2.2: version "10.2.2" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.2.tgz#48206bc114c1252940c41b25b41af5b545aca878" integrity sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ== @@ -13987,13 +13866,6 @@ magic-string@0.30.0: dependencies: "@jridgewell/sourcemap-codec" "^1.4.13" -magic-string@0.30.5: - version "0.30.5" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.5.tgz#1994d980bd1c8835dc6e78db7cbd4ae4f24746f9" - integrity sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA== - dependencies: - "@jridgewell/sourcemap-codec" "^1.4.15" - magic-string@0.30.8: version "0.30.8" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.8.tgz#14e8624246d2bedba70d5462aa99ac9681844613" @@ -14001,7 +13873,7 @@ magic-string@0.30.8: dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" -magic-string@^0.30.5, magic-string@~0.30.2: +magic-string@~0.30.2: version "0.30.10" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.10.tgz#123d9c41a0cb5640c892b041d4cfb3bd0aa4b39e" integrity sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ== @@ -14998,12 +14870,12 @@ nwsapi@^2.2.2: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.9.tgz#7f3303218372db2e9f27c27766bcfc59ae7e61c6" integrity sha512-2f3F0SEEer8bBu0dsNCFF50N0cTThV1nWFYcEYFZttdW0lDAoybv9cQoK7X7/68Z89S7FoRrVjP1LPX4XRf9vg== -nx@18.3.3: - version "18.3.3" - resolved "https://registry.yarnpkg.com/nx/-/nx-18.3.3.tgz#ab96811961b631efd4f0c83550e92f7b0a625e83" - integrity sha512-GqC5ANfTWV6SFbgquZwuRMI2Z2nO0c0Yx4JzM3x32aJOgXsmRml3WcV0a5648bIXSen34gylHYl2EHaxVWkzNQ== +nx@19.0.1: + version "19.0.1" + resolved "https://registry.yarnpkg.com/nx/-/nx-19.0.1.tgz#7f360a10e2498581921d4716aeb9255cb850763b" + integrity sha512-zhXlXv9fbkTOJe4tlwwWw1dLCbSszvLJQmktUW8JS7ezuT1bWMYgdqIMZNRPpgQkU5ryC+ahs4yTBDk07kdWRw== dependencies: - "@nrwl/tao" "18.3.3" + "@nrwl/tao" "19.0.1" "@yarnpkg/lockfile" "^1.1.0" "@yarnpkg/parsers" "3.0.0-rc.46" "@zkochan/js-yaml" "0.0.6" @@ -15038,16 +14910,16 @@ nx@18.3.3: yargs "^17.6.2" yargs-parser "21.1.1" optionalDependencies: - "@nx/nx-darwin-arm64" "18.3.3" - "@nx/nx-darwin-x64" "18.3.3" - "@nx/nx-freebsd-x64" "18.3.3" - "@nx/nx-linux-arm-gnueabihf" "18.3.3" - "@nx/nx-linux-arm64-gnu" "18.3.3" - "@nx/nx-linux-arm64-musl" "18.3.3" - "@nx/nx-linux-x64-gnu" "18.3.3" - "@nx/nx-linux-x64-musl" "18.3.3" - "@nx/nx-win32-arm64-msvc" "18.3.3" - "@nx/nx-win32-x64-msvc" "18.3.3" + "@nx/nx-darwin-arm64" "19.0.1" + "@nx/nx-darwin-x64" "19.0.1" + "@nx/nx-freebsd-x64" "19.0.1" + "@nx/nx-linux-arm-gnueabihf" "19.0.1" + "@nx/nx-linux-arm64-gnu" "19.0.1" + "@nx/nx-linux-arm64-musl" "19.0.1" + "@nx/nx-linux-x64-gnu" "19.0.1" + "@nx/nx-linux-x64-musl" "19.0.1" + "@nx/nx-win32-arm64-msvc" "19.0.1" + "@nx/nx-win32-x64-msvc" "19.0.1" nypm@^0.3.8: version "0.3.8" @@ -15075,20 +14947,12 @@ object-inspect@^1.13.1: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== -object-is@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.6.tgz#1a6a53aed2dd8f7e6775ff870bea58545956ab07" - integrity sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object.assign@^4.1.4, object.assign@^4.1.5: +object.assign@^4.1.5: version "4.1.5" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== @@ -16095,6 +15959,15 @@ prompts@^2.0.1, prompts@^2.4.0: kleur "^3.0.3" sisteransi "^1.0.5" +prop-types@^15.7.2: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" @@ -16277,6 +16150,16 @@ react-dom@18.2.0: loose-envify "^1.1.0" scheduler "^0.23.0" +react-inspector@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-6.0.2.tgz#aa3028803550cb6dbd7344816d5c80bf39d07e9d" + integrity sha512-x+b7LxhmHXjHoU/VrFAzw5iutsILRoYyDq97EDYdFpPLcvqtEzk4ZSZSQjnFPbr5T57tLXnHcqFYoN1pI6u8uQ== + +react-is@^16.13.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + react-is@^18.0.0: version "18.3.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" @@ -16400,7 +16283,7 @@ recast@^0.21.0: source-map "~0.6.1" tslib "^2.0.1" -recast@^0.23.1, recast@^0.23.3: +recast@^0.23.1: version "0.23.6" resolved "https://registry.yarnpkg.com/recast/-/recast-0.23.6.tgz#198fba74f66143a30acc81929302d214ce4e3bfa" integrity sha512-9FHoNjX1yjuesMwuthAmPKabxYQdOgihFYmT5ebXfYGBcnqXZf3WOVz+5foEZ8Y83P4ZY6yQD5GMmtV+pgCCAQ== @@ -16920,32 +16803,10 @@ semver-dsl@^1.0.1: dependencies: semver "^5.3.0" -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.6.0: - version "5.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - -semver@7.6.0: - version "7.6.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.0.tgz#1a46a4db4bffcccd97b743b5005c8325f23d4e2d" - integrity sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg== - dependencies: - lru-cache "^6.0.0" - -semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0: - version "7.6.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.1.tgz#60bfe090bf907a25aa8119a72b9f90ef7ca281b2" - integrity sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA== - -semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0, semver@^6.3.1: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@~7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== +"semver@2 || 3 || 4 || 5", semver@7.3.2, semver@7.6.0, semver@7.x, semver@^5.3.0, semver@^5.6.0, semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0, semver@^6.3.1, semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@~7.0.0: + version "7.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" + integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== send@0.18.0: version "0.18.0" @@ -18445,7 +18306,7 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -util@^0.12.4, util@^0.12.5: +util@^0.12.4: version "0.12.5" resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== From 3be31da35fc1423f0c3902e2a64b71a8b900464e Mon Sep 17 00:00:00 2001 From: Dan Date: Thu, 9 May 2024 11:52:05 +0200 Subject: [PATCH 199/203] Fix Calculation --- .../src/app/portfolio/calculator/twr/portfolio-calculator.ts | 4 ++-- apps/api/src/app/portfolio/portfolio.service.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index 3406d1b8a..c5ed98543 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -339,7 +339,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { const datesWithOrders = {}; for (const { date, type } of orders) { - if (['BUY', 'SELL'].includes(type)) { + if (['BUY', 'SELL', 'STAKE'].includes(type)) { datesWithOrders[date] = true; } } @@ -459,7 +459,7 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { } if (order.type === 'STAKE') { - order.unitPrice = marketSymbolMap[order.date]?.[symbol]; + order.unitPrice = marketSymbolMap[order.date]?.[symbol] ?? new Big(0); } if (order.unitPrice) { diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index 82b775c40..feea4c67e 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -1817,7 +1817,7 @@ export class PortfolioService { cashDetailsWithExcludedAccounts.balanceInBaseCurrency ).minus(balanceInBaseCurrency); - excludedAccountsAndActivities = excludedBalanceInBaseCurrency + let excludedAccountsAndActivities = excludedBalanceInBaseCurrency .plus(totalOfExcludedActivities) .toNumber(); From 97ba28fe1c243ed013c6636ec980502cc31a5917 Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 10 May 2024 11:22:28 +0200 Subject: [PATCH 200/203] Readded TimeWeighted Performance --- .../portfolio-calculator.ts | 298 ++++++++++++++++++ .../portfolio-calculator.factory.ts | 17 +- .../calculator/portfolio-calculator.ts | 7 +- .../src/app/portfolio/portfolio.service.ts | 54 +++- .../historical-data-item.interface.ts | 1 + 5 files changed, 372 insertions(+), 5 deletions(-) create mode 100644 apps/api/src/app/portfolio/calculator/constantPortfolioReturn/portfolio-calculator.ts diff --git a/apps/api/src/app/portfolio/calculator/constantPortfolioReturn/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/constantPortfolioReturn/portfolio-calculator.ts new file mode 100644 index 000000000..87b28ab85 --- /dev/null +++ b/apps/api/src/app/portfolio/calculator/constantPortfolioReturn/portfolio-calculator.ts @@ -0,0 +1,298 @@ +import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; +import { parseDate, resetHours } from '@ghostfolio/common/helper'; +import { + HistoricalDataItem, + SymbolMetrics, + UniqueAsset +} from '@ghostfolio/common/interfaces'; +import { PortfolioSnapshot, TimelinePosition } from '@ghostfolio/common/models'; + +import { Big } from 'big.js'; +import { addDays, eachDayOfInterval } from 'date-fns'; + +import { PortfolioOrder } from '../../interfaces/portfolio-order.interface'; +import { TWRPortfolioCalculator } from '../twr/portfolio-calculator'; + +export class CPRPortfolioCalculator extends TWRPortfolioCalculator { + private holdings: { [date: string]: { [symbol: string]: Big } } = {}; + private holdingCurrencies: { [symbol: string]: string } = {}; + + protected calculateOverallPerformance( + positions: TimelinePosition[] + ): PortfolioSnapshot { + return super.calculateOverallPerformance(positions); + } + + protected getSymbolMetrics({ + dataSource, + end, + exchangeRates, + isChartMode = false, + marketSymbolMap, + start, + step = 1, + symbol + }: { + end: Date; + exchangeRates: { [dateString: string]: number }; + isChartMode?: boolean; + marketSymbolMap: { + [date: string]: { [symbol: string]: Big }; + }; + start: Date; + step?: number; + } & UniqueAsset): SymbolMetrics { + return super.getSymbolMetrics({ + dataSource, + end, + exchangeRates, + isChartMode, + marketSymbolMap, + start, + step, + symbol + }); + } + + public override async getChartData({ + end = new Date(Date.now()), + start, + step = 1 + }: { + end?: Date; + start: Date; + step?: number; + }): Promise { + const timelineHoldings = this.getHoldings(start, end); + const calculationDates = Object.keys(timelineHoldings) + .filter((date) => { + let parsed = parseDate(date); + parsed >= start && parsed <= end; + }) + .sort(); + let data: HistoricalDataItem[] = []; + + data.push({ + date: start.toDateString(), + netPerformanceInPercentage: 0, + netPerformanceInPercentageWithCurrencyEffect: 0, + investmentValueWithCurrencyEffect: 0, + netPerformance: 0, + netPerformanceWithCurrencyEffect: 0, + netWorth: 0, + totalAccountBalance: 0, + totalInvestment: 0, + totalInvestmentValueWithCurrencyEffect: 0, + value: 0, + valueWithCurrencyEffect: 0 + }); + + let totalInvestment = Object.keys( + timelineHoldings[start.toDateString()] + ).reduce((sum, holding) => { + return sum.plus( + timelineHoldings[start.toDateString()][holding].mul( + this.marketMap[start.toDateString()][holding] + ) + ); + }, new Big(0)); + + let previousNetPerformanceInPercentage = new Big(0); + let previousNetPerformanceInPercentageWithCurrencyEffect = new Big(0); + + for (let i = 1; i < calculationDates.length; i++) { + const date = calculationDates[i]; + const previousDate = calculationDates[i - 1]; + const holdings = timelineHoldings[previousDate]; + let newTotalInvestment = new Big(0); + let netPerformanceInPercentage = new Big(0); + let netPerformanceInPercentageWithCurrencyEffect = new Big(0); + + for (const holding of Object.keys(holdings)) { + ({ + netPerformanceInPercentage, + netPerformanceInPercentageWithCurrencyEffect, + newTotalInvestment + } = await this.handleSingleHolding( + previousDate, + holding, + date, + totalInvestment, + timelineHoldings, + netPerformanceInPercentage, + netPerformanceInPercentageWithCurrencyEffect, + newTotalInvestment + )); + totalInvestment = newTotalInvestment; + } + + previousNetPerformanceInPercentage = + previousNetPerformanceInPercentage.mul( + netPerformanceInPercentage.plus(1) + ); + previousNetPerformanceInPercentageWithCurrencyEffect = + previousNetPerformanceInPercentageWithCurrencyEffect.mul( + netPerformanceInPercentageWithCurrencyEffect.plus(1) + ); + + data.push({ + date, + netPerformanceInPercentage: + previousNetPerformanceInPercentage.toNumber(), + netPerformanceInPercentageWithCurrencyEffect: + previousNetPerformanceInPercentageWithCurrencyEffect.toNumber() + }); + } + + return data; + } + + private async handleSingleHolding( + previousDate: string, + holding: string, + date: string, + totalInvestment, + timelineHoldings: { [date: string]: { [symbol: string]: Big } }, + netPerformanceInPercentage, + netPerformanceInPercentageWithCurrencyEffect, + newTotalInvestment + ) { + const previousPrice = this.marketMap[previousDate][holding]; + const currentPrice = this.marketMap[date][holding]; + const previousPriceInBaseCurrency = + await this.exchangeRateDataService.toCurrencyAtDate( + previousPrice.toNumber(), + this.getCurrency(holding), + this.currency, + parseDate(previousDate) + ); + const portfolioWeight = totalInvestment + ? timelineHoldings[previousDate][holding] + .mul(previousPriceInBaseCurrency) + .div(totalInvestment) + : 0; + + netPerformanceInPercentage = netPerformanceInPercentage.plus( + currentPrice.div(previousPrice).minus(1).mul(portfolioWeight) + ); + + const priceInBaseCurrency = + await this.exchangeRateDataService.toCurrencyAtDate( + currentPrice.toNumber(), + this.getCurrency(holding), + this.currency, + parseDate(date) + ); + netPerformanceInPercentageWithCurrencyEffect = + netPerformanceInPercentageWithCurrencyEffect.plus( + new Big(priceInBaseCurrency) + .div(new Big(previousPriceInBaseCurrency)) + .minus(1) + .mul(portfolioWeight) + ); + + newTotalInvestment = newTotalInvestment.plus( + timelineHoldings[date][holding].mul(priceInBaseCurrency) + ); + return { + netPerformanceInPercentage, + netPerformanceInPercentageWithCurrencyEffect, + newTotalInvestment + }; + } + + private getCurrency(symbol: string) { + if (!this.holdingCurrencies[symbol]) { + this.holdingCurrencies[symbol] = this.activities.find( + (a) => a.SymbolProfile.symbol === symbol + ).SymbolProfile.currency; + } + + return this.holdingCurrencies[symbol]; + } + + private getHoldings(start: Date, end: Date) { + if ( + this.holdings && + Object.keys(this.holdings).some((h) => parseDate(h) >= end) && + Object.keys(this.holdings).some((h) => parseDate(h) <= start) + ) { + return this.holdings; + } + + this.computeHoldings(start, end); + return this.holdings; + } + + private computeHoldings(start: Date, end: Date) { + const investmentByDate = this.getInvestmentByDate(); + const transactionDates = Object.keys(investmentByDate).sort(); + let dates = eachDayOfInterval({ start, end }, { step: 1 }) + .map((date) => { + return resetHours(date); + }) + .sort((a, b) => a.getTime() - b.getTime()); + let currentHoldings: { [date: string]: { [symbol: string]: Big } } = {}; + + this.calculateInitialHoldings(investmentByDate, start, currentHoldings); + + for (let i = 1; i < dates.length; i++) { + const date = dates[i]; + const previousDate = dates[i - 1]; + if (transactionDates.some((d) => d === date.toDateString())) { + let holdings = { ...currentHoldings[previousDate.toDateString()] }; + investmentByDate[date.toDateString()].forEach((trade) => { + holdings[trade.SymbolProfile.symbol] = holdings[ + trade.SymbolProfile.symbol + ].plus(trade.quantity.mul(getFactor(trade.type))); + }); + currentHoldings[date.toDateString()] = holdings; + } else { + currentHoldings[date.toDateString()] = + currentHoldings[previousDate.toDateString()]; + } + } + + this.holdings = currentHoldings; + } + + private calculateInitialHoldings( + investmentByDate: { [date: string]: PortfolioOrder[] }, + start: Date, + currentHoldings: { [date: string]: { [symbol: string]: Big } } + ) { + const preRangeTrades = Object.keys(investmentByDate) + .filter((date) => resetHours(new Date(date)) <= start) + .map((date) => investmentByDate[date]) + .reduce((a, b) => a.concat(b), []) + .reduce((groupBySymbol, trade) => { + if (!groupBySymbol[trade.SymbolProfile.symbol]) { + groupBySymbol[trade.SymbolProfile.symbol] = []; + } + + groupBySymbol[trade.SymbolProfile.symbol].push(trade); + + return groupBySymbol; + }, {}); + + for (const symbol of Object.keys(preRangeTrades)) { + const trades: PortfolioOrder[] = preRangeTrades[symbol]; + let startQuantity = trades.reduce((sum, trade) => { + return sum.plus(trade.quantity.mul(getFactor(trade.type))); + }, new Big(0)); + currentHoldings[start.toDateString()][symbol] = startQuantity; + } + } + + private getInvestmentByDate(): { [date: string]: PortfolioOrder[] } { + return this.activities.reduce((groupedByDate, order) => { + if (!groupedByDate[order.date]) { + groupedByDate[order.date] = []; + } + + groupedByDate[order.date].push(order); + + return groupedByDate; + }, {}); + } +} diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts index 762415d1e..89181ea12 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.factory.ts @@ -8,13 +8,15 @@ import { DateRange, UserWithSettings } from '@ghostfolio/common/types'; import { Injectable } from '@nestjs/common'; +import { CPRPortfolioCalculator } from './constantPortfolioReturn/portfolio-calculator'; import { MWRPortfolioCalculator } from './mwr/portfolio-calculator'; import { PortfolioCalculator } from './portfolio-calculator'; import { TWRPortfolioCalculator } from './twr/portfolio-calculator'; export enum PerformanceCalculationType { MWR = 'MWR', // Money-Weighted Rate of Return - TWR = 'TWR' // Time-Weighted Rate of Return + TWR = 'TWR', // Time-Weighted Rate of Return + CPR = 'CPR' // Constant Portfolio Rate of Return } @Injectable() @@ -74,6 +76,19 @@ export class PortfolioCalculatorFactory { exchangeRateDataService: this.exchangeRateDataService, redisCacheService: this.redisCacheService }); + case PerformanceCalculationType.CPR: + return new CPRPortfolioCalculator({ + accountBalanceItems, + activities, + currency, + currentRateService: this.currentRateService, + dateRange, + useCache, + userId, + configurationService: this.configurationService, + exchangeRateDataService: this.exchangeRateDataService, + redisCacheService: this.redisCacheService + }); default: throw new Error('Invalid calculation type'); } diff --git a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts index 52ce1a6e9..274f4cffa 100644 --- a/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/portfolio-calculator.ts @@ -53,12 +53,12 @@ export abstract class PortfolioCalculator { protected activities: PortfolioOrder[]; private configurationService: ConfigurationService; - private currency: string; + protected currency: string; private currentRateService: CurrentRateService; private dataProviderInfos: DataProviderInfo[]; private dateRange: DateRange; private endDate: Date; - private exchangeRateDataService: ExchangeRateDataService; + protected exchangeRateDataService: ExchangeRateDataService; private redisCacheService: RedisCacheService; private snapshot: PortfolioSnapshot; private snapshotPromise: Promise; @@ -66,6 +66,7 @@ export abstract class PortfolioCalculator { private transactionPoints: TransactionPoint[]; private useCache: boolean; private userId: string; + protected marketMap: { [date: string]: { [symbol: string]: Big } } = {}; public constructor({ accountBalanceItems, @@ -288,6 +289,8 @@ export abstract class PortfolioCalculator { } } + this.marketMap = marketSymbolMap; + const endDateString = format(endDate, DATE_FORMAT); if (firstIndex > 0) { diff --git a/apps/api/src/app/portfolio/portfolio.service.ts b/apps/api/src/app/portfolio/portfolio.service.ts index feea4c67e..81601dbb3 100644 --- a/apps/api/src/app/portfolio/portfolio.service.ts +++ b/apps/api/src/app/portfolio/portfolio.service.ts @@ -740,7 +740,9 @@ export class PortfolioService { const portfolioCalculator = this.calculatorFactory.createCalculator({ userId, activities: orders.filter((order) => { - return ['BUY', 'DIVIDEND', 'ITEM', 'SELL'].includes(order.type); + return ['BUY', 'DIVIDEND', 'ITEM', 'SELL', 'STAKE'].includes( + order.type + ); }), calculationType: PerformanceCalculationType.TWR, currency: userCurrency, @@ -1279,10 +1281,20 @@ export class PortfolioService { let currentNetWorth = 0; - const items = await portfolioCalculator.getChart({ + let items = await portfolioCalculator.getChart({ dateRange }); + items = await this.calculatedTimeWeightedPerformance( + calculateTimeWeightedPerformance, + activities, + dateRange, + userId, + userCurrency, + filters, + items + ); + const itemOfToday = items.find(({ date }) => { return date === format(new Date(), DATE_FORMAT); }); @@ -1330,6 +1342,44 @@ export class PortfolioService { }; } + private async calculatedTimeWeightedPerformance( + calculateTimeWeightedPerformance: boolean, + activities: Activity[], + dateRange: string, + userId: string, + userCurrency: string, + filters: Filter[], + items: HistoricalDataItem[] + ) { + if (calculateTimeWeightedPerformance) { + const portfolioCalculatorCPR = this.calculatorFactory.createCalculator({ + activities, + dateRange, + userId, + calculationType: PerformanceCalculationType.CPR, + currency: userCurrency, + hasFilters: filters?.length > 0, + isExperimentalFeatures: + this.request.user.Settings.settings.isExperimentalFeatures + }); + let timeWeightedInvestmentItems = await portfolioCalculatorCPR.getChart({ + dateRange + }); + + items = items.map((item) => { + let matchingItem = timeWeightedInvestmentItems.find( + (timeWeightedInvestmentItem) => + timeWeightedInvestmentItem.date === item.date + ); + item.timeWeightedPerformance = matchingItem.netPerformanceInPercentage; + item.timeWeightedPerformanceWithCurrencyEffect = + matchingItem.netPerformanceInPercentageWithCurrencyEffect; + return item; + }); + } + return items; + } + @LogPerformance public async getReport(impersonationId: string): Promise { const userId = await this.getUserId(impersonationId, this.request.user.id); diff --git a/libs/common/src/lib/interfaces/historical-data-item.interface.ts b/libs/common/src/lib/interfaces/historical-data-item.interface.ts index a36206011..7f785e509 100644 --- a/libs/common/src/lib/interfaces/historical-data-item.interface.ts +++ b/libs/common/src/lib/interfaces/historical-data-item.interface.ts @@ -17,5 +17,6 @@ export interface HistoricalDataItem { value?: number; valueInPercentage?: number; timeWeightedPerformance?: number; + timeWeightedPerformanceWithCurrencyEffect?: number; valueWithCurrencyEffect?: number; } From 3bf3905a841bbf767512e5fd9c9d654ecc5546e6 Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 10 May 2024 12:02:36 +0200 Subject: [PATCH 201/203] Fix date strings --- .../portfolio-calculator.ts | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/apps/api/src/app/portfolio/calculator/constantPortfolioReturn/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/constantPortfolioReturn/portfolio-calculator.ts index 87b28ab85..e2c38b3c6 100644 --- a/apps/api/src/app/portfolio/calculator/constantPortfolioReturn/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/constantPortfolioReturn/portfolio-calculator.ts @@ -1,5 +1,5 @@ import { getFactor } from '@ghostfolio/api/helper/portfolio.helper'; -import { parseDate, resetHours } from '@ghostfolio/common/helper'; +import { DATE_FORMAT, parseDate, resetHours } from '@ghostfolio/common/helper'; import { HistoricalDataItem, SymbolMetrics, @@ -8,7 +8,7 @@ import { import { PortfolioSnapshot, TimelinePosition } from '@ghostfolio/common/models'; import { Big } from 'big.js'; -import { addDays, eachDayOfInterval } from 'date-fns'; +import { addDays, eachDayOfInterval, format } from 'date-fns'; import { PortfolioOrder } from '../../interfaces/portfolio-order.interface'; import { TWRPortfolioCalculator } from '../twr/portfolio-calculator'; @@ -71,9 +71,10 @@ export class CPRPortfolioCalculator extends TWRPortfolioCalculator { }) .sort(); let data: HistoricalDataItem[] = []; + const startString = format(start, DATE_FORMAT); data.push({ - date: start.toDateString(), + date: startString, netPerformanceInPercentage: 0, netPerformanceInPercentageWithCurrencyEffect: 0, investmentValueWithCurrencyEffect: 0, @@ -87,15 +88,16 @@ export class CPRPortfolioCalculator extends TWRPortfolioCalculator { valueWithCurrencyEffect: 0 }); - let totalInvestment = Object.keys( - timelineHoldings[start.toDateString()] - ).reduce((sum, holding) => { - return sum.plus( - timelineHoldings[start.toDateString()][holding].mul( - this.marketMap[start.toDateString()][holding] - ) - ); - }, new Big(0)); + let totalInvestment = Object.keys(timelineHoldings[startString]).reduce( + (sum, holding) => { + return sum.plus( + timelineHoldings[startString][holding].mul( + this.marketMap[startString][holding] + ) + ); + }, + new Big(0) + ); let previousNetPerformanceInPercentage = new Big(0); let previousNetPerformanceInPercentageWithCurrencyEffect = new Big(0); @@ -237,19 +239,18 @@ export class CPRPortfolioCalculator extends TWRPortfolioCalculator { this.calculateInitialHoldings(investmentByDate, start, currentHoldings); for (let i = 1; i < dates.length; i++) { - const date = dates[i]; - const previousDate = dates[i - 1]; - if (transactionDates.some((d) => d === date.toDateString())) { - let holdings = { ...currentHoldings[previousDate.toDateString()] }; - investmentByDate[date.toDateString()].forEach((trade) => { + const dateString = format(dates[i], DATE_FORMAT); + const previousDateString = format(dates[i - 1], DATE_FORMAT); + if (transactionDates.some((d) => d === dateString)) { + let holdings = { ...currentHoldings[previousDateString] }; + investmentByDate[dateString].forEach((trade) => { holdings[trade.SymbolProfile.symbol] = holdings[ trade.SymbolProfile.symbol ].plus(trade.quantity.mul(getFactor(trade.type))); }); - currentHoldings[date.toDateString()] = holdings; + currentHoldings[dateString] = holdings; } else { - currentHoldings[date.toDateString()] = - currentHoldings[previousDate.toDateString()]; + currentHoldings[dateString] = currentHoldings[previousDateString]; } } @@ -275,12 +276,14 @@ export class CPRPortfolioCalculator extends TWRPortfolioCalculator { return groupBySymbol; }, {}); + currentHoldings[format(start, DATE_FORMAT)] = {}; + for (const symbol of Object.keys(preRangeTrades)) { const trades: PortfolioOrder[] = preRangeTrades[symbol]; let startQuantity = trades.reduce((sum, trade) => { return sum.plus(trade.quantity.mul(getFactor(trade.type))); }, new Big(0)); - currentHoldings[start.toDateString()][symbol] = startQuantity; + currentHoldings[format(start, DATE_FORMAT)][symbol] = startQuantity; } } From cff8d62d74051e4fceeee93c1a431b89893b9554 Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 10 May 2024 12:24:13 +0200 Subject: [PATCH 202/203] Init holdings --- .../calculator/constantPortfolioReturn/portfolio-calculator.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/api/src/app/portfolio/calculator/constantPortfolioReturn/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/constantPortfolioReturn/portfolio-calculator.ts index e2c38b3c6..49faa0b28 100644 --- a/apps/api/src/app/portfolio/calculator/constantPortfolioReturn/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/constantPortfolioReturn/portfolio-calculator.ts @@ -244,6 +244,7 @@ export class CPRPortfolioCalculator extends TWRPortfolioCalculator { if (transactionDates.some((d) => d === dateString)) { let holdings = { ...currentHoldings[previousDateString] }; investmentByDate[dateString].forEach((trade) => { + holdings[trade.SymbolProfile.symbol] ??= new Big(0); holdings[trade.SymbolProfile.symbol] = holdings[ trade.SymbolProfile.symbol ].plus(trade.quantity.mul(getFactor(trade.type))); From 5225beab2339fadff8d3a6a195641a096cbf5958 Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 10 May 2024 12:53:22 +0200 Subject: [PATCH 203/203] Fix and remove tests --- ...folio-calculator-baln-buy-and-sell.spec.ts | 1 - ...folio-calculator-novn-buy-and-sell.spec.ts | 2 - .../calculator/twr/portfolio-calculator.ts | 32 ---- ...-calculator-novn-baln-buy-and-sell.spec.ts | 152 ------------------ 4 files changed, 187 deletions(-) delete mode 100644 apps/api/src/app/portfolio/portfolio-calculator-novn-baln-buy-and-sell.spec.ts diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts index 4a26ee838..53ebdf19f 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-baln-buy-and-sell.spec.ts @@ -174,7 +174,6 @@ describe('PortfolioCalculator', () => { symbol: 'BALN.SW', tags: [], timeWeightedInvestment: new Big('285.8'), - tags: undefined, timeWeightedInvestmentWithCurrencyEffect: new Big('285.8'), transactionCount: 2, valueInBaseCurrency: new Big('0') diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts index 5c65a9f23..902f710ee 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator-novn-buy-and-sell.spec.ts @@ -136,7 +136,6 @@ describe('PortfolioCalculator', () => { netPerformanceInPercentage: 0, netPerformanceInPercentageWithCurrencyEffect: 0, netPerformanceWithCurrencyEffect: 0, - timeWeightedPerformance: 0, netWorth: 151.6, totalAccountBalance: 0, totalInvestment: 151.6, @@ -152,7 +151,6 @@ describe('PortfolioCalculator', () => { netPerformanceInPercentage: 13.100263852242744, netPerformanceInPercentageWithCurrencyEffect: 13.100263852242744, netPerformanceWithCurrencyEffect: 19.86, - timeWeightedPerformance: 0, netWorth: 0, totalAccountBalance: 0, totalInvestment: 0, diff --git a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts index c5ed98543..69716e405 100644 --- a/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts +++ b/apps/api/src/app/portfolio/calculator/twr/portfolio-calculator.ts @@ -574,38 +574,6 @@ export class TWRPortfolioCalculator extends PortfolioCalculator { totalUnits = totalUnits.plus(order.quantity.mul(getFactor(order.type))); - if (order.type === 'DIVIDEND') { - const dividend = order.quantity.mul(order.unitPrice); - - totalDividend = totalDividend.plus(dividend); - totalDividendInBaseCurrency = totalDividendInBaseCurrency.plus( - dividend.mul(exchangeRateAtOrderDate ?? 1) - ); - } else if (order.type === 'INTEREST') { - const interest = order.quantity.mul(order.unitPrice); - - totalInterest = totalInterest.plus(interest); - totalInterestInBaseCurrency = totalInterestInBaseCurrency.plus( - interest.mul(exchangeRateAtOrderDate ?? 1) - ); - } else if (order.type === 'ITEM') { - const valuables = order.quantity.mul(order.unitPrice); - - totalValuables = totalValuables.plus(valuables); - totalValuablesInBaseCurrency = totalValuablesInBaseCurrency.plus( - valuables.mul(exchangeRateAtOrderDate ?? 1) - ); - } else if (order.type === 'LIABILITY') { - const liabilities = order.quantity.mul(order.unitPrice); - - totalLiabilities = totalLiabilities.plus(liabilities); - totalLiabilitiesInBaseCurrency = totalLiabilitiesInBaseCurrency.plus( - liabilities.mul(exchangeRateAtOrderDate ?? 1) - ); - } else if (order.type === 'STAKE') { - totalStakeRewards = totalStakeRewards.plus(order.quantity); - } - const valueOfInvestment = totalUnits.mul(order.unitPriceInBaseCurrency); const valueOfInvestmentWithCurrencyEffect = totalUnits.mul( diff --git a/apps/api/src/app/portfolio/portfolio-calculator-novn-baln-buy-and-sell.spec.ts b/apps/api/src/app/portfolio/portfolio-calculator-novn-baln-buy-and-sell.spec.ts deleted file mode 100644 index b56118b0c..000000000 --- a/apps/api/src/app/portfolio/portfolio-calculator-novn-baln-buy-and-sell.spec.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { CurrentRateService } from '@ghostfolio/api/app/portfolio/current-rate.service'; -import { ExchangeRateDataService } from '@ghostfolio/api/services/exchange-rate-data/exchange-rate-data.service'; -import { parseDate } from '@ghostfolio/common/helper'; - -import Big from 'big.js'; - -import { CurrentRateServiceMock } from './current-rate.service.mock'; -import { PortfolioCalculator } from './portfolio-calculator'; - -jest.mock('@ghostfolio/api/app/portfolio/current-rate.service', () => { - return { - // eslint-disable-next-line @typescript-eslint/naming-convention - CurrentRateService: jest.fn().mockImplementation(() => { - return CurrentRateServiceMock; - }) - }; -}); - -describe('PortfolioCalculator', () => { - let currentRateService: CurrentRateService; - let exchangeRateDataService: ExchangeRateDataService; - - beforeEach(() => { - currentRateService = new CurrentRateService(null, null, null, null); - - exchangeRateDataService = new ExchangeRateDataService( - null, - null, - null, - null - ); - }); - - describe('get current positions', () => { - it.only('with NOVN.SW and BALN.SW buy and sell', async () => { - const portfolioCalculator = new PortfolioCalculator({ - currentRateService, - exchangeRateDataService, - currency: 'CHF', - orders: [ - { - currency: 'CHF', - date: '2022-03-07', - dataSource: 'YAHOO', - fee: new Big(0), - name: 'Novartis AG', - quantity: new Big(2), - symbol: 'NOVN.SW', - type: 'BUY', - unitPrice: new Big(75.8) - }, - { - currency: 'CHF', - date: '2022-04-01', - dataSource: 'YAHOO', - fee: new Big(0), - name: 'Novartis AG', - quantity: new Big(0), - symbol: 'NOVN.SW', - type: 'BUY', - unitPrice: new Big(80.0) - }, - { - currency: 'CHF', - date: '2022-04-08', - dataSource: 'YAHOO', - fee: new Big(0), - name: 'Novartis AG', - quantity: new Big(2), - symbol: 'NOVN.SW', - type: 'SELL', - unitPrice: new Big(85.73) - }, - { - currency: 'CHF', - date: '2022-03-22', - dataSource: 'YAHOO', - fee: new Big(1.55), - name: 'Bâloise Holding AG', - quantity: new Big(2), - symbol: 'BALN.SW', - type: 'BUY', - unitPrice: new Big(142.9) - }, - { - currency: 'CHF', - date: '2022-04-01', - dataSource: 'YAHOO', - fee: new Big(0), - name: 'Bâloise Holding AG', - quantity: new Big(0), - symbol: 'BALN.SW', - type: 'BUY', - unitPrice: new Big(138) - }, - { - currency: 'CHF', - date: '2022-04-10', - dataSource: 'YAHOO', - fee: new Big(1.65), - name: 'Bâloise Holding AG', - quantity: new Big(2), - symbol: 'BALN.SW', - type: 'SELL', - unitPrice: new Big(136.6) - } - ] - }); - - portfolioCalculator.computeTransactionPoints(); - - const spy = jest - .spyOn(Date, 'now') - .mockImplementation(() => parseDate('2022-04-11').getTime()); - - const chartData = await portfolioCalculator.getChartData({ - start: parseDate('2022-03-07'), - calculateTimeWeightedPerformance: true - }); - - spy.mockRestore(); - - expect(chartData[0]).toEqual({ - date: '2022-03-07', - investmentValueWithCurrencyEffect: 151.6, - netPerformance: 0, - netPerformanceInPercentage: 0, - netPerformanceInPercentageWithCurrencyEffect: 0, - netPerformanceWithCurrencyEffect: 0, - timeWeightedPerformance: 0, - totalInvestment: 151.6, - totalInvestmentValueWithCurrencyEffect: 151.6, - value: 151.6, - valueWithCurrencyEffect: 151.6 - }); - - expect(chartData[chartData.length - 1]).toEqual({ - date: '2022-04-11', - investmentValueWithCurrencyEffect: 0, - netPerformance: 19.86, - netPerformanceInPercentage: 13.100263852242744, - netPerformanceInPercentageWithCurrencyEffect: 13.100263852242744, - netPerformanceWithCurrencyEffect: 19.86, - timeWeightedPerformance: 0, - totalInvestment: 0, - totalInvestmentValueWithCurrencyEffect: 0, - value: 0, - valueWithCurrencyEffect: 0 - }); - }); - }); -});