Compare commits

..

22 Commits

Author SHA1 Message Date
wiz
cb8fdb5e8d Hack docker frontend entrypoint to auto-enable lightning 2023-03-21 15:57:22 +09:00
softsimon
d337bf3ee2 Turn off LN if Macaroon is missing 2023-03-21 15:52:41 +09:00
softsimon
758e4d4f4c Disable LN on macaroon fail 2023-03-21 15:49:38 +09:00
softsimon
cd2bda4b49 Pull russian from transifex 2023-03-20 21:44:47 +09:00
wiz
493ea0641d Merge pull request #3487 from mempool/simon/catch-unhandled-lnd-axios-request
Catch exeptions in Lightning stats
2023-03-20 21:42:47 +09:00
wiz
ca1b6553c9 Merge branch 'master' into simon/catch-unhandled-lnd-axios-request 2023-03-20 20:53:41 +09:00
wiz
d479715d8e Merge pull request #3450 from mempool/nymkappa/configurable-timeout
Make core and lnd rpc calls timeout configurable
2023-03-20 20:50:51 +09:00
softsimon
e3109a8fec Catch exeptions in Lightning stats
fixes #3486
2023-03-20 20:46:11 +09:00
softsimon
e6bc5bef33 Updating russian i18n 2023-03-20 18:50:20 +09:00
softsimon
d82a7169b7 Pull from transifex 2023-03-20 18:28:15 +09:00
wiz
ba48b6f7ce Merge branch 'master' into nymkappa/configurable-timeout 2023-03-20 18:26:04 +09:00
wiz
8e1cf997f7 Merge pull request #3451 from mempool/simon/mining-difficulty-overflow-fix
Difficulty mining ellipsis fix
2023-03-20 18:25:51 +09:00
wiz
70d8548c92 Merge branch 'master' into simon/mining-difficulty-overflow-fix 2023-03-20 17:45:27 +09:00
wiz
cce7dd917f Merge branch 'master' into nymkappa/configurable-timeout 2023-03-20 17:38:40 +09:00
wiz
3dafb284a9 Merge pull request #3447 from mempool/hunicus/readme-video-poster
Add poster image for readme video
2023-03-20 17:37:21 +09:00
wiz
6a599a9a30 Merge pull request #3448 from mempool/simon/fix-missing-temp-cache-disk-cache
Fix missing temp cache in disk cache
2023-03-20 17:33:41 +09:00
softsimon
74fb292633 Difficulty mining ellipsis fix 2023-03-20 17:21:34 +09:00
nymkappa
c6e063ea2f Make lnd timeout configurable 2023-03-20 16:35:44 +09:00
nymkappa
81d563381a Make bitcoin core timeout configurable 2023-03-20 16:15:40 +09:00
softsimon
343d1345e2 Merge pull request #3445 from mempool/simon/liquid-blinding-tests-failing
Fixing broken liquid blinding tests
2023-03-20 15:46:41 +09:00
hunicus
1ed20a95df Add poster image for readme video
Also add line-break after video and remove screenshot.
2023-03-19 22:58:39 -04:00
softsimon
e27bdd3e2b Fixing broken liquid blinding tests 2023-03-19 17:30:06 +09:00
23 changed files with 152 additions and 77 deletions

View File

@@ -1,13 +1,13 @@
# The Mempool Open Source Project™ [![mempool](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/simple/ry4br7/master&style=flat-square)](https://dashboard.cypress.io/projects/ry4br7/runs)
https://user-images.githubusercontent.com/232186/222445818-234aa6c9-c233-4c52-b3f0-e32b8232893b.mp4
https://user-images.githubusercontent.com/93150691/226236121-375ea64f-b4a1-4cc0-8fad-a6fb33226840.mp4
<br>
Mempool is the fully-featured mempool visualizer, explorer, and API service running at [mempool.space](https://mempool.space/).
It is an open-source project developed and operated for the benefit of the Bitcoin community, with a focus on the emerging transaction fee market that is evolving Bitcoin into a multi-layer ecosystem.
![mempool](https://mempool.space/resources/screenshots/v2.4.0-dashboard.png)
# Installation Methods
Mempool can be self-hosted on a wide variety of your own hardware, ranging from a simple one-click installation on a Raspberry Pi full-node distro all the way to a robust production instance on a powerful FreeBSD server.

View File

@@ -34,7 +34,8 @@
"HOST": "127.0.0.1",
"PORT": 8332,
"USERNAME": "mempool",
"PASSWORD": "mempool"
"PASSWORD": "mempool",
"TIMEOUT": 60000
},
"ELECTRUM": {
"HOST": "127.0.0.1",
@@ -48,7 +49,8 @@
"HOST": "127.0.0.1",
"PORT": 8332,
"USERNAME": "mempool",
"PASSWORD": "mempool"
"PASSWORD": "mempool",
"TIMEOUT": 60000
},
"DATABASE": {
"ENABLED": true,
@@ -92,7 +94,8 @@
"LND": {
"TLS_CERT_PATH": "tls.cert",
"MACAROON_PATH": "readonly.macaroon",
"REST_API_URL": "https://localhost:8080"
"REST_API_URL": "https://localhost:8080",
"TIMEOUT": 10000
},
"CLIGHTNING": {
"SOCKET": "lightning-rpc"

View File

@@ -35,7 +35,8 @@
"HOST": "__CORE_RPC_HOST__",
"PORT": 15,
"USERNAME": "__CORE_RPC_USERNAME__",
"PASSWORD": "__CORE_RPC_PASSWORD__"
"PASSWORD": "__CORE_RPC_PASSWORD__",
"TIMEOUT": "__CORE_RPC_TIMEOUT__"
},
"ELECTRUM": {
"HOST": "__ELECTRUM_HOST__",
@@ -49,7 +50,8 @@
"HOST": "__SECOND_CORE_RPC_HOST__",
"PORT": 17,
"USERNAME": "__SECOND_CORE_RPC_USERNAME__",
"PASSWORD": "__SECOND_CORE_RPC_PASSWORD__"
"PASSWORD": "__SECOND_CORE_RPC_PASSWORD__",
"TIMEOUT": "__SECOND_CORE_RPC_TIMEOUT__"
},
"DATABASE": {
"ENABLED": false,
@@ -108,7 +110,8 @@
"LND": {
"TLS_CERT_PATH": "",
"MACAROON_PATH": "",
"REST_API_URL": "https://localhost:8080"
"REST_API_URL": "https://localhost:8080",
"TIMEOUT": 10000
},
"CLIGHTNING": {
"SOCKET": "__CLIGHTNING_SOCKET__"

View File

@@ -53,14 +53,16 @@ describe('Mempool Backend Config', () => {
HOST: '127.0.0.1',
PORT: 8332,
USERNAME: 'mempool',
PASSWORD: 'mempool'
PASSWORD: 'mempool',
TIMEOUT: 60000
});
expect(config.SECOND_CORE_RPC).toStrictEqual({
HOST: '127.0.0.1',
PORT: 8332,
USERNAME: 'mempool',
PASSWORD: 'mempool'
PASSWORD: 'mempool',
TIMEOUT: 60000
});
expect(config.DATABASE).toStrictEqual({

View File

@@ -7,7 +7,7 @@ const nodeRpcCredentials: BitcoinRpcCredentials = {
port: config.CORE_RPC.PORT,
user: config.CORE_RPC.USERNAME,
pass: config.CORE_RPC.PASSWORD,
timeout: 60000,
timeout: config.CORE_RPC.TIMEOUT,
};
export default new bitcoin.Client(nodeRpcCredentials);

View File

@@ -7,7 +7,7 @@ const nodeRpcCredentials: BitcoinRpcCredentials = {
port: config.SECOND_CORE_RPC.PORT,
user: config.SECOND_CORE_RPC.USERNAME,
pass: config.SECOND_CORE_RPC.PASSWORD,
timeout: 60000,
timeout: config.SECOND_CORE_RPC.TIMEOUT,
};
export default new bitcoin.Client(nodeRpcCredentials);

View File

@@ -4,21 +4,28 @@ import * as fs from 'fs';
import { AbstractLightningApi } from '../lightning-api-abstract-factory';
import { ILightningApi } from '../lightning-api.interface';
import config from '../../../config';
import logger from '../../../logger';
class LndApi implements AbstractLightningApi {
axiosConfig: AxiosRequestConfig = {};
constructor() {
if (config.LIGHTNING.ENABLED) {
if (!config.LIGHTNING.ENABLED) {
return;
}
try {
this.axiosConfig = {
headers: {
'Grpc-Metadata-macaroon': fs.readFileSync(config.LND.MACAROON_PATH).toString('hex')
'Grpc-Metadata-macaroon': fs.readFileSync(config.LND.MACAROON_PATH).toString('hex'),
},
httpsAgent: new Agent({
ca: fs.readFileSync(config.LND.TLS_CERT_PATH)
}),
timeout: 10000
timeout: config.LND.TIMEOUT
};
} catch (e) {
logger.err(`Could not initialize LND Macaroon/TLS Cert. Disabling LIGHTNING. ` + (e instanceof Error ? e.message : e));
config.LIGHTNING.ENABLED = false;
}
}

View File

@@ -52,6 +52,7 @@ interface IConfig {
TLS_CERT_PATH: string;
MACAROON_PATH: string;
REST_API_URL: string;
TIMEOUT: number;
};
CLIGHTNING: {
SOCKET: string;
@@ -66,12 +67,14 @@ interface IConfig {
PORT: number;
USERNAME: string;
PASSWORD: string;
TIMEOUT: number;
};
SECOND_CORE_RPC: {
HOST: string;
PORT: number;
USERNAME: string;
PASSWORD: string;
TIMEOUT: number;
};
DATABASE: {
ENABLED: boolean;
@@ -170,13 +173,15 @@ const defaults: IConfig = {
'HOST': '127.0.0.1',
'PORT': 8332,
'USERNAME': 'mempool',
'PASSWORD': 'mempool'
'PASSWORD': 'mempool',
'TIMEOUT': 60000,
},
'SECOND_CORE_RPC': {
'HOST': '127.0.0.1',
'PORT': 8332,
'USERNAME': 'mempool',
'PASSWORD': 'mempool'
'PASSWORD': 'mempool',
'TIMEOUT': 60000,
},
'DATABASE': {
'ENABLED': true,
@@ -216,6 +221,7 @@ const defaults: IConfig = {
'TLS_CERT_PATH': '',
'MACAROON_PATH': '',
'REST_API_URL': 'https://localhost:8080',
'TIMEOUT': 10000,
},
'CLIGHTNING': {
'SOCKET': '',

View File

@@ -215,11 +215,11 @@ class Server {
await lightningStatsUpdater.$startService();
await forensicsService.$startService();
} catch(e) {
logger.err(`Nodejs lightning backend crashed. Restarting in 1 minute. Reason: ${(e instanceof Error ? e.message : e)}`);
logger.err(`Exception in $runLightningBackend. Restarting in 1 minute. Reason: ${(e instanceof Error ? e.message : e)}`);
await Common.sleep$(1000 * 60);
this.$runLightningBackend();
};
}
}
setUpWebsocketHandling(): void {
if (this.wss) {

View File

@@ -22,12 +22,15 @@ class LightningStatsUpdater {
* Update the latest entry for each node every config.LIGHTNING.STATS_REFRESH_INTERVAL seconds
*/
private async $logStatsDaily(): Promise<void> {
const date = new Date();
Common.setDateMidnight(date);
const networkGraph = await lightningApi.$getNetworkGraph();
await LightningStatsImporter.computeNetworkStats(date.getTime() / 1000, networkGraph);
logger.debug(`Updated latest network stats`, logger.tags.ln);
try {
const date = new Date();
Common.setDateMidnight(date);
const networkGraph = await lightningApi.$getNetworkGraph();
await LightningStatsImporter.computeNetworkStats(date.getTime() / 1000, networkGraph);
logger.debug(`Updated latest network stats`, logger.tags.ln);
} catch (e) {
logger.err(`Exception in $logStatsDaily. Reason: ${(e instanceof Error ? e.message : e)}`);
}
}
}

View File

@@ -34,6 +34,7 @@ If you want to use different credentials, specify them in the `docker-compose.ym
CORE_RPC_PORT: "8332"
CORE_RPC_USERNAME: "customuser"
CORE_RPC_PASSWORD: "custompassword"
CORE_RPC_TIMEOUT: "60000"
```
The IP address in the example above refers to Docker's default gateway IP address so that the container can hit the `bitcoind` instance running on the host machine. If your setup is different, update it accordingly.
@@ -160,7 +161,8 @@ Corresponding `docker-compose.yml` overrides:
"HOST": "127.0.0.1",
"PORT": 8332,
"USERNAME": "mempool",
"PASSWORD": "mempool"
"PASSWORD": "mempool",
"TIMEOUT": 60000
},
```
@@ -172,6 +174,7 @@ Corresponding `docker-compose.yml` overrides:
CORE_RPC_PORT: ""
CORE_RPC_USERNAME: ""
CORE_RPC_PASSWORD: ""
CORE_RPC_TIMEOUT: 60000
...
```
@@ -221,7 +224,8 @@ Corresponding `docker-compose.yml` overrides:
"HOST": "127.0.0.1",
"PORT": 8332,
"USERNAME": "mempool",
"PASSWORD": "mempool"
"PASSWORD": "mempool",
"TIMEOUT": 60000
},
```
@@ -233,6 +237,7 @@ Corresponding `docker-compose.yml` overrides:
SECOND_CORE_RPC_PORT: ""
SECOND_CORE_RPC_USERNAME: ""
SECOND_CORE_RPC_PASSWORD: ""
SECOND_CORE_RPC_TIMEOUT: ""
...
```
@@ -405,6 +410,7 @@ Corresponding `docker-compose.yml` overrides:
"TLS_CERT_PATH": ""
"MACAROON_PATH": ""
"REST_API_URL": "https://localhost:8080"
"TIMEOUT": 10000
}
```
@@ -415,6 +421,7 @@ Corresponding `docker-compose.yml` overrides:
LND_TLS_CERT_PATH: ""
LND_MACAROON_PATH: ""
LND_REST_API_URL: "https://localhost:8080"
LND_TIMEOUT: 10000
...
```

View File

@@ -33,7 +33,8 @@
"HOST": "__CORE_RPC_HOST__",
"PORT": __CORE_RPC_PORT__,
"USERNAME": "__CORE_RPC_USERNAME__",
"PASSWORD": "__CORE_RPC_PASSWORD__"
"PASSWORD": "__CORE_RPC_PASSWORD__",
"TIMEOUT": __CORE_RPC_TIMEOUT__
},
"ELECTRUM": {
"HOST": "__ELECTRUM_HOST__",
@@ -47,7 +48,8 @@
"HOST": "__SECOND_CORE_RPC_HOST__",
"PORT": __SECOND_CORE_RPC_PORT__,
"USERNAME": "__SECOND_CORE_RPC_USERNAME__",
"PASSWORD": "__SECOND_CORE_RPC_PASSWORD__"
"PASSWORD": "__SECOND_CORE_RPC_PASSWORD__",
"TIMEOUT": __SECOND_CORE_RPC_TIMEOUT__
},
"DATABASE": {
"ENABLED": __DATABASE_ENABLED__,
@@ -84,7 +86,8 @@
"LND": {
"TLS_CERT_PATH": "__LND_TLS_CERT_PATH__",
"MACAROON_PATH": "__LND_MACAROON_PATH__",
"REST_API_URL": "__LND_REST_API_URL__"
"REST_API_URL": "__LND_REST_API_URL__",
"TIMEOUT": "__LND_TIMEOUT__"
},
"CLIGHTNING": {
"SOCKET": "__CLIGHTNING_SOCKET__"

View File

@@ -37,6 +37,7 @@ __CORE_RPC_HOST__=${CORE_RPC_HOST:=127.0.0.1}
__CORE_RPC_PORT__=${CORE_RPC_PORT:=8332}
__CORE_RPC_USERNAME__=${CORE_RPC_USERNAME:=mempool}
__CORE_RPC_PASSWORD__=${CORE_RPC_PASSWORD:=mempool}
__CORE_RPC_TIMEOUT__=${CORE_RPC_TIMEOUT:=60000}
# ELECTRUM
__ELECTRUM_HOST__=${ELECTRUM_HOST:=127.0.0.1}
@@ -51,6 +52,7 @@ __SECOND_CORE_RPC_HOST__=${SECOND_CORE_RPC_HOST:=127.0.0.1}
__SECOND_CORE_RPC_PORT__=${SECOND_CORE_RPC_PORT:=8332}
__SECOND_CORE_RPC_USERNAME__=${SECOND_CORE_RPC_USERNAME:=mempool}
__SECOND_CORE_RPC_PASSWORD__=${SECOND_CORE_RPC_PASSWORD:=mempool}
__SECOND_CORE_RPC_TIMEOUT__=${SECOND_CORE_RPC_TIMEOUT:=60000}
# DATABASE
__DATABASE_ENABLED__=${DATABASE_ENABLED:=true}
@@ -108,6 +110,7 @@ __LIGHTNING_LOGGER_UPDATE_INTERVAL__=${LIGHTNING_LOGGER_UPDATE_INTERVAL:=30}
__LND_TLS_CERT_PATH__=${LND_TLS_CERT_PATH:=""}
__LND_MACAROON_PATH__=${LND_MACAROON_PATH:=""}
__LND_REST_API_URL__=${LND_REST_API_URL:="https://localhost:8080"}
__LND_TIMEOUT__=${LND_TIMEOUT:=10000}
# CLN
__CLIGHTNING_SOCKET__=${CLIGHTNING_SOCKET:=""}
@@ -156,6 +159,7 @@ sed -i "s/__CORE_RPC_HOST__/${__CORE_RPC_HOST__}/g" mempool-config.json
sed -i "s/__CORE_RPC_PORT__/${__CORE_RPC_PORT__}/g" mempool-config.json
sed -i "s/__CORE_RPC_USERNAME__/${__CORE_RPC_USERNAME__}/g" mempool-config.json
sed -i "s/__CORE_RPC_PASSWORD__/${__CORE_RPC_PASSWORD__}/g" mempool-config.json
sed -i "s/__CORE_RPC_TIMEOUT__/${__CORE_RPC_TIMEOUT__}/g" mempool-config.json
sed -i "s/__ELECTRUM_HOST__/${__ELECTRUM_HOST__}/g" mempool-config.json
sed -i "s/__ELECTRUM_PORT__/${__ELECTRUM_PORT__}/g" mempool-config.json
@@ -167,6 +171,7 @@ sed -i "s/__SECOND_CORE_RPC_HOST__/${__SECOND_CORE_RPC_HOST__}/g" mempool-config
sed -i "s/__SECOND_CORE_RPC_PORT__/${__SECOND_CORE_RPC_PORT__}/g" mempool-config.json
sed -i "s/__SECOND_CORE_RPC_USERNAME__/${__SECOND_CORE_RPC_USERNAME__}/g" mempool-config.json
sed -i "s/__SECOND_CORE_RPC_PASSWORD__/${__SECOND_CORE_RPC_PASSWORD__}/g" mempool-config.json
sed -i "s/__SECOND_CORE_RPC_TIMEOUT__/${__SECOND_CORE_RPC_TIMEOUT__}/g" mempool-config.json
sed -i "s/__DATABASE_ENABLED__/${__DATABASE_ENABLED__}/g" mempool-config.json
sed -i "s/__DATABASE_HOST__/${__DATABASE_HOST__}/g" mempool-config.json
@@ -218,6 +223,7 @@ sed -i "s!__LIGHTNING_LOGGER_UPDATE_INTERVAL__!${__LIGHTNING_LOGGER_UPDATE_INTER
sed -i "s!__LND_TLS_CERT_PATH__!${__LND_TLS_CERT_PATH__}!g" mempool-config.json
sed -i "s!__LND_MACAROON_PATH__!${__LND_MACAROON_PATH__}!g" mempool-config.json
sed -i "s!__LND_REST_API_URL__!${__LND_REST_API_URL__}!g" mempool-config.json
sed -i "s!__LND_TIMEOUT__!${__LND_TIMEOUT__}!g" mempool-config.json
# CLN
sed -i "s!__CLIGHTNING_SOCKET__!${__CLIGHTNING_SOCKET__}!g" mempool-config.json

View File

@@ -10,6 +10,8 @@ cp /etc/nginx/nginx.conf /patch/nginx.conf
sed -i "s/__MEMPOOL_FRONTEND_HTTP_PORT__/${__MEMPOOL_FRONTEND_HTTP_PORT__}/g" /patch/nginx.conf
cat /patch/nginx.conf > /etc/nginx/nginx.conf
[ "${APP_LIGHTNING_NODE_PORT}" = "9735" ] && LIGHTNING=true
# Runtime overrides - read env vars defined in docker compose
__TESTNET_ENABLED__=${TESTNET_ENABLED:=false}

View File

@@ -158,10 +158,10 @@ describe('Liquid', () => {
it('show empty unblinded TX', () => {
cy.visit(`${basePath}/tx/f2f41c0850e8e7e3f1af233161fd596662e67c11ef10ed15943884186fbb7f46#blinded=`);
cy.waitForSkeletonGone();
cy.get('.table-tx-vin tr:nth-child(1)').should('have.class', '');
cy.get('.table-tx-vin tr:nth-child(1)').should('have.class', 'ng-star-inserted');
cy.get('.table-tx-vin tr:nth-child(1) .amount').should('contain.text', 'Confidential');
cy.get('.table-tx-vout tr:nth-child(1)').should('have.class', '');
cy.get('.table-tx-vout tr:nth-child(2)').should('have.class', '');
cy.get('.table-tx-vout tr:nth-child(1)').should('have.class', 'ng-star-inserted');
cy.get('.table-tx-vout tr:nth-child(2)').should('have.class', 'ng-star-inserted');
cy.get('.table-tx-vout tr:nth-child(1) .amount').should('contain.text', 'Confidential');
cy.get('.table-tx-vout tr:nth-child(2) .amount').should('contain.text', 'Confidential');
});
@@ -169,8 +169,8 @@ describe('Liquid', () => {
it('show invalid unblinded TX hex', () => {
cy.visit(`${basePath}/tx/f2f41c0850e8e7e3f1af233161fd596662e67c11ef10ed15943884186fbb7f46#blinded=123`);
cy.waitForSkeletonGone();
cy.get('.table-tx-vin tr').should('have.class', '');
cy.get('.table-tx-vout tr').should('have.class', '');
cy.get('.table-tx-vin tr').should('have.class', 'ng-star-inserted');
cy.get('.table-tx-vout tr').should('have.class', 'ng-star-inserted');
cy.get('.error-unblinded').contains('Error: Invalid blinding data (invalid hex)');
});

View File

@@ -109,10 +109,10 @@ describe('Liquid Testnet', () => {
it('show empty unblinded TX', () => {
cy.visit(`${basePath}/tx/c3d908ab77891e4c569b0df71aae90f4720b157019ebb20db176f4f9c4d626b8#blinded=`);
cy.waitForSkeletonGone();
cy.get('.table-tx-vin tr:nth-child(1)').should('have.class', '');
cy.get('.table-tx-vin tr:nth-child(1)').should('have.class', 'ng-star-inserted');
cy.get('.table-tx-vin tr:nth-child(1) .amount').should('contain.text', 'Confidential');
cy.get('.table-tx-vout tr:nth-child(1)').should('have.class', '');
cy.get('.table-tx-vout tr:nth-child(2)').should('have.class', '');
cy.get('.table-tx-vout tr:nth-child(1)').should('have.class', 'ng-star-inserted');
cy.get('.table-tx-vout tr:nth-child(2)').should('have.class', 'ng-star-inserted');
cy.get('.table-tx-vout tr:nth-child(1) .amount').should('contain.text', 'Confidential');
cy.get('.table-tx-vout tr:nth-child(2) .amount').should('contain.text', 'Confidential');
});
@@ -120,8 +120,8 @@ describe('Liquid Testnet', () => {
it('show invalid unblinded TX hex', () => {
cy.visit(`${basePath}/tx/2477f220eef1d03f8ffa4a2861c275d155c3562adf0d79523aeeb0c59ee611ba#blinded=5000`);
cy.waitForSkeletonGone();
cy.get('.table-tx-vin tr').should('have.class', '');
cy.get('.table-tx-vout tr').should('have.class', '');
cy.get('.table-tx-vin tr').should('have.class', 'ng-star-inserted');
cy.get('.table-tx-vout tr').should('have.class', 'ng-star-inserted');
cy.get('.error-unblinded').contains('Error: Invalid blinding data (invalid hex)');
});

View File

@@ -47,7 +47,8 @@
</div>
</div>
<div class="item" *ngIf="showHalving">
<h5 class="card-title" i18n="difficulty-box.next-halving">Next Halving</h5>
<h5 class="card-title" i18n="difficulty-box.next-halving" i18n-ngbTooltip="difficulty-box.next-halving"
ngbTooltip="Next Halving" placement="bottom" #averagefee [disableTooltip]="!isEllipsisActive(averagefee)">Next Halving</h5>
<div class="card-text">
<ng-container *ngTemplateOutlet="epochData.blocksUntilHalving === 1 ? blocksSingular : blocksPlural; context: {$implicit: epochData.blocksUntilHalving }"></ng-container>
<ng-template #blocksPlural let-i i18n="shared.blocks">{{ i }} <span class="shared-block">blocks</span></ng-template>
@@ -77,7 +78,7 @@
</div>
</div>
<div class="item">
<h5 class="card-title" i18n="difficulty-box.current-period">Current Period</h5>
<h5 class="card-title" i18n="difficulty-box.next-halving">Next Halving</h5>
<div class="card-text">
<div class="skeleton-loader"></div>
<div class="skeleton-loader"></div>

View File

@@ -10,6 +10,7 @@
.item {
padding: 0 5px;
width: 100%;
max-width: 150px;
&:nth-child(1) {
display: none;
@media (min-width: 485px) {
@@ -85,6 +86,9 @@
.card-title {
color: #4a68b9;
font-size: 1rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.progress {

View File

@@ -83,4 +83,8 @@ export class DifficultyMiningComponent implements OnInit {
})
);
}
isEllipsisActive(e): boolean {
return (e.offsetWidth < e.scrollWidth);
}
}

View File

@@ -50,14 +50,14 @@
</div>
</div>
<div class="item">
<h5 class="card-title" i18n="mining.rewards-per-tx">Reward Per Tx</h5>
<h5 class="card-title" i18n="mining.fees-per-block">Avg Block Fees</h5>
<div class="card-text">
<div class="skeleton-loader"></div>
<div class="skeleton-loader"></div>
</div>
</div>
<div class="item">
<h5 class="card-title" i18n="mining.average-fee">Reward Per Tx</h5>
<h5 class="card-title" i18n="mining.average-fee">Avg Tx Fee</h5>
<div class="card-text">
<div class="skeleton-loader"></div>
<div class="skeleton-loader"></div>

View File

@@ -3203,7 +3203,7 @@
</trans-unit>
<trans-unit id="0c65c3ee0ce537e507e0b053b479012e5803d2cf" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks expected</source>
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> Blöcke erwartet</target>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> Blöcke erwartet</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">13</context>
@@ -3221,7 +3221,7 @@
</trans-unit>
<trans-unit id="b89cb92adf0a831d4a263ecdba02139abbda02ae" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks mined</source>
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> Blöcke gefunden</target>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> Blöcke gefunden</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">18</context>
@@ -3239,7 +3239,7 @@
</trans-unit>
<trans-unit id="229dfb17b342aa8b9a1db27557069445ea1a7051" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks remaining</source>
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> verbleibende Blöcke</target>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> verbleibende Blöcke</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">24</context>
@@ -3257,7 +3257,7 @@
</trans-unit>
<trans-unit id="4f78348af343fb64016891d67b53bdab473f9dbf" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks ahead</source>
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> Blöcke voraus</target>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> Blöcke voraus</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">29</context>
@@ -3275,7 +3275,7 @@
</trans-unit>
<trans-unit id="697b8cb1caaf1729809bc5c065d4dd873810550a" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks behind</source>
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> Blöcke dahinter</target>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> Blöcke dahinter</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">34</context>
@@ -3995,6 +3995,7 @@
</trans-unit>
<trans-unit id="312539377512157124" datatype="html">
<source><x id="INTERPOLATION" equiv-text="i"/> blocks</source>
<target><x id="INTERPOLATION" equiv-text="i"/> blöcke</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">165,163</context>
@@ -4014,6 +4015,7 @@
</trans-unit>
<trans-unit id="3666195172774554282" datatype="html">
<source>Other (<x id="PH" equiv-text="percentage"/>)</source>
<target>Andere (<x id="PH" equiv-text="percentage"/>)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">201</context>
@@ -6773,6 +6775,7 @@
</trans-unit>
<trans-unit id="5222540403093176126" datatype="html">
<source><x id="PH" equiv-text="nodeCount"/> nodes</source>
<target><x id="PH" equiv-text="nodeCount"/> nodes</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts</context>
<context context-type="linenumber">104,103</context>

View File

@@ -3995,6 +3995,7 @@
</trans-unit>
<trans-unit id="312539377512157124" datatype="html">
<source><x id="INTERPOLATION" equiv-text="i"/> blocks</source>
<target><x id="INTERPOLATION" equiv-text="i"/> blocos</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">165,163</context>
@@ -4014,6 +4015,7 @@
</trans-unit>
<trans-unit id="3666195172774554282" datatype="html">
<source>Other (<x id="PH" equiv-text="percentage"/>)</source>
<target>Outras (<x id="PH" equiv-text="percentage"/>)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">201</context>
@@ -6773,6 +6775,7 @@
</trans-unit>
<trans-unit id="5222540403093176126" datatype="html">
<source><x id="PH" equiv-text="nodeCount"/> nodes</source>
<target><x id="PH" equiv-text="nodeCount"/> nós</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts</context>
<context context-type="linenumber">104,103</context>

View File

@@ -348,7 +348,7 @@
</trans-unit>
<trans-unit id="27387c2af5dcaf343a548feba821515f5dc00faa" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> transaction</source>
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> транзакция</target>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> транзакция</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/bisq/bisq-address/bisq-address.component.html</context>
<context context-type="linenumber">48</context>
@@ -373,7 +373,7 @@
</trans-unit>
<trans-unit id="14779b0ce4cbc4d975a35a8fe074426228a324f3" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> transactions</source>
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> транзакции(й)</target>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> транзакции(й)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/bisq/bisq-address/bisq-address.component.html</context>
<context context-type="linenumber">49</context>
@@ -1109,7 +1109,7 @@
</trans-unit>
<trans-unit id="8e623d3cfecb7c560c114390db53c1f430ffd0de" datatype="html">
<source><x id="INTERPOLATION" equiv-text="confirmation&lt;/ng-template&gt; &lt;ng-template #confirmationPlural let-i i18n=&quot;shared.confirmation-count.plural|Transaction plural confir"/> confirmation</source>
<target> <x id="INTERPOLATION" equiv-text="confirmation&lt;/ng-template&gt; &lt;ng-template #confirmationPlural let-i i18n=&quot;shared.confirmation-count.plural|Transaction plural confir"/> подтверждение</target>
<target><x id="INTERPOLATION" equiv-text="confirmation&lt;/ng-template&gt; &lt;ng-template #confirmationPlural let-i i18n=&quot;shared.confirmation-count.plural|Transaction plural confir"/> подтверждение</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/bisq/bisq-transaction/bisq-transaction.component.html</context>
<context context-type="linenumber">20,21</context>
@@ -1131,7 +1131,7 @@
</trans-unit>
<trans-unit id="bc5b0a2631f0b7bc71aaec6aa6f01af21f9a80d4" datatype="html">
<source><x id="INTERPOLATION" equiv-text="confirmations&lt;/ng-template&gt; &lt;/button&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class=&quot;clearfix&quot;&gt;&lt;/div&gt; &lt;div class=&quot;box tran"/> confirmations</source>
<target> <x id="INTERPOLATION" equiv-text="confirmations&lt;/ng-template&gt; &lt;/button&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class=&quot;clearfix&quot;&gt;&lt;/div&gt; &lt;div class=&quot;box tran"/> подтверждения(й)</target>
<target><x id="INTERPOLATION" equiv-text="confirmations&lt;/ng-template&gt; &lt;/button&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class=&quot;clearfix&quot;&gt;&lt;/div&gt; &lt;div class=&quot;box tran"/> подтверждения(й)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/bisq/bisq-transaction/bisq-transaction.component.html</context>
<context context-type="linenumber">21,22</context>
@@ -1764,7 +1764,7 @@
</trans-unit>
<trans-unit id="c3360a933cb312b395d276a2b865214cf832df58" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ (transactions?.length | number) || '?' }}"/> of <x id="INTERPOLATION_1" equiv-text="{{ txCount | number }}"/> </source>
<target> <x id="INTERPOLATION" equiv-text="{{ (transactions?.length | number) || '?' }}"/> из <x id="INTERPOLATION_1" equiv-text="{{ txCount | number }}"/></target>
<target><x id="INTERPOLATION" equiv-text="{{ (transactions?.length | number) || '?' }}"/> из <x id="INTERPOLATION_1" equiv-text="{{ txCount | number }}"/></target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/asset/asset.component.html</context>
<context context-type="linenumber">78</context>
@@ -3203,6 +3203,7 @@
</trans-unit>
<trans-unit id="0c65c3ee0ce537e507e0b053b479012e5803d2cf" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks expected</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блоков добавлено</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">13</context>
@@ -3211,6 +3212,7 @@
</trans-unit>
<trans-unit id="ec9f27d00a7778cd1cfe1806105d2ca3314fa506" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block expected</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блок добавлен</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">14</context>
@@ -3219,6 +3221,7 @@
</trans-unit>
<trans-unit id="b89cb92adf0a831d4a263ecdba02139abbda02ae" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks mined</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блоков намайнено</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">18</context>
@@ -3227,6 +3230,7 @@
</trans-unit>
<trans-unit id="4f7e823fd45c6def13a3f15f678888c7fe254fa5" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block mined</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блок намайнен</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">19</context>
@@ -3235,6 +3239,7 @@
</trans-unit>
<trans-unit id="229dfb17b342aa8b9a1db27557069445ea1a7051" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks remaining</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блоков осталось</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">24</context>
@@ -3243,6 +3248,7 @@
</trans-unit>
<trans-unit id="13ff0d092caf85cd23815f0235e316dc3a6d1bbe" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block remaining</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блок остался</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">25</context>
@@ -3251,6 +3257,7 @@
</trans-unit>
<trans-unit id="4f78348af343fb64016891d67b53bdab473f9dbf" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks ahead</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блоков ожидает</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">29</context>
@@ -3259,6 +3266,7 @@
</trans-unit>
<trans-unit id="15c5f3475966bf3be381378b046a65849f0f6bb6" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block ahead</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блок ожидает</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">30</context>
@@ -3267,6 +3275,7 @@
</trans-unit>
<trans-unit id="697b8cb1caaf1729809bc5c065d4dd873810550a" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks behind</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блоков позади</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">34</context>
@@ -3275,6 +3284,7 @@
</trans-unit>
<trans-unit id="32137887e3f5a25b3a016eb03357f4e363fccb0b" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block behind</source>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> блок позади</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">35</context>
@@ -3283,6 +3293,7 @@
</trans-unit>
<trans-unit id="5e78899c9b98f29856ce3c7c265e1344bc7a5a18" datatype="html">
<source>Average block time</source>
<target>Среднее время блока</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">42,45</context>
@@ -3984,6 +3995,7 @@
</trans-unit>
<trans-unit id="312539377512157124" datatype="html">
<source><x id="INTERPOLATION" equiv-text="i"/> blocks</source>
<target><x id="INTERPOLATION" equiv-text="i"/> блоков</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">165,163</context>
@@ -4003,6 +4015,7 @@
</trans-unit>
<trans-unit id="3666195172774554282" datatype="html">
<source>Other (<x id="PH" equiv-text="percentage"/>)</source>
<target>Другое ( <x id="PH" equiv-text="percentage"/> )</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">201</context>
@@ -4505,7 +4518,7 @@
</trans-unit>
<trans-unit id="time-since" datatype="html">
<source><x id="DATE" equiv-text="dateStrings.i18nYear"/> ago</source>
<target> <x id="DATE" equiv-text="dateStrings.i18nYear"/> назад</target>
<target><x id="DATE" equiv-text="dateStrings.i18nYear"/> назад</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">103</context>
@@ -4565,6 +4578,7 @@
</trans-unit>
<trans-unit id="time-until" datatype="html">
<source>In ~<x id="DATE" equiv-text="dateStrings.i18nYear"/></source>
<target>Через ~<x id="DATE" equiv-text="dateStrings.i18nYear"/></target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">126</context>
@@ -5053,7 +5067,7 @@
</trans-unit>
<trans-unit id="ea7c261363dc5f6134b7bacba2a1ef97f4ff7859" datatype="html">
<source><x id="INTERPOLATION" equiv-text="remaining&lt;/ng-template&gt;"/> remaining</source>
<target> <x id="INTERPOLATION" equiv-text="remaining&lt;/ng-template&gt;"/> осталось</target>
<target><x id="INTERPOLATION" equiv-text="remaining&lt;/ng-template&gt;"/> осталось</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/transactions-list/transactions-list.component.html</context>
<context context-type="linenumber">332,333</context>
@@ -5106,7 +5120,7 @@
</trans-unit>
<trans-unit id="25d58cd5c18fd9c1c89d6062d67dcc2482161410" datatype="html">
<source>This transaction saved <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/>% on fees by using native SegWit</source>
<target>Эта транзакция сэкономила <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/> % на комиссиях за счет использования нативного SegWit.</target>
<target>Эта транзакция сэкономила <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/>% на комиссиях за счет использования нативного SegWit.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
<context context-type="linenumber">2</context>
@@ -5133,7 +5147,7 @@
</trans-unit>
<trans-unit id="b6a3f6afdac6873e2d261647d834c02c91376893" datatype="html">
<source>This transaction saved <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/>% on fees by using SegWit and could save <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/>% more by fully upgrading to native SegWit</source>
<target>Эта транзакция сэкономила <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/> % на комиссиях за счет использования SegWit и может сэкономить еще <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/> % за счет полного перехода на нативный SegWit.</target>
<target>Эта транзакция сэкономила <x id="INTERPOLATION" equiv-text="{{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}"/>% на комиссиях за счет использования SegWit и может сэкономить еще <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/>% за счет полного перехода на нативный SegWit.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
<context context-type="linenumber">4</context>
@@ -5142,7 +5156,7 @@
</trans-unit>
<trans-unit id="a67530e246368aa7e5d010061fd84c3c4fe755c2" datatype="html">
<source>This transaction could save <x id="INTERPOLATION" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/>% on fees by upgrading to native SegWit or <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialP2shSegwitGains * 100 | number: '1.0-0' }}"/>% by upgrading to SegWit-P2SH</source>
<target>Эта транзакция могла сэкономить <x id="INTERPOLATION" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/> % на комиссиях за счет перехода на нативный SegWit или <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialP2shSegwitGains * 100 | number: '1.0-0' }}"/> % за счет обновления до SegWit-P2SH.</target>
<target>Эта транзакция могла сэкономить <x id="INTERPOLATION" equiv-text="{{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}"/>% на комиссиях за счет перехода на нативный SegWit или <x id="INTERPOLATION_1" equiv-text="{{ segwitGains.potentialP2shSegwitGains * 100 | number: '1.0-0' }}"/>% за счет обновления до SegWit-P2SH.</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tx-features/tx-features.component.html</context>
<context context-type="linenumber">6</context>
@@ -5264,7 +5278,7 @@
</trans-unit>
<trans-unit id="60601e02e7c1f6c4dbabd0ef0bb8946003db8dec" datatype="html">
<source>Only ~<x id="INTERPOLATION" equiv-text="{{ medianFeeNeeded | feeRounding }}"/> sat/vB was needed to get into this block</source>
<target>Чтобы попасть в этот блок, необходимо всего ~ <x id="INTERPOLATION" equiv-text="{{ medianFeeNeeded | feeRounding }}"/> sat / vB</target>
<target>Чтобы попасть в этот блок, необходимо всего ~<x id="INTERPOLATION" equiv-text="{{ medianFeeNeeded | feeRounding }}"/> sat/vB</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tx-fee-rating/tx-fee-rating.component.html</context>
<context context-type="linenumber">2</context>
@@ -5277,7 +5291,7 @@
</trans-unit>
<trans-unit id="0fa66b0c410bef320d3f370d7c98c51754b5f28f" datatype="html">
<source>Overpaid <x id="INTERPOLATION" equiv-text="{{ overpaidTimes }}"/>x</source>
<target>Переплачено <x id="INTERPOLATION" equiv-text="{{ overpaidTimes }}"/> x</target>
<target>Переплачено <x id="INTERPOLATION" equiv-text="{{ overpaidTimes }}"/>x</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/tx-fee-rating/tx-fee-rating.component.html</context>
<context context-type="linenumber">2</context>
@@ -5564,7 +5578,7 @@
</trans-unit>
<trans-unit id="205c1b86ac1cc419c4d0cca51fdde418c4ffdc20" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> channels</source>
<target> <x id="INTERPOLATION" equiv-text="{{ i }}"/> каналов</target>
<target><x id="INTERPOLATION" equiv-text="{{ i }}"/> каналов</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/channel/channel-box/channel-box.component.html</context>
<context context-type="linenumber">79</context>
@@ -6712,6 +6726,7 @@
</trans-unit>
<trans-unit id="599038141003770125" datatype="html">
<source>Clearnet and Darknet</source>
<target>Clearnet и Darknet</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
<context context-type="linenumber">164,161</context>
@@ -6723,6 +6738,7 @@
</trans-unit>
<trans-unit id="1282458597026430784" datatype="html">
<source>Clearnet Only (IPv4, IPv6)</source>
<target>Только Clearnet (IPv4, IPv6)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
<context context-type="linenumber">185,182</context>
@@ -6734,6 +6750,7 @@
</trans-unit>
<trans-unit id="2165336009914523952" datatype="html">
<source>Darknet Only (Tor, I2P, cjdns)</source>
<target>Только Darknet (Tor, I2P, cjdns)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-networks-chart/nodes-networks-chart.component.ts</context>
<context context-type="linenumber">206,203</context>
@@ -6758,6 +6775,7 @@
</trans-unit>
<trans-unit id="5222540403093176126" datatype="html">
<source><x id="PH" equiv-text="nodeCount"/> nodes</source>
<target><x id="PH" equiv-text="nodeCount"/> узлов</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-country-chart/nodes-per-country-chart.component.ts</context>
<context context-type="linenumber">104,103</context>
@@ -7020,7 +7038,7 @@
</trans-unit>
<trans-unit id="date-base.year" datatype="html">
<source><x id="DATE" equiv-text="counter"/> year</source>
<target> <x id="DATE" equiv-text="counter"/> год</target>
<target><x id="DATE" equiv-text="counter"/> год</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">3</context>
@@ -7028,7 +7046,7 @@
</trans-unit>
<trans-unit id="date-base.years" datatype="html">
<source><x id="DATE" equiv-text="counter"/> years</source>
<target> <x id="DATE" equiv-text="counter"/> лет</target>
<target><x id="DATE" equiv-text="counter"/> лет</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">4</context>
@@ -7036,7 +7054,7 @@
</trans-unit>
<trans-unit id="date-base.month" datatype="html">
<source><x id="DATE" equiv-text="counter"/> month</source>
<target> <x id="DATE" equiv-text="counter"/> месяц</target>
<target><x id="DATE" equiv-text="counter"/> месяц</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">5</context>
@@ -7044,7 +7062,7 @@
</trans-unit>
<trans-unit id="date-base.months" datatype="html">
<source><x id="DATE" equiv-text="counter"/> months</source>
<target> <x id="DATE" equiv-text="counter"/> месяцев</target>
<target><x id="DATE" equiv-text="counter"/> месяцев</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">6</context>
@@ -7052,7 +7070,7 @@
</trans-unit>
<trans-unit id="date-base.week" datatype="html">
<source><x id="DATE" equiv-text="counter"/> week</source>
<target> <x id="DATE" equiv-text="counter"/> неделя</target>
<target><x id="DATE" equiv-text="counter"/> неделю</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">7</context>
@@ -7060,7 +7078,7 @@
</trans-unit>
<trans-unit id="date-base.weeks" datatype="html">
<source><x id="DATE" equiv-text="counter"/> weeks</source>
<target> <x id="DATE" equiv-text="counter"/> недель</target>
<target><x id="DATE" equiv-text="counter"/> недели</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">8</context>
@@ -7068,7 +7086,7 @@
</trans-unit>
<trans-unit id="date-base.day" datatype="html">
<source><x id="DATE" equiv-text="counter"/> day</source>
<target> <x id="DATE" equiv-text="counter"/> дней</target>
<target><x id="DATE" equiv-text="counter"/> дней</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">9</context>
@@ -7076,7 +7094,7 @@
</trans-unit>
<trans-unit id="date-base.days" datatype="html">
<source><x id="DATE" equiv-text="counter"/> days</source>
<target> <x id="DATE" equiv-text="counter"/> дней</target>
<target><x id="DATE" equiv-text="counter"/> дней</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">10</context>
@@ -7084,7 +7102,7 @@
</trans-unit>
<trans-unit id="date-base.hour" datatype="html">
<source><x id="DATE" equiv-text="counter"/> hour</source>
<target> <x id="DATE" equiv-text="counter"/> час</target>
<target><x id="DATE" equiv-text="counter"/> час</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">11</context>
@@ -7092,7 +7110,7 @@
</trans-unit>
<trans-unit id="date-base.hours" datatype="html">
<source><x id="DATE" equiv-text="counter"/> hours</source>
<target> <x id="DATE" equiv-text="counter"/> часов</target>
<target><x id="DATE" equiv-text="counter"/> часов</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">12</context>
@@ -7100,7 +7118,7 @@
</trans-unit>
<trans-unit id="date-base.minute" datatype="html">
<source><x id="DATE" equiv-text="counter"/> minute</source>
<target> <x id="DATE" equiv-text="counter"/> минута</target>
<target><x id="DATE" equiv-text="counter"/> минута</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">13</context>
@@ -7108,7 +7126,7 @@
</trans-unit>
<trans-unit id="date-base.minutes" datatype="html">
<source><x id="DATE" equiv-text="counter"/> minutes</source>
<target> <x id="DATE" equiv-text="counter"/> минут</target>
<target><x id="DATE" equiv-text="counter"/> минут</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">14</context>
@@ -7116,7 +7134,7 @@
</trans-unit>
<trans-unit id="date-base.second" datatype="html">
<source><x id="DATE" equiv-text="counter"/> second</source>
<target> <x id="DATE" equiv-text="counter"/> секунда</target>
<target><x id="DATE" equiv-text="counter"/> секунда</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">15</context>
@@ -7124,7 +7142,7 @@
</trans-unit>
<trans-unit id="date-base.seconds" datatype="html">
<source><x id="DATE" equiv-text="counter"/> seconds</source>
<target> <x id="DATE" equiv-text="counter"/> секунд</target>
<target><x id="DATE" equiv-text="counter"/> секунд</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/shared/i18n/dates.ts</context>
<context context-type="linenumber">16</context>