From 8df076e1af6ca0feb0c43770ece7cb5883037cb9 Mon Sep 17 00:00:00 2001 From: mistakia <1823355+mistakia@users.noreply.github.com> Date: Sat, 17 Feb 2024 08:29:35 -0500 Subject: [PATCH 01/26] feat: add internationalization support --- api/server.mjs | 43 +- locales/en.json | 386 +++++++++++++++ package.json | 5 + src/core/api/service.js | 11 +- src/core/app/actions.js | 5 +- src/core/constants.js | 20 + src/core/docs/actions.js | 5 +- src/core/i18n/actions.js | 10 + src/core/i18n/index.js | 26 + src/core/i18n/reducer.js | 17 + src/core/i18n/sagas.js | 37 ++ src/core/reducers.js | 4 +- src/core/sagas.js | 4 +- src/styles/variables.styl | 3 + .../account-blocks-summary.js | 190 ++++---- .../components/account-meta/account-meta.js | 170 ++++--- src/views/components/app/app.js | 10 +- src/views/components/block-info/block-info.js | 123 ++--- .../components/change-locale/change-locale.js | 59 +++ .../change-locale/change-locale.styl | 15 + src/views/components/change-locale/index.js | 17 + .../components/github-events/github-events.js | 118 +++-- .../ledger-chart-addresses.js | 24 +- .../ledger-chart-amounts.js | 13 +- .../ledger-chart-blocks.js | 31 +- .../ledger-chart-metrics.js | 14 +- .../ledger-chart-usd-transferred.js | 24 +- .../ledger-chart-volume.js | 18 +- src/views/components/menu/menu.js | 262 +++++----- src/views/components/menu/menu.styl | 6 +- src/views/components/network/network.js | 448 ++++++++--------- .../representative-alerts.js | 268 +++++----- .../representative-delegators.js | 23 +- .../representative-info.js | 76 ++- .../representative-network.js | 70 ++- .../representative-telemetry.js | 155 +++--- .../representative-uptime.js | 210 ++++---- .../representatives-bandwidth-by-weight.js | 32 +- .../representatives-cemented-by-weight.js | 35 +- .../representatives-checked-by-weight.js | 35 +- .../representatives-cluster-charts.js | 367 +++++++------- .../representatives-country-by-weight.js | 27 +- .../representatives-filters.js | 28 +- .../representatives-offline.js | 99 ++-- .../representatives-provider-by-weight.js | 27 +- .../representatives-quorum-charts.js | 382 +++++++-------- .../representatives-search.js | 7 +- .../representatives-version-by-weight.js | 27 +- .../representatives-weight-chart.js | 117 ++--- .../representatives-weight.js | 89 ++-- .../representatives/representatives.js | 456 +++++++++--------- src/views/components/search-bar/search-bar.js | 7 +- src/views/components/uptime/uptime.js | 80 +-- src/views/pages/account/account.js | 104 ++-- src/views/pages/block/block.js | 205 ++++---- src/views/pages/doc/doc.js | 274 +++++------ src/views/pages/home/home.js | 74 +-- src/views/pages/ledger/ledger.js | 143 +++--- .../pages/representatives/representatives.js | 167 ++++--- src/views/pages/roadmap/roadmap.js | 20 +- src/views/root.js | 6 - src/views/routes.js | 5 + webpack/webpack.dev.babel.mjs | 7 + yarn.lock | 211 +++++++- 64 files changed, 3556 insertions(+), 2395 deletions(-) create mode 100644 locales/en.json create mode 100644 src/core/i18n/actions.js create mode 100644 src/core/i18n/index.js create mode 100644 src/core/i18n/reducer.js create mode 100644 src/core/i18n/sagas.js create mode 100644 src/views/components/change-locale/change-locale.js create mode 100644 src/views/components/change-locale/change-locale.styl create mode 100644 src/views/components/change-locale/index.js diff --git a/api/server.mjs b/api/server.mjs index 02050a2c..bbf07af0 100644 --- a/api/server.mjs +++ b/api/server.mjs @@ -18,6 +18,7 @@ import serveStatic from 'serve-static' import cors from 'cors' import favicon from 'express-favicon' import robots from 'express-robots-txt' +import { slowDown } from 'express-slow-down' import * as config from '#config' import * as routes from '#api/routes/index.mjs' @@ -70,6 +71,9 @@ api.use((req, res, next) => { const resourcesPath = path.join(__dirname, '..', 'resources') api.use('/resources', serveStatic(resourcesPath)) +const localesPath = path.join(__dirname, '..', 'locales') +api.use('/locales', serveStatic(localesPath)) + const dataPath = path.join(__dirname, '..', 'data') api.use('/data', serveStatic(dataPath)) @@ -95,9 +99,42 @@ api.use('/api/representatives', routes.representatives) api.use('/api/weight', routes.weight) const docsPath = path.join(__dirname, '..', 'docs') -api.use('/api/docs', serveStatic(docsPath)) -api.get('/api/docs/*', (req, res) => { - res.status(404).send('Not found') + +const speedLimiter = slowDown({ + windowMs: 10 * 60 * 1000, // 10 minutes + delayAfter: 50, // allow 50 requests per 10 minutes, then... + delayMs: 500, // begin adding 500ms of delay per request above 50: + maxDelayMs: 20000 // maximum delay of 20 seconds +}) + +api.use('/api/docs', speedLimiter, serveStatic(docsPath)) +api.use('/api/docs/en', speedLimiter, serveStatic(docsPath)) +api.get('/api/docs/:locale/*', speedLimiter, async (req, res) => { + const { locale } = req.params + const doc_id = req.params[0] // Capture the rest of the path as doc_id + const localized_doc_path = path.join(docsPath, locale, `${doc_id}.md`) + const default_doc_path = path.join(docsPath, 'en', `${doc_id}.md`) + + // check if paths are under the docs directory + if ( + !localized_doc_path.startsWith(docsPath) || + !default_doc_path.startsWith(docsPath) + ) { + return res.status(403).send('Forbidden') + } + + try { + if (fs.existsSync(localized_doc_path)) { + return res.sendFile(localized_doc_path) + } else if (fs.existsSync(default_doc_path)) { + return res.redirect(`/api/docs/en/${doc_id}`) + } else { + return res.status(404).send('Document not found') + } + } catch (error) { + console.error(error) + return res.status(500).send('Internal Server Error') + } }) api.use('/api/*', (err, req, res, next) => { diff --git a/locales/en.json b/locales/en.json new file mode 100644 index 00000000..d2677cf1 --- /dev/null +++ b/locales/en.json @@ -0,0 +1,386 @@ +{ + "account_page": { + "address": "Account Address", + "change_summary": "Change Summary", + "copy_notification": "Account address copied", + "seo_description": "Information for nano representative", + "seo_title": "Nano Account", + "telemetry_charts": "Telemetry Charts", + "unopened_description": "While the account address is valid, no blocks have been observed. If NANO has been sent to this account, it still needs to publish a corresponding block to receive the funds and establish an opening balance. An account's balance can only be updated by the account holder as they are the only ones who can publish blocks to their chain.", + "unopened_note": "If an opening block has already been published, it may take a few moments to spread through the network and be observed by the nano.community nodes.", + "unopened_title": "This account hasn't been opened yet" + }, + "account_blocks_summary": { + "first_timestamp": "First Timestamp", + "last_timestamp": "Last Timestamp", + "max_amount": "Max Amount", + "min_amount": "Min Amount", + "no_records": "No Records", + "receiving_account": "Receiving Account", + "representative_account": "Representative Account", + "sending_account": "Sending Account", + "showing_top_10": "Showing top 10 accounts by total descending", + "transactions": "TXs" + }, + "account_meta": { + "account_info": "Account Info", + "funding_account": "Funding Account", + "funding_timestamp": "Funding Timestamp", + "height": "Height", + "last_modified": "Last Modified", + "open_timestamp": "Open Timestamp", + "opening_balance": "Opening Balance", + "receivable_balance": "Receivable Balance" + }, + "block_page": { + "amount": "Amount", + "copy_notification": "Block hash copied", + "delegated_representative": "Delegated Representative", + "description": "Description", + "epoch_v1": "Epoch v1 — Upgraded account-chains from legacy blocks (open, receive, send, change) to state blocks.", + "epoch_v2": "Epoch v2 - Upgraded account-chains to use higher Proof-of-Work difficulty.", + "receiving_account": "Receiving Account", + "section_label": "Block Hash", + "sending_account": "Sending Account", + "seo_description": "Information related to a Nano Block", + "seo_title": "Nano Block", + "voting_weight": "Voting Weight" + }, + "block_info": { + "block_account": "Block Account", + "operation": "Operation", + "status": "Status", + "timestamp": "Timestamp" + }, + "block_status": { + "confirmed": "Confirmed", + "unconfirmed": "Unconfirmed" + }, + "block_type": { + "change": "Change", + "epoch": "Epoch", + "open": "Open", + "receive": "Receive", + "send": "Send" + }, + "common": { + "account_one": "Account", + "account_other": "Accounts", + "address": "Address", + "balance": "Balance", + "bandwidth_limit": "Bandwidth Limit", + "blocks": "Blocks", + "blocks_diff_short": "Blocks Diff", + "by_online_weight": "By Online Weight", + "clear_filters": "Clear Filters", + "click_to_copy": "Click to copy", + "collapse": "Collapse", + "conf_short": "Conf.", + "conf_diff_short": "Conf. Diff", + "country": "Country", + "delegator_one": "Delegator", + "delegator_other": "Delegators", + "max": "Max", + "min": "Min", + "offline": "Offline", + "online": "Online", + "peers": "Peers", + "percent_of_total": "% of Total", + "port": "Port", + "quorum_delta": "Quorum Delta", + "representative_one": "Representative", + "representative_other": "Representatives", + "show_more": "Show {{count}} more", + "total": "Total", + "unchecked": "Unchecked", + "unlimited": "Unlimited", + "version": "Version", + "weight": "Weight" + }, + "delegators": { + "showing_top_delegators": "Showing top 100 delegators with a minimum balance of 1 Nano." + }, + "doc": { + "contributors": "Contributor", + "document_not_found": "Document (or Account) not found", + "edit_page": "Edit Page", + "help_out": "Help out", + "not_found_404": "404", + "section_link_copied": "Section link copied", + "updated_by": "updated by" + }, + "github_events": { + "action": { + "added_member": "added member", + "commented_on_commit": "commented on commit", + "commented_on_issue": "commented on issue", + "commented_on_pr_review": "commented on pr review", + "created": "created {{action}}", + "deleted": "deleted {{action}}", + "forked": "forked", + "issue_action": "{{action}} issue", + "made_public": "made public", + "pr_action": "{{action}} pr", + "pr_review": "pr review {{title}}", + "published_release": "published release", + "pushed_commit": "pushed commit to {{ref}}", + "sponsorship_started": "sponsorship started", + "watching_repo": "watching repo" + }, + "events_title": "Development Events" + }, + "ledger": { + "addresses": { + "active_detail": "Active shows the number of unique addresses used. New shows the number of addresses created. Reused shows the number of addresses used that were created on a previous day.", + "active_stats": "Active Address Stats", + "new_stats": "New Address Stats", + "total_number": "The total number of active, new, and reused addresses used per day." + }, + "amounts": { + "total_number": "The number of confirmed send-type blocks per day where the amount in the block is in a given range (in Nano)" + }, + "blocks": { + "change": "Change Block Stats", + "description": "The number of blocks confirmed per day.", + "open": "Open Block Stats", + "receive": "Receive Block Stats", + "send": "Send Block Stats", + "total": "Total Block Stats" + }, + "description": "Description", + "usd_transferred": { + "desc_1": "The total amount of value transferred (in USD) per day.", + "desc_2": "Based on the daily closing price of Nano/USD and the total amount of Nano transferred that day.", + "usd_transferred": "USD Transferred", + "usd_transferred_stats": "USD Transferred Stats" + }, + "volume": { + "change_stats": "Change Stats", + "description": "The total amount sent (in Nano) and total amount of voting weight changed per day.", + "send_stats": "Send Stats" + } + }, + "ledger_page": { + "addresses_tab": "Addresses", + "amounts_tab": "Amounts", + "blocks_tab": "Blocks", + "seo_description": "On-chain metrics and analytics of the Nano ledger", + "seo_title": "Nano Ledger Analysis", + "value_transferred_tab": "Value Transferred", + "volume_tab": "Volume" + }, + "menu": { + "account_setup": "Account Setup", + "acquiring": "Acquiring", + "advantages": "Advantages", + "attack_vectors": "Attack Vectors", + "basics": "Basics", + "best_practices": "Best Practices", + "choosing_a_rep": "Choosing a Rep", + "challenges": "Challenges", + "communities": "Communities", + "contribution_guide": "Contribution Guide", + "design": "Design", + "developer_discussions": "Developer Discussions", + "developers": "Developers", + "documentation": "Documentation", + "faqs": "FAQs", + "get_involved": "Get Involved", + "get_support": "Get Support", + "getting_started": "Getting Started", + "glossary": "Glossary", + "guides": "Guides", + "history": "History", + "how_it_works": "How it works", + "integrations": "Integrations", + "investment_thesis": "Investment thesis", + "learn": "Learn", + "ledger": "Ledger", + "misconceptions": "Misconceptions", + "overview": "Overview", + "planning": "Planning 👾", + "privacy": "Privacy", + "protocol": "Protocol", + "running_a_node": "Running a node", + "security": "Security", + "stats": "Stats", + "storing": "Storing", + "telemetry": "Telemetry", + "topics": "Topics", + "using": "Using", + "why_it_matters": "Why it matters" + }, + "network": { + "unconfirmed_pool_text": "Number of blocks waiting to be confirmed $(network.pr_text)", + "censor_text": "The minimum number of representatives needed to censor transactions or stall the network", + "confirm_text": "The minimum number of representatives needed to confirm transactions", + "confirmations": "Confirmations (24h)", + "confirmations_text": "Total number of transactions confirmed by the network over the last 24 hours", + "energy_text": "Estimated live network CPU energy usage of Principle Representatives based on collected CPU model info. The estimate is based on CPU TDP, which is the average power, in watts, the processor dissipates when operating at base frequency with all cores active under manufacture-defined, high-complexity workload", + "energy_usage": "Energy Usage (TDP) (24h)", + "nano_ticker": "NanoTicker", + "online_stake": "Online Stake", + "principal_reps": "Principal Reps", + "pr_text": "as observed across the networks principal representatives: voting nodes with more than 0.1% of the online voting weight delegated to them", + "reps_to_censor": "Reps to Censor or Stall", + "reps_to_confirm": "Reps to Confirm", + "settlement": "Settlement (24h)", + "settlement_text": "Total amount of value settled by the network over the last 24 hours (only send blocks)", + "speed_text": "Median time in milliseconds for a block to get confirmed (across all buckets)", + "stats_title": "Network Stats", + "total_reps": "Total Reps (24h)", + "tx_backlog": "Tx Backlog", + "tx_fees": "Tx Fees (24h)", + "tx_speed": "Tx Speed ({{time_range}})", + "tx_throughput": "Tx Throughput", + "throughput_text": "Median number of transactions confirmed per second in the last minute $(network.pr_text)" + }, + "posts": { + "nano_foundation": "Nano Foundation", + "top": "Top", + "trending": "Trending" + }, + "representative_alerts": { + "table_header": { + "behind": "Behind", + "issue": "Issue", + "last_online": "Last Online", + "percent_online_weight": "% Online Weight", + "representative": "Representative" + }, + "tooltip": { + "behind": "Representative has fallen behind or is bootstrapping. The cutoff is a cemented count beyond the 95th percentile. (via telemetry)", + "low_uptime": "Representative has been offline more than 25% in the last 28 days.", + "offline": "Representative has stopped voting and appears offline.", + "overweight": "Representative has beyond 3M Nano voting weight. Delegators should consider distributing the weight to improve the network's resilience and value." + }, + "type": { + "behind": "Behind", + "low_uptime": "Low Uptime", + "offline": "Offline", + "overweight": "Overweight" + } + }, + "representatives_cemented_by_weight": { + "title": "Confirmation Differential", + "tooltip": "Displays the amount of voting weight that is within X number of confirmations from the leading node. Helpful in knowing how well in-sync and aligned nodes are across the network" + }, + "representatives_checked_by_weight": { + "title": "Blocks Differential", + "tooltip": "Displays the amount of voting weight that is within X number of blocks from the leading node. Useful for getting a sense of how in-sync block propagation is within the network" + }, + "representative_delegators": { + "showing_top_delegators": "Showing top 100 delegators with a minimum balance of 1 Nano." + }, + "representative_info": { + "first_seen": "First Seen", + "last_seen": "Last Seen", + "weight_represented": "Weight Represented" + }, + "representative_network": { + "city": "City", + "isp": "ISP", + "network": "Network", + "provider": "Provider" + }, + "representative_telemetry": { + "blocks_diff": "Blocks Diff", + "conf": "Conf.", + "conf_diff": "Conf. Diff", + "telemetry": "Telemetry", + "telemetry_timestamp": "Telemetry Timestamp" + }, + "representative_uptime": { + "2m_uptime": "2M Uptime", + "2w_uptime": "2W Uptime", + "3m_uptime": "3M Uptime", + "current_status": "Current Status", + "down": "Down", + "down_for": "Down for", + "operational": "Operational", + "up_for": "Up for", + "warning": "Warning" + }, + "representatives": { + "alias": "Alias", + "cpu_cores": "CPU Cores", + "cpu_model": "CPU Model", + "tdp": "TDP (wH)", + "protocol_version": "Protocol", + "last_seen": "Last Seen", + "host_asn": "Host ASN" + }, + "representatives_bandwidth_by_weight": { + "tooltip": "Displays the amount of voting weight based on the bandwidth limit set locally by each node" + }, + "representatives_cluster": { + "blocks_diff": "Blocks Behind", + "conf_diff": "Confirmations Behind", + "unchecked": "Unchecked Count" + }, + "representatives_country_by_weight": { + "title": "Country" + }, + "representatives_offline": { + "account": "Offline Account", + "last_online": "Last Online" + }, + "representatives_page": { + "seo_description": "Explore and analyze Nano network representatives", + "seo_title": "Nano Representatives Explorer", + "telemetry_tab": "Telemetry", + "weight_distribution_tab": "Weight Distribution", + "weight_history_tab": "Weight History", + "offline_reps_tab": "Offline Reps" + }, + "representatives_provider_by_weight": { + "title": "Hosting Provider" + }, + "representatives_quorum_charts": { + "peers_weight": "Peers Weight", + "quorum_delta": "Quorum Delta", + "title": "Quorum Charts", + "trended_weight": "Trended Weight" + }, + "representatives_search": { + "placeholder": "Filter by account, alias, ip" + }, + "representatives_weight": { + "trended": "Trended" + }, + "representatives_weight_chart": { + "title": "Weight Distribution by Representative" + }, + "representatives_version_by_weight": { + "title": "Versions" + }, + "roadmap": { + "header": { + "subtitle": "Community objectives", + "title": "Planning" + }, + "seo": { + "description": "Nano development & community roadmap", + "tags": [ + "roadmap", + "nano", + "future", + "release", + "design", + "tasks", + "discussions", + "community", + "ambassadors", + "managers" + ], + "title": "Roadmap" + } + }, + "search_bar": { + "placeholder": "Search by Address / Block Hash" + }, + "uptime": { + "now": "Now", + "days_ago": "days ago" + } +} diff --git a/package.json b/package.json index 18cb527f..5dc73212 100644 --- a/package.json +++ b/package.json @@ -95,9 +95,12 @@ "express-favicon": "^2.0.4", "express-jwt": "^8.4.1", "express-robots-txt": "^1.0.0", + "express-slow-down": "^2.0.1", "fetch-cheerio-object": "^1.3.0", "front-matter": "^4.0.2", "fs-extra": "^11.1.1", + "i18next": "^23.8.2", + "i18next-http-backend": "^2.4.3", "jsonwebtoken": "^9.0.1", "knex": "^0.95.15", "markdown-it": "^12.3.2", @@ -116,6 +119,7 @@ "react": "^17.0.2", "react-dom": "^17.0.2", "react-helmet": "^6.1.0", + "react-i18next": "^14.0.5", "react-redux": "^7.2.9", "react-router": "^5.3.4", "redux-saga": "^1.2.3", @@ -144,6 +148,7 @@ "compression-webpack-plugin": "^10.0.0", "concurrently": "^8.2.0", "copy-text-to-clipboard": "^3.2.0", + "copy-webpack-plugin": "^12.0.2", "cross-env": "^7.0.3", "css-loader": "6.8.1", "deepmerge": "4.3.1", diff --git a/src/core/api/service.js b/src/core/api/service.js index 05413f6b..6f7e1830 100644 --- a/src/core/api/service.js +++ b/src/core/api/service.js @@ -32,9 +32,14 @@ export const api = { const url = `${API_URL}/posts/${id}?${queryString.stringify(params)}` return { url } }, - getDoc({ id }) { - const url = `${API_URL}/docs${id}.md` - return { url } + getDoc({ id, locale = 'en' }) { + if (locale === 'en') { + const url = `${API_URL}/docs${id}.md` + return { url } + } else { + const url = `${API_URL}/docs/${locale}/${id}.md` + return { url } + } }, getLabelDoc({ id }) { const url = `${API_URL}/docs${id}.md` diff --git a/src/core/app/actions.js b/src/core/app/actions.js index e178832a..c671f3ee 100644 --- a/src/core/app/actions.js +++ b/src/core/app/actions.js @@ -1,11 +1,12 @@ export const appActions = { INIT_APP: 'INIT_APP', - init: ({ token, key }) => ({ + init: ({ token, key, locale }) => ({ type: appActions.INIT_APP, payload: { token, - key + key, + locale } }) } diff --git a/src/core/constants.js b/src/core/constants.js index c8b1dfb2..ca98ab23 100644 --- a/src/core/constants.js +++ b/src/core/constants.js @@ -12,3 +12,23 @@ export const WS_URL = IS_DEV ? 'ws://localhost:8080' : 'wss://nano.community' // 3 Million Nano (3e36) export const REP_MAX_WEIGHT = BigNumber(3).shiftedBy(36) +export const SUPPORTED_LOCALES = [ + 'ar', + 'en', + 'de', + 'es', + 'fa', + 'fr', + 'hi', + 'it', + 'ja', + 'ko', + 'nl', + 'pl', + 'pt', + 'ru', + 'tr', + 'vi', + 'zh', + 'no' +] diff --git a/src/core/docs/actions.js b/src/core/docs/actions.js index 2aa6f4d9..956cbcdb 100644 --- a/src/core/docs/actions.js +++ b/src/core/docs/actions.js @@ -19,10 +19,11 @@ export const docActions = { GET_LABEL_DOC_COMMIT_PENDING: 'GET_LABEL_DOC_COMMIT_PENDING', GET_LABEL_DOC_COMMIT_FULFILLED: 'GET_LABEL_DOC_COMMIT_FULFILLED', - getDoc: (id) => ({ + getDoc: ({ id, locale = 'en' }) => ({ type: docActions.GET_DOC, payload: { - id + id, + locale } }), diff --git a/src/core/i18n/actions.js b/src/core/i18n/actions.js new file mode 100644 index 00000000..4e968253 --- /dev/null +++ b/src/core/i18n/actions.js @@ -0,0 +1,10 @@ +export const i18nActions = { + CHANGE_LOCALE: 'CHANGE_LOCALE', + + change_locale: (locale) => ({ + type: i18nActions.CHANGE_LOCALE, + payload: { + locale + } + }) +} diff --git a/src/core/i18n/index.js b/src/core/i18n/index.js new file mode 100644 index 00000000..3fe3721d --- /dev/null +++ b/src/core/i18n/index.js @@ -0,0 +1,26 @@ +import { initReactI18next } from 'react-i18next' +import i18n from 'i18next' +import HttpBackend from 'i18next-http-backend' + +import { SUPPORTED_LOCALES } from '@core/constants' + +export { i18nActions } from './actions' +export { i18nReducer } from './reducer' +export { i18nSagas } from './sagas' + +i18n + .use(HttpBackend) + .use(initReactI18next) + .init({ + // detection + debug: true, + backend: { + // Configuration options for the backend plugin + loadPath: '/locales/{{lng}}.json' // Path to the translation files + }, + lng: 'en', + fallbackLng: 'en', + supportedLngs: SUPPORTED_LOCALES + }) + +export default i18n diff --git a/src/core/i18n/reducer.js b/src/core/i18n/reducer.js new file mode 100644 index 00000000..1891169f --- /dev/null +++ b/src/core/i18n/reducer.js @@ -0,0 +1,17 @@ +import { Record } from 'immutable' + +import { i18nActions } from './actions' + +const initialState = new Record({ + locale: 'en' +}) + +export function i18nReducer(state = initialState(), { payload, type }) { + switch (type) { + case i18nActions.CHANGE_LOCALE: + return state.set('locale', payload.locale) + + default: + return state + } +} diff --git a/src/core/i18n/sagas.js b/src/core/i18n/sagas.js new file mode 100644 index 00000000..06135e04 --- /dev/null +++ b/src/core/i18n/sagas.js @@ -0,0 +1,37 @@ +import { takeLatest, put, fork } from 'redux-saga/effects' +import i18n from 'i18next' + +import { localStorageAdapter } from '@core/utils' +import { appActions } from '@core/app/actions' +import { i18nActions } from './actions' + +export function* init({ payload }) { + if (payload.locale) { + yield put(i18nActions.change_locale(payload.locale)) + } + + // TODO detect user locale +} + +export function ChangeLocale({ payload }) { + localStorageAdapter.setItem('locale', payload.locale) + i18n.changeLanguage(payload.locale) +} + +//= ==================================== +// WATCHERS +// ------------------------------------- + +export function* watchInitApp() { + yield takeLatest(appActions.INIT_APP, init) +} + +export function* watchChangeLocale() { + yield takeLatest(i18nActions.CHANGE_LOCALE, ChangeLocale) +} + +//= ==================================== +// ROOT +// ------------------------------------- + +export const i18nSagas = [fork(watchInitApp), fork(watchChangeLocale)] diff --git a/src/core/reducers.js b/src/core/reducers.js index e85abb34..7ee19b01 100644 --- a/src/core/reducers.js +++ b/src/core/reducers.js @@ -15,6 +15,7 @@ import { postsReducer } from './posts' import { postlistsReducer } from './postlists' import { nanodb_reducer } from './nanodb' import { api_reducer } from './api' +import { i18nReducer } from './i18n' const rootReducer = (history) => combineReducers({ @@ -32,7 +33,8 @@ const rootReducer = (history) => posts: postsReducer, postlists: postlistsReducer, nanodb: nanodb_reducer, - api: api_reducer + api: api_reducer, + i18n: i18nReducer }) export default rootReducer diff --git a/src/core/sagas.js b/src/core/sagas.js index b121138b..3938c284 100644 --- a/src/core/sagas.js +++ b/src/core/sagas.js @@ -11,6 +11,7 @@ import { ledgerSagas } from './ledger' import { networkSagas } from './network' import { postlistSagas } from './postlists' import { nanodb_sagas } from './nanodb' +import { i18nSagas } from './i18n' export default function* rootSage() { yield all([ @@ -24,6 +25,7 @@ export default function* rootSage() { ...ledgerSagas, ...networkSagas, ...postlistSagas, - ...nanodb_sagas + ...nanodb_sagas, + ...i18nSagas ]) } diff --git a/src/styles/variables.styl b/src/styles/variables.styl index 39968701..a6248ee6 100644 --- a/src/styles/variables.styl +++ b/src/styles/variables.styl @@ -9,3 +9,6 @@ $nanoBlueGrey = #676686 $nanoLightBlue = #F4FAFF $hoverShadow = $borderColor + +$hoverBackground = rgba(255, 255, 255, 0.8) +$hoverBorder = rgba(0, 0, 0, 0.23) \ No newline at end of file diff --git a/src/views/components/account-blocks-summary/account-blocks-summary.js b/src/views/components/account-blocks-summary/account-blocks-summary.js index 1490080d..bab7eef0 100644 --- a/src/views/components/account-blocks-summary/account-blocks-summary.js +++ b/src/views/components/account-blocks-summary/account-blocks-summary.js @@ -11,103 +11,121 @@ import TableRow from '@mui/material/TableRow' import LinearProgress from '@mui/material/LinearProgress' import { Link } from 'react-router-dom' import dayjs from 'dayjs' +import { useTranslation } from 'react-i18next' import './account-blocks-summary.styl' -export default class AccountBlocksSummary extends React.Component { - render() { - const { account, type, accountLabel } = this.props +export default function AccountBlocksSummary({ account, type, accountLabel }) { + const { t } = useTranslation() + const items = account.getIn(['blocks_summary', type], []) + const isChange = type === 'change' - const items = account.getIn(['blocks_summary', type], []) - const isChange = type === 'change' + const is_loading = account.get( + `account_is_loading_blocks_${type}_summary`, + true + ) - const is_loading = account.get( - `account_is_loading_blocks_${type}_summary`, - true - ) - - return ( -
- The total number of active, new, and reused addresses used per - day. + {t( + 'ledger.addresses.total_number', + 'The total number of active, new, and reused addresses used per day.' + )}
- Active shows the number of unique addresses used. New shows the - number of addresses created. Reused shows the number of addresses - used that were created on a previous day. + {t( + 'ledger.addresses.active_detail', + 'Active shows the number of unique addresses used. New shows the number of addresses created. Reused shows the number of addresses used that were created on a previous day.' + )}
The total amount of value transferred (in USD) per day.
- Based on the daily closing price of Nano/USD and the total amount - of Nano transferred that day. + {t( + 'ledger.usd_transferred.desc_1', + 'The total amount of value transferred (in USD) per day.' + )} +
++ {t( + 'ledger.usd_transferred.desc_2', + 'Based on the daily closing price of Nano/USD and the total amount of Nano transferred that day.' + )}
- While the account address is valid, no blocks have been observed. - If NANO has been sent to this account, it still needs to publish a - corresponding block to receive the funds and establish an opening - balance. An accounts balance can only be updated by the account - holder as they are the only ones who can publish blocks to their - chain. + {t( + 'account_page.unopened_description', + "While the account address is valid, no blocks have been observed. If NANO has been sent to this account, it still needs to publish a corresponding block to receive the funds and establish an opening balance. An account's balance can only be updated by the account holder as they are the only ones who can publish blocks to their chain." + )}
- If an opening block has already been published, it may take a few - moments to spread through the network and be observed by the - nano.community nodes. + {t( + 'account_page.unopened_note', + 'If an opening block has already been published, it may take a few moments to spread through the network and be observed by the nano.community nodes.' + )}
Document (or Account) not found
-#([a-z0-9]{6})<\/code>/gi,
- '#$1
'
- )
+
+
+
+
+
+ {t('doc.document_not_found', 'Document (or Account) not found')} +
#([a-z0-9]{6})<\/code>/gi,
+ '#$1
'
+ )
+
+ return (
+
+ t.trim()) : []}
+ path={path}
+ />
+
+
+
+
+
+
+ {Boolean(authors.length) && (
+
+ {authors}
+
+ )}
+ {Boolean(authors.length) && (
+
+ {authors.length} {t('doc.contributors', 'Contributor')}
+ {authors.length !== 1 ? 's' : ''}.{' '}
+
+ {t('doc.help_out', 'Help out')}
+
+
+ )}
+ {Boolean(author) && (
+
+ {t('doc.updated_by', 'updated by')}{' '}
+
+ {author} {timeago.format(lastUpdated)}
+
+
+ )}
+
+
+
+
+
+
+ )
}
DocPage.propTypes = {
diff --git a/src/views/pages/home/home.js b/src/views/pages/home/home.js
index 817ea1f9..201515ea 100644
--- a/src/views/pages/home/home.js
+++ b/src/views/pages/home/home.js
@@ -1,4 +1,5 @@
import React from 'react'
+import { useTranslation } from 'react-i18next'
import RepresentativeAlerts from '@components/representative-alerts'
import Posts from '@components/posts'
@@ -9,42 +10,45 @@ import Seo from '@components/seo'
import './home.styl'
-export default class HomePage extends React.Component {
- render() {
- return (
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
- )
- }
+
+ )
}
diff --git a/src/views/pages/ledger/ledger.js b/src/views/pages/ledger/ledger.js
index 547948b0..22c6aa10 100644
--- a/src/views/pages/ledger/ledger.js
+++ b/src/views/pages/ledger/ledger.js
@@ -1,7 +1,8 @@
-import React from 'react'
+import React, { useState, useEffect } from 'react'
import PropTypes from 'prop-types'
import Tabs from '@mui/material/Tabs'
import Tab from '@mui/material/Tab'
+import { useTranslation } from 'react-i18next'
import LedgerChartBlocks from '@components/ledger-chart-blocks'
import LedgerChartAddresses from '@components/ledger-chart-addresses'
@@ -29,82 +30,78 @@ TabPanel.propTypes = {
index: PropTypes.number
}
-export default class LedgerPage extends React.Component {
- constructor(props) {
- super(props)
+export default function LedgerPage({ load, data, isLoading }) {
+ const { t } = useTranslation()
+ const [value, setValue] = useState(0)
- this.state = {
- value: 0
- }
- }
-
- handleChange = (event, value) => {
- this.setState({ value })
- }
+ useEffect(() => {
+ load()
+ }, [])
- componentDidMount() {
- this.props.load()
+ const handleChange = (event, value) => {
+ setValue(value)
}
- render() {
- const { data, isLoading } = this.props
-
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
- )
- }
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ )
}
LedgerPage.propTypes = {
diff --git a/src/views/pages/representatives/representatives.js b/src/views/pages/representatives/representatives.js
index 93d6a5f6..1b683879 100644
--- a/src/views/pages/representatives/representatives.js
+++ b/src/views/pages/representatives/representatives.js
@@ -1,7 +1,8 @@
-import React from 'react'
+import React, { useState } from 'react'
import PropTypes from 'prop-types'
import Tabs from '@mui/material/Tabs'
import Tab from '@mui/material/Tab'
+import { useTranslation } from 'react-i18next'
import Seo from '@components/seo'
import Menu from '@components/menu'
@@ -22,9 +23,7 @@ import RepresentativesQuorumCharts from '@components/representatives-quorum-char
import './representatives.styl'
-function TabPanel(props) {
- const { children, value, index, ...other } = props
-
+function TabPanel({ children, value, index, ...other }) {
return (
{
- this.setState({ value })
+ const handleChange = (event, value) => {
+ setValue(value)
}
- render() {
- return (
- <>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
- >
- )
- }
+
+
+
+
+ >
+ )
}
diff --git a/src/views/pages/roadmap/roadmap.js b/src/views/pages/roadmap/roadmap.js
index 7ea2cd02..22eb25a8 100644
--- a/src/views/pages/roadmap/roadmap.js
+++ b/src/views/pages/roadmap/roadmap.js
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
import ImmutablePropTypes from 'react-immutable-proptypes'
import { List } from 'immutable'
import { GithubIssue as GithubIssueRecord } from '@core/github-issues'
+import { useTranslation } from 'react-i18next'
import Seo from '@components/seo'
import Menu from '@components/menu'
@@ -78,6 +79,8 @@ export default function RoadmapPage({
load_github_discussions,
load_github_issues
}) {
+ const { t } = useTranslation()
+
useEffect(() => {
load_github_discussions()
load_github_issues({
@@ -131,9 +134,12 @@ export default function RoadmapPage({
return (
<>
@@ -182,8 +188,10 @@ export default function RoadmapPage({
- Planning
- Community discussions
+ {t('roadmap.header.title', 'Planning')}
+
+ {t('roadmap.header.subtitle', 'Community objectives')}
+
{items}
diff --git a/src/views/root.js b/src/views/root.js
index 486e0d25..5f62b064 100644
--- a/src/views/root.js
+++ b/src/views/root.js
@@ -10,18 +10,12 @@ import createStore from '@core/store'
import history from '@core/history'
import App from '@components/app'
-// Import Language Provider
-// import LanguageProvider from 'containers/LanguageProvider';
-
// Load the favicon and the .htaccess file
// import '!file-loader?name=[name].[ext]!./images/favicon.ico';
// import 'file-loader?name=.htaccess!./.htaccess'; // eslint-disable-line import/extensions
// import configureStore from './configureStore';
-// Import i18n messages
-// import { translationMessages } from './i18n';
-
// Observe loading of Open Sans (to remove open sans, remove the tag in
// the index.html file and this observer)
// const openSansObserver = new FontFaceObserver('Open Sans', {});
diff --git a/src/views/routes.js b/src/views/routes.js
index 4e0428b3..5e9d67eb 100644
--- a/src/views/routes.js
+++ b/src/views/routes.js
@@ -12,6 +12,7 @@ import RepresentativesPage from '@pages/representatives'
import TelemetryPage from '@pages/telemetry'
import LabelPage from '@pages/label'
import LivePage from '@pages/live'
+import { SUPPORTED_LOCALES } from '@core/constants'
const Routes = () => (
@@ -31,6 +32,10 @@ const Routes = () => (
component={AccountPage}
/>
+
)
diff --git a/webpack/webpack.dev.babel.mjs b/webpack/webpack.dev.babel.mjs
index 737b25dc..cf883f04 100644
--- a/webpack/webpack.dev.babel.mjs
+++ b/webpack/webpack.dev.babel.mjs
@@ -6,6 +6,7 @@ import path from 'path'
import webpack from 'webpack'
import HtmlWebpackPlugin from 'html-webpack-plugin'
import CircularDependencyPlugin from 'circular-dependency-plugin'
+import CopyWebpackPlugin from 'copy-webpack-plugin'
import base from './webpack.base.babel.mjs'
@@ -44,6 +45,12 @@ export default base({
new CircularDependencyPlugin({
exclude: /a\.js|node_modules/, // exclude node_modules
failOnError: false // show a warning when there is a circular dependency
+ }),
+ new CopyWebpackPlugin({
+ patterns: [
+ { from: 'locales', to: 'locales' },
+ { from: 'resources', to: 'resources' }
+ ]
})
],
diff --git a/yarn.lock b/yarn.lock
index 81309f04..4cf0571e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2460,6 +2460,15 @@ __metadata:
languageName: node
linkType: hard
+"@babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.23.9":
+ version: 7.23.9
+ resolution: "@babel/runtime@npm:7.23.9"
+ dependencies:
+ regenerator-runtime: ^0.14.0
+ checksum: 6bbebe8d27c0c2dd275d1ac197fc1a6c00e18dab68cc7aaff0adc3195b45862bae9c4cc58975629004b0213955b2ed91e99eccb3d9b39cabea246c657323d667
+ languageName: node
+ linkType: hard
+
"@babel/template@npm:^7.22.15, @babel/template@npm:^7.23.9":
version: 7.23.9
resolution: "@babel/template@npm:7.23.9"
@@ -3511,6 +3520,13 @@ __metadata:
languageName: node
linkType: hard
+"@sindresorhus/merge-streams@npm:^2.1.0":
+ version: 2.2.1
+ resolution: "@sindresorhus/merge-streams@npm:2.2.1"
+ checksum: edb3d7b8fd9cdf4976c32483f073bb903f8ee94a2f1e93b47cc7d9205ac77cf64fce751ea45b1b39036a8de19d980cb942fff596c0d200232f3e1d4835c8ca4b
+ languageName: node
+ linkType: hard
+
"@smithy/abort-controller@npm:^2.1.1":
version: 2.1.1
resolution: "@smithy/abort-controller@npm:2.1.1"
@@ -4943,7 +4959,7 @@ __metadata:
languageName: node
linkType: hard
-"ajv-keywords@npm:^5.0.0":
+"ajv-keywords@npm:^5.0.0, ajv-keywords@npm:^5.1.0":
version: 5.1.0
resolution: "ajv-keywords@npm:5.1.0"
dependencies:
@@ -4966,7 +4982,7 @@ __metadata:
languageName: node
linkType: hard
-"ajv@npm:^8.0.0, ajv@npm:^8.8.0":
+"ajv@npm:^8.0.0, ajv@npm:^8.8.0, ajv@npm:^8.9.0":
version: 8.12.0
resolution: "ajv@npm:8.12.0"
dependencies:
@@ -5674,7 +5690,7 @@ __metadata:
languageName: node
linkType: hard
-"braces@npm:^3.0.1, braces@npm:~3.0.2":
+"braces@npm:^3.0.1, braces@npm:^3.0.2, braces@npm:~3.0.2":
version: 3.0.2
resolution: "braces@npm:3.0.2"
dependencies:
@@ -6686,6 +6702,22 @@ __metadata:
languageName: node
linkType: hard
+"copy-webpack-plugin@npm:^12.0.2":
+ version: 12.0.2
+ resolution: "copy-webpack-plugin@npm:12.0.2"
+ dependencies:
+ fast-glob: ^3.3.2
+ glob-parent: ^6.0.1
+ globby: ^14.0.0
+ normalize-path: ^3.0.0
+ schema-utils: ^4.2.0
+ serialize-javascript: ^6.0.2
+ peerDependencies:
+ webpack: ^5.1.0
+ checksum: 98127735336c6db5924688486d3a1854a41835963d0c0b81695b2e3d58c6675164be7d23dee7090b84a56d3c9923175d3d0863ac1942bcc3317d2efc1962b927
+ languageName: node
+ linkType: hard
+
"core-js-compat@npm:^3.31.0":
version: 3.31.1
resolution: "core-js-compat@npm:3.31.1"
@@ -6753,6 +6785,15 @@ __metadata:
languageName: node
linkType: hard
+"cross-fetch@npm:4.0.0":
+ version: 4.0.0
+ resolution: "cross-fetch@npm:4.0.0"
+ dependencies:
+ node-fetch: ^2.6.12
+ checksum: ecca4f37ffa0e8283e7a8a590926b66713a7ef7892757aa36c2d20ffa27b0ac5c60dcf453119c809abe5923fc0bae3702a4d896bfb406ef1077b0d0018213e24
+ languageName: node
+ linkType: hard
+
"cross-spawn@npm:^5.0.1":
version: 5.1.0
resolution: "cross-spawn@npm:5.1.0"
@@ -8509,6 +8550,15 @@ __metadata:
languageName: node
linkType: hard
+"express-rate-limit@npm:7":
+ version: 7.1.5
+ resolution: "express-rate-limit@npm:7.1.5"
+ peerDependencies:
+ express: 4 || 5 || ^5.0.0-beta.1
+ checksum: bdf6ddf4f8c8659d31de6ec1f088b473b2cb4180eb09ae234a279c88744832276e5c1482d530875110c90e314b51a7720bcfb2b3139c1b9e6bf652ba4b59f192
+ languageName: node
+ linkType: hard
+
"express-robots-txt@npm:^1.0.0":
version: 1.0.0
resolution: "express-robots-txt@npm:1.0.0"
@@ -8518,6 +8568,17 @@ __metadata:
languageName: node
linkType: hard
+"express-slow-down@npm:^2.0.1":
+ version: 2.0.1
+ resolution: "express-slow-down@npm:2.0.1"
+ dependencies:
+ express-rate-limit: 7
+ peerDependencies:
+ express: ">= 4"
+ checksum: bb59970b6321ef45affb5d1ba0331d065f8430ccae7e36fd67d3a8696634fe20a878420cd5659e210255cea0b6b1b502eca02f8d7a195695fa00c36cd258799e
+ languageName: node
+ linkType: hard
+
"express-unless@npm:^2.1.3":
version: 2.1.3
resolution: "express-unless@npm:2.1.3"
@@ -8663,6 +8724,19 @@ __metadata:
languageName: node
linkType: hard
+"fast-glob@npm:^3.3.2":
+ version: 3.3.2
+ resolution: "fast-glob@npm:3.3.2"
+ dependencies:
+ "@nodelib/fs.stat": ^2.0.2
+ "@nodelib/fs.walk": ^1.2.3
+ glob-parent: ^5.1.2
+ merge2: ^1.3.0
+ micromatch: ^4.0.4
+ checksum: 900e4979f4dbc3313840078419245621259f349950411ca2fa445a2f9a1a6d98c3b5e7e0660c5ccd563aa61abe133a21765c6c0dec8e57da1ba71d8000b05ec1
+ languageName: node
+ linkType: hard
+
"fast-json-stable-stringify@npm:^2.0.0":
version: 2.1.0
resolution: "fast-json-stable-stringify@npm:2.1.0"
@@ -9378,7 +9452,7 @@ __metadata:
languageName: node
linkType: hard
-"glob-parent@npm:^5.1.0, glob-parent@npm:~5.1.2":
+"glob-parent@npm:^5.1.0, glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2":
version: 5.1.2
resolution: "glob-parent@npm:5.1.2"
dependencies:
@@ -9387,7 +9461,7 @@ __metadata:
languageName: node
linkType: hard
-"glob-parent@npm:^6.0.2":
+"glob-parent@npm:^6.0.1, glob-parent@npm:^6.0.2":
version: 6.0.2
resolution: "glob-parent@npm:6.0.2"
dependencies:
@@ -9507,6 +9581,20 @@ __metadata:
languageName: node
linkType: hard
+"globby@npm:^14.0.0":
+ version: 14.0.1
+ resolution: "globby@npm:14.0.1"
+ dependencies:
+ "@sindresorhus/merge-streams": ^2.1.0
+ fast-glob: ^3.3.2
+ ignore: ^5.2.4
+ path-type: ^5.0.0
+ slash: ^5.1.0
+ unicorn-magic: ^0.1.0
+ checksum: 33568444289afb1135ad62d52d5e8412900cec620e3b6ece533afa46d004066f14b97052b643833d7cf4ee03e7fac571430130cde44c333df91a45d313105170
+ languageName: node
+ linkType: hard
+
"gopd@npm:^1.0.1":
version: 1.0.1
resolution: "gopd@npm:1.0.1"
@@ -9951,6 +10039,15 @@ __metadata:
languageName: node
linkType: hard
+"html-parse-stringify@npm:^3.0.1":
+ version: 3.0.1
+ resolution: "html-parse-stringify@npm:3.0.1"
+ dependencies:
+ void-elements: 3.1.0
+ checksum: 334fdebd4b5c355dba8e95284cead6f62bf865a2359da2759b039db58c805646350016d2017875718bc3c4b9bf81a0d11be5ee0cf4774a3a5a7b97cde21cfd67
+ languageName: node
+ linkType: hard
+
"html-webpack-plugin@npm:^5.5.3":
version: 5.5.3
resolution: "html-webpack-plugin@npm:5.5.3"
@@ -10171,6 +10268,24 @@ __metadata:
languageName: node
linkType: hard
+"i18next-http-backend@npm:^2.4.3":
+ version: 2.4.3
+ resolution: "i18next-http-backend@npm:2.4.3"
+ dependencies:
+ cross-fetch: 4.0.0
+ checksum: 8abd3966475828d677f5f5351eee93ba6412a2d3e4e663966af0762ea98a605d4b8dce6966650d28acf5411e39fd44cc8aae87ed94b39b627791eeba22a1e73e
+ languageName: node
+ linkType: hard
+
+"i18next@npm:^23.8.2":
+ version: 23.8.2
+ resolution: "i18next@npm:23.8.2"
+ dependencies:
+ "@babel/runtime": ^7.23.2
+ checksum: c20e68c6c216bfcedc16d8d8b1ee545423e26e84ace36b699f936ec8cf1b4df8ee2ae093e7a3e444a9cb5931ca76698ae1a80d31691aa4153bcc804394e0019e
+ languageName: node
+ linkType: hard
+
"iconv-lite@npm:0.4.24":
version: 0.4.24
resolution: "iconv-lite@npm:0.4.24"
@@ -12762,6 +12877,16 @@ __metadata:
languageName: node
linkType: hard
+"micromatch@npm:^4.0.4":
+ version: 4.0.5
+ resolution: "micromatch@npm:4.0.5"
+ dependencies:
+ braces: ^3.0.2
+ picomatch: ^2.3.1
+ checksum: 02a17b671c06e8fefeeb6ef996119c1e597c942e632a21ef589154f23898c9c6a9858526246abb14f8bca6e77734aa9dcf65476fca47cedfb80d9577d52843fc
+ languageName: node
+ linkType: hard
+
"mime-db@npm:1.47.0, mime-db@npm:>= 1.43.0 < 2, mime-db@npm:^1.28.0":
version: 1.47.0
resolution: "mime-db@npm:1.47.0"
@@ -13422,7 +13547,7 @@ __metadata:
languageName: node
linkType: hard
-"node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.8":
+"node-fetch@npm:^2.6.1, node-fetch@npm:^2.6.12, node-fetch@npm:^2.6.8":
version: 2.7.0
resolution: "node-fetch@npm:2.7.0"
dependencies:
@@ -14310,6 +14435,13 @@ __metadata:
languageName: node
linkType: hard
+"path-type@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "path-type@npm:5.0.0"
+ checksum: 15ec24050e8932c2c98d085b72cfa0d6b4eeb4cbde151a0a05726d8afae85784fc5544f733d8dfc68536587d5143d29c0bd793623fad03d7e61cc00067291cd5
+ languageName: node
+ linkType: hard
+
"pend@npm:~1.2.0":
version: 1.2.0
resolution: "pend@npm:1.2.0"
@@ -14338,7 +14470,7 @@ __metadata:
languageName: node
linkType: hard
-"picomatch@npm:^2.0.4":
+"picomatch@npm:^2.0.4, picomatch@npm:^2.3.1":
version: 2.3.1
resolution: "picomatch@npm:2.3.1"
checksum: 050c865ce81119c4822c45d3c84f1ced46f93a0126febae20737bd05ca20589c564d6e9226977df859ed5e03dc73f02584a2b0faad36e896936238238b0446cf
@@ -14917,6 +15049,24 @@ __metadata:
languageName: node
linkType: hard
+"react-i18next@npm:^14.0.5":
+ version: 14.0.5
+ resolution: "react-i18next@npm:14.0.5"
+ dependencies:
+ "@babel/runtime": ^7.23.9
+ html-parse-stringify: ^3.0.1
+ peerDependencies:
+ i18next: ">= 23.2.3"
+ react: ">= 16.8.0"
+ peerDependenciesMeta:
+ react-dom:
+ optional: true
+ react-native:
+ optional: true
+ checksum: 54fe5ffd887d633852ea7e82e98b6ef057facf45dec512469dd0e43ae64d9450d2bafe7c85c87fd650cf6dad1bf81727a89fba23af0508b7a806153d459fc5cc
+ languageName: node
+ linkType: hard
+
"react-immutable-proptypes@npm:^2.2.0":
version: 2.2.0
resolution: "react-immutable-proptypes@npm:2.2.0"
@@ -15702,6 +15852,7 @@ __metadata:
concurrently: ^8.2.0
connected-react-router: ^6.9.3
copy-text-to-clipboard: ^3.2.0
+ copy-webpack-plugin: ^12.0.2
cors: ^2.8.5
cross-env: ^7.0.3
css-loader: 6.8.1
@@ -15726,6 +15877,7 @@ __metadata:
express-favicon: ^2.0.4
express-jwt: ^8.4.1
express-robots-txt: ^1.0.0
+ express-slow-down: ^2.0.1
fetch-cheerio-object: ^1.3.0
file-loader: ^6.2.0
front-matter: ^4.0.2
@@ -15734,6 +15886,8 @@ __metadata:
html-inline-script-webpack-plugin: ^2.0.3
html-loader: ^2.1.2
html-webpack-plugin: ^5.5.3
+ i18next: ^23.8.2
+ i18next-http-backend: ^2.4.3
image-webpack-loader: ^7.0.1
ipfs-deploy: ^12.0.1
jsonwebtoken: ^9.0.1
@@ -15759,6 +15913,7 @@ __metadata:
react: ^17.0.2
react-dom: ^17.0.2
react-helmet: ^6.1.0
+ react-i18next: ^14.0.5
react-immutable-proptypes: ^2.2.0
react-redux: ^7.2.9
react-router: ^5.3.4
@@ -15894,6 +16049,18 @@ __metadata:
languageName: node
linkType: hard
+"schema-utils@npm:^4.2.0":
+ version: 4.2.0
+ resolution: "schema-utils@npm:4.2.0"
+ dependencies:
+ "@types/json-schema": ^7.0.9
+ ajv: ^8.9.0
+ ajv-formats: ^2.1.1
+ ajv-keywords: ^5.1.0
+ checksum: 26a0463d47683258106e6652e9aeb0823bf0b85843039e068b57da1892f7ae6b6b1094d48e9ed5ba5cbe9f7166469d880858b9d91abe8bd249421eb813850cde
+ languageName: node
+ linkType: hard
+
"seamless-immutable@npm:^7.1.3":
version: 7.1.4
resolution: "seamless-immutable@npm:7.1.4"
@@ -16084,6 +16251,15 @@ __metadata:
languageName: node
linkType: hard
+"serialize-javascript@npm:^6.0.2":
+ version: 6.0.2
+ resolution: "serialize-javascript@npm:6.0.2"
+ dependencies:
+ randombytes: ^2.1.0
+ checksum: c4839c6206c1d143c0f80763997a361310305751171dd95e4b57efee69b8f6edd8960a0b7fbfc45042aadff98b206d55428aee0dc276efe54f100899c7fa8ab7
+ languageName: node
+ linkType: hard
+
"serve-index@npm:^1.9.1":
version: 1.9.1
resolution: "serve-index@npm:1.9.1"
@@ -16252,6 +16428,13 @@ __metadata:
languageName: node
linkType: hard
+"slash@npm:^5.1.0":
+ version: 5.1.0
+ resolution: "slash@npm:5.1.0"
+ checksum: 70434b34c50eb21b741d37d455110258c42d2cf18c01e6518aeb7299f3c6e626330c889c0c552b5ca2ef54a8f5a74213ab48895f0640717cacefeef6830a1ba4
+ languageName: node
+ linkType: hard
+
"smart-buffer@npm:^4.2.0":
version: 4.2.0
resolution: "smart-buffer@npm:4.2.0"
@@ -17570,6 +17753,13 @@ __metadata:
languageName: node
linkType: hard
+"unicorn-magic@npm:^0.1.0":
+ version: 0.1.0
+ resolution: "unicorn-magic@npm:0.1.0"
+ checksum: 48c5882ca3378f380318c0b4eb1d73b7e3c5b728859b060276e0a490051d4180966beeb48962d850fd0c6816543bcdfc28629dcd030bb62a286a2ae2acb5acb6
+ languageName: node
+ linkType: hard
+
"uniq@npm:^1.0.1":
version: 1.0.1
resolution: "uniq@npm:1.0.1"
@@ -17849,6 +18039,13 @@ __metadata:
languageName: node
linkType: hard
+"void-elements@npm:3.1.0":
+ version: 3.1.0
+ resolution: "void-elements@npm:3.1.0"
+ checksum: 0390f818107fa8fce55bb0a5c3f661056001c1d5a2a48c28d582d4d847347c2ab5b7f8272314cac58acf62345126b6b09bea623a185935f6b1c3bbce0dfd7f7f
+ languageName: node
+ linkType: hard
+
"watchpack@npm:^2.4.0":
version: 2.4.0
resolution: "watchpack@npm:2.4.0"
From 8676de905b40d5c883e241ee51a1c672d3d7daff Mon Sep 17 00:00:00 2001
From: mistakia <1823355+mistakia@users.noreply.github.com>
Date: Mon, 19 Feb 2024 21:11:58 -0500
Subject: [PATCH 02/26] feat: added `home` to locales json
---
locales/en.json | 1 +
src/views/components/menu/menu.js | 3 ++-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/locales/en.json b/locales/en.json
index d2677cf1..428a1cb1 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -191,6 +191,7 @@
"glossary": "Glossary",
"guides": "Guides",
"history": "History",
+ "home": "Home",
"how_it_works": "How it works",
"integrations": "Integrations",
"investment_thesis": "Investment thesis",
diff --git a/src/views/components/menu/menu.js b/src/views/components/menu/menu.js
index ffef5004..31c6914a 100644
--- a/src/views/components/menu/menu.js
+++ b/src/views/components/menu/menu.js
@@ -163,6 +163,7 @@ function MenuSections() {
export default function Menu({ hide, hideSearch, hide_speed_dial }) {
const [open, setOpen] = useState(false)
+ const { t } = useTranslation()
const handleOpen = () => setOpen(true)
const handleClose = () => setOpen(false)
@@ -204,7 +205,7 @@ export default function Menu({ hide, hideSearch, hide_speed_dial }) {
{!isHome && (
}
- tooltipTitle='Home'
+ tooltipTitle={t('menu.home', 'Home')}
tooltipPlacement={isMobile ? 'left' : 'right'}
onClick={handleHomeClick}
/>
From 9a9407f5177fbaed9b50e334b757a9af96404dd6 Mon Sep 17 00:00:00 2001
From: mistakia <1823355+mistakia@users.noreply.github.com>
Date: Mon, 19 Feb 2024 21:16:44 -0500
Subject: [PATCH 03/26] fix: use async instead of `fs.existsSync`
---
api/server.mjs | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/api/server.mjs b/api/server.mjs
index bbf07af0..6cdc96d3 100644
--- a/api/server.mjs
+++ b/api/server.mjs
@@ -124,9 +124,19 @@ api.get('/api/docs/:locale/*', speedLimiter, async (req, res) => {
}
try {
- if (fs.existsSync(localized_doc_path)) {
+ if (
+ await fs.promises
+ .access(localized_doc_path, fs.constants.F_OK)
+ .then(() => true)
+ .catch(() => false)
+ ) {
return res.sendFile(localized_doc_path)
- } else if (fs.existsSync(default_doc_path)) {
+ } else if (
+ await fs.promises
+ .access(default_doc_path, fs.constants.F_OK)
+ .then(() => true)
+ .catch(() => false)
+ ) {
return res.redirect(`/api/docs/en/${doc_id}`)
} else {
return res.status(404).send('Document not found')
From 56c8714fa288d779054de73b949eb3b26d38e630 Mon Sep 17 00:00:00 2001
From: mistakia <1823355+mistakia@users.noreply.github.com>
Date: Mon, 19 Feb 2024 21:17:08 -0500
Subject: [PATCH 04/26] fix: remove unnecessary react fragments
---
.../representative-telemetry-chart.js | 6 +-----
.../representatives-cluster-charts.js | 12 +++++-------
.../representatives-weight-chart.js | 12 +++++-------
3 files changed, 11 insertions(+), 19 deletions(-)
diff --git a/src/views/components/representative-telemetry-chart/representative-telemetry-chart.js b/src/views/components/representative-telemetry-chart/representative-telemetry-chart.js
index ce73622c..a0d0d280 100644
--- a/src/views/components/representative-telemetry-chart/representative-telemetry-chart.js
+++ b/src/views/components/representative-telemetry-chart/representative-telemetry-chart.js
@@ -43,11 +43,7 @@ export default class RepresentativeTelemetryChart extends React.Component {
]
}
- return (
- <>
-
- >
- )
+ return
}
}
diff --git a/src/views/components/representatives-cluster-charts/representatives-cluster-charts.js b/src/views/components/representatives-cluster-charts/representatives-cluster-charts.js
index c40214f6..5c507046 100644
--- a/src/views/components/representatives-cluster-charts/representatives-cluster-charts.js
+++ b/src/views/components/representatives-cluster-charts/representatives-cluster-charts.js
@@ -212,13 +212,11 @@ export default function RepresentativesClusterCharts({
}
return (
- <>
-
- >
+
)
}
diff --git a/src/views/components/representatives-weight-chart/representatives-weight-chart.js b/src/views/components/representatives-weight-chart/representatives-weight-chart.js
index b1703fed..c40eb0bf 100644
--- a/src/views/components/representatives-weight-chart/representatives-weight-chart.js
+++ b/src/views/components/representatives-weight-chart/representatives-weight-chart.js
@@ -71,13 +71,11 @@ export default function RepresentativesWeightChart({
}
return (
- <>
-
- >
+
)
}
From ad26736ddc67f53e61e5f8ebefd907fec0a04e3b Mon Sep 17 00:00:00 2001
From: mistakia <1823355+mistakia@users.noreply.github.com>
Date: Mon, 19 Feb 2024 22:10:30 -0500
Subject: [PATCH 05/26] feat: cleanup and add missing `en` localization, added
`es` localization file
---
locales/en.json | 16 +-
locales/es.json | 387 ++++++++++++++++++
.../representative-telemetry.js | 6 +-
.../representatives-cluster-charts.js | 6 +-
4 files changed, 401 insertions(+), 14 deletions(-)
create mode 100644 locales/es.json
diff --git a/locales/en.json b/locales/en.json
index 428a1cb1..7852ae07 100644
--- a/locales/en.json
+++ b/locales/en.json
@@ -69,7 +69,9 @@
"address": "Address",
"balance": "Balance",
"bandwidth_limit": "Bandwidth Limit",
+ "bandwidth_limit_short": "BW Limit",
"blocks": "Blocks",
+ "blocks_behind": "Blocks Behind",
"blocks_diff_short": "Blocks Diff",
"by_online_weight": "By Online Weight",
"clear_filters": "Clear Filters",
@@ -77,6 +79,7 @@
"collapse": "Collapse",
"conf_short": "Conf.",
"conf_diff_short": "Conf. Diff",
+ "confirmations_behind": "Confirmations Behind",
"country": "Country",
"delegator_one": "Delegator",
"delegator_other": "Delegators",
@@ -93,7 +96,9 @@
"show_more": "Show {{count}} more",
"total": "Total",
"unchecked": "Unchecked",
+ "unchecked_count": "Unchecked Count",
"unlimited": "Unlimited",
+ "uptime": "Uptime",
"version": "Version",
"weight": "Weight"
},
@@ -194,6 +199,7 @@
"home": "Home",
"how_it_works": "How it works",
"integrations": "Integrations",
+ "introduction": "Introduction",
"investment_thesis": "Investment thesis",
"learn": "Learn",
"ledger": "Ledger",
@@ -219,6 +225,7 @@
"confirmations_text": "Total number of transactions confirmed by the network over the last 24 hours",
"energy_text": "Estimated live network CPU energy usage of Principle Representatives based on collected CPU model info. The estimate is based on CPU TDP, which is the average power, in watts, the processor dissipates when operating at base frequency with all cores active under manufacture-defined, high-complexity workload",
"energy_usage": "Energy Usage (TDP) (24h)",
+ "fee_text": "The Nano network operates without fees",
"nano_ticker": "NanoTicker",
"online_stake": "Online Stake",
"principal_reps": "Principal Reps",
@@ -228,6 +235,7 @@
"settlement": "Settlement (24h)",
"settlement_text": "Total amount of value settled by the network over the last 24 hours (only send blocks)",
"speed_text": "Median time in milliseconds for a block to get confirmed (across all buckets)",
+ "stake_text": "Percentage of delegated Nano weight actively participating in voting",
"stats_title": "Network Stats",
"total_reps": "Total Reps (24h)",
"tx_backlog": "Tx Backlog",
@@ -285,9 +293,6 @@
"provider": "Provider"
},
"representative_telemetry": {
- "blocks_diff": "Blocks Diff",
- "conf": "Conf.",
- "conf_diff": "Conf. Diff",
"telemetry": "Telemetry",
"telemetry_timestamp": "Telemetry Timestamp"
},
@@ -314,11 +319,6 @@
"representatives_bandwidth_by_weight": {
"tooltip": "Displays the amount of voting weight based on the bandwidth limit set locally by each node"
},
- "representatives_cluster": {
- "blocks_diff": "Blocks Behind",
- "conf_diff": "Confirmations Behind",
- "unchecked": "Unchecked Count"
- },
"representatives_country_by_weight": {
"title": "Country"
},
diff --git a/locales/es.json b/locales/es.json
new file mode 100644
index 00000000..d6cbf2e2
--- /dev/null
+++ b/locales/es.json
@@ -0,0 +1,387 @@
+{
+ "account_page": {
+ "address": "Dirección de la Cuenta",
+ "change_summary": "Resumen de Cambios",
+ "copy_notification": "Dirección de cuenta copiada",
+ "seo_description": "Información para representante nano",
+ "seo_title": "Cuenta Nano",
+ "telemetry_charts": "Gráficos de Telemetría",
+ "unopened_description": "Aunque la dirección de la cuenta es válida, no se han observado bloques. Si se ha enviado NANO a esta cuenta, aún necesita publicar un bloque correspondiente para recibir los fondos y establecer un saldo inicial. El saldo de una cuenta solo puede ser actualizado por el titular de la cuenta ya que son los únicos que pueden publicar bloques en su cadena.",
+ "unopened_note": "Si ya se ha publicado un bloque de apertura, puede tardar unos momentos en propagarse por la red y ser observado por los nodos de nano.community.",
+ "unopened_title": "Esta cuenta no ha sido abierta aún"
+ },
+ "account_blocks_summary": {
+ "first_timestamp": "Primera Marca de Tiempo",
+ "last_timestamp": "Última Marca de Tiempo",
+ "max_amount": "Cantidad Máxima",
+ "min_amount": "Cantidad Mínima",
+ "no_records": "Sin Registros",
+ "receiving_account": "Cuenta Receptora",
+ "representative_account": "Cuenta Representativa",
+ "sending_account": "Cuenta Emisora",
+ "showing_top_10": "Mostrando las 10 mejores cuentas por total descendente",
+ "transactions": "TXs"
+ },
+ "account_meta": {
+ "account_info": "Información de la Cuenta",
+ "funding_account": "Cuenta de Financiación",
+ "funding_timestamp": "Marca de Tiempo de Financiación",
+ "height": "Altura",
+ "last_modified": "Última Modificación",
+ "open_timestamp": "Marca de Tiempo de Apertura",
+ "opening_balance": "Saldo de Apertura",
+ "receivable_balance": "Saldo por Cobrar"
+ },
+ "block_page": {
+ "amount": "Cantidad",
+ "copy_notification": "Hash de bloque copiado",
+ "delegated_representative": "Representante Delegado",
+ "description": "Descripción",
+ "epoch_v1": "Época v1 — Cadenas de cuentas actualizadas de bloques heredados (abrir, recibir, enviar, cambiar) a bloques de estado.",
+ "epoch_v2": "Época v2 - Cadenas de cuentas actualizadas para usar una dificultad de Prueba de Trabajo más alta.",
+ "receiving_account": "Cuenta Receptora",
+ "section_label": "Hash de Bloque",
+ "sending_account": "Cuenta Emisora",
+ "seo_description": "Información relacionada con un Bloque Nano",
+ "seo_title": "Bloque Nano",
+ "voting_weight": "Peso de Votación"
+ },
+ "block_info": {
+ "block_account": "Cuenta de Bloque",
+ "operation": "Operación",
+ "status": "Estado",
+ "timestamp": "Marca de Tiempo"
+ },
+ "block_status": {
+ "confirmed": "Confirmado",
+ "unconfirmed": "No Confirmado"
+ },
+ "block_type": {
+ "change": "Cambiar",
+ "epoch": "Época",
+ "open": "Abrir",
+ "receive": "Recibir",
+ "send": "Enviar"
+ },
+ "common": {
+ "account_one": "Cuenta",
+ "account_other": "Cuentas",
+ "address": "Dirección",
+ "balance": "Saldo",
+ "bandwidth_limit": "Límite de Ancho de Banda",
+ "bandwidth_limit_short": "Límite de BW",
+ "blocks": "Bloques",
+ "blocks_behind": "Bloques Atrasados",
+ "blocks_diff_short": "Dif de Bloques",
+ "by_online_weight": "Por Peso en Línea",
+ "clear_filters": "Limpiar Filtros",
+ "click_to_copy": "Clic para copiar",
+ "collapse": "Colapsar",
+ "conf_diff_short": "Dif de Conf",
+ "conf_short": "Conf.",
+ "confirmations_behind": "Confirmaciones Atrasadas",
+ "country": "País",
+ "delegator_one": "Delegador",
+ "delegator_other": "Delegadores",
+ "max": "Máx",
+ "min": "Mín",
+ "offline": "Fuera de Línea",
+ "online": "En Línea",
+ "peers": "Pares",
+ "percent_of_total": "% del Total",
+ "port": "Puerto",
+ "quorum_delta": "Delta de Cuórum",
+ "representative_one": "Representante",
+ "representative_other": "Representantes",
+ "show_more": "Mostrar {{count}} más",
+ "total": "Total",
+ "unchecked": "Sin Verificar",
+ "unchecked_count": "Cuenta Sin Verificar",
+ "unlimited": "Ilimitado",
+ "uptime": "Tiempo Activo",
+ "version": "Versión",
+ "weight": "Peso"
+ },
+ "delegators": {
+ "showing_top_delegators": "Mostrando los 100 principales delegadores con un saldo mínimo de 1 Nano."
+ },
+ "doc": {
+ "contributors": "Colaborador",
+ "document_not_found": "Documento (o Cuenta) no encontrado",
+ "edit_page": "Editar Página",
+ "help_out": "Ayudar",
+ "not_found_404": "404",
+ "section_link_copied": "Enlace de sección copiado",
+ "updated_by": "actualizado por"
+ },
+ "github_events": {
+ "action": {
+ "added_member": "miembro agregado",
+ "commented_on_commit": "comentó en commit",
+ "commented_on_issue": "comentó en problema",
+ "commented_on_pr_review": "comentó en revisión de pr",
+ "created": "creado {{action}}",
+ "deleted": "eliminado {{action}}",
+ "forked": "bifurcado",
+ "issue_action": "{{action}} problema",
+ "made_public": "hecho público",
+ "pr_action": "{{action}} pr",
+ "pr_review": "revisión de pr {{title}}",
+ "published_release": "lanzamiento publicado",
+ "pushed_commit": "commit empujado a {{ref}}",
+ "sponsorship_started": "patrocinio iniciado",
+ "watching_repo": "observando repositorio"
+ },
+ "events_title": "Eventos de Desarrollo"
+ },
+ "ledger": {
+ "addresses": {
+ "active_detail": "Activo muestra el número de direcciones únicas utilizadas. Nuevo muestra el número de direcciones creadas. Reutilizado muestra el número de direcciones utilizadas que fueron creadas en un día anterior.",
+ "active_stats": "Estadísticas de Direcciones Activas",
+ "new_stats": "Estadísticas de Nuevas Direcciones",
+ "total_number": "El número total de direcciones activas, nuevas y reutilizadas utilizadas por día."
+ },
+ "amounts": {
+ "total_number": "El número de bloques de tipo envío confirmados por día donde la cantidad en el bloque está en un rango dado (en Nano)"
+ },
+ "blocks": {
+ "change": "Estadísticas de Bloques de Cambio",
+ "description": "El número de bloques confirmados por día.",
+ "open": "Estadísticas de Bloques de Apertura",
+ "receive": "Estadísticas de Bloques de Recepción",
+ "send": "Estadísticas de Bloques de Envío",
+ "total": "Estadísticas de Bloques Totales"
+ },
+ "description": "Descripción",
+ "usd_transferred": {
+ "desc_1": "El monto total de valor transferido (en USD) por día.",
+ "desc_2": "Basado en el precio de cierre diario de Nano/USD y el monto total de Nano transferido ese día.",
+ "usd_transferred": "USD Transferidos",
+ "usd_transferred_stats": "Estadísticas de USD Transferidos"
+ },
+ "volume": {
+ "change_stats": "Estadísticas de Cambio",
+ "description": "El monto total enviado (en Nano) y el monto total de peso de votación cambiado por día.",
+ "send_stats": "Estadísticas de Envío"
+ }
+ },
+ "ledger_page": {
+ "addresses_tab": "Direcciones",
+ "amounts_tab": "Cantidades",
+ "blocks_tab": "Bloques",
+ "seo_description": "Métricas y análisis en cadena del libro mayor de Nano",
+ "seo_title": "Análisis del Libro Mayor de Nano",
+ "value_transferred_tab": "Valor Transferido",
+ "volume_tab": "Volumen"
+ },
+ "menu": {
+ "account_setup": "Configuración de la Cuenta",
+ "acquiring": "Adquiriendo",
+ "advantages": "Ventajas",
+ "attack_vectors": "Vectores de Ataque",
+ "basics": "Básicos",
+ "best_practices": "Mejores Prácticas",
+ "choosing_a_rep": "Elegir un Representante",
+ "challenges": "Desafíos",
+ "communities": "Comunidades",
+ "contribution_guide": "Guía de Contribución",
+ "design": "Diseño",
+ "developer_discussions": "Discusiones de Desarrolladores",
+ "developers": "Desarrolladores",
+ "documentation": "Documentación",
+ "faqs": "Preguntas Frecuentes",
+ "get_involved": "Involúcrate",
+ "get_support": "Obtener Soporte",
+ "getting_started": "Empezando",
+ "glossary": "Glosario",
+ "guides": "Guías",
+ "history": "Historia",
+ "home": "Inicio",
+ "how_it_works": "Cómo Funciona",
+ "integrations": "Integraciones",
+ "introduction": "Introducción",
+ "investment_thesis": "Tesis de Inversión",
+ "learn": "Aprender",
+ "ledger": "Libro Mayor",
+ "misconceptions": "Malentendidos",
+ "overview": "Visión General",
+ "planning": "Planificación 👾",
+ "privacy": "Privacidad",
+ "protocol": "Protocolo",
+ "running_a_node": "Ejecutando un Nodo",
+ "security": "Seguridad",
+ "stats": "Estadísticas",
+ "storing": "Almacenando",
+ "telemetry": "Telemetría",
+ "topics": "Temas",
+ "using": "Usando",
+ "why_it_matters": "Por Qué es Importante"
+ },
+ "network": {
+ "backlog_text": "Número mediano de transacciones esperando ser confirmadas $(network.pr_text)",
+ "censor_text": "El número mínimo de representantes necesarios para censurar transacciones o paralizar la red",
+ "confirm_text": "El número mínimo de representantes necesarios para confirmar transacciones",
+ "confirmations": "Confirmaciones (24h)",
+ "confirmations_text": "Número total de transacciones confirmadas por la red en las últimas 24 horas",
+ "energy_text": "Estimación del uso de energía de CPU de la red en vivo de los Representantes Principales basada en la información recopilada del modelo de CPU. La estimación se basa en el TDP de la CPU, que es la potencia promedio, en vatios, que disipa el procesador cuando opera a la frecuencia base con todos los núcleos activos bajo una carga de trabajo de alta complejidad definida por el fabricante",
+ "energy_usage": "Uso de Energía (TDP) (24h)",
+ "fee_text": "La red Nano opera sin tarifas",
+ "nano_ticker": "NanoTicker",
+ "online_stake": "Participación en Línea",
+ "principal_reps": "Representantes Principales",
+ "pr_text": "según se observa en los representantes principales de la red: nodos de votación con más del 0.1% del peso de voto en línea delegado a ellos",
+ "reps_to_censor": "Representantes para Censurar o Paralizar",
+ "reps_to_confirm": "Representantes para Confirmar",
+ "settlement": "Liquidación (24h)",
+ "settlement_text": "Cantidad total de valor liquidado por la red en las últimas 24 horas",
+ "speed_text": "Tiempo en milisegundos para que una transacción de prueba sea confirmada",
+ "stake_text": "Porcentaje del peso Nano delegado que participa activamente en la votación",
+ "stats_title": "Estadísticas de la Red",
+ "total_reps": "Total de Representantes (24h)",
+ "tx_backlog": "Cola de Tx",
+ "tx_fees": "Tarifas de Tx (24h)",
+ "tx_speed": "Velocidad de Tx",
+ "tx_throughput": "Rendimiento de Tx",
+ "throughput_text": "Número mediano de transacciones confirmadas por segundo en el último minuto $(network.pr_text)"
+ },
+ "posts": {
+ "nano_foundation": "Fundación Nano",
+ "top": "Top",
+ "trending": "Tendencias"
+ },
+ "representative_alerts": {
+ "table_header": {
+ "behind": "Atrasado",
+ "issue": "Problema",
+ "last_online": "Última vez en línea",
+ "percent_online_weight": "% Peso en Línea",
+ "representative": "Representante"
+ },
+ "tooltip": {
+ "behind": "El representante se ha quedado atrás o está arrancando. El límite es un recuento cementado más allá del percentil 95. (vía telemetría)",
+ "low_uptime": "El representante ha estado fuera de línea más del 25% en los últimos 28 días.",
+ "offline": "El representante ha dejado de votar y parece estar fuera de línea.",
+ "overweight": "El representante tiene más de 3M de peso de voto Nano. Los delegadores deberían considerar distribuir el peso para mejorar la resiliencia de la red y su valor."
+ },
+ "type": {
+ "behind": "Atrasado",
+ "low_uptime": "Bajo Tiempo Activo",
+ "offline": "Fuera de Línea",
+ "overweight": "Sobrepeso"
+ }
+ },
+ "representatives_cemented_by_weight": {
+ "title": "Diferencial de Confirmación",
+ "tooltip": "Muestra la cantidad de peso de voto que está dentro de X número de confirmaciones del nodo líder. Útil para saber qué tan bien sincronizados y alineados están los nodos a través de la red"
+ },
+ "representatives_checked_by_weight": {
+ "title": "Diferencial de Bloques",
+ "tooltip": "Muestra la cantidad de peso de voto que está dentro de X número de bloques del nodo líder. Útil para tener una idea de qué tan bien se propaga la sincronización de bloques dentro de la red"
+ },
+ "representative_delegators": {
+ "showing_top_delegators": "Mostrando los 100 principales delegadores con un saldo mínimo de 1 Nano."
+ },
+ "representative_info": {
+ "first_seen": "Primera Vez Visto",
+ "last_seen": "Última Vez Visto",
+ "weight_represented": "Peso Representado"
+ },
+ "representative_network": {
+ "city": "Ciudad",
+ "isp": "ISP",
+ "network": "Red",
+ "provider": "Proveedor"
+ },
+ "representative_telemetry": {
+ "telemetry": "Telemetría",
+ "telemetry_timestamp": "Marca de Tiempo de Telemetría"
+ },
+ "representative_uptime": {
+ "2m_uptime": "Tiempo Activo 2M",
+ "2w_uptime": "Tiempo Activo 2S",
+ "3m_uptime": "Tiempo Activo 3M",
+ "current_status": "Estado Actual",
+ "down": "Caído",
+ "down_for": "Caído Durante",
+ "operational": "Operativo",
+ "up_for": "Activo Durante",
+ "warning": "Advertencia"
+ },
+ "representatives": {
+ "alias": "Alias",
+ "cpu_cores": "Núcleos de CPU",
+ "cpu_model": "Modelo de CPU",
+ "tdp": "TDP (wH)",
+ "protocol_version": "Versión del Protocolo",
+ "last_seen": "Última Vez Visto",
+ "host_asn": "ASN del Host"
+ },
+ "representatives_bandwidth_by_weight": {
+ "tooltip": "Muestra la cantidad de peso de voto basado en el límite de ancho de banda establecido localmente por cada nodo"
+ },
+ "representatives_country_by_weight": {
+ "title": "País"
+ },
+ "representatives_offline": {
+ "account": "Cuenta Fuera de Línea",
+ "last_online": "Última Vez en Línea"
+ },
+ "representatives_page": {
+ "seo_description": "Explora y analiza los representantes de la red Nano",
+ "seo_title": "Explorador de Representantes Nano",
+ "telemetry_tab": "Telemetría",
+ "weight_distribution_tab": "Distribución del Peso",
+ "weight_history_tab": "Historial del Peso",
+ "offline_reps_tab": "Representantes Fuera de Línea"
+ },
+ "representatives_provider_by_weight": {
+ "title": "Proveedor de Hosting"
+ },
+ "representatives_quorum_charts": {
+ "peers_weight": "Peso de los Pares",
+ "quorum_delta": "Delta del Cuórum",
+ "title": "Gráficos del Cuórum",
+ "trended_weight": "Peso Tendencial"
+ },
+ "representatives_search": {
+ "placeholder": "Filtrar por cuenta, alias, ip"
+ },
+ "representatives_weight": {
+ "trended": "Tendencial"
+ },
+ "representatives_weight_chart": {
+ "title": "Distribución del Peso por Representante"
+ },
+ "representatives_version_by_weight": {
+ "title": "Versiones"
+ },
+ "roadmap": {
+ "header": {
+ "subtitle": "Objetivos de la comunidad",
+ "title": "Planificación"
+ },
+ "seo": {
+ "description": "Hoja de ruta de desarrollo y comunidad de Nano",
+ "tags": [
+ "hoja de ruta",
+ "nano",
+ "futuro",
+ "lanzamiento",
+ "diseño",
+ "tareas",
+ "discusiones",
+ "comunidad",
+ "embajadores",
+ "gestores"
+ ],
+ "title": "Hoja de Ruta"
+ }
+ },
+ "search_bar": {
+ "placeholder": "Buscar por Dirección / Hash de Bloque"
+ },
+ "uptime": {
+ "now": "Ahora",
+ "days_ago": "días atrás"
+ }
+}
diff --git a/src/views/components/representative-telemetry/representative-telemetry.js b/src/views/components/representative-telemetry/representative-telemetry.js
index cc1347e6..fe2594dd 100644
--- a/src/views/components/representative-telemetry/representative-telemetry.js
+++ b/src/views/components/representative-telemetry/representative-telemetry.js
@@ -46,15 +46,15 @@ export default function RepresentativeTelemetry({ account }) {
value: block_count ? BigNumber(block_count).toFormat() : '-'
},
{
- label: t('representative_telemetry.blocks_diff', 'Blocks Diff'),
+ label: t('common.blocks_behind', 'Blocks Behind'),
value: block_behind ? BigNumber(block_behind).toFormat() : '-'
},
{
- label: t('representative_telemetry.conf', 'Conf.'),
+ label: t('common.conf_short', 'Conf.'),
value: cemented_count ? BigNumber(cemented_count).toFormat() : '-'
},
{
- label: t('representative_telemetry.conf_diff', 'Conf. Diff'),
+ label: t('common.conf_diff_short', 'Conf. Diff'),
value: cemented_behind ? BigNumber(cemented_behind).toFormat() : '-'
},
{
diff --git a/src/views/components/representatives-cluster-charts/representatives-cluster-charts.js b/src/views/components/representatives-cluster-charts/representatives-cluster-charts.js
index 5c507046..fed1da63 100644
--- a/src/views/components/representatives-cluster-charts/representatives-cluster-charts.js
+++ b/src/views/components/representatives-cluster-charts/representatives-cluster-charts.js
@@ -90,17 +90,17 @@ export default function RepresentativesClusterCharts({
},
title: [
{
- text: t('representatives_cluster.conf_diff', 'Confirmations Behind'),
+ text: t('common.confirmations_behind', 'Confirmations Behind'),
top: 20,
...title_common
},
{
- text: t('representatives_cluster.blocks_diff', 'Blocks Behind'),
+ text: t('common.blocks_behind', 'Blocks Behind'),
top: 140,
...title_common
},
{
- text: t('representatives_cluster.unchecked', 'Unchecked Count'),
+ text: t('common.unchecked_count', 'Unchecked Count'),
top: 260,
...title_common
},
From 63f1e8c81228178db1e20142857ecd0317e70a3d Mon Sep 17 00:00:00 2001
From: mistakia <1823355+mistakia@users.noreply.github.com>
Date: Mon, 19 Feb 2024 22:56:55 -0500
Subject: [PATCH 06/26] feat: add `fr` locale
---
locales/fr.json | 387 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 387 insertions(+)
create mode 100644 locales/fr.json
diff --git a/locales/fr.json b/locales/fr.json
new file mode 100644
index 00000000..a7606e82
--- /dev/null
+++ b/locales/fr.json
@@ -0,0 +1,387 @@
+{
+ "account_page": {
+ "address": "Adresse du Compte",
+ "change_summary": "Résumé des Changements",
+ "copy_notification": "Adresse du compte copiée",
+ "seo_description": "Informations pour le représentant nano",
+ "seo_title": "Compte Nano",
+ "telemetry_charts": "Graphiques de Télémétrie",
+ "unopened_description": "Bien que l'adresse du compte soit valide, aucun bloc n'a été observé. Si du NANO a été envoyé à ce compte, il doit encore publier un bloc correspondant pour recevoir les fonds et établir un solde d'ouverture. Le solde d'un compte ne peut être mis à jour que par le détenteur du compte car il est le seul à pouvoir publier des blocs sur sa chaîne.",
+ "unopened_note": "Si un bloc d'ouverture a déjà été publié, cela peut prendre quelques instants pour se propager à travers le réseau et être observé par les nœuds de nano.community.",
+ "unopened_title": "Ce compte n'a pas encore été ouvert"
+ },
+ "account_blocks_summary": {
+ "first_timestamp": "Premier Horodatage",
+ "last_timestamp": "Dernier Horodatage",
+ "max_amount": "Montant Max",
+ "min_amount": "Montant Min",
+ "no_records": "Aucun Enregistrement",
+ "receiving_account": "Compte Récepteur",
+ "representative_account": "Compte Représentatif",
+ "sending_account": "Compte Émetteur",
+ "showing_top_10": "Affichage des 10 meilleurs comptes par total décroissant",
+ "transactions": "Transactions"
+ },
+ "account_meta": {
+ "account_info": "Infos du Compte",
+ "funding_account": "Compte de Financement",
+ "funding_timestamp": "Horodatage du Financement",
+ "height": "Hauteur",
+ "last_modified": "Dernière Modification",
+ "open_timestamp": "Horodatage d'Ouverture",
+ "opening_balance": "Solde d'Ouverture",
+ "receivable_balance": "Solde Recevable"
+ },
+ "block_page": {
+ "amount": "Montant",
+ "copy_notification": "Hash du bloc copié",
+ "delegated_representative": "Représentant Délégué",
+ "description": "Description",
+ "epoch_v1": "Époque v1 — Mise à niveau des chaînes de comptes des blocs hérités (ouvrir, recevoir, envoyer, changer) vers des blocs d'état.",
+ "epoch_v2": "Époque v2 - Mise à niveau des chaînes de comptes pour utiliser une difficulté de Preuve de Travail plus élevée.",
+ "receiving_account": "Compte Récepteur",
+ "section_label": "Hash du Bloc",
+ "sending_account": "Compte Émetteur",
+ "seo_description": "Informations liées à un Bloc Nano",
+ "seo_title": "Bloc Nano",
+ "voting_weight": "Poids de Vote"
+ },
+ "block_info": {
+ "block_account": "Compte du Bloc",
+ "operation": "Opération",
+ "status": "Statut",
+ "timestamp": "Horodatage"
+ },
+ "block_status": {
+ "confirmed": "Confirmé",
+ "unconfirmed": "Non Confirmé"
+ },
+ "block_type": {
+ "change": "Changement",
+ "epoch": "Époque",
+ "open": "Ouvrir",
+ "receive": "Recevoir",
+ "send": "Envoyer"
+ },
+ "common": {
+ "account_one": "Compte",
+ "account_other": "Comptes",
+ "address": "Adresse",
+ "balance": "Solde",
+ "bandwidth_limit": "Limite de Bande Passante",
+ "bandwidth_limit_short": "Limite BP",
+ "blocks": "Blocs",
+ "blocks_behind": "Blocs en Retard",
+ "blocks_diff_short": "Diff Blocs",
+ "by_online_weight": "Par Poids en Ligne",
+ "clear_filters": "Effacer les Filtres",
+ "click_to_copy": "Cliquer pour copier",
+ "collapse": "Réduire",
+ "conf_short": "Conf.",
+ "conf_diff_short": "Diff Conf",
+ "confirmations_behind": "Confirmations en Retard",
+ "country": "Pays",
+ "delegator_one": "Délégué",
+ "delegator_other": "Délégués",
+ "max": "Max",
+ "min": "Min",
+ "offline": "Hors ligne",
+ "online": "En ligne",
+ "peers": "Pairs",
+ "percent_of_total": "% du Total",
+ "port": "Port",
+ "quorum_delta": "Delta du Quorum",
+ "representative_one": "Représentant",
+ "representative_other": "Représentants",
+ "show_more": "Afficher {{count}} de plus",
+ "total": "Total",
+ "unchecked": "Non vérifié",
+ "unchecked_count": "Compte Non Vérifié",
+ "unlimited": "Illimité",
+ "uptime": "Temps de Fonctionnement",
+ "version": "Version",
+ "weight": "Poids"
+ },
+ "delegators": {
+ "showing_top_delegators": "Affichage des 100 principaux délégateurs avec un solde minimum de 1 Nano."
+ },
+ "doc": {
+ "contributors": "Contributeur",
+ "document_not_found": "Document (ou Compte) non trouvé",
+ "edit_page": "Modifier la Page",
+ "help_out": "Aider",
+ "not_found_404": "404",
+ "section_link_copied": "Lien de section copié",
+ "updated_by": "mis à jour par"
+ },
+ "github_events": {
+ "action": {
+ "added_member": "membre ajouté",
+ "commented_on_commit": "a commenté le commit",
+ "commented_on_issue": "a commenté le problème",
+ "commented_on_pr_review": "a commenté la révision de pr",
+ "created": "créé {{action}}",
+ "deleted": "supprimé {{action}}",
+ "forked": "forké",
+ "issue_action": "{{action}} problème",
+ "made_public": "rendu public",
+ "pr_action": "{{action}} pr",
+ "pr_review": "révision de pr {{title}}",
+ "published_release": "publication publiée",
+ "pushed_commit": "commit poussé à {{ref}}",
+ "sponsorship_started": "parrainage commencé",
+ "watching_repo": "suivi du dépôt"
+ },
+ "events_title": "Événements de Développement"
+ },
+ "ledger": {
+ "addresses": {
+ "active_detail": "Actif montre le nombre d'adresses uniques utilisées. Nouveau montre le nombre d'adresses créées. Réutilisé montre le nombre d'adresses utilisées qui ont été créées un jour précédent.",
+ "active_stats": "Statistiques d'Adresses Actives",
+ "new_stats": "Statistiques de Nouvelles Adresses",
+ "total_number": "Le nombre total d'adresses actives, nouvelles et réutilisées utilisées par jour."
+ },
+ "amounts": {
+ "total_number": "Le nombre de blocs de type envoi confirmés par jour où le montant dans le bloc est dans une plage donnée (en Nano)"
+ },
+ "blocks": {
+ "change": "Statistiques de Blocs de Changement",
+ "description": "Le nombre de blocs confirmés par jour.",
+ "open": "Statistiques de Blocs d'Ouverture",
+ "receive": "Statistiques de Blocs de Réception",
+ "send": "Statistiques de Blocs d'Envoi",
+ "total": "Statistiques Totales de Blocs"
+ },
+ "description": "Description",
+ "usd_transferred": {
+ "desc_1": "Le montant total de la valeur transférée (en USD) par jour.",
+ "desc_2": "Basé sur le prix de clôture quotidien de Nano/USD et le montant total de Nano transféré ce jour-là.",
+ "usd_transferred": "USD Transférés",
+ "usd_transferred_stats": "Statistiques des USD Transférés"
+ },
+ "volume": {
+ "change_stats": "Statistiques de Changement",
+ "description": "Le montant total envoyé (en Nano) et le montant total du poids de vote changé par jour.",
+ "send_stats": "Statistiques d'Envoi"
+ }
+ },
+ "ledger_page": {
+ "addresses_tab": "Adresses",
+ "amounts_tab": "Montants",
+ "blocks_tab": "Blocs",
+ "seo_description": "Métriques et analyses en chaîne du grand livre Nano",
+ "seo_title": "Analyse du Grand Livre Nano",
+ "value_transferred_tab": "Valeur Transférée",
+ "volume_tab": "Volume"
+ },
+ "menu": {
+ "account_setup": "Configuration du Compte",
+ "acquiring": "Acquisition",
+ "advantages": "Avantages",
+ "attack_vectors": "Vecteurs d'Attaque",
+ "basics": "Bases",
+ "best_practices": "Meilleures Pratiques",
+ "choosing_a_rep": "Choisir un Représentant",
+ "challenges": "Défis",
+ "communities": "Communautés",
+ "contribution_guide": "Guide de Contribution",
+ "design": "Conception",
+ "developer_discussions": "Discussions des Développeurs",
+ "developers": "Développeurs",
+ "documentation": "Documentation",
+ "faqs": "FAQs",
+ "get_involved": "S'impliquer",
+ "get_support": "Obtenir du Support",
+ "getting_started": "Commencer",
+ "glossary": "Glossaire",
+ "guides": "Guides",
+ "history": "Histoire",
+ "home": "Accueil",
+ "how_it_works": "Comment ça Marche",
+ "integrations": "Intégrations",
+ "introduction": "Introduction",
+ "investment_thesis": "Thèse d'Investissement",
+ "learn": "Apprendre",
+ "ledger": "Grand Livre",
+ "misconceptions": "Idées Fausses",
+ "overview": "Aperçu",
+ "planning": "Planification",
+ "privacy": "Confidentialité",
+ "protocol": "Protocole",
+ "running_a_node": "Exécuter un Nœud",
+ "security": "Sécurité",
+ "stats": "Statistiques",
+ "storing": "Stockage",
+ "telemetry": "Télémétrie",
+ "topics": "Sujets",
+ "using": "Utilisation",
+ "why_it_matters": "Pourquoi C'est Important"
+ },
+ "network": {
+ "backlog_text": "Nombre médian de transactions en attente de confirmation $(network.pr_text)",
+ "censor_text": "Le nombre minimum de représentants nécessaires pour censurer les transactions ou paralyser le réseau",
+ "confirm_text": "Le nombre minimum de représentants nécessaires pour confirmer les transactions",
+ "confirmations": "Confirmations (24h)",
+ "confirmations_text": "Nombre total de transactions confirmées par le réseau au cours des dernières 24 heures",
+ "energy_text": "Estimation de la consommation d'énergie CPU du réseau en direct des représentants principaux basée sur les informations collectées sur le modèle de CPU. L'estimation est basée sur le TDP du CPU, qui est la puissance moyenne, en watts, que le processeur dissipe lorsqu'il fonctionne à la fréquence de base avec tous les cœurs actifs sous une charge de travail complexe définie par le fabricant",
+ "energy_usage": "Utilisation d'énergie (TDP) (24h)",
+ "fee_text": "Le réseau Nano fonctionne sans frais",
+ "nano_ticker": "NanoTicker",
+ "online_stake": "Enjeu en ligne",
+ "principal_reps": "Représentants principaux",
+ "pr_text": "tel qu'observé à travers les représentants principaux du réseau : nœuds de vote avec plus de 0,1 % du poids de vote en ligne qui leur est délégué",
+ "reps_to_censor": "Représentants pour censurer ou paralyser",
+ "reps_to_confirm": "Représentants pour confirmer",
+ "settlement": "Règlement (24h)",
+ "settlement_text": "Montant total de la valeur réglée par le réseau au cours des dernières 24 heures",
+ "speed_text": "Temps en millisecondes pour qu'une transaction de test soit confirmée",
+ "stake_text": "Pourcentage du poids Nano délégué participant activement au vote",
+ "stats_title": "Statistiques du réseau",
+ "total_reps": "Total des représentants (24h)",
+ "tx_backlog": "Arriéré de Tx",
+ "tx_fees": "Frais de Tx (24h)",
+ "tx_speed": "Vitesse de Tx",
+ "tx_throughput": "Débit de Tx",
+ "throughput_text": "Nombre médian de transactions confirmées par seconde au cours de la dernière minute $(network.pr_text)"
+ },
+ "posts": {
+ "nano_foundation": "Fondation Nano",
+ "top": "Top",
+ "trending": "Tendance"
+ },
+ "representative_alerts": {
+ "table_header": {
+ "behind": "Retard",
+ "issue": "Problème",
+ "last_online": "Dernière fois en ligne",
+ "percent_online_weight": "% Poids en ligne",
+ "representative": "Représentant"
+ },
+ "tooltip": {
+ "behind": "Le représentant est en retard ou en phase de démarrage. Le seuil est un compte cimenté au-delà du 95e percentile. (via télémétrie)",
+ "low_uptime": "Le représentant a été hors ligne plus de 25 % au cours des 28 derniers jours.",
+ "offline": "Le représentant a cessé de voter et semble être hors ligne.",
+ "overweight": "Le représentant a plus de 3M de poids de vote Nano. Les délégateurs devraient envisager de distribuer le poids pour améliorer la résilience du réseau et sa valeur."
+ },
+ "type": {
+ "behind": "Retard",
+ "low_uptime": "Faible disponibilité",
+ "offline": "Hors ligne",
+ "overweight": "Surpoids"
+ }
+ },
+ "representatives_cemented_by_weight": {
+ "title": "Différentiel de confirmation",
+ "tooltip": "Affiche la quantité de poids de vote qui est à X nombre de confirmations du nœud leader. Utile pour savoir à quel point les nœuds sont bien synchronisés et alignés à travers le réseau"
+ },
+ "representatives_checked_by_weight": {
+ "title": "Différentiel de blocs",
+ "tooltip": "Affiche la quantité de poids de vote qui est à X nombre de blocs du nœud leader. Utile pour avoir une idée de la synchronisation de la propagation des blocs au sein du réseau"
+ },
+ "representative_delegators": {
+ "showing_top_delegators": "Affichage des 100 principaux délégateurs avec un solde minimum de 1 Nano."
+ },
+ "representative_info": {
+ "first_seen": "Première apparition",
+ "last_seen": "Dernière apparition",
+ "weight_represented": "Poids représenté"
+ },
+ "representative_network": {
+ "city": "Ville",
+ "isp": "FAI",
+ "network": "Réseau",
+ "provider": "Fournisseur"
+ },
+ "representative_telemetry": {
+ "telemetry": "Télémétrie",
+ "telemetry_timestamp": "Horodatage de la télémétrie"
+ },
+ "representative_uptime": {
+ "2m_uptime": "Disponibilité 2M",
+ "2w_uptime": "Disponibilité 2S",
+ "3m_uptime": "Disponibilité 3M",
+ "current_status": "Statut actuel",
+ "down": "Hors ligne",
+ "down_for": "Hors ligne depuis",
+ "operational": "Opérationnel",
+ "up_for": "En ligne depuis",
+ "warning": "Avertissement"
+ },
+ "representatives": {
+ "alias": "Alias",
+ "cpu_cores": "Cœurs CPU",
+ "cpu_model": "Modèle CPU",
+ "tdp": "TDP (wH)",
+ "protocol_version": "Protocole",
+ "last_seen": "Dernière vue",
+ "host_asn": "ASN hôte"
+ },
+ "representatives_bandwidth_by_weight": {
+ "tooltip": "Affiche la quantité de poids de vote basée sur la limite de bande passante définie localement par chaque nœud"
+ },
+ "representatives_country_by_weight": {
+ "title": "Pays"
+ },
+ "representatives_offline": {
+ "account": "Compte hors ligne",
+ "last_online": "Dernière fois en ligne"
+ },
+ "representatives_page": {
+ "seo_description": "Explorer et analyser les représentants du réseau Nano",
+ "seo_title": "Explorateur de représentants Nano",
+ "telemetry_tab": "Télémétrie",
+ "weight_distribution_tab": "Distribution du poids",
+ "weight_history_tab": "Historique du poids",
+ "offline_reps_tab": "Représentants hors ligne"
+ },
+ "representatives_provider_by_weight": {
+ "title": "Fournisseur d'hébergement"
+ },
+ "representatives_quorum_charts": {
+ "peers_weight": "Poids des pairs",
+ "quorum_delta": "Delta du quorum",
+ "title": "Graphiques du quorum",
+ "trended_weight": "Poids tendanciel"
+ },
+ "representatives_search": {
+ "placeholder": "Filtrer par compte, alias, ip"
+ },
+ "representatives_weight": {
+ "trended": "Tendanciel"
+ },
+ "representatives_weight_chart": {
+ "title": "Distribution du poids par représentant"
+ },
+ "representatives_version_by_weight": {
+ "title": "Versions"
+ },
+ "roadmap": {
+ "header": {
+ "subtitle": "Objectifs de la communauté",
+ "title": "Planification"
+ },
+ "seo": {
+ "description": "Feuille de route du développement et de la communauté Nano",
+ "tags": [
+ "feuille de route",
+ "nano",
+ "futur",
+ "sortie",
+ "conception",
+ "tâches",
+ "discussions",
+ "communauté",
+ "ambassadeurs",
+ "gestionnaires"
+ ],
+ "title": "Feuille de route"
+ }
+ },
+ "search_bar": {
+ "placeholder": "Rechercher par adresse / hachage de bloc"
+ },
+ "uptime": {
+ "now": "Maintenant",
+ "days_ago": "jours passés"
+ }
+}
From d769d7af6bcf54614063b5290e1278ea6bf21855 Mon Sep 17 00:00:00 2001
From: mistakia <1823355+mistakia@users.noreply.github.com>
Date: Mon, 19 Feb 2024 23:40:22 -0500
Subject: [PATCH 07/26] feat: add `it` locale
---
locales/it.json | 387 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 387 insertions(+)
create mode 100644 locales/it.json
diff --git a/locales/it.json b/locales/it.json
new file mode 100644
index 00000000..5137017b
--- /dev/null
+++ b/locales/it.json
@@ -0,0 +1,387 @@
+{
+ "account_page": {
+ "address": "Indirizzo Account",
+ "change_summary": "Riepilogo Modifiche",
+ "copy_notification": "Indirizzo account copiato",
+ "seo_description": "Informazioni per rappresentante nano",
+ "seo_title": "Account Nano",
+ "telemetry_charts": "Grafici Telemetria",
+ "unopened_description": "Sebbene l'indirizzo dell'account sia valido, non sono stati osservati blocchi. Se NANO è stato inviato a questo account, è ancora necessario pubblicare un blocco corrispondente per ricevere i fondi e stabilire un saldo di apertura. Il saldo di un account può essere aggiornato solo dal titolare dell'account poiché sono gli unici che possono pubblicare blocchi sulla loro catena.",
+ "unopened_note": "Se un blocco di apertura è già stato pubblicato, potrebbe richiedere alcuni momenti per diffondersi attraverso la rete ed essere osservato dai nodi di nano.community.",
+ "unopened_title": "Questo account non è stato ancora aperto"
+ },
+ "account_blocks_summary": {
+ "first_timestamp": "Primo Timestamp",
+ "last_timestamp": "Ultimo Timestamp",
+ "max_amount": "Importo Massimo",
+ "min_amount": "Importo Minimo",
+ "no_records": "Nessun Record",
+ "receiving_account": "Account Ricevente",
+ "representative_account": "Account Rappresentante",
+ "sending_account": "Account Mittente",
+ "showing_top_10": "Mostrando i primi 10 account per totale discendente",
+ "transactions": "Transazioni"
+ },
+ "account_meta": {
+ "account_info": "Informazioni Account",
+ "funding_account": "Account di Finanziamento",
+ "funding_timestamp": "Timestamp di Finanziamento",
+ "height": "Altezza",
+ "last_modified": "Ultima Modifica",
+ "open_timestamp": "Timestamp di Apertura",
+ "opening_balance": "Saldo di Apertura",
+ "receivable_balance": "Saldo Ricevibile"
+ },
+ "block_page": {
+ "amount": "Importo",
+ "copy_notification": "Hash del blocco copiato",
+ "delegated_representative": "Rappresentante Delegato",
+ "description": "Descrizione",
+ "epoch_v1": "Epoca v1 — Aggiornamento delle catene di account dai blocchi legacy (apertura, ricezione, invio, cambio) ai blocchi di stato.",
+ "epoch_v2": "Epoca v2 - Aggiornamento delle catene di account per utilizzare una difficoltà di Proof-of-Work più elevata.",
+ "receiving_account": "Account Ricevente",
+ "section_label": "Hash del Blocco",
+ "sending_account": "Account Mittente",
+ "seo_description": "Informazioni relative a un Blocco Nano",
+ "seo_title": "Blocco Nano",
+ "voting_weight": "Peso di Voto"
+ },
+ "block_info": {
+ "block_account": "Account del Blocco",
+ "operation": "Operazione",
+ "status": "Stato",
+ "timestamp": "Timestamp"
+ },
+ "block_status": {
+ "confirmed": "Confermato",
+ "unconfirmed": "Non confermato"
+ },
+ "block_type": {
+ "change": "Cambio",
+ "epoch": "Epoca",
+ "open": "Apertura",
+ "receive": "Ricezione",
+ "send": "Invio"
+ },
+ "common": {
+ "account_one": "Account",
+ "account_other": "Account",
+ "address": "Indirizzo",
+ "balance": "Saldo",
+ "bandwidth_limit": "Limite di Banda",
+ "bandwidth_limit_short": "Limite BW",
+ "blocks": "Blocchi",
+ "blocks_behind": "Blocchi Indietro",
+ "blocks_diff_short": "Diff Blocchi",
+ "by_online_weight": "Per Peso Online",
+ "clear_filters": "Cancella Filtri",
+ "click_to_copy": "Clicca per copiare",
+ "collapse": "Collassa",
+ "conf_short": "Conf.",
+ "conf_diff_short": "Diff Conf.",
+ "confirmations_behind": "Conferme Indietro",
+ "country": "Paese",
+ "delegator_one": "Delegante",
+ "delegator_other": "Deleganti",
+ "max": "Max",
+ "min": "Min",
+ "offline": "Offline",
+ "online": "Online",
+ "peers": "Peer",
+ "percent_of_total": "% del Totale",
+ "port": "Porta",
+ "quorum_delta": "Delta del Quorum",
+ "representative_one": "Rappresentante",
+ "representative_other": "Rappresentanti",
+ "show_more": "Mostra altri {{count}}",
+ "total": "Totale",
+ "unchecked": "Non verificato",
+ "unchecked_count": "Conteggio Non Verificato",
+ "unlimited": "Illimitato",
+ "uptime": "Tempo di Attività",
+ "version": "Versione",
+ "weight": "Peso"
+ },
+ "delegators": {
+ "showing_top_delegators": "Mostrando i primi 100 deleganti con un saldo minimo di 1 Nano."
+ },
+ "doc": {
+ "contributors": "Contributore",
+ "document_not_found": "Documento (o Account) non trovato",
+ "edit_page": "Modifica Pagina",
+ "help_out": "Aiuta",
+ "not_found_404": "404",
+ "section_link_copied": "Link sezione copiato",
+ "updated_by": "aggiornato da"
+ },
+ "github_events": {
+ "action": {
+ "added_member": "membro aggiunto",
+ "commented_on_commit": "commentato su commit",
+ "commented_on_issue": "commentato su problema",
+ "commented_on_pr_review": "commentato su revisione pr",
+ "created": "creato {{action}}",
+ "deleted": "eliminato {{action}}",
+ "forked": "forkato",
+ "issue_action": "{{action}} problema",
+ "made_public": "reso pubblico",
+ "pr_action": "{{action}} pr",
+ "pr_review": "revisione pr {{title}}",
+ "published_release": "rilascio pubblicato",
+ "pushed_commit": "commit spinto su {{ref}}",
+ "sponsorship_started": "sponsorizzazione iniziata",
+ "watching_repo": "osservando repo"
+ },
+ "events_title": "Eventi di Sviluppo"
+ },
+ "ledger": {
+ "addresses": {
+ "active_detail": "Attivo mostra il numero di indirizzi unici utilizzati. Nuovo mostra il numero di indirizzi creati. Riutilizzato mostra il numero di indirizzi utilizzati che sono stati creati in un giorno precedente.",
+ "active_stats": "Statistiche Indirizzi Attivi",
+ "new_stats": "Statistiche Nuovi Indirizzi",
+ "total_number": "Il numero totale di indirizzi attivi, nuovi e riutilizzati utilizzati al giorno."
+ },
+ "amounts": {
+ "total_number": "Il numero di blocchi di tipo invio confermati al giorno dove l'importo nel blocco è in un dato intervallo (in Nano)"
+ },
+ "blocks": {
+ "change": "Statistiche Blocchi di Cambiamento",
+ "description": "Il numero di blocchi confermati al giorno.",
+ "open": "Statistiche Blocchi di Apertura",
+ "receive": "Statistiche Blocchi di Ricezione",
+ "send": "Statistiche Blocchi di Invio",
+ "total": "Statistiche Totali dei Blocchi"
+ },
+ "description": "Descrizione",
+ "usd_transferred": {
+ "desc_1": "L'importo totale del valore trasferito (in USD) al giorno.",
+ "desc_2": "Basato sul prezzo di chiusura giornaliero di Nano/USD e l'importo totale di Nano trasferito quel giorno.",
+ "usd_transferred": "USD Trasferiti",
+ "usd_transferred_stats": "Statistiche USD Trasferiti"
+ },
+ "volume": {
+ "change_stats": "Statistiche di Cambiamento",
+ "description": "L'importo totale inviato (in Nano) e l'importo totale del peso di voto cambiato al giorno.",
+ "send_stats": "Statistiche di Invio"
+ }
+ },
+ "ledger_page": {
+ "addresses_tab": "Indirizzi",
+ "amounts_tab": "Importi",
+ "blocks_tab": "Blocchi",
+ "seo_description": "Metriche e analisi on-chain del registro Nano",
+ "seo_title": "Analisi del Registro Nano",
+ "value_transferred_tab": "Valore Trasferito",
+ "volume_tab": "Volume"
+ },
+ "menu": {
+ "account_setup": "Configurazione Account",
+ "acquiring": "Acquisizione",
+ "advantages": "Vantaggi",
+ "attack_vectors": "Vettori di Attacco",
+ "basics": "Basi",
+ "best_practices": "Migliori Pratiche",
+ "choosing_a_rep": "Scegliere un Rappresentante",
+ "challenges": "Sfide",
+ "communities": "Comunità",
+ "contribution_guide": "Guida al Contributo",
+ "design": "Design",
+ "developer_discussions": "Discussioni degli Sviluppatori",
+ "developers": "Sviluppatori",
+ "documentation": "Documentazione",
+ "faqs": "FAQ",
+ "get_involved": "Partecipa",
+ "get_support": "Ottieni Supporto",
+ "getting_started": "Iniziare",
+ "glossary": "Glossario",
+ "guides": "Guide",
+ "history": "Storia",
+ "home": "Home",
+ "how_it_works": "Come Funziona",
+ "integrations": "Integrazioni",
+ "introduction": "Introduzione",
+ "investment_thesis": "Tesi di Investimento",
+ "learn": "Impara",
+ "ledger": "Registro",
+ "misconceptions": "Malintesi",
+ "overview": "Panoramica",
+ "planning": "Pianificazione",
+ "privacy": "Privacy",
+ "protocol": "Protocollo",
+ "running_a_node": "Gestire un Nodo",
+ "security": "Sicurezza",
+ "stats": "Statistiche",
+ "storing": "Conservazione",
+ "telemetry": "Telemetria",
+ "topics": "Argomenti",
+ "using": "Utilizzo",
+ "why_it_matters": "Perché È Importante"
+ },
+ "network": {
+ "backlog_text": "Numero mediano di transazioni in attesa di essere confermate $(network.pr_text)",
+ "censor_text": "Il numero minimo di rappresentanti necessari per censurare le transazioni o bloccare la rete",
+ "confirm_text": "Il numero minimo di rappresentanti necessari per confermare le transazioni",
+ "confirmations": "Conferme (24h)",
+ "confirmations_text": "Numero totale di transazioni confermate dalla rete nelle ultime 24 ore",
+ "energy_text": "Stima dell'uso di energia CPU della rete live dei Rappresentanti Principali basata sulle informazioni raccolte sul modello di CPU. La stima si basa sul TDP del CPU, che è la potenza media, in watt, che il processore dissipa quando opera alla frequenza di base con tutti i core attivi sotto un carico di lavoro ad alta complessità definito dal produttore",
+ "energy_usage": "Uso di Energia (TDP) (24h)",
+ "fee_text": "La rete Nano opera senza commissioni",
+ "nano_ticker": "NanoTicker",
+ "online_stake": "Stake Online",
+ "principal_reps": "Rappresentanti Principali",
+ "pr_text": "come osservato attraverso i rappresentanti principali della rete: nodi di voto con più dello 0,1% del peso di voto online a loro delegato",
+ "reps_to_censor": "Rappresentanti per Censurare o Bloccare",
+ "reps_to_confirm": "Rappresentanti per Confermare",
+ "settlement": "Liquidazione (24h)",
+ "settlement_text": "Importo totale del valore liquidato dalla rete nelle ultime 24 ore",
+ "speed_text": "Tempo in millisecondi affinché una transazione di prova venga confermata",
+ "stake_text": "Percentuale del peso Nano delegato che partecipa attivamente al voto",
+ "stats_title": "Statistiche della Rete",
+ "total_reps": "Rappresentanti Totali (24h)",
+ "tx_backlog": "Arretrato Tx",
+ "tx_fees": "Commissioni Tx (24h)",
+ "tx_speed": "Velocità Tx",
+ "tx_throughput": "Throughput Tx",
+ "throughput_text": "Numero mediano di transazioni confermate al secondo nell'ultimo minuto $(network.pr_text)"
+ },
+ "posts": {
+ "nano_foundation": "Fondazione Nano",
+ "top": "Top",
+ "trending": "Di Tendenza"
+ },
+ "representative_alerts": {
+ "table_header": {
+ "behind": "Indietro",
+ "issue": "Problema",
+ "last_online": "Ultima Volta Online",
+ "percent_online_weight": "% Peso Online",
+ "representative": "Rappresentante"
+ },
+ "tooltip": {
+ "behind": "Il rappresentante è indietro o sta eseguendo il bootstrap. Il limite è un conteggio cementato oltre il 95° percentile. (tramite telemetria)",
+ "low_uptime": "Il rappresentante è stato offline più del 25% negli ultimi 28 giorni.",
+ "offline": "Il rappresentante ha smesso di votare e sembra offline.",
+ "overweight": "Il rappresentante ha oltre 3M di peso di voto Nano. I deleganti dovrebbero considerare di distribuire il peso per migliorare la resilienza della rete e il suo valore."
+ },
+ "type": {
+ "behind": "Indietro",
+ "low_uptime": "Bassa Disponibilità",
+ "offline": "Offline",
+ "overweight": "Sovrappeso"
+ }
+ },
+ "representatives_cemented_by_weight": {
+ "title": "Differenziale di Conferma",
+ "tooltip": "Mostra la quantità di peso di voto che si trova entro un numero X di conferme dal nodo leader. Utile per sapere quanto bene i nodi sono sincronizzati e allineati attraverso la rete"
+ },
+ "representatives_checked_by_weight": {
+ "title": "Differenziale di Blocchi",
+ "tooltip": "Mostra la quantità di peso di voto che si trova entro un numero X di blocchi dal nodo leader. Utile per avere un'idea di quanto bene la propagazione dei blocchi sia sincronizzata all'interno della rete"
+ },
+ "representative_delegators": {
+ "showing_top_delegators": "Mostrando i primi 100 deleganti con un saldo minimo di 1 Nano."
+ },
+ "representative_info": {
+ "first_seen": "Prima Vista",
+ "last_seen": "Ultima Vista",
+ "weight_represented": "Peso Rappresentato"
+ },
+ "representative_network": {
+ "city": "Città",
+ "isp": "ISP",
+ "network": "Rete",
+ "provider": "Fornitore"
+ },
+ "representative_telemetry": {
+ "telemetry": "Telemetria",
+ "telemetry_timestamp": "Timestamp Telemetria"
+ },
+ "representative_uptime": {
+ "2m_uptime": "Disponibilità 2M",
+ "2w_uptime": "Disponibilità 2S",
+ "3m_uptime": "Disponibilità 3M",
+ "current_status": "Stato Attuale",
+ "down": "Giù",
+ "down_for": "Giù Per",
+ "operational": "Operativo",
+ "up_for": "Su Per",
+ "warning": "Avvertimento"
+ },
+ "representatives": {
+ "alias": "Alias",
+ "cpu_cores": "Core CPU",
+ "cpu_model": "Modello CPU",
+ "tdp": "TDP (wH)",
+ "protocol_version": "Protocollo",
+ "last_seen": "Ultima Vista",
+ "host_asn": "ASN Host"
+ },
+ "representatives_bandwidth_by_weight": {
+ "tooltip": "Mostra la quantità di peso di voto basata sul limite di banda impostato localmente da ciascun nodo"
+ },
+ "representatives_country_by_weight": {
+ "title": "Paese"
+ },
+ "representatives_offline": {
+ "account": "Account Offline",
+ "last_online": "Ultima Volta Online"
+ },
+ "representatives_page": {
+ "seo_description": "Esplora e analizza i rappresentanti della rete Nano",
+ "seo_title": "Esploratore dei Rappresentanti Nano",
+ "telemetry_tab": "Telemetria",
+ "weight_distribution_tab": "Distribuzione del Peso",
+ "weight_history_tab": "Storia del Peso",
+ "offline_reps_tab": "Rappresentanti Offline"
+ },
+ "representatives_provider_by_weight": {
+ "title": "Fornitore di Hosting"
+ },
+ "representatives_quorum_charts": {
+ "peers_weight": "Peso dei Peers",
+ "quorum_delta": "Delta del Quorum",
+ "title": "Grafici del Quorum",
+ "trended_weight": "Peso Tendenziale"
+ },
+ "representatives_search": {
+ "placeholder": "Filtra per account, alias, ip"
+ },
+ "representatives_weight": {
+ "trended": "Tendenziale"
+ },
+ "representatives_weight_chart": {
+ "title": "Distribuzione del Peso per Rappresentante"
+ },
+ "representatives_version_by_weight": {
+ "title": "Versioni"
+ },
+ "roadmap": {
+ "header": {
+ "subtitle": "Obiettivi della comunità",
+ "title": "Pianificazione"
+ },
+ "seo": {
+ "description": "Sviluppo di Nano & roadmap della comunità",
+ "tags": [
+ "roadmap",
+ "nano",
+ "futuro",
+ "rilascio",
+ "design",
+ "compiti",
+ "discussioni",
+ "comunità",
+ "ambasciatori",
+ "gestori"
+ ],
+ "title": "Roadmap"
+ }
+ },
+ "search_bar": {
+ "placeholder": "Cerca per Indirizzo / Hash del Blocco"
+ },
+ "uptime": {
+ "now": "Adesso",
+ "days_ago": "giorni fa"
+ }
+}
From 41b05bf8865ea7896152cb91cb777f7d9f0a6bb0 Mon Sep 17 00:00:00 2001
From: mistakia <1823355+mistakia@users.noreply.github.com>
Date: Tue, 20 Feb 2024 00:04:24 -0500
Subject: [PATCH 08/26] feat: add `de` localization
---
locales/de.json | 387 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 387 insertions(+)
create mode 100644 locales/de.json
diff --git a/locales/de.json b/locales/de.json
new file mode 100644
index 00000000..89bf3494
--- /dev/null
+++ b/locales/de.json
@@ -0,0 +1,387 @@
+{
+ "account_page": {
+ "address": "Kontoadresse",
+ "change_summary": "Zusammenfassung ändern",
+ "copy_notification": "Kontoadresse kopiert",
+ "seo_description": "Informationen für Nano-Vertreter",
+ "seo_title": "Nano-Konto",
+ "telemetry_charts": "Telemetrie-Diagramme",
+ "unopened_description": "Obwohl die Kontoadresse gültig ist, wurden noch keine Blöcke beobachtet. Wenn NANO an dieses Konto gesendet wurde, muss noch ein entsprechender Block veröffentlicht werden, um die Mittel zu erhalten und ein Eröffnungsguthaben zu erstellen. Das Guthaben eines Kontos kann nur vom Kontoinhaber aktualisiert werden, da nur diese Blöcke in ihrer Kette veröffentlichen können.",
+ "unopened_note": "Wenn ein Eröffnungsblock bereits veröffentlicht wurde, kann es einige Momente dauern, bis er sich im Netzwerk verbreitet und von den Nano.community-Knoten beobachtet wird.",
+ "unopened_title": "Dieses Konto wurde noch nicht eröffnet"
+ },
+ "account_blocks_summary": {
+ "first_timestamp": "Erster Zeitstempel",
+ "last_timestamp": "Letzter Zeitstempel",
+ "max_amount": "Maximalbetrag",
+ "min_amount": "Minimalbetrag",
+ "no_records": "Keine Aufzeichnungen",
+ "receiving_account": "Empfangskonto",
+ "representative_account": "Vertreterkonto",
+ "sending_account": "Absenderkonto",
+ "showing_top_10": "Zeigt die Top 10 Konten nach Gesamtbetrag absteigend",
+ "transactions": "Transaktionen"
+ },
+ "account_meta": {
+ "account_info": "Kontoinformationen",
+ "funding_account": "Finanzierungskonto",
+ "funding_timestamp": "Finanzierungszeitstempel",
+ "height": "Höhe",
+ "last_modified": "Zuletzt geändert",
+ "open_timestamp": "Öffnungszeitstempel",
+ "opening_balance": "Eröffnungsbilanz",
+ "receivable_balance": "Forderungssaldo"
+ },
+ "block_page": {
+ "amount": "Betrag",
+ "copy_notification": "Blockhash kopiert",
+ "delegated_representative": "Delegierter Vertreter",
+ "description": "Beschreibung",
+ "epoch_v1": "Epoche v1 — Aktualisierte Kontoketten von Legacy-Blöcken (öffnen, empfangen, senden, ändern) zu State-Blöcken.",
+ "epoch_v2": "Epoche v2 - Aktualisierte Kontoketten für höhere Proof-of-Work-Schwierigkeit.",
+ "receiving_account": "Empfangskonto",
+ "section_label": "Blockhash",
+ "sending_account": "Absenderkonto",
+ "seo_description": "Informationen zu einem Nano-Block",
+ "seo_title": "Nano-Block",
+ "voting_weight": "Stimmengewicht"
+ },
+ "block_info": {
+ "block_account": "Blockkonto",
+ "operation": "Operation",
+ "status": "Status",
+ "timestamp": "Zeitstempel"
+ },
+ "block_status": {
+ "confirmed": "Bestätigt",
+ "unconfirmed": "Unbestätigt"
+ },
+ "block_type": {
+ "change": "Ändern",
+ "epoch": "Epoche",
+ "open": "Öffnen",
+ "receive": "Empfangen",
+ "send": "Senden"
+ },
+ "common": {
+ "account_one": "Konto",
+ "account_other": "Konten",
+ "address": "Adresse",
+ "balance": "Saldo",
+ "bandwidth_limit": "Bandbreitenlimit",
+ "bandwidth_limit_short": "BW-Limit",
+ "blocks": "Blöcke",
+ "blocks_behind": "Blöcke zurück",
+ "blocks_diff_short": "Blöcke Diff",
+ "by_online_weight": "Nach Online-Gewicht",
+ "clear_filters": "Filter löschen",
+ "click_to_copy": "Zum Kopieren klicken",
+ "collapse": "Einklappen",
+ "conf_short": "Bestät.",
+ "conf_diff_short": "Bestät. Diff",
+ "confirmations_behind": "Bestätigungen zurück",
+ "country": "Land",
+ "delegator_one": "Delegierender",
+ "delegator_other": "Delegierende",
+ "max": "Max",
+ "min": "Min",
+ "offline": "Offline",
+ "online": "Online",
+ "peers": "Peers",
+ "percent_of_total": "% des Gesamten",
+ "port": "Port",
+ "quorum_delta": "Quorum-Delta",
+ "representative_one": "Vertreter",
+ "representative_other": "Vertreter",
+ "show_more": "Zeige {{count}} mehr",
+ "total": "Gesamt",
+ "unchecked": "Ungeprüft",
+ "unchecked_count": "Ungeprüfte Anzahl",
+ "unlimited": "Unbegrenzt",
+ "uptime": "Betriebszeit",
+ "version": "Version",
+ "weight": "Gewicht"
+ },
+ "delegators": {
+ "showing_top_delegators": "Zeigt die Top 100 Delegierenden mit einem Mindestguthaben von 1 Nano."
+ },
+ "doc": {
+ "contributors": "Mitwirkende",
+ "document_not_found": "Dokument (oder Konto) nicht gefunden",
+ "edit_page": "Seite bearbeiten",
+ "help_out": "Helfen",
+ "not_found_404": "404",
+ "section_link_copied": "Abschnittslink kopiert",
+ "updated_by": "aktualisiert von"
+ },
+ "github_events": {
+ "action": {
+ "added_member": "Mitglied hinzugefügt",
+ "commented_on_commit": "kommentierte Commit",
+ "commented_on_issue": "kommentierte Problem",
+ "commented_on_pr_review": "kommentierte PR-Überprüfung",
+ "created": "erstellt {{action}}",
+ "deleted": "gelöscht {{action}}",
+ "forked": "geforkt",
+ "issue_action": "{{action}} Problem",
+ "made_public": "öffentlich gemacht",
+ "pr_action": "{{action}} PR",
+ "pr_review": "PR-Überprüfung {{title}}",
+ "published_release": "Veröffentlichung veröffentlicht",
+ "pushed_commit": "Commit gepusht zu {{ref}}",
+ "sponsorship_started": "Sponsoring begonnen",
+ "watching_repo": "beobachtet Repo"
+ },
+ "events_title": "Entwicklungsereignisse"
+ },
+ "ledger": {
+ "addresses": {
+ "active_detail": "Aktiv zeigt die Anzahl der einzigartigen Adressen, die verwendet wurden. Neu zeigt die Anzahl der erstellten Adressen. Wiederverwendet zeigt die Anzahl der Adressen, die verwendet wurden, die an einem früheren Tag erstellt wurden.",
+ "active_stats": "Aktive Adressstatistiken",
+ "new_stats": "Neue Adressstatistiken",
+ "total_number": "Die Gesamtzahl der pro Tag verwendeten aktiven, neuen und wiederverwendeten Adressen."
+ },
+ "amounts": {
+ "total_number": "Die Anzahl der pro Tag bestätigten Sendetyp-Blöcke, bei denen der Betrag im Block in einem bestimmten Bereich liegt (in Nano)"
+ },
+ "blocks": {
+ "change": "Änderungsblockstatistiken",
+ "description": "Die Anzahl der pro Tag bestätigten Blöcke.",
+ "open": "Öffnungsblockstatistiken",
+ "receive": "Empfangsblockstatistiken",
+ "send": "Sendeblockstatistiken",
+ "total": "Gesamtblockstatistiken"
+ },
+ "description": "Beschreibung",
+ "usd_transferred": {
+ "desc_1": "Der Gesamtbetrag des pro Tag übertragenen Werts (in USD).",
+ "desc_2": "Basierend auf dem täglichen Schlusskurs von Nano/USD und dem gesamten an diesem Tag übertragenen Nano-Betrag.",
+ "usd_transferred": "USD übertragen",
+ "usd_transferred_stats": "USD-Übertragungsstatistiken"
+ },
+ "volume": {
+ "change_stats": "Änderungsstatistiken",
+ "description": "Der gesamte gesendete Betrag (in Nano) und der gesamte Betrag des geänderten Abstimmungsgewichts pro Tag.",
+ "send_stats": "Sendestatistiken"
+ }
+ },
+ "ledger_page": {
+ "addresses_tab": "Adressen",
+ "amounts_tab": "Beträge",
+ "blocks_tab": "Blöcke",
+ "seo_description": "On-Chain-Metriken und Analysen des Nano-Ledgers",
+ "seo_title": "Nano-Ledger-Analyse",
+ "value_transferred_tab": "Übertragener Wert",
+ "volume_tab": "Volumen"
+ },
+ "menu": {
+ "account_setup": "Kontoeinrichtung",
+ "acquiring": "Erwerben",
+ "advantages": "Vorteile",
+ "attack_vectors": "Angriffsvektoren",
+ "basics": "Grundlagen",
+ "best_practices": "Beste Praktiken",
+ "choosing_a_rep": "Einen Vertreter wählen",
+ "challenges": "Herausforderungen",
+ "communities": "Gemeinschaften",
+ "contribution_guide": "Beitragshandbuch",
+ "design": "Design",
+ "developer_discussions": "Entwicklerdiskussionen",
+ "developers": "Entwickler",
+ "documentation": "Dokumentation",
+ "faqs": "FAQs",
+ "get_involved": "Mitmachen",
+ "get_support": "Unterstützung erhalten",
+ "getting_started": "Erste Schritte",
+ "glossary": "Glossar",
+ "guides": "Anleitungen",
+ "history": "Geschichte",
+ "home": "Startseite",
+ "how_it_works": "Wie es funktioniert",
+ "integrations": "Integrationen",
+ "introduction": "Einführung",
+ "investment_thesis": "Investmentthese",
+ "learn": "Lernen",
+ "ledger": "Ledger",
+ "misconceptions": "Missverständnisse",
+ "overview": "Übersicht",
+ "planning": "Planung",
+ "privacy": "Datenschutz",
+ "protocol": "Protokoll",
+ "running_a_node": "Einen Knoten betreiben",
+ "security": "Sicherheit",
+ "stats": "Statistiken",
+ "storing": "Speichern",
+ "telemetry": "Telemetrie",
+ "topics": "Themen",
+ "using": "Verwenden",
+ "why_it_matters": "Warum es wichtig ist"
+ },
+ "network": {
+ "backlog_text": "Mediananzahl der Transaktionen, die auf Bestätigung warten $(network.pr_text)",
+ "censor_text": "Die Mindestanzahl von Vertretern, die benötigt wird, um Transaktionen zu zensieren oder das Netzwerk zu stoppen",
+ "confirm_text": "Die Mindestanzahl von Vertretern, die benötigt wird, um Transaktionen zu bestätigen",
+ "confirmations": "Bestätigungen (24h)",
+ "confirmations_text": "Gesamtanzahl der Transaktionen, die vom Netzwerk in den letzten 24 Stunden bestätigt wurden",
+ "energy_text": "Geschätzter CPU-Energieverbrauch des Live-Netzwerks der Hauptvertreter basierend auf gesammelten CPU-Modellinformationen. Die Schätzung basiert auf der CPU-TDP, die die durchschnittliche Leistung in Watt ist, die der Prozessor bei Betrieb mit Basisfrequenz mit allen Kernen unter einer vom Hersteller definierten, hochkomplexen Arbeitslast abgibt",
+ "energy_usage": "Energieverbrauch (TDP) (24h)",
+ "fee_text": "Das Nano-Netzwerk funktioniert ohne Gebühren",
+ "nano_ticker": "NanoTicker",
+ "online_stake": "Online-Stake",
+ "principal_reps": "Hauptvertreter",
+ "pr_text": "wie beobachtet über die Hauptvertreter des Netzwerks: abstimmende Knoten mit mehr als 0,1% des online delegierten Abstimmungsgewichts",
+ "reps_to_censor": "Vertreter zum Zensieren oder Stoppen",
+ "reps_to_confirm": "Vertreter zur Bestätigung",
+ "settlement": "Abwicklung (24h)",
+ "settlement_text": "Gesamtbetrag des Werts, der vom Netzwerk in den letzten 24 Stunden abgewickelt wurde",
+ "speed_text": "Zeit in Millisekunden für eine Testtransaktion, um bestätigt zu werden",
+ "stake_text": "Prozentsatz des delegierten Nano-Gewichts, das aktiv an der Abstimmung teilnimmt",
+ "stats_title": "Netzwerkstatistiken",
+ "total_reps": "Gesamtvertreter (24h)",
+ "tx_backlog": "Tx-Rückstand",
+ "tx_fees": "Tx-Gebühren (24h)",
+ "tx_speed": "Tx-Geschwindigkeit",
+ "tx_throughput": "Tx-Durchsatz",
+ "throughput_text": "Mediananzahl der Transaktionen, die pro Sekunde in der letzten Minute bestätigt wurden $(network.pr_text)"
+ },
+ "posts": {
+ "nano_foundation": "Nano Foundation",
+ "top": "Top",
+ "trending": "Trend"
+ },
+ "representative_alerts": {
+ "table_header": {
+ "behind": "Zurück",
+ "issue": "Problem",
+ "last_online": "Zuletzt online",
+ "percent_online_weight": "% Online-Gewicht",
+ "representative": "Vertreter"
+ },
+ "tooltip": {
+ "behind": "Vertreter ist zurückgefallen oder bootet neu. Der Grenzwert ist eine zementierte Anzahl über dem 95. Perzentil. (via Telemetrie)",
+ "low_uptime": "Vertreter war mehr als 25% in den letzten 28 Tagen offline.",
+ "offline": "Vertreter hat aufgehört zu voten und scheint offline zu sein.",
+ "overweight": "Vertreter hat über 3M Nano Abstimmungsgewicht. Delegierende sollten in Erwägung ziehen, das Gewicht zu verteilen, um die Widerstandsfähigkeit und den Wert des Netzwerks zu verbessern."
+ },
+ "type": {
+ "behind": "Zurück",
+ "low_uptime": "Niedrige Betriebszeit",
+ "offline": "Offline",
+ "overweight": "Übergewicht"
+ }
+ },
+ "representatives_cemented_by_weight": {
+ "title": "Bestätigungsdifferenz",
+ "tooltip": "Zeigt das Abstimmungsgewicht, das innerhalb einer bestimmten Anzahl von Bestätigungen vom führenden Knoten entfernt ist. Hilfreich, um zu wissen, wie gut synchronisiert und ausgerichtet die Knoten im Netzwerk sind"
+ },
+ "representatives_checked_by_weight": {
+ "title": "Blockdifferenz",
+ "tooltip": "Zeigt das Abstimmungsgewicht, das innerhalb einer bestimmten Anzahl von Blöcken vom führenden Knoten entfernt ist. Nützlich, um ein Gefühl dafür zu bekommen, wie gut die Blockverbreitung im Netzwerk synchronisiert ist"
+ },
+ "representative_delegators": {
+ "showing_top_delegators": "Zeigt die Top 100 Delegierenden mit einem Mindestguthaben von 1 Nano."
+ },
+ "representative_info": {
+ "first_seen": "Erstmals gesehen",
+ "last_seen": "Zuletzt gesehen",
+ "weight_represented": "Vertretenes Gewicht"
+ },
+ "representative_network": {
+ "city": "Stadt",
+ "isp": "ISP",
+ "network": "Netzwerk",
+ "provider": "Anbieter"
+ },
+ "representative_telemetry": {
+ "telemetry": "Telemetrie",
+ "telemetry_timestamp": "Telemetrie-Zeitstempel"
+ },
+ "representative_uptime": {
+ "2m_uptime": "2M Betriebszeit",
+ "2w_uptime": "2W Betriebszeit",
+ "3m_uptime": "3M Betriebszeit",
+ "current_status": "Aktueller Status",
+ "down": "Unten",
+ "down_for": "Unten seit",
+ "operational": "Betriebsbereit",
+ "up_for": "Oben seit",
+ "warning": "Warnung"
+ },
+ "representatives": {
+ "alias": "Alias",
+ "cpu_cores": "CPU Kerne",
+ "cpu_model": "CPU Modell",
+ "tdp": "TDP (wH)",
+ "protocol_version": "Protokoll",
+ "last_seen": "Zuletzt gesehen",
+ "host_asn": "Host ASN"
+ },
+ "representatives_bandwidth_by_weight": {
+ "tooltip": "Zeigt das Abstimmungsgewicht basierend auf dem lokal von jedem Knoten festgelegten Bandbreitenlimit"
+ },
+ "representatives_country_by_weight": {
+ "title": "Land"
+ },
+ "representatives_offline": {
+ "account": "Offline-Konto",
+ "last_online": "Zuletzt online"
+ },
+ "representatives_page": {
+ "seo_description": "Erkunden und analysieren Sie Nano-Netzwerkvertreter",
+ "seo_title": "Nano-Vertreter-Explorer",
+ "telemetry_tab": "Telemetrie",
+ "weight_distribution_tab": "Gewichtsverteilung",
+ "weight_history_tab": "Gewichtsverlauf",
+ "offline_reps_tab": "Offline-Reps"
+ },
+ "representatives_provider_by_weight": {
+ "title": "Hosting-Anbieter"
+ },
+ "representatives_quorum_charts": {
+ "peers_weight": "Peers-Gewicht",
+ "quorum_delta": "Quorum-Delta",
+ "title": "Quorum-Diagramme",
+ "trended_weight": "Trendgewicht"
+ },
+ "representatives_search": {
+ "placeholder": "Filtern nach Konto, Alias, IP"
+ },
+ "representatives_weight": {
+ "trended": "Trend"
+ },
+ "representatives_weight_chart": {
+ "title": "Gewichtsverteilung nach Vertreter"
+ },
+ "representatives_version_by_weight": {
+ "title": "Versionen"
+ },
+ "roadmap": {
+ "header": {
+ "subtitle": "Gemeinschaftsziele",
+ "title": "Planung"
+ },
+ "seo": {
+ "description": "Nano-Entwicklung & Gemeinschafts-Roadmap",
+ "tags": [
+ "roadmap",
+ "nano",
+ "zukunft",
+ "veröffentlichung",
+ "design",
+ "aufgaben",
+ "diskussionen",
+ "gemeinschaft",
+ "botschafter",
+ "manager"
+ ],
+ "title": "Roadmap"
+ }
+ },
+ "search_bar": {
+ "placeholder": "Suche nach Adresse / Block-Hash"
+ },
+ "uptime": {
+ "now": "Jetzt",
+ "days_ago": "Tage her"
+ }
+}
From 325fc51fb705c803d149f0d54e4b2972636cf425 Mon Sep 17 00:00:00 2001
From: mistakia <1823355+mistakia@users.noreply.github.com>
Date: Tue, 20 Feb 2024 00:23:52 -0500
Subject: [PATCH 09/26] feat: add `nl` localization
---
locales/nl.json | 387 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 387 insertions(+)
create mode 100644 locales/nl.json
diff --git a/locales/nl.json b/locales/nl.json
new file mode 100644
index 00000000..a4b0e44c
--- /dev/null
+++ b/locales/nl.json
@@ -0,0 +1,387 @@
+{
+ "account_page": {
+ "address": "Accountadres",
+ "change_summary": "Samenvatting wijzigen",
+ "copy_notification": "Accountadres gekopieerd",
+ "seo_description": "Informatie voor nano vertegenwoordiger",
+ "seo_title": "Nano Account",
+ "telemetry_charts": "Telemetrie Grafieken",
+ "unopened_description": "Hoewel het accountadres geldig is, zijn er geen blokken waargenomen. Als NANO naar dit account is verzonden, moet het nog een overeenkomstig blok publiceren om de fondsen te ontvangen en een openingsbalans vast te stellen. Het saldo van een account kan alleen worden bijgewerkt door de accounthouder, omdat zij de enigen zijn die blokken op hun keten kunnen publiceren.",
+ "unopened_note": "Als er al een openingsblok is gepubliceerd, kan het even duren voordat het zich door het netwerk verspreidt en wordt waargenomen door de nano.community nodes.",
+ "unopened_title": "Dit account is nog niet geopend"
+ },
+ "account_blocks_summary": {
+ "first_timestamp": "Eerste Tijdstempel",
+ "last_timestamp": "Laatste Tijdstempel",
+ "max_amount": "Max Bedrag",
+ "min_amount": "Min Bedrag",
+ "no_records": "Geen Records",
+ "receiving_account": "Ontvangend Account",
+ "representative_account": "Vertegenwoordigend Account",
+ "sending_account": "Verzendend Account",
+ "showing_top_10": "Toont top 10 accounts op totaal aflopend",
+ "transactions": "Transacties"
+ },
+ "account_meta": {
+ "account_info": "Accountinformatie",
+ "funding_account": "Financieringsaccount",
+ "funding_timestamp": "Financieringstijdstempel",
+ "height": "Hoogte",
+ "last_modified": "Laatst Gewijzigd",
+ "open_timestamp": "Open Tijdstempel",
+ "opening_balance": "Openingsbalans",
+ "receivable_balance": "Te Ontvangen Balans"
+ },
+ "block_page": {
+ "amount": "Bedrag",
+ "copy_notification": "Blokhash gekopieerd",
+ "delegated_representative": "Gedelegeerde Vertegenwoordiger",
+ "description": "Beschrijving",
+ "epoch_v1": "Epoch v1 — Geüpgrade accountketens van legacy blokken (open, ontvang, verzend, wijzig) naar staat blokken.",
+ "epoch_v2": "Epoch v2 - Geüpgrade accountketens om hogere Proof-of-Work moeilijkheid te gebruiken.",
+ "receiving_account": "Ontvangend Account",
+ "section_label": "Blok Hash",
+ "sending_account": "Verzendend Account",
+ "seo_description": "Informatie gerelateerd aan een Nano Blok",
+ "seo_title": "Nano Blok",
+ "voting_weight": "Stemgewicht"
+ },
+ "block_info": {
+ "block_account": "Blok Account",
+ "operation": "Operatie",
+ "status": "Status",
+ "timestamp": "Tijdstempel"
+ },
+ "block_status": {
+ "confirmed": "Bevestigd",
+ "unconfirmed": "Onbevestigd"
+ },
+ "block_type": {
+ "change": "Wijzig",
+ "epoch": "Epoch",
+ "open": "Open",
+ "receive": "Ontvang",
+ "send": "Verzend"
+ },
+ "common": {
+ "account_one": "Account",
+ "account_other": "Accounts",
+ "address": "Adres",
+ "balance": "Balans",
+ "bandwidth_limit": "Bandbreedtelimiet",
+ "bandwidth_limit_short": "BW Limiet",
+ "blocks": "Blokken",
+ "blocks_behind": "Blokken Achter",
+ "blocks_diff_short": "Blokken Versch.",
+ "by_online_weight": "Door Online Gewicht",
+ "clear_filters": "Filters Wissen",
+ "click_to_copy": "Klik om te kopiëren",
+ "collapse": "Inklappen",
+ "conf_short": "Bevest.",
+ "conf_diff_short": "Bevest. Versch.",
+ "confirmations_behind": "Bevestigingen Achter",
+ "country": "Land",
+ "delegator_one": "Delegator",
+ "delegator_other": "Delegators",
+ "max": "Max",
+ "min": "Min",
+ "offline": "Offline",
+ "online": "Online",
+ "peers": "Peers",
+ "percent_of_total": "% van Totaal",
+ "port": "Poort",
+ "quorum_delta": "Quorum Delta",
+ "representative_one": "Vertegenwoordiger",
+ "representative_other": "Vertegenwoordigers",
+ "show_more": "Toon {{count}} meer",
+ "total": "Totaal",
+ "unchecked": "Ongecontroleerd",
+ "unchecked_count": "Ongecontroleerd Aantal",
+ "unlimited": "Onbeperkt",
+ "uptime": "Uptime",
+ "version": "Versie",
+ "weight": "Gewicht"
+ },
+ "delegators": {
+ "showing_top_delegators": "Toont de top 100 delegators met een minimum saldo van 1 Nano."
+ },
+ "doc": {
+ "contributors": "Bijdragers",
+ "document_not_found": "Document (of Account) niet gevonden",
+ "edit_page": "Pagina bewerken",
+ "help_out": "Helpen",
+ "not_found_404": "404",
+ "section_link_copied": "Sectielink gekopieerd",
+ "updated_by": "bijgewerkt door"
+ },
+ "github_events": {
+ "action": {
+ "added_member": "lid toegevoegd",
+ "commented_on_commit": "gereageerd op commit",
+ "commented_on_issue": "gereageerd op issue",
+ "commented_on_pr_review": "gereageerd op pr review",
+ "created": "aangemaakt {{action}}",
+ "deleted": "verwijderd {{action}}",
+ "forked": "geforkt",
+ "issue_action": "{{action}} issue",
+ "made_public": "openbaar gemaakt",
+ "pr_action": "{{action}} pr",
+ "pr_review": "pr review {{title}}",
+ "published_release": "publicatie uitgebracht",
+ "pushed_commit": "commit gepusht naar {{ref}}",
+ "sponsorship_started": "sponsoring gestart",
+ "watching_repo": "repo volgen"
+ },
+ "events_title": "Ontwikkelingsevenementen"
+ },
+ "ledger": {
+ "addresses": {
+ "active_detail": "Actief toont het aantal unieke adressen dat gebruikt is. Nieuw toont het aantal adressen dat gecreëerd is. Hergebruikt toont het aantal adressen dat gebruikt is dat op een eerdere dag gecreëerd werd.",
+ "active_stats": "Actieve Adresstatistieken",
+ "new_stats": "Nieuwe Adresstatistieken",
+ "total_number": "Het totale aantal actieve, nieuwe en hergebruikte adressen dat per dag gebruikt wordt."
+ },
+ "amounts": {
+ "total_number": "Het aantal bevestigde verzend-type blokken per dag waarbij het bedrag in het blok binnen een bepaald bereik valt (in Nano)"
+ },
+ "blocks": {
+ "change": "Wijzigingsblok Statistieken",
+ "description": "Het aantal blokken bevestigd per dag.",
+ "open": "Openingsblok Statistieken",
+ "receive": "Ontvangstblok Statistieken",
+ "send": "Verzendblok Statistieken",
+ "total": "Totale Blokstatistieken"
+ },
+ "description": "Beschrijving",
+ "usd_transferred": {
+ "desc_1": "Het totale bedrag aan waarde overgedragen (in USD) per dag.",
+ "desc_2": "Gebaseerd op de dagelijkse slotkoers van Nano/USD en het totale bedrag aan Nano overgedragen die dag.",
+ "usd_transferred": "USD Overgedragen",
+ "usd_transferred_stats": "USD Overgedragen Statistieken"
+ },
+ "volume": {
+ "change_stats": "Wijzigingsstatistieken",
+ "description": "Het totale verzonden bedrag (in Nano) en het totale bedrag aan stemgewicht gewijzigd per dag.",
+ "send_stats": "Verzendstatistieken"
+ }
+ },
+ "ledger_page": {
+ "addresses_tab": "Adressen",
+ "amounts_tab": "Bedragen",
+ "blocks_tab": "Blokken",
+ "seo_description": "On-chain metrieken en analyses van het Nano grootboek",
+ "seo_title": "Nano Grootboek Analyse",
+ "value_transferred_tab": "Overgedragen Waarde",
+ "volume_tab": "Volume"
+ },
+ "menu": {
+ "account_setup": "Account Instellen",
+ "acquiring": "Verkrijgen",
+ "advantages": "Voordelen",
+ "attack_vectors": "Aanvalsvectoren",
+ "basics": "Basis",
+ "best_practices": "Beste Praktijken",
+ "choosing_a_rep": "Een vertegenwoordiger kiezen",
+ "challenges": "Uitdagingen",
+ "communities": "Gemeenschappen",
+ "contribution_guide": "Bijdragegids",
+ "design": "Ontwerp",
+ "developer_discussions": "Ontwikkelaarsdiscussies",
+ "developers": "Ontwikkelaars",
+ "documentation": "Documentatie",
+ "faqs": "FAQs",
+ "get_involved": "Doe mee",
+ "get_support": "Ondersteuning krijgen",
+ "getting_started": "Beginnen",
+ "glossary": "Woordenlijst",
+ "guides": "Gidsen",
+ "history": "Geschiedenis",
+ "home": "Home",
+ "how_it_works": "Hoe het werkt",
+ "integrations": "Integraties",
+ "introduction": "Introductie",
+ "investment_thesis": "Investeringsthese",
+ "learn": "Leren",
+ "ledger": "Grootboek",
+ "misconceptions": "Misvattingen",
+ "overview": "Overzicht",
+ "planning": "Planning 👾",
+ "privacy": "Privacy",
+ "protocol": "Protocol",
+ "running_a_node": "Een node uitvoeren",
+ "security": "Beveiliging",
+ "stats": "Statistieken",
+ "storing": "Opslaan",
+ "telemetry": "Telemetrie",
+ "topics": "Onderwerpen",
+ "using": "Gebruiken",
+ "why_it_matters": "Waarom het belangrijk is"
+ },
+ "network": {
+ "backlog_text": "Mediaan aantal transacties wachtend op bevestiging $(network.pr_text)",
+ "censor_text": "Het minimum aantal vertegenwoordigers nodig om transacties te censureren of het netwerk te stagneren",
+ "confirm_text": "Het minimum aantal vertegenwoordigers nodig om transacties te bevestigen",
+ "confirmations": "Bevestigingen (24u)",
+ "confirmations_text": "Totaal aantal transacties bevestigd door het netwerk in de laatste 24 uur",
+ "energy_text": "Geschat live netwerk CPU energieverbruik van Principiële Vertegenwoordigers gebaseerd op verzamelde CPU model info. De schatting is gebaseerd op CPU TDP, wat het gemiddelde vermogen, in watt, is dat de processor afgeeft bij bedrijf op basisfrequentie met alle kernen actief onder door de fabrikant gedefinieerde, hoog-complexiteit werklast",
+ "energy_usage": "Energieverbruik (TDP) (24u)",
+ "fee_text": "Het Nano netwerk werkt zonder kosten",
+ "nano_ticker": "NanoTicker",
+ "online_stake": "Online Inzet",
+ "principal_reps": "Principiële Vertegenwoordigers",
+ "pr_text": "zoals waargenomen over de netwerken principiële vertegenwoordigers: stemmende nodes met meer dan 0.1% van het online stemgewicht aan hen gedelegeerd",
+ "reps_to_censor": "Vertegenwoordigers om te Censureren of Stagneren",
+ "reps_to_confirm": "Vertegenwoordigers om te Bevestigen",
+ "settlement": "Afhandeling (24u)",
+ "settlement_text": "Totaal bedrag aan waarde afgewikkeld door het netwerk over de laatste 24 uur",
+ "speed_text": "Tijd in milliseconden voor een testtransactie om bevestigd te worden",
+ "stake_text": "Percentage van gedelegeerd Nano gewicht actief deelnemend in stemmen",
+ "stats_title": "Netwerkstatistieken",
+ "total_reps": "Totaal Vertegenwoordigers (24u)",
+ "tx_backlog": "Tx Achterstand",
+ "tx_fees": "Tx Kosten (24u)",
+ "tx_speed": "Tx Snelheid",
+ "tx_throughput": "Tx Doorvoer",
+ "throughput_text": "Mediaan aantal transacties bevestigd per seconde in de laatste minuut $(network.pr_text)"
+ },
+ "posts": {
+ "nano_foundation": "Nano Stichting",
+ "top": "Top",
+ "trending": "Trending"
+ },
+ "representative_alerts": {
+ "table_header": {
+ "behind": "Achter",
+ "issue": "Probleem",
+ "last_online": "Laatst Online",
+ "percent_online_weight": "% Online Gewicht",
+ "representative": "Vertegenwoordiger"
+ },
+ "tooltip": {
+ "behind": "Vertegenwoordiger is achtergebleven of is aan het opstarten. De afkap is een gecementeerd aantal voorbij de 95e percentiel. (via telemetrie)",
+ "low_uptime": "Vertegenwoordiger is meer dan 25% offline geweest in de laatste 28 dagen.",
+ "offline": "Vertegenwoordiger is gestopt met stemmen en lijkt offline.",
+ "overweight": "Vertegenwoordiger heeft meer dan 3M Nano stemgewicht. Delegators zouden moeten overwegen het gewicht te verdelen om de veerkracht en waarde van het netwerk te verbeteren."
+ },
+ "type": {
+ "behind": "Achter",
+ "low_uptime": "Lage Uptime",
+ "offline": "Offline",
+ "overweight": "Overgewicht"
+ }
+ },
+ "representatives_cemented_by_weight": {
+ "title": "Bevestigingsverschil",
+ "tooltip": "Toont de hoeveelheid stemgewicht die binnen X aantal bevestigingen van de leidende node is. Handig om te weten hoe goed gesynchroniseerd en uitgelijnd nodes zijn over het netwerk"
+ },
+ "representatives_checked_by_weight": {
+ "title": "Blokverschil",
+ "tooltip": "Toont de hoeveelheid stemgewicht die binnen X aantal blokken van de leidende node is. Nuttig om een gevoel te krijgen van hoe goed blokpropagatie is gesynchroniseerd binnen het netwerk"
+ },
+ "representative_delegators": {
+ "showing_top_delegators": "Toont top 100 delegators met een minimum saldo van 1 Nano."
+ },
+ "representative_info": {
+ "first_seen": "Eerst Gezien",
+ "last_seen": "Laatst Gezien",
+ "weight_represented": "Gewicht Vertegenwoordigd"
+ },
+ "representative_network": {
+ "city": "Stad",
+ "isp": "ISP",
+ "network": "Netwerk",
+ "provider": "Provider"
+ },
+ "representative_telemetry": {
+ "telemetry": "Telemetrie",
+ "telemetry_timestamp": "Telemetrie Tijdstempel"
+ },
+ "representative_uptime": {
+ "2m_uptime": "2M Uptime",
+ "2w_uptime": "2W Uptime",
+ "3m_uptime": "3M Uptime",
+ "current_status": "Huidige Status",
+ "down": "Omlaag",
+ "down_for": "Omlaag Voor",
+ "operational": "Operationeel",
+ "up_for": "Omhoog Voor",
+ "warning": "Waarschuwing"
+ },
+ "representatives": {
+ "alias": "Alias",
+ "cpu_cores": "CPU Kernen",
+ "cpu_model": "CPU Model",
+ "tdp": "TDP (wH)",
+ "protocol_version": "Protocol",
+ "last_seen": "Laatst Gezien",
+ "host_asn": "Host ASN"
+ },
+ "representatives_bandwidth_by_weight": {
+ "tooltip": "Toont de hoeveelheid stemgewicht gebaseerd op de bandbreedtelimiet die lokaal door elke node is ingesteld"
+ },
+ "representatives_country_by_weight": {
+ "title": "Land"
+ },
+ "representatives_offline": {
+ "account": "Offline Account",
+ "last_online": "Laatst Online"
+ },
+ "representatives_page": {
+ "seo_description": "Verken en analyseer Nano netwerkvertegenwoordigers",
+ "seo_title": "Nano Verteegenwoordigers Verkenner",
+ "telemetry_tab": "Telemetrie",
+ "weight_distribution_tab": "Gewichtsverdeling",
+ "weight_history_tab": "Gewichtsgeschiedenis",
+ "offline_reps_tab": "Offline Vertegenwoordigers"
+ },
+ "representatives_provider_by_weight": {
+ "title": "Hosting Provider"
+ },
+ "representatives_quorum_charts": {
+ "peers_weight": "Peers Gewicht",
+ "quorum_delta": "Quorum Delta",
+ "title": "Quorum Grafieken",
+ "trended_weight": "Getrend Gewicht"
+ },
+ "representatives_search": {
+ "placeholder": "Filter op account, alias, ip"
+ },
+ "representatives_weight": {
+ "trended": "Getrend"
+ },
+ "representatives_weight_chart": {
+ "title": "Gewichtsverdeling per Vertegenwoordiger"
+ },
+ "representatives_version_by_weight": {
+ "title": "Versies"
+ },
+ "roadmap": {
+ "header": {
+ "subtitle": "Gemeenschapsdoelstellingen",
+ "title": "Planning"
+ },
+ "seo": {
+ "description": "Nano ontwikkeling & gemeenschapsroadmap",
+ "tags": [
+ "roadmap",
+ "nano",
+ "toekomst",
+ "release",
+ "ontwerp",
+ "taken",
+ "discussies",
+ "gemeenschap",
+ "ambassadeurs",
+ "managers"
+ ],
+ "title": "Roadmap"
+ }
+ },
+ "search_bar": {
+ "placeholder": "Zoeken op Adres / Blok Hash"
+ },
+ "uptime": {
+ "now": "Nu",
+ "days_ago": "dagen geleden"
+ }
+}
From fa02272f2784a35db521753e314677f55cf287fe Mon Sep 17 00:00:00 2001
From: mistakia <1823355+mistakia@users.noreply.github.com>
Date: Tue, 20 Feb 2024 20:53:21 -0500
Subject: [PATCH 10/26] feat: add `ru` localization
---
locales/ru.json | 387 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 387 insertions(+)
create mode 100644 locales/ru.json
diff --git a/locales/ru.json b/locales/ru.json
new file mode 100644
index 00000000..09a1889f
--- /dev/null
+++ b/locales/ru.json
@@ -0,0 +1,387 @@
+{
+ "account_page": {
+ "address": "Адрес аккаунта",
+ "change_summary": "Изменить сводку",
+ "copy_notification": "Адрес аккаунта скопирован",
+ "seo_description": "Информация для представителя нано",
+ "seo_title": "Аккаунт Nano",
+ "telemetry_charts": "Телеметрические графики",
+ "unopened_description": "Хотя адрес аккаунта действителен, блоки не наблюдались. Если NANO были отправлены на этот аккаунт, необходимо опубликовать соответствующий блок для получения средств и установления начального баланса. Баланс аккаунта может быть обновлен только владельцем аккаунта, так как только они могут публиковать блоки в своей цепочке.",
+ "unopened_note": "Если открывающий блок уже был опубликован, может потребоваться несколько моментов, чтобы он распространился по сети и был замечен узлами nano.community.",
+ "unopened_title": "Этот аккаунт еще не был открыт"
+ },
+ "account_blocks_summary": {
+ "first_timestamp": "Первая отметка времени",
+ "last_timestamp": "Последняя отметка времени",
+ "max_amount": "Максимальная сумма",
+ "min_amount": "Минимальная сумма",
+ "no_records": "Записей нет",
+ "receiving_account": "Получающий аккаунт",
+ "representative_account": "Представительский аккаунт",
+ "sending_account": "Отправляющий аккаунт",
+ "showing_top_10": "Показаны 10 лучших аккаунтов по убыванию общей суммы",
+ "transactions": "Транзакции"
+ },
+ "account_meta": {
+ "account_info": "Информация об аккаунте",
+ "funding_account": "Финансирующий аккаунт",
+ "funding_timestamp": "Время финансирования",
+ "height": "Высота",
+ "last_modified": "Последнее изменение",
+ "open_timestamp": "Время открытия",
+ "opening_balance": "Начальный баланс",
+ "receivable_balance": "Получаемый баланс"
+ },
+ "block_page": {
+ "amount": "Сумма",
+ "copy_notification": "Хэш блока скопирован",
+ "delegated_representative": "Делегированный представитель",
+ "description": "Описание",
+ "epoch_v1": "Эпоха v1 — Обновление цепочек аккаунтов с устаревших блоков (открытие, получение, отправка, изменение) до состояний блоков.",
+ "epoch_v2": "Эпоха v2 - Обновление цепочек аккаунтов для использования более высокой сложности Proof-of-Work.",
+ "receiving_account": "Получающий аккаунт",
+ "section_label": "Хэш блока",
+ "sending_account": "Отправляющий аккаунт",
+ "seo_description": "Информация, связанная с блоком Nano",
+ "seo_title": "Блок Nano",
+ "voting_weight": "Вес голоса"
+ },
+ "block_info": {
+ "block_account": "Аккаунт блока",
+ "operation": "Операция",
+ "status": "Статус",
+ "timestamp": "Отметка времени"
+ },
+ "block_status": {
+ "confirmed": "Подтверждено",
+ "unconfirmed": "Не подтверждено"
+ },
+ "block_type": {
+ "change": "Изменение",
+ "epoch": "Эпоха",
+ "open": "Открыть",
+ "receive": "Получить",
+ "send": "Отправить"
+ },
+ "common": {
+ "account_one": "Аккаунт",
+ "account_other": "Аккаунты",
+ "address": "Адрес",
+ "balance": "Баланс",
+ "bandwidth_limit": "Лимит пропускной способности",
+ "bandwidth_limit_short": "Лимит ПС",
+ "blocks": "Блоки",
+ "blocks_behind": "Блоков позади",
+ "blocks_diff_short": "Разн. блоков",
+ "by_online_weight": "По онлайн весу",
+ "clear_filters": "Очистить фильтры",
+ "click_to_copy": "Нажмите, чтобы скопировать",
+ "collapse": "Свернуть",
+ "conf_short": "Подтв.",
+ "conf_diff_short": "Разн. подтв.",
+ "confirmations_behind": "Подтверждений позади",
+ "country": "Страна",
+ "delegator_one": "Делегатор",
+ "delegator_other": "Делегаторы",
+ "max": "Макс",
+ "min": "Мин",
+ "offline": "Оффлайн",
+ "online": "Онлайн",
+ "peers": "Пиры",
+ "percent_of_total": "% от общего",
+ "port": "Порт",
+ "quorum_delta": "Дельта кворума",
+ "representative_one": "Представитель",
+ "representative_other": "Представители",
+ "show_more": "Показать еще {{count}}",
+ "total": "Всего",
+ "unchecked": "Не проверено",
+ "unchecked_count": "Количество не проверенных",
+ "unlimited": "Неограниченно",
+ "uptime": "Время работы",
+ "version": "Версия",
+ "weight": "Вес"
+ },
+ "delegators": {
+ "showing_top_delegators": "Показаны 100 лучших делегаторов с минимальным балансом в 1 Nano."
+ },
+ "doc": {
+ "contributors": "Участник",
+ "document_not_found": "Документ (или аккаунт) не найден",
+ "edit_page": "Редактировать страницу",
+ "help_out": "Помочь",
+ "not_found_404": "404",
+ "section_link_copied": "Ссылка на раздел скопирована",
+ "updated_by": "обновлено"
+ },
+ "github_events": {
+ "action": {
+ "added_member": "добавлен участник",
+ "commented_on_commit": "прокомментирован коммит",
+ "commented_on_issue": "прокомментирована проблема",
+ "commented_on_pr_review": "прокомментирован обзор пулл-реквеста",
+ "created": "создано {{action}}",
+ "deleted": "удалено {{action}}",
+ "forked": "форкнуто",
+ "issue_action": "{{action}} проблема",
+ "made_public": "сделано публичным",
+ "pr_action": "{{action}} пулл-реквест",
+ "pr_review": "обзор пулл-реквеста {{title}}",
+ "published_release": "опубликован релиз",
+ "pushed_commit": "отправлен коммит в {{ref}}",
+ "sponsorship_started": "начат спонсорство",
+ "watching_repo": "просмотр репозитория"
+ },
+ "events_title": "События разработки"
+ },
+ "ledger": {
+ "addresses": {
+ "active_detail": "Активные показывает количество уникальных использованных адресов. Новые показывает количество созданных адресов. Повторно используемые показывает количество использованных адресов, созданных в предыдущие дни.",
+ "active_stats": "Статистика активных адресов",
+ "new_stats": "Статистика новых адресов",
+ "total_number": "Общее количество активных, новых и повторно используемых адресов, используемых в день."
+ },
+ "amounts": {
+ "total_number": "Количество подтвержденных блоков отправки в день, где сумма в блоке находится в заданном диапазоне (в Nano)"
+ },
+ "blocks": {
+ "change": "Статистика блоков изменения",
+ "description": "Количество подтвержденных блоков в день.",
+ "open": "Статистика открытых блоков",
+ "receive": "Статистика блоков получения",
+ "send": "Статистика блоков отправки",
+ "total": "Общая статистика блоков"
+ },
+ "description": "Описание",
+ "usd_transferred": {
+ "desc_1": "Общая сумма переданной стоимости (в USD) в день.",
+ "desc_2": "Основано на закрытии дневной цены Nano/USD и общей сумме переданного Nano в тот день.",
+ "usd_transferred": "Передано в USD",
+ "usd_transferred_stats": "Статистика передачи в USD"
+ },
+ "volume": {
+ "change_stats": "Статистика изменений",
+ "description": "Общая отправленная сумма (в Nano) и общая сумма измененного веса голосования в день.",
+ "send_stats": "Статистика отправок"
+ }
+ },
+ "ledger_page": {
+ "addresses_tab": "Адреса",
+ "amounts_tab": "Суммы",
+ "blocks_tab": "Блоки",
+ "seo_description": "Метрики и аналитика блокчейна Nano",
+ "seo_title": "Анализ блокчейна Nano",
+ "value_transferred_tab": "Переданная стоимость",
+ "volume_tab": "Объем"
+ },
+ "menu": {
+ "account_setup": "Настройка аккаунта",
+ "acquiring": "Приобретение",
+ "advantages": "Преимущества",
+ "attack_vectors": "Векторы атак",
+ "basics": "Основы",
+ "best_practices": "Лучшие практики",
+ "choosing_a_rep": "Выбор представителя",
+ "challenges": "Вызовы",
+ "communities": "Сообщества",
+ "contribution_guide": "Руководство по вкладу",
+ "design": "Дизайн",
+ "developer_discussions": "Обсуждения разработчиков",
+ "developers": "Разработчики",
+ "documentation": "Документация",
+ "faqs": "ЧаВо",
+ "get_involved": "Принять участие",
+ "get_support": "Получить поддержку",
+ "getting_started": "Начало работы",
+ "glossary": "Глоссарий",
+ "guides": "Руководства",
+ "history": "История",
+ "home": "Главная",
+ "how_it_works": "Как это работает",
+ "integrations": "Интеграции",
+ "introduction": "Введение",
+ "investment_thesis": "Инвестиционная теза",
+ "learn": "Учиться",
+ "ledger": "Блокчейн",
+ "misconceptions": "Заблуждения",
+ "overview": "Обзор",
+ "planning": "Планирование 👾",
+ "privacy": "Конфиденциальность",
+ "protocol": "Протокол",
+ "running_a_node": "Управление узлом",
+ "security": "Безопасность",
+ "stats": "Статистика",
+ "storing": "Хранение",
+ "telemetry": "Телеметрия",
+ "topics": "Темы",
+ "using": "Использование",
+ "why_it_matters": "Почему это важно"
+ },
+ "network": {
+ "backlog_text": "Медианное количество транзакций, ожидающих подтверждения $(network.pr_text)",
+ "censor_text": "Минимальное количество представителей, необходимых для цензурирования транзакций или остановки сети",
+ "confirm_text": "Минимальное количество представителей, необходимых для подтверждения транзакций",
+ "confirmations": "Подтверждения (24ч)",
+ "confirmations_text": "Общее количество транзакций, подтвержденных сетью за последние 24 часа",
+ "energy_text": "Оценка потребления энергии ЦПУ живой сети основных представителей на основе собранной информации о модели ЦПУ. Оценка основана на TDP ЦПУ, которая является средней мощностью в ваттах, рассеиваемой процессором при работе на базовой частоте со всеми активными ядрами под нагрузкой высокой сложности, определенной производителем",
+ "energy_usage": "Использование энергии (TDP) (24ч)",
+ "fee_text": "Сеть Nano работает без комиссий",
+ "nano_ticker": "Тикер Nano",
+ "online_stake": "Онлайн ставка",
+ "principal_reps": "Основные представители",
+ "pr_text": "как наблюдается по всей сети основных представителей: голосующих узлов с более чем 0.1% онлайн веса голосования, делегированных им",
+ "reps_to_censor": "Представители для цензуры или остановки",
+ "reps_to_confirm": "Представители для подтверждения",
+ "settlement": "Расчет (24ч)",
+ "settlement_text": "Общая сумма стоимости, урегулированной сетью за последние 24 часа",
+ "speed_text": "Время в миллисекундах для подтверждения тестовой транзакции",
+ "stake_text": "Процент делегированного веса Nano, активно участвующего в голосовании",
+ "stats_title": "Статистика сети",
+ "total_reps": "Всего представителей (24ч)",
+ "tx_backlog": "Очередь транзакций",
+ "tx_fees": "Комиссии за транзакции (24ч)",
+ "tx_speed": "Скорость транзакций",
+ "tx_throughput": "Пропускная способность транзакций",
+ "throughput_text": "Медианное количество транзакций, подтвержденных в секунду за последнюю минуту $(network.pr_text)"
+ },
+ "posts": {
+ "nano_foundation": "Фонд Nano",
+ "top": "Топ",
+ "trending": "Тренды"
+ },
+ "representative_alerts": {
+ "table_header": {
+ "behind": "Позади",
+ "issue": "Проблема",
+ "last_online": "Последний раз онлайн",
+ "percent_online_weight": "% Онлайн веса",
+ "representative": "Представитель"
+ },
+ "tooltip": {
+ "behind": "Представитель отстал или загружается. Критерий - цементированный счет за пределами 95-го процентиля. (через телеметрию)",
+ "low_uptime": "Представитель был оффлайн более 25% в последние 28 дней.",
+ "offline": "Представитель прекратил голосование и кажется оффлайн.",
+ "overweight": "У представителя более 3M Nano веса голосования. Делегаторам следует рассмотреть возможность распределения веса для улучшения устойчивости сети и ее ценности."
+ },
+ "type": {
+ "behind": "Отстает",
+ "low_uptime": "Низкое время работы",
+ "offline": "Оффлайн",
+ "overweight": "Избыточный вес"
+ }
+ },
+ "representatives_cemented_by_weight": {
+ "title": "Дифференциал подтверждений",
+ "tooltip": "Показывает количество веса голосования, которое находится в пределах X подтверждений от ведущего узла. Полезно для понимания, насколько хорошо узлы синхронизированы и выровнены по всей сети"
+ },
+ "representatives_checked_by_weight": {
+ "title": "Дифференциал блоков",
+ "tooltip": "Показывает количество веса голосования, которое находится в пределах X блоков от ведущего узла. Полезно для получения представления о том, насколько хорошо распространение блоков синхронизировано в сети"
+ },
+ "representative_delegators": {
+ "showing_top_delegators": "Показаны 100 лучших делегаторов с минимальным балансом в 1 Nano."
+ },
+ "representative_info": {
+ "first_seen": "Впервые замечен",
+ "last_seen": "Последний раз замечен",
+ "weight_represented": "Представленный вес"
+ },
+ "representative_network": {
+ "city": "Город",
+ "isp": "Интернет-провайдер",
+ "network": "Сеть",
+ "provider": "Провайдер"
+ },
+ "representative_telemetry": {
+ "telemetry": "Телеметрия",
+ "telemetry_timestamp": "Временная метка телеметрии"
+ },
+ "representative_uptime": {
+ "2m_uptime": "Время работы 2М",
+ "2w_uptime": "Время работы 2Н",
+ "3m_uptime": "Время работы 3М",
+ "current_status": "Текущий статус",
+ "down": "Не работает",
+ "down_for": "Не работает в течение",
+ "operational": "Работает",
+ "up_for": "Работает в течение",
+ "warning": "Предупреждение"
+ },
+ "representatives": {
+ "alias": "Псевдоним",
+ "cpu_cores": "Ядра ЦПУ",
+ "cpu_model": "Модель ЦПУ",
+ "tdp": "TDP (втч)",
+ "protocol_version": "Протокол",
+ "last_seen": "Последний раз замечен",
+ "host_asn": "Хост ASN"
+ },
+ "representatives_bandwidth_by_weight": {
+ "tooltip": "Показывает количество веса голосования на основе локально установленного лимита пропускной способности каждого узла"
+ },
+ "representatives_country_by_weight": {
+ "title": "Страна"
+ },
+ "representatives_offline": {
+ "account": "Оффлайн аккаунт",
+ "last_online": "Последний раз онлайн"
+ },
+ "representatives_page": {
+ "seo_description": "Исследуйте и анализируйте представителей сети Nano",
+ "seo_title": "Исследователь представителей Nano",
+ "telemetry_tab": "Телеметрия",
+ "weight_distribution_tab": "Распределение веса",
+ "weight_history_tab": "История веса",
+ "offline_reps_tab": "Оффлайн представители"
+ },
+ "representatives_provider_by_weight": {
+ "title": "Хостинг-провайдер"
+ },
+ "representatives_quorum_charts": {
+ "peers_weight": "Вес пиров",
+ "quorum_delta": "Дельта кворума",
+ "title": "Графики кворума",
+ "trended_weight": "Трендовый вес"
+ },
+ "representatives_search": {
+ "placeholder": "Фильтр по аккаунту, псевдониму, IP"
+ },
+ "representatives_weight": {
+ "trended": "Трендовый"
+ },
+ "representatives_weight_chart": {
+ "title": "Распределение веса по представителям"
+ },
+ "representatives_version_by_weight": {
+ "title": "Версии"
+ },
+ "roadmap": {
+ "header": {
+ "subtitle": "Цели сообщества",
+ "title": "Планирование"
+ },
+ "seo": {
+ "description": "Дорожная карта развития и сообщества Nano",
+ "tags": [
+ "дорожная карта",
+ "nano",
+ "будущее",
+ "выпуск",
+ "дизайн",
+ "задачи",
+ "обсуждения",
+ "сообщество",
+ "послы",
+ "менеджеры"
+ ],
+ "title": "Дорожная карта"
+ }
+ },
+ "search_bar": {
+ "placeholder": "Поиск по адресу / хешу блока"
+ },
+ "uptime": {
+ "now": "Сейчас",
+ "days_ago": "дней назад"
+ }
+}
From 94d99b1a45b26a449f3688acfd8a41ba43f93652 Mon Sep 17 00:00:00 2001
From: mistakia <1823355+mistakia@users.noreply.github.com>
Date: Tue, 20 Feb 2024 21:07:45 -0500
Subject: [PATCH 11/26] fix: change locale select `renderValue` prop
---
src/views/components/change-locale/change-locale.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/views/components/change-locale/change-locale.js b/src/views/components/change-locale/change-locale.js
index 04a03535..1c7436fc 100644
--- a/src/views/components/change-locale/change-locale.js
+++ b/src/views/components/change-locale/change-locale.js
@@ -35,6 +35,7 @@ export default function ChangeLocale({ change_locale, locale }) {
value={locale}
variant='outlined'
onChange={(event) => change_locale(event.target.value)}
+ native={false}
renderValue={(selected) => (
<>
Date: Tue, 20 Feb 2024 22:59:13 -0500
Subject: [PATCH 12/26] feat: organize docs by locale
---
api/server.mjs | 4 +-
docs/{ => en}/community.md | 0
docs/{ => en}/contributing.md | 0
docs/{ => en}/design/attack-vectors.md | 0
docs/{ => en}/design/basics.md | 0
docs/{ => en}/design/challenges.md | 0
docs/{ => en}/design/glossary.md | 0
docs/{ => en}/design/roadmap.md | 0
docs/{ => en}/design/security.md | 0
docs/{ => en}/faqs.md | 0
.../adding-custom-stats.md | 0
.../developer-discussions.md | 0
.../getting-started-devs/documentation.md | 0
.../getting-started-devs/getting-started.md | 0
.../getting-started-devs/integrations.md | 0
.../protocol-reference.md | 0
.../getting-started-devs/running-a-node.md | 0
.../tutorials/overview.md | 0
.../getting-started-users/acquiring.md | 0
docs/{ => en}/getting-started-users/basics.md | 0
.../getting-started-users/best-practices.md | 0
.../choosing-a-representative.md | 0
.../{ => en}/getting-started-users/privacy.md | 0
.../getting-started-users/storing/basics.md | 0
.../getting-started-users/storing/setup.md | 0
docs/{ => en}/getting-started-users/using.md | 0
docs/{ => en}/history/community/nano-trade.md | 0
docs/{ => en}/history/overview.md | 0
docs/{ => en}/introduction/advantages.md | 0
docs/{ => en}/introduction/basics.md | 0
docs/{ => en}/introduction/how-it-works.md | 0
.../introduction/investment-thesis.md | 0
docs/{ => en}/introduction/misconceptions.md | 0
docs/{ => en}/introduction/why-it-matters.md | 0
docs/{ => en}/labels.md | 0
docs/{ => en}/labels/attack-vectors.md | 0
docs/{ => en}/labels/congestion-spam.md | 0
docs/{ => en}/labels/consensus.md | 0
docs/{ => en}/labels/economics.md | 0
docs/{ => en}/labels/finality.md | 0
docs/{ => en}/labels/governance.md | 0
docs/{ => en}/labels/micropayments.md | 0
.../labels/minimum-account-balances.md | 0
docs/{ => en}/labels/privacy.md | 0
docs/{ => en}/labels/scalability.md | 0
docs/{ => en}/labels/security.md | 0
.../{ => en}/labels/tx-prioritization/dpow.md | 0
docs/{ => en}/labels/tx-prioritization/fee.md | 0
.../labels/tx-prioritization/taac-pos4qos.md | 0
docs/{ => en}/labels/wallets.md | 0
docs/{ => en}/okrs.md | 0
docs/{ => en}/support.md | 0
src/core/api/service.js | 2 +-
src/core/docs/selectors.js | 9 ++-
src/views/components/menu/menu.js | 70 ++++++++++---------
src/views/pages/doc/doc.js | 43 +++++++-----
56 files changed, 74 insertions(+), 54 deletions(-)
rename docs/{ => en}/community.md (100%)
rename docs/{ => en}/contributing.md (100%)
rename docs/{ => en}/design/attack-vectors.md (100%)
rename docs/{ => en}/design/basics.md (100%)
rename docs/{ => en}/design/challenges.md (100%)
rename docs/{ => en}/design/glossary.md (100%)
rename docs/{ => en}/design/roadmap.md (100%)
rename docs/{ => en}/design/security.md (100%)
rename docs/{ => en}/faqs.md (100%)
rename docs/{ => en}/getting-started-devs/adding-custom-stats.md (100%)
rename docs/{ => en}/getting-started-devs/developer-discussions.md (100%)
rename docs/{ => en}/getting-started-devs/documentation.md (100%)
rename docs/{ => en}/getting-started-devs/getting-started.md (100%)
rename docs/{ => en}/getting-started-devs/integrations.md (100%)
rename docs/{ => en}/getting-started-devs/protocol-reference.md (100%)
rename docs/{ => en}/getting-started-devs/running-a-node.md (100%)
rename docs/{ => en}/getting-started-devs/tutorials/overview.md (100%)
rename docs/{ => en}/getting-started-users/acquiring.md (100%)
rename docs/{ => en}/getting-started-users/basics.md (100%)
rename docs/{ => en}/getting-started-users/best-practices.md (100%)
rename docs/{ => en}/getting-started-users/choosing-a-representative.md (100%)
rename docs/{ => en}/getting-started-users/privacy.md (100%)
rename docs/{ => en}/getting-started-users/storing/basics.md (100%)
rename docs/{ => en}/getting-started-users/storing/setup.md (100%)
rename docs/{ => en}/getting-started-users/using.md (100%)
rename docs/{ => en}/history/community/nano-trade.md (100%)
rename docs/{ => en}/history/overview.md (100%)
rename docs/{ => en}/introduction/advantages.md (100%)
rename docs/{ => en}/introduction/basics.md (100%)
rename docs/{ => en}/introduction/how-it-works.md (100%)
rename docs/{ => en}/introduction/investment-thesis.md (100%)
rename docs/{ => en}/introduction/misconceptions.md (100%)
rename docs/{ => en}/introduction/why-it-matters.md (100%)
rename docs/{ => en}/labels.md (100%)
rename docs/{ => en}/labels/attack-vectors.md (100%)
rename docs/{ => en}/labels/congestion-spam.md (100%)
rename docs/{ => en}/labels/consensus.md (100%)
rename docs/{ => en}/labels/economics.md (100%)
rename docs/{ => en}/labels/finality.md (100%)
rename docs/{ => en}/labels/governance.md (100%)
rename docs/{ => en}/labels/micropayments.md (100%)
rename docs/{ => en}/labels/minimum-account-balances.md (100%)
rename docs/{ => en}/labels/privacy.md (100%)
rename docs/{ => en}/labels/scalability.md (100%)
rename docs/{ => en}/labels/security.md (100%)
rename docs/{ => en}/labels/tx-prioritization/dpow.md (100%)
rename docs/{ => en}/labels/tx-prioritization/fee.md (100%)
rename docs/{ => en}/labels/tx-prioritization/taac-pos4qos.md (100%)
rename docs/{ => en}/labels/wallets.md (100%)
rename docs/{ => en}/okrs.md (100%)
rename docs/{ => en}/support.md (100%)
diff --git a/api/server.mjs b/api/server.mjs
index 6cdc96d3..0c9b6100 100644
--- a/api/server.mjs
+++ b/api/server.mjs
@@ -107,8 +107,8 @@ const speedLimiter = slowDown({
maxDelayMs: 20000 // maximum delay of 20 seconds
})
-api.use('/api/docs', speedLimiter, serveStatic(docsPath))
-api.use('/api/docs/en', speedLimiter, serveStatic(docsPath))
+api.use('/api/docs', speedLimiter, serveStatic(path.join(docsPath, 'en')))
+api.use('/api/docs/en', speedLimiter, serveStatic(path.join(docsPath, 'en')))
api.get('/api/docs/:locale/*', speedLimiter, async (req, res) => {
const { locale } = req.params
const doc_id = req.params[0] // Capture the rest of the path as doc_id
diff --git a/docs/community.md b/docs/en/community.md
similarity index 100%
rename from docs/community.md
rename to docs/en/community.md
diff --git a/docs/contributing.md b/docs/en/contributing.md
similarity index 100%
rename from docs/contributing.md
rename to docs/en/contributing.md
diff --git a/docs/design/attack-vectors.md b/docs/en/design/attack-vectors.md
similarity index 100%
rename from docs/design/attack-vectors.md
rename to docs/en/design/attack-vectors.md
diff --git a/docs/design/basics.md b/docs/en/design/basics.md
similarity index 100%
rename from docs/design/basics.md
rename to docs/en/design/basics.md
diff --git a/docs/design/challenges.md b/docs/en/design/challenges.md
similarity index 100%
rename from docs/design/challenges.md
rename to docs/en/design/challenges.md
diff --git a/docs/design/glossary.md b/docs/en/design/glossary.md
similarity index 100%
rename from docs/design/glossary.md
rename to docs/en/design/glossary.md
diff --git a/docs/design/roadmap.md b/docs/en/design/roadmap.md
similarity index 100%
rename from docs/design/roadmap.md
rename to docs/en/design/roadmap.md
diff --git a/docs/design/security.md b/docs/en/design/security.md
similarity index 100%
rename from docs/design/security.md
rename to docs/en/design/security.md
diff --git a/docs/faqs.md b/docs/en/faqs.md
similarity index 100%
rename from docs/faqs.md
rename to docs/en/faqs.md
diff --git a/docs/getting-started-devs/adding-custom-stats.md b/docs/en/getting-started-devs/adding-custom-stats.md
similarity index 100%
rename from docs/getting-started-devs/adding-custom-stats.md
rename to docs/en/getting-started-devs/adding-custom-stats.md
diff --git a/docs/getting-started-devs/developer-discussions.md b/docs/en/getting-started-devs/developer-discussions.md
similarity index 100%
rename from docs/getting-started-devs/developer-discussions.md
rename to docs/en/getting-started-devs/developer-discussions.md
diff --git a/docs/getting-started-devs/documentation.md b/docs/en/getting-started-devs/documentation.md
similarity index 100%
rename from docs/getting-started-devs/documentation.md
rename to docs/en/getting-started-devs/documentation.md
diff --git a/docs/getting-started-devs/getting-started.md b/docs/en/getting-started-devs/getting-started.md
similarity index 100%
rename from docs/getting-started-devs/getting-started.md
rename to docs/en/getting-started-devs/getting-started.md
diff --git a/docs/getting-started-devs/integrations.md b/docs/en/getting-started-devs/integrations.md
similarity index 100%
rename from docs/getting-started-devs/integrations.md
rename to docs/en/getting-started-devs/integrations.md
diff --git a/docs/getting-started-devs/protocol-reference.md b/docs/en/getting-started-devs/protocol-reference.md
similarity index 100%
rename from docs/getting-started-devs/protocol-reference.md
rename to docs/en/getting-started-devs/protocol-reference.md
diff --git a/docs/getting-started-devs/running-a-node.md b/docs/en/getting-started-devs/running-a-node.md
similarity index 100%
rename from docs/getting-started-devs/running-a-node.md
rename to docs/en/getting-started-devs/running-a-node.md
diff --git a/docs/getting-started-devs/tutorials/overview.md b/docs/en/getting-started-devs/tutorials/overview.md
similarity index 100%
rename from docs/getting-started-devs/tutorials/overview.md
rename to docs/en/getting-started-devs/tutorials/overview.md
diff --git a/docs/getting-started-users/acquiring.md b/docs/en/getting-started-users/acquiring.md
similarity index 100%
rename from docs/getting-started-users/acquiring.md
rename to docs/en/getting-started-users/acquiring.md
diff --git a/docs/getting-started-users/basics.md b/docs/en/getting-started-users/basics.md
similarity index 100%
rename from docs/getting-started-users/basics.md
rename to docs/en/getting-started-users/basics.md
diff --git a/docs/getting-started-users/best-practices.md b/docs/en/getting-started-users/best-practices.md
similarity index 100%
rename from docs/getting-started-users/best-practices.md
rename to docs/en/getting-started-users/best-practices.md
diff --git a/docs/getting-started-users/choosing-a-representative.md b/docs/en/getting-started-users/choosing-a-representative.md
similarity index 100%
rename from docs/getting-started-users/choosing-a-representative.md
rename to docs/en/getting-started-users/choosing-a-representative.md
diff --git a/docs/getting-started-users/privacy.md b/docs/en/getting-started-users/privacy.md
similarity index 100%
rename from docs/getting-started-users/privacy.md
rename to docs/en/getting-started-users/privacy.md
diff --git a/docs/getting-started-users/storing/basics.md b/docs/en/getting-started-users/storing/basics.md
similarity index 100%
rename from docs/getting-started-users/storing/basics.md
rename to docs/en/getting-started-users/storing/basics.md
diff --git a/docs/getting-started-users/storing/setup.md b/docs/en/getting-started-users/storing/setup.md
similarity index 100%
rename from docs/getting-started-users/storing/setup.md
rename to docs/en/getting-started-users/storing/setup.md
diff --git a/docs/getting-started-users/using.md b/docs/en/getting-started-users/using.md
similarity index 100%
rename from docs/getting-started-users/using.md
rename to docs/en/getting-started-users/using.md
diff --git a/docs/history/community/nano-trade.md b/docs/en/history/community/nano-trade.md
similarity index 100%
rename from docs/history/community/nano-trade.md
rename to docs/en/history/community/nano-trade.md
diff --git a/docs/history/overview.md b/docs/en/history/overview.md
similarity index 100%
rename from docs/history/overview.md
rename to docs/en/history/overview.md
diff --git a/docs/introduction/advantages.md b/docs/en/introduction/advantages.md
similarity index 100%
rename from docs/introduction/advantages.md
rename to docs/en/introduction/advantages.md
diff --git a/docs/introduction/basics.md b/docs/en/introduction/basics.md
similarity index 100%
rename from docs/introduction/basics.md
rename to docs/en/introduction/basics.md
diff --git a/docs/introduction/how-it-works.md b/docs/en/introduction/how-it-works.md
similarity index 100%
rename from docs/introduction/how-it-works.md
rename to docs/en/introduction/how-it-works.md
diff --git a/docs/introduction/investment-thesis.md b/docs/en/introduction/investment-thesis.md
similarity index 100%
rename from docs/introduction/investment-thesis.md
rename to docs/en/introduction/investment-thesis.md
diff --git a/docs/introduction/misconceptions.md b/docs/en/introduction/misconceptions.md
similarity index 100%
rename from docs/introduction/misconceptions.md
rename to docs/en/introduction/misconceptions.md
diff --git a/docs/introduction/why-it-matters.md b/docs/en/introduction/why-it-matters.md
similarity index 100%
rename from docs/introduction/why-it-matters.md
rename to docs/en/introduction/why-it-matters.md
diff --git a/docs/labels.md b/docs/en/labels.md
similarity index 100%
rename from docs/labels.md
rename to docs/en/labels.md
diff --git a/docs/labels/attack-vectors.md b/docs/en/labels/attack-vectors.md
similarity index 100%
rename from docs/labels/attack-vectors.md
rename to docs/en/labels/attack-vectors.md
diff --git a/docs/labels/congestion-spam.md b/docs/en/labels/congestion-spam.md
similarity index 100%
rename from docs/labels/congestion-spam.md
rename to docs/en/labels/congestion-spam.md
diff --git a/docs/labels/consensus.md b/docs/en/labels/consensus.md
similarity index 100%
rename from docs/labels/consensus.md
rename to docs/en/labels/consensus.md
diff --git a/docs/labels/economics.md b/docs/en/labels/economics.md
similarity index 100%
rename from docs/labels/economics.md
rename to docs/en/labels/economics.md
diff --git a/docs/labels/finality.md b/docs/en/labels/finality.md
similarity index 100%
rename from docs/labels/finality.md
rename to docs/en/labels/finality.md
diff --git a/docs/labels/governance.md b/docs/en/labels/governance.md
similarity index 100%
rename from docs/labels/governance.md
rename to docs/en/labels/governance.md
diff --git a/docs/labels/micropayments.md b/docs/en/labels/micropayments.md
similarity index 100%
rename from docs/labels/micropayments.md
rename to docs/en/labels/micropayments.md
diff --git a/docs/labels/minimum-account-balances.md b/docs/en/labels/minimum-account-balances.md
similarity index 100%
rename from docs/labels/minimum-account-balances.md
rename to docs/en/labels/minimum-account-balances.md
diff --git a/docs/labels/privacy.md b/docs/en/labels/privacy.md
similarity index 100%
rename from docs/labels/privacy.md
rename to docs/en/labels/privacy.md
diff --git a/docs/labels/scalability.md b/docs/en/labels/scalability.md
similarity index 100%
rename from docs/labels/scalability.md
rename to docs/en/labels/scalability.md
diff --git a/docs/labels/security.md b/docs/en/labels/security.md
similarity index 100%
rename from docs/labels/security.md
rename to docs/en/labels/security.md
diff --git a/docs/labels/tx-prioritization/dpow.md b/docs/en/labels/tx-prioritization/dpow.md
similarity index 100%
rename from docs/labels/tx-prioritization/dpow.md
rename to docs/en/labels/tx-prioritization/dpow.md
diff --git a/docs/labels/tx-prioritization/fee.md b/docs/en/labels/tx-prioritization/fee.md
similarity index 100%
rename from docs/labels/tx-prioritization/fee.md
rename to docs/en/labels/tx-prioritization/fee.md
diff --git a/docs/labels/tx-prioritization/taac-pos4qos.md b/docs/en/labels/tx-prioritization/taac-pos4qos.md
similarity index 100%
rename from docs/labels/tx-prioritization/taac-pos4qos.md
rename to docs/en/labels/tx-prioritization/taac-pos4qos.md
diff --git a/docs/labels/wallets.md b/docs/en/labels/wallets.md
similarity index 100%
rename from docs/labels/wallets.md
rename to docs/en/labels/wallets.md
diff --git a/docs/okrs.md b/docs/en/okrs.md
similarity index 100%
rename from docs/okrs.md
rename to docs/en/okrs.md
diff --git a/docs/support.md b/docs/en/support.md
similarity index 100%
rename from docs/support.md
rename to docs/en/support.md
diff --git a/src/core/api/service.js b/src/core/api/service.js
index 6f7e1830..f36328c5 100644
--- a/src/core/api/service.js
+++ b/src/core/api/service.js
@@ -37,7 +37,7 @@ export const api = {
const url = `${API_URL}/docs${id}.md`
return { url }
} else {
- const url = `${API_URL}/docs/${locale}/${id}.md`
+ const url = `${API_URL}/docs/${locale}${id}.md`
return { url }
}
},
diff --git a/src/core/docs/selectors.js b/src/core/docs/selectors.js
index 903e7fdd..81cb2d57 100644
--- a/src/core/docs/selectors.js
+++ b/src/core/docs/selectors.js
@@ -1,11 +1,18 @@
import { Doc } from './doc'
+import i18n from '@core/i18n'
+
export function getDocs(state) {
return state.get('docs')
}
export function getDocById(state, { location }) {
+ const locale = i18n.language
+
const path = location.pathname
- const id = path.endsWith('/') ? path.slice(0, -1) : path
+ let id = path.endsWith('/') ? path.slice(0, -1) : path
+ if (locale) {
+ id = id.replace(`/${locale}`, '')
+ }
return getDocs(state).get(id, new Doc())
}
diff --git a/src/views/components/menu/menu.js b/src/views/components/menu/menu.js
index 31c6914a..0c91b3a9 100644
--- a/src/views/components/menu/menu.js
+++ b/src/views/components/menu/menu.js
@@ -17,7 +17,8 @@ import './menu.styl'
const iOS = /iPad|iPhone|iPod/.test(navigator.userAgent)
function MenuSections() {
- const { t } = useTranslation()
+ const { t, i18n } = useTranslation()
+ const locale = i18n.language
return (
@@ -25,55 +26,56 @@ function MenuSections() {
{t('menu.introduction', 'Introduction')}
-
+
{t('menu.overview', 'Overview')}
-
+
{t('menu.advantages', 'Advantages')}
-
+
{t('menu.how_it_works', 'How it works')}
-
+
{t('menu.why_it_matters', 'Why it matters')}
-
+
{t('menu.misconceptions', 'Misconceptions')}
-
+
{t('menu.investment_thesis', 'Investment thesis')}
-
+
{t('menu.history', 'History')}
- {t('menu.faqs', 'FAQs')}
+ {t('menu.faqs', 'FAQs')}
{t('menu.guides', 'Guides')}
-
+
{t('menu.basics', 'Basics')}
-
+
{t('menu.storing', 'Storing')}
-
+
{t('menu.acquiring', 'Acquiring')}
-
+
{t('menu.choosing_a_rep', 'Choosing a Rep')}
-
+
{t('menu.using', 'Using')}
-
+
{t('menu.account_setup', 'Account Setup')}
-
+
{t('menu.privacy', 'Privacy')}
-
+
{t('menu.best_practices', 'Best Practices')}
@@ -81,20 +83,22 @@ function MenuSections() {
{t('menu.learn', 'Learn')}
- {t('menu.design', 'Design')}
-
+
+ {t('menu.design', 'Design')}
+
+
{t('menu.security', 'Security')}
-
+
{t('menu.attack_vectors', 'Attack Vectors')}
-
+
{t('menu.challenges', 'Challenges')}
-
+
{t('menu.glossary', 'Glossary')}
-
+
{t('menu.get_support', 'Get Support')}
@@ -104,22 +108,22 @@ function MenuSections() {
{t('menu.developers', 'Developers')}
-
+
{t('menu.getting_started', 'Getting Started')}
-
+
{t('menu.integrations', 'Integrations')}
-
+
{t('menu.running_a_node', 'Running a node')}
-
+
{t('menu.documentation', 'Documentation')}
-
+
{t('menu.protocol', 'Protocol')}
-
+
{t('menu.developer_discussions', 'Developer Discussions')}
@@ -130,10 +134,10 @@ function MenuSections() {
{t('menu.planning', 'Planning 👾')}
-
+
{t('menu.contribution_guide', 'Contribution Guide')}
-
+
{t('menu.communities', 'Communities')}
@@ -154,7 +158,9 @@ function MenuSections() {
{t('menu.topics', 'Topics')}
- {t('menu.privacy', 'Privacy')}
+
+ {t('menu.privacy', 'Privacy')}
+
diff --git a/src/views/pages/doc/doc.js b/src/views/pages/doc/doc.js
index 85a0d58d..095d0406 100644
--- a/src/views/pages/doc/doc.js
+++ b/src/views/pages/doc/doc.js
@@ -1,7 +1,7 @@
/* global REPO */
import React, { useEffect } from 'react'
-import { useParams } from 'react-router-dom'
+import { useParams, useHistory } from 'react-router-dom'
import { renderToString } from 'react-dom/server'
import PropTypes from 'prop-types'
import * as timeago from 'timeago.js'
@@ -65,24 +65,31 @@ md.renderer.rules.heading_open = (tokens, idx) => {
const nextToken = tokens[idx + 1]
const text = nextToken.content
const tag = token.tag
- const escapedText = text.toLowerCase().replace(/[^\w]+/g, '-')
+ const escaped_text = text.toLowerCase().replace(/[^\w]+/g, '-')
- return `<${tag} class="doc__header" id=${escapedText}>`
+ return `<${tag} class="doc__header" id=${escaped_text}>`
}
export default function DocPage({ getDoc, showNotification, doc, location }) {
- const { t } = useTranslation()
- const path = location.pathname.endsWith('/')
- ? location.pathname.slice(0, -1)
- : location.pathname
+ const { t, i18n } = useTranslation()
+ const history = useHistory()
- const { locale } = useParams()
+ let { locale } = useParams()
+ const path = location.pathname.endsWith('/')
+ ? location.pathname.slice(0, -1).replace(`/${locale}`, '')
+ : location.pathname.replace(`/${locale}`, '')
useEffect(() => {
+ if (!locale) {
+ locale = i18n.language
+ history.push(`/${locale}${path}`)
+ } else {
+ i18n.changeLanguage(locale)
+ }
getDoc({ id: path, locale })
- }, [getDoc, path, locale])
+ }, [getDoc, path, locale, i18n])
- const handleClick = (e) => {
+ const handle_click = (e) => {
const event_path = e.composedPath()
const element = event_path.find((p) => p.className === 'doc__header-link')
const anchor = element ? element.dataset.anchor : ''
@@ -102,18 +109,18 @@ export default function DocPage({ getDoc, showNotification, doc, location }) {
const headers = document.querySelectorAll('.doc__header-link')
headers.forEach((header) => {
- header.addEventListener('click', handleClick)
+ header.addEventListener('click', handle_click)
})
return () =>
headers.forEach((header) => {
- header.removeEventListener('click', handleClick)
+ header.removeEventListener('click', handle_click)
})
- }, [location, handleClick])
+ }, [location, handle_click])
const author = doc.getIn(['commit', 'commit', 'author', 'name'])
- const lastUpdated = doc.getIn(['commit', 'commit', 'author', 'date'])
- const commitHref = doc.getIn(['commit', 'html_url'])
+ const last_updated = doc.getIn(['commit', 'commit', 'author', 'date'])
+ const commit_href = doc.getIn(['commit', 'html_url'])
const authors = []
doc.get('authors', []).forEach((author, index) => {
@@ -208,15 +215,15 @@ export default function DocPage({ getDoc, showNotification, doc, location }) {
{Boolean(author) && (
{t('doc.updated_by', 'updated by')}{' '}
-
- {author} {timeago.format(lastUpdated)}
+
+ {author} {timeago.format(last_updated)}
)}