Compare commits

..
Author SHA1 Message Date
transifex-integration[bot] 8ee7ec2886 Translate frontend/src/locale/messages.xlf in fa
100% reviewed for the source file 'frontend/src/locale/messages.xlf'
on the 'fa' language.
2023-03-09 23:51:31 +00:00
92 changed files with 10036 additions and 18201 deletions

No files matched your search

+11 -17
View File
@@ -171,58 +171,52 @@ Helpful link: https://gist.github.com/System-Glitch/cb4e87bf1ae3fec9925725bb3ebe
Run bitcoind on regtest:
```
bitcoind -regtest
bitcoind -regtest -rpcport=8332
```
Create a new wallet, if needed:
```
bitcoin-cli -regtest createwallet test
bitcoin-cli -regtest -rpcport=8332 createwallet test
```
Load wallet (this command may take a while if you have lot of UTXOs):
```
bitcoin-cli -regtest loadwallet test
bitcoin-cli -regtest -rpcport=8332 loadwallet test
```
Get a new address:
```
address=$(bitcoin-cli -regtest getnewaddress)
address=$(./src/bitcoin-cli -regtest -rpcport=8332 getnewaddress)
```
Mine blocks to the previously generated address. You need at least 101 blocks before you can spend. This will take some time to execute (~1 min):
```
bitcoin-cli -regtest generatetoaddress 101 $address
bitcoin-cli -regtest -rpcport=8332 generatetoaddress 101 $address
```
Send 0.1 BTC at 5 sat/vB to another address:
```
bitcoin-cli -named -regtest sendtoaddress address=$(bitcoin-cli -regtest getnewaddress) amount=0.1 fee_rate=5
./src/bitcoin-cli -named -regtest -rpcport=8332 sendtoaddress address=$(./src/bitcoin-cli -regtest -rpcport=8332 getnewaddress) amount=0.1 fee_rate=5
```
See more example of `sendtoaddress`:
```
bitcoin-cli sendtoaddress # will print the help
./src/bitcoin-cli sendtoaddress # will print the help
```
Mini script to generate random network activity (random TX count with random tx fee-rate). It's slow so don't expect to use this to test mempool spam, except if you let it run for a long time, or maybe with multiple regtest nodes connected to each other.
Mini script to generate transactions with random TX fee-rate (between 1 to 100 sat/vB). It's slow so don't expect to use this to test mempool spam, except if you let it run for a long time, or maybe with multiple regtest nodes connected to each other.
```
#!/bin/bash
address=$(bitcoin-cli -regtest getnewaddress)
bitcoin-cli -regtest generatetoaddress 101 $address
address=$(./src/bitcoin-cli -regtest -rpcport=8332 getnewaddress)
for i in {1..1000000}
do
for y in $(seq 1 "$(jot -r 1 1 1000)")
do
bitcoin-cli -regtest -named sendtoaddress address=$address amount=0.01 fee_rate=$(jot -r 1 1 100)
done
bitcoin-cli -regtest generatetoaddress 1 $address
sleep 5
./src/bitcoin-cli -regtest -rpcport=8332 -named sendtoaddress address=$address amount=0.01 fee_rate=$(jot -r 1 1 100)
done
```
Generate block at regular interval (every 10 seconds in this example):
```
watch -n 10 "bitcoin-cli -regtest generatetoaddress 1 $address"
watch -n 10 "./src/bitcoin-cli -regtest -rpcport=8332 generatetoaddress 1 $address"
```
### Mining pools update
@@ -23,11 +23,9 @@ describe('Mempool Difficulty Adjustment', () => {
remainingBlocks: 1834,
remainingTime: 977591692,
previousRetarget: 0.6280047707459726,
previousTime: 1660820820,
nextRetargetHeight: 751968,
timeAvg: 533038,
timeOffset: 0,
expectedBlocks: 161.68833333333333,
},
],
[ // Vector 2 (testnet)
@@ -45,13 +43,11 @@ describe('Mempool Difficulty Adjustment', () => {
estimatedRetargetDate: 1661895424692,
remainingBlocks: 1834,
remainingTime: 977591692,
previousTime: 1660820820,
previousRetarget: 0.6280047707459726,
nextRetargetHeight: 751968,
timeAvg: 533038,
timeOffset: -667000, // 11 min 7 seconds since last block (testnet only)
// If we add time avg to abs(timeOffset) it makes exactly 1200000 ms, or 20 minutes
expectedBlocks: 161.68833333333333,
},
],
] as [[number, number, number, number, string, number], DifficultyAdjustment][];
+1 -1
View File
@@ -641,7 +641,7 @@ class Blocks {
if (this.newBlockCallbacks.length) {
this.newBlockCallbacks.forEach((cb) => cb(blockExtended, txIds, transactions));
}
if (!memPool.hasPriority() && (block.height % 6 === 0)) {
if (!memPool.hasPriority()) {
diskCache.$saveCacheToDisk();
}
+2 -6
View File
@@ -9,11 +9,9 @@ export interface DifficultyAdjustment {
remainingBlocks: number; // Block count
remainingTime: number; // Duration of time in ms
previousRetarget: number; // Percent: -75 to 300
previousTime: number; // Unix time in ms
nextRetargetHeight: number; // Block Height
timeAvg: number; // Duration of time in ms
timeOffset: number; // (Testnet) Time since last block (cap @ 20min) in ms
expectedBlocks: number; // Block count
}
export function calcDifficultyAdjustment(
@@ -34,12 +32,12 @@ export function calcDifficultyAdjustment(
const progressPercent = (blockHeight >= 0) ? blocksInEpoch / EPOCH_BLOCK_LENGTH * 100 : 100;
const remainingBlocks = EPOCH_BLOCK_LENGTH - blocksInEpoch;
const nextRetargetHeight = (blockHeight >= 0) ? blockHeight + remainingBlocks : 0;
const expectedBlocks = diffSeconds / BLOCK_SECONDS_TARGET;
let difficultyChange = 0;
let timeAvgSecs = diffSeconds / blocksInEpoch;
let timeAvgSecs = BLOCK_SECONDS_TARGET;
// Only calculate the estimate once we have 7.2% of blocks in current epoch
if (blocksInEpoch >= ESTIMATE_LAG_BLOCKS) {
timeAvgSecs = diffSeconds / blocksInEpoch;
difficultyChange = (BLOCK_SECONDS_TARGET / timeAvgSecs - 1) * 100;
// Max increase is x4 (+300%)
if (difficultyChange > 300) {
@@ -76,11 +74,9 @@ export function calcDifficultyAdjustment(
remainingBlocks,
remainingTime,
previousRetarget,
previousTime: DATime,
nextRetargetHeight,
timeAvg,
timeOffset,
expectedBlocks,
};
}
+4 -73
View File
@@ -11,33 +11,19 @@ import { Common } from './common';
class DiskCache {
private cacheSchemaVersion = 3;
private static TMP_FILE_NAME = config.MEMPOOL.CACHE_DIR + '/tmp-cache.json';
private static TMP_FILE_NAMES = config.MEMPOOL.CACHE_DIR + '/tmp-cache{number}.json';
private static FILE_NAME = config.MEMPOOL.CACHE_DIR + '/cache.json';
private static FILE_NAMES = config.MEMPOOL.CACHE_DIR + '/cache{number}.json';
private static CHUNK_FILES = 25;
private isWritingCache = false;
constructor() {
if (!cluster.isMaster) {
return;
}
process.on('SIGINT', (e) => {
this.saveCacheToDiskSync();
process.exit(2);
});
process.on('SIGTERM', (e) => {
this.saveCacheToDiskSync();
process.exit(2);
});
}
constructor() { }
async $saveCacheToDisk(): Promise<void> {
if (!cluster.isPrimary) {
return;
}
if (this.isWritingCache) {
logger.debug('Saving cache already in progress. Skipping.');
logger.debug('Saving cache already in progress. Skipping.')
return;
}
try {
@@ -55,7 +41,6 @@ class DiskCache {
const chunkSize = Math.floor(mempoolArray.length / DiskCache.CHUNK_FILES);
await fsPromises.writeFile(DiskCache.FILE_NAME, JSON.stringify({
network: config.MEMPOOL.NETWORK,
cacheSchemaVersion: this.cacheSchemaVersion,
blocks: blocks.getBlocks(),
blockSummaries: blocks.getBlockSummaries(),
@@ -76,57 +61,7 @@ class DiskCache {
}
}
saveCacheToDiskSync(): void {
if (!cluster.isPrimary) {
return;
}
if (this.isWritingCache) {
logger.debug('Saving cache already in progress. Skipping.');
return;
}
try {
logger.debug('Writing mempool and blocks data to disk cache (sync)...');
this.isWritingCache = true;
const mempool = memPool.getMempool();
const mempoolArray: TransactionExtended[] = [];
for (const tx in mempool) {
mempoolArray.push(mempool[tx]);
}
Common.shuffleArray(mempoolArray);
const chunkSize = Math.floor(mempoolArray.length / DiskCache.CHUNK_FILES);
fs.writeFileSync(DiskCache.TMP_FILE_NAME, JSON.stringify({
network: config.MEMPOOL.NETWORK,
cacheSchemaVersion: this.cacheSchemaVersion,
blocks: blocks.getBlocks(),
blockSummaries: blocks.getBlockSummaries(),
mempool: {},
mempoolArray: mempoolArray.splice(0, chunkSize),
}), { flag: 'w' });
for (let i = 1; i < DiskCache.CHUNK_FILES; i++) {
fs.writeFileSync(DiskCache.TMP_FILE_NAMES.replace('{number}', i.toString()), JSON.stringify({
mempool: {},
mempoolArray: mempoolArray.splice(0, chunkSize),
}), { flag: 'w' });
}
fs.renameSync(DiskCache.TMP_FILE_NAME, DiskCache.FILE_NAME);
for (let i = 1; i < DiskCache.CHUNK_FILES; i++) {
fs.renameSync(DiskCache.TMP_FILE_NAMES.replace('{number}', i.toString()), DiskCache.FILE_NAMES.replace('{number}', i.toString()));
}
logger.debug('Mempool and blocks data saved to disk cache');
this.isWritingCache = false;
} catch (e) {
logger.warn('Error writing to cache file: ' + (e instanceof Error ? e.message : e));
this.isWritingCache = false;
}
}
wipeCache(): void {
wipeCache() {
logger.notice(`Wiping nodejs backend cache/cache*.json files`);
try {
fs.unlinkSync(DiskCache.FILE_NAME);
@@ -148,7 +83,7 @@ class DiskCache {
}
}
loadMempoolCache(): void {
loadMempoolCache() {
if (!fs.existsSync(DiskCache.FILE_NAME)) {
return;
}
@@ -162,10 +97,6 @@ class DiskCache {
logger.notice('Disk cache contains an outdated schema version. Clearing it and skipping the cache loading.');
return this.wipeCache();
}
if (data.network && data.network !== config.MEMPOOL.NETWORK) {
logger.notice('Disk cache contains data from a different network. Clearing it and skipping the cache loading.');
return this.wipeCache();
}
if (data.mempoolArray) {
for (const tx of data.mempoolArray) {
+8 -8
View File
@@ -417,24 +417,24 @@ class NodesApi {
if (!ispList[isp1]) {
ispList[isp1] = {
ids: [channel.isp1ID],
id: channel.isp1ID.toString(),
capacity: 0,
channels: 0,
nodes: {},
};
} else if (ispList[isp1].ids.includes(channel.isp1ID) === false) {
ispList[isp1].ids.push(channel.isp1ID);
} else if (ispList[isp1].id.indexOf(channel.isp1ID) === -1) {
ispList[isp1].id += ',' + channel.isp1ID.toString();
}
if (!ispList[isp2]) {
ispList[isp2] = {
ids: [channel.isp2ID],
id: channel.isp2ID.toString(),
capacity: 0,
channels: 0,
nodes: {},
};
} else if (ispList[isp2].ids.includes(channel.isp2ID) === false) {
ispList[isp2].ids.push(channel.isp2ID);
} else if (ispList[isp2].id.indexOf(channel.isp2ID) === -1) {
ispList[isp2].id += ',' + channel.isp2ID.toString();
}
ispList[isp1].capacity += channel.capacity;
@@ -444,11 +444,11 @@ class NodesApi {
ispList[isp2].channels += 1;
ispList[isp2].nodes[channel.node2PublicKey] = true;
}
const ispRanking: any[] = [];
for (const isp of Object.keys(ispList)) {
ispRanking.push([
ispList[isp].ids.sort((a, b) => a - b).join(','),
ispList[isp].id,
isp,
ispList[isp].capacity,
ispList[isp].channels,
+1 -27
View File
@@ -31,11 +31,6 @@ class Mempool {
private mempoolProtection = 0;
private latestTransactions: any[] = [];
private ESPLORA_MISSING_TX_WARNING_THRESHOLD = 100;
private SAMPLE_TIME = 10000; // In ms
private timer = new Date().getTime();
private missingTxCount = 0;
constructor() {
setInterval(this.updateTxPerSecond.bind(this), 1000);
setInterval(this.deleteExpiredTransactions.bind(this), 20000);
@@ -133,16 +128,6 @@ class Mempool {
loadingIndicators.setProgress('mempool', Object.keys(this.mempoolCache).length / transactions.length * 100);
}
// https://github.com/mempool/mempool/issues/3283
const logEsplora404 = (missingTxCount, threshold, time) => {
const log = `In the past ${time / 1000} seconds, esplora tx API replied ${missingTxCount} times with a 404 error code while updating nodejs backend mempool`;
if (missingTxCount >= threshold) {
logger.warn(log);
} else if (missingTxCount > 0) {
logger.debug(log);
}
};
for (const txid of transactions) {
if (!this.mempoolCache[txid]) {
try {
@@ -157,10 +142,7 @@ class Mempool {
}
hasChange = true;
newTransactions.push(transaction);
} catch (e: any) {
if (config.MEMPOOL.BACKEND === 'esplora' && e.response?.status === 404) {
this.missingTxCount++;
}
} catch (e) {
logger.debug(`Error finding transaction '${txid}' in the mempool: ` + (e instanceof Error ? e.message : e));
}
}
@@ -170,14 +152,6 @@ class Mempool {
}
}
// Reset esplora 404 counter and log a warning if needed
const elapsedTime = new Date().getTime() - this.timer;
if (elapsedTime > this.SAMPLE_TIME) {
logEsplora404(this.missingTxCount, this.ESPLORA_MISSING_TX_WARNING_THRESHOLD, elapsedTime);
this.timer = new Date().getTime();
this.missingTxCount = 0;
}
// Prevent mempool from clear on bitcoind restart by delaying the deletion
if (this.mempoolProtection === 0
&& currentMempoolSize > 20000
+1 -3
View File
@@ -17,9 +17,7 @@ class PoolsUpdater {
treeUrl: string = config.MEMPOOL.POOLS_JSON_TREE_URL;
public async updatePoolsJson(): Promise<void> {
if (['mainnet', 'testnet', 'signet'].includes(config.MEMPOOL.NETWORK) === false ||
config.MEMPOOL.ENABLED === false
) {
if (['mainnet', 'testnet', 'signet'].includes(config.MEMPOOL.NETWORK) === false) {
return;
}
-4
View File
@@ -38,10 +38,6 @@
"translation": "src/locale/messages.de.xlf",
"baseHref": "/de/"
},
"da": {
"translation": "src/locale/messages.da.xlf",
"baseHref": "/da/"
},
"es": {
"translation": "src/locale/messages.es.xlf",
"baseHref": "/es/"
-27
View File
@@ -254,30 +254,3 @@ export function selectPowerOfTen(val: number): { divider: number, unit: string }
return selectedPowerOfTen;
}
const featureActivation = {
mainnet: {
rbf: 399701,
segwit: 477120,
taproot: 709632,
},
testnet: {
rbf: 720255,
segwit: 872730,
taproot: 2032291,
},
signet: {
rbf: 0,
segwit: 0,
taproot: 0,
},
};
export function isFeatureActive(network: string, height: number, feature: 'rbf' | 'segwit' | 'taproot'): boolean {
const activationHeight = featureActivation[network || 'mainnet']?.[feature];
if (activationHeight != null) {
return height >= activationHeight;
} else {
return false;
}
}
@@ -209,7 +209,7 @@
<span>EmbassyOS</span>
</a>
<a href="https://github.com/btcpayserver/btcpayserver" target="_blank" title="BTCPay Server">
<img class="image not-rounded" src="/resources/profile/btcpayserver.svg" />
<img class="image" src="/resources/profile/btcpayserver.svg" />
<span>BTCPay</span>
</a>
<a href="https://github.com/bisq-network/bisq" target="_blank" title="Bisq">
@@ -268,26 +268,6 @@
<img class="image" src="/resources/profile/nunchuk.svg" />
<span>Nunchuk</span>
</a>
<a href="https://github.com/bitcoin-s/bitcoin-s" target="_blank" title="bitcoin-s">
<img class="image" src="/resources/profile/bitcoin-s.svg" />
<span>bitcoin-s</span>
</a>
<a href="https://github.com/EdgeApp" target="_blank" title="Edge">
<img class="image not-rounded" src="/resources/profile/edge.svg" />
<span>Edge</span>
</a>
<a href="https://github.com/GaloyMoney" target="_blank" title="Galoy">
<img class="image" src="/resources/profile/galoy.svg" />
<span>Galoy</span>
</a>
<a href="https://github.com/BoltzExchange" target="_blank" title="Boltz">
<img class="image" src="/resources/profile/boltz.svg" />
<span>Boltz</span>
</a>
<a href="https://github.com/MutinyWallet" target="_blank" title="Mutiny">
<img class="image not-rounded" src="/resources/profile/mutiny.svg" />
<span>Mutiny</span>
</a>
</div>
</div>
@@ -403,12 +383,6 @@
<a target="_blank" href="https://matrix.to/#/#mempool:bitcoin.kyoto">
<svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="matrix" class="svg-inline--fa fa-matrix fa-w-16 fa-2x" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1536 1792"><path fill="currentColor" d="M40.467 163.152v1465.696H145.92V1664H0V128h145.92v35.152zm450.757 464.64v74.14h2.069c19.79-28.356 43.717-50.215 71.483-65.575 27.765-15.656 59.963-23.336 96-23.336 34.56 0 66.165 6.795 94.818 20.086 28.652 13.293 50.216 37.22 65.28 70.893 16.246-23.926 38.4-45.194 66.166-63.507 27.766-18.314 60.848-27.472 98.954-27.472 28.948 0 55.828 3.545 80.64 10.635 24.812 7.088 45.785 18.314 63.508 33.968 17.722 15.656 31.31 35.742 41.354 60.85 9.747 25.107 14.768 55.236 14.768 90.683v366.573h-150.35V865.28c0-18.314-.59-35.741-2.068-51.987-1.476-16.247-5.316-30.426-11.52-42.24-6.499-12.112-15.656-21.563-28.062-28.653-12.405-7.088-29.242-10.634-50.214-10.634-21.268 0-38.4 4.135-51.397 12.112-12.997 8.27-23.336 18.608-30.72 31.901-7.386 12.997-12.407 27.765-14.77 44.602-2.363 16.542-3.84 33.379-3.84 50.216v305.133H692.971v-307.2c0-16.247-.294-32.197-1.18-48.149-.591-15.95-3.84-30.424-9.157-44.011-5.317-13.293-14.178-24.223-26.585-32.197-12.406-7.976-30.425-12.112-54.646-12.112-7.088 0-16.542 1.478-28.062 4.726-11.52 3.25-23.04 9.157-33.968 18.02-10.93 8.86-20.383 21.563-28.063 38.103-7.68 16.543-11.52 38.4-11.52 65.28v317.834H349.44V627.792zm1004.309 1001.056V163.152H1390.08V128H1536v1536h-145.92v-35.152z"/></svg>
</a>
<a target="_blank" href="https://youtube.com/@mempool">
<svg aria-hidden="true" focusable="false" data-prefix="fab" data-icon="youtube" class="svg-inline--fa fa-youtube fa-w-16 fa-2x" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z"/></svg>
</a>
<a target="_blank" href="https://bitcointv.com/c/mempool/videos" class="bitcointv">
<svg xmlns="http://www.w3.org/2000/svg" focusable="false" viewBox="0 0 440 440"><path d="M225.57,2.08l-.69-.45a4.22,4.22,0,0,0-5.72,1.23L182.33,46.09a4,4,0,0,0,.88,5.81l9.38,6.38L173.48,97.49a4.22,4.22,0,0,0,2.45,4.19s3.55.7,4.53-1l41.92-40.56a3.62,3.62,0,0,0-1.51-5.1l-10.55-6.12L227.44,6.79A4.26,4.26,0,0,0,225.57,2.08Z" fill="currentColor"></path><path d="M118.52,401.83c-62.51,0-113.37-51-113.37-113.67V214.68C5.15,152,56,101,118.52,101H342.08a24.82,24.82,0,0,1,24.76,24.83V377a24.81,24.81,0,0,1-24.76,24.82Z"></path><path d="M342.08,105.18a20.65,20.65,0,0,1,20.61,20.66V377a20.66,20.66,0,0,1-20.61,20.66H118.52C58.3,397.67,9.31,348.55,9.31,288.16V214.68c0-60.38,49-109.5,109.21-109.5H342.08m0-8.34H118.52C53.62,96.84,1,149.6,1,214.68v73.48C1,353.24,53.62,406,118.52,406H342.08A29,29,0,0,0,371,377V125.84a29,29,0,0,0-28.92-29Z" fill="currentColor"></path><path fill="currentColor" d="M344.69,346.23A25.84,25.84,0,1,0,335,369.87l-10.22-10.2a11.69,11.69,0,1,1,4.77-5.12l10.31,10.28A25.84,25.84,0,0,0,344.69,346.23Z"></path><path fill="currentColor" d="M315.82,257.61a25.67,25.67,0,0,0-12.53,5.22L315,274.49a9.58,9.58,0,0,1,2.11-.73A9.72,9.72,0,1,1,309.4,283a9.4,9.4,0,0,1,.75-3.41L298.4,267.84a25.77,25.77,0,1,0,17.42-10.23Z"></path><path fill="currentColor" d="M313,214a7.76,7.76,0,1,1,1.41,10.91,7.62,7.62,0,0,1-2.19-2.69l-18.67-.14a25.94,25.94,0,1,0,.05-7l18.64.14A7.4,7.4,0,0,1,313,214Z"></path><path fill="currentColor" d="M341.2,144.08h-6.32c-1.67,0-3.61,1.87-3.61,4.29s1.94,4.29,3.61,4.29h6.32c1.67,0,3.61-1.87,3.61-4.29S342.87,144.08,341.2,144.08Z"></path><path fill="currentColor" d="M301.75,144.08h-6.44c-1.67,0-3.61,1.87-3.61,4.29s1.94,4.29,3.61,4.29h6.44c1.67,0,3.61-1.87,3.61-4.29S303.42,144.08,301.75,144.08Z"></path><path fill="currentColor" d="M321.77,144.08h-7c-1.67,0-3.62,1.87-3.62,4.29s1.95,4.29,3.62,4.29h7c1.67,0,3.62-1.87,3.62-4.29S323.44,144.08,321.77,144.08Z"></path><ellipse fill="currentColor" cx="295.97" cy="127.61" rx="4.27" ry="4.29"></ellipse><path fill="currentColor" d="M340.54,131.9a4.29,4.29,0,1,0-4.27-4.29A4.28,4.28,0,0,0,340.54,131.9Z"></path><path fill="currentColor" d="M318.26,131.9a4.29,4.29,0,1,0-4.27-4.29A4.29,4.29,0,0,0,318.26,131.9Z"></path><ellipse fill="currentColor" cx="295.97" cy="169.13" rx="4.27" ry="4.29"></ellipse><path fill="currentColor" d="M340.54,164.84a4.3,4.3,0,1,0,4.27,4.29A4.29,4.29,0,0,0,340.54,164.84Z"></path><path fill="currentColor" d="M318.26,164.84a4.3,4.3,0,1,0,4.28,4.29A4.29,4.29,0,0,0,318.26,164.84Z"></path><path d="M108.62,256.87c8.36-1,7.68-7.76,3.14-17-3.64-7.4-9.74-16.39-15.75-25.36-14.23-21.23-27.69-42.23-5.35-41.07,19.55,1,42.9,18.63,68.22,36.74,31.1,22.24,65.16,45.21,98.81,39.11a151.19,151.19,0,0,1,20-2.37V221a92,92,0,0,0-91.91-92.16H124.33A92,92,0,0,0,32.42,221v17.59c17.71,3.81,31,9.94,43.8,14.15C86.6,256.16,96.69,258.31,108.62,256.87Z"></path><path d="M273.37,310.79c-35-15.26-76.67-32.1-104-23.59-3.15,1-5,2.3-6,3.85-3.35,5.31,4.67,13.57,14.89,22.17,7.17,6,15.36,12.21,21.44,17.64,11.47,10.26,15.35,17.84-9.89,16.62-29.75-1.44-49.18-13.75-71.18-24l-.29-.14a165.84,165.84,0,0,0-22.93-8.91c-15.74-4.67-34.22-6.79-58.51-3.28A91.93,91.93,0,0,0,124.33,375h61.45A92,92,0,0,0,273.37,310.79Z"></path><path fill="currentColor" d="M257.69,249.31C224,255.41,190,232.44,158.88,210.2c-25.32-18.11-48.67-35.72-68.22-36.74C68.32,172.3,81.78,193.3,96,214.53c6,9,12.11,18,15.75,25.36,4.54,9.22,5.22,16-3.14,17-11.93,1.44-22-.71-32.4-4.13-12.8-4.21-26.09-10.34-43.8-14.15v44.26c0,1.26.14,2.48.19,3.72a91.8,91.8,0,0,0,2.9,19.62c.43,1.67.84,3.34,1.37,5,24.29-3.51,42.77-1.39,58.51,3.28a165.84,165.84,0,0,1,22.93,8.91c.39-.12.76-.26,1.14-.39l-.85.53c22,10.25,41.43,22.56,71.18,24,25.24,1.22,21.36-6.36,9.89-16.62-6.08-5.43-14.27-11.61-21.44-17.64-10.22-8.6-18.24-16.86-14.89-22.17,1-1.55,2.87-2.87,6-3.85,27.33-8.51,69,8.33,104,23.59.32-1,.56-2.05.84-3.07a92.33,92.33,0,0,0,3.48-24.87V246.94A151.19,151.19,0,0,0,257.69,249.31Z"></path><path fill="currentColor" d="M192,137a78,78,0,0,1,77.78,78v73.91a78,78,0,0,1-77.78,78H118.51a78,78,0,0,1-77.78-78V215a78,78,0,0,1,77.78-78H192m0-8.33H118.51A86.21,86.21,0,0,0,32.42,215v73.91a86.21,86.21,0,0,0,86.09,86.33H192a86.21,86.21,0,0,0,86.09-86.33V215A86.21,86.21,0,0,0,192,128.64Z"></path></svg>
</a>
</div>
</div>
@@ -11,12 +11,6 @@
line-height: 32px;
}
.image.not-rounded {
border-radius: 0;
width: 60px;
height: 60px;
}
.intro {
margin: 25px auto 30px;
width: 250px;
@@ -42,11 +36,9 @@
video {
width: 640px;
height: 360px;
max-width: 90%;
margin-top: 0;
@media (min-width: 768px) {
height: 360px;
}
}
.social-icons {
@@ -59,13 +51,9 @@
.enterprise-sponsor,
.community-integrations-sponsor,
.maintainers {
margin-top: 30px;
margin-top: 68px;
margin-bottom: 68px;
scroll-margin: 30px;
@media (min-width: 768px) {
margin-top: 68px;
}
}
.maintainers {
@@ -211,16 +199,6 @@
a {
margin: 45px 10px;
}
.bitcointv svg {
width: 36px;
height: auto;
vertical-align: bottom;
margin-bottom: 2px;
margin-left: 5px;
}
.bitcointv svg:hover {
opacity: 0.75;
}
}
}
@@ -234,11 +212,6 @@
}
.community-integrations-sponsor {
max-width: 1110px;
max-width: 965px;
margin: auto;
}
.community-integrations-sponsor img.image {
width: 64px;
height: 64px;
}
@@ -121,7 +121,7 @@
<ng-container *ngIf="!isLoadingBlock; else loadingRest">
<tr *ngIf="network !== 'liquid' && network !== 'liquidtestnet'">
<td i18n="mempool-block.fee-span">Fee span</td>
<td><span>{{ block.extras.feeRange[1] | number:'1.0-0' }} - {{ block.extras.feeRange[block.extras.feeRange.length - 1] | number:'1.0-0' }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span></span></td>
<td><span>{{ block.extras.feeRange[0] | number:'1.0-0' }} - {{ block.extras.feeRange[block.extras.feeRange.length - 1] | number:'1.0-0' }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span></span></td>
</tr>
<tr *ngIf="block?.extras?.medianFee != undefined">
<td class="td-width" i18n="block.median-fee">Median fee</td>
@@ -20,8 +20,8 @@ interface BlockchainBlock extends BlockExtended {
export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy {
@Input() static: boolean = false;
@Input() offset: number = 0;
@Input() height: number = 0; // max height of blocks in chunk (dynamic blocks only)
@Input() count: number = 8; // number of blocks in this chunk (dynamic blocks only)
@Input() height: number = 0;
@Input() count: number = 8;
@Input() loadingTip: boolean = false;
@Input() connected: boolean = true;
@@ -31,7 +31,6 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy {
dynamicBlocksAmount: number = 8;
emptyBlocks: BlockExtended[] = this.mountEmptyBlocks();
markHeight: number;
chainTip: number;
blocksSubscription: Subscription;
blockPageSubscription: Subscription;
networkSubscription: Subscription;
@@ -74,7 +73,6 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy {
}
ngOnInit() {
this.chainTip = this.stateService.latestBlockHeight;
this.dynamicBlocksAmount = Math.min(8, this.stateService.env.KEEP_BLOCKS_AMOUNT);
if (['', 'testnet', 'signet'].includes(this.stateService.network)) {
@@ -109,7 +107,7 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy {
this.blocks.unshift(block);
this.blocks = this.blocks.slice(0, this.dynamicBlocksAmount);
if (txConfirmed && block.height > this.chainTip) {
if (txConfirmed) {
this.markHeight = block.height;
this.moveArrowToPosition(true, true);
} else {
@@ -117,7 +115,7 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy {
}
this.blockStyles = [];
if (this.blocksFilled && block.height > this.chainTip) {
if (this.blocksFilled) {
this.blocks.forEach((b, i) => this.blockStyles.push(this.getStyleForBlock(b, i, i ? -155 : -205)));
setTimeout(() => {
this.blockStyles = [];
@@ -131,8 +129,6 @@ export class BlockchainBlocksComponent implements OnInit, OnChanges, OnDestroy {
if (this.blocks.length === this.dynamicBlocksAmount) {
this.blocksFilled = true;
}
this.chainTip = Math.max(this.chainTip, block.height);
this.cd.markForCheck();
});
} else {
@@ -87,8 +87,8 @@ export class BlocksList implements OnInit, OnDestroy {
this.stateService.blocks$
.pipe(
switchMap((block) => {
if (block[0].height <= this.lastBlockHeight) {
return [null]; // Return an empty stream so the last pipe is not executed
if (block[0].height < this.lastBlockHeight) {
return []; // Return an empty stream so the last pipe is not executed
}
this.lastBlockHeight = block[0].height;
return [block];
@@ -101,16 +101,14 @@ export class BlocksList implements OnInit, OnDestroy {
this.lastPage = this.page;
return blocks[0];
}
if (blocks[1]) {
this.blocksCount = Math.max(this.blocksCount, blocks[1][0].height) + 1;
if (this.stateService.env.MINING_DASHBOARD) {
// @ts-ignore: Need to add an extra field for the template
blocks[1][0].extras.pool.logo = `/resources/mining-pools/` +
blocks[1][0].extras.pool.name.toLowerCase().replace(' ', '').replace('.', '') + '.svg';
}
acc.unshift(blocks[1][0]);
acc = acc.slice(0, this.widget ? 6 : 15);
this.blocksCount = Math.max(this.blocksCount, blocks[1][0].height) + 1;
if (this.stateService.env.MINING_DASHBOARD) {
// @ts-ignore: Need to add an extra field for the template
blocks[1][0].extras.pool.logo = `/resources/mining-pools/` +
blocks[1][0].extras.pool.name.toLowerCase().replace(' ', '').replace('.', '') + '.svg';
}
acc.unshift(blocks[1][0]);
acc = acc.slice(0, this.widget ? 6 : 15);
return acc;
}, [])
);
@@ -1,87 +0,0 @@
<div *ngIf="showTitle" class="main-title" i18n="dashboard.difficulty-adjustment">Difficulty Adjustment</div>
<div class="card-wrapper">
<div class="card">
<div class="card-body more-padding">
<div class="difficulty-adjustment-container" *ngIf="(isLoadingWebSocket$ | async) === false && (difficultyEpoch$ | async) as epochData; else loadingDifficulty">
<div class="item">
<h5 class="card-title" i18n="difficulty-box.remaining">Remaining</h5>
<div class="card-text">
<ng-container *ngTemplateOutlet="epochData.remainingBlocks === 1 ? blocksSingular : blocksPlural; context: {$implicit: epochData.remainingBlocks }"></ng-container>
<ng-template #blocksPlural let-i i18n="shared.blocks">{{ i }} <span class="shared-block">blocks</span></ng-template>
<ng-template #blocksSingular let-i i18n="shared.block">{{ i }} <span class="shared-block">block</span></ng-template>
</div>
<div class="symbol"><app-time kind="until" [time]="epochData.estimatedRetargetDate" [fastRender]="true"></app-time></div>
</div>
<div class="item">
<h5 class="card-title" i18n="difficulty-box.estimate">Estimate</h5>
<div *ngIf="epochData.remainingBlocks < 1870; else recentlyAdjusted" class="card-text" [ngStyle]="{'color': epochData.colorAdjustments}">
<span *ngIf="epochData.change > 0; else arrowDownDifficulty" >
<fa-icon class="retarget-sign" [icon]="['fas', 'caret-up']" [fixedWidth]="true"></fa-icon>
</span>
<ng-template #arrowDownDifficulty >
<fa-icon class="retarget-sign" [icon]="['fas', 'caret-down']" [fixedWidth]="true"></fa-icon>
</ng-template>
{{ epochData.change | absolute | number: '1.2-2' }}
<span class="symbol">%</span>
</div>
<ng-template #recentlyAdjusted>
<div class="card-text">&#8212;</div>
</ng-template>
<div class="symbol">
<span i18n="difficulty-box.previous">Previous</span>:
<span [ngStyle]="{'color': epochData.colorPreviousAdjustments}">
<span *ngIf="epochData.previousRetarget > 0; else arrowDownPreviousDifficulty" >
<fa-icon class="previous-retarget-sign" [icon]="['fas', 'caret-up']" [fixedWidth]="true"></fa-icon>
</span>
<ng-template #arrowDownPreviousDifficulty >
<fa-icon class="previous-retarget-sign" [icon]="['fas', 'caret-down']" [fixedWidth]="true"></fa-icon>
</ng-template>
{{ epochData.previousRetarget | absolute | number: '1.2-2' }} </span> %
</div>
</div>
<div class="item" *ngIf="showProgress">
<h5 class="card-title" i18n="difficulty-box.current-period">Current Period</h5>
<div class="card-text">{{ epochData.progress | number: '1.2-2' }} <span class="symbol">%</span></div>
<div class="progress small-bar">
<div class="progress-bar" role="progressbar" style="width: 15%; background-color: #105fb0" [ngStyle]="{'width': epochData.base}">&nbsp;</div>
</div>
</div>
<div class="item" *ngIf="showHalving">
<h5 class="card-title" i18n="difficulty-box.next-halving">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>
<ng-template #blocksSingular let-i i18n="shared.block">{{ i }} <span class="shared-block">block</span></ng-template>
</div>
<div class="symbol"><app-time kind="until" [time]="epochData.timeUntilHalving" [fastRender]="true"></app-time></div>
</div>
</div>
</div>
</div>
</div>
<ng-template #loadingDifficulty>
<div class="difficulty-skeleton loading-container">
<div class="item">
<h5 class="card-title" i18n="difficulty-box.remaining">Remaining</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="difficulty-box.estimate">Estimate</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="difficulty-box.current-period">Current Period</h5>
<div class="card-text">
<div class="skeleton-loader"></div>
<div class="skeleton-loader"></div>
</div>
</div>
</div>
</ng-template>
@@ -1,155 +0,0 @@
.difficulty-adjustment-container {
display: flex;
flex-direction: row;
justify-content: space-around;
height: 76px;
.shared-block {
color: #ffffff66;
font-size: 12px;
}
.item {
padding: 0 5px;
width: 100%;
&:nth-child(1) {
display: none;
@media (min-width: 485px) {
display: table-cell;
}
@media (min-width: 768px) {
display: none;
}
@media (min-width: 992px) {
display: table-cell;
}
}
}
.card-text {
font-size: 22px;
margin-top: -9px;
position: relative;
}
}
.difficulty-skeleton {
display: flex;
justify-content: space-between;
@media (min-width: 376px) {
flex-direction: row;
}
.item {
min-width: 120px;
max-width: 150px;
margin: 0;
width: -webkit-fill-available;
@media (min-width: 376px) {
margin: 0 auto 0px;
}
&:first-child{
display: none;
@media (min-width: 485px) {
display: block;
}
@media (min-width: 768px) {
display: none;
}
@media (min-width: 992px) {
display: block;
}
}
&:last-child {
margin-bottom: 0;
}
}
.card-text {
.skeleton-loader {
width: 100%;
display: block;
&:first-child {
margin: 14px auto 0;
max-width: 80px;
}
&:last-child {
margin: 10px auto 0;
max-width: 120px;
}
}
}
}
.card {
background-color: #1d1f31;
height: 100%;
}
.card-title {
color: #4a68b9;
font-size: 1rem;
}
.progress {
display: inline-flex;
width: 100%;
background-color: #2d3348;
height: 1.1rem;
max-width: 180px;
}
.skeleton-loader {
max-width: 100%;
}
.more-padding {
padding: 18px;
}
.small-bar {
height: 8px;
top: -4px;
max-width: 120px;
}
.loading-container {
min-height: 76px;
}
.main-title {
position: relative;
color: #ffffff91;
margin-top: -13px;
font-size: 10px;
text-transform: uppercase;
font-weight: 500;
text-align: center;
padding-bottom: 3px;
}
.card-wrapper {
.card {
height: auto !important;
}
.card-body {
display: flex;
flex: inherit;
text-align: center;
flex-direction: column;
justify-content: space-around;
padding: 24px 20px;
}
}
.retarget-sign {
margin-right: -3px;
font-size: 14px;
top: -2px;
position: relative;
}
.previous-retarget-sign {
margin-right: -2px;
font-size: 10px;
}
.symbol {
font-size: 13px;
}
@@ -1,86 +0,0 @@
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
import { combineLatest, Observable, timer } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { StateService } from '../../services/state.service';
interface EpochProgress {
base: string;
change: number;
progress: number;
remainingBlocks: number;
newDifficultyHeight: number;
colorAdjustments: string;
colorPreviousAdjustments: string;
estimatedRetargetDate: number;
previousRetarget: number;
blocksUntilHalving: number;
timeUntilHalving: number;
}
@Component({
selector: 'app-difficulty-mining',
templateUrl: './difficulty-mining.component.html',
styleUrls: ['./difficulty-mining.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DifficultyMiningComponent implements OnInit {
isLoadingWebSocket$: Observable<boolean>;
difficultyEpoch$: Observable<EpochProgress>;
@Input() showProgress = true;
@Input() showHalving = false;
@Input() showTitle = true;
constructor(
public stateService: StateService,
) { }
ngOnInit(): void {
this.isLoadingWebSocket$ = this.stateService.isLoadingWebSocket$;
this.difficultyEpoch$ = combineLatest([
this.stateService.blocks$.pipe(map(([block]) => block)),
this.stateService.difficultyAdjustment$,
])
.pipe(
map(([block, da]) => {
let colorAdjustments = '#ffffff66';
if (da.difficultyChange > 0) {
colorAdjustments = '#3bcc49';
}
if (da.difficultyChange < 0) {
colorAdjustments = '#dc3545';
}
let colorPreviousAdjustments = '#dc3545';
if (da.previousRetarget) {
if (da.previousRetarget >= 0) {
colorPreviousAdjustments = '#3bcc49';
}
if (da.previousRetarget === 0) {
colorPreviousAdjustments = '#ffffff66';
}
} else {
colorPreviousAdjustments = '#ffffff66';
}
const blocksUntilHalving = 210000 - (block.height % 210000);
const timeUntilHalving = new Date().getTime() + (blocksUntilHalving * 600000);
const data = {
base: `${da.progressPercent.toFixed(2)}%`,
change: da.difficultyChange,
progress: da.progressPercent,
remainingBlocks: da.remainingBlocks - 1,
colorAdjustments,
colorPreviousAdjustments,
newDifficultyHeight: da.nextRetargetHeight,
estimatedRetargetDate: da.estimatedRetargetDate,
previousRetarget: da.previousRetarget,
blocksUntilHalving,
timeUntilHalving,
};
return data;
})
);
}
}
@@ -1,41 +0,0 @@
<div
#tooltip
*ngIf="status"
class="difficulty-tooltip"
[style.visibility]="status ? 'visible' : 'hidden'"
[style.left]="tooltipPosition.x + 'px'"
[style.top]="tooltipPosition.y + 'px'"
>
<ng-container [ngSwitch]="status">
<ng-container *ngSwitchCase="'mined'">
<ng-container *ngIf="isAhead">
<ng-container *ngTemplateOutlet="expected === 1 ? blocksSingular : blocksPlural; context: {$implicit: expected }"></ng-container>
<ng-template #blocksPlural let-i i18n="difficulty-box.expected-blocks">{{ i }} blocks expected</ng-template>
<ng-template #blocksSingular let-i i18n="difficulty-box.expected-block">{{ i }} block expected</ng-template>
</ng-container>
<ng-container *ngIf="!isAhead">
<ng-container *ngTemplateOutlet="mined === 1 ? blocksSingular : blocksPlural; context: {$implicit: mined }"></ng-container>
<ng-template #blocksPlural let-i i18n="difficulty-box.mined-blocks">{{ i }} blocks mined</ng-template>
<ng-template #blocksSingular let-i i18n="difficulty-box.mined-block">{{ i }} block mined</ng-template>
</ng-container>
</ng-container>
<ng-container *ngSwitchCase="'remaining'">
<ng-container *ngTemplateOutlet="remaining === 1 ? blocksSingular : blocksPlural; context: {$implicit: remaining }"></ng-container>
<ng-template #blocksPlural let-i i18n="difficulty-box.remaining-blocks">{{ i }} blocks remaining</ng-template>
<ng-template #blocksSingular let-i i18n="difficulty-box.remaining-block">{{ i }} block remaining</ng-template>
</ng-container>
<ng-container *ngSwitchCase="'ahead'">
<ng-container *ngTemplateOutlet="ahead === 1 ? blocksSingular : blocksPlural; context: {$implicit: ahead }"></ng-container>
<ng-template #blocksPlural let-i i18n="difficulty-box.blocks-ahead">{{ i }} blocks ahead</ng-template>
<ng-template #blocksSingular let-i i18n="difficulty-box.block-ahead">{{ i }} block ahead</ng-template>
</ng-container>
<ng-container *ngSwitchCase="'behind'">
<ng-container *ngTemplateOutlet="behind === 1 ? blocksSingular : blocksPlural; context: {$implicit: behind }"></ng-container>
<ng-template #blocksPlural let-i i18n="difficulty-box.blocks-behind">{{ i }} blocks behind</ng-template>
<ng-template #blocksSingular let-i i18n="difficulty-box.block-behind">{{ i }} block behind</ng-template>
</ng-container>
<ng-container *ngSwitchCase="'next'">
<span class="next-block" i18n="@@bdf0e930eb22431140a2eaeacd809cc5f8ebd38c">Next Block</span>
</ng-container>
</ng-container>
</div>
@@ -1,22 +0,0 @@
.difficulty-tooltip {
position: fixed;
background: rgba(#11131f, 0.95);
border-radius: 4px;
box-shadow: 1px 1px 10px rgba(0,0,0,0.5);
color: #b1b1b1;
padding: 10px 15px;
text-align: left;
pointer-events: none;
max-width: 300px;
min-width: 200px;
text-align: center;
p {
margin: 0;
white-space: nowrap;
}
}
.next-block {
text-transform: lowercase;
}
@@ -1,66 +0,0 @@
import { Component, ElementRef, ViewChild, Input, OnChanges } from '@angular/core';
interface EpochProgress {
base: string;
change: number;
progress: number;
minedBlocks: number;
remainingBlocks: number;
expectedBlocks: number;
newDifficultyHeight: number;
colorAdjustments: string;
colorPreviousAdjustments: string;
estimatedRetargetDate: number;
previousRetarget: number;
blocksUntilHalving: number;
timeUntilHalving: number;
}
const EPOCH_BLOCK_LENGTH = 2016; // Bitcoin mainnet
@Component({
selector: 'app-difficulty-tooltip',
templateUrl: './difficulty-tooltip.component.html',
styleUrls: ['./difficulty-tooltip.component.scss'],
})
export class DifficultyTooltipComponent implements OnChanges {
@Input() status: string | void;
@Input() progress: EpochProgress | void = null;
@Input() cursorPosition: { x: number, y: number };
mined: number;
ahead: number;
behind: number;
expected: number;
remaining: number;
isAhead: boolean;
isBehind: boolean;
tooltipPosition = { x: 0, y: 0 };
@ViewChild('tooltip') tooltipElement: ElementRef<HTMLCanvasElement>;
constructor() {}
ngOnChanges(changes): void {
if (changes.cursorPosition && changes.cursorPosition.currentValue) {
let x = changes.cursorPosition.currentValue.x;
let y = changes.cursorPosition.currentValue.y - 50;
if (this.tooltipElement) {
const elementBounds = this.tooltipElement.nativeElement.getBoundingClientRect();
x -= elementBounds.width / 2;
x = Math.min(Math.max(x, 20), (window.innerWidth - 20 - elementBounds.width));
}
this.tooltipPosition = { x, y };
}
if ((changes.progress || changes.status) && this.progress && this.status) {
this.remaining = this.progress.remainingBlocks;
this.expected = this.progress.expectedBlocks;
this.mined = this.progress.minedBlocks;
this.ahead = Math.max(0, this.mined - this.expected);
this.behind = Math.max(0, this.expected - this.mined);
this.isAhead = this.ahead > 0;
this.isBehind = this.behind > 0;
}
}
}
@@ -3,100 +3,81 @@
<div class="card">
<div class="card-body more-padding">
<div class="difficulty-adjustment-container" *ngIf="(isLoadingWebSocket$ | async) === false && (difficultyEpoch$ | async) as epochData; else loadingDifficulty">
<div class="epoch-progress">
<svg class="epoch-blocks" height="22px" width="100%" viewBox="0 0 224 9" shape-rendering="crispEdges" preserveAspectRatio="none">
<defs>
<linearGradient id="diff-gradient" x1="0%" y1="0%" x2="100%" y2="0%" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#105fb0" />
<stop offset="100%" stop-color="#9339f4" />
</linearGradient>
<linearGradient id="diff-hover-gradient" x1="0%" y1="0%" x2="100%" y2="0%" gradientUnits="userSpaceOnUse">
<stop offset="0%" stop-color="#2486eb" />
<stop offset="100%" stop-color="#ae6af7" />
</linearGradient>
</defs>
<rect
*ngFor="let rect of shapes"
[attr.x]="rect.x" [attr.y]="rect.y"
[attr.width]="rect.w" [attr.height]="rect.h"
class="rect {{rect.status}}"
[class.hover]="hoverSection && rect.status === hoverSection.status"
(pointerover)="onHover($event, rect);"
(pointerout)="onBlur($event);"
>
<animate
*ngIf="rect.status === 'next'"
attributeType="XML"
attributeName="fill"
[attr.values]="'#fff;' + (rect.expected ? '#D81B60' : '#2d3348') + ';#fff'"
dur="2s"
repeatCount="indefinite"/>
</rect>
</svg>
<div class="item">
<h5 class="card-title" i18n="difficulty-box.remaining">Remaining</h5>
<div class="card-text">
<ng-container *ngTemplateOutlet="epochData.remainingBlocks === 1 ? blocksSingular : blocksPlural; context: {$implicit: epochData.remainingBlocks }"></ng-container>
<ng-template #blocksPlural let-i i18n="shared.blocks">{{ i }} <span class="shared-block">blocks</span></ng-template>
<ng-template #blocksSingular let-i i18n="shared.block">{{ i }} <span class="shared-block">block</span></ng-template>
</div>
<div class="symbol"><app-time kind="until" [time]="epochData.estimatedRetargetDate" [fastRender]="true"></app-time></div>
</div>
<div class="difficulty-stats">
<div class="item">
<div class="card-text">
~<app-time [time]="epochData.timeAvg / 1000" [forceFloorOnTimeIntervals]="['minute']" [fractionDigits]="1"></app-time>
</div>
<div class="symbol" i18n="difficulty-box.average-block-time">Average block time</div>
</div>
<div class="item">
<div *ngIf="epochData.remainingBlocks < 1870; else recentlyAdjusted" class="card-text" [ngStyle]="{'color': epochData.colorAdjustments}">
<span *ngIf="epochData.change > 0; else arrowDownDifficulty" >
<fa-icon class="retarget-sign" [icon]="['fas', 'caret-up']" [fixedWidth]="true"></fa-icon>
</span>
<ng-template #arrowDownDifficulty >
<fa-icon class="retarget-sign" [icon]="['fas', 'caret-down']" [fixedWidth]="true"></fa-icon>
</ng-template>
{{ epochData.change | absolute | number: '1.2-2' }}
<span class="symbol">%</span>
</div>
<ng-template #recentlyAdjusted>
<div class="card-text">&#8212;</div>
<div class="item">
<h5 class="card-title" i18n="difficulty-box.estimate">Estimate</h5>
<div *ngIf="epochData.remainingBlocks < 1870; else recentlyAdjusted" class="card-text" [ngStyle]="{'color': epochData.colorAdjustments}">
<span *ngIf="epochData.change > 0; else arrowDownDifficulty" >
<fa-icon class="retarget-sign" [icon]="['fas', 'caret-up']" [fixedWidth]="true"></fa-icon>
</span>
<ng-template #arrowDownDifficulty >
<fa-icon class="retarget-sign" [icon]="['fas', 'caret-down']" [fixedWidth]="true"></fa-icon>
</ng-template>
<div class="symbol">
<span i18n="difficulty-box.previous">Previous</span>:
<span [ngStyle]="{'color': epochData.colorPreviousAdjustments}">
<span *ngIf="epochData.previousRetarget > 0; else arrowDownPreviousDifficulty" >
<fa-icon class="previous-retarget-sign" [icon]="['fas', 'caret-up']" [fixedWidth]="true"></fa-icon>
</span>
<ng-template #arrowDownPreviousDifficulty >
<fa-icon class="previous-retarget-sign" [icon]="['fas', 'caret-down']" [fixedWidth]="true"></fa-icon>
</ng-template>
{{ epochData.previousRetarget | absolute | number: '1.2-2' }} </span> %
</div>
{{ epochData.change | absolute | number: '1.2-2' }}
<span class="symbol">%</span>
</div>
<div class="item">
<div class="card-text"><app-time kind="until" [time]="epochData.estimatedRetargetDate" [fastRender]="true"></app-time></div>
<div class="symbol">
{{ epochData.retargetDateString }}
</div>
<ng-template #recentlyAdjusted>
<div class="card-text">&#8212;</div>
</ng-template>
<div class="symbol">
<span i18n="difficulty-box.previous">Previous</span>:
<span [ngStyle]="{'color': epochData.colorPreviousAdjustments}">
<span *ngIf="epochData.previousRetarget > 0; else arrowDownPreviousDifficulty" >
<fa-icon class="previous-retarget-sign" [icon]="['fas', 'caret-up']" [fixedWidth]="true"></fa-icon>
</span>
<ng-template #arrowDownPreviousDifficulty >
<fa-icon class="previous-retarget-sign" [icon]="['fas', 'caret-down']" [fixedWidth]="true"></fa-icon>
</ng-template>
{{ epochData.previousRetarget | absolute | number: '1.2-2' }} </span> %
</div>
</div>
<div class="item" *ngIf="showProgress">
<h5 class="card-title" i18n="difficulty-box.current-period">Current Period</h5>
<div class="card-text">{{ epochData.progress | number: '1.2-2' }} <span class="symbol">%</span></div>
<div class="progress small-bar">
<div class="progress-bar" role="progressbar" style="width: 15%; background-color: #105fb0" [ngStyle]="{'width': epochData.base}">&nbsp;</div>
</div>
</div>
<div class="item" *ngIf="showHalving">
<h5 class="card-title" i18n="difficulty-box.next-halving">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>
<ng-template #blocksSingular let-i i18n="shared.block">{{ i }} <span class="shared-block">block</span></ng-template>
</div>
<div class="symbol"><app-time kind="until" [time]="epochData.timeUntilHalving" [fastRender]="true"></app-time></div>
</div>
</div>
</div>
</div>
</div>
<ng-template #loadingDifficulty>
<div class="epoch-progress">
<div class="skeleton-loader"></div>
</div>
<div class="difficulty-skeleton loading-container">
<div class="item">
<h5 class="card-title" i18n="difficulty-box.remaining">Remaining</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="difficulty-box.estimate">Estimate</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="difficulty-box.current-period">Current Period</h5>
<div class="card-text">
<div class="skeleton-loader"></div>
<div class="skeleton-loader"></div>
@@ -104,10 +85,3 @@
</div>
</div>
</ng-template>
<app-difficulty-tooltip
*ngIf="hoverSection && (isLoadingWebSocket$ | async) === false && (difficultyEpoch$ | async) as epochData"
[cursorPosition]="tooltipPosition"
[status]="hoverSection.status"
[progress]="epochData"
></app-difficulty-tooltip>
@@ -1,14 +1,8 @@
.difficulty-adjustment-container {
display: flex;
flex-direction: column;
justify-content: space-between;
}
.difficulty-stats {
display: flex;
flex-direction: row;
justify-content: space-around;
height: 50.5px;
height: 76px;
.shared-block {
color: #ffffff66;
font-size: 12px;
@@ -30,8 +24,8 @@
}
}
.card-text {
font-size: 20px;
margin: auto;
font-size: 22px;
margin-top: -9px;
position: relative;
}
}
@@ -39,14 +33,11 @@
.difficulty-skeleton {
display: flex;
flex-direction: row;
justify-content: space-around;
height: 50.5px;
justify-content: space-between;
@media (min-width: 376px) {
flex-direction: row;
}
.item {
min-width: 120px;
max-width: 150px;
margin: 0;
width: -webkit-fill-available;
@@ -74,7 +65,7 @@
width: 100%;
display: block;
&:first-child {
margin: 10px auto 4px;
margin: 14px auto 0;
max-width: 80px;
}
&:last-child {
@@ -118,7 +109,7 @@
}
.loading-container {
min-height: 50.5px;
min-height: 76px;
}
.main-title {
@@ -142,7 +133,7 @@
text-align: center;
flex-direction: column;
justify-content: space-around;
padding: 20px;
padding: 24px 20px;
}
}
@@ -160,50 +151,4 @@
.symbol {
font-size: 13px;
}
.epoch-progress {
width: 100%;
height: 22px;
margin-bottom: 12px;
}
.epoch-blocks {
display: block;
width: 100%;
background: #2d3348;
.rect {
fill: #2d3348;
&.behind {
fill: #D81B60;
}
&.mined {
fill: url(#diff-gradient);
}
&.ahead {
fill: #1a9436;
}
&.hover {
fill: #535e84;
&.behind {
fill: #e94d86;
}
&.mined {
fill: url(#diff-hover-gradient);
}
&.ahead {
fill: #29d951;
}
}
}
}
.blocks-ahead {
color: #3bcc49;
}
.blocks-behind {
color: #D81B60;
}
@@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, Component, HostListener, Inject, Input, LOCALE_ID, OnInit } from '@angular/core';
import { ChangeDetectionStrategy, Component, Input, OnInit } from '@angular/core';
import { combineLatest, Observable, timer } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { StateService } from '../..//services/state.service';
@@ -7,33 +7,16 @@ interface EpochProgress {
base: string;
change: number;
progress: number;
minedBlocks: number;
remainingBlocks: number;
expectedBlocks: number;
newDifficultyHeight: number;
colorAdjustments: string;
colorPreviousAdjustments: string;
estimatedRetargetDate: number;
retargetDateString: string;
previousRetarget: number;
blocksUntilHalving: number;
timeUntilHalving: number;
timeAvg: number;
}
type BlockStatus = 'mined' | 'behind' | 'ahead' | 'next' | 'remaining';
interface DiffShape {
x: number;
y: number;
w: number;
h: number;
status: BlockStatus;
expected: boolean;
}
const EPOCH_BLOCK_LENGTH = 2016; // Bitcoin mainnet
@Component({
selector: 'app-difficulty',
templateUrl: './difficulty.component.html',
@@ -41,27 +24,15 @@ const EPOCH_BLOCK_LENGTH = 2016; // Bitcoin mainnet
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DifficultyComponent implements OnInit {
@Input() showProgress = true;
@Input() showHalving = false;
@Input() showTitle = true;
isLoadingWebSocket$: Observable<boolean>;
difficultyEpoch$: Observable<EpochProgress>;
epochStart: number;
currentHeight: number;
currentIndex: number;
expectedHeight: number;
expectedIndex: number;
difference: number;
shapes: DiffShape[];
tooltipPosition = { x: 0, y: 0 };
hoverSection: DiffShape | void;
@Input() showProgress = true;
@Input() showHalving = false;
@Input() showTitle = true;
constructor(
public stateService: StateService,
@Inject(LOCALE_ID) private locale: string,
) { }
ngOnInit(): void {
@@ -94,110 +65,22 @@ export class DifficultyComponent implements OnInit {
const blocksUntilHalving = 210000 - (block.height % 210000);
const timeUntilHalving = new Date().getTime() + (blocksUntilHalving * 600000);
const newEpochStart = Math.floor(this.stateService.latestBlockHeight / EPOCH_BLOCK_LENGTH) * EPOCH_BLOCK_LENGTH;
const newExpectedHeight = Math.floor(newEpochStart + da.expectedBlocks);
if (newEpochStart !== this.epochStart || newExpectedHeight !== this.expectedHeight || this.currentHeight !== this.stateService.latestBlockHeight) {
this.epochStart = newEpochStart;
this.expectedHeight = newExpectedHeight;
this.currentHeight = this.stateService.latestBlockHeight;
this.currentIndex = this.currentHeight - this.epochStart;
this.expectedIndex = Math.min(this.expectedHeight - this.epochStart, 2016) - 1;
this.difference = this.currentIndex - this.expectedIndex;
this.shapes = [];
this.shapes = this.shapes.concat(this.blocksToShapes(
0, Math.min(this.currentIndex, this.expectedIndex), 'mined', true
));
this.shapes = this.shapes.concat(this.blocksToShapes(
this.currentIndex + 1, this.expectedIndex, 'behind', true
));
this.shapes = this.shapes.concat(this.blocksToShapes(
this.expectedIndex + 1, this.currentIndex, 'ahead', false
));
if (this.currentIndex < 2015) {
this.shapes = this.shapes.concat(this.blocksToShapes(
this.currentIndex + 1, this.currentIndex + 1, 'next', (this.expectedIndex > this.currentIndex)
));
}
this.shapes = this.shapes.concat(this.blocksToShapes(
Math.max(this.currentIndex + 2, this.expectedIndex + 1), 2105, 'remaining', false
));
}
let retargetDateString;
if (da.remainingBlocks > 1870) {
retargetDateString = (new Date(da.estimatedRetargetDate)).toLocaleDateString(this.locale, { month: 'long', day: 'numeric' });
} else {
retargetDateString = (new Date(da.estimatedRetargetDate)).toLocaleTimeString(this.locale, { month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric' });
}
const data = {
base: `${da.progressPercent.toFixed(2)}%`,
change: da.difficultyChange,
progress: da.progressPercent,
minedBlocks: this.currentIndex + 1,
remainingBlocks: da.remainingBlocks - 1,
expectedBlocks: Math.floor(da.expectedBlocks),
remainingBlocks: da.remainingBlocks,
colorAdjustments,
colorPreviousAdjustments,
newDifficultyHeight: da.nextRetargetHeight,
estimatedRetargetDate: da.estimatedRetargetDate,
retargetDateString,
previousRetarget: da.previousRetarget,
blocksUntilHalving,
timeUntilHalving,
timeAvg: da.timeAvg,
};
return data;
})
);
}
blocksToShapes(start: number, end: number, status: BlockStatus, expected: boolean = false): DiffShape[] {
const startY = start % 9;
const startX = Math.floor(start / 9);
const endY = (end % 9);
const endX = Math.floor(end / 9);
if (startX > endX) {
return [];
}
if (startX === endX) {
return [{
x: startX, y: startY, w: 1, h: 1 + endY - startY, status, expected
}];
}
const shapes = [];
shapes.push({
x: startX, y: startY, w: 1, h: 9 - startY, status, expected
});
shapes.push({
x: endX, y: 0, w: 1, h: endY + 1, status, expected
});
if (startX < endX - 1) {
shapes.push({
x: startX + 1, y: 0, w: endX - startX - 1, h: 9, status, expected
});
}
return shapes;
}
@HostListener('pointermove', ['$event'])
onPointerMove(event) {
this.tooltipPosition = { x: event.clientX, y: event.clientY };
}
onHover(event, rect): void {
this.hoverSection = rect;
}
onBlur(event): void {
this.hoverSection = null;
}
}
@@ -214,7 +214,6 @@ export class MempoolBlocksComponent implements OnInit, OnDestroy {
lastBlock.feeRange = lastBlock.feeRange.concat(block.feeRange);
lastBlock.feeRange.sort((a, b) => a - b);
lastBlock.medianFee = this.median(lastBlock.feeRange);
lastBlock.totalFees += block.totalFees;
}
return blocks;
}
@@ -4,6 +4,7 @@
<div class="row row-cols-1 row-cols-md-2">
<!-- Temporary stuff here - Will be moved to a component once we have more useful data to show -->
<div class="col">
<div class="main-title">
<span [attr.data-cy]="'reward-stats'" i18n="mining.reward-stats">Reward stats</span>&nbsp;
@@ -21,7 +22,7 @@
<!-- difficulty adjustment -->
<div class="col">
<div class="main-title" i18n="dashboard.difficulty-adjustment">Difficulty Adjustment</div>
<app-difficulty-mining [attr.data-cy]="'difficulty-adjustment'" [showTitle]="false" [showProgress]="false" [showHalving]="true"></app-difficulty-mining>
<app-difficulty [attr.data-cy]="'difficulty-adjustment'" [showTitle]="false" [showProgress]="false" [showHalving]="true"></app-difficulty>
</div>
<!-- pool distribution -->
@@ -162,10 +162,10 @@ export class PoolRankingComponent implements OnInit {
if (this.miningWindowPreference === '24h') {
return `<b style="color: white">${pool.name} (${pool.share}%)</b><br>` +
pool.lastEstimatedHashrate.toString() + ' PH/s' +
`<br>` + $localize`${ i }:INTERPOLATION: blocks`;
`<br>` + $localize`${i} blocks`;
} else {
return `<b style="color: white">${pool.name} (${pool.share}%)</b><br>` +
$localize`${ i }:INTERPOLATION: blocks`;
$localize`${i} blocks`;
}
}
},
@@ -195,15 +195,13 @@ export class PoolRankingComponent implements OnInit {
},
borderColor: '#000',
formatter: () => {
const percentage = totalShareOther.toFixed(2) + '%';
const i = totalBlockOther.toString();
if (this.miningWindowPreference === '24h') {
return `<b style="color: white">` + $localize`Other (${percentage})` + `</b><br>` +
return `<b style="color: white">${'Other'} (${totalShareOther.toFixed(2)}%)</b><br>` +
totalEstimatedHashrateOther.toString() + ' PH/s' +
`<br>` + $localize`${ i }:INTERPOLATION: blocks`;
`<br>` + totalBlockOther.toString() + ` blocks`;
} else {
return `<b style="color: white">` + $localize`Other (${percentage})` + `</b><br>` +
$localize`${ i }:INTERPOLATION: blocks`;
return `<b style="color: white">${'Other'} (${totalShareOther.toFixed(2)}%)</b><br>` +
totalBlockOther.toString() + ` blocks`;
}
}
},
@@ -53,8 +53,3 @@ form {
margin-top: 1px;
margin-right: 2px;
}
input:focus {
box-shadow: none;
border-color: #1b1f2c;
}
@@ -19,7 +19,6 @@ export class TimeComponent implements OnInit, OnChanges, OnDestroy {
@Input() fixedRender = false;
@Input() relative = false;
@Input() forceFloorOnTimeIntervals: string[];
@Input() fractionDigits: number = 0;
constructor(
private ref: ChangeDetectorRef,
@@ -89,12 +88,7 @@ export class TimeComponent implements OnInit, OnChanges, OnDestroy {
} else {
counter = Math.round(seconds / this.intervals[i]);
}
let rounded = counter;
if (this.fractionDigits) {
const roundFactor = Math.pow(10,this.fractionDigits);
rounded = Math.round((seconds / this.intervals[i]) * roundFactor) / roundFactor;
}
const dateStrings = dates(rounded);
const dateStrings = dates(counter);
if (counter > 0) {
switch (this.kind) {
case 'since':
@@ -67,7 +67,7 @@
<td><app-time kind="span" [time]="tx.status.block_time - transactionTime" [fastRender]="true" [relative]="true"></app-time></td>
</tr>
</ng-template>
<tr *ngIf="network !== 'liquid' && network !== 'liquidtestnet' && featuresEnabled">
<tr *ngIf="network !== 'liquid' && network !== 'liquidtestnet'">
<td class="td-width" i18n="transaction.features|Transaction features">Features</td>
<td>
<app-tx-features [tx]="tx"></app-tx-features>
@@ -468,7 +468,6 @@
<ng-template #feeTable>
<table class="table table-borderless table-striped">
<tbody>
<tr *ngIf="isMobile && (network === 'liquid' || network === 'liquidtestnet' || !featuresEnabled)"></tr>
<tr>
<td class="td-width" i18n="transaction.fee|Transaction fee">Fee</td>
<td>{{ tx.fee | number }} <span class="symbol" i18n="shared.sat|sat">sat</span> <span class="fiat"><app-fiat [blockConversion]="blockConversion" [value]="tx.fee"></app-fiat></span></td>
@@ -489,7 +488,7 @@
<div class="effective-fee-container">
{{ tx.effectiveFeePerVsize | feeRounding }} <span class="symbol" i18n="shared.sat-vbyte|sat/vB">sat/vB</span>
<ng-template [ngIf]="tx.status.confirmed">
<app-tx-fee-rating class="ml-2 mr-2" *ngIf="tx.fee || tx.effectiveFeePerVsize" [tx]="tx"></app-tx-fee-rating>
<app-tx-fee-rating class="d-none d-lg-inline ml-2" *ngIf="tx.fee" [tx]="tx"></app-tx-fee-rating>
</ng-template>
</div>
<button type="button" class="btn btn-outline-info btn-sm btn-small-height float-right" (click)="showCpfpDetails = !showCpfpDetails">CPFP <fa-icon [icon]="['fas', 'info-circle']" [fixedWidth]="true"></fa-icon></button>
@@ -23,7 +23,6 @@ import { BlockExtended, CpfpInfo } from '../../interfaces/node-api.interface';
import { LiquidUnblinding } from './liquid-ublinding';
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
import { Price, PriceService } from '../../services/price.service';
import { isFeatureActive } from '../../bitcoin.utils';
@Component({
selector: 'app-transaction',
@@ -75,12 +74,6 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
flowEnabled: boolean;
blockConversion: Price;
tooltipPosition: { x: number, y: number };
isMobile: boolean;
featuresEnabled: boolean;
segwitEnabled: boolean;
rbfEnabled: boolean;
taprootEnabled: boolean;
@ViewChild('graphContainer')
graphContainer: ElementRef;
@@ -204,7 +197,6 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
}
this.tx = tx;
this.setFeatures();
this.isCached = true;
if (tx.fee === undefined) {
this.tx.fee = 0;
@@ -299,7 +291,6 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
}
this.tx = tx;
this.setFeatures();
this.isCached = false;
if (tx.fee === undefined) {
this.tx.fee = 0;
@@ -356,7 +347,7 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
this.blocksSubscription = this.stateService.blocks$.subscribe(([block, txConfirmed]) => {
this.latestBlock = block;
if (txConfirmed && this.tx && !this.tx.status.confirmed) {
if (txConfirmed && this.tx) {
this.tx.status = {
confirmed: true,
block_height: block.height,
@@ -437,23 +428,9 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
});
}
setFeatures(): void {
if (this.tx) {
this.segwitEnabled = !this.tx.status.confirmed || isFeatureActive(this.stateService.network, this.tx.status.block_height, 'segwit');
this.taprootEnabled = !this.tx.status.confirmed || isFeatureActive(this.stateService.network, this.tx.status.block_height, 'taproot');
this.rbfEnabled = !this.tx.status.confirmed || isFeatureActive(this.stateService.network, this.tx.status.block_height, 'rbf');
} else {
this.segwitEnabled = false;
this.taprootEnabled = false;
this.rbfEnabled = false;
}
this.featuresEnabled = this.segwitEnabled || this.taprootEnabled || this.rbfEnabled;
}
resetTransaction() {
this.error = undefined;
this.tx = null;
this.setFeatures();
this.waitingForTransaction = false;
this.isLoadingTx = true;
this.rbfTransaction = undefined;
@@ -518,11 +495,8 @@ export class TransactionComponent implements OnInit, AfterViewInit, OnDestroy {
@HostListener('window:resize', ['$event'])
setGraphSize(): void {
this.isMobile = window.innerWidth < 850;
if (this.graphContainer) {
setTimeout(() => {
this.graphWidth = this.graphContainer.nativeElement.clientWidth;
}, 1);
this.graphWidth = this.graphContainer.nativeElement.clientWidth;
}
}
@@ -1,7 +1,7 @@
import { Component, OnInit, Input, ChangeDetectionStrategy, OnChanges, Output, EventEmitter, ChangeDetectorRef } from '@angular/core';
import { StateService } from '../../services/state.service';
import { CacheService } from '../../services/cache.service';
import { Observable, ReplaySubject, BehaviorSubject, merge, Subscription, of, forkJoin } from 'rxjs';
import { Observable, ReplaySubject, BehaviorSubject, merge, Subscription, of } from 'rxjs';
import { Outspend, Transaction, Vin, Vout } from '../../interfaces/electrs.interface';
import { ElectrsApiService } from '../../services/electrs-api.service';
import { environment } from '../../../environments/environment';
@@ -70,19 +70,12 @@ export class TransactionsListComponent implements OnInit, OnChanges {
.pipe(
switchMap((txIds) => {
if (!this.cached) {
// break list into batches of 50 (maximum supported by esplora)
const batches = [];
for (let i = 0; i < txIds.length; i += 50) {
batches.push(txIds.slice(i, i + 50));
}
return forkJoin(batches.map(batch => this.apiService.getOutspendsBatched$(batch)));
return this.apiService.getOutspendsBatched$(txIds);
} else {
return of([]);
}
}),
tap((batchedOutspends: Outspend[][][]) => {
// flatten batched results back into a single array
const outspends = batchedOutspends.flat(1);
tap((outspends: Outspend[][]) => {
if (!this.transactions) {
return;
}
@@ -56,25 +56,9 @@
</ng-container>
</ng-container>
<p *ngIf="line.value == null && line.confidential" i18n="shared.confidential">Confidential</p>
<p *ngIf="line.value != null">
<ng-template [ngIf]="line.asset && line.asset !== nativeAssetId" [ngIfElse]="defaultOutput">
<div *ngIf="assetsMinimal && assetsMinimal[line.asset] else assetNotFound">
<ng-container *ngTemplateOutlet="assetBox; context:{ $implicit: line }"></ng-container>
</div>
<ng-template #assetNotFound>
{{ line.value }} <span class="symbol">{{ line.asset | slice : 0 : 7 }}</span>
</ng-template>
</ng-template>
<ng-template #defaultOutput>
<app-amount [blockConversion]="blockConversion" [satoshis]="line.value"></app-amount>
</ng-template>
</p>
<p *ngIf="line.value != null"><app-amount [blockConversion]="blockConversion" [satoshis]="line.value"></app-amount></p>
<p *ngIf="line.type !== 'fee' && line.address" class="address">
<app-truncate [text]="line.address"></app-truncate>
</p>
</ng-template>
</div>
<ng-template #assetBox let-item>
{{ item.value / pow(10, assetsMinimal[item.asset][3]) | number: '1.' + assetsMinimal[item.asset][3] + '-' + assetsMinimal[item.asset][3] }} <span class="symbol">{{ assetsMinimal[item.asset][1] }}</span>
</ng-template>
@@ -1,8 +1,6 @@
import { Component, ElementRef, ViewChild, Input, OnChanges, OnInit } from '@angular/core';
import { tap } from 'rxjs';
import { Price, PriceService } from '../../services/price.service';
import { StateService } from '../../services/state.service';
import { environment } from '../../../environments/environment';
interface Xput {
type: 'input' | 'output' | 'fee';
@@ -18,7 +16,6 @@ interface Xput {
pegout?: string;
confidential?: boolean;
timestamp?: number;
asset?: string;
}
@Component({
@@ -30,19 +27,13 @@ export class TxBowtieGraphTooltipComponent implements OnChanges {
@Input() line: Xput | void;
@Input() cursorPosition: { x: number, y: number };
@Input() isConnector: boolean = false;
@Input() assetsMinimal: any;
tooltipPosition = { x: 0, y: 0 };
blockConversion: Price;
nativeAssetId = this.stateService.network === 'liquidtestnet' ? environment.nativeTestAssetId : environment.nativeAssetId;
@ViewChild('tooltip') tooltipElement: ElementRef<HTMLCanvasElement>;
constructor(
private priceService: PriceService,
private stateService: StateService,
) {}
constructor(private priceService: PriceService) {}
ngOnChanges(changes): void {
if (changes.line?.currentValue) {
@@ -69,8 +60,4 @@ export class TxBowtieGraphTooltipComponent implements OnChanges {
this.tooltipPosition = { x, y };
}
}
pow(base: number, exponent: number): number {
return Math.pow(base, exponent);
}
}
@@ -172,6 +172,5 @@
[line]="hoverLine"
[cursorPosition]="tooltipPosition"
[isConnector]="hoverConnector"
[assetsMinimal]="assetsMinimal"
></app-tx-bowtie-graph-tooltip>
</div>
@@ -6,7 +6,6 @@ import { ReplaySubject, merge, Subscription, of } from 'rxjs';
import { tap, switchMap } from 'rxjs/operators';
import { ApiService } from '../../services/api.service';
import { RelativeUrlPipe } from '../../shared/pipes/relative-url/relative-url.pipe';
import { AssetsService } from '../../services/assets.service';
interface SvgLine {
path: string;
@@ -31,7 +30,6 @@ interface Xput {
pegout?: string;
confidential?: boolean;
timestamp?: number;
asset?: string;
}
@Component({
@@ -73,7 +71,6 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
zeroValueWidth = 60;
zeroValueThickness = 20;
hasLine: boolean;
assetsMinimal: any;
outspendsSubscription: Subscription;
refreshOutspends$: ReplaySubject<string> = new ReplaySubject();
@@ -98,7 +95,6 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
private relativeUrlPipe: RelativeUrlPipe,
private stateService: StateService,
private apiService: ApiService,
private assetsService: AssetsService,
@Inject(LOCALE_ID) private locale: string,
) {
if (this.locale.startsWith('ar') || this.locale.startsWith('fa') || this.locale.startsWith('he')) {
@@ -109,12 +105,6 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
ngOnInit(): void {
this.initGraph();
if (this.network === 'liquid' || this.network === 'liquidtestnet') {
this.assetsService.getAssetsMinimalJson$.subscribe((assets) => {
this.assetsMinimal = assets;
});
}
this.outspendsSubscription = merge(
this.refreshOutspends$
.pipe(
@@ -172,8 +162,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
index: i,
pegout: v?.pegout?.scriptpubkey_address,
confidential: (this.isLiquid && v?.value === undefined),
timestamp: this.tx.status.block_time,
asset: v?.asset,
timestamp: this.tx.status.block_time
} as Xput;
});
@@ -193,8 +182,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
coinbase: v?.is_coinbase,
pegin: v?.is_pegin,
confidential: (this.isLiquid && v?.prevout?.value === undefined),
timestamp: this.tx.status.block_time,
asset: v?.prevout?.asset,
timestamp: this.tx.status.block_time
} as Xput;
});
@@ -220,8 +208,8 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
this.outputs = this.initLines('out', voutWithFee, totalValue, this.maxStrands);
this.middle = {
path: `M ${(this.width / 2) - this.midWidth} ${(this.height / 2) + 0.25} L ${(this.width / 2) + this.midWidth} ${(this.height / 2) + 0.25}`,
style: `stroke-width: ${this.combinedWeight + 0.5}; stroke: ${this.gradient[1]}`
path: `M ${(this.width / 2) - this.midWidth} ${(this.height / 2) + 0.5} L ${(this.width / 2) + this.midWidth} ${(this.height / 2) + 0.5}`,
style: `stroke-width: ${this.combinedWeight + 1}; stroke: ${this.gradient[1]}`
};
this.hasLine = this.inputs.reduce((line, put) => line || !put.zeroValue, false)
@@ -278,7 +266,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
const lineParams = weights.map((w, i) => {
return {
weight: w,
thickness: xputs[i].value === 0 ? this.zeroValueThickness : Math.min(this.combinedWeight + 0.5, Math.max(this.minWeight - 1, w) + 1),
thickness: xputs[i].value === 0 ? this.zeroValueThickness : Math.max(this.minWeight - 1, w) + 1,
offset: 0,
innerY: 0,
outerY: 0,
@@ -290,7 +278,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
// bounds of the middle segment
const innerTop = (this.height / 2) - (this.combinedWeight / 2);
const innerBottom = innerTop + this.combinedWeight + 0.5;
const innerBottom = innerTop + this.combinedWeight;
// tracks the visual bottom of the endpoints of the previous line
let lastOuter = 0;
let lastInner = innerTop;
@@ -315,7 +303,7 @@ export class TxBowtieGraphComponent implements OnInit, OnChanges {
// set the vertical position of the (center of the) outer side of the line
line.outerY = lastOuter + (line.thickness / 2);
line.innerY = Math.min(innerBottom - (line.thickness / 2), Math.max(innerTop + (line.thickness / 2), lastInner + (line.weight / 2)));
line.innerY = Math.min(innerBottom + (line.thickness / 2), Math.max(innerTop + (line.thickness / 2), lastInner + (line.weight / 2)));
// special case to center single input/outputs
if (xputs.length === 1) {
@@ -1,4 +1,4 @@
<ng-template [ngIf]="segwitEnabled">
<ng-template [ngIf]="!tx.status.confirmed || tx.status.block_height >= 477120">
<span *ngIf="segwitGains.realizedSegwitGains && !segwitGains.potentialSegwitGains; else segwitTwo" class="badge badge-success mr-1" i18n-ngbTooltip="ngbTooltip about segwit gains" ngbTooltip="This transaction saved {{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}% on fees by using native SegWit" placement="bottom" i18n="tx-features.tag.segwit|SegWit">SegWit</span>
<ng-template #segwitTwo>
<span *ngIf="segwitGains.realizedSegwitGains && segwitGains.potentialSegwitGains; else potentialP2shSegwitGains" class="badge badge-warning mr-1" i18n-ngbTooltip="ngbTooltip about double segwit gains" ngbTooltip="This transaction saved {{ segwitGains.realizedSegwitGains * 100 | number: '1.0-0' }}% on fees by using SegWit and could save {{ segwitGains.potentialSegwitGains * 100 | number : '1.0-0' }}% more by fully upgrading to native SegWit" placement="bottom" i18n="tx-features.tag.segwit|SegWit">SegWit</span>
@@ -8,7 +8,7 @@
</ng-template>
</ng-template>
<ng-template [ngIf]="taprootEnabled">
<ng-template [ngIf]="!tx.status.confirmed || tx.status.block_height >= 709632">
<span *ngIf="segwitGains.realizedTaprootGains && !segwitGains.potentialTaprootGains; else notFullyTaproot" class="badge badge-success mr-1" i18n-ngbTooltip="Tooltip about fees saved with taproot" ngbTooltip="This transaction uses Taproot and thereby saved at least {{ segwitGains.realizedTaprootGains * 100 | number: '1.0-0' }}% on fees" placement="bottom" i18n="tx-features.tag.taproot|Taproot">Taproot</span>
<ng-template #notFullyTaproot>
<span *ngIf="segwitGains.realizedTaprootGains && segwitGains.potentialTaprootGains; else noTaproot" class="badge badge-warning mr-1" i18n-ngbTooltip="Tooltip about fees that saved and could be saved with taproot" ngbTooltip="This transaction uses Taproot and already saved at least {{ segwitGains.realizedTaprootGains * 100 | number: '1.0-0' }}% on fees, but could save an additional {{ segwitGains.potentialTaprootGains * 100 | number: '1.0-0' }}% by fully using Taproot" placement="bottom" i18n="tx-features.tag.taproot|Taproot">Taproot</span>
@@ -24,7 +24,7 @@
</ng-template>
</ng-template>
<ng-template [ngIf]="rbfEnabled">
<ng-template [ngIf]="!tx.status.confirmed || tx.status.block_height > 399700">
<span *ngIf="isRbfTransaction; else rbfDisabled" class="badge badge-success" i18n-ngbTooltip="RBF tooltip" ngbTooltip="This transaction supports Replace-By-Fee (RBF) allowing fee bumping" placement="bottom" i18n="tx-features.tag.rbf|RBF">RBF</span>
<ng-template #rbfDisabled><span class="badge badge-danger mr-1" i18n-ngbTooltip="RBF disabled tooltip" ngbTooltip="This transaction does NOT support Replace-By-Fee (RBF) and cannot be fee bumped using this method" placement="bottom"><del i18n="tx-features.tag.rbf|RBF">RBF</del></span></ng-template>
</ng-template>
@@ -1,7 +1,6 @@
import { Component, ChangeDetectionStrategy, OnChanges, Input } from '@angular/core';
import { calcSegwitFeeGains, isFeatureActive } from '../../bitcoin.utils';
import { calcSegwitFeeGains } from '../../bitcoin.utils';
import { Transaction } from '../../interfaces/electrs.interface';
import { StateService } from '../../services/state.service';
@Component({
selector: 'app-tx-features',
@@ -22,21 +21,12 @@ export class TxFeaturesComponent implements OnChanges {
isRbfTransaction: boolean;
isTaproot: boolean;
segwitEnabled: boolean;
rbfEnabled: boolean;
taprootEnabled: boolean;
constructor(
private stateService: StateService,
) { }
constructor() { }
ngOnChanges() {
if (!this.tx) {
return;
}
this.segwitEnabled = !this.tx.status.confirmed || isFeatureActive(this.stateService.network, this.tx.status.block_height, 'segwit');
this.taprootEnabled = !this.tx.status.confirmed || isFeatureActive(this.stateService.network, this.tx.status.block_height, 'taproot');
this.rbfEnabled = !this.tx.status.confirmed || isFeatureActive(this.stateService.network, this.tx.status.block_height, 'rbf');
this.segwitGains = calcSegwitFeeGains(this.tx);
this.isRbfTransaction = this.tx.vin.some((v) => v.sequence < 0xfffffffe);
this.isTaproot = this.tx.vin.some((v) => v.prevout && v.prevout.scriptpubkey_type === 'v1_p2tr');
@@ -3,7 +3,6 @@ import { Transaction } from '../../interfaces/electrs.interface';
import { StateService } from '../../services/state.service';
import { Subscription } from 'rxjs';
import { BlockExtended } from '../../interfaces/node-api.interface';
import { CacheService } from '../../services/cache.service';
@Component({
selector: 'app-tx-fee-rating',
@@ -24,12 +23,12 @@ export class TxFeeRatingComponent implements OnInit, OnChanges, OnDestroy {
constructor(
private stateService: StateService,
private cacheService: CacheService,
private cd: ChangeDetectorRef,
) { }
ngOnInit() {
this.blocksSubscription = this.cacheService.loadedBlocks$.subscribe((block) => {
this.blocksSubscription = this.stateService.blocks$.subscribe(([block]) => {
this.blocks.push(block);
if (this.tx.status.confirmed && this.tx.status.block_height === block.height && block?.extras?.medianFee > 0) {
this.calculateRatings(block);
this.cd.markForCheck();
@@ -42,9 +41,8 @@ export class TxFeeRatingComponent implements OnInit, OnChanges, OnDestroy {
if (!this.tx.status.confirmed) {
return;
}
this.cacheService.loadBlock(this.tx.status.block_height);
const foundBlock = this.cacheService.getCachedBlock(this.tx.status.block_height) || null;
const foundBlock = this.blocks.find((b) => b.height === this.tx.status.block_height);
if (foundBlock && foundBlock?.extras?.medianFee > 0) {
this.calculateRatings(foundBlock);
}
@@ -33,11 +33,9 @@ export interface DifficultyAdjustment {
remainingBlocks: number;
remainingTime: number;
previousRetarget: number;
previousTime: number;
nextRetargetHeight: number;
timeAvg: number;
timeOffset: number;
expectedBlocks: number;
}
export interface AddressInformation {
@@ -36,25 +36,25 @@
<ng-template #tableHeader>
<thead>
<th class="alias text-left" i18n="lightning.alias">Alias</th>
<th class="nodedetails text-left">&nbsp;</th>
<th class="status text-left" i18n="status">Status</th>
<th class="feerate text-left" *ngIf="status !== 'closed'" i18n="transaction.fee-rate|Transaction fee rate">Fee rate</th>
<th class="feerate text-left" *ngIf="status === 'closed'" i18n="channels.closing_date">Closing date</th>
<th class="liquidity text-right" i18n="lightning.capacity">Capacity</th>
<th class="channelid text-right" i18n="channels.id">Channel ID</th>
<th class="alias text-left d-none d-md-table-cell">&nbsp;</th>
<th class="alias text-left d-none d-md-table-cell" i18n="status">Status</th>
<th *ngIf="status !== 'closed'" class="channels text-left d-none d-md-table-cell" i18n="transaction.fee-rate|Transaction fee rate">Fee rate</th>
<th *ngIf="status === 'closed'" class="channels text-left d-none d-md-table-cell" i18n="channels.closing_date">Closing date</th>
<th class="capacity text-right d-none d-md-table-cell" i18n="lightning.capacity">Capacity</th>
<th class="capacity text-right" i18n="channels.id">Channel ID</th>
</thead>
</ng-template>
<ng-template #tableTemplate let-channel let-node="node">
<td class="alias text-left">
<app-truncate [text]="node.alias || '?'" [maxWidth]="200" [lastChars]="6"></app-truncate>
<div>{{ node.alias || '?' }}</div>
<div class="second-line">
<app-truncate [text]="node.public_key" [maxWidth]="200" [lastChars]="6" [link]="['/lightning/node' | relativeUrl, node.public_key]">
<app-clipboard [text]="node.public_key" size="small"></app-clipboard>
</app-truncate>
</div>
</td>
<td class="nodedetails text-left">
<td class="alias text-left d-none d-md-table-cell">
<div class="second-line"><ng-container *ngTemplateOutlet="xChannels; context: {$implicit: node.channels }"></ng-container></div>
<div class="second-line">
<app-amount *ngIf="node.capacity > 100000000; else smallnode" [satoshis]="node.capacity" [digitsInfo]="'1.2-2'" [noFiat]="true"></app-amount>
@@ -64,7 +64,7 @@
</ng-template>
</div>
</td>
<td class="status">
<td class="d-none d-md-table-cell">
<span class="badge rounded-pill badge-secondary" *ngIf="channel.status === 0" i18n="status.inactive">Inactive</span>
<span class="badge rounded-pill badge-success" *ngIf="channel.status === 1" i18n="status.active">Active</span>
<ng-template [ngIf]="channel.status === 2">
@@ -74,20 +74,20 @@
</ng-template>
</ng-template>
</td>
<td *ngIf="status !== 'closed'" class="feerate text-left">
<td *ngIf="status !== 'closed'" class="capacity text-left d-none d-md-table-cell">
{{ channel.fee_rate }} <span class="symbol">ppm ({{ channel.fee_rate / 10000 | number }}%)</span>
</td>
<td *ngIf="status === 'closed'" class="feerate text-left">
<td *ngIf="status === 'closed'" class="capacity text-left d-none d-md-table-cell">
<app-timestamp [unixTime]="channel.closing_date"></app-timestamp>
</td>
<td class="liquidity text-right">
<td class="capacity text-right d-none d-md-table-cell">
<app-amount *ngIf="channel.capacity > 100000000; else smallchannel" [satoshis]="channel.capacity" [digitsInfo]="'1.2-2'" [noFiat]="true"></app-amount>
<ng-template #smallchannel>
{{ channel.capacity | amountShortener: 1 }}
<span class="sats" i18n="shared.sats">sats</span>
</ng-template>
</td>
<td class="channelid text-right">
</td>
<td class="capacity text-right">
<a [routerLink]="['/lightning/channel' | relativeUrl, channel.id]">{{ channel.short_id }}</a>
</td>
</ng-template>
@@ -100,19 +100,19 @@
<td class="alias text-left" style="width: 370px;">
<span class="skeleton-loader"></span>
</td>
<td class="nodedetails text-left">
<td class="alias text-left">
<span class="skeleton-loader"></span>
</td>
<td class="status text-left">
<td class="capacity text-left d-none d-md-table-cell">
<span class="skeleton-loader"></span>
</td>
<td class="feerate text-left">
<td class="channels text-left d-none d-md-table-cell">
<span class="skeleton-loader"></span>
</td>
<td class="liquidity text-right">
<td class="channels text-right d-none d-md-table-cell">
<span class="skeleton-loader"></span>
</td>
<td class="channelid text-left">
<td class="channels text-left">
<span class="skeleton-loader"></span>
</td>
</tr>
@@ -31,36 +31,4 @@
@media (max-width: 435px) {
flex-grow: 1;
}
}
.alias {
padding-left: 0;
}
.feerate {
@media (max-width: 815px) {
display: none;
}
}
.status {
@media (max-width: 710px) {
display: none;
}
}
.nodedetails {
@media (max-width: 600px) {
display: none;
}
}
.liquidity {
@media (max-width: 500px) {
display: none;
}
}
.channelid {
padding-right: 0;
}
@@ -2,10 +2,7 @@
color: #4a68b9;
font-size: 10px;
margin-bottom: 4px;
font-size: 1rem;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 1rem;
}
.card-text {
@@ -57,7 +57,7 @@
</tr>
<tr *ngIf="(avgChannelDistance$ | async) as avgDistance;">
<td i18n="lightning.avg-distance" class="text-truncate">Avg channel distance</td>
<td class="direction-ltr">{{ avgDistance | amountShortener: 1 }} <span class="symbol">km</span> <span class="separator">·</span>{{ kmToMiles(avgDistance) | amountShortener: 1 }} <span class="symbol">mi</span></td>
<td class="direction-ltr">{{ avgDistance | number : '1.0-0' }} <span class="symbol">km</span> <span class="separator">/</span> {{ kmToMiles(avgDistance) | number : '1.0-0' }} <span class="symbol">mi</span></td>
</tr>
</tbody>
</table>
@@ -108,6 +108,5 @@ app-fiat {
}
.separator {
margin: 0 0.25em;
color: slategrey;
margin: 0 1em;
}
@@ -207,8 +207,8 @@ export class NodesMap implements OnInit, OnChanges {
return `
<b style="color: white">${alias}</b><br>
${liquidity}<br>` +
$localize`:@@205c1b86ac1cc419c4d0cca51fdde418c4ffdc20:${data[5]}:INTERPOLATION: channels` + `<br>
${liquidity}<br>
${data[5]} channels<br>
${getFlagEmoji(data[7])} ${data[6]}
`;
}
@@ -99,9 +99,8 @@ export class NodesPerCountryChartComponent implements OnInit {
},
borderColor: '#000',
formatter: () => {
const nodeCount = country.count.toString();
return `<b style="color: white">${country.name.en} (${country.share}%)</b><br>` +
$localize`${nodeCount} nodes` + `<br>` +
$localize`${country.count.toString()} nodes` + `<br>` +
$localize`${this.amountShortenerPipe.transform(country.capacity / 100000000, 2)} BTC capacity`
;
}
@@ -116,7 +115,7 @@ export class NodesPerCountryChartComponent implements OnInit {
color: 'grey',
},
value: totalShareOther,
name: $localize`Other (${totalShareOther.toFixed(2) + '%'})`,
name: 'Other' + (this.isMobile() ? `` : ` (${totalShareOther.toFixed(2)}%)`),
label: {
overflow: 'truncate',
color: '#b1b1b1',
@@ -132,9 +131,8 @@ export class NodesPerCountryChartComponent implements OnInit {
},
borderColor: '#000',
formatter: () => {
const nodeCount = totalNodeOther.toString();
return `<b style="color: white">` + $localize`Other (${totalShareOther.toFixed(2) + '%'})` + `</b><br>` +
$localize`${nodeCount} nodes`;
return `<b style="color: white">${'Other'} (${totalShareOther.toFixed(2)}%)</b><br>` +
totalNodeOther.toString() + ` nodes`;
},
},
data: 9999 as any
@@ -3,21 +3,21 @@
<div *ngIf="widget">
<div class="pool-distribution" *ngIf="(nodesPerAsObservable$ | async) as stats; else loadingReward">
<div class="item">
<h5 class="card-title" i18n="lightning.clearnet-capacity">Clearnet Capacity</h5>
<h5 class="card-title d-inline-block" i18n="lightning.clearnet-capacity">Clearnet Capacity</h5>
<p class="card-text" i18n-ngbTooltip="lightning.clearnet-capacity-desc"
ngbTooltip="How much liquidity is running on nodes advertising at least one clearnet IP address" placement="bottom">
<app-amount [satoshis]="stats.clearnetCapacity" [digitsInfo]="'1.2-2'" [noFiat]="true"></app-amount>
</p>
</div>
<div class="item">
<h5 class="card-title" i18n="lightning.unknown-capacity">Unknown Capacity</h5>
<h5 class="card-title d-inline-block" i18n="lightning.unknown-capacity">Unknown Capacity</h5>
<p class="card-text" i18n-ngbTooltip="lightning.unknown-capacity-desc"
ngbTooltip="How much liquidity is running on nodes which ISP was not identifiable" placement="bottom">
<app-amount [satoshis]="stats.unknownCapacity" [digitsInfo]="'1.2-2'" [noFiat]="true"></app-amount>
</p>
</div>
<div class="item">
<h5 class="card-title" i18n="lightning.tor-capacity">Tor Capacity</h5>
<h5 class="card-title d-inline-block" i18n="lightning.tor-capacity">Tor Capacity</h5>
<p class="card-text" i18n-ngbTooltip="lightning.tor-capacity-desc"
ngbTooltip="How much liquidity is running on nodes advertising only Tor addresses" placement="bottom">
<app-amount [satoshis]="stats.torCapacity" [digitsInfo]="'1.2-2'" [noFiat]="true"></app-amount>
@@ -80,19 +80,19 @@
<ng-template #loadingReward>
<div class="pool-distribution">
<div class="item">
<h5 class="card-title" i18n="lightning.clearnet-capacity">Clearnet Capacity</h5>
<h5 class="card-title d-inline-block" i18n="lightning.clearnet-capacity">Clearnet Capacity</h5>
<p class="card-text">
<span class="skeleton-loader skeleton-loader-big"></span>
</p>
</div>
<div class="item">
<h5 class="card-title" i18n="lightning.unknown-capacity">Unknown Capacity</h5>
<h5 class="card-title d-inline-block" i18n="lightning.unknown-capacity">Unknown Capacity</h5>
<p class="card-text">
<span class="skeleton-loader skeleton-loader-big"></span>
</p>
</div>
<div class="item">
<h5 class="card-title" i18n="lightning.tor-capacity">Tor Capacity</h5>
<h5 class="card-title d-inline-block" i18n="lightning.tor-capacity">Tor Capacity</h5>
<p class="card-text">
<span class="skeleton-loader skeleton-loader-big"></span>
</p>
@@ -68,13 +68,10 @@
margin-bottom: 5px;
}
.item {
max-width: 150px;
max-width: 160px;
width: 50%;
display: inline-block;
margin: 0px auto 20px;
@media (min-width: 485px) {
max-width: 160px;
}
&:nth-child(2) {
order: 2;
@media (min-width: 485px) {
@@ -153,9 +153,8 @@ export class NodesPerISPChartComponent implements OnInit {
},
borderColor: '#000',
formatter: () => {
const nodeCount = isp[4].toString();
return `<b style="color: white">${isp[1]} (${this.sortBy === 'capacity' ? isp[7] : isp[6]}%)</b><br>` +
$localize`${nodeCount} nodes` + `<br>` +
$localize`${isp[4].toString()} nodes` + `<br>` +
$localize`${this.amountShortenerPipe.transform(isp[2] / 100000000, 2)} BTC`
;
}
@@ -170,7 +169,7 @@ export class NodesPerISPChartComponent implements OnInit {
color: 'grey',
},
value: totalShareOther,
name: $localize`Other (${totalShareOther.toFixed(2) + '%'})`,
name: 'Other' + (isMobile() || this.widget ? `` : ` (${totalShareOther.toFixed(2)}%)`),
label: {
overflow: 'truncate',
color: '#b1b1b1',
@@ -186,9 +185,8 @@ export class NodesPerISPChartComponent implements OnInit {
},
borderColor: '#000',
formatter: () => {
const nodeCount = nodeCountOther.toString();
return `<b style="color: white">` + $localize`Other (${totalShareOther.toFixed(2) + '%'})` + `</b><br>` +
$localize`${nodeCount} nodes` + `<br>` +
return `<b style="color: white">Other (${totalShareOther.toFixed(2)}%)</b><br>` +
$localize`${nodeCountOther.toString()} nodes` + `<br>` +
$localize`${this.amountShortenerPipe.transform(capacityOther / 100000000, 2)} BTC`;
}
},
@@ -256,7 +256,7 @@ export class LightningStatisticsChartComponent implements OnInit {
series: data.channel_count.length === 0 ? [] : [
{
zlevel: 1,
name: $localize`:@@807cf11e6ac1cde912496f764c176bdfdd6b7e19:Channels`,
name: 'Channels',
showSymbol: false,
symbol: 'none',
data: data.channel_count,
-6
View File
@@ -58,8 +58,6 @@ import { AssetsNavComponent } from '../components/assets/assets-nav/assets-nav.c
import { StatusViewComponent } from '../components/status-view/status-view.component';
import { FeesBoxComponent } from '../components/fees-box/fees-box.component';
import { DifficultyComponent } from '../components/difficulty/difficulty.component';
import { DifficultyTooltipComponent } from '../components/difficulty/difficulty-tooltip.component';
import { DifficultyMiningComponent } from '../components/difficulty-mining/difficulty-mining.component';
import { TermsOfServiceComponent } from '../components/terms-of-service/terms-of-service.component';
import { TxBowtieGraphComponent } from '../components/tx-bowtie-graph/tx-bowtie-graph.component';
import { TxBowtieGraphTooltipComponent } from '../components/tx-bowtie-graph-tooltip/tx-bowtie-graph-tooltip.component';
@@ -135,8 +133,6 @@ import { GeolocationComponent } from '../shared/components/geolocation/geolocati
StatusViewComponent,
FeesBoxComponent,
DifficultyComponent,
DifficultyMiningComponent,
DifficultyTooltipComponent,
TxBowtieGraphComponent,
TxBowtieGraphTooltipComponent,
TermsOfServiceComponent,
@@ -238,8 +234,6 @@ import { GeolocationComponent } from '../shared/components/geolocation/geolocati
StatusViewComponent,
FeesBoxComponent,
DifficultyComponent,
DifficultyMiningComponent,
DifficultyTooltipComponent,
TxBowtieGraphComponent,
TxBowtieGraphTooltipComponent,
TermsOfServiceComponent,
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+151 -310
View File
@@ -750,11 +750,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">32</context>
<context context-type="linenumber">33</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">42</context>
<context context-type="linenumber">43</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/lightning-dashboard/lightning-dashboard.component.html</context>
@@ -775,11 +775,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/about/about.component.html</context>
<context context-type="linenumber">391,394</context>
<context context-type="linenumber">375,378</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">87</context>
<context context-type="linenumber">88</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
@@ -805,7 +805,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">89</context>
<context context-type="linenumber">90</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
@@ -1487,7 +1487,7 @@
<target>متحدین جامعه</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/about/about.component.html</context>
<context context-type="linenumber">291,293</context>
<context context-type="linenumber">275,277</context>
</context-group>
<note priority="1" from="description">about.alliances</note>
</trans-unit>
@@ -1496,7 +1496,7 @@
<target>مترجم‌های پروژه</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/about/about.component.html</context>
<context context-type="linenumber">307,309</context>
<context context-type="linenumber">291,293</context>
</context-group>
<note priority="1" from="description">about.translators</note>
</trans-unit>
@@ -1505,7 +1505,7 @@
<target>مشارکت کنندگان</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/about/about.component.html</context>
<context context-type="linenumber">321,323</context>
<context context-type="linenumber">305,307</context>
</context-group>
<note priority="1" from="description">about.contributors</note>
</trans-unit>
@@ -1514,7 +1514,7 @@
<target>اعضای پروژه</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/about/about.component.html</context>
<context context-type="linenumber">333,335</context>
<context context-type="linenumber">317,319</context>
</context-group>
<note priority="1" from="description">about.project_members</note>
</trans-unit>
@@ -1523,7 +1523,7 @@
<target>نگهدارندگان پروژه</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/about/about.component.html</context>
<context context-type="linenumber">346,348</context>
<context context-type="linenumber">330,332</context>
</context-group>
<note priority="1" from="description">about.maintainers</note>
</trans-unit>
@@ -2215,7 +2215,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/channels-list/channels-list.component.html</context>
<context context-type="linenumber">41,43</context>
<context context-type="linenumber">41,42</context>
</context-group>
<note priority="1" from="description">Transaction fee rate</note>
<note priority="1" from="meaning">transaction.fee-rate</note>
@@ -2633,10 +2633,6 @@
<context context-type="sourcefile">src/app/components/block/block.component.html</context>
<context context-type="linenumber">8,9</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">38</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mempool-block/mempool-block.component.ts</context>
<context context-type="linenumber">75</context>
@@ -3084,17 +3080,13 @@
<trans-unit id="63da83692b85cf17e0606153029a83fd4038d6dd" datatype="html">
<source>Difficulty Adjustment</source>
<target>تنظیم سختی بلاک‌ها</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="linenumber">1,5</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">1,5</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">23</context>
<context context-type="linenumber">24</context>
</context-group>
<note priority="1" from="description">dashboard.difficulty-adjustment</note>
</trans-unit>
@@ -3102,11 +3094,11 @@
<source>Remaining</source>
<target>باقیمانده</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">7,9</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">66,69</context>
</context-group>
<note priority="1" from="description">difficulty-box.remaining</note>
@@ -3115,11 +3107,11 @@
<source><x id="INTERPOLATION" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;blocks&lt;/span&gt;&lt;/ng-template&gt; &lt;ng-template"/> <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;"/>blocks<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source>
<target><x id="INTERPOLATION" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;blocks&lt;/span&gt;&lt;/ng-template&gt; &lt;ng-template"/> <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;"/>بلاک<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/> </target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">10,11</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">53,54</context>
</context-group>
<context-group purpose="location">
@@ -3140,11 +3132,11 @@
<source><x id="INTERPOLATION" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;block&lt;/span&gt;&lt;/ng-template&gt; &lt;/div&gt;"/> <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;"/>block<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source>
<target><x id="INTERPOLATION" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;block&lt;/span&gt;&lt;/ng-template&gt; &lt;/div&gt;"/> <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;"/>بلاک<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">11,12</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">54,55</context>
</context-group>
<context-group purpose="location">
@@ -3157,11 +3149,11 @@
<source>Estimate</source>
<target>تخمین</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">16,17</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">73,76</context>
</context-group>
<note priority="1" from="description">difficulty-box.estimate</note>
@@ -3169,13 +3161,9 @@
<trans-unit id="680d5c75b7fd8d37961083608b9fcdc4167b4c43" datatype="html">
<source>Previous</source>
<target>قبلی</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="linenumber">31,33</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">59,61</context>
<context context-type="linenumber">31,33</context>
</context-group>
<note priority="1" from="description">difficulty-box.previous</note>
</trans-unit>
@@ -3183,11 +3171,11 @@
<source>Current Period</source>
<target>دوره فعلی</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">43,44</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">80,83</context>
</context-group>
<note priority="1" from="description">difficulty-box.current-period</note>
@@ -3196,110 +3184,11 @@
<source>Next Halving</source>
<target>نصف‌شدن یارانهٔ بلاک بعدی</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">50,52</context>
</context-group>
<note priority="1" from="description">difficulty-box.next-halving</note>
</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>
</context-group>
<note priority="1" from="description">difficulty-box.expected-blocks</note>
</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>
</context-group>
<note priority="1" from="description">difficulty-box.expected-block</note>
</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>
</context-group>
<note priority="1" from="description">difficulty-box.mined-blocks</note>
</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>
</context-group>
<note priority="1" from="description">difficulty-box.mined-block</note>
</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>
</context-group>
<note priority="1" from="description">difficulty-box.remaining-blocks</note>
</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>
</context-group>
<note priority="1" from="description">difficulty-box.remaining-block</note>
</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>
</context-group>
<note priority="1" from="description">difficulty-box.blocks-ahead</note>
</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>
</context-group>
<note priority="1" from="description">difficulty-box.block-ahead</note>
</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>
</context-group>
<note priority="1" from="description">difficulty-box.blocks-behind</note>
</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>
</context-group>
<note priority="1" from="description">difficulty-box.block-behind</note>
</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>
</context-group>
<note priority="1" from="description">difficulty-box.average-block-time</note>
</trans-unit>
<trans-unit id="6ff9e8b67bc2cda7569dc0996d4c2fd858c5d4e6" datatype="html">
<source>Either 2x the minimum, or the Low Priority rate (whichever is lower)</source>
<target>«2 برابر نرخ کمینه» یا «اولویت پایین» (هر کدام که کمتر است)</target>
@@ -3778,7 +3667,7 @@
<target>وضعیت پاداش</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">9</context>
<context context-type="linenumber">10</context>
</context-group>
<note priority="1" from="description">mining.reward-stats</note>
</trans-unit>
@@ -3787,7 +3676,7 @@
<target>(144 بلاک)</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">10</context>
<context context-type="linenumber">11</context>
</context-group>
<note priority="1" from="description">mining.144-blocks</note>
</trans-unit>
@@ -3796,7 +3685,7 @@
<target>آخرین بلاک‌ها</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">52</context>
<context context-type="linenumber">53</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
@@ -3809,7 +3698,7 @@
<target>تنظیم‌سختی‌ها</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">66</context>
<context context-type="linenumber">67</context>
</context-group>
<note priority="1" from="description">dashboard.adjustments</note>
</trans-unit>
@@ -3818,7 +3707,7 @@
<target>انتشار تراکنش</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">91</context>
<context context-type="linenumber">92</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/push-transaction/push-transaction.component.html</context>
@@ -3993,9 +3882,9 @@
<context context-type="linenumber">58</context>
</context-group>
</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>
<trans-unit id="6095122426142344316" datatype="html">
<source><x id="PH" equiv-text="i"/> blocks</source>
<target><x id="PH" 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>
@@ -4004,42 +3893,6 @@
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">168,167</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">203,201</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">206,205</context>
</context-group>
</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>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">205</context>
</context-group>
<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">119,114</context>
</context-group>
<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">136</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts</context>
<context context-type="linenumber">173,168</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts</context>
<context context-type="linenumber">190</context>
</context-group>
</trans-unit>
<trans-unit id="2158ea60725d3a97aed6f0f00aa7df48d7bb42ff" datatype="html">
<source>mining pool</source>
@@ -4513,28 +4366,40 @@
<target>همین الان</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">79</context>
<context context-type="linenumber">78</context>
</context-group>
</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>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">97</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">98</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">99</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">100</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">101</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">103</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">104</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">105</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">106</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">107</context>
@@ -4547,54 +4412,54 @@
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">109</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">110</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">111</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">112</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">113</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">114</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">115</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">116</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">117</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">118</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">119</context>
</context-group>
</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">120</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">121</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">122</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">123</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">124</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">125</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">126</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">127</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">128</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">129</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">130</context>
@@ -4607,54 +4472,54 @@
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">132</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">133</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">134</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">135</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">136</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">137</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">138</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">139</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">140</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">141</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="time-span" datatype="html">
<source>After <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">143</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">144</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">145</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">146</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">147</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">148</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">149</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">151</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">152</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">153</context>
@@ -4667,34 +4532,22 @@
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">155</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">156</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">157</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">158</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">159</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">160</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">161</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">162</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">163</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">164</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">165</context>
</context-group>
</trans-unit>
<trans-unit id="0094b97dd052620710f173e7aedf6807a1eba1f5" datatype="html">
<source>This transaction has been replaced by:</source>
@@ -5587,10 +5440,6 @@
<context context-type="sourcefile">src/app/lightning/channels-list/channels-list.component.html</context>
<context context-type="linenumber">123,124</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-map/nodes-map.component.ts</context>
<context context-type="linenumber">211,208</context>
</context-group>
<note priority="1" from="description">lightning.x-channels</note>
</trans-unit>
<trans-unit id="4e64e04c01e8f5fc09c41cb8942dcc3af0398b28" datatype="html">
@@ -5831,7 +5680,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/channels-list/channels-list.component.html</context>
<context context-type="linenumber">42,44</context>
<context context-type="linenumber">42,43</context>
</context-group>
<note priority="1" from="description">lightning.closing_date</note>
</trans-unit>
@@ -5972,7 +5821,7 @@
<target>sats</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/channels-list/channels-list.component.html</context>
<context context-type="linenumber">63,68</context>
<context context-type="linenumber">63,67</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/channels-list/channels-list.component.html</context>
@@ -6290,10 +6139,6 @@
<context context-type="sourcefile">src/app/lightning/statistics-chart/lightning-statistics-chart.component.ts</context>
<context context-type="linenumber">194,193</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/statistics-chart/lightning-statistics-chart.component.ts</context>
<context context-type="linenumber">259,257</context>
</context-group>
<note priority="1" from="description">lightning.channels</note>
</trans-unit>
<trans-unit id="e4706894b195010f6814e54bf6570c729d69aaca" datatype="html">
@@ -6774,23 +6619,19 @@
<note priority="1" from="description">lightning.share</note>
</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>
<source><x id="PH" equiv-text="country.count.toString()"/> nodes</source>
<target><x id="PH" equiv-text="country.count.toString()"/> گره</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>
</context-group>
<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">137,136</context>
<context context-type="linenumber">103,102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts</context>
<context context-type="linenumber">158,157</context>
<context context-type="linenumber">157,156</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts</context>
<context context-type="linenumber">191,190</context>
<context context-type="linenumber">189,188</context>
</context-group>
</trans-unit>
<trans-unit id="7032954508645880700" datatype="html">
@@ -6798,7 +6639,7 @@
<target>ظرفیت <x id="PH" equiv-text="this.amountShortenerPipe.transform(country.capacity / 100000000, 2)"/> BTC</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">105,103</context>
<context context-type="linenumber">104,102</context>
</context-group>
</trans-unit>
<trans-unit id="7ede3edfacd291eb9db08e11845d9efdf197f417" datatype="html">
@@ -6916,11 +6757,11 @@
<target><x id="PH" equiv-text="this.amountShortenerPipe.transform(isp[2] / 100000000, 2)"/> BTC</target>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts</context>
<context context-type="linenumber">159,157</context>
<context context-type="linenumber">158,156</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts</context>
<context context-type="linenumber">192,190</context>
<context context-type="linenumber">190,188</context>
</context-group>
</trans-unit>
<trans-unit id="c18497e4f0db0d0ad0c71ba294295f42b3d312c9" datatype="html">
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+149 -296
View File
@@ -691,11 +691,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">32</context>
<context context-type="linenumber">33</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">42</context>
<context context-type="linenumber">43</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/lightning-dashboard/lightning-dashboard.component.html</context>
@@ -715,11 +715,11 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/about/about.component.html</context>
<context context-type="linenumber">391,394</context>
<context context-type="linenumber">375,378</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">87</context>
<context context-type="linenumber">88</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
@@ -744,7 +744,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">89</context>
<context context-type="linenumber">90</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
@@ -1380,7 +1380,7 @@
<source>Community Alliances</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/about/about.component.html</context>
<context context-type="linenumber">291,293</context>
<context context-type="linenumber">275,277</context>
</context-group>
<note priority="1" from="description">about.alliances</note>
</trans-unit>
@@ -1388,7 +1388,7 @@
<source>Project Translators</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/about/about.component.html</context>
<context context-type="linenumber">307,309</context>
<context context-type="linenumber">291,293</context>
</context-group>
<note priority="1" from="description">about.translators</note>
</trans-unit>
@@ -1396,7 +1396,7 @@
<source>Project Contributors</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/about/about.component.html</context>
<context context-type="linenumber">321,323</context>
<context context-type="linenumber">305,307</context>
</context-group>
<note priority="1" from="description">about.contributors</note>
</trans-unit>
@@ -1404,7 +1404,7 @@
<source>Project Members</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/about/about.component.html</context>
<context context-type="linenumber">333,335</context>
<context context-type="linenumber">317,319</context>
</context-group>
<note priority="1" from="description">about.project_members</note>
</trans-unit>
@@ -1412,7 +1412,7 @@
<source>Project Maintainers</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/about/about.component.html</context>
<context context-type="linenumber">346,348</context>
<context context-type="linenumber">330,332</context>
</context-group>
<note priority="1" from="description">about.maintainers</note>
</trans-unit>
@@ -2056,7 +2056,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/channels-list/channels-list.component.html</context>
<context context-type="linenumber">41,43</context>
<context context-type="linenumber">41,42</context>
</context-group>
<note priority="1" from="description">Transaction fee rate</note>
<note priority="1" from="meaning">transaction.fee-rate</note>
@@ -2452,10 +2452,6 @@
<context context-type="sourcefile">src/app/components/block/block.component.html</context>
<context context-type="linenumber">8,9</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">38</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mempool-block/mempool-block.component.ts</context>
<context context-type="linenumber">75</context>
@@ -2874,28 +2870,24 @@
</trans-unit>
<trans-unit id="63da83692b85cf17e0606153029a83fd4038d6dd" datatype="html">
<source>Difficulty Adjustment</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="linenumber">1,5</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">1,5</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">23</context>
<context context-type="linenumber">24</context>
</context-group>
<note priority="1" from="description">dashboard.difficulty-adjustment</note>
</trans-unit>
<trans-unit id="0912816d94f2f05a7eee8f7622670e0c6bbbce16" datatype="html">
<source>Remaining</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">7,9</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">66,69</context>
</context-group>
<note priority="1" from="description">difficulty-box.remaining</note>
@@ -2904,11 +2896,11 @@
<source><x id="INTERPOLATION" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;blocks&lt;/span&gt;&lt;/ng-template&gt;
&lt;ng-template"/> <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;"/>blocks<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">10,11</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">53,54</context>
</context-group>
<context-group purpose="location">
@@ -2929,11 +2921,11 @@
<source><x id="INTERPOLATION" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;block&lt;/span&gt;&lt;/ng-template&gt;
&lt;/div&gt;"/> <x id="START_TAG_SPAN" ctype="x-span" equiv-text="&lt;span class=&quot;shared-block&quot;&gt;"/>block<x id="CLOSE_TAG_SPAN" ctype="x-span" equiv-text="&lt;/span&gt;"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">11,12</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">54,55</context>
</context-group>
<context-group purpose="location">
@@ -2945,35 +2937,31 @@
<trans-unit id="5e65ce907fc0e1a1a09d4130eb8c59d00a9457ef" datatype="html">
<source>Estimate</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">16,17</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">73,76</context>
</context-group>
<note priority="1" from="description">difficulty-box.estimate</note>
</trans-unit>
<trans-unit id="680d5c75b7fd8d37961083608b9fcdc4167b4c43" datatype="html">
<source>Previous</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="linenumber">31,33</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">59,61</context>
<context context-type="linenumber">31,33</context>
</context-group>
<note priority="1" from="description">difficulty-box.previous</note>
</trans-unit>
<trans-unit id="5db469cd0357e5f578b85a996f7e99c9e4148ff5" datatype="html">
<source>Current Period</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">43,44</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">80,83</context>
</context-group>
<note priority="1" from="description">difficulty-box.current-period</note>
@@ -2981,99 +2969,11 @@
<trans-unit id="df71fa93f0503396ea2bb3ba5161323330314d6c" datatype="html">
<source>Next Halving</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty-mining/difficulty-mining.component.html</context>
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">50,52</context>
</context-group>
<note priority="1" from="description">difficulty-box.next-halving</note>
</trans-unit>
<trans-unit id="0c65c3ee0ce537e507e0b053b479012e5803d2cf" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks expected</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">13</context>
</context-group>
<note priority="1" from="description">difficulty-box.expected-blocks</note>
</trans-unit>
<trans-unit id="ec9f27d00a7778cd1cfe1806105d2ca3314fa506" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block expected</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">14</context>
</context-group>
<note priority="1" from="description">difficulty-box.expected-block</note>
</trans-unit>
<trans-unit id="b89cb92adf0a831d4a263ecdba02139abbda02ae" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks mined</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">18</context>
</context-group>
<note priority="1" from="description">difficulty-box.mined-blocks</note>
</trans-unit>
<trans-unit id="4f7e823fd45c6def13a3f15f678888c7fe254fa5" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block mined</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">19</context>
</context-group>
<note priority="1" from="description">difficulty-box.mined-block</note>
</trans-unit>
<trans-unit id="229dfb17b342aa8b9a1db27557069445ea1a7051" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks remaining</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">24</context>
</context-group>
<note priority="1" from="description">difficulty-box.remaining-blocks</note>
</trans-unit>
<trans-unit id="13ff0d092caf85cd23815f0235e316dc3a6d1bbe" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block remaining</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">25</context>
</context-group>
<note priority="1" from="description">difficulty-box.remaining-block</note>
</trans-unit>
<trans-unit id="4f78348af343fb64016891d67b53bdab473f9dbf" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks ahead</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">29</context>
</context-group>
<note priority="1" from="description">difficulty-box.blocks-ahead</note>
</trans-unit>
<trans-unit id="15c5f3475966bf3be381378b046a65849f0f6bb6" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block ahead</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">30</context>
</context-group>
<note priority="1" from="description">difficulty-box.block-ahead</note>
</trans-unit>
<trans-unit id="697b8cb1caaf1729809bc5c065d4dd873810550a" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> blocks behind</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">34</context>
</context-group>
<note priority="1" from="description">difficulty-box.blocks-behind</note>
</trans-unit>
<trans-unit id="32137887e3f5a25b3a016eb03357f4e363fccb0b" datatype="html">
<source><x id="INTERPOLATION" equiv-text="{{ i }}"/> block behind</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty-tooltip.component.html</context>
<context context-type="linenumber">35</context>
</context-group>
<note priority="1" from="description">difficulty-box.block-behind</note>
</trans-unit>
<trans-unit id="5e78899c9b98f29856ce3c7c265e1344bc7a5a18" datatype="html">
<source>Average block time</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/difficulty/difficulty.component.html</context>
<context context-type="linenumber">42,45</context>
</context-group>
<note priority="1" from="description">difficulty-box.average-block-time</note>
</trans-unit>
<trans-unit id="6ff9e8b67bc2cda7569dc0996d4c2fd858c5d4e6" datatype="html">
<source>Either 2x the minimum, or the Low Priority rate (whichever is lower)</source>
<context-group purpose="location">
@@ -3513,7 +3413,7 @@
<source>Reward stats</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">9</context>
<context context-type="linenumber">10</context>
</context-group>
<note priority="1" from="description">mining.reward-stats</note>
</trans-unit>
@@ -3521,7 +3421,7 @@
<source>(144 blocks)</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">10</context>
<context context-type="linenumber">11</context>
</context-group>
<note priority="1" from="description">mining.144-blocks</note>
</trans-unit>
@@ -3529,7 +3429,7 @@
<source>Latest blocks</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">52</context>
<context context-type="linenumber">53</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/dashboard/dashboard.component.html</context>
@@ -3541,7 +3441,7 @@
<source>Adjustments</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">66</context>
<context context-type="linenumber">67</context>
</context-group>
<note priority="1" from="description">dashboard.adjustments</note>
</trans-unit>
@@ -3549,7 +3449,7 @@
<source>Broadcast Transaction</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/mining-dashboard/mining-dashboard.component.html</context>
<context context-type="linenumber">91</context>
<context context-type="linenumber">92</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/push-transaction/push-transaction.component.html</context>
@@ -3709,8 +3609,8 @@
<context context-type="linenumber">58</context>
</context-group>
</trans-unit>
<trans-unit id="312539377512157124" datatype="html">
<source><x id="INTERPOLATION" equiv-text="i"/> blocks</source>
<trans-unit id="6095122426142344316" datatype="html">
<source><x id="PH" equiv-text="i"/> blocks</source>
<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>
@@ -3719,41 +3619,6 @@
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">168,167</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">203,201</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">206,205</context>
</context-group>
</trans-unit>
<trans-unit id="3666195172774554282" datatype="html">
<source>Other (<x id="PH" equiv-text="percentage"/>)</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">201</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/pool-ranking/pool-ranking.component.ts</context>
<context context-type="linenumber">205</context>
</context-group>
<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">119,114</context>
</context-group>
<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">136</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts</context>
<context context-type="linenumber">173,168</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts</context>
<context context-type="linenumber">190</context>
</context-group>
</trans-unit>
<trans-unit id="2158ea60725d3a97aed6f0f00aa7df48d7bb42ff" datatype="html">
<source>mining pool</source>
@@ -4189,27 +4054,39 @@
<source>Just now</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">79</context>
<context context-type="linenumber">78</context>
</context-group>
</trans-unit>
<trans-unit id="time-since" datatype="html">
<source><x id="DATE" equiv-text="dateStrings.i18nYear"/> ago</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">97</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">98</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">99</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">100</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">101</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">103</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">104</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">105</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">106</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">107</context>
@@ -4222,53 +4099,53 @@
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">109</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">110</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">111</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">112</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">113</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">114</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">115</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">116</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">117</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">118</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">119</context>
</context-group>
</trans-unit>
<trans-unit id="time-until" datatype="html">
<source>In ~<x id="DATE" equiv-text="dateStrings.i18nYear"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">120</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">121</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">122</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">123</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">124</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">125</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">126</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">127</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">128</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">129</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">130</context>
@@ -4281,53 +4158,53 @@
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">132</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">133</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">134</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">135</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">136</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">137</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">138</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">139</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">140</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">141</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">142</context>
</context-group>
</trans-unit>
<trans-unit id="time-span" datatype="html">
<source>After <x id="DATE" equiv-text="dateStrings.i18nYear"/></source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">143</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">144</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">145</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">146</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">147</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">148</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">149</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">150</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">151</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">152</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">153</context>
@@ -4340,34 +4217,22 @@
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">155</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">156</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">157</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">158</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">159</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">160</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">161</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">162</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">163</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">164</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/components/time/time.component.ts</context>
<context context-type="linenumber">165</context>
</context-group>
</trans-unit>
<trans-unit id="0094b97dd052620710f173e7aedf6807a1eba1f5" datatype="html">
<source>This transaction has been replaced by:</source>
@@ -5179,10 +5044,6 @@
<context context-type="sourcefile">src/app/lightning/channels-list/channels-list.component.html</context>
<context context-type="linenumber">123,124</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-map/nodes-map.component.ts</context>
<context context-type="linenumber">211,208</context>
</context-group>
<note priority="1" from="description">lightning.x-channels</note>
</trans-unit>
<trans-unit id="4e64e04c01e8f5fc09c41cb8942dcc3af0398b28" datatype="html">
@@ -5411,7 +5272,7 @@
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/channels-list/channels-list.component.html</context>
<context context-type="linenumber">42,44</context>
<context context-type="linenumber">42,43</context>
</context-group>
<note priority="1" from="description">lightning.closing_date</note>
</trans-unit>
@@ -5539,7 +5400,7 @@
<source>sats</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/channels-list/channels-list.component.html</context>
<context context-type="linenumber">63,68</context>
<context context-type="linenumber">63,67</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/channels-list/channels-list.component.html</context>
@@ -5841,10 +5702,6 @@
<context context-type="sourcefile">src/app/lightning/statistics-chart/lightning-statistics-chart.component.ts</context>
<context context-type="linenumber">194,193</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/statistics-chart/lightning-statistics-chart.component.ts</context>
<context context-type="linenumber">259,257</context>
</context-group>
<note priority="1" from="description">lightning.channels</note>
</trans-unit>
<trans-unit id="e4706894b195010f6814e54bf6570c729d69aaca" datatype="html">
@@ -6285,29 +6142,25 @@
<note priority="1" from="description">lightning.share</note>
</trans-unit>
<trans-unit id="5222540403093176126" datatype="html">
<source><x id="PH" equiv-text="nodeCount"/> nodes</source>
<source><x id="PH" equiv-text="country.count.toString()"/> nodes</source>
<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>
</context-group>
<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">137,136</context>
<context context-type="linenumber">103,102</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts</context>
<context context-type="linenumber">158,157</context>
<context context-type="linenumber">157,156</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts</context>
<context context-type="linenumber">191,190</context>
<context context-type="linenumber">189,188</context>
</context-group>
</trans-unit>
<trans-unit id="7032954508645880700" datatype="html">
<source><x id="PH" equiv-text="this.amountShortenerPipe.transform(country.capacity / 100000000, 2)"/> BTC capacity</source>
<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">105,103</context>
<context context-type="linenumber">104,102</context>
</context-group>
</trans-unit>
<trans-unit id="7ede3edfacd291eb9db08e11845d9efdf197f417" datatype="html">
@@ -6413,11 +6266,11 @@
<source><x id="PH" equiv-text="this.amountShortenerPipe.transform(isp[2] / 100000000, 2)"/> BTC</source>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts</context>
<context context-type="linenumber">159,157</context>
<context context-type="linenumber">158,156</context>
</context-group>
<context-group purpose="location">
<context context-type="sourcefile">src/app/lightning/nodes-per-isp-chart/nodes-per-isp-chart.component.ts</context>
<context context-type="linenumber">192,190</context>
<context context-type="linenumber">190,188</context>
</context-group>
</trans-unit>
<trans-unit id="c18497e4f0db0d0ad0c71ba294295f42b3d312c9" datatype="html">
File diff suppressed because it is too large. Load diff
@@ -1,52 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="75.845146"
height="68.671829"
viewBox="0 0 75.845148 68.671834"
version="1.1"
id="svg382"
sodipodi:docname="bitcoin-s.svg"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview384"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="2.9911866"
inkscape:cx="224.49285"
inkscape:cy="34.935968"
inkscape:window-width="2676"
inkscape:window-height="1439"
inkscape:window-x="1156"
inkscape:window-y="676"
inkscape:window-maximized="0"
inkscape:current-layer="g380" />
<defs
id="defs372">
<clipPath
clipPathUnits="userSpaceOnUse"
id="a">
<path
d="M 0,96.978 H 360.81 V 0 H 0 Z"
id="path369" />
</clipPath>
</defs>
<g
clip-path="url(#a)"
transform="matrix(1.33333,0,0,-1.33333,-42.513227,99.207752)"
id="g380">
<path
d="m 60.327,74.406 c -15.708,0 -28.442,-12.734 -28.442,-28.442 0,-9.185 4.357,-17.347 11.112,-22.546 3.014,1.79 8.559,4.834 10.472,4.2 2.675,-0.886 5.147,-1.348 7.414,-1.385 2.139,-0.034 3.845,0.313 5.121,1.035 1.276,0.726 1.926,1.866 1.951,3.419 0.027,1.62 -0.746,2.88 -2.32,3.78 -1.573,0.902 -4.068,1.867 -7.487,2.894 -3.611,1.162 -6.574,2.295 -8.889,3.402 -2.316,1.107 -4.314,2.728 -5.998,4.86 -1.682,2.135 -2.496,4.92 -2.44,8.352 0.082,5.055 2.089,8.91 6.022,11.57 3.931,2.659 8.847,3.938 14.742,3.842 A 37.212,37.212 0 0 0 73.314,67.3 c 3.804,-1.325 5.115,-14.326 5.115,-14.326 -2.3,2.047 -5.06,3.664 -8.283,4.85 -3.22,1.188 -6.289,1.805 -9.205,1.852 -2.333,0.038 -4.201,-0.336 -5.608,-1.124 -1.406,-0.788 -2.123,-1.992 -2.149,-3.611 -0.03,-1.813 0.759,-3.187 2.363,-4.122 1.606,-0.933 4.214,-1.978 7.824,-3.141 3.482,-1.092 6.317,-2.16 8.503,-3.202 2.187,-1.04 4.075,-2.592 5.66,-4.661 1.587,-2.067 2.354,-4.753 2.3,-8.057 -0.058,-3.56 -1.028,-6.5 -2.867,-8.856 7.147,5.166 11.802,13.567 11.802,23.06 0,15.709 -12.734,28.443 -28.442,28.443"
id="path675"
style="fill:#ed5039;fill-opacity:1" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

-24
View File
@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="78px" height="78px" viewBox="0 0 78 78" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 60 (88103) - https://sketch.com -->
<title>Group</title>
<desc>Created with Sketch.</desc>
<defs>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#FFE96D" offset="0%"></stop>
<stop stop-color="#E1C218" offset="100%"></stop>
</linearGradient>
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
<stop stop-color="#FFE96D" offset="0%"></stop>
<stop stop-color="#ECD138" offset="62.3511283%"></stop>
<stop stop-color="#E1C218" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Logo" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group">
<circle id="Oval" stroke="#EED33E" stroke-width="3" fill="#081E36" cx="39" cy="39" r="37.5"></circle>
<path d="M36.4583326,43.7755404 L40.53965,35.2316544 L39.4324865,35.2316544 L46.0754873,17.6071752 C46.292579,17.0204094 46.3287609,16.5159331 46.1840331,16.0937464 C46.0393053,15.671561 45.7860319,15.3674444 45.4242131,15.1813966 C45.0623942,14.9953487 44.6535376,14.9524146 44.1976433,15.0525945 C43.7417511,15.1527743 43.3256596,15.4461573 42.9493689,15.9327433 L22.6078557,40.7701025 C22.2026186,41.2710003 22,41.7575877 22,42.2298646 C22,42.6735173 22.1592003,43.0420366 22.477601,43.3354226 C22.7960017,43.6288058 23.1940025,43.7755404 23.6716036,43.7755404 L36.4583326,43.7755404 Z" id="Path" fill="url(#linearGradient-1)"></path>
<path d="M44.4883879,63.7755404 L48.8604707,55.165009 L47.6744296,55.165009 L54.7906978,37.4030526 C55.0232558,36.8117097 55.0620155,36.3032983 54.9069768,35.8778185 C54.7519381,35.4523399 54.4806208,35.1458511 54.0930248,34.958352 C53.7054289,34.7708528 53.2674441,34.7275839 52.7790706,34.8285452 C52.2906992,34.9295065 51.8449641,35.2251779 51.4418653,35.7155595 L29.6511611,60.746659 C29.2170537,61.251464 29,61.7418469 29,62.2178078 C29,62.6649211 29.1705423,63.036315 29.5116268,63.3319895 C29.8527113,63.6276613 30.2790669,63.7755404 30.7906936,63.7755404 L44.4883879,63.7755404 Z" id="Path-Copy" fill="url(#linearGradient-2)" transform="translate(42.000000, 49.275540) rotate(-180.000000) translate(-42.000000, -49.275540) "></path>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

-1
View File
@@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg id="Layer_1" data-name="Layer 1" version="1.1" width="24.63" height="23.44" xmlns="http://www.w3.org/2000/svg"><defs id="defs4"><style id="style2">.edge-logo-cls-2{fill-rule:evenodd;fill:#66eda8}</style></defs><g id="Navigation_header_L_sticky" data-name="Navigation/header_L_sticky"><g id="edge_logo_dark" data-name="edge logo dark"><path id="Fill-10" class="edge-logo-cls-2" d="M.43 23.44 4.22 13h6.66l3.5-9.63h10.25l-7.3 20.07z"/><path id="Fill-12" class="edge-logo-cls-2" d="M0 10.46 3.82 0h9.04L9.05 10.46z"/></g></g></svg>

Before

Width:  |  Height:  |  Size: 588 B

-1
View File
@@ -1 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg width="56.91" height="56.91" fill="none" xmlns="http://www.w3.org/2000/svg"><path style="fill:#3654ff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4" d="M0 0h56.91v56.91H0z"/><path d="M35.097 23.313a6.521 6.521 0 0 0-.838-1.839 5.378 5.378 0 0 0-1.314-1.364 5.868 5.868 0 0 0-1.761-.859 7.545 7.545 0 0 0-2.18-.298c-1.487 0-2.792.37-3.914 1.108-1.122.738-1.996 1.811-2.621 3.217-.625 1.406-.938 3.123-.938 5.15 0 2.025.308 3.75.923 5.17s1.486 2.502 2.613 3.245c1.127.743 2.458 1.115 3.992 1.115 1.392 0 2.583-.249 3.572-.746.99-.497 1.748-1.2 2.273-2.109.498-.863.76-1.876.786-3.04h-6.248v-4.63h12.174v3.664c0 2.557-.54 4.752-1.62 6.584a10.975 10.975 0 0 1-4.46 4.233c-1.893.99-4.061 1.484-6.504 1.484-2.728 0-5.123-.604-7.188-1.812-2.065-1.208-3.672-2.926-4.823-5.156-1.15-2.23-1.726-4.879-1.726-7.947 0-2.358.343-4.463 1.03-6.313.687-1.852 1.65-3.42 2.89-4.709a12.495 12.495 0 0 1 4.334-2.94c1.647-.673 3.433-1.009 5.355-1.009 1.648 0 3.182.24 4.602.718 1.42.478 2.683 1.152 3.786 2.023a11.025 11.025 0 0 1 2.706 3.104 10.648 10.648 0 0 1 1.35 3.955z" fill="#fff"/></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

@@ -1,3 +0,0 @@
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 417.5H52.6667V437.75H113.667V417.5H134V215H154.333V174.5H134V154.25H93.3333V174.5H73V194.75H52.6667V215H113.667V255.5H93.3333V275.75H52.6667V255.5H32.3333V174.5H52.6667V154.25H73V134H195V154.25H215.333V174.5H235.667V215H256V255.5H276.333V275.75H296.667V235.25H317V215H337.333V174.5H357.667V134H378V113.75H398.333V73.25H439V53H479.667V73.25H500V93.5H459.333V73.25H439V93.5H418.667V336.5H439V437.75H459.333V458H378V437.75H357.667V235.25H337.333V255.5H317V296H296.667V336.5H276.333V377H235.667V336.5H215.333V296H195V235.25H174.667V356.75H154.333V417.5H134V437.75H113.667V458H32.3333V437.75H12V417.5Z" fill="#E23A5E"/>
</svg>

Before

Width:  |  Height:  |  Size: 735 B

+2 -5
View File
@@ -95,7 +95,7 @@ do for url in / \
'/api/v1/lightning/statistics/3y' \
'/api/v1/lightning/statistics/all' \
'/api/v1/lightning/nodes/isp-ranking' \
'/api/v1/lightning/nodes/isp/15169,396982' `# Google` \
'/api/v1/lightning/nodes/isp/396982,15169' `# Google` \
'/api/v1/lightning/nodes/isp/14618,16509' `# Amazon` \
'/api/v1/lightning/nodes/isp/39572' `# DataWeb` \
'/api/v1/lightning/nodes/isp/14061' `# Digital Ocean` \
@@ -107,15 +107,12 @@ do for url in / \
'/api/v1/lightning/nodes/isp/34197' `# SHRD SARL` \
'/api/v1/lightning/nodes/isp/42275' `# Three Fourteen SASU` \
'/api/v1/lightning/nodes/isp/16276' `# OVH SAS` \
'/api/v1/lightning/nodes/isp/10796,11351,11426,11427,12271,20001,20115,33363' `# Spectrum` \
'/api/v1/lightning/nodes/isp/11426,11427,20001,20115,11351,10796,33363,12271' `# Spectrum` \
'/api/v1/lightning/nodes/isp/701' `# Verizon` \
'/api/v1/lightning/nodes/isp/12876' `# Scaleway` \
'/api/v1/lightning/nodes/isp/33915' `# Ziggo` \
'/api/v1/lightning/nodes/isp/3320' `# Deutsche Telekom AG` \
'/api/v1/lightning/nodes/isp/8075' `# Microsoft Azure` \
'/api/v1/lightning/nodes/isp/212531', `# UAB Interneto vizija` \
'/api/v1/lightning/nodes/isp/63949', `# Linode` \
'/api/v1/lightning/nodes/isp/51167', `# Contabo GmbH` \
'/api/v1/lightning/nodes/countries' \
'/api/v1/lightning/nodes/rankings' \
'/api/v1/lightning/nodes/rankings/liquidity' \