diff --git a/apps/console-lite-e2e/src/integration/market-trade.test.ts b/apps/console-lite-e2e/src/integration/market-trade.test.ts index 84fd1502c..c21110a13 100644 --- a/apps/console-lite-e2e/src/integration/market-trade.test.ts +++ b/apps/console-lite-e2e/src/integration/market-trade.test.ts @@ -270,7 +270,10 @@ describe('Market trade', { tags: '@smoke' }, () => { .find('dt') .eq(3) .should('have.text', 'Est. Fees (tDAI)'); - cy.get('#step-2-panel').find('dd').eq(3).should('have.text', '3 (3.03%)'); + cy.get('#step-2-panel') + .find('dd') + .eq(3) + .should('have.text', '3.00 (3.03%)'); } }); @@ -292,7 +295,10 @@ describe('Market trade', { tags: '@smoke' }, () => { cy.get('#step-3-panel').find('dd').eq(2).should('have.text', '98.93006'); - cy.get('#step-3-panel').find('dd').eq(3).should('have.text', '3 (3.03%)'); + cy.get('#step-3-panel') + .find('dd') + .eq(3) + .should('have.text', '3.00 (3.03%)'); cy.get('#step-3-panel').find('dd').eq(4).should('have.text', ' - '); diff --git a/apps/console-lite/src/app/components/deal-ticket/deal-ticket-steps.tsx b/apps/console-lite/src/app/components/deal-ticket/deal-ticket-steps.tsx index fca280017..9767a5a64 100644 --- a/apps/console-lite/src/app/components/deal-ticket/deal-ticket-steps.tsx +++ b/apps/console-lite/src/app/components/deal-ticket/deal-ticket-steps.tsx @@ -23,7 +23,6 @@ import { toDecimal, removeDecimal, addDecimalsFormatNumber, - addDecimalsNormalizeNumber, addDecimal, formatNumber, } from '@vegaprotocol/react-helpers'; @@ -156,7 +155,7 @@ export const DealTicketSteps = ({ market }: DealTicketMarketProps) => { .decimalPlaces(2) .toString(); - return `${addDecimalsNormalizeNumber( + return `${addDecimalsFormatNumber( estMargin.totalFees, assetDecimals )} (${formatNumber(addDecimal(percentage, assetDecimals), 2)}%)`; diff --git a/apps/explorer-e2e/src/integration/network.cy.js b/apps/explorer-e2e/src/integration/network.cy.js index 0e8f06af3..5afd69d36 100644 --- a/apps/explorer-e2e/src/integration/network.cy.js +++ b/apps/explorer-e2e/src/integration/network.cy.js @@ -148,7 +148,7 @@ context('Network parameters page', { tags: '@smoke' }, function () { const parameterName = network_parameter[0]; const parameterValue = network_parameter[1]; if (this.networkParameterFormat.fiveDecimal.includes(parameterName)) { - cy.convert_number_to_four_decimal(parameterValue) + cy.convert_number_to_max_four_decimal(parameterValue) .add_commas_to_number_if_large_enough() .then((parameterValueFormatted) => { cy.get(tableRows) @@ -179,7 +179,7 @@ context('Network parameters page', { tags: '@smoke' }, function () { if ( this.networkParameterFormat.eighteenDecimal.includes(parameterName) ) { - cy.convert_number_to_eighteen_decimal(parameterValue) + cy.convert_number_to_max_eighteen_decimal(parameterValue) .add_commas_to_number_if_large_enough() .then((parameterValueFormatted) => { cy.get(tableRows) @@ -212,7 +212,7 @@ context('Network parameters page', { tags: '@smoke' }, function () { const jsonFields = '.hljs'; const sideMenuBackground = '.absolute'; - // Engage dark mode if not allready set + // Engage dark mode if not already set cy.get(sideMenuBackground) .should('have.css', 'background-color') .then((background_color) => { diff --git a/apps/explorer-e2e/src/support/common.functions.js b/apps/explorer-e2e/src/support/common.functions.js index 40b324305..f38506960 100644 --- a/apps/explorer-e2e/src/support/common.functions.js +++ b/apps/explorer-e2e/src/support/common.functions.js @@ -68,12 +68,19 @@ Cypress.Commands.add( } ); -Cypress.Commands.add('convert_number_to_eighteen_decimal', (number) => { - // this will take a number like this : 700000000000000000000 - // and convert it to a number like this: 700.000000000000000000 - return BigNumber((number / 1000000000000000000).toString()).toFixed(18); +Cypress.Commands.add('convert_number_to_max_eighteen_decimal', (number) => { + // this will take a number like this : 700000000000000000001 + // and convert it to a number like this: 700.000000000000000001 + const value = BigNumber(number / 1000000000000000000).toString(); + return parseFloat(value).toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 18, + }); }); -Cypress.Commands.add('convert_number_to_four_decimal', (number) => { - return parseFloat(number).toFixed(4); +Cypress.Commands.add('convert_number_to_max_four_decimal', (number) => { + return parseFloat(number).toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 4, + }); }); diff --git a/apps/token-e2e/src/integration/flow/governance-flow.cy.js b/apps/token-e2e/src/integration/flow/governance-flow.cy.js index 2c9591ce4..b86d4b04d 100644 --- a/apps/token-e2e/src/integration/flow/governance-flow.cy.js +++ b/apps/token-e2e/src/integration/flow/governance-flow.cy.js @@ -644,7 +644,7 @@ context( it('Unable to create a proposal - when no tokens are associated', function () { cy.vega_wallet_teardown(); cy.get(vegaWalletAssociatedBalance, txTimeout).contains( - '0.000000000000000000', + '0.00', txTimeout ); cy.go_to_make_new_proposal(governanceProposalType.RAW); @@ -759,7 +759,7 @@ context( cy.get(vegaWallet).within(() => { cy.get(vegaWalletAssociatedBalance, txTimeout).should( 'contain', - '0.999900000000000000' + '0.9999' ); }); cy.navigate_to('governance'); @@ -804,7 +804,7 @@ context( cy.get(connectToVegaWalletButton).should('not.exist'); // 3001-VOTE-100 cy.get(vegaWalletAssociatedBalance, txTimeout).contains( - '1.000000000000000000', + '1.00', txTimeout ); cy.vote_for_proposal('against'); diff --git a/apps/token-e2e/src/integration/flow/staking-flow.cy.js b/apps/token-e2e/src/integration/flow/staking-flow.cy.js index f4bc50109..63aa2f35e 100644 --- a/apps/token-e2e/src/integration/flow/staking-flow.cy.js +++ b/apps/token-e2e/src/integration/flow/staking-flow.cy.js @@ -554,7 +554,7 @@ context( cy.get(vegaWallet).within(() => { cy.get(vegaWalletAssociatedBalance, txTimeout).should( 'contain', - '0.000000000000000000' + '0.00' ); }); @@ -608,7 +608,7 @@ context( cy.get(vegaWallet).within(() => { cy.get(vegaWalletAssociatedBalance, txTimeout).should( 'contain', - '0.000000000000000000' + '0.00' ); }); @@ -656,7 +656,7 @@ context( cy.get(vegaWallet).within(() => { cy.get(vegaWalletAssociatedBalance, txTimeout).should( 'contain', - '2.000000000000000000' + '2.00' ); }); @@ -819,7 +819,7 @@ context( cy.get(vegaWallet).within(() => { cy.get(vegaWalletAssociatedBalance, txTimeout).should( 'contain', - '12.000000000000000000' + '12.00' ); }); diff --git a/apps/token-e2e/src/integration/flow/token-association-flow.cy.js b/apps/token-e2e/src/integration/flow/token-association-flow.cy.js index d1442a6bc..6d583c13f 100644 --- a/apps/token-e2e/src/integration/flow/token-association-flow.cy.js +++ b/apps/token-e2e/src/integration/flow/token-association-flow.cy.js @@ -109,7 +109,7 @@ context( cy.get(ethWalletAssociatedBalances, txTimeout) .contains(vegaWalletPublicKeyShort) .parent() - .should('contain', '1,001.000000000000000000', txTimeout); + .should('contain', '1,001.00', txTimeout); cy.get(ethWalletTotalAssociatedBalance, txTimeout) .contains('1,001.00', txTimeout) @@ -118,7 +118,7 @@ context( cy.get(vegaWallet).within(() => { cy.get(vegaWalletAssociatedBalance, txTimeout).should( 'contain', - '1,001.000000000000000000' + '1,001.00' ); }); }); diff --git a/apps/token-e2e/src/integration/flow/withdrawal-flow.cy.js b/apps/token-e2e/src/integration/flow/withdrawal-flow.cy.js index 189197908..3e1bbadb7 100644 --- a/apps/token-e2e/src/integration/flow/withdrawal-flow.cy.js +++ b/apps/token-e2e/src/integration/flow/withdrawal-flow.cy.js @@ -79,7 +79,7 @@ context( cy.getByTestId(withdraw).should('be.visible').click(); cy.getByTestId(selectAsset).select(usdtName); cy.getByTestId(balanceAvailable, txTimeout).should('exist'); - cy.getByTestId(withdrawalThreshold).should('have.text', '100,000.00000T'); + cy.getByTestId(withdrawalThreshold).should('have.text', '100,000.00T'); cy.getByTestId(delayTime).should('have.text', 'None'); cy.getByTestId(amountInput).click().type('100'); cy.getByTestId(submitWithdrawalButton).click(); @@ -94,7 +94,7 @@ context( .should('have.attr', 'href') .and('contain', '/txs/'); cy.getByTestId(withdrawalAssetSymbol).should('have.text', usdcSymbol); - cy.getByTestId(withdrawalAmount).should('have.text', '100.00000'); + cy.getByTestId(withdrawalAmount).should('have.text', '100.00'); cy.getByTestId(withdrawalRecipient) .should('have.text', truncatedWithdrawalEthAddress) .and('have.attr', 'href') @@ -118,7 +118,7 @@ context( .parent() .within(() => { cy.get('[col-id="asset.symbol"]').should('have.text', usdcSymbol); - cy.get('[col-id="amount"]').should('have.text', '100.00000'); + cy.get('[col-id="amount"]').should('have.text', '100.00'); cy.get('[col-id="details.receiverAddress"]') .find('a') .should('have.attr', 'href') @@ -163,7 +163,7 @@ context( .parent() .within(() => { cy.get('[col-id="asset.symbol"]').should('have.text', usdcSymbol); - cy.get('[col-id="amount"]').should('have.text', '100.00000'); + cy.get('[col-id="amount"]').should('have.text', '100.00'); cy.get('[col-id="details.receiverAddress"]') .find('a') .should('have.attr', 'href') diff --git a/apps/token-e2e/src/integration/view/wallet-eth.cy.js b/apps/token-e2e/src/integration/view/wallet-eth.cy.js index 655206c24..2b2e4658b 100644 --- a/apps/token-e2e/src/integration/view/wallet-eth.cy.js +++ b/apps/token-e2e/src/integration/view/wallet-eth.cy.js @@ -141,7 +141,7 @@ context( cy.get(currencyValue) .should('be.visible') .invoke('text') - .should('match', /\d{0,3}(,\d{3})*\.\d{18}$/); + .should('match', /\d{0,3}(,\d{3})*\.\d{2}$/); }); }); @@ -210,7 +210,7 @@ context( cy.get(currencyValue) .should('be.visible') .invoke('text') - .should('match', /\d{0,3}(,\d{3})*\.\d{18}$/); + .should('match', /\d{0,3}(,\d{3})*\.\d{2}$/); }); }); diff --git a/apps/token-e2e/src/integration/view/wallet-vega.cy.js b/apps/token-e2e/src/integration/view/wallet-vega.cy.js index 53aab05c2..8b11c92a7 100644 --- a/apps/token-e2e/src/integration/view/wallet-vega.cy.js +++ b/apps/token-e2e/src/integration/view/wallet-vega.cy.js @@ -197,18 +197,14 @@ context( { tags: '@smoke' }, function () { cy.get(walletContainer).within(() => { - cy.get(currencyValue) - .should('be.visible') - .and('have.text', `0.000000000000000000`); + cy.get(currencyValue).should('be.visible').and('have.text', `0.00`); }); } ); it('should have Unstaked value visible', { tags: '@smoke' }, function () { cy.get(walletContainer).within(() => { - cy.get(vegaUnstaked) - .should('be.visible') - .and('have.text', `0.000000000000000000`); + cy.get(vegaUnstaked).should('be.visible').and('have.text', `0.00`); }); }); @@ -331,7 +327,7 @@ context( .contains(currency.id) .parent() .siblings() - .within(() => cy.contains_exactly('10.00000').should('be.visible')); + .within(() => cy.contains_exactly('10.00').should('be.visible')); cy.get(vegaWalletCurrencyTitle) .contains(currency.id) @@ -351,7 +347,7 @@ context( .contains(currency.id) .parent() .siblings() - .within(() => cy.contains_exactly('6.00000').should('be.visible')); + .within(() => cy.contains_exactly('6.00').should('be.visible')); cy.get(vegaWalletCurrencyTitle) .contains(currency.id) @@ -371,7 +367,7 @@ context( .contains(currency.id) .parent() .siblings() - .within(() => cy.contains_exactly('8.00000').should('be.visible')); + .within(() => cy.contains_exactly('8.00').should('be.visible')); cy.get(vegaWalletCurrencyTitle) .contains(currency.id) @@ -391,7 +387,7 @@ context( .contains(currency.id) .parent() .siblings() - .within(() => cy.contains_exactly('2.00000').should('be.visible')); + .within(() => cy.contains_exactly('2.00').should('be.visible')); cy.get(vegaWalletCurrencyTitle) .contains(currency.id) diff --git a/apps/token-e2e/src/support/staking.functions.js b/apps/token-e2e/src/support/staking.functions.js index 2ad5bb590..8a35364e5 100644 --- a/apps/token-e2e/src/support/staking.functions.js +++ b/apps/token-e2e/src/support/staking.functions.js @@ -208,7 +208,7 @@ Cypress.Commands.add( if (parseFloat(unstakedBalance) != parseFloat(tokenAmount)) { cy.vega_wallet_teardown(); cy.get(vegaWalletAssociatedBalance, txTimeout).contains( - '0.000000000000000000', + '0.00', txTimeout ); cy.staking_page_associate_tokens(tokenAmount); diff --git a/apps/token-e2e/src/support/wallet-teardown.functions.js b/apps/token-e2e/src/support/wallet-teardown.functions.js index 9b94bb725..f023d8652 100644 --- a/apps/token-e2e/src/support/wallet-teardown.functions.js +++ b/apps/token-e2e/src/support/wallet-teardown.functions.js @@ -95,7 +95,7 @@ Cypress.Commands.add('vega_wallet_teardown', function () { cy.get(vegaWalletAssociatedBalance) .invoke('text') .then((balance) => { - if (balance != '0.000000000000000000') { + if (balance != '0.00') { cy.vega_wallet_teardown_vesting(this.vestingContract); cy.vega_wallet_teardown_staking(this.stakingBridgeContract); } @@ -105,7 +105,7 @@ Cypress.Commands.add('vega_wallet_teardown', function () { cy.get(vegaWalletContainer).within(() => { cy.get(vegaWalletAssociatedBalance, { timeout: transactionTimeout }).should( 'contain', - '0.000000000000000000', + '0.00', { timeout: transactionTimeout } ); }); diff --git a/apps/token/src/lib/format-number.spec.ts b/apps/token/src/lib/format-number.spec.ts index 32729253a..13dda7ae7 100644 --- a/apps/token/src/lib/format-number.spec.ts +++ b/apps/token/src/lib/format-number.spec.ts @@ -3,9 +3,9 @@ import { formatNumber } from './format-number'; describe('formatNumber and formatNumberPercentage', () => { it.each([ - { v: new BigNumber(123), d: 3, o: '123.000' }, + { v: new BigNumber(123), d: 3, o: '123.00' }, { v: new BigNumber(123.123), d: 3, o: '123.123' }, - { v: new BigNumber(123.123), d: 6, o: '123.123000' }, + { v: new BigNumber(123.123), d: 6, o: '123.123' }, { v: new BigNumber(123.123), d: 0, o: '123' }, { v: new BigNumber(123), d: undefined, o: '123.00' }, // it default to 2 decimal places { v: new BigNumber(30000), d: undefined, o: '30,000.00' }, diff --git a/apps/token/src/routes/staking/home/node-list.spec.tsx b/apps/token/src/routes/staking/home/node-list.spec.tsx index 45dc90245..6d4a5b389 100644 --- a/apps/token/src/routes/staking/home/node-list.spec.tsx +++ b/apps/token/src/routes/staking/home/node-list.spec.tsx @@ -240,11 +240,11 @@ describe('Nodes list', () => { expect( grid.querySelector('[role="gridcell"][col-id="stakeScore"]') - ).toHaveTextContent('0.23010'); + ).toHaveTextContent('0.2301'); expect( grid.querySelector('[role="gridcell"][col-id="performanceScore"]') - ).toHaveTextContent('1.00000'); + ).toHaveTextContent('1.00'); expect( grid.querySelector('[role="gridcell"][col-id="votingPower"]') diff --git a/apps/trading-e2e/src/integration/trading-accounts.cy.ts b/apps/trading-e2e/src/integration/trading-accounts.cy.ts index f66cfce08..1adbdb7e8 100644 --- a/apps/trading-e2e/src/integration/trading-accounts.cy.ts +++ b/apps/trading-e2e/src/integration/trading-accounts.cy.ts @@ -28,6 +28,6 @@ describe('accounts', { tags: '@smoke' }, () => { cy.getByTestId('tab-accounts') .get(tradingAccountRowId) .find('[col-id="deposited"]') - .should('have.text', '1,000'); + .should('have.text', '1,000.00'); }); }); diff --git a/apps/trading-e2e/src/integration/withdraw.cy.ts b/apps/trading-e2e/src/integration/withdraw.cy.ts index a09438e15..e0d14c0eb 100644 --- a/apps/trading-e2e/src/integration/withdraw.cy.ts +++ b/apps/trading-e2e/src/integration/withdraw.cy.ts @@ -51,7 +51,7 @@ describe('withdraw', { tags: '@smoke' }, () => { ); }); it('max amount', () => { - selectAsset(asset2Name); // Will be above maximum because the vega wallet doesnt have any collateral + selectAsset(asset2Name); // Will be above maximum because the vega wallet doesn't have any collateral cy.get(amountField).clear().type('1001', { delay: 100 }); cy.getByTestId(submitWithdrawBtn).click(); cy.get('[data-testid="input-error-text"]').should( @@ -81,17 +81,14 @@ describe('withdraw', { tags: '@smoke' }, () => { 'contain.text', 'Balance available' ); - cy.getByTestId('BALANCE_AVAILABLE_value').should( - 'have.text', - '1,000.00000' - ); + cy.getByTestId('BALANCE_AVAILABLE_value').should('have.text', '1,000.00'); cy.getByTestId('WITHDRAWAL_THRESHOLD_label').should( 'contain.text', 'Delayed withdrawal threshold' ); cy.getByTestId('WITHDRAWAL_THRESHOLD_value').should( 'contain.text', - '100.00000' + '100.00' ); cy.getByTestId('DELAY_TIME_label').should('contain.text', 'Delay time'); cy.getByTestId('DELAY_TIME_value').should('have.text', 'None'); diff --git a/apps/trading/client-pages/liquidity/liquidity.tsx b/apps/trading/client-pages/liquidity/liquidity.tsx index 08fa95b03..70ee0fff7 100644 --- a/apps/trading/client-pages/liquidity/liquidity.tsx +++ b/apps/trading/client-pages/liquidity/liquidity.tsx @@ -6,7 +6,7 @@ import { } from '@vegaprotocol/liquidity'; import { tooltipMapping } from '@vegaprotocol/market-info'; import { - addDecimalsNormalizeNumber, + addDecimalsFormatNumber, NetworkParams, t, useDataProvider, @@ -151,7 +151,7 @@ export const Liquidity = () => { >
{targetStake - ? `${addDecimalsNormalizeNumber( + ? `${addDecimalsFormatNumber( targetStake, assetDecimalPlaces ?? 0 )} ${symbol}` @@ -164,7 +164,7 @@ export const Liquidity = () => { >
{suppliedStake - ? `${addDecimalsNormalizeNumber( + ? `${addDecimalsFormatNumber( suppliedStake, assetDecimalPlaces ?? 0 )} ${symbol}` diff --git a/apps/trading/components/select-market/select-market-columns.tsx b/apps/trading/components/select-market/select-market-columns.tsx index 2a9480e78..fe64cd4f0 100644 --- a/apps/trading/components/select-market/select-market-columns.tsx +++ b/apps/trading/components/select-market/select-market-columns.tsx @@ -7,7 +7,7 @@ import { calcCandleVolume, } from '@vegaprotocol/market-list'; import { - addDecimalsNormalizeNumber, + addDecimalsFormatNumber, PriceCell, signedNumberCssClass, t, @@ -251,7 +251,7 @@ export const columns = ( value: market.data?.markPrice ? ( {openVolume && - addDecimalsNormalizeNumber( - openVolume, - market.positionDecimalPlaces - )} + addDecimalsFormatNumber(openVolume, market.positionDecimalPlaces)}

), className: `${cellClassNames} hidden xxl:table-cell font-mono`, diff --git a/libs/accounts/src/lib/accounts-table.spec.tsx b/libs/accounts/src/lib/accounts-table.spec.tsx index 46ef9c6e0..a4649e998 100644 --- a/libs/accounts/src/lib/accounts-table.spec.tsx +++ b/libs/accounts/src/lib/accounts-table.spec.tsx @@ -55,8 +55,8 @@ describe('AccountsTable', () => { const cells = await screen.findAllByRole('gridcell'); const expectedValues = [ 'tBTC', - '1,256', - '1,2561,256', + '1,256.00', + '1,256.001,256.00', 'Breakdown', 'Deposit', ]; diff --git a/libs/accounts/src/lib/accounts-table.tsx b/libs/accounts/src/lib/accounts-table.tsx index 58f093db9..04b774c95 100644 --- a/libs/accounts/src/lib/accounts-table.tsx +++ b/libs/accounts/src/lib/accounts-table.tsx @@ -2,7 +2,7 @@ import { forwardRef, useState } from 'react'; import type { ValueFormatterParams } from 'ag-grid-community'; import type { Asset } from '@vegaprotocol/assets'; import { - addDecimalsNormalizeNumber, + addDecimalsFormatNumber, isNumeric, t, } from '@vegaprotocol/react-helpers'; @@ -38,8 +38,8 @@ export const progressBarValueFormatter = ({ const max = BigInt(data.deposited); const range = max > min ? max : min; return { - low: addDecimalsNormalizeNumber(min.toString(), data.asset.decimals, 4), - high: addDecimalsNormalizeNumber(mid.toString(), data.asset.decimals, 4), + low: addDecimalsFormatNumber(min.toString(), data.asset.decimals, 4), + high: addDecimalsFormatNumber(mid.toString(), data.asset.decimals, 4), value: range ? Number((min * BigInt(100)) / range) : 0, intent: Intent.Warning, }; @@ -125,7 +125,7 @@ export const AccountTable = forwardRef( data && data.asset && isNumeric(value) && - addDecimalsNormalizeNumber(value, data.asset.decimals) + addDecimalsFormatNumber(value, data.asset.decimals) } maxWidth={300} /> diff --git a/libs/accounts/src/lib/breakdown-table.spec.tsx b/libs/accounts/src/lib/breakdown-table.spec.tsx index b9647bb37..1adc85e8b 100644 --- a/libs/accounts/src/lib/breakdown-table.spec.tsx +++ b/libs/accounts/src/lib/breakdown-table.spec.tsx @@ -51,9 +51,9 @@ describe('BreakdownTable', () => { const expectedValues = [ 'Margin', 'BTCUSD Monthly (30 Jun 2022)', - '1,2561,256', - '1,256', - '1,256', + '1,256.001,256.00', + '1,256.00', + '1,256.00', ]; cells.forEach((cell, i) => { expect(cell).toHaveTextContent(expectedValues[i]); diff --git a/libs/assets/src/lib/asset-details-table.tsx b/libs/assets/src/lib/asset-details-table.tsx index 9c8e347de..e12fa31a7 100644 --- a/libs/assets/src/lib/asset-details-table.tsx +++ b/libs/assets/src/lib/asset-details-table.tsx @@ -1,4 +1,4 @@ -import { addDecimalsNormalizeNumber, t } from '@vegaprotocol/react-helpers'; +import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers'; import type { Schema } from '@vegaprotocol/types'; import type { KeyValueTableRowProps } from '@vegaprotocol/ui-toolkit'; import { @@ -43,7 +43,7 @@ type Mapping = { [key in string]: { value: string; tooltip: string } }; const num = (asset: Asset, n: string | undefined | null) => { if (typeof n === 'undefined' || n == null) return ''; - return addDecimalsNormalizeNumber(n, asset.decimals); + return addDecimalsFormatNumber(n, asset.decimals); }; export const rows: Rows = [ diff --git a/libs/deal-ticket/src/components/deal-ticket-validation/margin-warning.tsx b/libs/deal-ticket/src/components/deal-ticket-validation/margin-warning.tsx index 2c6d97933..621bb4230 100644 --- a/libs/deal-ticket/src/components/deal-ticket-validation/margin-warning.tsx +++ b/libs/deal-ticket/src/components/deal-ticket-validation/margin-warning.tsx @@ -1,4 +1,4 @@ -import { normalizeFormatNumber, t } from '@vegaprotocol/react-helpers'; +import { formatNumber, t } from '@vegaprotocol/react-helpers'; import { ButtonLink } from '@vegaprotocol/ui-toolkit'; import { DepositDialog, useDepositDialog } from '@vegaprotocol/deposits'; @@ -30,12 +30,11 @@ export const MarginWarning = ({ margin, balance, asset }: Props) => {

- {`${normalizeFormatNumber(margin, asset.decimals)} ${ - asset.symbol - } ${t('currently required')}, ${normalizeFormatNumber( - balance, - asset.decimals - )} ${asset.symbol} ${t('available')}`} + {`${formatNumber(margin, asset.decimals)} ${asset.symbol} ${t( + 'currently required' + )}, ${formatNumber(balance, asset.decimals)} ${asset.symbol} ${t( + 'available' + )}`}

diff --git a/libs/deal-ticket/src/components/trading-mode-tooltip/compile-grid-data.tsx b/libs/deal-ticket/src/components/trading-mode-tooltip/compile-grid-data.tsx index 7c3f4c861..bc7d15cc2 100644 --- a/libs/deal-ticket/src/components/trading-mode-tooltip/compile-grid-data.tsx +++ b/libs/deal-ticket/src/components/trading-mode-tooltip/compile-grid-data.tsx @@ -1,7 +1,7 @@ import { t, getDateTimeFormat, - addDecimalsNormalizeNumber, + addDecimalsFormatNumber, } from '@vegaprotocol/react-helpers'; import { Schema } from '@vegaprotocol/types'; import { Link as UILink } from '@vegaprotocol/ui-toolkit'; @@ -21,7 +21,7 @@ export const compileGridData = ( market.data?.trigger === Schema.AuctionTrigger.AUCTION_TRIGGER_LIQUIDITY; const formatStake = (value: string) => { - const formattedValue = addDecimalsNormalizeNumber( + const formattedValue = addDecimalsFormatNumber( value, market.tradableInstrument.instrument.product.settlementAsset.decimals ); @@ -77,7 +77,7 @@ export const compileGridData = ( value: market.data.indicativePrice && market.data.indicativePrice !== '0' ? `~ - ${addDecimalsNormalizeNumber( + ${addDecimalsFormatNumber( market.data.indicativePrice, market.decimalPlaces )}` @@ -91,7 +91,7 @@ export const compileGridData = ( value: market.data.indicativeVolume && market.data.indicativeVolume !== '0' ? '~' + - addDecimalsNormalizeNumber( + addDecimalsFormatNumber( market.data.indicativeVolume, market.positionDecimalPlaces ) diff --git a/libs/deal-ticket/src/hooks/use-fee-deal-ticket-details.tsx b/libs/deal-ticket/src/hooks/use-fee-deal-ticket-details.tsx index 8a1f81293..7c4ae58e7 100644 --- a/libs/deal-ticket/src/hooks/use-fee-deal-ticket-details.tsx +++ b/libs/deal-ticket/src/hooks/use-fee-deal-ticket-details.tsx @@ -1,7 +1,7 @@ import { FeesBreakdown } from '@vegaprotocol/market-info'; import { - addDecimalsNormalizeNumber, - normalizeFormatNumber, + addDecimalsFormatNumber, + formatNumber, t, } from '@vegaprotocol/react-helpers'; import { Schema } from '@vegaprotocol/types'; @@ -116,14 +116,14 @@ export const getFeeDetailsValues = ({ value: string | number | null | undefined ): string => { return value && !isNaN(Number(value)) - ? normalizeFormatNumber(value, market.decimalPlaces) + ? formatNumber(value, market.decimalPlaces) : '-'; }; const formatValueWithAssetDp = ( value: string | number | null | undefined ): string => { return value && !isNaN(Number(value)) - ? addDecimalsNormalizeNumber(value, assetDecimals) + ? addDecimalsFormatNumber(value, assetDecimals) : '-'; }; return [ diff --git a/libs/deal-ticket/src/hooks/use-order-closeout.spec.tsx b/libs/deal-ticket/src/hooks/use-order-closeout.spec.tsx index 0334a79e5..430bcd48e 100644 --- a/libs/deal-ticket/src/hooks/use-order-closeout.spec.tsx +++ b/libs/deal-ticket/src/hooks/use-order-closeout.spec.tsx @@ -82,7 +82,7 @@ describe('useOrderCloseOut', () => { ), } ); - expect(result.current).toEqual('1.00000'); + expect(result.current).toEqual('1.00'); }); it('should return proper empty value', () => { @@ -101,6 +101,6 @@ describe('useOrderCloseOut', () => { ), } ); - expect(result.current).toEqual('0.00000'); + expect(result.current).toEqual('0.00'); }); }); diff --git a/libs/fills/src/lib/fills-table.spec.tsx b/libs/fills/src/lib/fills-table.spec.tsx index 2c57ded42..d6358e77f 100644 --- a/libs/fills/src/lib/fills-table.spec.tsx +++ b/libs/fills/src/lib/fills-table.spec.tsx @@ -89,7 +89,7 @@ describe('FillsTable', () => { const cells = screen.getAllByRole('gridcell'); const expectedValues = [ buyerFill.market?.tradableInstrument.instrument.name || '', - '+3.00000', + '+3.00', '1.00 BTC', '3.00 BTC', 'Maker', @@ -126,7 +126,7 @@ describe('FillsTable', () => { const cells = screen.getAllByRole('gridcell'); const expectedValues = [ buyerFill.market?.tradableInstrument.instrument.name || '', - '-3.00000', + '-3.00', '1.00 BTC', '3.00 BTC', 'Taker', diff --git a/libs/liquidity/src/lib/liquidity-table.tsx b/libs/liquidity/src/lib/liquidity-table.tsx index fe431db76..24284c56e 100644 --- a/libs/liquidity/src/lib/liquidity-table.tsx +++ b/libs/liquidity/src/lib/liquidity-table.tsx @@ -1,6 +1,6 @@ import { forwardRef } from 'react'; import { - addDecimalsNormalizeNumber, + addDecimalsFormatNumber, formatNumberPercentage, getDateTimeFormat, t, @@ -41,18 +41,14 @@ export const LiquidityTable = forwardRef( ({ data, symbol = '', assetDecimalPlaces, stakeToCcySiskas }, ref) => { const assetDecimalsFormatter = ({ value }: ValueFormatterParams) => { if (!value) return '-'; - return `${addDecimalsNormalizeNumber(value, assetDecimalPlaces ?? 0, 5)}`; + return `${addDecimalsFormatNumber(value, assetDecimalPlaces ?? 0, 5)}`; }; const stakeToCcySiskasFormatter = ({ value }: ValueFormatterParams) => { if (!value) return '-'; const newValue = new BigNumber(value) .times(stakeToCcySiskas ?? 1) .toString(); - return `${addDecimalsNormalizeNumber( - newValue, - assetDecimalPlaces ?? 0, - 5 - )}`; + return `${addDecimalsFormatNumber(newValue, assetDecimalPlaces ?? 0, 5)}`; }; if (!data) return null; diff --git a/libs/market-info/src/components/fees-breakdown/fees-breakdown.tsx b/libs/market-info/src/components/fees-breakdown/fees-breakdown.tsx index f869c03cf..8dae39d0c 100644 --- a/libs/market-info/src/components/fees-breakdown/fees-breakdown.tsx +++ b/libs/market-info/src/components/fees-breakdown/fees-breakdown.tsx @@ -1,6 +1,6 @@ import { totalFeesPercentage } from '@vegaprotocol/market-list'; import { - addDecimalsNormalizeNumber, + addDecimalsFormatNumber, formatNumberPercentage, t, } from '@vegaprotocol/react-helpers'; @@ -70,7 +70,7 @@ export const FeesBreakdown = ({ .toString(); const formatValue = (value: string | number | null | undefined): string => { return value && !isNaN(Number(value)) - ? addDecimalsNormalizeNumber(value, decimals) + ? addDecimalsFormatNumber(value, decimals) : '-'; }; return ( diff --git a/libs/market-info/src/components/market-info/info-key-value-table.tsx b/libs/market-info/src/components/market-info/info-key-value-table.tsx index 97a19cd13..96d62d035 100644 --- a/libs/market-info/src/components/market-info/info-key-value-table.tsx +++ b/libs/market-info/src/components/market-info/info-key-value-table.tsx @@ -1,5 +1,5 @@ import { - addDecimalsNormalizeNumber, + addDecimalsFormatNumber, formatNumber, formatNumberPercentage, t, @@ -40,10 +40,7 @@ const Row = ({ return value; } if (decimalPlaces) { - return `${addDecimalsNormalizeNumber( - value, - decimalPlaces - )} ${assetSymbol}`; + return `${addDecimalsFormatNumber(value, decimalPlaces)} ${assetSymbol}`; } if (asPercentage) { return formatNumberPercentage(new BigNumber(value).times(100)); diff --git a/libs/orders/src/lib/components/order-list/order-edit-dialog.tsx b/libs/orders/src/lib/components/order-list/order-edit-dialog.tsx index 2668d2e46..ede004134 100644 --- a/libs/orders/src/lib/components/order-list/order-edit-dialog.tsx +++ b/libs/orders/src/lib/components/order-list/order-edit-dialog.tsx @@ -4,7 +4,7 @@ import { Size, getDateTimeFormat, addDecimal, - addDecimalsNormalizeNumber, + addDecimalsFormatNumber, } from '@vegaprotocol/react-helpers'; import { Schema } from '@vegaprotocol/types'; import { @@ -68,10 +68,7 @@ export const OrderEditDialog = ({

{t(`Price`)}

- {addDecimalsNormalizeNumber( - order.price, - order.market.decimalPlaces - )} + {addDecimalsFormatNumber(order.price, order.market.decimalPlaces)}

)} diff --git a/libs/positions/src/lib/positions-table.spec.tsx b/libs/positions/src/lib/positions-table.spec.tsx index 87861735b..b84b0ae84 100644 --- a/libs/positions/src/lib/positions-table.spec.tsx +++ b/libs/positions/src/lib/positions-table.spec.tsx @@ -92,7 +92,7 @@ it('add color and sign to amount, displays positive notional value', async () => expect(cells[2].classList.contains('text-vega-green-dark')).toBeTruthy(); expect(cells[2].classList.contains('text-vega-red-dark')).toBeFalsy(); expect(cells[2].textContent).toEqual('+100'); - expect(cells[1].textContent).toEqual('1,230'); + expect(cells[1].textContent).toEqual('1,230.0'); await act(async () => { result.rerender( @@ -102,7 +102,7 @@ it('add color and sign to amount, displays positive notional value', async () => expect(cells[2].classList.contains('text-vega-green-dark')).toBeFalsy(); expect(cells[2].classList.contains('text-vega-red-dark')).toBeTruthy(); expect(cells[2].textContent?.startsWith('-100')).toBeTruthy(); - expect(cells[1].textContent).toEqual('1,230'); + expect(cells[1].textContent).toEqual('1,230.0'); }); it('displays mark price', async () => { @@ -162,7 +162,7 @@ it('displays allocated margin', async () => { }); const cells = screen.getAllByRole('gridcell'); const cell = cells[8]; - expect(cell.textContent).toEqual('123,456'); + expect(cell.textContent).toEqual('123,456.00'); }); it('displays realised and unrealised PNL', async () => { diff --git a/libs/positions/src/lib/positions-table.tsx b/libs/positions/src/lib/positions-table.tsx index bda7600d7..3e8b4fc86 100644 --- a/libs/positions/src/lib/positions-table.tsx +++ b/libs/positions/src/lib/positions-table.tsx @@ -10,7 +10,7 @@ import type { import { ProgressBarCell } from '@vegaprotocol/ui-toolkit'; import { PriceFlashCell, - addDecimalsNormalizeNumber, + addDecimalsFormatNumber, volumePrefix, t, toBigNum, @@ -68,11 +68,11 @@ export const AmountCell = ({ valueFormatted }: AmountCellProps) => { className={classNames('text-right', signedNumberCssClass(openVolume))} > {volumePrefix( - addDecimalsNormalizeNumber(openVolume, positionDecimalPlaces) + addDecimalsFormatNumber(openVolume, positionDecimalPlaces) )}
- {addDecimalsNormalizeNumber(notional, marketDecimalPlaces)} + {addDecimalsFormatNumber(notional, marketDecimalPlaces)}
) : null; @@ -155,7 +155,7 @@ export const PositionsTable = forwardRef( }: VegaValueFormatterParams) => { return !data ? undefined - : addDecimalsNormalizeNumber( + : addDecimalsFormatNumber( data.notional, data.marketDecimalPlaces ); @@ -183,7 +183,7 @@ export const PositionsTable = forwardRef( return data?.openVolume === undefined ? undefined : volumePrefix( - addDecimalsNormalizeNumber( + addDecimalsFormatNumber( data.openVolume, data.positionDecimalPlaces ) @@ -222,7 +222,7 @@ export const PositionsTable = forwardRef( ) { return '-'; } - return addDecimalsNormalizeNumber( + return addDecimalsFormatNumber( data.markPrice, data.marketDecimalPlaces ); @@ -258,7 +258,7 @@ export const PositionsTable = forwardRef( if (!data) { return undefined; } - return addDecimalsNormalizeNumber( + return addDecimalsFormatNumber( data.averageEntryPrice, data.marketDecimalPlaces ); @@ -292,7 +292,7 @@ export const PositionsTable = forwardRef( if (!data) { return undefined; } - return addDecimalsNormalizeNumber( + return addDecimalsFormatNumber( data.liquidationPrice, data.marketDecimalPlaces ); @@ -340,7 +340,7 @@ export const PositionsTable = forwardRef( if (!data) { return undefined; } - return addDecimalsNormalizeNumber( + return addDecimalsFormatNumber( data.marginAccountBalance, data.decimals ); @@ -364,7 +364,7 @@ export const PositionsTable = forwardRef( }: VegaValueFormatterParams) => { return !data ? undefined - : addDecimalsNormalizeNumber(data.realisedPNL, data.decimals); + : addDecimalsFormatNumber(data.realisedPNL, data.decimals); }} cellRenderer="PriceFlashCell" headerTooltip={t( @@ -389,7 +389,7 @@ export const PositionsTable = forwardRef( }: VegaValueFormatterParams) => !data ? undefined - : addDecimalsNormalizeNumber(data.unrealisedPNL, data.decimals) + : addDecimalsFormatNumber(data.unrealisedPNL, data.decimals) } cellRenderer="PriceFlashCell" headerTooltip={t( diff --git a/libs/react-helpers/src/lib/format/number.spec.tsx b/libs/react-helpers/src/lib/format/number.spec.tsx index 17a0fc5b2..5a599d519 100644 --- a/libs/react-helpers/src/lib/format/number.spec.tsx +++ b/libs/react-helpers/src/lib/format/number.spec.tsx @@ -1,50 +1,33 @@ import BigNumber from 'bignumber.js'; import { - addDecimalsNormalizeNumber, + addDecimalsFormatNumber, compactNumber, formatNumber, formatNumberPercentage, isNumeric, - normalizeFormatNumber, toNumberParts, } from './number'; describe('number react-helpers', () => { it.each([ { v: new BigNumber(123000), d: 5, o: '1.23' }, - { v: new BigNumber(123000), d: 3, o: '123' }, - { v: new BigNumber(123000), d: 1, o: '12,300' }, + { v: new BigNumber(123000), d: 3, o: '123.00' }, + { v: new BigNumber(123000), d: 1, o: '12,300.0' }, { v: new BigNumber(123001), d: 2, o: '1,230.01' }, - { v: new BigNumber(123001000), d: 2, o: '1,230,010' }, + { v: new BigNumber(123001000), d: 2, o: '1,230,010.00' }, ])( - 'formats with addDecimalsNormalizeNumber given number correctly', + 'formats with addDecimalsFormatNumber given number correctly', ({ v, d, o }) => { - expect(addDecimalsNormalizeNumber(v.toString(), d)).toStrictEqual(o); + expect(addDecimalsFormatNumber(v.toString(), d)).toStrictEqual(o); } ); it.each([ - { v: new BigNumber(123.0), d: 3, o: '123' }, + { v: new BigNumber(123), d: 3, o: '123.00' }, { v: new BigNumber(123.123), d: 3, o: '123.123' }, { v: new BigNumber(123.6666), d: 3, o: '123.667' }, - { v: new BigNumber(123.003), d: 6, o: '123.003' }, - { v: new BigNumber(123.003), d: 0, o: '123' }, - { v: new BigNumber(123), d: undefined, o: '123' }, - { v: new BigNumber(30000), d: undefined, o: '30,000' }, - { v: new BigNumber(3.000001), d: undefined, o: '3' }, - ])( - `formats with normalizeFormatNumber given number correctly`, - ({ v, d, o }) => { - expect(normalizeFormatNumber(v, d)).toStrictEqual(o); - } - ); - - it.each([ - { v: new BigNumber(123), d: 3, o: '123.000' }, - { v: new BigNumber(123.123), d: 3, o: '123.123' }, - { v: new BigNumber(123.6666), d: 3, o: '123.667' }, - { v: new BigNumber(123.123), d: 6, o: '123.123000' }, + { v: new BigNumber(123.123), d: 6, o: '123.123' }, { v: new BigNumber(123.123), d: 0, o: '123' }, { v: new BigNumber(123), d: undefined, o: '123' }, { v: new BigNumber(30000), d: undefined, o: '30,000' }, @@ -54,9 +37,9 @@ describe('number react-helpers', () => { }); it.each([ - { v: new BigNumber(123), d: 3, o: '123.000%' }, + { v: new BigNumber(123), d: 3, o: '123.00%' }, { v: new BigNumber(123.123), d: 3, o: '123.123%' }, - { v: new BigNumber(123.123), d: 6, o: '123.123000%' }, + { v: new BigNumber(123.123), d: 6, o: '123.123%' }, { v: new BigNumber(123.123), d: 0, o: '123%' }, { v: new BigNumber(123), d: undefined, o: '123.00%' }, // it default to 2 decimal places { v: new BigNumber(30000), d: undefined, o: '30,000.00%' }, @@ -70,15 +53,15 @@ describe('toNumberParts', () => { it.each([ { v: null, d: 3, o: ['0', '000'] }, { v: undefined, d: 3, o: ['0', '000'] }, - { v: new BigNumber(123), d: 3, o: ['123', '000'] }, + { v: new BigNumber(123), d: 3, o: ['123', '00'] }, { v: new BigNumber(123.123), d: 3, o: ['123', '123'] }, - { v: new BigNumber(123.123), d: 6, o: ['123', '123000'] }, + { v: new BigNumber(123.123), d: 6, o: ['123', '123'] }, { v: new BigNumber(123.123), d: 0, o: ['123', ''] }, - { v: new BigNumber(123), d: undefined, o: ['123', '000000000000000000'] }, + { v: new BigNumber(123), d: undefined, o: ['123', '00'] }, { v: new BigNumber(30000), d: undefined, - o: ['30,000', '000000000000000000'], + o: ['30,000', '00'], }, ])('returns correct tuple given the different arguments', ({ v, d, o }) => { expect(toNumberParts(v, d)).toStrictEqual(o); diff --git a/libs/react-helpers/src/lib/format/number.tsx b/libs/react-helpers/src/lib/format/number.tsx index 700d02f4f..839bdacf4 100644 --- a/libs/react-helpers/src/lib/format/number.tsx +++ b/libs/react-helpers/src/lib/format/number.tsx @@ -6,6 +6,7 @@ import React from 'react'; import { getUserLocale } from './utils'; +const MIN_FRACTION_DIGITS = 2; const MAX_FRACTION_DIGITS = 20; export function toDecimal(numberOfDecimals: number) { @@ -44,16 +45,7 @@ export const getNumberFormat = memoize((digits: number) => { return new Intl.NumberFormat(getUserLocale()); } return new Intl.NumberFormat(getUserLocale(), { - minimumFractionDigits: Math.min(Math.max(0, digits), MAX_FRACTION_DIGITS), - maximumFractionDigits: Math.min(Math.max(0, digits), MAX_FRACTION_DIGITS), - }); -}); - -export const getMaximumDigitsNumberFormat = memoize((digits: number) => { - if (isNil(digits) || digits < 0) { - return new Intl.NumberFormat(getUserLocale()); - } - return new Intl.NumberFormat(getUserLocale(), { + minimumFractionDigits: Math.min(Math.max(0, digits), MIN_FRACTION_DIGITS), maximumFractionDigits: Math.min(Math.max(0, digits), MAX_FRACTION_DIGITS), }); }); @@ -76,20 +68,6 @@ export const formatNumber = ( return getNumberFormat(formatDecimals).format(Number(rawValue)); }; -/** normalizeFormatNumber will format the number with fixed decimals, but without insignificant trailing zeros - * @param rawValue - should be a number that is not outside the safe range fail as in https://mikemcl.github.io/bignumber.js/#toN - * @param formatDecimals - number of decimals to use - */ -export const normalizeFormatNumber = ( - rawValue: string | number | BigNumber, - formatDecimals = 0 -): string => { - const numberToFormat = getMaximumDigitsNumberFormat(formatDecimals).format( - new BigNumber(rawValue).toNumber() - ); - return numberToFormat; -}; - export const addDecimalsFormatNumber = ( rawValue: string | number, decimalPlaces: number, @@ -100,15 +78,6 @@ export const addDecimalsFormatNumber = ( return formatNumber(x, formatDecimals); }; -export const addDecimalsNormalizeNumber = ( - rawValue: string | number, - decimalPlaces: number, - formatDecimals: number = decimalPlaces -) => { - const x = addDecimal(rawValue, decimalPlaces); - return normalizeFormatNumber(x, formatDecimals); -}; - export const formatNumberPercentage = (value: BigNumber, decimals?: number) => { const decimalPlaces = typeof decimals === 'undefined' ? Math.max(value.dp() || 0, 2) : decimals; diff --git a/libs/react-helpers/src/lib/grid/size.tsx b/libs/react-helpers/src/lib/grid/size.tsx index 66dd62ac9..522740d47 100644 --- a/libs/react-helpers/src/lib/grid/size.tsx +++ b/libs/react-helpers/src/lib/grid/size.tsx @@ -1,7 +1,7 @@ import { Schema } from '@vegaprotocol/types'; import type { ICellRendererParams } from 'ag-grid-community'; import classNames from 'classnames'; -import { addDecimalsNormalizeNumber } from '../format'; +import { addDecimalsFormatNumber } from '../format'; export const Size = ({ value, @@ -26,7 +26,7 @@ export const Size = ({ : side === Schema.Side.SIDE_SELL ? '-' : ''} - {addDecimalsNormalizeNumber(value, positionDecimalPlaces)} + {addDecimalsFormatNumber(value, positionDecimalPlaces)} ); }; diff --git a/libs/ui-toolkit/src/components/price-change/price-change-cell.spec.tsx b/libs/ui-toolkit/src/components/price-change/price-change-cell.spec.tsx index 282387ecf..04c08e679 100644 --- a/libs/ui-toolkit/src/components/price-change/price-change-cell.spec.tsx +++ b/libs/ui-toolkit/src/components/price-change/price-change-cell.spec.tsx @@ -10,12 +10,12 @@ describe('PriceChangeCell', () => { /> ); expect(screen.getByText('-48.51%')).toBeInTheDocument(); - expect(screen.getByText('-22.100')).toBeInTheDocument(); + expect(screen.getByText('-22.10')).toBeInTheDocument(); }); it('renders correctly and calculates the price change without decimals', () => { render(); expect(screen.getByText('-48.51%')).toBeInTheDocument(); - expect(screen.getByText('-22,100.000')).toBeInTheDocument(); + expect(screen.getByText('-22,100.00')).toBeInTheDocument(); }); }); diff --git a/package.json b/package.json index 0a37ed319..2ac840259 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "test:all": "nx run-many --all --target=test", "build:all": "nx run-many --all --target=build", "lint:all": "nx run-many --all --target=lint", + "e2e:all": "nx run-many --all --target=e2e", "vegacapsule": "vegacapsule network bootstrap --config-path=../frontend-monorepo/vegacapsule/config.hcl" }, "engines": {