diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 00000000..055fdedd --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,19 @@ +name: Build and Deploy +on: [push] +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2.3.1 + + - name: Install and Build + run: | + npm install + npm run build.js + + - name: Deploy + uses: JamesIves/github-pages-deploy-action@4.1.1 + with: + branch: gh-pages # The branch the action should deploy to. + folder: . # The folder the action should deploy. diff --git a/.gitignore b/.gitignore index 34d52de6..8287e478 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,16 @@ src/**/*.js.map !src/lib/*.js !src/lib/**/*.js src/lib/numbersLab/*.js -debug/ \ No newline at end of file +debug/ + +src/*.js +src/d/*.js +src/lib/numberslab/*.js +src/model/*.js +src/model/blockchain/*.js +src/pages/*.js +src/providers/*.js +src/utils/*.js +src/workers/*.js + +package-lock.json \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..95236b8d --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "api"] + path = api + url = https://github.com/qwertycoin-org/mowallet-api.git diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..3e47c099 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +sudo: false +language: node_js +os: + - linux + - osx +node_js: + - '6' + - '8' + - '10' \ No newline at end of file diff --git a/Deploy.md b/Deploy.md deleted file mode 100644 index 9fe51237..00000000 --- a/Deploy.md +++ /dev/null @@ -1,40 +0,0 @@ -# How to compile & Deploy -The project is using Typescript as main language and not other dependencies on external libraries (everything is already included). - -# Compilation -The first step will be to compile the typescript code into javascript code so browsers will be able to understand it. -You also need to build some files that are dynamically generated like the manifest ... -This task is doable with : -``` -npm install -nodejs ./node_modules/typescript/bin/tsc --project tsconfig.prod.json -nodejs build.js -``` -The first task install dependencies (typescript) and the text one compile the typescript code. -We are using a custom tsconfig file which is optimized for production. - -# Change configuration -You will have to edit the file src/config.js in order to change the API endpoint. -The default value use the same domain appended by /api/ - -That's all - -# Deploy -All the content of the src directory needs to be exposed with a web-server. -You will also need to expose the content of the src_api content to an endpoint which can interpret PHP. -By default the configuration looks at domainname.com/api/ - - -# Permissions -The API stores precomputed data for performances in a directory called cache/ in the same directory of the API code (PHP code). -You will need to create this directory with the write permissions. - -# Cron task / Process -Precomputed data are build by another process. This process will call the Masari daemon and compute blocks into chunks of blocks to reduce network latency. -In order to do so, you will need to run the file blockchain.php with an environment variable "export=true". -This file will shut down after 1h, and has a anti-concurrency mechanism built in. - -One way to handle this is by running a cron task each minute with something like: -``` -* * * * * root cd /var/www/domain.com/api && export generate=true && php blockchain.php -``` \ No newline at end of file diff --git a/README.md b/README.md index b37f7ce6..82b57c2f 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,16 @@ -# Karbo fork of Masari Web Wallet - Fully client-side -This web wallet is doing everything client-side to give the best privacy to users. -The server is currently only used to optimize the communication with the daemon and compress the blockchain. +![image](https://cdn.qwertycoin.org/images/press/other/qwc-github-3.png) +#### Master Build Status +[![Build Status](https://travis-ci.org/qwertycoin-org/webwallet-js.svg?branch=master)](https://travis-ci.org/qwertycoin-org/webwallet-js) [![Build status](https://ci.appveyor.com/api/projects/status/rvsgv9p8wbolxfkt/branch/master?svg=true)](https://ci.appveyor.com/project/Qwertycoin/webwallet-js-iiaw6/branch/master) -Note: This requirement may be removed in the future once daemons evolve and return enough data. +# Qwertycoin Web Wallet - Fully client-side +This web wallet is doing everything client-side to give the best privacy to users. +The API servers are currently only used to optimize the communication with the daemon and compress the blockchain. # Security **No keys, seeds, or sensitive data is sent to the server** If you find a potential security issue, please contact me so we/I can patch it as soon as possible. Encryption is done with a certified library, [Tweetnacl.Js.](https://github.com/dchest/tweetnacl-js) -# Contributors and thanks -Developers: -- gnock (main) -- cryptochangements -- davehlong (initial adaptation of PHP Api for Bytecoin based coins) -- aiwe (adapted for Bytecoin/CryptoNote from Monero codebase) - -Translations: -- English: too many people -- French: gnock -- Serbian cyrillic: girugameshh -- German: F0sching -- Hungarian: Gelesztaa -- Greek: GeraltOfTrivia -- Russian, Ukrainian: Aiwe - -# Contributing -- You can help Masari by translation the wallet in your native language, it's really easy! -Read [the translations guide](TRANSLATIONS.md) to get instructions on how to do that -- Report bugs & ideas to help us improve the web wallet by opening an issue -- [Make a donation to Masari](https://www.masariwallet.com/#!donate) - -# Forks / Other Coins -We have been receiving multiple coin developers help to fork it. As the time required to develop this project is heavy, please consider giving a mention to this project if you fork it. - -If you are a developer of a Cryptonote/Monero fork and would like to get a fork, please contact us (@gnock on the [official Discord](https://discord.gg/eSb9ZdM)). - -Depending on your coin specifics, I can provide support, maintenancem and development/updates for a payment in return - crypto only. -If you are not willing to pay for this service, please do not contact us and make us lose time. - -The code is readable, it should be enough for you to use it. - # Features (non-exhaustive) - Complete wallet sync without server side processing for security - Receive/send history @@ -52,3 +22,82 @@ The code is readable, it should be enough for you to use it. - View only wallet - Basic network stats +# How to compile & Deploy +The project is using Typescript as main language everything else (dependencies) is already included. + +## Compilation +The first step will be to compile the typescript code into javascript code so browsers will be able to understand it. +You also need to build some files that are dynamically generated like the manifest ... +This task is doable with : +``` +npm install +nodejs ./node_modules/typescript/bin/tsc --project tsconfig.json +nodejs build.js +``` +The first task install dependencies (typescript) and the text one compile the typescript code. +We are using a custom tsconfig file which is optimized for production. + +## Deploy +All the content of the src directory needs to be exposed with a web-server. + +## Change configuration +You will have to edit the file src/config.ts in order to change the API endpoint. + +That's all + +### Donate + +``` +QWC: QWC1K6XEhCC1WsZzT9RRVpc1MLXXdHVKt2BUGSrsmkkXAvqh52sVnNc1pYmoF2TEXsAvZnyPaZu8MW3S8EWHNfAh7X2xa63P7Y +``` +``` +BTC: 1DkocMNiqFkbjhCmG4sg9zYQbi4YuguFWw +``` +``` +ETH: 0xA660Fb28C06542258bd740973c17F2632dff2517 +``` +``` +BCH: qz975ndvcechzywtz59xpkt2hhdzkzt3vvt8762yk9 +``` +``` +XMR: 47gmN4GMQ17Veur5YEpru7eCQc5A65DaWUThZa9z9bP6jNMYXPKAyjDcAW4RzNYbRChEwnKu1H3qt9FPW9CnpwZgNscKawX +``` +``` +ETN: etnkJXJFqiH9FCt6Gq2HWHPeY92YFsmvKX7qaysvnV11M796Xmovo2nSu6EUCMnniqRqAhKX9AQp31GbG3M2DiVM3qRDSQ5Vwq +``` + +### Contributors and thanks + +#### Developers: +- gnock (main) +- cryptochangements +- davehlong (initial adaptation of PHP Api for Bytecoin based coins) +- aiwe (adapted for Bytecoin/CryptoNote from Monero codebase) +- nnian, ExploShot (adapted for Qwertycoin codebase) + +#### Translations: +- Chinese: mainframer, [Alex Nnian - Qwertycoin](https://github.com/qwertycoin-org) +- English: too many people +- French: gnock +- German: F0sching, [Alex Nnian - Qwertycoin](https://github.com/qwertycoin-org) +- Greek: GeraltOfTrivia +- Hungarian: Gelesztaa +- Italian: unknown :( +- Japanese: [Alex Nnian - Qwertycoin](https://github.com/qwertycoin-org) +- Korean: [Xecute0101 - Qwertycoin](https://github.com/qwertycoin-org) +- Persian: M4hdi1995 +- Russian: [Aiwe](https://github.com/aivve) +- Serbian cyrillic: girugameshh +- Spanish: [Guerreru](https://github.com/Guerreru) +- Ukrainian: [Aiwe](https://github.com/aivve) + +#### Incomplete Translations: +- [Arabic](https://github.com/qwertycoin-org/webwallet-js/blob/master/src/translations/ar.json) +- [Hebrew](https://github.com/qwertycoin-org/webwallet-js/blob/master/src/translations/he.json) +- [Hindi](https://github.com/qwertycoin-org/webwallet-js/blob/master/src/translations/hi.json) +- [Polish](https://github.com/qwertycoin-org/webwallet-js/blob/master/src/translations/pl.json) +- [Portuguese](https://github.com/qwertycoin-org/webwallet-js/blob/master/src/translations/pk.json) +- [Romanian](https://github.com/qwertycoin-org/webwallet-js/blob/master/src/translations/ro.json) +- [Turkish](https://github.com/qwertycoin-org/webwallet-js/blob/master/src/translations/tr.json) +- [Urdu](https://github.com/qwertycoin-org/webwallet-js/blob/master/src/translations/pk.json) +- [Vietnamese ](https://github.com/qwertycoin-org/webwallet-js/blob/master/src/translations/vn.json) diff --git a/TRANSLATIONS.md b/TRANSLATIONS.md deleted file mode 100644 index d3eb767f..00000000 --- a/TRANSLATIONS.md +++ /dev/null @@ -1,19 +0,0 @@ -# Translating the web wallet -You can help Masari by translating the wallet into your native language, it's very easy! - -# Steps -- Copy/paste the content of [the english translation](src/translations/en.json) in a text editor (Notepad, Word, etc.) -- Translate the parts between quotes that are always after ":" -For example, if you have this: -``` -"disableSecurity":"Disable this security, I understand the risk", -``` -- You need to translate: -``` -Disable this security, I understand the risk -``` -- If you need to use double quotes (") in your text, please put a \ before it. - -# Submitting translations -- Send us your translation by opening an [issue](https://github.com/masari-project/masari-webwallet/issues) on Github or sending it to us directly on the [official Discord](https://discord.gg/eSb9ZdM) -- You can also fork your own repo and make changes, then submit a Pull Request \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..1ba60c49 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,12 @@ +environment: + nodejs_version: "8" + +# Install scripts. (runs after repo cloning) +install: + # Get the latest stable version of Node.js or io.js + - ps: Install-Product node $env:nodejs_version + # install modules + - npm install + - npm test + +build: off diff --git a/debug-router.php b/debug-router.php deleted file mode 100644 index f97863c1..00000000 --- a/debug-router.php +++ /dev/null @@ -1,30 +0,0 @@ - - Karbo API + Qwertycoin API -

Karbo Wallet API relay

+

Qwertycoin Wallet API relay

diff --git a/src/api.ts b/src/api.ts index 49fa4afb..c818edd2 100644 --- a/src/api.ts +++ b/src/api.ts @@ -23,7 +23,7 @@ function sendMessageToParent(type : string, data : any){ } window.addEventListener('message', function(e : MessageEvent){ - console.log(e); + //console.log(e); if(e.data == 'hasWallet'){ sendMessageToParent('hasWallet', WalletRepository.hasOneStored()); } diff --git a/src/assets/css/bootstrap-grid.css b/src/assets/css/bootstrap-grid.css new file mode 100644 index 00000000..5a71a41a --- /dev/null +++ b/src/assets/css/bootstrap-grid.css @@ -0,0 +1,2050 @@ +/*! + * Bootstrap Grid v4.0.0 (https://getbootstrap.com) + * Copyright 2011-2018 The Bootstrap Authors + * Copyright 2011-2018 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +@-ms-viewport { + width: device-width; +} + +html { + box-sizing: border-box; + -ms-overflow-style: scrollbar; +} + +*, +*::before, +*::after { + box-sizing: inherit; +} + +.container { + width: 100%; + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} + +@media (min-width: 576px) { + .container { + max-width: 540px; + } +} + +@media (min-width: 768px) { + .container { + max-width: 720px; + } +} + +@media (min-width: 992px) { + .container { + max-width: 960px; + } +} + +@media (min-width: 1200px) { + .container { + max-width: 1140px; + } +} + +.container-fluid { + width: 100%; + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} + +.row { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin-right: -15px; + margin-left: -15px; +} + +.no-gutters { + margin-right: 0; + margin-left: 0; +} + +.no-gutters > .col, +.no-gutters > [class*="col-"] { + padding-right: 0; + padding-left: 0; +} + +.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col, +.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm, +.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md, +.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg, +.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl, +.col-xl-auto { + position: relative; + width: 100%; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} + +.col { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; +} + +.col-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; +} + +.col-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; +} + +.col-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; +} + +.col-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; +} + +.col-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; +} + +.col-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; +} + +.col-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; +} + +.col-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; +} + +.col-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; +} + +.col-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; +} + +.col-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; +} + +.col-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; +} + +.col-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; +} + +.order-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; +} + +.order-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; +} + +.order-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; +} + +.order-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; +} + +.order-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; +} + +.order-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; +} + +.order-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; +} + +.order-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; +} + +.order-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; +} + +.order-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; +} + +.order-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; +} + +.order-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; +} + +.order-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; +} + +.order-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; +} + +.order-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; +} + +.offset-1 { + margin-left: 8.333333%; +} + +.offset-2 { + margin-left: 16.666667%; +} + +.offset-3 { + margin-left: 25%; +} + +.offset-4 { + margin-left: 33.333333%; +} + +.offset-5 { + margin-left: 41.666667%; +} + +.offset-6 { + margin-left: 50%; +} + +.offset-7 { + margin-left: 58.333333%; +} + +.offset-8 { + margin-left: 66.666667%; +} + +.offset-9 { + margin-left: 75%; +} + +.offset-10 { + margin-left: 83.333333%; +} + +.offset-11 { + margin-left: 91.666667%; +} + +@media (min-width: 576px) { + .col-sm { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + .col-sm-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + .col-sm-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; + } + .col-sm-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-sm-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .col-sm-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .col-sm-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; + } + .col-sm-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .col-sm-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; + } + .col-sm-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; + } + .col-sm-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + .col-sm-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; + } + .col-sm-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; + } + .col-sm-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + .order-sm-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; + } + .order-sm-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; + } + .order-sm-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; + } + .order-sm-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + } + .order-sm-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; + } + .order-sm-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; + } + .order-sm-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; + } + .order-sm-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; + } + .order-sm-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; + } + .order-sm-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; + } + .order-sm-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; + } + .order-sm-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; + } + .order-sm-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; + } + .order-sm-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; + } + .order-sm-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; + } + .offset-sm-0 { + margin-left: 0; + } + .offset-sm-1 { + margin-left: 8.333333%; + } + .offset-sm-2 { + margin-left: 16.666667%; + } + .offset-sm-3 { + margin-left: 25%; + } + .offset-sm-4 { + margin-left: 33.333333%; + } + .offset-sm-5 { + margin-left: 41.666667%; + } + .offset-sm-6 { + margin-left: 50%; + } + .offset-sm-7 { + margin-left: 58.333333%; + } + .offset-sm-8 { + margin-left: 66.666667%; + } + .offset-sm-9 { + margin-left: 75%; + } + .offset-sm-10 { + margin-left: 83.333333%; + } + .offset-sm-11 { + margin-left: 91.666667%; + } +} + +@media (min-width: 768px) { + .col-md { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + .col-md-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + .col-md-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; + } + .col-md-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-md-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .col-md-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .col-md-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; + } + .col-md-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .col-md-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; + } + .col-md-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; + } + .col-md-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + .col-md-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; + } + .col-md-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; + } + .col-md-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + .order-md-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; + } + .order-md-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; + } + .order-md-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; + } + .order-md-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + } + .order-md-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; + } + .order-md-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; + } + .order-md-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; + } + .order-md-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; + } + .order-md-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; + } + .order-md-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; + } + .order-md-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; + } + .order-md-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; + } + .order-md-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; + } + .order-md-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; + } + .order-md-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; + } + .offset-md-0 { + margin-left: 0; + } + .offset-md-1 { + margin-left: 8.333333%; + } + .offset-md-2 { + margin-left: 16.666667%; + } + .offset-md-3 { + margin-left: 25%; + } + .offset-md-4 { + margin-left: 33.333333%; + } + .offset-md-5 { + margin-left: 41.666667%; + } + .offset-md-6 { + margin-left: 50%; + } + .offset-md-7 { + margin-left: 58.333333%; + } + .offset-md-8 { + margin-left: 66.666667%; + } + .offset-md-9 { + margin-left: 75%; + } + .offset-md-10 { + margin-left: 83.333333%; + } + .offset-md-11 { + margin-left: 91.666667%; + } +} + +@media (min-width: 992px) { + .col-lg { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + .col-lg-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + .col-lg-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; + } + .col-lg-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-lg-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .col-lg-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .col-lg-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; + } + .col-lg-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .col-lg-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; + } + .col-lg-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; + } + .col-lg-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + .col-lg-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; + } + .col-lg-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; + } + .col-lg-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + .order-lg-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; + } + .order-lg-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; + } + .order-lg-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; + } + .order-lg-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + } + .order-lg-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; + } + .order-lg-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; + } + .order-lg-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; + } + .order-lg-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; + } + .order-lg-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; + } + .order-lg-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; + } + .order-lg-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; + } + .order-lg-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; + } + .order-lg-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; + } + .order-lg-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; + } + .order-lg-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; + } + .offset-lg-0 { + margin-left: 0; + } + .offset-lg-1 { + margin-left: 8.333333%; + } + .offset-lg-2 { + margin-left: 16.666667%; + } + .offset-lg-3 { + margin-left: 25%; + } + .offset-lg-4 { + margin-left: 33.333333%; + } + .offset-lg-5 { + margin-left: 41.666667%; + } + .offset-lg-6 { + margin-left: 50%; + } + .offset-lg-7 { + margin-left: 58.333333%; + } + .offset-lg-8 { + margin-left: 66.666667%; + } + .offset-lg-9 { + margin-left: 75%; + } + .offset-lg-10 { + margin-left: 83.333333%; + } + .offset-lg-11 { + margin-left: 91.666667%; + } +} + +@media (min-width: 1200px) { + .col-xl { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + .col-xl-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + .col-xl-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; + } + .col-xl-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-xl-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .col-xl-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .col-xl-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; + } + .col-xl-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .col-xl-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; + } + .col-xl-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; + } + .col-xl-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + .col-xl-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; + } + .col-xl-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; + } + .col-xl-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + .order-xl-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; + } + .order-xl-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; + } + .order-xl-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; + } + .order-xl-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + } + .order-xl-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; + } + .order-xl-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; + } + .order-xl-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; + } + .order-xl-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; + } + .order-xl-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; + } + .order-xl-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; + } + .order-xl-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; + } + .order-xl-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; + } + .order-xl-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; + } + .order-xl-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; + } + .order-xl-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; + } + .offset-xl-0 { + margin-left: 0; + } + .offset-xl-1 { + margin-left: 8.333333%; + } + .offset-xl-2 { + margin-left: 16.666667%; + } + .offset-xl-3 { + margin-left: 25%; + } + .offset-xl-4 { + margin-left: 33.333333%; + } + .offset-xl-5 { + margin-left: 41.666667%; + } + .offset-xl-6 { + margin-left: 50%; + } + .offset-xl-7 { + margin-left: 58.333333%; + } + .offset-xl-8 { + margin-left: 66.666667%; + } + .offset-xl-9 { + margin-left: 75%; + } + .offset-xl-10 { + margin-left: 83.333333%; + } + .offset-xl-11 { + margin-left: 91.666667%; + } +} + +.d-none { + display: none !important; +} + +.d-inline { + display: inline !important; +} + +.d-inline-block { + display: inline-block !important; +} + +.d-block { + display: block !important; +} + +.d-table { + display: table !important; +} + +.d-table-row { + display: table-row !important; +} + +.d-table-cell { + display: table-cell !important; +} + +.d-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; +} + +.d-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; +} + +@media (min-width: 576px) { + .d-sm-none { + display: none !important; + } + .d-sm-inline { + display: inline !important; + } + .d-sm-inline-block { + display: inline-block !important; + } + .d-sm-block { + display: block !important; + } + .d-sm-table { + display: table !important; + } + .d-sm-table-row { + display: table-row !important; + } + .d-sm-table-cell { + display: table-cell !important; + } + .d-sm-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + .d-sm-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} + +@media (min-width: 768px) { + .d-md-none { + display: none !important; + } + .d-md-inline { + display: inline !important; + } + .d-md-inline-block { + display: inline-block !important; + } + .d-md-block { + display: block !important; + } + .d-md-table { + display: table !important; + } + .d-md-table-row { + display: table-row !important; + } + .d-md-table-cell { + display: table-cell !important; + } + .d-md-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + .d-md-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} + +@media (min-width: 992px) { + .d-lg-none { + display: none !important; + } + .d-lg-inline { + display: inline !important; + } + .d-lg-inline-block { + display: inline-block !important; + } + .d-lg-block { + display: block !important; + } + .d-lg-table { + display: table !important; + } + .d-lg-table-row { + display: table-row !important; + } + .d-lg-table-cell { + display: table-cell !important; + } + .d-lg-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + .d-lg-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} + +@media (min-width: 1200px) { + .d-xl-none { + display: none !important; + } + .d-xl-inline { + display: inline !important; + } + .d-xl-inline-block { + display: inline-block !important; + } + .d-xl-block { + display: block !important; + } + .d-xl-table { + display: table !important; + } + .d-xl-table-row { + display: table-row !important; + } + .d-xl-table-cell { + display: table-cell !important; + } + .d-xl-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + .d-xl-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} + +@media print { + .d-print-none { + display: none !important; + } + .d-print-inline { + display: inline !important; + } + .d-print-inline-block { + display: inline-block !important; + } + .d-print-block { + display: block !important; + } + .d-print-table { + display: table !important; + } + .d-print-table-row { + display: table-row !important; + } + .d-print-table-cell { + display: table-cell !important; + } + .d-print-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + .d-print-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} + +.flex-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; +} + +.flex-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; +} + +.flex-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; +} + +.flex-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; +} + +.flex-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; +} + +.flex-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; +} + +.flex-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; +} + +.justify-content-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; +} + +.justify-content-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; +} + +.justify-content-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; +} + +.justify-content-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; +} + +.justify-content-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; +} + +.align-items-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; +} + +.align-items-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; +} + +.align-items-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; +} + +.align-items-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; +} + +.align-items-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; +} + +.align-content-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; +} + +.align-content-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; +} + +.align-content-center { + -ms-flex-line-pack: center !important; + align-content: center !important; +} + +.align-content-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; +} + +.align-content-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; +} + +.align-content-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; +} + +.align-self-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; +} + +.align-self-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; +} + +.align-self-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; +} + +.align-self-center { + -ms-flex-item-align: center !important; + align-self: center !important; +} + +.align-self-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; +} + +.align-self-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; +} + +@media (min-width: 576px) { + .flex-sm-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; + } + .flex-sm-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; + } + .flex-sm-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + .flex-sm-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + .flex-sm-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + .flex-sm-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + .flex-sm-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + .justify-content-sm-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + .justify-content-sm-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + .justify-content-sm-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; + } + .justify-content-sm-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + .justify-content-sm-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + .align-items-sm-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; + } + .align-items-sm-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; + } + .align-items-sm-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; + } + .align-items-sm-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + .align-items-sm-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + .align-content-sm-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + .align-content-sm-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + .align-content-sm-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + .align-content-sm-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + .align-content-sm-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + .align-content-sm-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + .align-self-sm-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + .align-self-sm-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + .align-self-sm-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + .align-self-sm-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + .align-self-sm-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + .align-self-sm-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} + +@media (min-width: 768px) { + .flex-md-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; + } + .flex-md-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; + } + .flex-md-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + .flex-md-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + .flex-md-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + .flex-md-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + .flex-md-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + .justify-content-md-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + .justify-content-md-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + .justify-content-md-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; + } + .justify-content-md-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + .justify-content-md-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + .align-items-md-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; + } + .align-items-md-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; + } + .align-items-md-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; + } + .align-items-md-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + .align-items-md-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + .align-content-md-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + .align-content-md-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + .align-content-md-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + .align-content-md-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + .align-content-md-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + .align-content-md-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + .align-self-md-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + .align-self-md-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + .align-self-md-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + .align-self-md-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + .align-self-md-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + .align-self-md-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} + +@media (min-width: 992px) { + .flex-lg-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; + } + .flex-lg-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; + } + .flex-lg-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + .flex-lg-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + .flex-lg-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + .flex-lg-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + .flex-lg-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + .justify-content-lg-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + .justify-content-lg-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + .justify-content-lg-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; + } + .justify-content-lg-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + .justify-content-lg-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + .align-items-lg-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; + } + .align-items-lg-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; + } + .align-items-lg-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; + } + .align-items-lg-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + .align-items-lg-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + .align-content-lg-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + .align-content-lg-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + .align-content-lg-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + .align-content-lg-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + .align-content-lg-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + .align-content-lg-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + .align-self-lg-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + .align-self-lg-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + .align-self-lg-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + .align-self-lg-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + .align-self-lg-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + .align-self-lg-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} + +@media (min-width: 1200px) { + .flex-xl-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; + } + .flex-xl-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; + } + .flex-xl-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + .flex-xl-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + .flex-xl-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + .flex-xl-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + .flex-xl-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + .justify-content-xl-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + .justify-content-xl-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + .justify-content-xl-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; + } + .justify-content-xl-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + .justify-content-xl-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + .align-items-xl-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; + } + .align-items-xl-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; + } + .align-items-xl-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; + } + .align-items-xl-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + .align-items-xl-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + .align-content-xl-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + .align-content-xl-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + .align-content-xl-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + .align-content-xl-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + .align-content-xl-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + .align-content-xl-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + .align-self-xl-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + .align-self-xl-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + .align-self-xl-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + .align-self-xl-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + .align-self-xl-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + .align-self-xl-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} +/*# sourceMappingURL=bootstrap-grid.css.map */ \ No newline at end of file diff --git a/src/assets/css/bootstrap-reboot.css b/src/assets/css/bootstrap-reboot.css new file mode 100644 index 00000000..5a75a62b --- /dev/null +++ b/src/assets/css/bootstrap-reboot.css @@ -0,0 +1,330 @@ +/*! + * Bootstrap Reboot v4.0.0 (https://getbootstrap.com) + * Copyright 2011-2018 The Bootstrap Authors + * Copyright 2011-2018 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) + */ +*, +*::before, +*::after { + box-sizing: border-box; +} + +html { + font-family: sans-serif; + line-height: 1.15; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + -ms-overflow-style: scrollbar; + -webkit-tap-highlight-color: transparent; +} + +@-ms-viewport { + width: device-width; +} + +article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section { + display: block; +} + +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + text-align: left; + background-color: #fff; +} + +[tabindex="-1"]:focus { + outline: 0 !important; +} + +hr { + box-sizing: content-box; + height: 0; + overflow: visible; +} + +h1, h2, h3, h4, h5, h6 { + margin-top: 0; + margin-bottom: 0.5rem; +} + +p { + margin-top: 0; + margin-bottom: 1rem; +} + +abbr[title], +abbr[data-original-title] { + text-decoration: underline; + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + cursor: help; + border-bottom: 0; +} + +address { + margin-bottom: 1rem; + font-style: normal; + line-height: inherit; +} + +ol, +ul, +dl { + margin-top: 0; + margin-bottom: 1rem; +} + +ol ol, +ul ul, +ol ul, +ul ol { + margin-bottom: 0; +} + +dt { + font-weight: 700; +} + +dd { + margin-bottom: .5rem; + margin-left: 0; +} + +blockquote { + margin: 0 0 1rem; +} + +dfn { + font-style: italic; +} + +b, +strong { + font-weight: bolder; +} + +small { + font-size: 80%; +} + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} + +sub { + bottom: -.25em; +} + +sup { + top: -.5em; +} + +a { + color: #007bff; + text-decoration: none; + background-color: transparent; + -webkit-text-decoration-skip: objects; +} + +a:hover { + color: #0056b3; + text-decoration: underline; +} + +a:not([href]):not([tabindex]) { + color: inherit; + text-decoration: none; +} + +a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus { + color: inherit; + text-decoration: none; +} + +a:not([href]):not([tabindex]):focus { + outline: 0; +} + +pre, +code, +kbd, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +pre { + margin-top: 0; + margin-bottom: 1rem; + overflow: auto; + -ms-overflow-style: scrollbar; +} + +figure { + margin: 0 0 1rem; +} + +img { + vertical-align: middle; + border-style: none; +} + +svg:not(:root) { + overflow: hidden; +} + +table { + border-collapse: collapse; +} + +caption { + padding-top: 0.75rem; + padding-bottom: 0.75rem; + color: #6c757d; + text-align: left; + caption-side: bottom; +} + +th { + text-align: inherit; +} + +label { + display: inline-block; + margin-bottom: .5rem; +} + +button { + border-radius: 0; +} + +button:focus { + outline: 1px dotted; + outline: 5px auto -webkit-focus-ring-color; +} + +input, +button, +select, +optgroup, +textarea { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +button, +input { + overflow: visible; +} + +button, +select { + text-transform: none; +} + +button, +html [type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + padding: 0; + border-style: none; +} + +input[type="radio"], +input[type="checkbox"] { + box-sizing: border-box; + padding: 0; +} + +input[type="date"], +input[type="time"], +input[type="datetime-local"], +input[type="month"] { + -webkit-appearance: listbox; +} + +textarea { + overflow: auto; + resize: vertical; +} + +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} + +legend { + display: block; + width: 100%; + max-width: 100%; + padding: 0; + margin-bottom: .5rem; + font-size: 1.5rem; + line-height: inherit; + color: inherit; + white-space: normal; +} + +progress { + vertical-align: baseline; +} + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +[type="search"] { + outline-offset: -2px; + -webkit-appearance: none; +} + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +::-webkit-file-upload-button { + font: inherit; + -webkit-appearance: button; +} + +output { + display: inline-block; +} + +summary { + display: list-item; + cursor: pointer; +} + +template { + display: none; +} + +[hidden] { + display: none !important; +} +/*# sourceMappingURL=bootstrap-reboot.css.map */ \ No newline at end of file diff --git a/src/assets/css/bootstrap.css b/src/assets/css/bootstrap.css new file mode 100644 index 00000000..aa497136 --- /dev/null +++ b/src/assets/css/bootstrap.css @@ -0,0 +1,8975 @@ +/*! + * Bootstrap v4.0.0 (https://getbootstrap.com) + * Copyright 2011-2018 The Bootstrap Authors + * Copyright 2011-2018 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +:root { + --blue: #007bff; + --indigo: #6610f2; + --purple: #6f42c1; + --pink: #e83e8c; + --red: #dc3545; + --orange: #fd7e14; + --yellow: #ffc107; + --green: #28a745; + --teal: #20c997; + --cyan: #17a2b8; + --white: #fff; + --gray: #6c757d; + --gray-dark: #343a40; + --primary: #007bff; + --secondary: #6c757d; + --success: #28a745; + --info: #17a2b8; + --warning: #ffc107; + --danger: #dc3545; + --light: #f8f9fa; + --dark: #343a40; + --breakpoint-xs: 0; + --breakpoint-sm: 576px; + --breakpoint-md: 768px; + --breakpoint-lg: 992px; + --breakpoint-xl: 1200px; + --font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +} + +*, +*::before, +*::after { + box-sizing: border-box; +} + +html { + font-family: sans-serif; + line-height: 1.15; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + -ms-overflow-style: scrollbar; + -webkit-tap-highlight-color: transparent; +} + +@-ms-viewport { + width: device-width; +} + +article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section { + display: block; +} + +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + text-align: left; + background-color: #fff; +} + +[tabindex="-1"]:focus { + outline: 0 !important; +} + +hr { + box-sizing: content-box; + height: 0; + overflow: visible; +} + +h1, h2, h3, h4, h5, h6 { + margin-top: 0; + margin-bottom: 0.5rem; +} + +p { + margin-top: 0; + margin-bottom: 1rem; +} + +abbr[title], +abbr[data-original-title] { + text-decoration: underline; + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + cursor: help; + border-bottom: 0; +} + +address { + margin-bottom: 1rem; + font-style: normal; + line-height: inherit; +} + +ol, +ul, +dl { + margin-top: 0; + margin-bottom: 1rem; +} + +ol ol, +ul ul, +ol ul, +ul ol { + margin-bottom: 0; +} + +dt { + font-weight: 700; +} + +dd { + margin-bottom: .5rem; + margin-left: 0; +} + +blockquote { + margin: 0 0 1rem; +} + +dfn { + font-style: italic; +} + +b, +strong { + font-weight: bolder; +} + +small { + font-size: 80%; +} + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} + +sub { + bottom: -.25em; +} + +sup { + top: -.5em; +} + +a { + color: #007bff; + text-decoration: none; + background-color: transparent; + -webkit-text-decoration-skip: objects; +} + +a:hover { + color: #0056b3; + text-decoration: underline; +} + +a:not([href]):not([tabindex]) { + color: inherit; + text-decoration: none; +} + +a:not([href]):not([tabindex]):hover, a:not([href]):not([tabindex]):focus { + color: inherit; + text-decoration: none; +} + +a:not([href]):not([tabindex]):focus { + outline: 0; +} + +pre, +code, +kbd, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +pre { + margin-top: 0; + margin-bottom: 1rem; + overflow: auto; + -ms-overflow-style: scrollbar; +} + +figure { + margin: 0 0 1rem; +} + +img { + vertical-align: middle; + border-style: none; +} + +svg:not(:root) { + overflow: hidden; +} + +table { + border-collapse: collapse; +} + +caption { + padding-top: 0.75rem; + padding-bottom: 0.75rem; + color: #6c757d; + text-align: left; + caption-side: bottom; +} + +th { + text-align: inherit; +} + +label { + display: inline-block; + margin-bottom: .5rem; +} + +button { + border-radius: 0; +} + +button:focus { + outline: 1px dotted; + outline: 5px auto -webkit-focus-ring-color; +} + +input, +button, +select, +optgroup, +textarea { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; +} + +button, +input { + overflow: visible; +} + +button, +select { + text-transform: none; +} + +button, +html [type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + padding: 0; + border-style: none; +} + +input[type="radio"], +input[type="checkbox"] { + box-sizing: border-box; + padding: 0; +} + +input[type="date"], +input[type="time"], +input[type="datetime-local"], +input[type="month"] { + -webkit-appearance: listbox; +} + +textarea { + overflow: auto; + resize: vertical; +} + +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} + +legend { + display: block; + width: 100%; + max-width: 100%; + padding: 0; + margin-bottom: .5rem; + font-size: 1.5rem; + line-height: inherit; + color: inherit; + white-space: normal; +} + +progress { + vertical-align: baseline; +} + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +[type="search"] { + outline-offset: -2px; + -webkit-appearance: none; +} + +[type="search"]::-webkit-search-cancel-button, +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +::-webkit-file-upload-button { + font: inherit; + -webkit-appearance: button; +} + +output { + display: inline-block; +} + +summary { + display: list-item; + cursor: pointer; +} + +template { + display: none; +} + +[hidden] { + display: none !important; +} + +h1, h2, h3, h4, h5, h6, +.h1, .h2, .h3, .h4, .h5, .h6 { + margin-bottom: 0.5rem; + font-family: inherit; + font-weight: 500; + line-height: 1.2; + color: inherit; +} + +h1, .h1 { + font-size: 2.5rem; +} + +h2, .h2 { + font-size: 2rem; +} + +h3, .h3 { + font-size: 1.75rem; +} + +h4, .h4 { + font-size: 1.5rem; +} + +h5, .h5 { + font-size: 1.25rem; +} + +h6, .h6 { + font-size: 1rem; +} + +.lead { + font-size: 1.25rem; + font-weight: 300; +} + +.display-1 { + font-size: 6rem; + font-weight: 300; + line-height: 1.2; +} + +.display-2 { + font-size: 5.5rem; + font-weight: 300; + line-height: 1.2; +} + +.display-3 { + font-size: 4.5rem; + font-weight: 300; + line-height: 1.2; +} + +.display-4 { + font-size: 3.5rem; + font-weight: 300; + line-height: 1.2; +} + +hr { + margin-top: 1rem; + margin-bottom: 1rem; + border: 0; + border-top: 1px solid rgba(0, 0, 0, 0.1); +} + +small, +.small { + font-size: 80%; + font-weight: 400; +} + +mark, +.mark { + padding: 0.2em; + background-color: #fcf8e3; +} + +.list-unstyled { + padding-left: 0; + list-style: none; +} + +.list-inline { + padding-left: 0; + list-style: none; +} + +.list-inline-item { + display: inline-block; +} + +.list-inline-item:not(:last-child) { + margin-right: 0.5rem; +} + +.initialism { + font-size: 90%; + text-transform: uppercase; +} + +.blockquote { + margin-bottom: 1rem; + font-size: 1.25rem; +} + +.blockquote-footer { + display: block; + font-size: 80%; + color: #6c757d; +} + +.blockquote-footer::before { + content: "\2014 \00A0"; +} + +.img-fluid { + max-width: 100%; + height: auto; +} + +.img-thumbnail { + padding: 0.25rem; + background-color: #fff; + border: 1px solid #dee2e6; + border-radius: 0.25rem; + max-width: 100%; + height: auto; +} + +.figure { + display: inline-block; +} + +.figure-img { + margin-bottom: 0.5rem; + line-height: 1; +} + +.figure-caption { + font-size: 90%; + color: #6c757d; +} + +code, +kbd, +pre, +samp { + font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; +} + +code { + font-size: 87.5%; + color: #e83e8c; + word-break: break-word; +} + +a > code { + color: inherit; +} + +kbd { + padding: 0.2rem 0.4rem; + font-size: 87.5%; + color: #fff; + background-color: #212529; + border-radius: 0.2rem; +} + +kbd kbd { + padding: 0; + font-size: 100%; + font-weight: 700; +} + +pre { + display: block; + font-size: 87.5%; + color: #212529; +} + +pre code { + font-size: inherit; + color: inherit; + word-break: normal; +} + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} + +.container { + width: 100%; + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} + +@media (min-width: 576px) { + .container { + max-width: 540px; + } +} + +@media (min-width: 768px) { + .container { + max-width: 720px; + } +} + +@media (min-width: 992px) { + .container { + max-width: 960px; + } +} + +@media (min-width: 1200px) { + .container { + max-width: 1140px; + } +} + +.container-fluid { + width: 100%; + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} + +.row { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin-right: -15px; + margin-left: -15px; +} + +.no-gutters { + margin-right: 0; + margin-left: 0; +} + +.no-gutters > .col, +.no-gutters > [class*="col-"] { + padding-right: 0; + padding-left: 0; +} + +.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col, +.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm, +.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md, +.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg, +.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl, +.col-xl-auto { + position: relative; + width: 100%; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} + +.col { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; +} + +.col-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; +} + +.col-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; +} + +.col-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; +} + +.col-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; +} + +.col-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; +} + +.col-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; +} + +.col-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; +} + +.col-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; +} + +.col-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; +} + +.col-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; +} + +.col-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; +} + +.col-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; +} + +.col-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; +} + +.order-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; +} + +.order-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; +} + +.order-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; +} + +.order-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; +} + +.order-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; +} + +.order-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; +} + +.order-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; +} + +.order-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; +} + +.order-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; +} + +.order-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; +} + +.order-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; +} + +.order-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; +} + +.order-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; +} + +.order-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; +} + +.order-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; +} + +.offset-1 { + margin-left: 8.333333%; +} + +.offset-2 { + margin-left: 16.666667%; +} + +.offset-3 { + margin-left: 25%; +} + +.offset-4 { + margin-left: 33.333333%; +} + +.offset-5 { + margin-left: 41.666667%; +} + +.offset-6 { + margin-left: 50%; +} + +.offset-7 { + margin-left: 58.333333%; +} + +.offset-8 { + margin-left: 66.666667%; +} + +.offset-9 { + margin-left: 75%; +} + +.offset-10 { + margin-left: 83.333333%; +} + +.offset-11 { + margin-left: 91.666667%; +} + +@media (min-width: 576px) { + .col-sm { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + .col-sm-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + .col-sm-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; + } + .col-sm-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-sm-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .col-sm-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .col-sm-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; + } + .col-sm-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .col-sm-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; + } + .col-sm-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; + } + .col-sm-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + .col-sm-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; + } + .col-sm-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; + } + .col-sm-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + .order-sm-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; + } + .order-sm-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; + } + .order-sm-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; + } + .order-sm-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + } + .order-sm-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; + } + .order-sm-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; + } + .order-sm-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; + } + .order-sm-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; + } + .order-sm-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; + } + .order-sm-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; + } + .order-sm-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; + } + .order-sm-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; + } + .order-sm-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; + } + .order-sm-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; + } + .order-sm-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; + } + .offset-sm-0 { + margin-left: 0; + } + .offset-sm-1 { + margin-left: 8.333333%; + } + .offset-sm-2 { + margin-left: 16.666667%; + } + .offset-sm-3 { + margin-left: 25%; + } + .offset-sm-4 { + margin-left: 33.333333%; + } + .offset-sm-5 { + margin-left: 41.666667%; + } + .offset-sm-6 { + margin-left: 50%; + } + .offset-sm-7 { + margin-left: 58.333333%; + } + .offset-sm-8 { + margin-left: 66.666667%; + } + .offset-sm-9 { + margin-left: 75%; + } + .offset-sm-10 { + margin-left: 83.333333%; + } + .offset-sm-11 { + margin-left: 91.666667%; + } +} + +@media (min-width: 768px) { + .col-md { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + .col-md-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + .col-md-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; + } + .col-md-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-md-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .col-md-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .col-md-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; + } + .col-md-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .col-md-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; + } + .col-md-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; + } + .col-md-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + .col-md-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; + } + .col-md-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; + } + .col-md-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + .order-md-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; + } + .order-md-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; + } + .order-md-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; + } + .order-md-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + } + .order-md-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; + } + .order-md-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; + } + .order-md-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; + } + .order-md-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; + } + .order-md-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; + } + .order-md-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; + } + .order-md-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; + } + .order-md-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; + } + .order-md-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; + } + .order-md-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; + } + .order-md-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; + } + .offset-md-0 { + margin-left: 0; + } + .offset-md-1 { + margin-left: 8.333333%; + } + .offset-md-2 { + margin-left: 16.666667%; + } + .offset-md-3 { + margin-left: 25%; + } + .offset-md-4 { + margin-left: 33.333333%; + } + .offset-md-5 { + margin-left: 41.666667%; + } + .offset-md-6 { + margin-left: 50%; + } + .offset-md-7 { + margin-left: 58.333333%; + } + .offset-md-8 { + margin-left: 66.666667%; + } + .offset-md-9 { + margin-left: 75%; + } + .offset-md-10 { + margin-left: 83.333333%; + } + .offset-md-11 { + margin-left: 91.666667%; + } +} + +@media (min-width: 992px) { + .col-lg { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + .col-lg-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + .col-lg-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; + } + .col-lg-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-lg-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .col-lg-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .col-lg-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; + } + .col-lg-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .col-lg-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; + } + .col-lg-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; + } + .col-lg-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + .col-lg-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; + } + .col-lg-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; + } + .col-lg-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + .order-lg-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; + } + .order-lg-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; + } + .order-lg-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; + } + .order-lg-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + } + .order-lg-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; + } + .order-lg-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; + } + .order-lg-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; + } + .order-lg-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; + } + .order-lg-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; + } + .order-lg-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; + } + .order-lg-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; + } + .order-lg-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; + } + .order-lg-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; + } + .order-lg-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; + } + .order-lg-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; + } + .offset-lg-0 { + margin-left: 0; + } + .offset-lg-1 { + margin-left: 8.333333%; + } + .offset-lg-2 { + margin-left: 16.666667%; + } + .offset-lg-3 { + margin-left: 25%; + } + .offset-lg-4 { + margin-left: 33.333333%; + } + .offset-lg-5 { + margin-left: 41.666667%; + } + .offset-lg-6 { + margin-left: 50%; + } + .offset-lg-7 { + margin-left: 58.333333%; + } + .offset-lg-8 { + margin-left: 66.666667%; + } + .offset-lg-9 { + margin-left: 75%; + } + .offset-lg-10 { + margin-left: 83.333333%; + } + .offset-lg-11 { + margin-left: 91.666667%; + } +} + +@media (min-width: 1200px) { + .col-xl { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + .col-xl-auto { + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: none; + } + .col-xl-1 { + -webkit-box-flex: 0; + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; + } + .col-xl-2 { + -webkit-box-flex: 0; + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-xl-3 { + -webkit-box-flex: 0; + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .col-xl-4 { + -webkit-box-flex: 0; + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .col-xl-5 { + -webkit-box-flex: 0; + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; + } + .col-xl-6 { + -webkit-box-flex: 0; + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .col-xl-7 { + -webkit-box-flex: 0; + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; + } + .col-xl-8 { + -webkit-box-flex: 0; + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; + } + .col-xl-9 { + -webkit-box-flex: 0; + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + .col-xl-10 { + -webkit-box-flex: 0; + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; + } + .col-xl-11 { + -webkit-box-flex: 0; + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; + } + .col-xl-12 { + -webkit-box-flex: 0; + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + .order-xl-first { + -webkit-box-ordinal-group: 0; + -ms-flex-order: -1; + order: -1; + } + .order-xl-last { + -webkit-box-ordinal-group: 14; + -ms-flex-order: 13; + order: 13; + } + .order-xl-0 { + -webkit-box-ordinal-group: 1; + -ms-flex-order: 0; + order: 0; + } + .order-xl-1 { + -webkit-box-ordinal-group: 2; + -ms-flex-order: 1; + order: 1; + } + .order-xl-2 { + -webkit-box-ordinal-group: 3; + -ms-flex-order: 2; + order: 2; + } + .order-xl-3 { + -webkit-box-ordinal-group: 4; + -ms-flex-order: 3; + order: 3; + } + .order-xl-4 { + -webkit-box-ordinal-group: 5; + -ms-flex-order: 4; + order: 4; + } + .order-xl-5 { + -webkit-box-ordinal-group: 6; + -ms-flex-order: 5; + order: 5; + } + .order-xl-6 { + -webkit-box-ordinal-group: 7; + -ms-flex-order: 6; + order: 6; + } + .order-xl-7 { + -webkit-box-ordinal-group: 8; + -ms-flex-order: 7; + order: 7; + } + .order-xl-8 { + -webkit-box-ordinal-group: 9; + -ms-flex-order: 8; + order: 8; + } + .order-xl-9 { + -webkit-box-ordinal-group: 10; + -ms-flex-order: 9; + order: 9; + } + .order-xl-10 { + -webkit-box-ordinal-group: 11; + -ms-flex-order: 10; + order: 10; + } + .order-xl-11 { + -webkit-box-ordinal-group: 12; + -ms-flex-order: 11; + order: 11; + } + .order-xl-12 { + -webkit-box-ordinal-group: 13; + -ms-flex-order: 12; + order: 12; + } + .offset-xl-0 { + margin-left: 0; + } + .offset-xl-1 { + margin-left: 8.333333%; + } + .offset-xl-2 { + margin-left: 16.666667%; + } + .offset-xl-3 { + margin-left: 25%; + } + .offset-xl-4 { + margin-left: 33.333333%; + } + .offset-xl-5 { + margin-left: 41.666667%; + } + .offset-xl-6 { + margin-left: 50%; + } + .offset-xl-7 { + margin-left: 58.333333%; + } + .offset-xl-8 { + margin-left: 66.666667%; + } + .offset-xl-9 { + margin-left: 75%; + } + .offset-xl-10 { + margin-left: 83.333333%; + } + .offset-xl-11 { + margin-left: 91.666667%; + } +} + +.table { + width: 100%; + max-width: 100%; + margin-bottom: 1rem; + background-color: transparent; +} + +.table th, +.table td { + padding: 0.75rem; + vertical-align: top; + border-top: 1px solid #dee2e6; +} + +.table thead th { + vertical-align: bottom; + border-bottom: 2px solid #dee2e6; +} + +.table tbody + tbody { + border-top: 2px solid #dee2e6; +} + +.table .table { + background-color: #fff; +} + +.table-sm th, +.table-sm td { + padding: 0.3rem; +} + +.table-bordered { + border: 1px solid #dee2e6; +} + +.table-bordered th, +.table-bordered td { + border: 1px solid #dee2e6; +} + +.table-bordered thead th, +.table-bordered thead td { + border-bottom-width: 2px; +} + +.table-striped tbody tr:nth-of-type(odd) { + background-color: rgba(0, 0, 0, 0.05); +} + +.table-hover tbody tr:hover { + background-color: rgba(0, 0, 0, 0.075); +} + +.table-primary, +.table-primary > th, +.table-primary > td { + background-color: #b8daff; +} + +.table-hover .table-primary:hover { + background-color: #9fcdff; +} + +.table-hover .table-primary:hover > td, +.table-hover .table-primary:hover > th { + background-color: #9fcdff; +} + +.table-secondary, +.table-secondary > th, +.table-secondary > td { + background-color: #d6d8db; +} + +.table-hover .table-secondary:hover { + background-color: #c8cbcf; +} + +.table-hover .table-secondary:hover > td, +.table-hover .table-secondary:hover > th { + background-color: #c8cbcf; +} + +.table-success, +.table-success > th, +.table-success > td { + background-color: #c3e6cb; +} + +.table-hover .table-success:hover { + background-color: #b1dfbb; +} + +.table-hover .table-success:hover > td, +.table-hover .table-success:hover > th { + background-color: #b1dfbb; +} + +.table-info, +.table-info > th, +.table-info > td { + background-color: #bee5eb; +} + +.table-hover .table-info:hover { + background-color: #abdde5; +} + +.table-hover .table-info:hover > td, +.table-hover .table-info:hover > th { + background-color: #abdde5; +} + +.table-warning, +.table-warning > th, +.table-warning > td { + background-color: #ffeeba; +} + +.table-hover .table-warning:hover { + background-color: #ffe8a1; +} + +.table-hover .table-warning:hover > td, +.table-hover .table-warning:hover > th { + background-color: #ffe8a1; +} + +.table-danger, +.table-danger > th, +.table-danger > td { + background-color: #f5c6cb; +} + +.table-hover .table-danger:hover { + background-color: #f1b0b7; +} + +.table-hover .table-danger:hover > td, +.table-hover .table-danger:hover > th { + background-color: #f1b0b7; +} + +.table-light, +.table-light > th, +.table-light > td { + background-color: #fdfdfe; +} + +.table-hover .table-light:hover { + background-color: #ececf6; +} + +.table-hover .table-light:hover > td, +.table-hover .table-light:hover > th { + background-color: #ececf6; +} + +.table-dark, +.table-dark > th, +.table-dark > td { + background-color: #c6c8ca; +} + +.table-hover .table-dark:hover { + background-color: #b9bbbe; +} + +.table-hover .table-dark:hover > td, +.table-hover .table-dark:hover > th { + background-color: #b9bbbe; +} + +.table-active, +.table-active > th, +.table-active > td { + background-color: rgba(0, 0, 0, 0.075); +} + +.table-hover .table-active:hover { + background-color: rgba(0, 0, 0, 0.075); +} + +.table-hover .table-active:hover > td, +.table-hover .table-active:hover > th { + background-color: rgba(0, 0, 0, 0.075); +} + +.table .thead-dark th { + color: #fff; + background-color: #212529; + border-color: #32383e; +} + +.table .thead-light th { + color: #495057; + background-color: #e9ecef; + border-color: #dee2e6; +} + +.table-dark { + color: #fff; + background-color: #212529; +} + +.table-dark th, +.table-dark td, +.table-dark thead th { + border-color: #32383e; +} + +.table-dark.table-bordered { + border: 0; +} + +.table-dark.table-striped tbody tr:nth-of-type(odd) { + background-color: rgba(255, 255, 255, 0.05); +} + +.table-dark.table-hover tbody tr:hover { + background-color: rgba(255, 255, 255, 0.075); +} + +@media (max-width: 575.98px) { + .table-responsive-sm { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + } + .table-responsive-sm > .table-bordered { + border: 0; + } +} + +@media (max-width: 767.98px) { + .table-responsive-md { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + } + .table-responsive-md > .table-bordered { + border: 0; + } +} + +@media (max-width: 991.98px) { + .table-responsive-lg { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + } + .table-responsive-lg > .table-bordered { + border: 0; + } +} + +@media (max-width: 1199.98px) { + .table-responsive-xl { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + } + .table-responsive-xl > .table-bordered { + border: 0; + } +} + +.table-responsive { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; +} + +.table-responsive > .table-bordered { + border: 0; +} + +.form-control { + display: block; + width: 100%; + padding: 0.375rem 0.75rem; + font-size: 1rem; + line-height: 1.5; + color: #495057; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ced4da; + border-radius: 0.25rem; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} + +.form-control::-ms-expand { + background-color: transparent; + border: 0; +} + +.form-control:focus { + color: #495057; + background-color: #fff; + border-color: #80bdff; + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} + +.form-control::-webkit-input-placeholder { + color: #6c757d; + opacity: 1; +} + +.form-control::-moz-placeholder { + color: #6c757d; + opacity: 1; +} + +.form-control:-ms-input-placeholder { + color: #6c757d; + opacity: 1; +} + +.form-control::-ms-input-placeholder { + color: #6c757d; + opacity: 1; +} + +.form-control::placeholder { + color: #6c757d; + opacity: 1; +} + +.form-control:disabled, .form-control[readonly] { + background-color: #e9ecef; + opacity: 1; +} + +select.form-control:not([size]):not([multiple]) { + height: calc(2.25rem + 2px); +} + +select.form-control:focus::-ms-value { + color: #495057; + background-color: #fff; +} + +.form-control-file, +.form-control-range { + display: block; + width: 100%; +} + +.col-form-label { + padding-top: calc(0.375rem + 1px); + padding-bottom: calc(0.375rem + 1px); + margin-bottom: 0; + font-size: inherit; + line-height: 1.5; +} + +.col-form-label-lg { + padding-top: calc(0.5rem + 1px); + padding-bottom: calc(0.5rem + 1px); + font-size: 1.25rem; + line-height: 1.5; +} + +.col-form-label-sm { + padding-top: calc(0.25rem + 1px); + padding-bottom: calc(0.25rem + 1px); + font-size: 0.875rem; + line-height: 1.5; +} + +.form-control-plaintext { + display: block; + width: 100%; + padding-top: 0.375rem; + padding-bottom: 0.375rem; + margin-bottom: 0; + line-height: 1.5; + background-color: transparent; + border: solid transparent; + border-width: 1px 0; +} + +.form-control-plaintext.form-control-sm, .input-group-sm > .form-control-plaintext.form-control, +.input-group-sm > .input-group-prepend > .form-control-plaintext.input-group-text, +.input-group-sm > .input-group-append > .form-control-plaintext.input-group-text, +.input-group-sm > .input-group-prepend > .form-control-plaintext.btn, +.input-group-sm > .input-group-append > .form-control-plaintext.btn, .form-control-plaintext.form-control-lg, .input-group-lg > .form-control-plaintext.form-control, +.input-group-lg > .input-group-prepend > .form-control-plaintext.input-group-text, +.input-group-lg > .input-group-append > .form-control-plaintext.input-group-text, +.input-group-lg > .input-group-prepend > .form-control-plaintext.btn, +.input-group-lg > .input-group-append > .form-control-plaintext.btn { + padding-right: 0; + padding-left: 0; +} + +.form-control-sm, .input-group-sm > .form-control, +.input-group-sm > .input-group-prepend > .input-group-text, +.input-group-sm > .input-group-append > .input-group-text, +.input-group-sm > .input-group-prepend > .btn, +.input-group-sm > .input-group-append > .btn { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + line-height: 1.5; + border-radius: 0.2rem; +} + +select.form-control-sm:not([size]):not([multiple]), .input-group-sm > select.form-control:not([size]):not([multiple]), +.input-group-sm > .input-group-prepend > select.input-group-text:not([size]):not([multiple]), +.input-group-sm > .input-group-append > select.input-group-text:not([size]):not([multiple]), +.input-group-sm > .input-group-prepend > select.btn:not([size]):not([multiple]), +.input-group-sm > .input-group-append > select.btn:not([size]):not([multiple]) { + height: calc(1.8125rem + 2px); +} + +.form-control-lg, .input-group-lg > .form-control, +.input-group-lg > .input-group-prepend > .input-group-text, +.input-group-lg > .input-group-append > .input-group-text, +.input-group-lg > .input-group-prepend > .btn, +.input-group-lg > .input-group-append > .btn { + padding: 0.5rem 1rem; + font-size: 1.25rem; + line-height: 1.5; + border-radius: 0.3rem; +} + +select.form-control-lg:not([size]):not([multiple]), .input-group-lg > select.form-control:not([size]):not([multiple]), +.input-group-lg > .input-group-prepend > select.input-group-text:not([size]):not([multiple]), +.input-group-lg > .input-group-append > select.input-group-text:not([size]):not([multiple]), +.input-group-lg > .input-group-prepend > select.btn:not([size]):not([multiple]), +.input-group-lg > .input-group-append > select.btn:not([size]):not([multiple]) { + height: calc(2.875rem + 2px); +} + +.form-group { + margin-bottom: 1rem; +} + +.form-text { + display: block; + margin-top: 0.25rem; +} + +.form-row { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin-right: -5px; + margin-left: -5px; +} + +.form-row > .col, +.form-row > [class*="col-"] { + padding-right: 5px; + padding-left: 5px; +} + +.form-check { + position: relative; + display: block; + padding-left: 1.25rem; +} + +.form-check-input { + position: absolute; + margin-top: 0.3rem; + margin-left: -1.25rem; +} + +.form-check-input:disabled ~ .form-check-label { + color: #6c757d; +} + +.form-check-label { + margin-bottom: 0; +} + +.form-check-inline { + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + padding-left: 0; + margin-right: 0.75rem; +} + +.form-check-inline .form-check-input { + position: static; + margin-top: 0; + margin-right: 0.3125rem; + margin-left: 0; +} + +.valid-feedback { + display: none; + width: 100%; + margin-top: 0.25rem; + font-size: 80%; + color: #28a745; +} + +.valid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: .5rem; + margin-top: .1rem; + font-size: .875rem; + line-height: 1; + color: #fff; + background-color: rgba(40, 167, 69, 0.8); + border-radius: .2rem; +} + +.was-validated .form-control:valid, .form-control.is-valid, .was-validated +.custom-select:valid, +.custom-select.is-valid { + border-color: #28a745; +} + +.was-validated .form-control:valid:focus, .form-control.is-valid:focus, .was-validated +.custom-select:valid:focus, +.custom-select.is-valid:focus { + border-color: #28a745; + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} + +.was-validated .form-control:valid ~ .valid-feedback, +.was-validated .form-control:valid ~ .valid-tooltip, .form-control.is-valid ~ .valid-feedback, +.form-control.is-valid ~ .valid-tooltip, .was-validated +.custom-select:valid ~ .valid-feedback, +.was-validated +.custom-select:valid ~ .valid-tooltip, +.custom-select.is-valid ~ .valid-feedback, +.custom-select.is-valid ~ .valid-tooltip { + display: block; +} + +.was-validated .form-check-input:valid ~ .form-check-label, .form-check-input.is-valid ~ .form-check-label { + color: #28a745; +} + +.was-validated .form-check-input:valid ~ .valid-feedback, +.was-validated .form-check-input:valid ~ .valid-tooltip, .form-check-input.is-valid ~ .valid-feedback, +.form-check-input.is-valid ~ .valid-tooltip { + display: block; +} + +.was-validated .custom-control-input:valid ~ .custom-control-label, .custom-control-input.is-valid ~ .custom-control-label { + color: #28a745; +} + +.was-validated .custom-control-input:valid ~ .custom-control-label::before, .custom-control-input.is-valid ~ .custom-control-label::before { + background-color: #71dd8a; +} + +.was-validated .custom-control-input:valid ~ .valid-feedback, +.was-validated .custom-control-input:valid ~ .valid-tooltip, .custom-control-input.is-valid ~ .valid-feedback, +.custom-control-input.is-valid ~ .valid-tooltip { + display: block; +} + +.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before, .custom-control-input.is-valid:checked ~ .custom-control-label::before { + background-color: #34ce57; +} + +.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before, .custom-control-input.is-valid:focus ~ .custom-control-label::before { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} + +.was-validated .custom-file-input:valid ~ .custom-file-label, .custom-file-input.is-valid ~ .custom-file-label { + border-color: #28a745; +} + +.was-validated .custom-file-input:valid ~ .custom-file-label::before, .custom-file-input.is-valid ~ .custom-file-label::before { + border-color: inherit; +} + +.was-validated .custom-file-input:valid ~ .valid-feedback, +.was-validated .custom-file-input:valid ~ .valid-tooltip, .custom-file-input.is-valid ~ .valid-feedback, +.custom-file-input.is-valid ~ .valid-tooltip { + display: block; +} + +.was-validated .custom-file-input:valid:focus ~ .custom-file-label, .custom-file-input.is-valid:focus ~ .custom-file-label { + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} + +.invalid-feedback { + display: none; + width: 100%; + margin-top: 0.25rem; + font-size: 80%; + color: #dc3545; +} + +.invalid-tooltip { + position: absolute; + top: 100%; + z-index: 5; + display: none; + max-width: 100%; + padding: .5rem; + margin-top: .1rem; + font-size: .875rem; + line-height: 1; + color: #fff; + background-color: rgba(220, 53, 69, 0.8); + border-radius: .2rem; +} + +.was-validated .form-control:invalid, .form-control.is-invalid, .was-validated +.custom-select:invalid, +.custom-select.is-invalid { + border-color: #dc3545; +} + +.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus, .was-validated +.custom-select:invalid:focus, +.custom-select.is-invalid:focus { + border-color: #dc3545; + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} + +.was-validated .form-control:invalid ~ .invalid-feedback, +.was-validated .form-control:invalid ~ .invalid-tooltip, .form-control.is-invalid ~ .invalid-feedback, +.form-control.is-invalid ~ .invalid-tooltip, .was-validated +.custom-select:invalid ~ .invalid-feedback, +.was-validated +.custom-select:invalid ~ .invalid-tooltip, +.custom-select.is-invalid ~ .invalid-feedback, +.custom-select.is-invalid ~ .invalid-tooltip { + display: block; +} + +.was-validated .form-check-input:invalid ~ .form-check-label, .form-check-input.is-invalid ~ .form-check-label { + color: #dc3545; +} + +.was-validated .form-check-input:invalid ~ .invalid-feedback, +.was-validated .form-check-input:invalid ~ .invalid-tooltip, .form-check-input.is-invalid ~ .invalid-feedback, +.form-check-input.is-invalid ~ .invalid-tooltip { + display: block; +} + +.was-validated .custom-control-input:invalid ~ .custom-control-label, .custom-control-input.is-invalid ~ .custom-control-label { + color: #dc3545; +} + +.was-validated .custom-control-input:invalid ~ .custom-control-label::before, .custom-control-input.is-invalid ~ .custom-control-label::before { + background-color: #efa2a9; +} + +.was-validated .custom-control-input:invalid ~ .invalid-feedback, +.was-validated .custom-control-input:invalid ~ .invalid-tooltip, .custom-control-input.is-invalid ~ .invalid-feedback, +.custom-control-input.is-invalid ~ .invalid-tooltip { + display: block; +} + +.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before, .custom-control-input.is-invalid:checked ~ .custom-control-label::before { + background-color: #e4606d; +} + +.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before, .custom-control-input.is-invalid:focus ~ .custom-control-label::before { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} + +.was-validated .custom-file-input:invalid ~ .custom-file-label, .custom-file-input.is-invalid ~ .custom-file-label { + border-color: #dc3545; +} + +.was-validated .custom-file-input:invalid ~ .custom-file-label::before, .custom-file-input.is-invalid ~ .custom-file-label::before { + border-color: inherit; +} + +.was-validated .custom-file-input:invalid ~ .invalid-feedback, +.was-validated .custom-file-input:invalid ~ .invalid-tooltip, .custom-file-input.is-invalid ~ .invalid-feedback, +.custom-file-input.is-invalid ~ .invalid-tooltip { + display: block; +} + +.was-validated .custom-file-input:invalid:focus ~ .custom-file-label, .custom-file-input.is-invalid:focus ~ .custom-file-label { + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} + +.form-inline { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row wrap; + flex-flow: row wrap; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.form-inline .form-check { + width: 100%; +} + +@media (min-width: 576px) { + .form-inline label { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + margin-bottom: 0; + } + .form-inline .form-group { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-flex: 0; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row wrap; + flex-flow: row wrap; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + margin-bottom: 0; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-plaintext { + display: inline-block; + } + .form-inline .input-group { + width: auto; + } + .form-inline .form-check { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + width: auto; + padding-left: 0; + } + .form-inline .form-check-input { + position: relative; + margin-top: 0; + margin-right: 0.25rem; + margin-left: 0; + } + .form-inline .custom-control { + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + } + .form-inline .custom-control-label { + margin-bottom: 0; + } +} + +.btn { + display: inline-block; + font-weight: 400; + text-align: center; + white-space: nowrap; + vertical-align: middle; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + border: 1px solid transparent; + padding: 0.375rem 0.75rem; + font-size: 1rem; + line-height: 1.5; + border-radius: 0.25rem; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} + +.btn:hover, .btn:focus { + text-decoration: none; +} + +.btn:focus, .btn.focus { + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} + +.btn.disabled, .btn:disabled { + opacity: 0.65; +} + +.btn:not(:disabled):not(.disabled) { + cursor: pointer; +} + +.btn:not(:disabled):not(.disabled):active, .btn:not(:disabled):not(.disabled).active { + background-image: none; +} + +a.btn.disabled, +fieldset:disabled a.btn { + pointer-events: none; +} + +.btn-primary { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} + +.btn-primary:hover { + color: #fff; + background-color: #0069d9; + border-color: #0062cc; +} + +.btn-primary:focus, .btn-primary.focus { + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} + +.btn-primary.disabled, .btn-primary:disabled { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} + +.btn-primary:not(:disabled):not(.disabled):active, .btn-primary:not(:disabled):not(.disabled).active, +.show > .btn-primary.dropdown-toggle { + color: #fff; + background-color: #0062cc; + border-color: #005cbf; +} + +.btn-primary:not(:disabled):not(.disabled):active:focus, .btn-primary:not(:disabled):not(.disabled).active:focus, +.show > .btn-primary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} + +.btn-secondary { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} + +.btn-secondary:hover { + color: #fff; + background-color: #5a6268; + border-color: #545b62; +} + +.btn-secondary:focus, .btn-secondary.focus { + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} + +.btn-secondary.disabled, .btn-secondary:disabled { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} + +.btn-secondary:not(:disabled):not(.disabled):active, .btn-secondary:not(:disabled):not(.disabled).active, +.show > .btn-secondary.dropdown-toggle { + color: #fff; + background-color: #545b62; + border-color: #4e555b; +} + +.btn-secondary:not(:disabled):not(.disabled):active:focus, .btn-secondary:not(:disabled):not(.disabled).active:focus, +.show > .btn-secondary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} + +.btn-success { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} + +.btn-success:hover { + color: #fff; + background-color: #218838; + border-color: #1e7e34; +} + +.btn-success:focus, .btn-success.focus { + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} + +.btn-success.disabled, .btn-success:disabled { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} + +.btn-success:not(:disabled):not(.disabled):active, .btn-success:not(:disabled):not(.disabled).active, +.show > .btn-success.dropdown-toggle { + color: #fff; + background-color: #1e7e34; + border-color: #1c7430; +} + +.btn-success:not(:disabled):not(.disabled):active:focus, .btn-success:not(:disabled):not(.disabled).active:focus, +.show > .btn-success.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} + +.btn-info { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} + +.btn-info:hover { + color: #fff; + background-color: #138496; + border-color: #117a8b; +} + +.btn-info:focus, .btn-info.focus { + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} + +.btn-info.disabled, .btn-info:disabled { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} + +.btn-info:not(:disabled):not(.disabled):active, .btn-info:not(:disabled):not(.disabled).active, +.show > .btn-info.dropdown-toggle { + color: #fff; + background-color: #117a8b; + border-color: #10707f; +} + +.btn-info:not(:disabled):not(.disabled):active:focus, .btn-info:not(:disabled):not(.disabled).active:focus, +.show > .btn-info.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} + +.btn-warning { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} + +.btn-warning:hover { + color: #212529; + background-color: #e0a800; + border-color: #d39e00; +} + +.btn-warning:focus, .btn-warning.focus { + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} + +.btn-warning.disabled, .btn-warning:disabled { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} + +.btn-warning:not(:disabled):not(.disabled):active, .btn-warning:not(:disabled):not(.disabled).active, +.show > .btn-warning.dropdown-toggle { + color: #212529; + background-color: #d39e00; + border-color: #c69500; +} + +.btn-warning:not(:disabled):not(.disabled):active:focus, .btn-warning:not(:disabled):not(.disabled).active:focus, +.show > .btn-warning.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} + +.btn-danger { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} + +.btn-danger:hover { + color: #fff; + background-color: #c82333; + border-color: #bd2130; +} + +.btn-danger:focus, .btn-danger.focus { + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} + +.btn-danger.disabled, .btn-danger:disabled { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} + +.btn-danger:not(:disabled):not(.disabled):active, .btn-danger:not(:disabled):not(.disabled).active, +.show > .btn-danger.dropdown-toggle { + color: #fff; + background-color: #bd2130; + border-color: #b21f2d; +} + +.btn-danger:not(:disabled):not(.disabled):active:focus, .btn-danger:not(:disabled):not(.disabled).active:focus, +.show > .btn-danger.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} + +.btn-light { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} + +.btn-light:hover { + color: #212529; + background-color: #e2e6ea; + border-color: #dae0e5; +} + +.btn-light:focus, .btn-light.focus { + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} + +.btn-light.disabled, .btn-light:disabled { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} + +.btn-light:not(:disabled):not(.disabled):active, .btn-light:not(:disabled):not(.disabled).active, +.show > .btn-light.dropdown-toggle { + color: #212529; + background-color: #dae0e5; + border-color: #d3d9df; +} + +.btn-light:not(:disabled):not(.disabled):active:focus, .btn-light:not(:disabled):not(.disabled).active:focus, +.show > .btn-light.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} + +.btn-dark { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} + +.btn-dark:hover { + color: #fff; + background-color: #23272b; + border-color: #1d2124; +} + +.btn-dark:focus, .btn-dark.focus { + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} + +.btn-dark.disabled, .btn-dark:disabled { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} + +.btn-dark:not(:disabled):not(.disabled):active, .btn-dark:not(:disabled):not(.disabled).active, +.show > .btn-dark.dropdown-toggle { + color: #fff; + background-color: #1d2124; + border-color: #171a1d; +} + +.btn-dark:not(:disabled):not(.disabled):active:focus, .btn-dark:not(:disabled):not(.disabled).active:focus, +.show > .btn-dark.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} + +.btn-outline-primary { + color: #007bff; + background-color: transparent; + background-image: none; + border-color: #007bff; +} + +.btn-outline-primary:hover { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} + +.btn-outline-primary:focus, .btn-outline-primary.focus { + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} + +.btn-outline-primary.disabled, .btn-outline-primary:disabled { + color: #007bff; + background-color: transparent; +} + +.btn-outline-primary:not(:disabled):not(.disabled):active, .btn-outline-primary:not(:disabled):not(.disabled).active, +.show > .btn-outline-primary.dropdown-toggle { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} + +.btn-outline-primary:not(:disabled):not(.disabled):active:focus, .btn-outline-primary:not(:disabled):not(.disabled).active:focus, +.show > .btn-outline-primary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} + +.btn-outline-secondary { + color: #6c757d; + background-color: transparent; + background-image: none; + border-color: #6c757d; +} + +.btn-outline-secondary:hover { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} + +.btn-outline-secondary:focus, .btn-outline-secondary.focus { + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} + +.btn-outline-secondary.disabled, .btn-outline-secondary:disabled { + color: #6c757d; + background-color: transparent; +} + +.btn-outline-secondary:not(:disabled):not(.disabled):active, .btn-outline-secondary:not(:disabled):not(.disabled).active, +.show > .btn-outline-secondary.dropdown-toggle { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} + +.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, .btn-outline-secondary:not(:disabled):not(.disabled).active:focus, +.show > .btn-outline-secondary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} + +.btn-outline-success { + color: #28a745; + background-color: transparent; + background-image: none; + border-color: #28a745; +} + +.btn-outline-success:hover { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} + +.btn-outline-success:focus, .btn-outline-success.focus { + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} + +.btn-outline-success.disabled, .btn-outline-success:disabled { + color: #28a745; + background-color: transparent; +} + +.btn-outline-success:not(:disabled):not(.disabled):active, .btn-outline-success:not(:disabled):not(.disabled).active, +.show > .btn-outline-success.dropdown-toggle { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} + +.btn-outline-success:not(:disabled):not(.disabled):active:focus, .btn-outline-success:not(:disabled):not(.disabled).active:focus, +.show > .btn-outline-success.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} + +.btn-outline-info { + color: #17a2b8; + background-color: transparent; + background-image: none; + border-color: #17a2b8; +} + +.btn-outline-info:hover { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} + +.btn-outline-info:focus, .btn-outline-info.focus { + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} + +.btn-outline-info.disabled, .btn-outline-info:disabled { + color: #17a2b8; + background-color: transparent; +} + +.btn-outline-info:not(:disabled):not(.disabled):active, .btn-outline-info:not(:disabled):not(.disabled).active, +.show > .btn-outline-info.dropdown-toggle { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} + +.btn-outline-info:not(:disabled):not(.disabled):active:focus, .btn-outline-info:not(:disabled):not(.disabled).active:focus, +.show > .btn-outline-info.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} + +.btn-outline-warning { + color: #ffc107; + background-color: transparent; + background-image: none; + border-color: #ffc107; +} + +.btn-outline-warning:hover { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} + +.btn-outline-warning:focus, .btn-outline-warning.focus { + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} + +.btn-outline-warning.disabled, .btn-outline-warning:disabled { + color: #ffc107; + background-color: transparent; +} + +.btn-outline-warning:not(:disabled):not(.disabled):active, .btn-outline-warning:not(:disabled):not(.disabled).active, +.show > .btn-outline-warning.dropdown-toggle { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} + +.btn-outline-warning:not(:disabled):not(.disabled):active:focus, .btn-outline-warning:not(:disabled):not(.disabled).active:focus, +.show > .btn-outline-warning.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} + +.btn-outline-danger { + color: #dc3545; + background-color: transparent; + background-image: none; + border-color: #dc3545; +} + +.btn-outline-danger:hover { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} + +.btn-outline-danger:focus, .btn-outline-danger.focus { + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} + +.btn-outline-danger.disabled, .btn-outline-danger:disabled { + color: #dc3545; + background-color: transparent; +} + +.btn-outline-danger:not(:disabled):not(.disabled):active, .btn-outline-danger:not(:disabled):not(.disabled).active, +.show > .btn-outline-danger.dropdown-toggle { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} + +.btn-outline-danger:not(:disabled):not(.disabled):active:focus, .btn-outline-danger:not(:disabled):not(.disabled).active:focus, +.show > .btn-outline-danger.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} + +.btn-outline-light { + color: #f8f9fa; + background-color: transparent; + background-image: none; + border-color: #f8f9fa; +} + +.btn-outline-light:hover { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} + +.btn-outline-light:focus, .btn-outline-light.focus { + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} + +.btn-outline-light.disabled, .btn-outline-light:disabled { + color: #f8f9fa; + background-color: transparent; +} + +.btn-outline-light:not(:disabled):not(.disabled):active, .btn-outline-light:not(:disabled):not(.disabled).active, +.show > .btn-outline-light.dropdown-toggle { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} + +.btn-outline-light:not(:disabled):not(.disabled):active:focus, .btn-outline-light:not(:disabled):not(.disabled).active:focus, +.show > .btn-outline-light.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} + +.btn-outline-dark { + color: #343a40; + background-color: transparent; + background-image: none; + border-color: #343a40; +} + +.btn-outline-dark:hover { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} + +.btn-outline-dark:focus, .btn-outline-dark.focus { + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} + +.btn-outline-dark.disabled, .btn-outline-dark:disabled { + color: #343a40; + background-color: transparent; +} + +.btn-outline-dark:not(:disabled):not(.disabled):active, .btn-outline-dark:not(:disabled):not(.disabled).active, +.show > .btn-outline-dark.dropdown-toggle { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} + +.btn-outline-dark:not(:disabled):not(.disabled):active:focus, .btn-outline-dark:not(:disabled):not(.disabled).active:focus, +.show > .btn-outline-dark.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} + +.btn-link { + font-weight: 400; + color: #007bff; + background-color: transparent; +} + +.btn-link:hover { + color: #0056b3; + text-decoration: underline; + background-color: transparent; + border-color: transparent; +} + +.btn-link:focus, .btn-link.focus { + text-decoration: underline; + border-color: transparent; + box-shadow: none; +} + +.btn-link:disabled, .btn-link.disabled { + color: #6c757d; +} + +.btn-lg, .btn-group-lg > .btn { + padding: 0.5rem 1rem; + font-size: 1.25rem; + line-height: 1.5; + border-radius: 0.3rem; +} + +.btn-sm, .btn-group-sm > .btn { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + line-height: 1.5; + border-radius: 0.2rem; +} + +.btn-block { + display: block; + width: 100%; +} + +.btn-block + .btn-block { + margin-top: 0.5rem; +} + +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} + +.fade { + opacity: 0; + transition: opacity 0.15s linear; +} + +.fade.show { + opacity: 1; +} + +.collapse { + display: none; +} + +.collapse.show { + display: block; +} + +tr.collapse.show { + display: table-row; +} + +tbody.collapse.show { + display: table-row-group; +} + +.collapsing { + position: relative; + height: 0; + overflow: hidden; + transition: height 0.35s ease; +} + +.dropup, +.dropdown { + position: relative; +} + +.dropdown-toggle::after { + display: inline-block; + width: 0; + height: 0; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid; + border-right: 0.3em solid transparent; + border-bottom: 0; + border-left: 0.3em solid transparent; +} + +.dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 10rem; + padding: 0.5rem 0; + margin: 0.125rem 0 0; + font-size: 1rem; + color: #212529; + text-align: left; + list-style: none; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; +} + +.dropup .dropdown-menu { + margin-top: 0; + margin-bottom: 0.125rem; +} + +.dropup .dropdown-toggle::after { + display: inline-block; + width: 0; + height: 0; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0; + border-right: 0.3em solid transparent; + border-bottom: 0.3em solid; + border-left: 0.3em solid transparent; +} + +.dropup .dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropright .dropdown-menu { + margin-top: 0; + margin-left: 0.125rem; +} + +.dropright .dropdown-toggle::after { + display: inline-block; + width: 0; + height: 0; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid transparent; + border-bottom: 0.3em solid transparent; + border-left: 0.3em solid; +} + +.dropright .dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropright .dropdown-toggle::after { + vertical-align: 0; +} + +.dropleft .dropdown-menu { + margin-top: 0; + margin-right: 0.125rem; +} + +.dropleft .dropdown-toggle::after { + display: inline-block; + width: 0; + height: 0; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ""; +} + +.dropleft .dropdown-toggle::after { + display: none; +} + +.dropleft .dropdown-toggle::before { + display: inline-block; + width: 0; + height: 0; + margin-right: 0.255em; + vertical-align: 0.255em; + content: ""; + border-top: 0.3em solid transparent; + border-right: 0.3em solid; + border-bottom: 0.3em solid transparent; +} + +.dropleft .dropdown-toggle:empty::after { + margin-left: 0; +} + +.dropleft .dropdown-toggle::before { + vertical-align: 0; +} + +.dropdown-divider { + height: 0; + margin: 0.5rem 0; + overflow: hidden; + border-top: 1px solid #e9ecef; +} + +.dropdown-item { + display: block; + width: 100%; + padding: 0.25rem 1.5rem; + clear: both; + font-weight: 400; + color: #212529; + text-align: inherit; + white-space: nowrap; + background-color: transparent; + border: 0; +} + +.dropdown-item:hover, .dropdown-item:focus { + color: #16181b; + text-decoration: none; + background-color: #f8f9fa; +} + +.dropdown-item.active, .dropdown-item:active { + color: #fff; + text-decoration: none; + background-color: #007bff; +} + +.dropdown-item.disabled, .dropdown-item:disabled { + color: #6c757d; + background-color: transparent; +} + +.dropdown-menu.show { + display: block; +} + +.dropdown-header { + display: block; + padding: 0.5rem 1.5rem; + margin-bottom: 0; + font-size: 0.875rem; + color: #6c757d; + white-space: nowrap; +} + +.btn-group, +.btn-group-vertical { + position: relative; + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + vertical-align: middle; +} + +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + -webkit-box-flex: 0; + -ms-flex: 0 1 auto; + flex: 0 1 auto; +} + +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover { + z-index: 1; +} + +.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active, +.btn-group-vertical > .btn:focus, +.btn-group-vertical > .btn:active, +.btn-group-vertical > .btn.active { + z-index: 1; +} + +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group, +.btn-group-vertical .btn + .btn, +.btn-group-vertical .btn + .btn-group, +.btn-group-vertical .btn-group + .btn, +.btn-group-vertical .btn-group + .btn-group { + margin-left: -1px; +} + +.btn-toolbar { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; +} + +.btn-toolbar .input-group { + width: auto; +} + +.btn-group > .btn:first-child { + margin-left: 0; +} + +.btn-group > .btn:not(:last-child):not(.dropdown-toggle), +.btn-group > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.btn-group > .btn:not(:first-child), +.btn-group > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.dropdown-toggle-split { + padding-right: 0.5625rem; + padding-left: 0.5625rem; +} + +.dropdown-toggle-split::after { + margin-left: 0; +} + +.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split { + padding-right: 0.375rem; + padding-left: 0.375rem; +} + +.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split { + padding-right: 0.75rem; + padding-left: 0.75rem; +} + +.btn-group-vertical { + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-align: start; + -ms-flex-align: start; + align-items: flex-start; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; +} + +.btn-group-vertical .btn, +.btn-group-vertical .btn-group { + width: 100%; +} + +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} + +.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle), +.btn-group-vertical > .btn-group:not(:last-child) > .btn { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} + +.btn-group-vertical > .btn:not(:first-child), +.btn-group-vertical > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.btn-group-toggle > .btn, +.btn-group-toggle > .btn-group > .btn { + margin-bottom: 0; +} + +.btn-group-toggle > .btn input[type="radio"], +.btn-group-toggle > .btn input[type="checkbox"], +.btn-group-toggle > .btn-group > .btn input[type="radio"], +.btn-group-toggle > .btn-group > .btn input[type="checkbox"] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} + +.input-group { + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-align: stretch; + -ms-flex-align: stretch; + align-items: stretch; + width: 100%; +} + +.input-group > .form-control, +.input-group > .custom-select, +.input-group > .custom-file { + position: relative; + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + width: 1%; + margin-bottom: 0; +} + +.input-group > .form-control:focus, +.input-group > .custom-select:focus, +.input-group > .custom-file:focus { + z-index: 3; +} + +.input-group > .form-control + .form-control, +.input-group > .form-control + .custom-select, +.input-group > .form-control + .custom-file, +.input-group > .custom-select + .form-control, +.input-group > .custom-select + .custom-select, +.input-group > .custom-select + .custom-file, +.input-group > .custom-file + .form-control, +.input-group > .custom-file + .custom-select, +.input-group > .custom-file + .custom-file { + margin-left: -1px; +} + +.input-group > .form-control:not(:last-child), +.input-group > .custom-select:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.input-group > .form-control:not(:first-child), +.input-group > .custom-select:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.input-group > .custom-file { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.input-group > .custom-file:not(:last-child) .custom-file-label, +.input-group > .custom-file:not(:last-child) .custom-file-label::before { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.input-group > .custom-file:not(:first-child) .custom-file-label, +.input-group > .custom-file:not(:first-child) .custom-file-label::before { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.input-group-prepend, +.input-group-append { + display: -webkit-box; + display: -ms-flexbox; + display: flex; +} + +.input-group-prepend .btn, +.input-group-append .btn { + position: relative; + z-index: 2; +} + +.input-group-prepend .btn + .btn, +.input-group-prepend .btn + .input-group-text, +.input-group-prepend .input-group-text + .input-group-text, +.input-group-prepend .input-group-text + .btn, +.input-group-append .btn + .btn, +.input-group-append .btn + .input-group-text, +.input-group-append .input-group-text + .input-group-text, +.input-group-append .input-group-text + .btn { + margin-left: -1px; +} + +.input-group-prepend { + margin-right: -1px; +} + +.input-group-append { + margin-left: -1px; +} + +.input-group-text { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + padding: 0.375rem 0.75rem; + margin-bottom: 0; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #495057; + text-align: center; + white-space: nowrap; + background-color: #e9ecef; + border: 1px solid #ced4da; + border-radius: 0.25rem; +} + +.input-group-text input[type="radio"], +.input-group-text input[type="checkbox"] { + margin-top: 0; +} + +.input-group > .input-group-prepend > .btn, +.input-group > .input-group-prepend > .input-group-text, +.input-group > .input-group-append:not(:last-child) > .btn, +.input-group > .input-group-append:not(:last-child) > .input-group-text, +.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} + +.input-group > .input-group-append > .btn, +.input-group > .input-group-append > .input-group-text, +.input-group > .input-group-prepend:not(:first-child) > .btn, +.input-group > .input-group-prepend:not(:first-child) > .input-group-text, +.input-group > .input-group-prepend:first-child > .btn:not(:first-child), +.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} + +.custom-control { + position: relative; + display: block; + min-height: 1.5rem; + padding-left: 1.5rem; +} + +.custom-control-inline { + display: -webkit-inline-box; + display: -ms-inline-flexbox; + display: inline-flex; + margin-right: 1rem; +} + +.custom-control-input { + position: absolute; + z-index: -1; + opacity: 0; +} + +.custom-control-input:checked ~ .custom-control-label::before { + color: #fff; + background-color: #007bff; +} + +.custom-control-input:focus ~ .custom-control-label::before { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} + +.custom-control-input:active ~ .custom-control-label::before { + color: #fff; + background-color: #b3d7ff; +} + +.custom-control-input:disabled ~ .custom-control-label { + color: #6c757d; +} + +.custom-control-input:disabled ~ .custom-control-label::before { + background-color: #e9ecef; +} + +.custom-control-label { + margin-bottom: 0; +} + +.custom-control-label::before { + position: absolute; + top: 0.25rem; + left: 0; + display: block; + width: 1rem; + height: 1rem; + pointer-events: none; + content: ""; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-color: #dee2e6; +} + +.custom-control-label::after { + position: absolute; + top: 0.25rem; + left: 0; + display: block; + width: 1rem; + height: 1rem; + content: ""; + background-repeat: no-repeat; + background-position: center center; + background-size: 50% 50%; +} + +.custom-checkbox .custom-control-label::before { + border-radius: 0.25rem; +} + +.custom-checkbox .custom-control-input:checked ~ .custom-control-label::before { + background-color: #007bff; +} + +.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E"); +} + +.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before { + background-color: #007bff; +} + +.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E"); +} + +.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before { + background-color: rgba(0, 123, 255, 0.5); +} + +.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before { + background-color: rgba(0, 123, 255, 0.5); +} + +.custom-radio .custom-control-label::before { + border-radius: 50%; +} + +.custom-radio .custom-control-input:checked ~ .custom-control-label::before { + background-color: #007bff; +} + +.custom-radio .custom-control-input:checked ~ .custom-control-label::after { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E"); +} + +.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before { + background-color: rgba(0, 123, 255, 0.5); +} + +.custom-select { + display: inline-block; + width: 100%; + height: calc(2.25rem + 2px); + padding: 0.375rem 1.75rem 0.375rem 0.75rem; + line-height: 1.5; + color: #495057; + vertical-align: middle; + background: #fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right 0.75rem center; + background-size: 8px 10px; + border: 1px solid #ced4da; + border-radius: 0.25rem; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + +.custom-select:focus { + border-color: #80bdff; + outline: 0; + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075), 0 0 5px rgba(128, 189, 255, 0.5); +} + +.custom-select:focus::-ms-value { + color: #495057; + background-color: #fff; +} + +.custom-select[multiple], .custom-select[size]:not([size="1"]) { + height: auto; + padding-right: 0.75rem; + background-image: none; +} + +.custom-select:disabled { + color: #6c757d; + background-color: #e9ecef; +} + +.custom-select::-ms-expand { + opacity: 0; +} + +.custom-select-sm { + height: calc(1.8125rem + 2px); + padding-top: 0.375rem; + padding-bottom: 0.375rem; + font-size: 75%; +} + +.custom-select-lg { + height: calc(2.875rem + 2px); + padding-top: 0.375rem; + padding-bottom: 0.375rem; + font-size: 125%; +} + +.custom-file { + position: relative; + display: inline-block; + width: 100%; + height: calc(2.25rem + 2px); + margin-bottom: 0; +} + +.custom-file-input { + position: relative; + z-index: 2; + width: 100%; + height: calc(2.25rem + 2px); + margin: 0; + opacity: 0; +} + +.custom-file-input:focus ~ .custom-file-control { + border-color: #80bdff; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} + +.custom-file-input:focus ~ .custom-file-control::before { + border-color: #80bdff; +} + +.custom-file-input:lang(en) ~ .custom-file-label::after { + content: "Browse"; +} + +.custom-file-label { + position: absolute; + top: 0; + right: 0; + left: 0; + z-index: 1; + height: calc(2.25rem + 2px); + padding: 0.375rem 0.75rem; + line-height: 1.5; + color: #495057; + background-color: #fff; + border: 1px solid #ced4da; + border-radius: 0.25rem; +} + +.custom-file-label::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + z-index: 3; + display: block; + height: calc(calc(2.25rem + 2px) - 1px * 2); + padding: 0.375rem 0.75rem; + line-height: 1.5; + color: #495057; + content: "Browse"; + background-color: #e9ecef; + border-left: 1px solid #ced4da; + border-radius: 0 0.25rem 0.25rem 0; +} + +.nav { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} + +.nav-link { + display: block; + padding: 0.5rem 1rem; +} + +.nav-link:hover, .nav-link:focus { + text-decoration: none; +} + +.nav-link.disabled { + color: #6c757d; +} + +.nav-tabs { + border-bottom: 1px solid #dee2e6; +} + +.nav-tabs .nav-item { + margin-bottom: -1px; +} + +.nav-tabs .nav-link { + border: 1px solid transparent; + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} + +.nav-tabs .nav-link:hover, .nav-tabs .nav-link:focus { + border-color: #e9ecef #e9ecef #dee2e6; +} + +.nav-tabs .nav-link.disabled { + color: #6c757d; + background-color: transparent; + border-color: transparent; +} + +.nav-tabs .nav-link.active, +.nav-tabs .nav-item.show .nav-link { + color: #495057; + background-color: #fff; + border-color: #dee2e6 #dee2e6 #fff; +} + +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} + +.nav-pills .nav-link { + border-radius: 0.25rem; +} + +.nav-pills .nav-link.active, +.nav-pills .show > .nav-link { + color: #fff; + background-color: #007bff; +} + +.nav-fill .nav-item { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + text-align: center; +} + +.nav-justified .nav-item { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + text-align: center; +} + +.tab-content > .tab-pane { + display: none; +} + +.tab-content > .active { + display: block; +} + +.navbar { + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + padding: 0.5rem 1rem; +} + +.navbar > .container, +.navbar > .container-fluid { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; +} + +.navbar-brand { + display: inline-block; + padding-top: 0.3125rem; + padding-bottom: 0.3125rem; + margin-right: 1rem; + font-size: 1.25rem; + line-height: inherit; + white-space: nowrap; +} + +.navbar-brand:hover, .navbar-brand:focus { + text-decoration: none; +} + +.navbar-nav { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} + +.navbar-nav .nav-link { + padding-right: 0; + padding-left: 0; +} + +.navbar-nav .dropdown-menu { + position: static; + float: none; +} + +.navbar-text { + display: inline-block; + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} + +.navbar-collapse { + -ms-flex-preferred-size: 100%; + flex-basis: 100%; + -webkit-box-flex: 1; + -ms-flex-positive: 1; + flex-grow: 1; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; +} + +.navbar-toggler { + padding: 0.25rem 0.75rem; + font-size: 1.25rem; + line-height: 1; + background-color: transparent; + border: 1px solid transparent; + border-radius: 0.25rem; +} + +.navbar-toggler:hover, .navbar-toggler:focus { + text-decoration: none; +} + +.navbar-toggler:not(:disabled):not(.disabled) { + cursor: pointer; +} + +.navbar-toggler-icon { + display: inline-block; + width: 1.5em; + height: 1.5em; + vertical-align: middle; + content: ""; + background: no-repeat center center; + background-size: 100% 100%; +} + +@media (max-width: 575.98px) { + .navbar-expand-sm > .container, + .navbar-expand-sm > .container-fluid { + padding-right: 0; + padding-left: 0; + } +} + +@media (min-width: 576px) { + .navbar-expand-sm { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + } + .navbar-expand-sm .navbar-nav { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + } + .navbar-expand-sm .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-sm .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; + } + .navbar-expand-sm .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-sm > .container, + .navbar-expand-sm > .container-fluid { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + } + .navbar-expand-sm .navbar-collapse { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; + } + .navbar-expand-sm .navbar-toggler { + display: none; + } + .navbar-expand-sm .dropup .dropdown-menu { + top: auto; + bottom: 100%; + } +} + +@media (max-width: 767.98px) { + .navbar-expand-md > .container, + .navbar-expand-md > .container-fluid { + padding-right: 0; + padding-left: 0; + } +} + +@media (min-width: 768px) { + .navbar-expand-md { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + } + .navbar-expand-md .navbar-nav { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + } + .navbar-expand-md .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-md .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; + } + .navbar-expand-md .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-md > .container, + .navbar-expand-md > .container-fluid { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + } + .navbar-expand-md .navbar-collapse { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; + } + .navbar-expand-md .navbar-toggler { + display: none; + } + .navbar-expand-md .dropup .dropdown-menu { + top: auto; + bottom: 100%; + } +} + +@media (max-width: 991.98px) { + .navbar-expand-lg > .container, + .navbar-expand-lg > .container-fluid { + padding-right: 0; + padding-left: 0; + } +} + +@media (min-width: 992px) { + .navbar-expand-lg { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + } + .navbar-expand-lg .navbar-nav { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + } + .navbar-expand-lg .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-lg .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; + } + .navbar-expand-lg .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-lg > .container, + .navbar-expand-lg > .container-fluid { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + } + .navbar-expand-lg .navbar-collapse { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; + } + .navbar-expand-lg .navbar-toggler { + display: none; + } + .navbar-expand-lg .dropup .dropdown-menu { + top: auto; + bottom: 100%; + } +} + +@media (max-width: 1199.98px) { + .navbar-expand-xl > .container, + .navbar-expand-xl > .container-fluid { + padding-right: 0; + padding-left: 0; + } +} + +@media (min-width: 1200px) { + .navbar-expand-xl { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; + } + .navbar-expand-xl .navbar-nav { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; + } + .navbar-expand-xl .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-xl .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; + } + .navbar-expand-xl .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-xl > .container, + .navbar-expand-xl > .container-fluid { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + } + .navbar-expand-xl .navbar-collapse { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; + } + .navbar-expand-xl .navbar-toggler { + display: none; + } + .navbar-expand-xl .dropup .dropdown-menu { + top: auto; + bottom: 100%; + } +} + +.navbar-expand { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -webkit-box-pack: start; + -ms-flex-pack: start; + justify-content: flex-start; +} + +.navbar-expand > .container, +.navbar-expand > .container-fluid { + padding-right: 0; + padding-left: 0; +} + +.navbar-expand .navbar-nav { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-direction: row; + flex-direction: row; +} + +.navbar-expand .navbar-nav .dropdown-menu { + position: absolute; +} + +.navbar-expand .navbar-nav .dropdown-menu-right { + right: 0; + left: auto; +} + +.navbar-expand .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; +} + +.navbar-expand > .container, +.navbar-expand > .container-fluid { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; +} + +.navbar-expand .navbar-collapse { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; +} + +.navbar-expand .navbar-toggler { + display: none; +} + +.navbar-expand .dropup .dropdown-menu { + top: auto; + bottom: 100%; +} + +.navbar-light .navbar-brand { + color: rgba(0, 0, 0, 0.9); +} + +.navbar-light .navbar-brand:hover, .navbar-light .navbar-brand:focus { + color: rgba(0, 0, 0, 0.9); +} + +.navbar-light .navbar-nav .nav-link { + color: rgba(0, 0, 0, 0.5); +} + +.navbar-light .navbar-nav .nav-link:hover, .navbar-light .navbar-nav .nav-link:focus { + color: rgba(0, 0, 0, 0.7); +} + +.navbar-light .navbar-nav .nav-link.disabled { + color: rgba(0, 0, 0, 0.3); +} + +.navbar-light .navbar-nav .show > .nav-link, +.navbar-light .navbar-nav .active > .nav-link, +.navbar-light .navbar-nav .nav-link.show, +.navbar-light .navbar-nav .nav-link.active { + color: rgba(0, 0, 0, 0.9); +} + +.navbar-light .navbar-toggler { + color: rgba(0, 0, 0, 0.5); + border-color: rgba(0, 0, 0, 0.1); +} + +.navbar-light .navbar-toggler-icon { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"); +} + +.navbar-light .navbar-text { + color: rgba(0, 0, 0, 0.5); +} + +.navbar-light .navbar-text a { + color: rgba(0, 0, 0, 0.9); +} + +.navbar-light .navbar-text a:hover, .navbar-light .navbar-text a:focus { + color: rgba(0, 0, 0, 0.9); +} + +.navbar-dark .navbar-brand { + color: #fff; +} + +.navbar-dark .navbar-brand:hover, .navbar-dark .navbar-brand:focus { + color: #fff; +} + +.navbar-dark .navbar-nav .nav-link { + color: rgba(255, 255, 255, 0.5); +} + +.navbar-dark .navbar-nav .nav-link:hover, .navbar-dark .navbar-nav .nav-link:focus { + color: rgba(255, 255, 255, 0.75); +} + +.navbar-dark .navbar-nav .nav-link.disabled { + color: rgba(255, 255, 255, 0.25); +} + +.navbar-dark .navbar-nav .show > .nav-link, +.navbar-dark .navbar-nav .active > .nav-link, +.navbar-dark .navbar-nav .nav-link.show, +.navbar-dark .navbar-nav .nav-link.active { + color: #fff; +} + +.navbar-dark .navbar-toggler { + color: rgba(255, 255, 255, 0.5); + border-color: rgba(255, 255, 255, 0.1); +} + +.navbar-dark .navbar-toggler-icon { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E"); +} + +.navbar-dark .navbar-text { + color: rgba(255, 255, 255, 0.5); +} + +.navbar-dark .navbar-text a { + color: #fff; +} + +.navbar-dark .navbar-text a:hover, .navbar-dark .navbar-text a:focus { + color: #fff; +} + +.card { + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + min-width: 0; + word-wrap: break-word; + background-color: #fff; + background-clip: border-box; + border: 1px solid rgba(0, 0, 0, 0.125); + border-radius: 0.25rem; +} + +.card > hr { + margin-right: 0; + margin-left: 0; +} + +.card > .list-group:first-child .list-group-item:first-child { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} + +.card > .list-group:last-child .list-group-item:last-child { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} + +.card-body { + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + padding: 1.25rem; +} + +.card-title { + margin-bottom: 0.75rem; +} + +.card-subtitle { + margin-top: -0.375rem; + margin-bottom: 0; +} + +.card-text:last-child { + margin-bottom: 0; +} + +.card-link:hover { + text-decoration: none; +} + +.card-link + .card-link { + margin-left: 1.25rem; +} + +.card-header { + padding: 0.75rem 1.25rem; + margin-bottom: 0; + background-color: rgba(0, 0, 0, 0.03); + border-bottom: 1px solid rgba(0, 0, 0, 0.125); +} + +.card-header:first-child { + border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0; +} + +.card-header + .list-group .list-group-item:first-child { + border-top: 0; +} + +.card-footer { + padding: 0.75rem 1.25rem; + background-color: rgba(0, 0, 0, 0.03); + border-top: 1px solid rgba(0, 0, 0, 0.125); +} + +.card-footer:last-child { + border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px); +} + +.card-header-tabs { + margin-right: -0.625rem; + margin-bottom: -0.75rem; + margin-left: -0.625rem; + border-bottom: 0; +} + +.card-header-pills { + margin-right: -0.625rem; + margin-left: -0.625rem; +} + +.card-img-overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: 1.25rem; +} + +.card-img { + width: 100%; + border-radius: calc(0.25rem - 1px); +} + +.card-img-top { + width: 100%; + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} + +.card-img-bottom { + width: 100%; + border-bottom-right-radius: calc(0.25rem - 1px); + border-bottom-left-radius: calc(0.25rem - 1px); +} + +.card-deck { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} + +.card-deck .card { + margin-bottom: 15px; +} + +@media (min-width: 576px) { + .card-deck { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row wrap; + flex-flow: row wrap; + margin-right: -15px; + margin-left: -15px; + } + .card-deck .card { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-flex: 1; + -ms-flex: 1 0 0%; + flex: 1 0 0%; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + margin-right: 15px; + margin-bottom: 0; + margin-left: 15px; + } +} + +.card-group { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; +} + +.card-group > .card { + margin-bottom: 15px; +} + +@media (min-width: 576px) { + .card-group { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -ms-flex-flow: row wrap; + flex-flow: row wrap; + } + .card-group > .card { + -webkit-box-flex: 1; + -ms-flex: 1 0 0%; + flex: 1 0 0%; + margin-bottom: 0; + } + .card-group > .card + .card { + margin-left: 0; + border-left: 0; + } + .card-group > .card:first-child { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .card-group > .card:first-child .card-img-top, + .card-group > .card:first-child .card-header { + border-top-right-radius: 0; + } + .card-group > .card:first-child .card-img-bottom, + .card-group > .card:first-child .card-footer { + border-bottom-right-radius: 0; + } + .card-group > .card:last-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .card-group > .card:last-child .card-img-top, + .card-group > .card:last-child .card-header { + border-top-left-radius: 0; + } + .card-group > .card:last-child .card-img-bottom, + .card-group > .card:last-child .card-footer { + border-bottom-left-radius: 0; + } + .card-group > .card:only-child { + border-radius: 0.25rem; + } + .card-group > .card:only-child .card-img-top, + .card-group > .card:only-child .card-header { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; + } + .card-group > .card:only-child .card-img-bottom, + .card-group > .card:only-child .card-footer { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; + } + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) { + border-radius: 0; + } + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-top, + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom, + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-header, + .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-footer { + border-radius: 0; + } +} + +.card-columns .card { + margin-bottom: 0.75rem; +} + +@media (min-width: 576px) { + .card-columns { + -webkit-column-count: 3; + -moz-column-count: 3; + column-count: 3; + -webkit-column-gap: 1.25rem; + -moz-column-gap: 1.25rem; + column-gap: 1.25rem; + } + .card-columns .card { + display: inline-block; + width: 100%; + } +} + +.breadcrumb { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + padding: 0.75rem 1rem; + margin-bottom: 1rem; + list-style: none; + background-color: #e9ecef; + border-radius: 0.25rem; +} + +.breadcrumb-item + .breadcrumb-item::before { + display: inline-block; + padding-right: 0.5rem; + padding-left: 0.5rem; + color: #6c757d; + content: "/"; +} + +.breadcrumb-item + .breadcrumb-item:hover::before { + text-decoration: underline; +} + +.breadcrumb-item + .breadcrumb-item:hover::before { + text-decoration: none; +} + +.breadcrumb-item.active { + color: #6c757d; +} + +.pagination { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + padding-left: 0; + list-style: none; + border-radius: 0.25rem; +} + +.page-link { + position: relative; + display: block; + padding: 0.5rem 0.75rem; + margin-left: -1px; + line-height: 1.25; + color: #007bff; + background-color: #fff; + border: 1px solid #dee2e6; +} + +.page-link:hover { + color: #0056b3; + text-decoration: none; + background-color: #e9ecef; + border-color: #dee2e6; +} + +.page-link:focus { + z-index: 2; + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} + +.page-link:not(:disabled):not(.disabled) { + cursor: pointer; +} + +.page-item:first-child .page-link { + margin-left: 0; + border-top-left-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} + +.page-item:last-child .page-link { + border-top-right-radius: 0.25rem; + border-bottom-right-radius: 0.25rem; +} + +.page-item.active .page-link { + z-index: 1; + color: #fff; + background-color: #007bff; + border-color: #007bff; +} + +.page-item.disabled .page-link { + color: #6c757d; + pointer-events: none; + cursor: auto; + background-color: #fff; + border-color: #dee2e6; +} + +.pagination-lg .page-link { + padding: 0.75rem 1.5rem; + font-size: 1.25rem; + line-height: 1.5; +} + +.pagination-lg .page-item:first-child .page-link { + border-top-left-radius: 0.3rem; + border-bottom-left-radius: 0.3rem; +} + +.pagination-lg .page-item:last-child .page-link { + border-top-right-radius: 0.3rem; + border-bottom-right-radius: 0.3rem; +} + +.pagination-sm .page-link { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + line-height: 1.5; +} + +.pagination-sm .page-item:first-child .page-link { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; +} + +.pagination-sm .page-item:last-child .page-link { + border-top-right-radius: 0.2rem; + border-bottom-right-radius: 0.2rem; +} + +.badge { + display: inline-block; + padding: 0.25em 0.4em; + font-size: 75%; + font-weight: 700; + line-height: 1; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 0.25rem; +} + +.badge:empty { + display: none; +} + +.btn .badge { + position: relative; + top: -1px; +} + +.badge-pill { + padding-right: 0.6em; + padding-left: 0.6em; + border-radius: 10rem; +} + +.badge-primary { + color: #fff; + background-color: #007bff; +} + +.badge-primary[href]:hover, .badge-primary[href]:focus { + color: #fff; + text-decoration: none; + background-color: #0062cc; +} + +.badge-secondary { + color: #fff; + background-color: #6c757d; +} + +.badge-secondary[href]:hover, .badge-secondary[href]:focus { + color: #fff; + text-decoration: none; + background-color: #545b62; +} + +.badge-success { + color: #fff; + background-color: #28a745; +} + +.badge-success[href]:hover, .badge-success[href]:focus { + color: #fff; + text-decoration: none; + background-color: #1e7e34; +} + +.badge-info { + color: #fff; + background-color: #17a2b8; +} + +.badge-info[href]:hover, .badge-info[href]:focus { + color: #fff; + text-decoration: none; + background-color: #117a8b; +} + +.badge-warning { + color: #212529; + background-color: #ffc107; +} + +.badge-warning[href]:hover, .badge-warning[href]:focus { + color: #212529; + text-decoration: none; + background-color: #d39e00; +} + +.badge-danger { + color: #fff; + background-color: #dc3545; +} + +.badge-danger[href]:hover, .badge-danger[href]:focus { + color: #fff; + text-decoration: none; + background-color: #bd2130; +} + +.badge-light { + color: #212529; + background-color: #f8f9fa; +} + +.badge-light[href]:hover, .badge-light[href]:focus { + color: #212529; + text-decoration: none; + background-color: #dae0e5; +} + +.badge-dark { + color: #fff; + background-color: #343a40; +} + +.badge-dark[href]:hover, .badge-dark[href]:focus { + color: #fff; + text-decoration: none; + background-color: #1d2124; +} + +.jumbotron { + padding: 2rem 1rem; + margin-bottom: 2rem; + background-color: #e9ecef; + border-radius: 0.3rem; +} + +@media (min-width: 576px) { + .jumbotron { + padding: 4rem 2rem; + } +} + +.jumbotron-fluid { + padding-right: 0; + padding-left: 0; + border-radius: 0; +} + +.alert { + position: relative; + padding: 0.75rem 1.25rem; + margin-bottom: 1rem; + border: 1px solid transparent; + border-radius: 0.25rem; +} + +.alert-heading { + color: inherit; +} + +.alert-link { + font-weight: 700; +} + +.alert-dismissible { + padding-right: 4rem; +} + +.alert-dismissible .close { + position: absolute; + top: 0; + right: 0; + padding: 0.75rem 1.25rem; + color: inherit; +} + +.alert-primary { + color: #004085; + background-color: #cce5ff; + border-color: #b8daff; +} + +.alert-primary hr { + border-top-color: #9fcdff; +} + +.alert-primary .alert-link { + color: #002752; +} + +.alert-secondary { + color: #383d41; + background-color: #e2e3e5; + border-color: #d6d8db; +} + +.alert-secondary hr { + border-top-color: #c8cbcf; +} + +.alert-secondary .alert-link { + color: #202326; +} + +.alert-success { + color: #155724; + background-color: #d4edda; + border-color: #c3e6cb; +} + +.alert-success hr { + border-top-color: #b1dfbb; +} + +.alert-success .alert-link { + color: #0b2e13; +} + +.alert-info { + color: #0c5460; + background-color: #d1ecf1; + border-color: #bee5eb; +} + +.alert-info hr { + border-top-color: #abdde5; +} + +.alert-info .alert-link { + color: #062c33; +} + +.alert-warning { + color: #856404; + background-color: #fff3cd; + border-color: #ffeeba; +} + +.alert-warning hr { + border-top-color: #ffe8a1; +} + +.alert-warning .alert-link { + color: #533f03; +} + +.alert-danger { + color: #721c24; + background-color: #f8d7da; + border-color: #f5c6cb; +} + +.alert-danger hr { + border-top-color: #f1b0b7; +} + +.alert-danger .alert-link { + color: #491217; +} + +.alert-light { + color: #818182; + background-color: #fefefe; + border-color: #fdfdfe; +} + +.alert-light hr { + border-top-color: #ececf6; +} + +.alert-light .alert-link { + color: #686868; +} + +.alert-dark { + color: #1b1e21; + background-color: #d6d8d9; + border-color: #c6c8ca; +} + +.alert-dark hr { + border-top-color: #b9bbbe; +} + +.alert-dark .alert-link { + color: #040505; +} + +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 1rem 0; + } + to { + background-position: 0 0; + } +} + +@keyframes progress-bar-stripes { + from { + background-position: 1rem 0; + } + to { + background-position: 0 0; + } +} + +.progress { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + height: 1rem; + overflow: hidden; + font-size: 0.75rem; + background-color: #e9ecef; + border-radius: 0.25rem; +} + +.progress-bar { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + color: #fff; + text-align: center; + background-color: #007bff; + transition: width 0.6s ease; +} + +.progress-bar-striped { + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-size: 1rem 1rem; +} + +.progress-bar-animated { + -webkit-animation: progress-bar-stripes 1s linear infinite; + animation: progress-bar-stripes 1s linear infinite; +} + +.media { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: start; + -ms-flex-align: start; + align-items: flex-start; +} + +.media-body { + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1; +} + +.list-group { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; +} + +.list-group-item-action { + width: 100%; + color: #495057; + text-align: inherit; +} + +.list-group-item-action:hover, .list-group-item-action:focus { + color: #495057; + text-decoration: none; + background-color: #f8f9fa; +} + +.list-group-item-action:active { + color: #212529; + background-color: #e9ecef; +} + +.list-group-item { + position: relative; + display: block; + padding: 0.75rem 1.25rem; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid rgba(0, 0, 0, 0.125); +} + +.list-group-item:first-child { + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} + +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} + +.list-group-item:hover, .list-group-item:focus { + z-index: 1; + text-decoration: none; +} + +.list-group-item.disabled, .list-group-item:disabled { + color: #6c757d; + background-color: #fff; +} + +.list-group-item.active { + z-index: 2; + color: #fff; + background-color: #007bff; + border-color: #007bff; +} + +.list-group-flush .list-group-item { + border-right: 0; + border-left: 0; + border-radius: 0; +} + +.list-group-flush:first-child .list-group-item:first-child { + border-top: 0; +} + +.list-group-flush:last-child .list-group-item:last-child { + border-bottom: 0; +} + +.list-group-item-primary { + color: #004085; + background-color: #b8daff; +} + +.list-group-item-primary.list-group-item-action:hover, .list-group-item-primary.list-group-item-action:focus { + color: #004085; + background-color: #9fcdff; +} + +.list-group-item-primary.list-group-item-action.active { + color: #fff; + background-color: #004085; + border-color: #004085; +} + +.list-group-item-secondary { + color: #383d41; + background-color: #d6d8db; +} + +.list-group-item-secondary.list-group-item-action:hover, .list-group-item-secondary.list-group-item-action:focus { + color: #383d41; + background-color: #c8cbcf; +} + +.list-group-item-secondary.list-group-item-action.active { + color: #fff; + background-color: #383d41; + border-color: #383d41; +} + +.list-group-item-success { + color: #155724; + background-color: #c3e6cb; +} + +.list-group-item-success.list-group-item-action:hover, .list-group-item-success.list-group-item-action:focus { + color: #155724; + background-color: #b1dfbb; +} + +.list-group-item-success.list-group-item-action.active { + color: #fff; + background-color: #155724; + border-color: #155724; +} + +.list-group-item-info { + color: #0c5460; + background-color: #bee5eb; +} + +.list-group-item-info.list-group-item-action:hover, .list-group-item-info.list-group-item-action:focus { + color: #0c5460; + background-color: #abdde5; +} + +.list-group-item-info.list-group-item-action.active { + color: #fff; + background-color: #0c5460; + border-color: #0c5460; +} + +.list-group-item-warning { + color: #856404; + background-color: #ffeeba; +} + +.list-group-item-warning.list-group-item-action:hover, .list-group-item-warning.list-group-item-action:focus { + color: #856404; + background-color: #ffe8a1; +} + +.list-group-item-warning.list-group-item-action.active { + color: #fff; + background-color: #856404; + border-color: #856404; +} + +.list-group-item-danger { + color: #721c24; + background-color: #f5c6cb; +} + +.list-group-item-danger.list-group-item-action:hover, .list-group-item-danger.list-group-item-action:focus { + color: #721c24; + background-color: #f1b0b7; +} + +.list-group-item-danger.list-group-item-action.active { + color: #fff; + background-color: #721c24; + border-color: #721c24; +} + +.list-group-item-light { + color: #818182; + background-color: #fdfdfe; +} + +.list-group-item-light.list-group-item-action:hover, .list-group-item-light.list-group-item-action:focus { + color: #818182; + background-color: #ececf6; +} + +.list-group-item-light.list-group-item-action.active { + color: #fff; + background-color: #818182; + border-color: #818182; +} + +.list-group-item-dark { + color: #1b1e21; + background-color: #c6c8ca; +} + +.list-group-item-dark.list-group-item-action:hover, .list-group-item-dark.list-group-item-action:focus { + color: #1b1e21; + background-color: #b9bbbe; +} + +.list-group-item-dark.list-group-item-action.active { + color: #fff; + background-color: #1b1e21; + border-color: #1b1e21; +} + +.close { + float: right; + font-size: 1.5rem; + font-weight: 700; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + opacity: .5; +} + +.close:hover, .close:focus { + color: #000; + text-decoration: none; + opacity: .75; +} + +.close:not(:disabled):not(.disabled) { + cursor: pointer; +} + +button.close { + padding: 0; + background-color: transparent; + border: 0; + -webkit-appearance: none; +} + +.modal-open { + overflow: hidden; +} + +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + display: none; + overflow: hidden; + outline: 0; +} + +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} + +.modal-dialog { + position: relative; + width: auto; + margin: 0.5rem; + pointer-events: none; +} + +.modal.fade .modal-dialog { + transition: -webkit-transform 0.3s ease-out; + transition: transform 0.3s ease-out; + transition: transform 0.3s ease-out, -webkit-transform 0.3s ease-out; + -webkit-transform: translate(0, -25%); + transform: translate(0, -25%); +} + +.modal.show .modal-dialog { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); +} + +.modal-dialog-centered { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + min-height: calc(100% - (0.5rem * 2)); +} + +.modal-content { + position: relative; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -ms-flex-direction: column; + flex-direction: column; + width: 100%; + pointer-events: auto; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0.3rem; + outline: 0; +} + +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} + +.modal-backdrop.fade { + opacity: 0; +} + +.modal-backdrop.show { + opacity: 0.5; +} + +.modal-header { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: start; + -ms-flex-align: start; + align-items: flex-start; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; + padding: 1rem; + border-bottom: 1px solid #e9ecef; + border-top-left-radius: 0.3rem; + border-top-right-radius: 0.3rem; +} + +.modal-header .close { + padding: 1rem; + margin: -1rem -1rem -1rem auto; +} + +.modal-title { + margin-bottom: 0; + line-height: 1.5; +} + +.modal-body { + position: relative; + -webkit-box-flex: 1; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + padding: 1rem; +} + +.modal-footer { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: end; + -ms-flex-pack: end; + justify-content: flex-end; + padding: 1rem; + border-top: 1px solid #e9ecef; +} + +.modal-footer > :not(:first-child) { + margin-left: .25rem; +} + +.modal-footer > :not(:last-child) { + margin-right: .25rem; +} + +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} + +@media (min-width: 576px) { + .modal-dialog { + max-width: 500px; + margin: 1.75rem auto; + } + .modal-dialog-centered { + min-height: calc(100% - (1.75rem * 2)); + } + .modal-sm { + max-width: 300px; + } +} + +@media (min-width: 992px) { + .modal-lg { + max-width: 800px; + } +} + +.tooltip { + position: absolute; + z-index: 1070; + display: block; + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: 0.875rem; + word-wrap: break-word; + opacity: 0; +} + +.tooltip.show { + opacity: 0.9; +} + +.tooltip .arrow { + position: absolute; + display: block; + width: 0.8rem; + height: 0.4rem; +} + +.tooltip .arrow::before { + position: absolute; + content: ""; + border-color: transparent; + border-style: solid; +} + +.bs-tooltip-top, .bs-tooltip-auto[x-placement^="top"] { + padding: 0.4rem 0; +} + +.bs-tooltip-top .arrow, .bs-tooltip-auto[x-placement^="top"] .arrow { + bottom: 0; +} + +.bs-tooltip-top .arrow::before, .bs-tooltip-auto[x-placement^="top"] .arrow::before { + top: 0; + border-width: 0.4rem 0.4rem 0; + border-top-color: #000; +} + +.bs-tooltip-right, .bs-tooltip-auto[x-placement^="right"] { + padding: 0 0.4rem; +} + +.bs-tooltip-right .arrow, .bs-tooltip-auto[x-placement^="right"] .arrow { + left: 0; + width: 0.4rem; + height: 0.8rem; +} + +.bs-tooltip-right .arrow::before, .bs-tooltip-auto[x-placement^="right"] .arrow::before { + right: 0; + border-width: 0.4rem 0.4rem 0.4rem 0; + border-right-color: #000; +} + +.bs-tooltip-bottom, .bs-tooltip-auto[x-placement^="bottom"] { + padding: 0.4rem 0; +} + +.bs-tooltip-bottom .arrow, .bs-tooltip-auto[x-placement^="bottom"] .arrow { + top: 0; +} + +.bs-tooltip-bottom .arrow::before, .bs-tooltip-auto[x-placement^="bottom"] .arrow::before { + bottom: 0; + border-width: 0 0.4rem 0.4rem; + border-bottom-color: #000; +} + +.bs-tooltip-left, .bs-tooltip-auto[x-placement^="left"] { + padding: 0 0.4rem; +} + +.bs-tooltip-left .arrow, .bs-tooltip-auto[x-placement^="left"] .arrow { + right: 0; + width: 0.4rem; + height: 0.8rem; +} + +.bs-tooltip-left .arrow::before, .bs-tooltip-auto[x-placement^="left"] .arrow::before { + left: 0; + border-width: 0.4rem 0 0.4rem 0.4rem; + border-left-color: #000; +} + +.tooltip-inner { + max-width: 200px; + padding: 0.25rem 0.5rem; + color: #fff; + text-align: center; + background-color: #000; + border-radius: 0.25rem; +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: block; + max-width: 276px; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: 0.875rem; + word-wrap: break-word; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0.3rem; +} + +.popover .arrow { + position: absolute; + display: block; + width: 1rem; + height: 0.5rem; + margin: 0 0.3rem; +} + +.popover .arrow::before, .popover .arrow::after { + position: absolute; + display: block; + content: ""; + border-color: transparent; + border-style: solid; +} + +.bs-popover-top, .bs-popover-auto[x-placement^="top"] { + margin-bottom: 0.5rem; +} + +.bs-popover-top .arrow, .bs-popover-auto[x-placement^="top"] .arrow { + bottom: calc((0.5rem + 1px) * -1); +} + +.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^="top"] .arrow::before, +.bs-popover-top .arrow::after, .bs-popover-auto[x-placement^="top"] .arrow::after { + border-width: 0.5rem 0.5rem 0; +} + +.bs-popover-top .arrow::before, .bs-popover-auto[x-placement^="top"] .arrow::before { + bottom: 0; + border-top-color: rgba(0, 0, 0, 0.25); +} + +.bs-popover-top .arrow::after, .bs-popover-auto[x-placement^="top"] .arrow::after { + bottom: 1px; + border-top-color: #fff; +} + +.bs-popover-right, .bs-popover-auto[x-placement^="right"] { + margin-left: 0.5rem; +} + +.bs-popover-right .arrow, .bs-popover-auto[x-placement^="right"] .arrow { + left: calc((0.5rem + 1px) * -1); + width: 0.5rem; + height: 1rem; + margin: 0.3rem 0; +} + +.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^="right"] .arrow::before, +.bs-popover-right .arrow::after, .bs-popover-auto[x-placement^="right"] .arrow::after { + border-width: 0.5rem 0.5rem 0.5rem 0; +} + +.bs-popover-right .arrow::before, .bs-popover-auto[x-placement^="right"] .arrow::before { + left: 0; + border-right-color: rgba(0, 0, 0, 0.25); +} + +.bs-popover-right .arrow::after, .bs-popover-auto[x-placement^="right"] .arrow::after { + left: 1px; + border-right-color: #fff; +} + +.bs-popover-bottom, .bs-popover-auto[x-placement^="bottom"] { + margin-top: 0.5rem; +} + +.bs-popover-bottom .arrow, .bs-popover-auto[x-placement^="bottom"] .arrow { + top: calc((0.5rem + 1px) * -1); +} + +.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^="bottom"] .arrow::before, +.bs-popover-bottom .arrow::after, .bs-popover-auto[x-placement^="bottom"] .arrow::after { + border-width: 0 0.5rem 0.5rem 0.5rem; +} + +.bs-popover-bottom .arrow::before, .bs-popover-auto[x-placement^="bottom"] .arrow::before { + top: 0; + border-bottom-color: rgba(0, 0, 0, 0.25); +} + +.bs-popover-bottom .arrow::after, .bs-popover-auto[x-placement^="bottom"] .arrow::after { + top: 1px; + border-bottom-color: #fff; +} + +.bs-popover-bottom .popover-header::before, .bs-popover-auto[x-placement^="bottom"] .popover-header::before { + position: absolute; + top: 0; + left: 50%; + display: block; + width: 1rem; + margin-left: -0.5rem; + content: ""; + border-bottom: 1px solid #f7f7f7; +} + +.bs-popover-left, .bs-popover-auto[x-placement^="left"] { + margin-right: 0.5rem; +} + +.bs-popover-left .arrow, .bs-popover-auto[x-placement^="left"] .arrow { + right: calc((0.5rem + 1px) * -1); + width: 0.5rem; + height: 1rem; + margin: 0.3rem 0; +} + +.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^="left"] .arrow::before, +.bs-popover-left .arrow::after, .bs-popover-auto[x-placement^="left"] .arrow::after { + border-width: 0.5rem 0 0.5rem 0.5rem; +} + +.bs-popover-left .arrow::before, .bs-popover-auto[x-placement^="left"] .arrow::before { + right: 0; + border-left-color: rgba(0, 0, 0, 0.25); +} + +.bs-popover-left .arrow::after, .bs-popover-auto[x-placement^="left"] .arrow::after { + right: 1px; + border-left-color: #fff; +} + +.popover-header { + padding: 0.5rem 0.75rem; + margin-bottom: 0; + font-size: 1rem; + color: inherit; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-top-left-radius: calc(0.3rem - 1px); + border-top-right-radius: calc(0.3rem - 1px); +} + +.popover-header:empty { + display: none; +} + +.popover-body { + padding: 0.5rem 0.75rem; + color: #212529; +} + +.carousel { + position: relative; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel-item { + position: relative; + display: none; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + width: 100%; + transition: -webkit-transform 0.6s ease; + transition: transform 0.6s ease; + transition: transform 0.6s ease, -webkit-transform 0.6s ease; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-perspective: 1000px; + perspective: 1000px; +} + +.carousel-item.active, +.carousel-item-next, +.carousel-item-prev { + display: block; +} + +.carousel-item-next, +.carousel-item-prev { + position: absolute; + top: 0; +} + +.carousel-item-next.carousel-item-left, +.carousel-item-prev.carousel-item-right { + -webkit-transform: translateX(0); + transform: translateX(0); +} + +@supports ((-webkit-transform-style: preserve-3d) or (transform-style: preserve-3d)) { + .carousel-item-next.carousel-item-left, + .carousel-item-prev.carousel-item-right { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + } +} + +.carousel-item-next, +.active.carousel-item-right { + -webkit-transform: translateX(100%); + transform: translateX(100%); +} + +@supports ((-webkit-transform-style: preserve-3d) or (transform-style: preserve-3d)) { + .carousel-item-next, + .active.carousel-item-right { + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + } +} + +.carousel-item-prev, +.active.carousel-item-left { + -webkit-transform: translateX(-100%); + transform: translateX(-100%); +} + +@supports ((-webkit-transform-style: preserve-3d) or (transform-style: preserve-3d)) { + .carousel-item-prev, + .active.carousel-item-left { + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + } +} + +.carousel-control-prev, +.carousel-control-next { + position: absolute; + top: 0; + bottom: 0; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + width: 15%; + color: #fff; + text-align: center; + opacity: 0.5; +} + +.carousel-control-prev:hover, .carousel-control-prev:focus, +.carousel-control-next:hover, +.carousel-control-next:focus { + color: #fff; + text-decoration: none; + outline: 0; + opacity: .9; +} + +.carousel-control-prev { + left: 0; +} + +.carousel-control-next { + right: 0; +} + +.carousel-control-prev-icon, +.carousel-control-next-icon { + display: inline-block; + width: 20px; + height: 20px; + background: transparent no-repeat center center; + background-size: 100% 100%; +} + +.carousel-control-prev-icon { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E"); +} + +.carousel-control-next-icon { + background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E"); +} + +.carousel-indicators { + position: absolute; + right: 0; + bottom: 10px; + left: 0; + z-index: 15; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + justify-content: center; + padding-left: 0; + margin-right: 15%; + margin-left: 15%; + list-style: none; +} + +.carousel-indicators li { + position: relative; + -webkit-box-flex: 0; + -ms-flex: 0 1 auto; + flex: 0 1 auto; + width: 30px; + height: 3px; + margin-right: 3px; + margin-left: 3px; + text-indent: -999px; + background-color: rgba(255, 255, 255, 0.5); +} + +.carousel-indicators li::before { + position: absolute; + top: -10px; + left: 0; + display: inline-block; + width: 100%; + height: 10px; + content: ""; +} + +.carousel-indicators li::after { + position: absolute; + bottom: -10px; + left: 0; + display: inline-block; + width: 100%; + height: 10px; + content: ""; +} + +.carousel-indicators .active { + background-color: #fff; +} + +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; +} + +.align-baseline { + vertical-align: baseline !important; +} + +.align-top { + vertical-align: top !important; +} + +.align-middle { + vertical-align: middle !important; +} + +.align-bottom { + vertical-align: bottom !important; +} + +.align-text-bottom { + vertical-align: text-bottom !important; +} + +.align-text-top { + vertical-align: text-top !important; +} + +.bg-primary { + background-color: #007bff !important; +} + +a.bg-primary:hover, a.bg-primary:focus, +button.bg-primary:hover, +button.bg-primary:focus { + background-color: #0062cc !important; +} + +.bg-secondary { + background-color: #6c757d !important; +} + +a.bg-secondary:hover, a.bg-secondary:focus, +button.bg-secondary:hover, +button.bg-secondary:focus { + background-color: #545b62 !important; +} + +.bg-success { + background-color: #28a745 !important; +} + +a.bg-success:hover, a.bg-success:focus, +button.bg-success:hover, +button.bg-success:focus { + background-color: #1e7e34 !important; +} + +.bg-info { + background-color: #17a2b8 !important; +} + +a.bg-info:hover, a.bg-info:focus, +button.bg-info:hover, +button.bg-info:focus { + background-color: #117a8b !important; +} + +.bg-warning { + background-color: #ffc107 !important; +} + +a.bg-warning:hover, a.bg-warning:focus, +button.bg-warning:hover, +button.bg-warning:focus { + background-color: #d39e00 !important; +} + +.bg-danger { + background-color: #dc3545 !important; +} + +a.bg-danger:hover, a.bg-danger:focus, +button.bg-danger:hover, +button.bg-danger:focus { + background-color: #bd2130 !important; +} + +.bg-light { + background-color: #f8f9fa !important; +} + +a.bg-light:hover, a.bg-light:focus, +button.bg-light:hover, +button.bg-light:focus { + background-color: #dae0e5 !important; +} + +.bg-dark { + background-color: #343a40 !important; +} + +a.bg-dark:hover, a.bg-dark:focus, +button.bg-dark:hover, +button.bg-dark:focus { + background-color: #1d2124 !important; +} + +.bg-white { + background-color: #fff !important; +} + +.bg-transparent { + background-color: transparent !important; +} + +.border { + border: 1px solid #dee2e6 !important; +} + +.border-top { + border-top: 1px solid #dee2e6 !important; +} + +.border-right { + border-right: 1px solid #dee2e6 !important; +} + +.border-bottom { + border-bottom: 1px solid #dee2e6 !important; +} + +.border-left { + border-left: 1px solid #dee2e6 !important; +} + +.border-0 { + border: 0 !important; +} + +.border-top-0 { + border-top: 0 !important; +} + +.border-right-0 { + border-right: 0 !important; +} + +.border-bottom-0 { + border-bottom: 0 !important; +} + +.border-left-0 { + border-left: 0 !important; +} + +.border-primary { + border-color: #007bff !important; +} + +.border-secondary { + border-color: #6c757d !important; +} + +.border-success { + border-color: #28a745 !important; +} + +.border-info { + border-color: #17a2b8 !important; +} + +.border-warning { + border-color: #ffc107 !important; +} + +.border-danger { + border-color: #dc3545 !important; +} + +.border-light { + border-color: #f8f9fa !important; +} + +.border-dark { + border-color: #343a40 !important; +} + +.border-white { + border-color: #fff !important; +} + +.rounded { + border-radius: 0.25rem !important; +} + +.rounded-top { + border-top-left-radius: 0.25rem !important; + border-top-right-radius: 0.25rem !important; +} + +.rounded-right { + border-top-right-radius: 0.25rem !important; + border-bottom-right-radius: 0.25rem !important; +} + +.rounded-bottom { + border-bottom-right-radius: 0.25rem !important; + border-bottom-left-radius: 0.25rem !important; +} + +.rounded-left { + border-top-left-radius: 0.25rem !important; + border-bottom-left-radius: 0.25rem !important; +} + +.rounded-circle { + border-radius: 50% !important; +} + +.rounded-0 { + border-radius: 0 !important; +} + +.clearfix::after { + display: block; + clear: both; + content: ""; +} + +.d-none { + display: none !important; +} + +.d-inline { + display: inline !important; +} + +.d-inline-block { + display: inline-block !important; +} + +.d-block { + display: block !important; +} + +.d-table { + display: table !important; +} + +.d-table-row { + display: table-row !important; +} + +.d-table-cell { + display: table-cell !important; +} + +.d-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; +} + +.d-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; +} + +@media (min-width: 576px) { + .d-sm-none { + display: none !important; + } + .d-sm-inline { + display: inline !important; + } + .d-sm-inline-block { + display: inline-block !important; + } + .d-sm-block { + display: block !important; + } + .d-sm-table { + display: table !important; + } + .d-sm-table-row { + display: table-row !important; + } + .d-sm-table-cell { + display: table-cell !important; + } + .d-sm-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + .d-sm-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} + +@media (min-width: 768px) { + .d-md-none { + display: none !important; + } + .d-md-inline { + display: inline !important; + } + .d-md-inline-block { + display: inline-block !important; + } + .d-md-block { + display: block !important; + } + .d-md-table { + display: table !important; + } + .d-md-table-row { + display: table-row !important; + } + .d-md-table-cell { + display: table-cell !important; + } + .d-md-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + .d-md-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} + +@media (min-width: 992px) { + .d-lg-none { + display: none !important; + } + .d-lg-inline { + display: inline !important; + } + .d-lg-inline-block { + display: inline-block !important; + } + .d-lg-block { + display: block !important; + } + .d-lg-table { + display: table !important; + } + .d-lg-table-row { + display: table-row !important; + } + .d-lg-table-cell { + display: table-cell !important; + } + .d-lg-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + .d-lg-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} + +@media (min-width: 1200px) { + .d-xl-none { + display: none !important; + } + .d-xl-inline { + display: inline !important; + } + .d-xl-inline-block { + display: inline-block !important; + } + .d-xl-block { + display: block !important; + } + .d-xl-table { + display: table !important; + } + .d-xl-table-row { + display: table-row !important; + } + .d-xl-table-cell { + display: table-cell !important; + } + .d-xl-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + .d-xl-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} + +@media print { + .d-print-none { + display: none !important; + } + .d-print-inline { + display: inline !important; + } + .d-print-inline-block { + display: inline-block !important; + } + .d-print-block { + display: block !important; + } + .d-print-table { + display: table !important; + } + .d-print-table-row { + display: table-row !important; + } + .d-print-table-cell { + display: table-cell !important; + } + .d-print-flex { + display: -webkit-box !important; + display: -ms-flexbox !important; + display: flex !important; + } + .d-print-inline-flex { + display: -webkit-inline-box !important; + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} + +.embed-responsive { + position: relative; + display: block; + width: 100%; + padding: 0; + overflow: hidden; +} + +.embed-responsive::before { + display: block; + content: ""; +} + +.embed-responsive .embed-responsive-item, +.embed-responsive iframe, +.embed-responsive embed, +.embed-responsive object, +.embed-responsive video { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; +} + +.embed-responsive-21by9::before { + padding-top: 42.857143%; +} + +.embed-responsive-16by9::before { + padding-top: 56.25%; +} + +.embed-responsive-4by3::before { + padding-top: 75%; +} + +.embed-responsive-1by1::before { + padding-top: 100%; +} + +.flex-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; +} + +.flex-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; +} + +.flex-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; +} + +.flex-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; +} + +.flex-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; +} + +.flex-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; +} + +.flex-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; +} + +.justify-content-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; +} + +.justify-content-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; +} + +.justify-content-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; +} + +.justify-content-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; +} + +.justify-content-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; +} + +.align-items-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; +} + +.align-items-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; +} + +.align-items-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; +} + +.align-items-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; +} + +.align-items-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; +} + +.align-content-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; +} + +.align-content-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; +} + +.align-content-center { + -ms-flex-line-pack: center !important; + align-content: center !important; +} + +.align-content-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; +} + +.align-content-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; +} + +.align-content-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; +} + +.align-self-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; +} + +.align-self-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; +} + +.align-self-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; +} + +.align-self-center { + -ms-flex-item-align: center !important; + align-self: center !important; +} + +.align-self-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; +} + +.align-self-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; +} + +@media (min-width: 576px) { + .flex-sm-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; + } + .flex-sm-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; + } + .flex-sm-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + .flex-sm-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + .flex-sm-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + .flex-sm-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + .flex-sm-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + .justify-content-sm-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + .justify-content-sm-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + .justify-content-sm-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; + } + .justify-content-sm-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + .justify-content-sm-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + .align-items-sm-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; + } + .align-items-sm-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; + } + .align-items-sm-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; + } + .align-items-sm-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + .align-items-sm-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + .align-content-sm-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + .align-content-sm-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + .align-content-sm-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + .align-content-sm-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + .align-content-sm-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + .align-content-sm-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + .align-self-sm-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + .align-self-sm-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + .align-self-sm-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + .align-self-sm-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + .align-self-sm-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + .align-self-sm-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} + +@media (min-width: 768px) { + .flex-md-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; + } + .flex-md-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; + } + .flex-md-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + .flex-md-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + .flex-md-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + .flex-md-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + .flex-md-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + .justify-content-md-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + .justify-content-md-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + .justify-content-md-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; + } + .justify-content-md-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + .justify-content-md-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + .align-items-md-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; + } + .align-items-md-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; + } + .align-items-md-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; + } + .align-items-md-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + .align-items-md-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + .align-content-md-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + .align-content-md-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + .align-content-md-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + .align-content-md-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + .align-content-md-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + .align-content-md-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + .align-self-md-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + .align-self-md-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + .align-self-md-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + .align-self-md-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + .align-self-md-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + .align-self-md-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} + +@media (min-width: 992px) { + .flex-lg-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; + } + .flex-lg-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; + } + .flex-lg-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + .flex-lg-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + .flex-lg-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + .flex-lg-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + .flex-lg-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + .justify-content-lg-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + .justify-content-lg-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + .justify-content-lg-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; + } + .justify-content-lg-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + .justify-content-lg-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + .align-items-lg-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; + } + .align-items-lg-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; + } + .align-items-lg-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; + } + .align-items-lg-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + .align-items-lg-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + .align-content-lg-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + .align-content-lg-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + .align-content-lg-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + .align-content-lg-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + .align-content-lg-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + .align-content-lg-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + .align-self-lg-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + .align-self-lg-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + .align-self-lg-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + .align-self-lg-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + .align-self-lg-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + .align-self-lg-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} + +@media (min-width: 1200px) { + .flex-xl-row { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: row !important; + flex-direction: row !important; + } + .flex-xl-column { + -webkit-box-orient: vertical !important; + -webkit-box-direction: normal !important; + -ms-flex-direction: column !important; + flex-direction: column !important; + } + .flex-xl-row-reverse { + -webkit-box-orient: horizontal !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + .flex-xl-column-reverse { + -webkit-box-orient: vertical !important; + -webkit-box-direction: reverse !important; + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + .flex-xl-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + .flex-xl-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + .flex-xl-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + .justify-content-xl-start { + -webkit-box-pack: start !important; + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + .justify-content-xl-end { + -webkit-box-pack: end !important; + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + .justify-content-xl-center { + -webkit-box-pack: center !important; + -ms-flex-pack: center !important; + justify-content: center !important; + } + .justify-content-xl-between { + -webkit-box-pack: justify !important; + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + .justify-content-xl-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + .align-items-xl-start { + -webkit-box-align: start !important; + -ms-flex-align: start !important; + align-items: flex-start !important; + } + .align-items-xl-end { + -webkit-box-align: end !important; + -ms-flex-align: end !important; + align-items: flex-end !important; + } + .align-items-xl-center { + -webkit-box-align: center !important; + -ms-flex-align: center !important; + align-items: center !important; + } + .align-items-xl-baseline { + -webkit-box-align: baseline !important; + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + .align-items-xl-stretch { + -webkit-box-align: stretch !important; + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + .align-content-xl-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + .align-content-xl-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + .align-content-xl-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + .align-content-xl-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + .align-content-xl-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + .align-content-xl-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + .align-self-xl-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + .align-self-xl-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + .align-self-xl-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + .align-self-xl-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + .align-self-xl-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + .align-self-xl-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} + +.float-left { + float: left !important; +} + +.float-right { + float: right !important; +} + +.float-none { + float: none !important; +} + +@media (min-width: 576px) { + .float-sm-left { + float: left !important; + } + .float-sm-right { + float: right !important; + } + .float-sm-none { + float: none !important; + } +} + +@media (min-width: 768px) { + .float-md-left { + float: left !important; + } + .float-md-right { + float: right !important; + } + .float-md-none { + float: none !important; + } +} + +@media (min-width: 992px) { + .float-lg-left { + float: left !important; + } + .float-lg-right { + float: right !important; + } + .float-lg-none { + float: none !important; + } +} + +@media (min-width: 1200px) { + .float-xl-left { + float: left !important; + } + .float-xl-right { + float: right !important; + } + .float-xl-none { + float: none !important; + } +} + +.position-static { + position: static !important; +} + +.position-relative { + position: relative !important; +} + +.position-absolute { + position: absolute !important; +} + +.position-fixed { + position: fixed !important; +} + +.position-sticky { + position: -webkit-sticky !important; + position: sticky !important; +} + +.fixed-top { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 1030; +} + +.fixed-bottom { + position: fixed; + right: 0; + bottom: 0; + left: 0; + z-index: 1030; +} + +@supports ((position: -webkit-sticky) or (position: sticky)) { + .sticky-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020; + } +} + +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + -webkit-clip-path: inset(50%); + clip-path: inset(50%); + border: 0; +} + +.sr-only-focusable:active, .sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + overflow: visible; + clip: auto; + white-space: normal; + -webkit-clip-path: none; + clip-path: none; +} + +.w-25 { + width: 25% !important; +} + +.w-50 { + width: 50% !important; +} + +.w-75 { + width: 75% !important; +} + +.w-100 { + width: 100% !important; +} + +.h-25 { + height: 25% !important; +} + +.h-50 { + height: 50% !important; +} + +.h-75 { + height: 75% !important; +} + +.h-100 { + height: 100% !important; +} + +.mw-100 { + max-width: 100% !important; +} + +.mh-100 { + max-height: 100% !important; +} + +.m-0 { + margin: 0 !important; +} + +.mt-0, +.my-0 { + margin-top: 0 !important; +} + +.mr-0, +.mx-0 { + margin-right: 0 !important; +} + +.mb-0, +.my-0 { + margin-bottom: 0 !important; +} + +.ml-0, +.mx-0 { + margin-left: 0 !important; +} + +.m-1 { + margin: 0.25rem !important; +} + +.mt-1, +.my-1 { + margin-top: 0.25rem !important; +} + +.mr-1, +.mx-1 { + margin-right: 0.25rem !important; +} + +.mb-1, +.my-1 { + margin-bottom: 0.25rem !important; +} + +.ml-1, +.mx-1 { + margin-left: 0.25rem !important; +} + +.m-2 { + margin: 0.5rem !important; +} + +.mt-2, +.my-2 { + margin-top: 0.5rem !important; +} + +.mr-2, +.mx-2 { + margin-right: 0.5rem !important; +} + +.mb-2, +.my-2 { + margin-bottom: 0.5rem !important; +} + +.ml-2, +.mx-2 { + margin-left: 0.5rem !important; +} + +.m-3 { + margin: 1rem !important; +} + +.mt-3, +.my-3 { + margin-top: 1rem !important; +} + +.mr-3, +.mx-3 { + margin-right: 1rem !important; +} + +.mb-3, +.my-3 { + margin-bottom: 1rem !important; +} + +.ml-3, +.mx-3 { + margin-left: 1rem !important; +} + +.m-4 { + margin: 1.5rem !important; +} + +.mt-4, +.my-4 { + margin-top: 1.5rem !important; +} + +.mr-4, +.mx-4 { + margin-right: 1.5rem !important; +} + +.mb-4, +.my-4 { + margin-bottom: 1.5rem !important; +} + +.ml-4, +.mx-4 { + margin-left: 1.5rem !important; +} + +.m-5 { + margin: 3rem !important; +} + +.mt-5, +.my-5 { + margin-top: 3rem !important; +} + +.mr-5, +.mx-5 { + margin-right: 3rem !important; +} + +.mb-5, +.my-5 { + margin-bottom: 3rem !important; +} + +.ml-5, +.mx-5 { + margin-left: 3rem !important; +} + +.p-0 { + padding: 0 !important; +} + +.pt-0, +.py-0 { + padding-top: 0 !important; +} + +.pr-0, +.px-0 { + padding-right: 0 !important; +} + +.pb-0, +.py-0 { + padding-bottom: 0 !important; +} + +.pl-0, +.px-0 { + padding-left: 0 !important; +} + +.p-1 { + padding: 0.25rem !important; +} + +.pt-1, +.py-1 { + padding-top: 0.25rem !important; +} + +.pr-1, +.px-1 { + padding-right: 0.25rem !important; +} + +.pb-1, +.py-1 { + padding-bottom: 0.25rem !important; +} + +.pl-1, +.px-1 { + padding-left: 0.25rem !important; +} + +.p-2 { + padding: 0.5rem !important; +} + +.pt-2, +.py-2 { + padding-top: 0.5rem !important; +} + +.pr-2, +.px-2 { + padding-right: 0.5rem !important; +} + +.pb-2, +.py-2 { + padding-bottom: 0.5rem !important; +} + +.pl-2, +.px-2 { + padding-left: 0.5rem !important; +} + +.p-3 { + padding: 1rem !important; +} + +.pt-3, +.py-3 { + padding-top: 1rem !important; +} + +.pr-3, +.px-3 { + padding-right: 1rem !important; +} + +.pb-3, +.py-3 { + padding-bottom: 1rem !important; +} + +.pl-3, +.px-3 { + padding-left: 1rem !important; +} + +.p-4 { + padding: 1.5rem !important; +} + +.pt-4, +.py-4 { + padding-top: 1.5rem !important; +} + +.pr-4, +.px-4 { + padding-right: 1.5rem !important; +} + +.pb-4, +.py-4 { + padding-bottom: 1.5rem !important; +} + +.pl-4, +.px-4 { + padding-left: 1.5rem !important; +} + +.p-5 { + padding: 3rem !important; +} + +.pt-5, +.py-5 { + padding-top: 3rem !important; +} + +.pr-5, +.px-5 { + padding-right: 3rem !important; +} + +.pb-5, +.py-5 { + padding-bottom: 3rem !important; +} + +.pl-5, +.px-5 { + padding-left: 3rem !important; +} + +.m-auto { + margin: auto !important; +} + +.mt-auto, +.my-auto { + margin-top: auto !important; +} + +.mr-auto, +.mx-auto { + margin-right: auto !important; +} + +.mb-auto, +.my-auto { + margin-bottom: auto !important; +} + +.ml-auto, +.mx-auto { + margin-left: auto !important; +} + +@media (min-width: 576px) { + .m-sm-0 { + margin: 0 !important; + } + .mt-sm-0, + .my-sm-0 { + margin-top: 0 !important; + } + .mr-sm-0, + .mx-sm-0 { + margin-right: 0 !important; + } + .mb-sm-0, + .my-sm-0 { + margin-bottom: 0 !important; + } + .ml-sm-0, + .mx-sm-0 { + margin-left: 0 !important; + } + .m-sm-1 { + margin: 0.25rem !important; + } + .mt-sm-1, + .my-sm-1 { + margin-top: 0.25rem !important; + } + .mr-sm-1, + .mx-sm-1 { + margin-right: 0.25rem !important; + } + .mb-sm-1, + .my-sm-1 { + margin-bottom: 0.25rem !important; + } + .ml-sm-1, + .mx-sm-1 { + margin-left: 0.25rem !important; + } + .m-sm-2 { + margin: 0.5rem !important; + } + .mt-sm-2, + .my-sm-2 { + margin-top: 0.5rem !important; + } + .mr-sm-2, + .mx-sm-2 { + margin-right: 0.5rem !important; + } + .mb-sm-2, + .my-sm-2 { + margin-bottom: 0.5rem !important; + } + .ml-sm-2, + .mx-sm-2 { + margin-left: 0.5rem !important; + } + .m-sm-3 { + margin: 1rem !important; + } + .mt-sm-3, + .my-sm-3 { + margin-top: 1rem !important; + } + .mr-sm-3, + .mx-sm-3 { + margin-right: 1rem !important; + } + .mb-sm-3, + .my-sm-3 { + margin-bottom: 1rem !important; + } + .ml-sm-3, + .mx-sm-3 { + margin-left: 1rem !important; + } + .m-sm-4 { + margin: 1.5rem !important; + } + .mt-sm-4, + .my-sm-4 { + margin-top: 1.5rem !important; + } + .mr-sm-4, + .mx-sm-4 { + margin-right: 1.5rem !important; + } + .mb-sm-4, + .my-sm-4 { + margin-bottom: 1.5rem !important; + } + .ml-sm-4, + .mx-sm-4 { + margin-left: 1.5rem !important; + } + .m-sm-5 { + margin: 3rem !important; + } + .mt-sm-5, + .my-sm-5 { + margin-top: 3rem !important; + } + .mr-sm-5, + .mx-sm-5 { + margin-right: 3rem !important; + } + .mb-sm-5, + .my-sm-5 { + margin-bottom: 3rem !important; + } + .ml-sm-5, + .mx-sm-5 { + margin-left: 3rem !important; + } + .p-sm-0 { + padding: 0 !important; + } + .pt-sm-0, + .py-sm-0 { + padding-top: 0 !important; + } + .pr-sm-0, + .px-sm-0 { + padding-right: 0 !important; + } + .pb-sm-0, + .py-sm-0 { + padding-bottom: 0 !important; + } + .pl-sm-0, + .px-sm-0 { + padding-left: 0 !important; + } + .p-sm-1 { + padding: 0.25rem !important; + } + .pt-sm-1, + .py-sm-1 { + padding-top: 0.25rem !important; + } + .pr-sm-1, + .px-sm-1 { + padding-right: 0.25rem !important; + } + .pb-sm-1, + .py-sm-1 { + padding-bottom: 0.25rem !important; + } + .pl-sm-1, + .px-sm-1 { + padding-left: 0.25rem !important; + } + .p-sm-2 { + padding: 0.5rem !important; + } + .pt-sm-2, + .py-sm-2 { + padding-top: 0.5rem !important; + } + .pr-sm-2, + .px-sm-2 { + padding-right: 0.5rem !important; + } + .pb-sm-2, + .py-sm-2 { + padding-bottom: 0.5rem !important; + } + .pl-sm-2, + .px-sm-2 { + padding-left: 0.5rem !important; + } + .p-sm-3 { + padding: 1rem !important; + } + .pt-sm-3, + .py-sm-3 { + padding-top: 1rem !important; + } + .pr-sm-3, + .px-sm-3 { + padding-right: 1rem !important; + } + .pb-sm-3, + .py-sm-3 { + padding-bottom: 1rem !important; + } + .pl-sm-3, + .px-sm-3 { + padding-left: 1rem !important; + } + .p-sm-4 { + padding: 1.5rem !important; + } + .pt-sm-4, + .py-sm-4 { + padding-top: 1.5rem !important; + } + .pr-sm-4, + .px-sm-4 { + padding-right: 1.5rem !important; + } + .pb-sm-4, + .py-sm-4 { + padding-bottom: 1.5rem !important; + } + .pl-sm-4, + .px-sm-4 { + padding-left: 1.5rem !important; + } + .p-sm-5 { + padding: 3rem !important; + } + .pt-sm-5, + .py-sm-5 { + padding-top: 3rem !important; + } + .pr-sm-5, + .px-sm-5 { + padding-right: 3rem !important; + } + .pb-sm-5, + .py-sm-5 { + padding-bottom: 3rem !important; + } + .pl-sm-5, + .px-sm-5 { + padding-left: 3rem !important; + } + .m-sm-auto { + margin: auto !important; + } + .mt-sm-auto, + .my-sm-auto { + margin-top: auto !important; + } + .mr-sm-auto, + .mx-sm-auto { + margin-right: auto !important; + } + .mb-sm-auto, + .my-sm-auto { + margin-bottom: auto !important; + } + .ml-sm-auto, + .mx-sm-auto { + margin-left: auto !important; + } +} + +@media (min-width: 768px) { + .m-md-0 { + margin: 0 !important; + } + .mt-md-0, + .my-md-0 { + margin-top: 0 !important; + } + .mr-md-0, + .mx-md-0 { + margin-right: 0 !important; + } + .mb-md-0, + .my-md-0 { + margin-bottom: 0 !important; + } + .ml-md-0, + .mx-md-0 { + margin-left: 0 !important; + } + .m-md-1 { + margin: 0.25rem !important; + } + .mt-md-1, + .my-md-1 { + margin-top: 0.25rem !important; + } + .mr-md-1, + .mx-md-1 { + margin-right: 0.25rem !important; + } + .mb-md-1, + .my-md-1 { + margin-bottom: 0.25rem !important; + } + .ml-md-1, + .mx-md-1 { + margin-left: 0.25rem !important; + } + .m-md-2 { + margin: 0.5rem !important; + } + .mt-md-2, + .my-md-2 { + margin-top: 0.5rem !important; + } + .mr-md-2, + .mx-md-2 { + margin-right: 0.5rem !important; + } + .mb-md-2, + .my-md-2 { + margin-bottom: 0.5rem !important; + } + .ml-md-2, + .mx-md-2 { + margin-left: 0.5rem !important; + } + .m-md-3 { + margin: 1rem !important; + } + .mt-md-3, + .my-md-3 { + margin-top: 1rem !important; + } + .mr-md-3, + .mx-md-3 { + margin-right: 1rem !important; + } + .mb-md-3, + .my-md-3 { + margin-bottom: 1rem !important; + } + .ml-md-3, + .mx-md-3 { + margin-left: 1rem !important; + } + .m-md-4 { + margin: 1.5rem !important; + } + .mt-md-4, + .my-md-4 { + margin-top: 1.5rem !important; + } + .mr-md-4, + .mx-md-4 { + margin-right: 1.5rem !important; + } + .mb-md-4, + .my-md-4 { + margin-bottom: 1.5rem !important; + } + .ml-md-4, + .mx-md-4 { + margin-left: 1.5rem !important; + } + .m-md-5 { + margin: 3rem !important; + } + .mt-md-5, + .my-md-5 { + margin-top: 3rem !important; + } + .mr-md-5, + .mx-md-5 { + margin-right: 3rem !important; + } + .mb-md-5, + .my-md-5 { + margin-bottom: 3rem !important; + } + .ml-md-5, + .mx-md-5 { + margin-left: 3rem !important; + } + .p-md-0 { + padding: 0 !important; + } + .pt-md-0, + .py-md-0 { + padding-top: 0 !important; + } + .pr-md-0, + .px-md-0 { + padding-right: 0 !important; + } + .pb-md-0, + .py-md-0 { + padding-bottom: 0 !important; + } + .pl-md-0, + .px-md-0 { + padding-left: 0 !important; + } + .p-md-1 { + padding: 0.25rem !important; + } + .pt-md-1, + .py-md-1 { + padding-top: 0.25rem !important; + } + .pr-md-1, + .px-md-1 { + padding-right: 0.25rem !important; + } + .pb-md-1, + .py-md-1 { + padding-bottom: 0.25rem !important; + } + .pl-md-1, + .px-md-1 { + padding-left: 0.25rem !important; + } + .p-md-2 { + padding: 0.5rem !important; + } + .pt-md-2, + .py-md-2 { + padding-top: 0.5rem !important; + } + .pr-md-2, + .px-md-2 { + padding-right: 0.5rem !important; + } + .pb-md-2, + .py-md-2 { + padding-bottom: 0.5rem !important; + } + .pl-md-2, + .px-md-2 { + padding-left: 0.5rem !important; + } + .p-md-3 { + padding: 1rem !important; + } + .pt-md-3, + .py-md-3 { + padding-top: 1rem !important; + } + .pr-md-3, + .px-md-3 { + padding-right: 1rem !important; + } + .pb-md-3, + .py-md-3 { + padding-bottom: 1rem !important; + } + .pl-md-3, + .px-md-3 { + padding-left: 1rem !important; + } + .p-md-4 { + padding: 1.5rem !important; + } + .pt-md-4, + .py-md-4 { + padding-top: 1.5rem !important; + } + .pr-md-4, + .px-md-4 { + padding-right: 1.5rem !important; + } + .pb-md-4, + .py-md-4 { + padding-bottom: 1.5rem !important; + } + .pl-md-4, + .px-md-4 { + padding-left: 1.5rem !important; + } + .p-md-5 { + padding: 3rem !important; + } + .pt-md-5, + .py-md-5 { + padding-top: 3rem !important; + } + .pr-md-5, + .px-md-5 { + padding-right: 3rem !important; + } + .pb-md-5, + .py-md-5 { + padding-bottom: 3rem !important; + } + .pl-md-5, + .px-md-5 { + padding-left: 3rem !important; + } + .m-md-auto { + margin: auto !important; + } + .mt-md-auto, + .my-md-auto { + margin-top: auto !important; + } + .mr-md-auto, + .mx-md-auto { + margin-right: auto !important; + } + .mb-md-auto, + .my-md-auto { + margin-bottom: auto !important; + } + .ml-md-auto, + .mx-md-auto { + margin-left: auto !important; + } +} + +@media (min-width: 992px) { + .m-lg-0 { + margin: 0 !important; + } + .mt-lg-0, + .my-lg-0 { + margin-top: 0 !important; + } + .mr-lg-0, + .mx-lg-0 { + margin-right: 0 !important; + } + .mb-lg-0, + .my-lg-0 { + margin-bottom: 0 !important; + } + .ml-lg-0, + .mx-lg-0 { + margin-left: 0 !important; + } + .m-lg-1 { + margin: 0.25rem !important; + } + .mt-lg-1, + .my-lg-1 { + margin-top: 0.25rem !important; + } + .mr-lg-1, + .mx-lg-1 { + margin-right: 0.25rem !important; + } + .mb-lg-1, + .my-lg-1 { + margin-bottom: 0.25rem !important; + } + .ml-lg-1, + .mx-lg-1 { + margin-left: 0.25rem !important; + } + .m-lg-2 { + margin: 0.5rem !important; + } + .mt-lg-2, + .my-lg-2 { + margin-top: 0.5rem !important; + } + .mr-lg-2, + .mx-lg-2 { + margin-right: 0.5rem !important; + } + .mb-lg-2, + .my-lg-2 { + margin-bottom: 0.5rem !important; + } + .ml-lg-2, + .mx-lg-2 { + margin-left: 0.5rem !important; + } + .m-lg-3 { + margin: 1rem !important; + } + .mt-lg-3, + .my-lg-3 { + margin-top: 1rem !important; + } + .mr-lg-3, + .mx-lg-3 { + margin-right: 1rem !important; + } + .mb-lg-3, + .my-lg-3 { + margin-bottom: 1rem !important; + } + .ml-lg-3, + .mx-lg-3 { + margin-left: 1rem !important; + } + .m-lg-4 { + margin: 1.5rem !important; + } + .mt-lg-4, + .my-lg-4 { + margin-top: 1.5rem !important; + } + .mr-lg-4, + .mx-lg-4 { + margin-right: 1.5rem !important; + } + .mb-lg-4, + .my-lg-4 { + margin-bottom: 1.5rem !important; + } + .ml-lg-4, + .mx-lg-4 { + margin-left: 1.5rem !important; + } + .m-lg-5 { + margin: 3rem !important; + } + .mt-lg-5, + .my-lg-5 { + margin-top: 3rem !important; + } + .mr-lg-5, + .mx-lg-5 { + margin-right: 3rem !important; + } + .mb-lg-5, + .my-lg-5 { + margin-bottom: 3rem !important; + } + .ml-lg-5, + .mx-lg-5 { + margin-left: 3rem !important; + } + .p-lg-0 { + padding: 0 !important; + } + .pt-lg-0, + .py-lg-0 { + padding-top: 0 !important; + } + .pr-lg-0, + .px-lg-0 { + padding-right: 0 !important; + } + .pb-lg-0, + .py-lg-0 { + padding-bottom: 0 !important; + } + .pl-lg-0, + .px-lg-0 { + padding-left: 0 !important; + } + .p-lg-1 { + padding: 0.25rem !important; + } + .pt-lg-1, + .py-lg-1 { + padding-top: 0.25rem !important; + } + .pr-lg-1, + .px-lg-1 { + padding-right: 0.25rem !important; + } + .pb-lg-1, + .py-lg-1 { + padding-bottom: 0.25rem !important; + } + .pl-lg-1, + .px-lg-1 { + padding-left: 0.25rem !important; + } + .p-lg-2 { + padding: 0.5rem !important; + } + .pt-lg-2, + .py-lg-2 { + padding-top: 0.5rem !important; + } + .pr-lg-2, + .px-lg-2 { + padding-right: 0.5rem !important; + } + .pb-lg-2, + .py-lg-2 { + padding-bottom: 0.5rem !important; + } + .pl-lg-2, + .px-lg-2 { + padding-left: 0.5rem !important; + } + .p-lg-3 { + padding: 1rem !important; + } + .pt-lg-3, + .py-lg-3 { + padding-top: 1rem !important; + } + .pr-lg-3, + .px-lg-3 { + padding-right: 1rem !important; + } + .pb-lg-3, + .py-lg-3 { + padding-bottom: 1rem !important; + } + .pl-lg-3, + .px-lg-3 { + padding-left: 1rem !important; + } + .p-lg-4 { + padding: 1.5rem !important; + } + .pt-lg-4, + .py-lg-4 { + padding-top: 1.5rem !important; + } + .pr-lg-4, + .px-lg-4 { + padding-right: 1.5rem !important; + } + .pb-lg-4, + .py-lg-4 { + padding-bottom: 1.5rem !important; + } + .pl-lg-4, + .px-lg-4 { + padding-left: 1.5rem !important; + } + .p-lg-5 { + padding: 3rem !important; + } + .pt-lg-5, + .py-lg-5 { + padding-top: 3rem !important; + } + .pr-lg-5, + .px-lg-5 { + padding-right: 3rem !important; + } + .pb-lg-5, + .py-lg-5 { + padding-bottom: 3rem !important; + } + .pl-lg-5, + .px-lg-5 { + padding-left: 3rem !important; + } + .m-lg-auto { + margin: auto !important; + } + .mt-lg-auto, + .my-lg-auto { + margin-top: auto !important; + } + .mr-lg-auto, + .mx-lg-auto { + margin-right: auto !important; + } + .mb-lg-auto, + .my-lg-auto { + margin-bottom: auto !important; + } + .ml-lg-auto, + .mx-lg-auto { + margin-left: auto !important; + } +} + +@media (min-width: 1200px) { + .m-xl-0 { + margin: 0 !important; + } + .mt-xl-0, + .my-xl-0 { + margin-top: 0 !important; + } + .mr-xl-0, + .mx-xl-0 { + margin-right: 0 !important; + } + .mb-xl-0, + .my-xl-0 { + margin-bottom: 0 !important; + } + .ml-xl-0, + .mx-xl-0 { + margin-left: 0 !important; + } + .m-xl-1 { + margin: 0.25rem !important; + } + .mt-xl-1, + .my-xl-1 { + margin-top: 0.25rem !important; + } + .mr-xl-1, + .mx-xl-1 { + margin-right: 0.25rem !important; + } + .mb-xl-1, + .my-xl-1 { + margin-bottom: 0.25rem !important; + } + .ml-xl-1, + .mx-xl-1 { + margin-left: 0.25rem !important; + } + .m-xl-2 { + margin: 0.5rem !important; + } + .mt-xl-2, + .my-xl-2 { + margin-top: 0.5rem !important; + } + .mr-xl-2, + .mx-xl-2 { + margin-right: 0.5rem !important; + } + .mb-xl-2, + .my-xl-2 { + margin-bottom: 0.5rem !important; + } + .ml-xl-2, + .mx-xl-2 { + margin-left: 0.5rem !important; + } + .m-xl-3 { + margin: 1rem !important; + } + .mt-xl-3, + .my-xl-3 { + margin-top: 1rem !important; + } + .mr-xl-3, + .mx-xl-3 { + margin-right: 1rem !important; + } + .mb-xl-3, + .my-xl-3 { + margin-bottom: 1rem !important; + } + .ml-xl-3, + .mx-xl-3 { + margin-left: 1rem !important; + } + .m-xl-4 { + margin: 1.5rem !important; + } + .mt-xl-4, + .my-xl-4 { + margin-top: 1.5rem !important; + } + .mr-xl-4, + .mx-xl-4 { + margin-right: 1.5rem !important; + } + .mb-xl-4, + .my-xl-4 { + margin-bottom: 1.5rem !important; + } + .ml-xl-4, + .mx-xl-4 { + margin-left: 1.5rem !important; + } + .m-xl-5 { + margin: 3rem !important; + } + .mt-xl-5, + .my-xl-5 { + margin-top: 3rem !important; + } + .mr-xl-5, + .mx-xl-5 { + margin-right: 3rem !important; + } + .mb-xl-5, + .my-xl-5 { + margin-bottom: 3rem !important; + } + .ml-xl-5, + .mx-xl-5 { + margin-left: 3rem !important; + } + .p-xl-0 { + padding: 0 !important; + } + .pt-xl-0, + .py-xl-0 { + padding-top: 0 !important; + } + .pr-xl-0, + .px-xl-0 { + padding-right: 0 !important; + } + .pb-xl-0, + .py-xl-0 { + padding-bottom: 0 !important; + } + .pl-xl-0, + .px-xl-0 { + padding-left: 0 !important; + } + .p-xl-1 { + padding: 0.25rem !important; + } + .pt-xl-1, + .py-xl-1 { + padding-top: 0.25rem !important; + } + .pr-xl-1, + .px-xl-1 { + padding-right: 0.25rem !important; + } + .pb-xl-1, + .py-xl-1 { + padding-bottom: 0.25rem !important; + } + .pl-xl-1, + .px-xl-1 { + padding-left: 0.25rem !important; + } + .p-xl-2 { + padding: 0.5rem !important; + } + .pt-xl-2, + .py-xl-2 { + padding-top: 0.5rem !important; + } + .pr-xl-2, + .px-xl-2 { + padding-right: 0.5rem !important; + } + .pb-xl-2, + .py-xl-2 { + padding-bottom: 0.5rem !important; + } + .pl-xl-2, + .px-xl-2 { + padding-left: 0.5rem !important; + } + .p-xl-3 { + padding: 1rem !important; + } + .pt-xl-3, + .py-xl-3 { + padding-top: 1rem !important; + } + .pr-xl-3, + .px-xl-3 { + padding-right: 1rem !important; + } + .pb-xl-3, + .py-xl-3 { + padding-bottom: 1rem !important; + } + .pl-xl-3, + .px-xl-3 { + padding-left: 1rem !important; + } + .p-xl-4 { + padding: 1.5rem !important; + } + .pt-xl-4, + .py-xl-4 { + padding-top: 1.5rem !important; + } + .pr-xl-4, + .px-xl-4 { + padding-right: 1.5rem !important; + } + .pb-xl-4, + .py-xl-4 { + padding-bottom: 1.5rem !important; + } + .pl-xl-4, + .px-xl-4 { + padding-left: 1.5rem !important; + } + .p-xl-5 { + padding: 3rem !important; + } + .pt-xl-5, + .py-xl-5 { + padding-top: 3rem !important; + } + .pr-xl-5, + .px-xl-5 { + padding-right: 3rem !important; + } + .pb-xl-5, + .py-xl-5 { + padding-bottom: 3rem !important; + } + .pl-xl-5, + .px-xl-5 { + padding-left: 3rem !important; + } + .m-xl-auto { + margin: auto !important; + } + .mt-xl-auto, + .my-xl-auto { + margin-top: auto !important; + } + .mr-xl-auto, + .mx-xl-auto { + margin-right: auto !important; + } + .mb-xl-auto, + .my-xl-auto { + margin-bottom: auto !important; + } + .ml-xl-auto, + .mx-xl-auto { + margin-left: auto !important; + } +} + +.text-justify { + text-align: justify !important; +} + +.text-nowrap { + white-space: nowrap !important; +} + +.text-truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.text-left { + text-align: left !important; +} + +.text-right { + text-align: right !important; +} + +.text-center { + text-align: center !important; +} + +@media (min-width: 576px) { + .text-sm-left { + text-align: left !important; + } + .text-sm-right { + text-align: right !important; + } + .text-sm-center { + text-align: center !important; + } +} + +@media (min-width: 768px) { + .text-md-left { + text-align: left !important; + } + .text-md-right { + text-align: right !important; + } + .text-md-center { + text-align: center !important; + } +} + +@media (min-width: 992px) { + .text-lg-left { + text-align: left !important; + } + .text-lg-right { + text-align: right !important; + } + .text-lg-center { + text-align: center !important; + } +} + +@media (min-width: 1200px) { + .text-xl-left { + text-align: left !important; + } + .text-xl-right { + text-align: right !important; + } + .text-xl-center { + text-align: center !important; + } +} + +.text-lowercase { + text-transform: lowercase !important; +} + +.text-uppercase { + text-transform: uppercase !important; +} + +.text-capitalize { + text-transform: capitalize !important; +} + +.font-weight-light { + font-weight: 300 !important; +} + +.font-weight-normal { + font-weight: 400 !important; +} + +.font-weight-bold { + font-weight: 700 !important; +} + +.font-italic { + font-style: italic !important; +} + +.text-white { + color: #fff !important; +} + +.text-primary { + color: #007bff !important; +} + +a.text-primary:hover, a.text-primary:focus { + color: #0062cc !important; +} + +.text-secondary { + color: #6c757d !important; +} + +a.text-secondary:hover, a.text-secondary:focus { + color: #545b62 !important; +} + +.text-success { + color: #28a745 !important; +} + +a.text-success:hover, a.text-success:focus { + color: #1e7e34 !important; +} + +.text-info { + color: #17a2b8 !important; +} + +a.text-info:hover, a.text-info:focus { + color: #117a8b !important; +} + +.text-warning { + color: #ffc107 !important; +} + +a.text-warning:hover, a.text-warning:focus { + color: #d39e00 !important; +} + +.text-danger { + color: #dc3545 !important; +} + +a.text-danger:hover, a.text-danger:focus { + color: #bd2130 !important; +} + +.text-light { + color: #f8f9fa !important; +} + +a.text-light:hover, a.text-light:focus { + color: #dae0e5 !important; +} + +.text-dark { + color: #343a40 !important; +} + +a.text-dark:hover, a.text-dark:focus { + color: #1d2124 !important; +} + +.text-muted { + color: #6c757d !important; +} + +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.visible { + visibility: visible !important; +} + +.invisible { + visibility: hidden !important; +} + +@media print { + *, + *::before, + *::after { + text-shadow: none !important; + box-shadow: none !important; + } + a:not(.btn) { + text-decoration: underline; + } + abbr[title]::after { + content: " (" attr(title) ")"; + } + pre { + white-space: pre-wrap !important; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + @page { + size: a3; + } + body { + min-width: 992px !important; + } + .container { + min-width: 992px !important; + } + .navbar { + display: none; + } + .badge { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table td, + .table th { + background-color: #fff !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} +/*# sourceMappingURL=bootstrap.css.map */ \ No newline at end of file diff --git a/src/assets/css/main.css b/src/assets/css/main.css index b83abb3a..5374c11c 100644 --- a/src/assets/css/main.css +++ b/src/assets/css/main.css @@ -13,7 +13,35 @@ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -body,html{margin:0;padding:0;min-height:100%;overflow-x:hidden} +@font-face { + font-family: robotoLatin; + src: + url('../fonts/roboto-v18-latin-regular.woff2') format('woff2'), + url('../fonts/roboto-v18-latin-regular.woff') format('woff'), +} + +/* Create two equal columns that floats next to each other */ +.column { + float: left; + width: 50%; + padding: 10px; +} + +/* Clear floats after the columns */ +.row:after { + content: ""; + display: table; + clear: both; +} + +/* Responsive layout - makes the two columns stack on top of each other instead of next to each other */ +@media screen and (max-width: 600px) { + .column { + width: 100%; + } +} + +body,html{margin:0;padding:0;min-height:100%;overflow-x:hidden;font-family: robotoLatin;} div,p,input,label{box-sizing: border-box;} *[v-cloak] { @@ -27,6 +55,7 @@ body{ overflow-y: hidden; font-weight: normal; background: #f7f7f7; + font-family: robotoLatin; } body.menuHidden{ overflow-y: auto; @@ -78,7 +107,7 @@ body.native .hideOnNonNative{ height:34px;line-height:34px; position: fixed; top:0; - background: #30466C; + background: #28276f; color:white; font-size:16px; font-weight: bold; @@ -136,7 +165,7 @@ body.menuHidden #menu { } #menu{ - background: #30466C; + background: #28276f; color: white; padding:10px 15px; } @@ -246,7 +275,95 @@ body.transparent #copyright{ } .walletAmount { - font-size: 30px; + display: block; + font-size: 1.4rem; + font-weight: bold; +} + +.btcValue { + font-size: 1rem; + display: block; +} + +.contacts table { + width: 100%; + border-collapse: collapse; + table-layout: fixed; +} + +.contacts .contact { + border-top: 1px solid #E2E2E2; +} + +#accountContacts { + padding: 10px 35px; +} + +.contacts table tr:first-child { + border-top: 0 none; +} + +.contacts contact td { + padding: 8px 0; +} + +.contacts .contact .contact-icon { + font-size: 16px; + width: 5%; + padding-left: 5px; +} + +.contacts .contact .contactname { + width: 45%; + font-size: 16px; + margin-left: 2vw; +} + +.contacts .contact .contactinfo { + font-size: 16px; + width: 8%; + text-align: right; + padding-right: 10px; + cursor: pointer; +} + +.elections .election { + margin-bottom: 3vh; +} + +.elections table { + width: 100%; + border-collapse: collapse; + table-layout: fixed; +} + +#nElections { + padding: 10px 35px; +} + +.elections table tr { + border-top: 0 none; + margin-bottom: 8vh; +} + +.elections election td { + padding: 8px 0; +} + +.elections .election .electiondescription { + width: 100%; + font-size: 16px; + margin-bottom: 25px; +} + +.elections .election .electionLink { + width: 100%; + font-size: 16px; + margin-bottom: 25px; +} + +.elections table .election .electionLink a { + padding-top: 1vh; } .transactions table{ @@ -292,7 +409,7 @@ body.transparent #copyright{ padding-right:5px; } .transactions .transaction .amount.more{color:#6bc534;} -.transactions .transaction .amount.less{color:#5b5b5b;} +.transactions .transaction .amount.less{color:#de2c2c;} .transactions .transaction .moreInfo { font-size: 20px; width: 8%; @@ -488,12 +605,12 @@ body.transparent #copyright{ } } .indexTab .mainBlock{ - min-height:90vh; + min-height:100vh; position: relative; text-align: center; - background-image: -webkit-linear-gradient(rgba(62, 75, 92, 0.70), rgba(62, 75, 92, 0.70)), url(../img/landing/balancing.jpg); - background-image: -o-linear-gradient(rgba(62, 75, 92, 0.70), rgba(62, 75, 92, 0.70)), url(../img/landing/balancing.jpg); - background-image: linear-gradient(rgba(62, 75, 92, 0.70), rgba(62, 75, 92, 0.70)), url(../img/landing/balancing.jpg); + background-image: -webkit-linear-gradient(rgba(62, 75, 92, 0.10), rgba(62, 75, 92, 0.10)), url(../img/landing/qclassic.jpg); + background-image: -o-linear-gradient(rgba(62, 75, 92, 0.10), rgba(62, 75, 92, 0.10)), url(../img/landing/qclassic.jpg); + background-image: linear-gradient(rgba(62, 75, 92, 0.10), rgba(62, 75, 92, 0.10)), url(../img/landing/qclassic.jpg); background-position: center center; background-size: cover; margin-bottom:160px; @@ -520,13 +637,15 @@ body.native .indexTab .mainBlock { .indexTab .mainBlock h1{ display: inline-block; color:white; - border-bottom:1px solid white; - padding: 0 20px; margin-bottom: 0; - font-size: 40px; + font-size: 50px; } .indexTab .mainBlock h2{ + color:white; + font-size:20px; +} +.indexTab .mainBlock h3{ color:#c8cacf; font-size:18px; } @@ -612,10 +731,10 @@ body.native .indexTab .mainBlock > .actions{ } .indexTab .block i{ font-size: 40px; - color:#00A0E3; + color:#f1c40f; } .indexTab .block h3{ - color:#30466C; + color:#28276f; font-size: 24px; margin: 0; margin-bottom:5px;margin-top:8px; @@ -625,7 +744,7 @@ body.native .indexTab .mainBlock > .actions{ text-decoration: none; } .indexTab .block h4{ - color:#30466C; + color:#28276f; font-size: 14px; margin: 0; font-weight: normal; diff --git a/src/assets/fonts/roboto-v18-latin-regular.woff b/src/assets/fonts/roboto-v18-latin-regular.woff new file mode 100644 index 00000000..92dfacc6 Binary files /dev/null and b/src/assets/fonts/roboto-v18-latin-regular.woff differ diff --git a/src/assets/fonts/roboto-v18-latin-regular.woff2 b/src/assets/fonts/roboto-v18-latin-regular.woff2 new file mode 100644 index 00000000..7e854e66 Binary files /dev/null and b/src/assets/fonts/roboto-v18-latin-regular.woff2 differ diff --git a/src/assets/img/coin_white.png b/src/assets/img/coin_white.png index 30a98ffa..aff3b7d0 100644 Binary files a/src/assets/img/coin_white.png and b/src/assets/img/coin_white.png differ diff --git a/src/assets/img/favicon.ico b/src/assets/img/favicon.ico index fa9f0f33..aff3b7d0 100644 Binary files a/src/assets/img/favicon.ico and b/src/assets/img/favicon.ico differ diff --git a/src/assets/img/icons/icon-128x128.png b/src/assets/img/icons/icon-128x128.png index 959433a1..d58c5756 100644 Binary files a/src/assets/img/icons/icon-128x128.png and b/src/assets/img/icons/icon-128x128.png differ diff --git a/src/assets/img/icons/icon-144x144.png b/src/assets/img/icons/icon-144x144.png index d3bd1943..cf6fe2c3 100644 Binary files a/src/assets/img/icons/icon-144x144.png and b/src/assets/img/icons/icon-144x144.png differ diff --git a/src/assets/img/icons/icon-152x152.png b/src/assets/img/icons/icon-152x152.png index 7ccfc684..578c71c0 100644 Binary files a/src/assets/img/icons/icon-152x152.png and b/src/assets/img/icons/icon-152x152.png differ diff --git a/src/assets/img/icons/icon-192x192.png b/src/assets/img/icons/icon-192x192.png index b58204e4..d06425f6 100644 Binary files a/src/assets/img/icons/icon-192x192.png and b/src/assets/img/icons/icon-192x192.png differ diff --git a/src/assets/img/icons/icon-256x256.png b/src/assets/img/icons/icon-256x256.png index e31e8250..c2ec5436 100644 Binary files a/src/assets/img/icons/icon-256x256.png and b/src/assets/img/icons/icon-256x256.png differ diff --git a/src/assets/img/icons/icon-402x402.png b/src/assets/img/icons/icon-402x402.png index edfb2748..954d6f55 100644 Binary files a/src/assets/img/icons/icon-402x402.png and b/src/assets/img/icons/icon-402x402.png differ diff --git a/src/assets/img/landing/75-usersthink-stock-image.jpg b/src/assets/img/landing/75-usersthink-stock-image.jpg deleted file mode 100644 index cbc0798a..00000000 Binary files a/src/assets/img/landing/75-usersthink-stock-image.jpg and /dev/null differ diff --git a/src/assets/img/landing/balancing.jpg b/src/assets/img/landing/balancing.jpg deleted file mode 100644 index 1d03a2e2..00000000 Binary files a/src/assets/img/landing/balancing.jpg and /dev/null differ diff --git a/src/assets/img/landing/qclassic.jpg b/src/assets/img/landing/qclassic.jpg new file mode 100644 index 00000000..771a5cd4 Binary files /dev/null and b/src/assets/img/landing/qclassic.jpg differ diff --git a/src/assets/img/landing/qwc_morepurple.png b/src/assets/img/landing/qwc_morepurple.png new file mode 100644 index 00000000..6d1c955d Binary files /dev/null and b/src/assets/img/landing/qwc_morepurple.png differ diff --git a/src/assets/img/logo.png b/src/assets/img/logo.png index 91b8d116..fcde6f20 100644 Binary files a/src/assets/img/logo.png and b/src/assets/img/logo.png differ diff --git a/src/assets/img/logoQrCode.jpg b/src/assets/img/logoQrCode.jpg index e3f908b3..bc67666a 100644 Binary files a/src/assets/img/logoQrCode.jpg and b/src/assets/img/logoQrCode.jpg differ diff --git a/src/assets/img/logoQrCode.png b/src/assets/img/logoQrCode.png index 302c9238..561ec955 100644 Binary files a/src/assets/img/logoQrCode.png and b/src/assets/img/logoQrCode.png differ diff --git a/src/assets/img/logo_vertical.png b/src/assets/img/logo_vertical.png index 6d434fff..d8d0e5ad 100644 Binary files a/src/assets/img/logo_vertical.png and b/src/assets/img/logo_vertical.png differ diff --git a/src/assets/img/qclassic.jpg b/src/assets/img/qclassic.jpg new file mode 100644 index 00000000..2693a25c Binary files /dev/null and b/src/assets/img/qclassic.jpg differ diff --git a/src/config.ts b/src/config.ts index 7d3e0a8c..8e6a57fd 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,35 +1,44 @@ -let global : any = typeof window !== 'undefined' ? window : self; +let global: any = typeof window !== 'undefined' ? window : self; global.config = { - apiUrl:typeof window !== 'undefined' && window.location ? window.location.href.substr(0,window.location.href.lastIndexOf('/')+1)+'api/' : 'https://wallet.karbo.org/api/', - mainnetExplorerUrl: "http://explorer.karbowanec.com/", - mainnetExplorerUrlHash: "http://explorer.karbowanec.com/?hash={ID}#blockchain_transaction", - mainnetExplorerUrlBlock: "http://explorer.karbowanec.com/?hash={ID}#blockchain_block", - testnetExplorerUrl: "http://testnet.karbo.org/", - testnetExplorerUrlHash: "http://testnet.karbo.org/?hash={ID}#blockchain_transaction", - testnetExplorerUrlBlock: "http://testnet.karbo.org/?hash={ID}#blockchain_block", + nodeList: [ + { owner: "Lomelicus", node: "https://pr01.myqwertycoin.com/sync/"}, + { owner: "ExploShot", node: "https://pr02.myqwertycoin.com/sync/"} + ], + nodeUrl: "https://pr02.myqwertycoin.com/sync/", + electionApiUrl: "https://voting.qwertycoin.org/api", + websiteApiUrl: "https://www.qwertycoin.org/wp-json", + mainnetExplorerUrl: "https://explorer.qwertycoin.org/", + mainnetExplorerUrlHash: "https://explorer.qwertycoin.org/?hash={ID}#blockchain_transaction", + mainnetExplorerUrlBlock: "https://explorer.qwertycoin.org/?hash={ID}#blockchain_block", + testnetExplorerUrl: "https://explorer.testnet.qwertycoin.org/", + testnetExplorerUrlHash: "https://explorer.testnet.qwertycoin.org/?hash={ID}#blockchain_transaction", + testnetExplorerUrlBlock: "https://explorer.testnet.qwertycoin.org/?hash={ID}#blockchain_block", testnet: false, - coinUnitPlaces: 12, - coinDisplayUnitPlaces: 2, - txMinConfirms: 10, + coinUnitPlaces: 8, + coinDisplayUnitPlaces: 2, + txMinConfirms: 10, txCoinbaseMinConfirms: 10, - addressPrefix: 111, - integratedAddressPrefix: 112, - addressPrefixTestnet: 111, - integratedAddressPrefixTestnet: 112, - subAddressPrefix: 113, - subAddressPrefixTestnet: 113, - coinFee: new JSBigInt('100000000000'), - feePerKB: new JSBigInt('100000000000'), //for testnet its not used, as fee is dynamic. - dustThreshold: new JSBigInt('100000000'),//used for choosing outputs/change - we decompose all the way down if the receiver wants now regardless of threshold + addressPrefix: 0x14820c, + integratedAddressPrefix: 0x148201, + addressPrefixTestnet: 0x14820c, + integratedAddressPrefixTestnet: 0x148201, + subAddressPrefix: 0x148202, + subAddressPrefixTestnet: 0x148202, + coinFee: new JSBigInt('100000000'), + feePerKB: new JSBigInt('100000000'), + dustThreshold: new JSBigInt('100000'), //used for choosing outputs/change - we decompose all the way down if the receiver wants now regardless of threshold defaultMixin: 0, // default value mixin idleTimeout: 30, idleWarningDuration: 20, - coinSymbol: 'KRB', - openAliasPrefix: "krb", - coinName: 'Karbo', - coinUriPrefix: 'karbowanec:', - avgBlockTime: 240, + coinSymbol: 'QWC', + openAliasPrefix: "qwc", + coinName: 'Qwertycoin', + coinUriPrefix: 'qwertycoin:', + avgBlockTime: 120, maxBlockNumber: 500000000, -}; \ No newline at end of file + remoteNodeFee: 0.25, + devFee: 1, + devAddress: "QWC1Dx9NNGkHCkgRgeF9fhEskhg5ddiDJGVXdGBwqW7CXqKHZe6gzxuhLzWZwBVTbeAofBPe6mSkeedRuFuxRwunAG7KBLYTgB" +}; diff --git a/src/d/config.d.ts b/src/d/config.d.ts index 22b631b2..377e0056 100644 --- a/src/d/config.d.ts +++ b/src/d/config.d.ts @@ -1,5 +1,12 @@ -declare var config : { - apiUrl:string, +declare var config: { + apiUrl: string[], + nodeList: { + owner: string, + node: string + }[], + nodeUrl: string, + electionApiUrl: string, + websiteApiUrl: string, mainnetExplorerUrl: string, mainnetExplorerUrlHash: string, mainnetExplorerUrlBlock: string, @@ -8,7 +15,7 @@ declare var config : { testnetExplorerUrlBlock: string, testnet: boolean, coinUnitPlaces: number, - txMinConfirms: number, // corresponds to CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE in Monero + txMinConfirms: number, // corresponds to CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE in Monero txCoinbaseMinConfirms: number, // corresponds to CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW in Monero coinSymbol: string, openAliasPrefix: string, @@ -27,5 +34,8 @@ declare var config : { idleTimeout: number, idleWarningDuration: number, maxBlockNumber: number, + remoteNodeFee: number, + devFee: number, + devAddress: string, avgBlockTime: number, -}; \ No newline at end of file +}; diff --git a/src/d/nacl.d.ts b/src/d/nacl.d.ts index d335a42a..ae0a618e 100644 --- a/src/d/nacl.d.ts +++ b/src/d/nacl.d.ts @@ -1 +1,17 @@ -declare var nacl : any; \ No newline at end of file +declare var nacl : { + ll:{ + ge_scalarmult:(a : Uint8Array, b : Uint8Array)=>Uint8Array, + ge_double_scalarmult_base_vartime:(a : Uint8Array, b : Uint8Array, c : Uint8Array)=>Uint8Array, + ge_double_scalarmult_postcomp_vartime:(a : Uint8Array, b : Uint8Array, c : Uint8Array, d : Uint8Array)=>Uint8Array, + ge_add:(a : Uint8Array, b : Uint8Array)=>Uint8Array, + ge_scalarmult_base:(a : Uint8Array)=>Uint8Array + }, + secretbox:any, + //open:(encrypted:Uint8Array, nonce:Uint8Array, privKey:Uint8Array)=>Uint8Array; + util:{ + encodeBase64:(value : Uint8Array)=>string, + }, + randomBytes:(bits : number) => Uint8Array +}; + +declare function keccak_256(bin : Uint8Array) : string; \ No newline at end of file diff --git a/src/d/rawDaemon.d.ts b/src/d/rawDaemon.d.ts index d730c4da..135e9a84 100644 --- a/src/d/rawDaemon.d.ts +++ b/src/d/rawDaemon.d.ts @@ -7,7 +7,7 @@ type Inputs = { mixin: number }, output: { - number: number, + number: number, transactionHash: string }, type: string @@ -15,7 +15,7 @@ type Inputs = { } type Outputs = { - globalIndex: number, + globalIndex: number, output: { amount: 0, target: { @@ -45,4 +45,9 @@ type RawDaemonTransaction = { paymentId: string }; -type RawDaemonBlock = any; \ No newline at end of file +type destination = { + address: string, + amount: number +} + +type RawDaemonBlock = any; diff --git a/src/filters/Filters.ts b/src/filters/Filters.ts new file mode 100644 index 00000000..9c36b59f --- /dev/null +++ b/src/filters/Filters.ts @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2018-2020, ExploShot + * Copyright (c) 2018-2020, The Qwertycoin Project + * Copyright (c) 2020, The Masari Project + * + * All rights reserved. + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * ==> Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * ==> Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * ==> Neither the name of Qwertycoin nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +export function VueFilterSatoshis(value: number) { + return '₿ ' + value.toFixed(8) +} + +export function VueFilterPiconero(value: number) { + return value.toFixed(12) +} + +export function VueFilterFiat(value: number, currency: string) { + if (currency == 'usd' || currency == 'aud' || currency == 'cad' || currency == 'nzd') { + return '$ ' + value.toFixed(2); + } + if (currency == 'eur') { + return '€ ' + value.toFixed(2); + } + if (currency == 'jpy') { + return '¥ ' + value.toFixed(2); + } + if (currency == 'gbp') { + return '£ ' + value.toFixed(2); + } + if (currency == 'chf') { + return 'Fr. ' + value.toFixed(2); + } + if (currency == 'sek') { + return 'kr ' + value.toFixed(2); + } + if (currency == 'czk') { + return 'CZK ' + value.toFixed(2); + } + if (currency == 'eth') { + return 'Ξ ' + value.toFixed(2); + } + if (currency == 'ltc') { + return 'Ł ' + value.toFixed(2); + } +} + +export function VueFilterHashrate(hashrate: number) { + let i = 0; + let byteUnits = ['H', 'kH', 'MH', 'GH', 'TH', 'PH', 'EH', 'ZH', 'YH']; + + while (hashrate > 1000) { + hashrate = hashrate / 1000; + i++; + } + + return hashrate.toFixed(2) + byteUnits[i]; +} \ No newline at end of file diff --git a/src/index.html b/src/index.html index fd4f4c2a..642f2656 100644 --- a/src/index.html +++ b/src/index.html @@ -2,14 +2,14 @@ - Karbo Web Wallet - + Qwertycoin Web Wallet + - + @@ -22,7 +22,7 @@ - + @@ -30,21 +30,21 @@ - - + + - - + + - + - + @@ -56,12 +56,14 @@ diff --git a/src/pages/support.ts b/src/pages/support.ts index 57fe8ec0..39b133fa 100644 --- a/src/pages/support.ts +++ b/src/pages/support.ts @@ -12,14 +12,7 @@ * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import {VueVar, VueWatched} from "../lib/numbersLab/VueAnnotate"; import {DestructableView} from "../lib/numbersLab/DestructableView"; -import {KeysRepository} from "../model/KeysRepository"; -import {Wallet} from "../model/Wallet"; -import {Password} from "../model/Password"; -import {BlockchainExplorerRpc2} from "../model/blockchain/BlockchainExplorerRpc2"; -import {BlockchainExplorerProvider} from "../providers/BlockchainExplorerProvider"; -import {Mnemonic} from "../model/Mnemonic"; import {AppState} from "../model/AppState"; class SupportView extends DestructableView{ diff --git a/src/pages/termsOfUse.html b/src/pages/termsOfUse.html index 86b57c90..c67f5012 100644 --- a/src/pages/termsOfUse.html +++ b/src/pages/termsOfUse.html @@ -12,14 +12,17 @@
English version:
- It is understood that interactions with masariwallet.com’s web wallet are entirely client-side.
- That masariwallet.com has no control or access to your wallet’s private keys, nor do they have the ability to recover your funds in any event of loss.
+ It is understood that interactions with myQWERTYCOIN.com’s web wallet are entirely client-side.
+ That myqwertycoin.com has no control or access to your wallet’s private keys, nor do they have the ability to recover your funds in any event of loss.
- In all circumstances, wallet.karbo.org, Karbo Core Team, Karbo promoters, or any entity affiliated with the Karbo project will not be liable for loss or misuse of funds held using the aforementioned wallet.
- Users also understand and agree that they are solely responsible for providing a secure environment to interact with a Karbowallet.com web wallet.
+ In all circumstances, myqwertycoin.com, Qwertycoin Core Team, Qwertycoin promoters, or any entity affiliated with the Qwertycoin project will not be liable for loss or misuse of funds held using the aforementioned wallet.
+ Users also understand and agree that they are solely responsible for providing a secure environment to interact with a Qwertycoin.org web wallet.
- Additionally, Karbowallet.com cannot, and will not, be held liable for use of funds originating from or arriving to a web wallet.
- By creating, importing, or interacting with a wallet on Karbowallet.com, you implicitly agree to these terms, and absolve the website owners and affiliates of any and all liability. + Additionally, myqwertycoin.com cannot, and will not, be held liable for use of funds originating from or arriving to a web wallet.
+ By creating, importing, or interacting with a wallet on myqwertycoin.com, you implicitly agree to these terms, and absolve the website owners and affiliates of any and all liability. +
+ With the new Feature for running myqwertycoin.com with daemons we added a remoteNode Fee of 0.25% but max 10 QWC for each outgoing transaction.
+ The developer also receives a fee of 1 QWC per outgoing transaction.
Privacy policy (EN)
diff --git a/src/providers/BlockchainExplorerProvider.ts b/src/providers/BlockchainExplorerProvider.ts index 8869c31c..c1c3e74e 100644 --- a/src/providers/BlockchainExplorerProvider.ts +++ b/src/providers/BlockchainExplorerProvider.ts @@ -15,14 +15,15 @@ import {Constants} from "../model/Constants"; import {DependencyInjectorInstance} from "../lib/numbersLab/DependencyInjector"; -import {BlockchainExplorerRpc2} from "../model/blockchain/BlockchainExplorerRpc2"; +import {BlockchainExplorer} from "../model/blockchain/BlockchainExplorer"; +import {BlockchainExplorerRpcDaemon} from "../model/blockchain/BlockchainExplorerRPCDaemon"; export class BlockchainExplorerProvider{ - static getInstance() : BlockchainExplorerRpc2{ - let blockchainExplorer : BlockchainExplorerRpc2 = DependencyInjectorInstance().getInstance(Constants.BLOCKCHAIN_EXPLORER); + static getInstance() : BlockchainExplorer{ + let blockchainExplorer : BlockchainExplorer = DependencyInjectorInstance().getInstance(Constants.BLOCKCHAIN_EXPLORER); if(blockchainExplorer === null) { - blockchainExplorer = new BlockchainExplorerRpc2(); + blockchainExplorer = new BlockchainExplorerRpcDaemon(); DependencyInjectorInstance().register(Constants.BLOCKCHAIN_EXPLORER, blockchainExplorer); } return blockchainExplorer; diff --git a/src/translations/ar.json b/src/translations/ar.json new file mode 100644 index 00000000..f6743f7b --- /dev/null +++ b/src/translations/ar.json @@ -0,0 +1,539 @@ +{ + "website": { + "title": "محفظة Qwertycoin | بسيطة وسلسة وآمنة. مرحبا بكم في المستقبل.", + "description": "المحفظة الرسمية عبر الإنترنت لعملة Qwertycoin - يتم التعامل معها بشكل كامل في متصفحك للحصول على أفضل حماية" + }, + "messages": { + "menu": { + "home": "الصفحة الرئيسية", + "account": "الحساب", + "send": "إرسال", + "receive": "تسلم", + "export": "تصدير", + "donate": "تبرع", + "elections": "انتخابات", + "contacts": "جهات الاتصال", + "settings": "الإعدادات", + "disconnect": "قطع الاتصال", + "network": "احصائيات الشبكة", + "mining": "تعدين" + }, + "global": { + "loading": "Loading", + "disableSecurity": "Disable this security, I understand the risk", + "passwordInvalidRequirements": "The password needs at least 8 characters - 1 upper case letter, 1 lower case letter, one number, and one special character", + "passwordConfirmationNotMatching": "The password does not match the first password you wrote", + "download": "Download", + "newVersionModal": { + "title": "A new version is available", + "content": "Do you want to reload to load the new version?", + "confirmText": "Yes", + "cancelText": "Back" + }, + "openWalletModal": { + "title": "Wallet Password", + "confirmText": "Open", + "cancelText": "Cancel" + }, + "invalidPasswordModal": { + "title": "Oops...", + "content": "Your password seems invalid", + "confirmText": "OK" + }, + "invalidMnemonicModal": { + "title": "Oops...", + "content": "The mnemonic phrase is invalid", + "confirmText": "OK" + }, + "passwordNotComplexEnoughModal": { + "title": "The password is not complex enough", + "confirmText": "OK" + }, + "permissionRequiredForCameraModal": { + "title": "Oops...", + "content": "The permission to access your camera is required to scan the QR code", + "confirmText": "OK" + } + }, + "bottom": { + "termsOfUse": "Terms of Use", + "privacyPolicy": "Privacy Policy", + "support": "Support", + "donate": "Donate", + "network": "Network Stats", + "miningPool": "Mining Pool", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Qwertycoin Wallet", + "tagLine": "anywhere. anytime. anyplace. any device.", + "tagLineTwo": "The simplest way to use Qwertycoin", + "actions": { + "loadWallet": "Load my wallet", + "importWallet": "Import a wallet", + "create": "Create", + "createWallet": "Create a wallet" + } + }, + "accountPage": { + "title": "Account", + "subtitle": "Your account overview and transaction history", + "synchronizingBlock": { + "text": "Synchronizing..." + }, + "balanceBlock": { + "title": "Your balance", + "unlocked": "Unlocked" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Transaction history", + "pendingTxStatus": "Pending", + "emptyWallet": "You currently have no funds in this wallet.", + "waitSync": "Please wait until the wallet is updated", + "beReallyPatient": "The initial setup can take some time...", + "getCoinAddress": "Receive QWC" + }, + "txDetails": { + "title": "Transaction details", + "txHash": "Transaction Hash", + "feesOnTx": "Transaction fee", + "blockHeight": "Block height", + "paymentId": "Payment ID", + "unlockStatus": "Status", + "unlockConfirm": "Confirmations", + "txPrivKey": "Transaction Private Key" + } + }, + "changeWalletPasswordPage": { + "title": "Change your password", + "oldPassword": { + "label": "Old password", + "invalid": "The password is invalid" + }, + "newPassword": { + "label": "Choose a new password to protect your wallet" + }, + "newPasswordConfirm": { + "label": "Confirm the new password" + }, + "confirm": "Change the password", + "modalSuccess": { + "title": "Password changed!", + "confirmText": "OK" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "Contacts" + }, + "electionsPage": { + "title": "انتخابات" + }, + "createWalletPage": { + "generatingStep": { + "title": "Your wallet is being generated...", + "subtitle": "It's almost done", + "waitingMessage": "Generating your wallet..." + }, + "finalizationStep": { + "title": "That was simple. Your account is ready!", + "subtitle": "Be ready to use Qwertycoin like you never have", + "passwordSelectionBlock": { + "label": "Protect your wallet" + }, + "passwordConfirmBlock": { + "label": "Confirm the password" + }, + "validPassword": "Use this password", + "backupBlock": { + "title": "Save your private credentials for recovery.", + "option1": "Option 1: ", + "option2": "Option 2: ", + "titlePdf": "Download a PDF copy", + "titleManualWrite": "Write down my keys", + "privateKeys": "Private key", + "mnemonicPhrase": "Mnemonic phrase", + "separatorManualMethodsSolution": " or ", + "confirmManuallyWritten": "I wrote my seed phrase down", + "warningMessage": "**Do not lose it!** It cannot be recovered if you lose it.
**Do not share it!** Your funds will be stolen if you use this file or seed on a malicious/phishing site.
**Make a backup!** Secure it like the millions of dollars it may one day be worth.
", + "finishButton": "I understand. Continue." + } + }, + "disclaimerBlock": { + "title": "Risk of Using QwertycoinWallet", + "content": "QwertycoinWallet is a web-based interface. It helps you use Qwertycoin without running a full Qwertycoin node.
We recommend you treat QwertycoinWallet like you will treat your actual wallet." + } + }, + "donatePage": { + "title": "Donate", + "subtitle": "Help to fund the development and pay the bills", + "webwalletBlock": { + "title": "Webwallet", + "content": "If you want to help to pay for the servers, to support new features development, and like this app, please consider a donation:

" + }, + "devFundBlock": { + "title": "Qwertycoin Dev fund", + "content": "To help Qwertycoin, you can donate at these addresses" + } + }, + "supportPage": { + "title": "Support", + "subtitle": "We are here to help!", + "getInTouchBlock": { + "title": "Let's Get In Touch!", + "content": "Do you have ideas or feedback that could help us improve the wallet? Contact us!", + "discord": "Qwertycoin Discord Channel" + } + }, + "networkPage": { + "title": "Network stats", + "subtitle": "Insights on the Qwertycoin network", + "statsBlock": { + "connectNode": "متصل ماسترنود", + "hashrate": "Network hashrate", + "height": "Blockchain height", + "difficulty": "Network difficulty", + "lastTimeBlock": "Last block found", + "lastReward": "Last block reward" + } + }, + "sendPage": { + "title": "Send QWC", + "sendBlock": { + "address": { + "label": "Destination address", + "placeholder": "Write the address where you want to send funds", + "invalid": "The destination address is invalid", + "fundsTo": "The funds will be sent to", + "receiver": "Receiver", + "description": "Description" + }, + "amount": { + "label": "Amount to send", + "invalid": "The amount is invalid" + }, + "paymentId": { + "label": "Payment ID (optional)", + "invalid": "The payment ID is invalid. The length must be 16 or 64 characters" + }, + "sendButton": "Send", + "cancelButton": "Cancel" + }, + "qrCodeScanning": { + "explication": "Present the QR code" + }, + "notEnoughMoneyModal": { + "title": "Oops...", + "content": "You don't have enough funds in your wallet to execute this transfer", + "confirmText": "OK" + }, + "thankYouDonationModal": { + "title": "Thank you for your donation!", + "content": "Your help is appreciated. This donation will help make Qwertycoin better", + "confirmText": "OK" + }, + "transferSentModal": { + "title": "Transfer sent successfully!", + "confirmText": "OK" + }, + "transferExceptionModal": { + "title": "Oops...", + "content": "An error occurred. Please report this error: {details}", + "confirmText": "OK" + }, + "invalidAmountModal": { + "title": "Oops...", + "content": "Invalid amount", + "confirmText": "OK" + }, + "creatingTransferModal": { + "title": "Creating transfer ...", + "content": "Please wait..." + }, + "finalizingTransferModal": { + "title": "Finalizing transfer ...", + "content": "Please wait..." + }, + "confirmTransactionModal": { + "title": "Confirm transfer?", + "content": "Amount: {amount}
Fees: {fees}
Total: {total}", + "confirmText": "Confirm", + "cancelText": "Cancel" + }, + "waitingNfcModal": { + "title": "Waiting Nfc", + "content": "Bring closer to the other device" + } + }, + "receivePage": { + "title": "Receive QWC", + "receiveBlock": { + "address": { + "title": "Your address to receive funds:", + "label": "Give this address to receive funds" + }, + "qrCode": { + "title": "Or personalize the QR code:", + "labelAmount": "Amount (optional)", + "labelRecipient": "Recipient name (optional)", + "labelDescription": "Transaction description (optional)", + "updateButton": "Update" + } + }, + "qrBlock": { + "title": "Your customized QR code" + }, + "waitingNfcToWriteModal": { + "title": "Waiting Nfc", + "titleSuccess": "Nfc Tag written", + "content": "Bring closer the NFC tag to write" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Tag capacity insufficient" + } + }, + "miningPage": { + "title": "Mine directly in your browser", + "subtitle": "Support the network by mining and be rewarded with QWC", + "parameterBlock": { + "title": "Parameters", + "labelDestinationAddress": "Wallet to mine", + "labelThreads": "Number of threads (more = higher hashrate)", + "start": "Start", + "stop": "Stop" + }, + "statisticsBlocks": { + "title": "Statistics", + "validShares": "Valid shares", + "hashrate": "Hashrate", + "maxHashrate": "Max Hashrate", + "dedicatedHardware": "With dedicating mining software and hardware, you could earn more and help decentralize the network.", + "miningHandledBy": "This mining is handled by the mining pool pool.qwertycoin.org" + } + }, + "settingsPage": { + "title": "Settings", + "subtitle": "Change your parameters here", + "versionBlock": { + "versionNumber": "Version number: ", + "versionCode": "Version code: " + }, + "settingsBlock": { + "speed": { + "label": "Speed to update the wallet (will consume more resources)", + "fastest": "Fastest", + "fast": "Fast", + "medium": "Medium", + "slow": "Slow" + }, + "language": { + "label": "Language" + }, + "currency": { + "label": "العملة الوطنية" + }, + "readMinerTx": { + "label": "Read miner transactions (only for solo mining)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Change my wallet password", + "deleteWalletButton": "Delete my wallet (local copy)", + "walletSettings": { + "creationHeight": { + "label": "Creation height of the wallet" + }, + "currentScanningHeight": { + "label": "Current scanning height" + }, + "updateButton": "Update" + }, + "deleteWalletModal": { + "title": "Delete My Wallet (local copy)", + "content": "Are you sure you REALLY want to delete your wallet ?", + "confirmText": "Yes I'm sure", + "cancelText": "Cancel" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Parameters", + "password": { + "label": "Password to protect your wallet" + }, + "passwordConfirm": { + "label": "Confirm the password", + "invalid": "The password does not match the first password you wrote" + }, + "importHeight": { + "label": "Height to import from:" + } + } + }, + "importFromQrPage": { + "title": "Importing wallet from a QR code", + "subtitle": "Import a wallet from an offline backup", + "qrCodeBlock": { + "title": "QR code", + "startScanButton": "Start the scan", + "importButton": "Import" + }, + "qrScanningBlock": { + "title": "Present the QR code" + } + }, + "exportPage": { + "title": "Backup your credentials", + "publicAddressBlock": { + "title": "Your public address" + }, + "pdfBlock": { + "title": "PDF Backup", + "downloadButton": "Download" + }, + "warningBlock": { + "title": "Warning", + "content": "If you choose to save your private keys or your mnemonic phrase, PLEASE DO NOT store them in clear-text for your own safety.
The file is an alternate solution where your keys are encrypted and contains a backup of all your transactions to spare you a future synchronisation." + }, + "exportBlock": { + "title": "Export your RAW credentials", + "privateKeysButton": "Get my private keys", + "mnemonicKeysButton": "Get my mnemonic phrase", + "fileButton": "Export to a file" + }, + "walletKeysModal": { + "title": "Private keys", + "confirmText": "OK", + "content": "Please carefully store these keys. Possessing them means possessing the funds associated !
Spend key: {privSpendKey}
Private view key: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Mnemonic phrase", + "confirmText": "OK", + "content": "Please store carefully this mnemonic phrase. Possessing it means possessing the funds associated ! The phrase is:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "In which language do you want your mnemonic phrase?", + "confirmText": "Export" + } + }, + "importPage": { + "title": "Create a wallet", + "subtitle": "From previously created keys, file, or mnemonic phrase", + "chooseMethod": "Choose your import method:", + "fromKeys": "From keys", + "fromFile": "From a file", + "fromMnemonic": "From a mnemonic phrase", + "fromQr": "From a QR code" + }, + "termsOfUsePage": { + "title": "Terms of use", + "subtitle": "Please read them carefully." + }, + "privacyPolicyPage": { + "title": "Privacy Policy", + "subtitle": "Please read them carefully." + }, + "importFromFilePage": { + "title": "Importing wallet from a backup file", + "subtitle": "Use your backup file to create a wallet", + "walletBlock": { + "title": "Wallet file", + "label": "Select the file", + "importButton": "Import" + } + }, + "importFromMnemonicPage": { + "title": "Importing wallet from a mnemonic phrase", + "subtitle": "Use your phrase to create a wallet", + "mnemonicBlock": { + "title": "Mnemonic phrase", + "mnemonic": { + "label": "Mnemonic phrase: 25 words", + "invalid": "The mnemonic phrase is invalid", + "language": "Language" + }, + "importButton": "Import" + } + }, + "importFromKeysPage": { + "title": "Importing wallet from keys", + "subtitle": "Use your keys to create a wallet", + "parametersBlock": { + "viewOnlyWallet": { + "label": "Do you want a view only wallet?" + } + }, + "keysBlock": { + "titleNotViewOnly": "Wallet keys", + "titleViewOnly": "View only wallet", + "privateSpend": { + "label": "Private spend key" + }, + "privateView": { + "label": "Private view key", + "optional": "(optional)" + }, + "publicKey": { + "label": "Public key" + }, + "importButton": "Import" + } + } + }, + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": true + } + } +} diff --git a/src/translations/br.json b/src/translations/br.json new file mode 100644 index 00000000..5b20dbe0 --- /dev/null +++ b/src/translations/br.json @@ -0,0 +1,539 @@ +{ + "website": { + "title": "Qwertycoin Carteira | Simples, sem costura, seguro. Bem vindo ao futuro.", + "description": "Carteira online oficial da moeda Qwertycoin - totalmente manuseada no seu navegador para uma segurança ideal" + }, + "messages": { + "menu": { + "home": "Casa", + "account": "Conta", + "send": "Mandar", + "receive": "Receber", + "export": "Exportar", + "donate": "Doar", + "elections": "Eleições", + "contacts": "Contatos", + "settings": "Definições", + "disconnect": "desconectar", + "network": "Estatística de redes", + "mining": "Mineração" + }, + "global": { + "loading": "Loading", + "disableSecurity": "Disable this security, I understand the risk", + "passwordInvalidRequirements": "The password needs at least 8 characters - 1 upper case letter, 1 lower case letter, one number, and one special character", + "passwordConfirmationNotMatching": "The password does not match the first password you wrote", + "download": "Download", + "newVersionModal": { + "title": "A new version is available", + "content": "Do you want to reload to load the new version?", + "confirmText": "Yes", + "cancelText": "Back" + }, + "openWalletModal": { + "title": "Wallet Password", + "confirmText": "Open", + "cancelText": "Cancel" + }, + "invalidPasswordModal": { + "title": "Oops...", + "content": "Your password seems invalid", + "confirmText": "OK" + }, + "invalidMnemonicModal": { + "title": "Oops...", + "content": "The mnemonic phrase is invalid", + "confirmText": "OK" + }, + "passwordNotComplexEnoughModal": { + "title": "The password is not complex enough", + "confirmText": "OK" + }, + "permissionRequiredForCameraModal": { + "title": "Oops...", + "content": "The permission to access your camera is required to scan the QR code", + "confirmText": "OK" + } + }, + "bottom": { + "termsOfUse": "Terms of Use", + "privacyPolicy": "Privacy Policy", + "support": "Support", + "donate": "Donate", + "network": "Network Stats", + "miningPool": "Mining Pool", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Qwertycoin Wallet", + "tagLine": "anywhere. anytime. anyplace. any device.", + "tagLineTwo": "The simplest way to use Qwertycoin", + "actions": { + "loadWallet": "Load my wallet", + "importWallet": "Import a wallet", + "create": "Create", + "createWallet": "Create a wallet" + } + }, + "accountPage": { + "title": "Account", + "subtitle": "Your account overview and transaction history", + "synchronizingBlock": { + "text": "Synchronizing..." + }, + "balanceBlock": { + "title": "Your balance", + "unlocked": "Unlocked" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Transaction history", + "pendingTxStatus": "Pending", + "emptyWallet": "You currently have no funds in this wallet.", + "waitSync": "Please wait until the wallet is updated", + "beReallyPatient": "The initial setup can take some time...", + "getCoinAddress": "Receive QWC" + }, + "txDetails": { + "title": "Transaction details", + "txHash": "Transaction Hash", + "feesOnTx": "Transaction fee", + "blockHeight": "Block height", + "paymentId": "Payment ID", + "unlockStatus": "Status", + "unlockConfirm": "Confirmations", + "txPrivKey": "Transaction Private Key" + } + }, + "changeWalletPasswordPage": { + "title": "Change your password", + "oldPassword": { + "label": "Old password", + "invalid": "The password is invalid" + }, + "newPassword": { + "label": "Choose a new password to protect your wallet" + }, + "newPasswordConfirm": { + "label": "Confirm the new password" + }, + "confirm": "Change the password", + "modalSuccess": { + "title": "Password changed!", + "confirmText": "OK" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "Contatos" + }, + "electionsPage": { + "title": "Eleições" + }, + "createWalletPage": { + "generatingStep": { + "title": "Your wallet is being generated...", + "subtitle": "It's almost done", + "waitingMessage": "Generating your wallet..." + }, + "finalizationStep": { + "title": "That was simple. Your account is ready!", + "subtitle": "Be ready to use Qwertycoin like you never have", + "passwordSelectionBlock": { + "label": "Protect your wallet" + }, + "passwordConfirmBlock": { + "label": "Confirm the password" + }, + "validPassword": "Use this password", + "backupBlock": { + "title": "Save your private credentials for recovery.", + "option1": "Option 1: ", + "option2": "Option 2: ", + "titlePdf": "Download a PDF copy", + "titleManualWrite": "Write down my keys", + "privateKeys": "Private key", + "mnemonicPhrase": "Mnemonic phrase", + "separatorManualMethodsSolution": " or ", + "confirmManuallyWritten": "I wrote my seed phrase down", + "warningMessage": "**Do not lose it!** It cannot be recovered if you lose it.
**Do not share it!** Your funds will be stolen if you use this file or seed on a malicious/phishing site.
**Make a backup!** Secure it like the millions of dollars it may one day be worth.
", + "finishButton": "I understand. Continue." + } + }, + "disclaimerBlock": { + "title": "Risk of Using QwertycoinWallet", + "content": "QwertycoinWallet is a web-based interface. It helps you use Qwertycoin without running a full Qwertycoin node.
We recommend you treat QwertycoinWallet like you will treat your actual wallet." + } + }, + "donatePage": { + "title": "Donate", + "subtitle": "Help to fund the development and pay the bills", + "webwalletBlock": { + "title": "Webwallet", + "content": "If you want to help to pay for the servers, to support new features development, and like this app, please consider a donation:

" + }, + "devFundBlock": { + "title": "Qwertycoin Dev fund", + "content": "To help Qwertycoin, you can donate at these addresses" + } + }, + "supportPage": { + "title": "Support", + "subtitle": "We are here to help!", + "getInTouchBlock": { + "title": "Let's Get In Touch!", + "content": "Do you have ideas or feedback that could help us improve the wallet? Contact us!", + "discord": "Qwertycoin Discord Channel" + } + }, + "networkPage": { + "title": "Network stats", + "subtitle": "Insights on the Qwertycoin network", + "statsBlock": { + "connectNode": "Connected Masternode", + "hashrate": "Network hashrate", + "height": "Blockchain height", + "difficulty": "Network difficulty", + "lastTimeBlock": "Last block found", + "lastReward": "Last block reward" + } + }, + "sendPage": { + "title": "Send QWC", + "sendBlock": { + "address": { + "label": "Destination address", + "placeholder": "Write the address where you want to send funds", + "invalid": "The destination address is invalid", + "fundsTo": "The funds will be sent to", + "receiver": "Receiver", + "description": "Description" + }, + "amount": { + "label": "Amount to send", + "invalid": "The amount is invalid" + }, + "paymentId": { + "label": "Payment ID (optional)", + "invalid": "The payment ID is invalid. The length must be 16 or 64 characters" + }, + "sendButton": "Send", + "cancelButton": "Cancel" + }, + "qrCodeScanning": { + "explication": "Present the QR code" + }, + "notEnoughMoneyModal": { + "title": "Oops...", + "content": "You don't have enough funds in your wallet to execute this transfer", + "confirmText": "OK" + }, + "thankYouDonationModal": { + "title": "Thank you for your donation!", + "content": "Your help is appreciated. This donation will help make Qwertycoin better", + "confirmText": "OK" + }, + "transferSentModal": { + "title": "Transfer sent successfully!", + "confirmText": "OK" + }, + "transferExceptionModal": { + "title": "Oops...", + "content": "An error occurred. Please report this error: {details}", + "confirmText": "OK" + }, + "invalidAmountModal": { + "title": "Oops...", + "content": "Invalid amount", + "confirmText": "OK" + }, + "creatingTransferModal": { + "title": "Creating transfer ...", + "content": "Please wait..." + }, + "finalizingTransferModal": { + "title": "Finalizing transfer ...", + "content": "Please wait..." + }, + "confirmTransactionModal": { + "title": "Confirm transfer?", + "content": "Amount: {amount}
Fees: {fees}
Total: {total}", + "confirmText": "Confirm", + "cancelText": "Cancel" + }, + "waitingNfcModal": { + "title": "Waiting Nfc", + "content": "Bring closer to the other device" + } + }, + "receivePage": { + "title": "Receive QWC", + "receiveBlock": { + "address": { + "title": "Your address to receive funds:", + "label": "Give this address to receive funds" + }, + "qrCode": { + "title": "Or personalize the QR code:", + "labelAmount": "Amount (optional)", + "labelRecipient": "Recipient name (optional)", + "labelDescription": "Transaction description (optional)", + "updateButton": "Update" + } + }, + "qrBlock": { + "title": "Your customized QR code" + }, + "waitingNfcToWriteModal": { + "title": "Waiting Nfc", + "titleSuccess": "Nfc Tag written", + "content": "Bring closer the NFC tag to write" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Tag capacity insufficient" + } + }, + "miningPage": { + "title": "Mine directly in your browser", + "subtitle": "Support the network by mining and be rewarded with QWC", + "parameterBlock": { + "title": "Parameters", + "labelDestinationAddress": "Wallet to mine", + "labelThreads": "Number of threads (more = higher hashrate)", + "start": "Start", + "stop": "Stop" + }, + "statisticsBlocks": { + "title": "Statistics", + "validShares": "Valid shares", + "hashrate": "Hashrate", + "maxHashrate": "Max Hashrate", + "dedicatedHardware": "With dedicating mining software and hardware, you could earn more and help decentralize the network.", + "miningHandledBy": "This mining is handled by the mining pool pool.qwertycoin.org" + } + }, + "settingsPage": { + "title": "Settings", + "subtitle": "Change your parameters here", + "versionBlock": { + "versionNumber": "Version number: ", + "versionCode": "Version code: " + }, + "settingsBlock": { + "speed": { + "label": "Speed to update the wallet (will consume more resources)", + "fastest": "Fastest", + "fast": "Fast", + "medium": "Medium", + "slow": "Slow" + }, + "language": { + "label": "Language" + }, + "currency": { + "label": "National Currency" + }, + "readMinerTx": { + "label": "Read miner transactions (only for solo mining)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Change my wallet password", + "deleteWalletButton": "Delete my wallet (local copy)", + "walletSettings": { + "creationHeight": { + "label": "Creation height of the wallet" + }, + "currentScanningHeight": { + "label": "Current scanning height" + }, + "updateButton": "Update" + }, + "deleteWalletModal": { + "title": "Delete My Wallet (local copy)", + "content": "Are you sure you REALLY want to delete your wallet ?", + "confirmText": "Yes I'm sure", + "cancelText": "Cancel" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Parameters", + "password": { + "label": "Password to protect your wallet" + }, + "passwordConfirm": { + "label": "Confirm the password", + "invalid": "The password does not match the first password you wrote" + }, + "importHeight": { + "label": "Height to import from:" + } + } + }, + "importFromQrPage": { + "title": "Importing wallet from a QR code", + "subtitle": "Import a wallet from an offline backup", + "qrCodeBlock": { + "title": "QR code", + "startScanButton": "Start the scan", + "importButton": "Import" + }, + "qrScanningBlock": { + "title": "Present the QR code" + } + }, + "exportPage": { + "title": "Backup your credentials", + "publicAddressBlock": { + "title": "Your public address" + }, + "pdfBlock": { + "title": "PDF Backup", + "downloadButton": "Download" + }, + "warningBlock": { + "title": "Warning", + "content": "If you choose to save your private keys or your mnemonic phrase, PLEASE DO NOT store them in clear-text for your own safety.
The file is an alternate solution where your keys are encrypted and contains a backup of all your transactions to spare you a future synchronisation." + }, + "exportBlock": { + "title": "Export your RAW credentials", + "privateKeysButton": "Get my private keys", + "mnemonicKeysButton": "Get my mnemonic phrase", + "fileButton": "Export to a file" + }, + "walletKeysModal": { + "title": "Private keys", + "confirmText": "OK", + "content": "Please carefully store these keys. Possessing them means possessing the funds associated !
Spend key: {privSpendKey}
Private view key: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Mnemonic phrase", + "confirmText": "OK", + "content": "Please store carefully this mnemonic phrase. Possessing it means possessing the funds associated ! The phrase is:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "In which language do you want your mnemonic phrase?", + "confirmText": "Export" + } + }, + "importPage": { + "title": "Create a wallet", + "subtitle": "From previously created keys, file, or mnemonic phrase", + "chooseMethod": "Choose your import method:", + "fromKeys": "From keys", + "fromFile": "From a file", + "fromMnemonic": "From a mnemonic phrase", + "fromQr": "From a QR code" + }, + "termsOfUsePage": { + "title": "Terms of use", + "subtitle": "Please read them carefully." + }, + "privacyPolicyPage": { + "title": "Privacy Policy", + "subtitle": "Please read them carefully." + }, + "importFromFilePage": { + "title": "Importing wallet from a backup file", + "subtitle": "Use your backup file to create a wallet", + "walletBlock": { + "title": "Wallet file", + "label": "Select the file", + "importButton": "Import" + } + }, + "importFromMnemonicPage": { + "title": "Importing wallet from a mnemonic phrase", + "subtitle": "Use your phrase to create a wallet", + "mnemonicBlock": { + "title": "Mnemonic phrase", + "mnemonic": { + "label": "Mnemonic phrase: 25 words", + "invalid": "The mnemonic phrase is invalid", + "language": "Language" + }, + "importButton": "Import" + } + }, + "importFromKeysPage": { + "title": "Importing wallet from keys", + "subtitle": "Use your keys to create a wallet", + "parametersBlock": { + "viewOnlyWallet": { + "label": "Do you want a view only wallet?" + } + }, + "keysBlock": { + "titleNotViewOnly": "Wallet keys", + "titleViewOnly": "View only wallet", + "privateSpend": { + "label": "Private spend key" + }, + "privateView": { + "label": "Private view key", + "optional": "(optional)" + }, + "publicKey": { + "label": "Public key" + }, + "importButton": "Import" + } + } + }, + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": true + } + } +} diff --git a/src/translations/de.json b/src/translations/de.json index bc52a6c1..679fb0e3 100644 --- a/src/translations/de.json +++ b/src/translations/de.json @@ -1,496 +1,539 @@ { - "website":{ - "title":"Offizielle Karbo Web Wallet", - "description":"Offizielle Online Wallet für Karbo currency, anonym, sicher und für optimale Sicherheit vollständig in deinem Browser verwaltet" + "website": { + "title": "Qwertycoin Web Wallet", + "description": "Offizielle Online Wallet für Qwertycoin Kryptowährung! Anonym, sicher und für optimale Sicherheit vollständig in deinem Browser verwaltet" }, "messages": { - "menu": { - "home": "Home", - "account": "Account", - "send": "Senden", - "receive": "Empfangen", - "export": "Export", - "donate": "Spenden", - "settings": "Einstellungen", - "disconnect": "Verbindung trennen", - "network": "Netzwerkstatus", - "mining": "Minen" - }, - "global": { - "loading": "wird geladen", - "disableSecurity":"Sicherheit verringern, ich verstehe das Risiko", - "passwordInvalidRequirements":"Das Passwort muss mindestens 8 Zeichen lang sein, einen Großbuchstaben, einen Kleinbuchstaben und eine Zahl oder Sonderzeichen enthalten", - "passwordConfirmationNotMatching":"Das Passwort entspricht nicht dem vorher eingegebenen", - "download":"Download", - "newVersionModal":{ - "title":"Eine neue Version ist verfügbar", - "content":"Möchtest du neu laden um die neue Version zu erhalten?", - "confirmText":"Ja", - "cancelText":"Später" - }, - "openWalletModal":{ - "title":"Wallet Passwort", - "confirmText":"Öffnen", - "cancelText":"Abbrechen" - }, - "invalidPasswordModal":{ - "title":"Uups...", - "content":"Dein Passwort scheint falsch zu sein", - "confirmText":"OK" - }, - "invalidMnemonicModal":{ - "title":"Uups...", - "content":"Die Mnemonic Phrase ist falsch", - "confirmText":"OK" - }, - "passwordNotComplexEnoughModal":{ - "title":"Das Passwort ist nicht komplex genug", - "confirmText":"OK" - }, - "permissionRequiredForCameraModal":{ - "title":"Uups...", - "content":"Das Recht zum benutzen der Kamera wird benötigt um den QR Code zu scannen", - "confirmText":"OK" - } - }, - "bottom": { - "termsOfUse": "Nutzungsbedingungen", - "privacyPolicy": "Datenschutzrichtlinie", - "support": "Support", - "donate": "Spenden", - "network": "Netzwerkstatus", - "miningPool": "Mining Pool", - "github": "GitHub" - }, - "homepage": { - "mainTitle": "Gesicherte Karbo Wallet", - "tagLine": "Der einfachste Weg Karbo jederzeit und überall zu nutzen", - "actions": { - "loadWallet": "Lade meine Wallet", - "importWallet": "Importiere eine Wallet", - "create": "Erstelle eine Wallet", - "createWallet": "Erstelle eine Wallet" - }, - "notes": { - "secure": { - "title": "Sicher", - "description": "Keine Server, voll verschlüsselt!" - }, - "fast": { - "title": "Schnell", - "description": "Sende jederzeit, von überall!" - }, - "technology": { - "title": "Einzigartige Technologie", - "description": "Direkt mit der Karbo Blockchain verbunden!" - }, - "openSource": { - "title": "Komplett open-source", - "description": "Vergügbar auf Github" - } - } - }, - "accountPage": { - "title": "Account", - "subtitle": "Überblick über deinen Account und deine Transactionshistorie", - "synchronizingBlock": { - "text": "Synchronisiere " - }, - "balanceBlock": { - "title": "Dein Guthaben", - "unlocked": "Entsperrt" - }, - "historyBlock": { - "title": "Transaktionshistorie", - "pendingTxStatus": "Ausstehend", - "emptyWallet": "Du hast zur Zeit kein Guthaben auf dieser Wallet", - "waitSync": "Warte bis die Wallet upgedated ist", - "beReallyPatient": "Die erste Einrichtung kann etwas dauern...", - "getCoinAddress": "Hol die deine Adresse um KRB zu empfangen" - }, - "txDetails":{ - "title":"Transaktionsdetails", - "txHash":"Tx hash", - "feesOnTx":"Gebühren der tx", - "blockHeight":"Blockhöhe", - "paymentId":"Payment ID", - "txPrivKey":"Privater Schlüssel für die Transaktion" - } - }, - "changeWalletPasswordPage":{ - "title":"Ändere dein Passwort", - "oldPassword":{ - "label":"Altes Passwort", - "invalid":"Das Passwort ist ungültig" - }, - "newPassword":{ - "label":"Wähle ein neues Passwort um deine Daten zu schützen" - }, - "newPasswordConfirm":{ - "label":"Bestätige das neue Passwort" - }, - "confirm":"Ändere das Passwort", - "modalSuccess":{ - "title":"Passwort geändert!", - "confirmText":"OK" - } - }, - "createWalletPage":{ - "generatingStep":{ - "title":"Deine Wallet wird erstellt...", - "subtitle":"Fast fertig", - "waitingMessage":"Erstelle deine Wallet..." - }, - "finalizationStep":{ - "title":"Das war einfach. Dein Account ist bereit!", - "subtitle":"Benutze Karbo wie noch nie zuvor", - "passwordSelectionBlock":{ - "label":"Schütze deine Daten mit einem Passwort" - }, - "passwordConfirmBlock":{ - "label":"Bestätige das Passwort" - }, - "validPassword":"Benutze diese Passwort", - "backupBlock":{ - "title":"Bitte lade eine verschlüsselte Kopie deiner Zugangsdaten für zukünftige Verwendung herunter", - "option1":"Option 1: ", - "option2":"Option 2: ", - "titlePdf":"Download einer PDF Kopie", - "titleManualWrite":"Schreibe meine Schlüssel auf", - "privateKeys":"Private key", - "mnemonicPhrase":"Mnemonic phrase", - "separatorManualMethodsSolution":" oder ", - "confirmManuallyWritten":"Ich habe es aufgeschieben", - "warningMessage":"**Auf keinen Fall verlieren!** Sie können nicht wiederhergestellt werden wenn du sie verlierst.
**Nicht weitergeben!** Deine Karbo werden gestohlen werden wenn diese Datei auf einer bösartigen/Phishing Seite benutzt.
**Mache ein Backup!** Sichere es so wie die Millionen Euro, die es eines Tages vielleicht wert sein wird.
", - "finishButton":"Ich habe verstanden. Weiter" - } - }, - "disclaimerBlock":{ - "title":"Risiko beim benutzen der KarboWallet", - "content":"KarboWallet ist ein web-basierendes Interface. Es hilft beim Nutzen von Karbo ohne einen vollen Node zu betreiben.
Wir empfehlen KarboWallet sicherheitstechnisch wie eine richtige Wallet zu behandeln." - } - }, - "donatePage":{ - "title":"Spenden", - "subtitle":"Hilf uns die Enwicklung zu finanzieren und die Rechnungen zu bezahlen", - "webwalletBlock":{ - "title":"Webwallet", - "content":"Diese Webwallet ist von Gnock in seiner Freizeit entwickelt.
Bitte denk über eine Spende nach wenn dir die App gefällt und du bei der Bezahlung der Server und der Enwicklung helfen willst.:

" - }, - "devFundBlock":{ - "title":"Karbo Entwicklerfonds", - "content":"Spende an diese Adresse um Karbo zu helfen" - } - }, - "supportPage":{ - "title":"Support", - "subtitle":"Du brauchst Hilfe, wir sind hier um zu helfen!", - "getInTouchBlock":{ - "title":"Nehmen wir Kontakt auf!", - "content":"Wenn du Ideen oder Feedback hast um die Wallet zu verbessern, kontaktiere uns!", - "discord":"Karbo Discord Channel" - } - }, - "networkPage":{ - "title":"Netzwerkstatus", - "subtitle":"Einblick ins Marsir Netzwerk", - "statsBlock":{ - "hashrate":"Netzwerk Hashrate", - "height":"Blockchainhöhe", - "difficulty":"Netzwerkschwierigkeit", - "lastTimeBlock":"Letzter gefundener Block", - "lastReward":"Letzte Blockbelohnung" - } - }, - "sendPage":{ - "title":"Schicke KRB", - "sendBlock":{ - "address":{ - "label":"Zieladresse", - "placeholder":"Schreiben Sie die Adresse, wo Sie wollen Mittel schicken", - "invalid":"Die Zieladresse ist ungültig", - "fundsTo":"Das Guthaben wird an folgende Adresse gesendet werden", - "receiver":"Empfänger", - "description":"Beschreibung" - }, - "amount":{ - "label":"Zu sendender Betrag", - "invalid":"Der Betrag ist ungültig" - }, - "paymentId":{ - "label":"Payment ID (optional)", - "invalid":"Die payment ID ist ungültig. Sie muss aus 16 oder 64 Zeichen bestehen" - }, - "sendButton":"Senden", - "cancelButton":"Abbrechen" - }, - "qrCodeScanning":{ - "explication":"Den QR code zeigen" - }, - "notEnoughMoneyModal":{ - "title":"Uups...", - "content":"Du hast nicht genügend Guthaben in deiner Wallet um den Transfer auszuführen", - "confirmText":"OK" - }, - "thankYouDonationModal":{ - "title":"Danke für deine Spende!", - "content":"Deine Hilfe wird sehr geschätzt.
Diese Spende wird helfen Karbo noch beser zu machen", - "confirmText":"Schließen" - }, - "transferSentModal":{ - "title":"Transfer erfolgreich versendet!", - "confirmText":"Schließen" - }, - "transferExceptionModal":{ - "title":"Uups...", - "content":"Ein Fehler ist aufgetreten. Bitte melde uns diesen Fehler: {details}", - "confirmText":"Schließen" - }, - "invalidAmountModal":{ - "title":"Uups...", - "content":"Üngültige Menge", - "confirmText":"Schließen" - }, - "creatingTransferModal":{ - "title":"Transfer wird erstellt ...", - "content":"Bitte warten..." - }, - "finalizingTransferModal":{ - "title":"Transfer wird fertiggestellt ...", - "content":"Bitte warten..." - }, - "confirmTransactionModal":{ - "title":"Transfer bestätigen ?", - "content":"Amount: {amount}
Fees: {fees}
Total: {total}", - "confirmText":"Bestätigen", - "cancelText":"Abbrechen" - }, - "waitingNfcModal":{ - "title":"Waiting Nfc", - "content":"Bring closer to the other device" - } - }, - "receivePage":{ - "title":"Empfange KRB", - "receiveBlock":{ - "address":{ - "title":"Deine Adresse um Guthaben zu empfangen", - "label":"Stelle diese Adresse bereit um Guthaben zu empfangen" - }, - "qrCode":{ - "title":"Oder personalisiere den QR code", - "labelAmount":"Menge (optional)", - "labelRecipient":"Empfängername (optional)", - "labelDescription":"Transaktionsbeschreibung (optional)", - "updateButton":"Update" - } - }, - "qrBlock":{ - "title":"Dein personlisierter QR code" - }, - "waitingNfcToWriteModal":{ - "title":"Waiting Nfc", - "titleSuccess":"Nfc Tag written", - "content":"Bring closer the NFC tag to write" - }, - "nfcErrorModal":{ - "titleInsufficientCapacity":"Tag capacity insufficient" - } - }, - "miningPage":{ - "title":"Mine direkt in deinem Browser", - "subtitle":"Unterstütze das Netzwerk für mehr Stabilität und werde mit KRB belohnt", - "parameterBlock":{ - "title":"Parameter", - "labelDestinationAddress":"Wallet für die gemined werden soll", - "labelThreads":"Anzahl von Threads (mehr = höhere Hashrate)", - "start":"Start", - "stop":"Stop" - }, - "statisticsBlocks":{ - "title":"Statistik", - "validShares":"Gültige shares", - "hashrate":"Hashrate", - "maxHashrate":"Max Hashrate", - "dedicatedHardware":"Mit spezieller Software könnetest du zwei- bis dreimal höhere Hashraten erreichen.
Spezielle Software würde auch mithilfe einer Grafikkarte minen(wenn du einge Gaming GPU hast).", - "miningHandledBy":"Minen erfolgt über den Mining Pool get.masaricoin.com" - } - }, - "settingsPage":{ - "title":"Einstellungen", - "subtitle":"Hier änderst du deine Parameter", - "versionBlock":{ - "versionNumber":"Version number: ", - "versionCode":"Version code: " - }, - "settingsBlock":{ - "speed":{ - "label":"Geschwindigkeit des Walletupdates (braucht mehr Energie)", - "fastest":"am schnellsten", - "fast":"schnell", - "medium":"mittel", - "slow":"langsam" - }, - "language":{ - "label":"Language" - }, - "readMinerTx":{ - "label":"Miner Transaktionen lesen (nur für Leute die solo minen)" - } - }, - "changePasswordButton":"Ändere mein Wallet Passwort", - "deleteWalletButton":"Lösche meine Wallet (lokale Kopie)", - "walletSettings":{ - "creationHeight":{ - "label":"Erstellhöhe der Wallet" - }, - "currentScanningHeight": { - "label": "Aktuelle Scanhöhe" - }, - "updateButton":"Update" - }, - "deleteWalletModal":{ - "title":"Lösche meine Wallet (lokale Kopie)", - "content":"Bist du SICHER das du deine Wallet löschen möchtest?", - "confirmText":"Ja, ich bin sicher", - "cancelText":"Abbrechen" - } - }, - "importBasePage":{ - "parametersBlock":{ - "title":"Parameter", - "password":{ - "label":"Passwort zum Schutz deiner Wallet" - }, - "passwordConfirm":{ - "label":"Bestätige das Passwort", - "invalid":"Das Passwort stimmt nicht mit dem ersten überein" - }, - "importHeight":{ - "label":"Höhe von der importiert werden soll" - } - } - }, - "importFromQrPage":{ - "title":"Importiere Wallet von einem QR code", - "subtitle":"Importiere Wallet von einem offline Backup", - "qrCodeBlock":{ - "title":"QR code", - "startScanButton":"Starte den Scan", - "importButton":"Importiere" - }, - "qrScanningBlock":{ - "title":"Präsentiere den QR code" - } - }, - "exportPage":{ - "title":"Sichere deine Daten", - "publicAddressBlock":{ - "title":"Deine öffentliche Adresse" - }, - "pdfBlock":{ - "title":"Pdf Backup", - "downloadButton":"Download" - }, - "warningBlock":{ - "title":"Warnung", - "content":"Wenn du deinen privaten Schlüssel oder deine mnemonische Phrase speichern möchtest, speichere sie zu deiner eigenen Sicherheit NICHT in klarer und unverschlüsselter Form..
Die Datei ist eine alternative Lösung, bei der deine Schlüssel verschlüsselt sind und ein Backup all deiner Transaktionen enthält, um dir eine zukünftige Synchronisation zu ersparen.." - }, - "exportBlock":{ - "title":"Exportiere deine RAW Zugangsdaten", - "privateKeysButton":"Gib mir meine pirvaten Schlüssel", - "mnemonicKeysButton":"Gib mir meine Mnemonic Phrase", - "fileButton":"Exportiere in eine Datei" - }, - "walletKeysModal":{ - "title":"Private Schlüssel", - "confirmText":"OK", - "content":"Diese Schlüssel bitte sorgfältig speichern. Der Besitz dieser bedeutetd den Besitz des zugeordneten Guthabens !
Spend key: {privSpendKey}
Private view key: {privViewKey}" - }, - "mnemonicKeyModal":{ - "title":"Mnemonic Phrase", - "confirmText":"OK", - "content":"Diese Mnemonic Phrase bitte sorgfältig speichern. Der Besitz dieser Phrase bedeutetd den Besitz des zugeordneten Guthabens ! Die Phrase lautet:
{mnemonic}" - }, - "mnemonicLangSelectionModal":{ - "title":"In welcher Sprache möchtest du deine Mnemonic Phrase ?", - "confirmText":"Exportiere" - } - }, - "importPage":{ - "title":"Erstelle eine Wallet", - "subtitle":"Von vorher erstellten Schlüsslen, einer Datei oder einer Mnemonic Phrase", - "chooseMethod":"Wähle deine Import Methode", - "fromKeys":"Von Schlüsseln", - "fromFile":"Von einer Datei", - "fromMnemonic":"Von einer Mnemonic Phrase", - "fromQr":"Von einem QR code" - }, - "termsOfUsePage":{ - "title":"Nutzungsbedingungen", - "subtitle":"Bitte lies diese genau" - }, - "privacyPolicyPage":{ - "title":"Privacy Policy", - "subtitle":"Bitte lies diese genau" - }, - "importFromFilePage":{ - "title":"Importieren einer Wallet aus einer Backup Datei", - "subtitle":"Benutze die Backup Datei um eine Wallet zu erstellen", - "walletBlock":{ - "title":"Wallet Datei", - "label":"Datei auswählen", - "importButton":"Importiere" - } - }, - "importFromMnemonicPage":{ - "title":"Importieren einer Wallet von einer Mnemonic Phrase", - "subtitle":"Benutze die Phrase um eine Wallet zu erstellen", - "mnemonicBlock":{ - "title":"Mnemonic Phrase", - "mnemonic":{ - "label":"Mnemonic Phrase : 25 Wörter", - "invalid":"Die Mnemonic Phrase ist ungültig", - "language":"Sprache" - }, - "importButton":"Importiere" - } - }, - "importFromKeysPage":{ - "title":"Importiere Wallet mithilfe von Schlüsseln", - "subtitle":"Benutze die Schlüssel um eine Wallet zu erstellen", - "parametersBlock":{ - "viewOnlyWallet":{ - "label":"Möchtest du eine View-Only Wallet?" - } - }, - "keysBlock":{ - "titleNotViewOnly":"Wallet Schlüssel", - "titleViewOnly":"View-Only Wallet", - "privateSpend":{ - "label":"Privater Spend Key" - }, - "privateView":{ - "label":"Privater View Key", - "optional":"(optional)" - }, - "publicKey":{ - "label":"Öffentlicher Schlüssel" - }, - "importButton":"Importiere" - } - } + "menu": { + "home": "Home", + "account": "Account", + "send": "Senden", + "receive": "Empfangen", + "export": "Export", + "donate": "Spenden", + "elections": "Abstimmungen", + "contacts": "Kontakte", + "settings": "Einstellungen", + "disconnect": "Ausloggen", + "network": "Netzwerkstatus", + "mining": "Minen" + }, + "global": { + "loading": "wird geladen", + "disableSecurity": "Verwendung eines schwachen Passworts bestätigen!", + "passwordInvalidRequirements": "Das Passwort muss mindestens 8 Zeichen lang sein, einen Großbuchstaben, einen Kleinbuchstaben und eine Zahl oder Sonderzeichen enthalten", + "passwordConfirmationNotMatching": "Das Passwort entspricht nicht dem vorher eingegebenen", + "download": "Download", + "newVersionModal": { + "title": "Eine neue Version ist verfügbar!", + "content": "Möchtest du neuladen um die neue Version zu erhalten?", + "confirmText": "Ja", + "cancelText": "Später" + }, + "openWalletModal": { + "title": "Wallet Passwort", + "confirmText": "Öffnen", + "cancelText": "Abbrechen" + }, + "invalidPasswordModal": { + "title": "Uups...", + "content": "Dein Passwort scheint falsch zu sein", + "confirmText": "OK" + }, + "invalidMnemonicModal": { + "title": "Uups...", + "content": "Die Mnemonic Phrase ist falsch", + "confirmText": "OK" + }, + "passwordNotComplexEnoughModal": { + "title": "Das Passwort ist nicht komplex genug", + "confirmText": "OK" + }, + "permissionRequiredForCameraModal": { + "title": "Uups...", + "content": "Das Recht zum benutzen der Kamera wird benötigt um den QR Code zu scannen", + "confirmText": "OK" + } + }, + "bottom": { + "termsOfUse": "Nutzungsbedingungen", + "privacyPolicy": "Datenschutzrichtlinie", + "support": "Support", + "donate": "Spenden", + "network": "Netzwerkstatus", + "miningPool": "Mining Pool", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Qwertycoin Wallet", + "tagLine": "Überall zu jeder Zeit - QWC auf jedem Gerät.", + "tagLineTwo": "Der schnellste Weg, Qwertycoin zu verwenden.", + "actions": { + "loadWallet": "Lade meine Wallet", + "importWallet": "Importiere eine Wallet", + "create": "Erstelle eine neue Wallet", + "createWallet": "Erstelle eine neue Wallet" + } + }, + "accountPage": { + "title": "Account", + "subtitle": "Überblick über deinen Account und deine Transaktionshistorie", + "synchronizingBlock": { + "text": "Synchronisiere " + }, + "balanceBlock": { + "title": "Dein Guthaben", + "unlocked": "Entsperrt" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Transaktionshistorie", + "pendingTxStatus": "Ausstehend", + "emptyWallet": "Du hast zur Zeit kein Guthaben auf dieser Wallet", + "waitSync": "Warte bis die Wallet synchronisiert ist.", + "beReallyPatient": "Die erste Einrichtung kann etwas dauern...", + "getCoinAddress": "Hol dir deine Adresse um QWC zu empfangen" + }, + "txDetails": { + "title": "Transaktionsdetails", + "txHash": "TX hash", + "feesOnTx": "Gebühren der TX", + "blockHeight": "Blockhöhe", + "paymentId": "Payment ID", + "unlockStatus": "Status", + "unlockConfirm": "Bestätigungen", + "txPrivKey": "Privater Schlüssel für diese Transaktion" + } + }, + "changeWalletPasswordPage": { + "title": "Ändere dein Passwort", + "oldPassword": { + "label": "Altes Passwort", + "invalid": "Das Passwort ist ungültig" + }, + "newPassword": { + "label": "Wähle ein neues Passwort um deine Daten zu schützen" + }, + "newPasswordConfirm": { + "label": "Bestätige das neue Passwort" + }, + "confirm": "Ändere das Passwort", + "modalSuccess": { + "title": "Passwort geändert!", + "confirmText": "OK" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Abbrechen", + "confirm": "Hinzufügen", + "contactAddress": "Adresse", + "contactName": "Name", + "getNewContacts": "Neuer Kontakt", + "newContact": "Neuer Kontakt", + "noContacts": "Du hast noch keine Kontakte", + "title": "Deine Kontakte" + }, + "contactDetailsBlock": { + "address": "Adresse", + "sendTo": "Sende an ", + "title": "Kontaktdetails" + }, + "subtitle": "Verbinde dich mit anderen QWC Nutzern und sende Ihnen QWC", + "title": "Kontakte" + }, + "electionsPage": { + "title": "Abstimmungen" + }, + "createWalletPage": { + "generatingStep": { + "title": "Deine Wallet wird erstellt...", + "subtitle": "Fast fertig", + "waitingMessage": "Erstelle deine Wallet..." + }, + "finalizationStep": { + "title": "Das war einfach. Dein Account ist bereit!", + "subtitle": "Benutze Qwertycoin wie noch nie zuvor", + "passwordSelectionBlock": { + "label": "Schütze deine Daten mit einem Passwort" + }, + "passwordConfirmBlock": { + "label": "Bestätige das Passwort" + }, + "validPassword": "Benutze diese Passwort", + "backupBlock": { + "title": "Bitte lade eine verschlüsselte Kopie deiner Zugangsdaten für zukünftige Verwendung herunter", + "option1": "Option 1: ", + "option2": "Option 2: ", + "titlePdf": "Download einer PDF Kopie", + "titleManualWrite": "Schreibe meine Schlüssel auf", + "privateKeys": "Private key", + "mnemonicPhrase": "Mnemonic phrase", + "separatorManualMethodsSolution": " oder ", + "confirmManuallyWritten": "Ich habe es aufgeschieben", + "warningMessage": "**Auf keinen Fall verlieren!** Sie können nicht wiederhergestellt werden wenn du sie verlierst.
**Nicht weitergeben!** Deine Qwertycoin werden gestohlen werden wenn diese Datei auf einer bösartigen/Phishing Seite benutzt.
**Mache ein Backup!** Sichere es so wie die Millionen Euro, die es eines Tages vielleicht wert sein wird.
", + "finishButton": "Ich habe verstanden. Weiter" + } + }, + "disclaimerBlock": { + "title": "Risiko beim benutzen der QwertycoinWallet", + "content": "QwertycoinWallet ist ein web-basierendes Interface. Es hilft beim Nutzen von Qwertycoin ohne einen vollen Node zu betreiben.
Wir empfehlen QwertycoinWallet sicherheitstechnisch wie eine richtige Wallet zu behandeln." + } + }, + "donatePage": { + "title": "Spenden", + "subtitle": "Hilf uns die Entwicklung zu finanzieren und die Rechnungen zu bezahlen", + "webwalletBlock": { + "title": "Webwallet", + "content": "Bitte denke über eine Spende nach wenn dir die App gefällt und du bei der Bezahlung der Server und der Enwicklung helfen willst.:

" + }, + "devFundBlock": { + "title": "Qwertycoin Entwicklerfonds", + "content": "Spende an diese Adresse um Qwertycoin zu unterstützen" + } + }, + "supportPage": { + "title": "Support", + "subtitle": "Du brauchst Hilfe? Wir helfen dir!", + "getInTouchBlock": { + "title": "So erreichst du uns!", + "content": "Wenn du Ideen oder Feedback hast um die Wallet zu verbessern, kontaktiere uns!", + "discord": "Qwertycoin Discord Channel" + } + }, + "networkPage": { + "title": "Netzwerkstatus", + "subtitle": "Einblicke ins Qwertycoin Netzwerk", + "statsBlock": { + "connectNode": "Verbundene Masternode", + "hashrate": "Netzwerk Hashrate", + "height": "Blockchainhöhe", + "difficulty": "Netzwerkschwierigkeit", + "lastTimeBlock": "Letzter gefundener Block", + "lastReward": "Letzte Blockbelohnung" + } + }, + "sendPage": { + "title": "QWC Überweisung", + "sendBlock": { + "address": { + "label": "Zieladresse", + "placeholder": "Empfängeradresse (QWC....)", + "invalid": "Die Zieladresse ist ungültig", + "fundsTo": "Das Guthaben wird an folgende Adresse gesendet werden", + "receiver": "Empfänger", + "description": "Beschreibung" + }, + "amount": { + "label": "Zu sendender Betrag", + "invalid": "Der Betrag ist ungültig" + }, + "paymentId": { + "label": "Payment ID (optional)", + "invalid": "Die payment ID ist ungültig. Sie muss aus 64 Zeichen bestehen" + }, + "sendButton": "Senden", + "cancelButton": "Abbrechen" + }, + "qrCodeScanning": { + "explication": "Den QR code zeigen" + }, + "notEnoughMoneyModal": { + "title": "Uups...", + "content": "Du hast nicht genügend Guthaben in deiner Wallet um den Transfer auszuführen", + "confirmText": "OK" + }, + "thankYouDonationModal": { + "title": "Danke für deine Spende!", + "content": "Deine Hilfe wird sehr geschätzt. Diese Spende wird helfen Qwertycoin noch beser zu machen", + "confirmText": "Schließen" + }, + "transferSentModal": { + "title": "Transfer erfolgreich versendet!", + "confirmText": "Schließen" + }, + "transferExceptionModal": { + "title": "Uups...", + "content": "Ein Fehler ist aufgetreten. Bitte melde uns diesen Fehler: {details}", + "confirmText": "Schließen" + }, + "invalidAmountModal": { + "title": "Uups...", + "content": "Üngültige Menge", + "confirmText": "Schließen" + }, + "creatingTransferModal": { + "title": "Transfer wird erstellt ...", + "content": "Bitte warten..." + }, + "finalizingTransferModal": { + "title": "Transfer wird fertiggestellt ...", + "content": "Bitte warten..." + }, + "confirmTransactionModal": { + "title": "Transfer bestätigen ?", + "content": "Amount: {amount}
Fees: {fees}
Total: {total}", + "confirmText": "Bestätigen", + "cancelText": "Abbrechen" + }, + "waitingNfcModal": { + "title": "Waiting NFC", + "content": "Bring closer to the other device" + } + }, + "receivePage": { + "title": "Empfange QWC", + "receiveBlock": { + "address": { + "title": "Deine Adresse um Qwertycoin zu empfangen", + "label": "Stelle diese Adresse bereit um QWC zu empfangen" + }, + "qrCode": { + "title": "Oder erstelle einen eigenen QR-Code um Zahlungen zu erhalten", + "labelAmount": "Geünschte QWC (optional)", + "labelRecipient": "Empfängername (optional)", + "labelDescription": "Beschreibung wofür diese Transaktion ist (optional)", + "updateButton": "QR-Code generieren" + } + }, + "qrBlock": { + "title": "Dein personalisierter QR code" + }, + "waitingNfcToWriteModal": { + "title": "Waiting Nfc", + "titleSuccess": "NFC Tag written", + "content": "Bring closer the NFC tag to write" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Tag capacity insufficient" + } + }, + "miningPage": { + "title": "Mine direkt in deinem Browser", + "subtitle": "Unterstütze das Netzwerk für mehr Stabilität und werde mit QWC belohnt", + "parameterBlock": { + "title": "Parameter", + "labelDestinationAddress": "Wallet für die gemined werden soll", + "labelThreads": "Anzahl von Threads (mehr = höhere Hashrate)", + "start": "Start", + "stop": "Stop" + }, + "statisticsBlocks": { + "title": "Statistik", + "validShares": "Gültige shares", + "hashrate": "Hashrate", + "maxHashrate": "Max Hashrate", + "dedicatedHardware": "Mit spezieller Software könnetest du zwei- bis dreimal höhere Hashraten erreichen.
Spezielle Software würde auch mithilfe einer Grafikkarte minen(wenn du einge Gaming GPU hast).", + "miningHandledBy": "Minen erfolgt über den Mining Pool pool.qwertycoin.org" + } + }, + "settingsPage": { + "title": "Einstellungen", + "subtitle": "Hier kannst du deine Einstellungen verwalten", + "versionBlock": { + "versionNumber": "Version number: ", + "versionCode": "Version code: " + }, + "settingsBlock": { + "speed": { + "label": "Mit welcher Geschwindigkeit soll die Wallet aktualisiert werden?", + "fastest": "am schnellsten", + "fast": "schnell", + "medium": "mittel", + "slow": "langsam" + }, + "language": { + "label": "Systemsprache" + }, + "currency": { + "label": "Landeswährung (Wird unter dem Kontostand angezeigt)" + }, + "readMinerTx": { + "label": "Zeige etwaige Mining Transaktionen an (optional)" + }, + "customNode": { + "label": "Favorisierten Server auswählen" + }, + "nodeUrl": { + "label": "Server Auswahl" + }, + "chooseNode": "Wähle deinen Server:" + }, + "changePasswordButton": "Wallet Passwort ändern", + "deleteWalletButton": "Entferne meine Wallet von diesem Gerät (nur wenn du ein Backup hast)", + "walletSettings": { + "creationHeight": { + "label": "Erstellhöhe deiner Wallet" + }, + "currentScanningHeight": { + "label": "Synchronisationshöhe" + }, + "updateButton": "Speichern" + }, + "deleteWalletModal": { + "title": "Lösche meine Wallet (lokale Kopie)", + "content": "Bist du SICHER, dass du deine Wallet löschen möchtest?", + "confirmText": "Ja, ich bin sicher", + "cancelText": "Abbrechen" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Parameter", + "password": { + "label": "Passwort zum Schutz deiner Wallet" + }, + "passwordConfirm": { + "label": "Bestätige das Passwort", + "invalid": "Das Passwort stimmt nicht mit dem ersten überein" + }, + "importHeight": { + "label": "Höhe von der importiert werden soll" + } + } + }, + "importFromQrPage": { + "title": "Importiere Wallet von einem QR code", + "subtitle": "Importiere Wallet von einem offline Backup", + "qrCodeBlock": { + "title": "QR code", + "startScanButton": "Starte den Scan", + "importButton": "Importiere" + }, + "qrScanningBlock": { + "title": "Präsentiere den QR code" + } + }, + "exportPage": { + "title": "Export deiner PrivateKeys", + "publicAddressBlock": { + "title": "Deine öffentliche Adresse" + }, + "pdfBlock": { + "title": "PDF Backup zum ausdrucken", + "downloadButton": "Download" + }, + "warningBlock": { + "title": "Hinweis", + "content": "Wenn du deinen privaten Schlüssel oder deine mnemonische Phrase speichern möchtest, speichere sie zu deiner eigenen Sicherheit NICHT in klarer und unverschlüsselter Form.
Diese Datei ist eine alternative Lösung, bei der deine Schlüssel verschlüsselt sind und ein Backup all deiner Transaktionen enthält, um dir eine zukünftige Synchronisation zu ersparen.." + }, + "exportBlock": { + "title": "Exportiere deine Private-Keys (Zugangsdaten)", + "privateKeysButton": "Zeige meine privaten Schlüssel an", + "mnemonicKeysButton": "Zeige meine Mnemonic Phrase", + "fileButton": "Exportiere in eine Datei" + }, + "walletKeysModal": { + "title": "Private Schlüssel", + "confirmText": "OK", + "content": "Diese Schlüssel bitte sorgfältig speichern. Der Besitz dieser bedeutetd den Besitz des zugeordneten Guthabens !
Spend key: {privSpendKey}
Private view key: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Mnemonic Phrase", + "confirmText": "OK", + "content": "Diese Mnemonic Phrase bitte sorgfältig speichern. Der Besitz dieser Phrase bedeutetd den Besitz des zugeordneten Guthabens ! Die Phrase lautet:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "In welcher Sprache möchtest du deine Mnemonic Phrase ?", + "confirmText": "Exportiere" + } + }, + "importPage": { + "title": "Importieren einer vorhandenen Wallet", + "subtitle": "Du kannst eine Wallet über den Seed (mnemonische Phrase), den privaten Keys oder durch eine WebWallet Backup-Datei importieren.", + "chooseMethod": "Wähle deine Import Methode", + "fromKeys": "Von Schlüsseln", + "fromFile": "Von einer Backupdatei", + "fromMnemonic": "Von einer Mnemonic Phrase", + "fromQr": "Von einem QR code" + }, + "termsOfUsePage": { + "title": "Nutzungsbedingungen", + "subtitle": "Bitte lies diese genau" + }, + "privacyPolicyPage": { + "title": "Privacy Policy", + "subtitle": "Bitte lies diese genau" + }, + "importFromFilePage": { + "title": "Importieren einer Wallet aus einer Backup Datei", + "subtitle": "Benutze die Backup Datei um eine Wallet zu erstellen", + "walletBlock": { + "title": "Wallet Datei", + "label": "Datei auswählen", + "importButton": "Importiere" + } + }, + "importFromMnemonicPage": { + "title": "Importieren einer Wallet von einer Mnemonic Phrase", + "subtitle": "Benutze die Phrase um eine Wallet zu erstellen", + "mnemonicBlock": { + "title": "Mnemonic Phrase", + "mnemonic": { + "label": "Mnemonic Phrase : 25 Wörter", + "invalid": "Die Mnemonic Phrase ist ungültig", + "language": "Sprache" + }, + "importButton": "Importiere" + } + }, + "importFromKeysPage": { + "title": "Importiere Wallet mithilfe von Schlüsseln", + "subtitle": "Benutze die Schlüssel um eine Wallet zu erstellen", + "parametersBlock": { + "viewOnlyWallet": { + "label": "Möchtest du eine View-Only Wallet?" + } + }, + "keysBlock": { + "titleNotViewOnly": "Wallet Schlüssel", + "titleViewOnly": "View-Only Wallet", + "privateSpend": { + "label": "Privater Spend Key" + }, + "privateView": { + "label": "Privater View Key", + "optional": "(optional)" + }, + "publicKey": { + "label": "Öffentlicher Schlüssel" + }, + "importButton": "Importiere" + } + } }, - "number":{ - - }, - "date":{ - "short": { - "year": "numeric", "month": "short", "day": "numeric" - }, - "long": { - "year": "numeric", "month": "short", "day": "numeric", - "weekday": "short", "hour": "numeric", "minute": "numeric", "hour12": false - } + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": false + } } } diff --git a/src/translations/en.json b/src/translations/en.json index af80583c..fc328c4a 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1,495 +1,539 @@ { - "website":{ - "title":"Client-side Karbo Web Wallet", - "description":"Official online wallet for Karbo currency - fully handled in your browser for optimal security" + "website": { + "title": "Qwertycoin Wallet | Simple, seamless, safe. Welcome to the future.", + "description": "Official online wallet for Qwertycoin currency - fully handled in your browser for optimal security" }, "messages": { - "menu": { - "home": "Home", - "account": "Account", - "send": "Send", - "receive": "Receive", - "export": "Export", - "donate": "Donate", - "settings": "Settings", - "disconnect": "Disconnect", - "network": "Network Stats", - "mining": "Mining" - }, - "global": { - "loading": "Loading", - "disableSecurity":"Disable this security, I understand the risk", - "passwordInvalidRequirements":"The password needs at least 8 characters - 1 upper case letter, 1 lower case letter, one number, and one special character", - "passwordConfirmationNotMatching":"The password does not match the first password you wrote", - "download":"Download", - "newVersionModal":{ - "title":"A new version is available", - "content":"Do you want to reload to load the new version?", - "confirmText":"Yes", - "cancelText":"Back" - }, - "openWalletModal":{ - "title":"Wallet Password", - "confirmText":"Open", - "cancelText":"Cancel" - }, - "invalidPasswordModal":{ - "title":"Oops...", - "content":"Your password seems invalid", - "confirmText":"OK" - }, - "invalidMnemonicModal":{ - "title":"Oops...", - "content":"The mnemonic phrase is invalid", - "confirmText":"OK" - }, - "passwordNotComplexEnoughModal":{ - "title":"The password is not complex enough", - "confirmText":"OK" - }, - "permissionRequiredForCameraModal":{ - "title":"Oops...", - "content":"The permission to access your camera is required to scan the QR code", - "confirmText":"OK" - } - }, - "bottom": { - "termsOfUse": "Terms of Use", - "privacyPolicy": "Privacy Policy", - "support": "Support", - "donate": "Donate", - "network": "Network Stats", - "miningPool": "Mining Pool", - "github": "GitHub" - }, - "homepage": { - "mainTitle": "Secure Karbo Wallet", - "tagLine": "The simplest way to use Karbo – anywhere and any time", - "actions": { - "loadWallet": "Load my wallet", - "importWallet": "Import a wallet", - "create": "Create", - "createWallet": "Create a wallet" - }, - "notes": { - "secure": { - "title": "Secure", - "description": "No servers, fully encrypted!" - }, - "fast": { - "title": "Fast", - "description": "Send Everywhere, Anytime!" - }, - "technology": { - "title": "Local", - "description": "Keys on your device" - }, - "openSource": { - "title": "Open-source", - "description": "Verify on Github!" - } - } - }, - "accountPage": { - "title": "Account", - "subtitle": "Your account overview and transaction history", - "synchronizingBlock": { - "text": "Synchronizing..." - }, - "balanceBlock": { - "title": "Your balance", - "unlocked": "Unlocked" - }, - "historyBlock": { - "title": "Transaction history", - "pendingTxStatus": "Pending", - "emptyWallet": "You currently have no funds in this wallet.", - "waitSync": "Please wait until the wallet is updated", - "beReallyPatient": "The initial setup can take some time...", - "getCoinAddress": "Receive KRB" - }, - "txDetails":{ - "title":"Transaction details", - "txHash":"Tx hash", - "feesOnTx":"Tx fees", - "blockHeight":"Block height", - "paymentId":"Payment ID", - "txPrivKey":"Transaction Private Key" - } - }, - "changeWalletPasswordPage":{ - "title":"Change your password", - "oldPassword":{ - "label":"Old password", - "invalid":"The password is invalid" - }, - "newPassword":{ - "label":"Choose a new password to protect your wallet" - }, - "newPasswordConfirm":{ - "label":"Confirm the new password" - }, - "confirm":"Change the password", - "modalSuccess":{ - "title":"Password changed!", - "confirmText":"OK" - } - }, - "createWalletPage":{ - "generatingStep":{ - "title":"Your wallet is being generated...", - "subtitle":"It's almost done", - "waitingMessage":"Generating your wallet..." - }, - "finalizationStep":{ - "title":"That was simple. Your account is ready!", - "subtitle":"Be ready to use Karbo like you never have", - "passwordSelectionBlock":{ - "label":"Protect your wallet" - }, - "passwordConfirmBlock":{ - "label":"Confirm the password" - }, - "validPassword":"Use this password", - "backupBlock":{ - "title":"Save your private credentials for recovery.", - "option1":"Option 1: ", - "option2":"Option 2: ", - "titlePdf":"Download a PDF copy", - "titleManualWrite":"Write down my keys", - "privateKeys":"Private key", - "mnemonicPhrase":"Mnemonic phrase", - "separatorManualMethodsSolution":" or ", - "confirmManuallyWritten":"I wrote my seed phrase down", - "warningMessage":"**Do not lose it!** It cannot be recovered if you lose it.
**Do not share it!** Your funds will be stolen if you use this file or seed on a malicious/phishing site.
**Make a backup!** Secure it like the millions of dollars it may one day be worth.
", - "finishButton":"I understand. Continue." - } - }, - "disclaimerBlock":{ - "title":"Risk of Using KarboWallet", - "content":"KarboWallet is a web-based interface. It helps you use Karbo without running a full Karbo node.
We recommend you treat KarboWallet like you will treat your actual wallet." - } - }, - "donatePage":{ - "title":"Donate", - "subtitle":"Help to fund the development and pay the bills", - "webwalletBlock":{ - "title":"Webwallet", - "content":"If you want to help to pay for the servers, to support new features development, and like this app, please consider a donation:

" - }, - "devFundBlock":{ - "title":"Karbo Dev fund", - "content":"To help Karbo, you can donate at these addresses" - } - }, - "supportPage":{ - "title":"Support", - "subtitle":"We are here to help!", - "getInTouchBlock":{ - "title":"Let's Get In Touch!", - "content":"Do you have ideas or feedback that could help us improve the wallet? Contact us!", - "discord":"Karbo Discord Channel" - } - }, - "networkPage":{ - "title":"Network stats", - "subtitle":"Insights on the Karbo network", - "statsBlock":{ - "hashrate":"Network hashrate", - "height":"Blockchain height", - "difficulty":"Network difficulty", - "lastTimeBlock":"Last block found", - "lastReward":"Last block reward" - } - }, - "sendPage":{ - "title":"Send KRB", - "sendBlock":{ - "address":{ - "label":"Destination address", - "placeholder":"Write the address where you want to send funds", - "invalid":"The destination address is invalid", - "fundsTo":"The funds will be sent to", - "receiver":"Receiver", - "description":"Description" - }, - "amount":{ - "label":"Amount to send", - "invalid":"The amount is invalid" - }, - "paymentId":{ - "label":"Payment ID (optional)", - "invalid":"The payment ID is invalid. The length must be 16 or 64 characters" - }, - "sendButton":"Send", - "cancelButton":"Cancel" - }, - "qrCodeScanning":{ - "explication":"Present the QR code" - }, - "notEnoughMoneyModal":{ - "title":"Oops...", - "content":"You don't have enough funds in your wallet to execute this transfer", - "confirmText":"OK" - }, - "thankYouDonationModal":{ - "title":"Thank you for your donation!", - "content":"Your help is appreciated.
This donation will help make Karbo better", - "confirmText":"OK" - }, - "transferSentModal":{ - "title":"Transfer sent successfully!", - "confirmText":"OK" - }, - "transferExceptionModal":{ - "title":"Oops...", - "content":"An error occurred. Please report this error: {details}", - "confirmText":"OK" - }, - "invalidAmountModal":{ - "title":"Oops...", - "content":"Invalid amount", - "confirmText":"OK" - }, - "creatingTransferModal":{ - "title":"Creating transfer ...", - "content":"Please wait..." - }, - "finalizingTransferModal":{ - "title":"Finalizing transfer ...", - "content":"Please wait..." - }, - "confirmTransactionModal":{ - "title":"Confirm transfer?", - "content":"Amount: {amount}
Fees: {fees}
Total: {total}", - "confirmText":"Confirm", - "cancelText":"Cancel" - }, - "waitingNfcModal":{ - "title":"Waiting Nfc", - "content":"Bring closer to the other device" - } - }, - "receivePage":{ - "title":"Receive KRB", - "receiveBlock":{ - "address":{ - "title":"Your address to receive funds:", - "label":"Give this address to receive funds" - }, - "qrCode":{ - "title":"Or personalize the QR code:", - "labelAmount":"Amount (optional)", - "labelRecipient":"Recipient name (optional)", - "labelDescription":"Transaction description (optional)", - "updateButton":"Update" - } - }, - "qrBlock":{ - "title":"Your customized QR code" - }, - "waitingNfcToWriteModal":{ - "title":"Waiting Nfc", - "titleSuccess":"Nfc Tag written", - "content":"Bring closer the NFC tag to write" - }, - "nfcErrorModal":{ - "titleInsufficientCapacity":"Tag capacity insufficient" - } - }, - "miningPage":{ - "title":"Mine directly in your browser", - "subtitle":"Support the network by mining and be rewarded with KRB", - "parameterBlock":{ - "title":"Parameters", - "labelDestinationAddress":"Wallet to mine", - "labelThreads":"Number of threads (more = higher hashrate)", - "start":"Start", - "stop":"Stop" - }, - "statisticsBlocks":{ - "title":"Statistics", - "validShares":"Valid shares", - "hashrate":"Hashrate", - "maxHashrate":"Max Hashrate", - "dedicatedHardware":"With dedicating mining software and hardware, you could earn more and help decentralize the network.", - "miningHandledBy":"This mining is handled by the mining pool get.masaricoin.com" - } - }, - "settingsPage":{ - "title":"Settings", - "subtitle":"Change your parameters here", - "versionBlock":{ - "versionNumber":"Version number: ", - "versionCode":"Version code: " - }, - "settingsBlock":{ - "speed":{ - "label":"Speed to update the wallet (will consume more resources)", - "fastest":"Fastest", - "fast":"Fast", - "medium":"Medium", - "slow":"Slow" - }, - "language":{ - "label":"Language" - }, - "readMinerTx":{ - "label":"Read miner transactions (only for solo mining)" - } - }, - "changePasswordButton":"Change my wallet password", - "deleteWalletButton":"Delete my wallet (local copy)", - "walletSettings":{ - "creationHeight":{ - "label":"Creation height of the wallet" - }, - "currentScanningHeight": { - "label": "Current scanning height" - }, - "updateButton":"Update" - }, - "deleteWalletModal":{ - "title":"Delete My Wallet (local copy)", - "content":"Are you sure you REALLY want to delete your wallet ?", - "confirmText":"Yes I'm sure", - "cancelText":"Cancel" - } - }, - "importBasePage":{ - "parametersBlock":{ - "title":"Parameters", - "password":{ - "label":"Password to protect your wallet" - }, - "passwordConfirm":{ - "label":"Confirm the password", - "invalid":"The password does not match the first password you wrote" - }, - "importHeight":{ - "label":"Height to import from:" - } - } - }, - "importFromQrPage":{ - "title":"Importing wallet from a QR code", - "subtitle":"Import a wallet from an offline backup", - "qrCodeBlock":{ - "title":"QR code", - "startScanButton":"Start the scan", - "importButton":"Import" - }, - "qrScanningBlock":{ - "title":"Present the QR code" - } - }, - "exportPage":{ - "title":"Backup your credentials", - "publicAddressBlock":{ - "title":"Your public address" - }, - "pdfBlock":{ - "title":"PDF Backup", - "downloadButton":"Download" - }, - "warningBlock":{ - "title":"Warning", - "content":"If you choose to save your private keys or your mnemonic phrase, PLEASE DO NOT store them in clear-text for your own safety.
The file is an alternate solution where your keys are encrypted and contains a backup of all your transactions to spare you a future synchronisation." - }, - "exportBlock":{ - "title":"Export your RAW credentials", - "privateKeysButton":"Get my private keys", - "mnemonicKeysButton":"Get my mnemonic phrase", - "fileButton":"Export to a file" - }, - "walletKeysModal":{ - "title":"Private keys", - "confirmText":"OK", - "content":"Please carefully store these keys. Possessing them means possessing the funds associated !
Spend key: {privSpendKey}
Private view key: {privViewKey}" - }, - "mnemonicKeyModal":{ - "title":"Mnemonic phrase", - "confirmText":"OK", - "content":"Please store carefully this mnemonic phrase. Possessing it means possessing the funds associated ! The phrase is:
{mnemonic}" - }, - "mnemonicLangSelectionModal":{ - "title":"In which language do you want your mnemonic phrase?", - "confirmText":"Export" - } - }, - "importPage":{ - "title":"Create a wallet", - "subtitle":"From previously created keys, file, or mnemonic phrase", - "chooseMethod":"Choose your import method:", - "fromKeys":"From keys", - "fromFile":"From a file", - "fromMnemonic":"From a mnemonic phrase", - "fromQr":"From a QR code" - }, - "termsOfUsePage":{ - "title":"Terms of use", - "subtitle":"Please read them carefully." - }, - "privacyPolicyPage":{ - "title":"Privacy Policy", - "subtitle":"Please read them carefully." - }, - "importFromFilePage":{ - "title":"Importing wallet from a backup file", - "subtitle":"Use your backup file to create a wallet", - "walletBlock":{ - "title":"Wallet file", - "label":"Select the file", - "importButton":"Import" - } - }, - "importFromMnemonicPage":{ - "title":"Importing wallet from a mnemonic phrase", - "subtitle":"Use your phrase to create a wallet", - "mnemonicBlock":{ - "title":"Mnemonic phrase", - "mnemonic":{ - "label":"Mnemonic phrase: 25 words", - "invalid":"The mnemonic phrase is invalid", - "language":"Language" - }, - "importButton":"Import" - } - }, - "importFromKeysPage":{ - "title":"Importing wallet from keys", - "subtitle":"Use your keys to create a wallet", - "parametersBlock":{ - "viewOnlyWallet":{ - "label":"Do you want a view only wallet?" - } - }, - "keysBlock":{ - "titleNotViewOnly":"Wallet keys", - "titleViewOnly":"View only wallet", - "privateSpend":{ - "label":"Private spend key" - }, - "privateView":{ - "label":"Private view key", - "optional":"(optional)" - }, - "publicKey":{ - "label":"Public key" - }, - "importButton":"Import" - } - } + "menu": { + "home": "Home", + "account": "Account", + "send": "Send", + "receive": "Receive", + "export": "Export", + "donate": "Donate", + "elections": "Elections", + "contacts": "Contacts", + "settings": "Settings", + "disconnect": "Disconnect", + "network": "Network Stats", + "mining": "Mining" + }, + "global": { + "loading": "Loading", + "disableSecurity": "Disable this security, I understand the risk", + "passwordInvalidRequirements": "The password needs at least 8 characters - 1 upper case letter, 1 lower case letter, one number, and one special character", + "passwordConfirmationNotMatching": "The password does not match the first password you wrote", + "download": "Download", + "newVersionModal": { + "title": "A new version is available", + "content": "Do you want to reload to load the new version?", + "confirmText": "Yes", + "cancelText": "Back" + }, + "openWalletModal": { + "title": "Wallet Password", + "confirmText": "Open", + "cancelText": "Cancel" + }, + "invalidPasswordModal": { + "title": "Oops...", + "content": "Your password seems invalid", + "confirmText": "OK" + }, + "invalidMnemonicModal": { + "title": "Oops...", + "content": "The mnemonic phrase is invalid", + "confirmText": "OK" + }, + "passwordNotComplexEnoughModal": { + "title": "The password is not complex enough", + "confirmText": "OK" + }, + "permissionRequiredForCameraModal": { + "title": "Oops...", + "content": "The permission to access your camera is required to scan the QR code", + "confirmText": "OK" + } + }, + "bottom": { + "termsOfUse": "Terms of Use", + "privacyPolicy": "Privacy Policy", + "support": "Support", + "donate": "Donate", + "network": "Network Stats", + "miningPool": "Mining Pool", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Qwertycoin Wallet", + "tagLine": "anywhere. anytime. anyplace. any device.", + "tagLineTwo": "The simplest way to use Qwertycoin", + "actions": { + "loadWallet": "Load my wallet", + "importWallet": "Import a wallet", + "create": "Create", + "createWallet": "Create a wallet" + } + }, + "accountPage": { + "title": "Account", + "subtitle": "Your account overview and transaction history", + "synchronizingBlock": { + "text": "Synchronizing..." + }, + "balanceBlock": { + "title": "Your balance", + "unlocked": "Unlocked" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Transaction history", + "pendingTxStatus": "Pending", + "emptyWallet": "You currently have no funds in this wallet.", + "waitSync": "Please wait until the wallet is updated", + "beReallyPatient": "The initial setup can take some time...", + "getCoinAddress": "Receive QWC" + }, + "txDetails": { + "title": "Transaction details", + "txHash": "Transaction Hash", + "feesOnTx": "Transaction fee", + "blockHeight": "Block height", + "paymentId": "Payment ID", + "unlockStatus": "Status", + "unlockConfirm": "Confirmations", + "txPrivKey": "Transaction Private Key" + } + }, + "changeWalletPasswordPage": { + "title": "Change your password", + "oldPassword": { + "label": "Old password", + "invalid": "The password is invalid" + }, + "newPassword": { + "label": "Choose a new password to protect your wallet" + }, + "newPasswordConfirm": { + "label": "Confirm the new password" + }, + "confirm": "Change the password", + "modalSuccess": { + "title": "Password changed!", + "confirmText": "OK" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "Contacts" + }, + "electionsPage": { + "title": "Elections" + }, + "createWalletPage": { + "generatingStep": { + "title": "Your wallet is being generated...", + "subtitle": "It's almost done", + "waitingMessage": "Generating your wallet..." + }, + "finalizationStep": { + "title": "That was simple. Your account is ready!", + "subtitle": "Be ready to use Qwertycoin like you never have", + "passwordSelectionBlock": { + "label": "Protect your wallet" + }, + "passwordConfirmBlock": { + "label": "Confirm the password" + }, + "validPassword": "Use this password", + "backupBlock": { + "title": "Save your private credentials for recovery.", + "option1": "Option 1: ", + "option2": "Option 2: ", + "titlePdf": "Download a PDF copy", + "titleManualWrite": "Write down my keys", + "privateKeys": "Private key", + "mnemonicPhrase": "Mnemonic phrase", + "separatorManualMethodsSolution": " or ", + "confirmManuallyWritten": "I wrote my seed phrase down", + "warningMessage": "**Do not lose it!** It cannot be recovered if you lose it.
**Do not share it!** Your funds will be stolen if you use this file or seed on a malicious/phishing site.
**Make a backup!** Secure it like the millions of dollars it may one day be worth.
", + "finishButton": "I understand. Continue." + } + }, + "disclaimerBlock": { + "title": "Risk of Using QwertycoinWallet", + "content": "QwertycoinWallet is a web-based interface. It helps you use Qwertycoin without running a full Qwertycoin node.
We recommend you treat QwertycoinWallet like you will treat your actual wallet." + } + }, + "donatePage": { + "title": "Donate", + "subtitle": "Help to fund the development and pay the bills", + "webwalletBlock": { + "title": "Webwallet", + "content": "If you want to help to pay for the servers, to support new features development, and like this app, please consider a donation:

" + }, + "devFundBlock": { + "title": "Qwertycoin Dev fund", + "content": "To help Qwertycoin, you can donate at these addresses" + } + }, + "supportPage": { + "title": "Support", + "subtitle": "We are here to help!", + "getInTouchBlock": { + "title": "Let's Get In Touch!", + "content": "Do you have ideas or feedback that could help us improve the wallet? Contact us!", + "discord": "Qwertycoin Discord Channel" + } + }, + "networkPage": { + "title": "Network stats", + "subtitle": "Insights on the Qwertycoin network", + "statsBlock": { + "connectNode": "Connected Masternode", + "hashrate": "Network hashrate", + "height": "Blockchain height", + "difficulty": "Network difficulty", + "lastTimeBlock": "Last block found", + "lastReward": "Last block reward" + } + }, + "sendPage": { + "title": "Send QWC", + "sendBlock": { + "address": { + "label": "Destination address", + "placeholder": "Write the address where you want to send funds", + "invalid": "The destination address is invalid", + "fundsTo": "The funds will be sent to", + "receiver": "Receiver", + "description": "Description" + }, + "amount": { + "label": "Amount to send", + "invalid": "The amount is invalid" + }, + "paymentId": { + "label": "Payment ID (optional)", + "invalid": "The payment ID is invalid. The length must be 16 or 64 characters" + }, + "sendButton": "Send", + "cancelButton": "Cancel" + }, + "qrCodeScanning": { + "explication": "Present the QR code" + }, + "notEnoughMoneyModal": { + "title": "Oops...", + "content": "You don't have enough funds in your wallet to execute this transfer", + "confirmText": "OK" + }, + "thankYouDonationModal": { + "title": "Thank you for your donation!", + "content": "Your help is appreciated. This donation will help make Qwertycoin better", + "confirmText": "OK" + }, + "transferSentModal": { + "title": "Transfer sent successfully!", + "confirmText": "OK" + }, + "transferExceptionModal": { + "title": "Oops...", + "content": "An error occurred. Please report this error: {details}", + "confirmText": "OK" + }, + "invalidAmountModal": { + "title": "Oops...", + "content": "Invalid amount", + "confirmText": "OK" + }, + "creatingTransferModal": { + "title": "Creating transfer ...", + "content": "Please wait..." + }, + "finalizingTransferModal": { + "title": "Finalizing transfer ...", + "content": "Please wait..." + }, + "confirmTransactionModal": { + "title": "Confirm transfer?", + "content": "Amount: {amount}
Fees: {fees}
Total: {total}", + "confirmText": "Confirm", + "cancelText": "Cancel" + }, + "waitingNfcModal": { + "title": "Waiting NFC", + "content": "Bring this device closer to the other device" + } + }, + "receivePage": { + "title": "Receive QWC", + "receiveBlock": { + "address": { + "title": "Your address to receive funds:", + "label": "Give this address to receive funds" + }, + "qrCode": { + "title": "Or personalize the QR code:", + "labelAmount": "Amount (optional)", + "labelRecipient": "Recipient name (optional)", + "labelDescription": "Transaction description (optional)", + "updateButton": "Update" + } + }, + "qrBlock": { + "title": "Your customized QR code" + }, + "waitingNfcToWriteModal": { + "title": "Waiting NFC", + "titleSuccess": "NFC Tag written", + "content": "Bring the NFC tag closer to this device to write" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Tag capacity insufficient" + } + }, + "miningPage": { + "title": "Mine directly in your browser", + "subtitle": "Support the network by mining and be rewarded with QWC", + "parameterBlock": { + "title": "Parameters", + "labelDestinationAddress": "Wallet to mine", + "labelThreads": "Number of threads (more = higher hashrate)", + "start": "Start", + "stop": "Stop" + }, + "statisticsBlocks": { + "title": "Statistics", + "validShares": "Valid shares", + "hashrate": "Hashrate", + "maxHashrate": "Max Hashrate", + "dedicatedHardware": "With dedicating mining software and hardware, you could earn more and help decentralize the network.", + "miningHandledBy": "This mining is handled by the mining pool pool.qwertycoin.org" + } + }, + "settingsPage": { + "title": "Settings", + "subtitle": "Change your parameters here", + "versionBlock": { + "versionNumber": "Version number: ", + "versionCode": "Version code: " + }, + "settingsBlock": { + "currency": { + "label": "National Currency" + }, + "language": { + "label": "Language" + }, + "readMinerTx": { + "label": "Read miner transactions (only for solo mining)" + }, + "speed": { + "fast": "Fast", + "fastest": "Fastest", + "label": "Speed to update the wallet (will consume more resources)", + "medium": "Medium", + "slow": "Slow" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Change my wallet password", + "deleteWalletButton": "Delete my wallet (local copy)", + "walletSettings": { + "creationHeight": { + "label": "Creation height of the wallet" + }, + "currentScanningHeight": { + "label": "Current scanning height" + }, + "updateButton": "Update" + }, + "deleteWalletModal": { + "title": "Delete My Wallet (local copy)", + "content": "Are you sure you REALLY want to delete your wallet ?", + "confirmText": "Yes I'm sure", + "cancelText": "Cancel" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Parameters", + "password": { + "label": "Password to protect your wallet" + }, + "passwordConfirm": { + "label": "Confirm the password", + "invalid": "The password does not match the first password you wrote" + }, + "importHeight": { + "label": "Height to import from:" + } + } + }, + "importFromQrPage": { + "title": "Importing wallet from a QR code", + "subtitle": "Import a wallet from an offline backup", + "qrCodeBlock": { + "title": "QR code", + "startScanButton": "Start the scan", + "importButton": "Import" + }, + "qrScanningBlock": { + "title": "Present the QR code" + } + }, + "exportPage": { + "title": "Backup your credentials", + "publicAddressBlock": { + "title": "Your public address" + }, + "pdfBlock": { + "title": "PDF Backup", + "downloadButton": "Download" + }, + "warningBlock": { + "title": "Warning", + "content": "If you choose to save your private keys or your mnemonic phrase, PLEASE DO NOT store them in clear-text for your own safety.
The file is an alternate solution where your keys are encrypted and contains a backup of all your transactions to spare you a future synchronisation." + }, + "exportBlock": { + "title": "Export your RAW credentials", + "privateKeysButton": "Get my private keys", + "mnemonicKeysButton": "Get my mnemonic phrase", + "fileButton": "Export to a file" + }, + "walletKeysModal": { + "title": "Private keys", + "confirmText": "OK", + "content": "Please carefully store these keys. Possessing them means possessing the funds associated !
Spend key: {privSpendKey}
Private view key: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Mnemonic phrase", + "confirmText": "OK", + "content": "Please store carefully this mnemonic phrase. Possessing it means possessing the funds associated ! The phrase is:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "In which language do you want your mnemonic phrase?", + "confirmText": "Export" + } + }, + "importPage": { + "title": "Create a wallet", + "subtitle": "From previously created keys, file, or mnemonic phrase", + "chooseMethod": "Choose your import method:", + "fromKeys": "From keys", + "fromFile": "From a file", + "fromMnemonic": "From a mnemonic phrase", + "fromQr": "From a QR code" + }, + "termsOfUsePage": { + "title": "Terms of use", + "subtitle": "Please read them carefully." + }, + "privacyPolicyPage": { + "title": "Privacy Policy", + "subtitle": "Please read them carefully." + }, + "importFromFilePage": { + "title": "Importing wallet from a backup file", + "subtitle": "Use your backup file to create a wallet", + "walletBlock": { + "title": "Wallet file", + "label": "Select the file", + "importButton": "Import" + } + }, + "importFromMnemonicPage": { + "title": "Importing wallet from a mnemonic phrase", + "subtitle": "Use your phrase to create a wallet", + "mnemonicBlock": { + "title": "Mnemonic phrase", + "mnemonic": { + "label": "Mnemonic phrase: 25 words", + "invalid": "The mnemonic phrase is invalid", + "language": "Language" + }, + "importButton": "Import" + } + }, + "importFromKeysPage": { + "title": "Importing wallet from keys", + "subtitle": "Use your keys to create a wallet", + "parametersBlock": { + "viewOnlyWallet": { + "label": "Do you want a view only wallet?" + } + }, + "keysBlock": { + "titleNotViewOnly": "Wallet keys", + "titleViewOnly": "View only wallet", + "privateSpend": { + "label": "Private spend key" + }, + "privateView": { + "label": "Private view key", + "optional": "(optional)" + }, + "publicKey": { + "label": "Public key" + }, + "importButton": "Import" + } + } }, - "number":{ - }, - "date":{ - "short": { - "year": "numeric", "month": "short", "day": "numeric" - }, - "long": { - "year": "numeric", "month": "short", "day": "numeric", - "weekday": "short", "hour": "numeric", "minute": "numeric", "hour12": true - } + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": true + } } -} \ No newline at end of file +} diff --git a/src/translations/es.json b/src/translations/es.json new file mode 100644 index 00000000..9db1bf27 --- /dev/null +++ b/src/translations/es.json @@ -0,0 +1,539 @@ +{ + "website": { + "title": "Billetera Qwertycoin | Sencilla, sin fisuras, segura. Bienvenido al futuro.", + "description": "Billetera oficial en línea para la moneda Qwertycoin: se maneja por completo en su navegador para una seguridad óptima" + }, + "messages": { + "menu": { + "home": "Inicio", + "account": "Cuenta", + "send": "Enviar", + "receive": "Recibir", + "export": "Exportar", + "donate": "Donar", + "Eleições": "Eleições", + "Contatos": "Contatos", + "settings": "Ajustes", + "disconnect": "Desconectar", + "network": "Estadísticas de red", + "mining": "Minería" + }, + "global": { + "loading": "Cargando", + "disableSecurity": "Desactivar esta seguridad, entiendo el riesgo.", + "passwordInvalidRequirements": "La contraseña necesita al menos 8 caracteres - 1 letra mayúscula, 1 letra minúscula, un número y un carácter especial", + "passwordConfirmationNotMatching": "La contraseña no coincide con la primera contraseña que escribió", + "download": "Descargar", + "newVersionModal": { + "title": "Una nueva versión esta disponible", + "content": "¿Quieres recargar para cargar la nueva versión?", + "confirmText": "Sí", + "cancelText": "Atrás" + }, + "openWalletModal": { + "title": "Contraseña de Billetera", + "confirmText": "Abrir", + "cancelText": "Cancelar" + }, + "invalidPasswordModal": { + "title": "Ups...", + "content": "Tu contraseña parece inválida", + "confirmText": "OK" + }, + "invalidMnemonicModal": { + "title": "Ups...", + "content": "La frase mnemotécnica no es válida.", + "confirmText": "OK" + }, + "passwordNotComplexEnoughModal": { + "title": "La contraseña no es lo suficientemente compleja", + "confirmText": "OK" + }, + "permissionRequiredForCameraModal": { + "title": "Ups...", + "content": "Se requiere permiso para acceder a su cámara para escanear el código QR", + "confirmText": "OK" + } + }, + "bottom": { + "termsOfUse": "Términos de Uso", + "privacyPolicy": "Política de privacidad", + "support": "Apoyo", + "donate": "Donar", + "network": "Estadísticas de red", + "miningPool": "Minería Junta", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Billetera Qwertycoin", + "tagLine": "en cualquier sitio. a cualquier momento. en cualquier lugar. en cualquier dispositivo.", + "tagLineTwo": "La forma más sencilla de usar Qwertycoin", + "actions": { + "loadWallet": "Cargar mi billetera", + "importWallet": "Importar una billetera", + "create": "Crear", + "createWallet": "Crear una billetera" + } + }, + "accountPage": { + "title": "Cuenta", + "subtitle": "Resumen de cuenta e historial de transacciones", + "synchronizingBlock": { + "text": "Sincronizando..." + }, + "balanceBlock": { + "title": "Su balance", + "unlocked": "Desbloqueado" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Historial de transacciones", + "pendingTxStatus": "Pendiente", + "emptyWallet": "Actualmente no tiene fondos en esta billetera.", + "waitSync": "Por favor, espere hasta que la billetera se actualice", + "beReallyPatient": "La configuración inicial puede tomar algún tiempo...", + "getCoinAddress": "Recibir QWC" + }, + "txDetails": { + "title": "Detalles de la transacción", + "txHash": "Hachís de transacción", + "feesOnTx": "Tarifa de transacción", + "blockHeight": "Altura del bloque", + "paymentId": "ID de pago", + "unlockStatus": "Estado", + "unlockConfirm": "Confirmaciones", + "txPrivKey": "Clave privada de la transacción" + } + }, + "changeWalletPasswordPage": { + "title": "Cambie su contraseña", + "oldPassword": { + "label": "Contraseña anterior", + "invalid": "La contraseña no es valida" + }, + "newPassword": { + "label": "Elija una nueva contraseña para proteger su billetera" + }, + "newPasswordConfirm": { + "label": "Confirme la nueva contraseña" + }, + "confirm": "Cambiar la contraseña", + "modalSuccess": { + "title": "¡Contraseña cambiada!", + "confirmText": "OK" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "Contatos" + }, + "electionsPage": { + "title": "Eleições" + }, + "createWalletPage": { + "generatingStep": { + "title": "Tu billetera se está generando....", + "subtitle": "Esta casi terminada", + "waitingMessage": "Generando su billetera..." + }, + "finalizationStep": { + "title": "Eso fue simple. ¡Tu cuenta está lista!", + "subtitle": "Prepárese para usar Qwertycoin como nunca lo ha hecho", + "passwordSelectionBlock": { + "label": "Proteja su billetera" + }, + "passwordConfirmBlock": { + "label": "Confirme la contraseña" + }, + "validPassword": "Use esta contraseña", + "backupBlock": { + "title": "Guarda tus credenciales privadas para la recuperación", + "option1": "Opción 1: ", + "option2": "Opción 2: ", + "titlePdf": "Descarga una copia en PDF", + "titleManualWrite": "Escribire mis llaves", + "privateKeys": "Llave privada", + "mnemonicPhrase": "Frase mnemotécnica", + "separatorManualMethodsSolution": " o ", + "confirmManuallyWritten": "Escribí mi frase semilla", + "warningMessage": "**¡No la pierdas!** No se puede recuperar si la pierdes.
**No la compartas!** Sus fondos serán robados si usa este archivo o semilla en un sitio malicioso / de phishing.
**Make a backup!** Asegúrala como los millones de dólares que un día puede valer.
", + "finishButton": "Lo entiendo. Continuar." + } + }, + "disclaimerBlock": { + "title": "Riesgo de usar la Billetera Qwertycoin", + "content": "La Billetera Qwertycoin es una interfaz basado en web. Le ayuda a usar Qwertycoin sin ejecutar un nodo Qwertycoin completo.
Le recomendamos que trate la Billetera Qwertycoin como tratará su billetera real." + } + }, + "donatePage": { + "title": "Donar", + "subtitle": "Ayude a financiar el desarrollo y a pagar las cuentas.", + "webwalletBlock": { + "title": "BilleteraWeb", + "content": "Si desea ayudar a pagar por los servidores, a apoyar el desarrollo de nuevas funciones, y como a esta aplicación, considere una donación:

" + }, + "devFundBlock": { + "title": "Fondo de desarrollo Qwertycoin", + "content": "Para ayudar a Qwertycoin, puede donar a estas direcciones" + } + }, + "supportPage": { + "title": "Apoyo", + "subtitle": "¡Estamos aquí para ayudar!", + "getInTouchBlock": { + "title": "¡Pongámonos En Contacto!", + "content": "¿Tiene ideas o comentarios que podrían ayudarnos a mejorar la billetera? ¡Contáctenos!", + "discord": "Canal de Qwertycoin en Discord" + } + }, + "networkPage": { + "title": "Estadísticas de red", + "subtitle": "Perspectivas sobre la red Qwertycoin", + "statsBlock": { + "connectNode": "Masternode conectado", + "hashrate": "Tasa de Hachís en red", + "height": "Altura de blockchain", + "difficulty": "Dificultad de red", + "lastTimeBlock": "Último bloque encontrado", + "lastReward": "Recompensa del último bloque" + } + }, + "sendPage": { + "title": "Enviar QWC", + "sendBlock": { + "address": { + "label": "Dirección de destino", + "placeholder": "Escriba la dirección a la que desea enviar los fondos.", + "invalid": "La dirección de destino no es válida", + "fundsTo": "Los fondos serán enviados a", + "receiver": "Destinatario", + "description": "Descripción" + }, + "amount": { + "label": "Cantidad a enviar", + "invalid": "La cantidad es inválida" + }, + "paymentId": { + "label": "Identificación de pago (opcional)", + "invalid": "El ID de pago no es válido. La longitud debe ser de 16 o 64 caracteres." + }, + "sendButton": "Enviar", + "cancelButton": "Cancelar" + }, + "qrCodeScanning": { + "explication": "Presentar el código QR" + }, + "notEnoughMoneyModal": { + "title": "Ups...", + "content": "No tiene fondos suficientes en su billetera para ejecutar esta transferencia.", + "confirmText": "OK" + }, + "thankYouDonationModal": { + "title": "¡Gracias por su donación!", + "content": "Su ayuda es apreciada. Esta donación ayudará a mejorar Qwertycoin", + "confirmText": "OK" + }, + "transferSentModal": { + "title": "Transferencia enviada con éxito!", + "confirmText": "OK" + }, + "transferExceptionModal": { + "title": "Ups...", + "content": "Ocurrió un error. Por favor reporte este error: {details}", + "confirmText": "OK" + }, + "invalidAmountModal": { + "title": "Ups...", + "content": "Monto invalido", + "confirmText": "OK" + }, + "creatingTransferModal": { + "title": "Creando transferencia ...", + "content": "Por favor espere..." + }, + "finalizingTransferModal": { + "title": "Finalizando la transferencia ...", + "content": "Por favor espere..." + }, + "confirmTransactionModal": { + "title": "¿Confirmar transferencia?", + "content": "Cantidad: {amount}
Tarifa: {fees}
Total: {total}", + "confirmText": "Confirmar", + "cancelText": "Cancelar" + }, + "waitingNfcModal": { + "title": "Esperando Nfc", + "content": "Acércate al otro dispositivo" + } + }, + "receivePage": { + "title": "Recibir QWC", + "receiveBlock": { + "address": { + "title": "Su dirección para recibir fondos.:", + "label": "Da esta dirección para recibir fondos." + }, + "qrCode": { + "title": "O personalizar el código QR:", + "labelAmount": "Cantidad (opcional)", + "labelRecipient": "Nombre del destinatario (opcional)", + "labelDescription": "Descripción de la transacción (opcional)", + "updateButton": "Actualizar" + } + }, + "qrBlock": { + "title": "Su código QR personalizado" + }, + "waitingNfcToWriteModal": { + "title": "Esperando Nfc", + "titleSuccess": "Etiqueta Nfc escrita", + "content": "Acercar la etiqueta NFC para escribir" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Capacidad de etiqueta insuficiente" + } + }, + "miningPage": { + "title": "Minar directamente en tu navegador", + "subtitle": "Apoye la red minando y sea recompensado con QWC", + "parameterBlock": { + "title": "Parámetros", + "labelDestinationAddress": "Billetera a minar", + "labelThreads": "Número de procesos (más = mayor Tasa de Hachís)", + "start": "Comenzar", + "stop": "Detener" + }, + "statisticsBlocks": { + "title": "Estadística", + "validShares": "Acciones validas", + "hashrate": "Tasa de Hachís", + "maxHashrate": "Tasa de Hachís Maxima", + "dedicatedHardware": "Al dedicar software y hardware de minería, podría ganar más y ayudar a descentralizar la red.", + "miningHandledBy": "Esta minería es manejada por la mineria junta pool.qwertycoin.org" + } + }, + "settingsPage": { + "title": "Ajustes", + "subtitle": "Cambie sus parámetros aquí", + "versionBlock": { + "versionNumber": "Número de versión: ", + "versionCode": "Código de versión: " + }, + "settingsBlock": { + "speed": { + "label": "Velocidad para actualizar la billetera (consumirá más recursos)", + "fastest": "Lo más rápido", + "fast": "Rápido", + "medium": "Medio", + "slow": "Lento" + }, + "language": { + "label": "Idioma" + }, + "currency": { + "label": "Moneda nacional" + }, + "readMinerTx": { + "label": "Leer transacciones mineras (solo para minería en solitario)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Cambiar mi contraseña de billetera", + "deleteWalletButton": "Eliminar mi billetera (copia local)", + "walletSettings": { + "creationHeight": { + "label": "Altura de creación de la cartera." + }, + "currentScanningHeight": { + "label": "Altura de escaneo actual" + }, + "updateButton": "Actualizar" + }, + "deleteWalletModal": { + "title": "Eliminar mi billetera (copia local)", + "content": "¿Está seguro de que REALMENTE desea eliminar su billetera?", + "confirmText": "Sí estoy seguro", + "cancelText": "Cancelar" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Parámetros", + "password": { + "label": "Contraseña para proteger su billetera" + }, + "passwordConfirm": { + "label": "Confirmar la contraseña", + "invalid": "La contraseña no coincide con la primera contraseña que escribió" + }, + "importHeight": { + "label": "Importar desde la altura:" + } + } + }, + "importFromQrPage": { + "title": "Importar billetera desde un código QR", + "subtitle": "Importar una billetera desde una copia de seguridad sin conexión", + "qrCodeBlock": { + "title": "Código QR", + "startScanButton": "Iniciar el escaneo", + "importButton": "Importar" + }, + "qrScanningBlock": { + "title": "Presentar el código QR" + } + }, + "exportPage": { + "title": "Copia de seguridad de sus credenciales", + "publicAddressBlock": { + "title": "Tu direccion publica" + }, + "pdfBlock": { + "title": "Copia de seguridad en PDF", + "downloadButton": "Descargar" + }, + "warningBlock": { + "title": "Advertencia", + "content": "Si elige guardar sus claves privadas o su frase mnemotécnica, POR FAVOR, para su propia seguridad NO las almacene en texto sin cifrar.
El archivo es una solución alternativa donde sus claves están encriptadas y contiene una copia de seguridad de todas sus transacciones, para ahorrarte una futura sincronización." + }, + "exportBlock": { + "title": "Exportar sus credenciales en bruto(RAW)", + "privateKeysButton": "Obtener mis llaves privadas", + "mnemonicKeysButton": "Obtener mi frase mnemotécnica", + "fileButton": "Exportar a un archivo" + }, + "walletKeysModal": { + "title": "Llaves privadas", + "confirmText": "OK", + "content": "Por favor, guarda cuidadosamente estas llaves. Poseerlas significa tener los fondos asociados !
Clave de gastos: {privSpendKey}
Clave de vista privada: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Frase mnemotécnica", + "confirmText": "OK", + "content": "Por favor guarde cuidadosamente esta frase mnemotécnica. ¡ Poseerla significa poseer los fondos asociados ! La frase es:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "¿En qué idioma quieres tu frase mnemotécnica?", + "confirmText": "Exportar" + } + }, + "importPage": { + "title": "Crear una billetera", + "subtitle": "A partir de claves, archivos o frases mnemónicas creadas previamente.", + "chooseMethod": "Elija su método de importación:", + "fromKeys": "De las llaves", + "fromFile": "De un archivo", + "fromMnemonic": "De una frase mnemotécnica.", + "fromQr": "De un código QR" + }, + "termsOfUsePage": { + "title": "Términos de Uso", + "subtitle": "Por favor léalos cuidadosamente." + }, + "privacyPolicyPage": { + "title": "Política de privacidad", + "subtitle": "Por favor léala cuidadosamente" + }, + "importFromFilePage": { + "title": "Importando billetera desde un archivo de respaldo", + "subtitle": "Utilice su archivo de copia de seguridad(respaldo) para crear una cartera", + "walletBlock": { + "title": "Archivo de billetera", + "label": "Selecciona el archivo", + "importButton": "Importar" + } + }, + "importFromMnemonicPage": { + "title": "Importando billetera desde una frase mnemotécnica.", + "subtitle": "Use su frase para crear una billetera", + "mnemonicBlock": { + "title": "Frase mnemotécnica", + "mnemonic": { + "label": "Frase mnemotécnica: 25 palabras.", + "invalid": "La frase mnemotécnica no es válida.", + "language": "Idioma" + }, + "importButton": "Importar" + } + }, + "importFromKeysPage": { + "title": "Importando billetera desde llaves", + "subtitle": "Use sus llaves para crear una billetera.", + "parametersBlock": { + "viewOnlyWallet": { + "label": "¿Quieres una billetera de solo ver?" + } + }, + "keysBlock": { + "titleNotViewOnly": "Llaves de billetera", + "titleViewOnly": "Billetera de solo ver", + "privateSpend": { + "label": "Clave de gasto privado" + }, + "privateView": { + "label": "Clave de vista privada", + "optional": "(opcional)" + }, + "publicKey": { + "label": "Llave pública" + }, + "importButton": "Importar" + } + } + }, + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": true + } + } +} diff --git a/src/translations/fa.json b/src/translations/fa.json new file mode 100644 index 00000000..89fc36b4 --- /dev/null +++ b/src/translations/fa.json @@ -0,0 +1,522 @@ +{ + "website": { + "title": "کیف پول Qwertycoin رسمی", + "description": "کیف پول Qwertycoin به طور کامل امن و کاربر است و تمام کربوهیدرات شما در دستگاه شما ذخیره می شود" + }, + "messages": { + "menu": { + "home": "خانه", + "account": "حساب", + "send": "ارسال", + "receive": "دریافت", + "export": "پشتیبان گیری", + "donate": "ارسال کادو", + "elections": "انتخابات", + "contacts": "مخاطب", + "settings": "تنظیمات", + "disconnect": "خروج", + "network": "شبکه", + "mining": "استخراج" + }, + "global": { + "loading": "در حال بارگیری", + "disableSecurity": "متوجه شدم", + "passwordInvalidRequirements": "یک رمز عبور قوی باید حداقل شامل هشت حرف با حروف بزرگ ، کوچک و سمبل باشد", + "passwordConfirmationNotMatching": "رمز عبور شما مطابقت ندارد", + "download": "دریافت", + "newVersionModal": { + "title": "نسخه ی جدیدی موجود است", + "content": "آیا مایل به بارگذاری مجدد صفحه و دریافت بروز رسانی میباشید ؟", + "confirmText": "بله", + "cancelText": "خیر" + }, + "openWalletModal": { + "title": "'رمز عبور کیف پول'", + "confirmText": "تایید", + "cancelText": "لغو" + }, + "invalidPasswordModal": { + "title": "متاسفیم", + "content": "رمز عبور اشتباه است", + "confirmText": "تایید" + }, + "invalidMnemonicModal": { + "title": "متاسفیم", + "content": "کد سید پشتیبان شما اشتباه است", + "confirmText": "تایید" + }, + "passwordNotComplexEnoughModal": { + "title": "رمز عبور شما به میزان کافی قوی نیست", + "confirmText": "تایید" + }, + "permissionRequiredForCameraModal": { + "title": "توجه", + "content": "برای دسترسی به دوربین شما نیاز به مجوز میباشد", + "confirmText": "تایید" + } + }, + "bottom": { + "termsOfUse": "شرایط استفاده", + "support": "پشتیبانی", + "donate": "ارسال کادو", + "network": "شبکه", + "miningPool": "استخر استخراج", + "github": "گیت هاب" + }, + "homepage": { + "mainTitle": "کیف پول زیر وب", + "tagLine": "آسان ترین راه برای استفاده از کربو", + "tagLineTwo": "ساده ترین راه استفاده از Qwertycoin", + "actions": { + "loadWallet": "بارگیری کیف پول", + "importWallet": "درون ریزی کیف پول", + "create": "انجام بده", + "createWallet": "ایجاد کیف پول" + } + }, + "accountPage": { + "title": "حساب کاربری", + "subtitle": "صفحه ی اصلی کیف پول کربو", + "synchronizingBlock": { + "text": "در حال همگام سازی با شبکه" + }, + "balanceBlock": { + "title": "کل حساب", + "unlocked": "در دسترس" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "تاریخچه تراکنش ها", + "pendingTxStatus": "تایید نشده", + "emptyWallet": "کیف پول شما در حال حاضر خالی میباشد", + "waitSync": "لطفا برای بارگذاری مجدد کیف پول صبر کنید", + "beReallyPatient": "این پروسه ممکن است مقداری به طول بیانجامد", + "getCoinAddress": "آدرس کیف پول شما" + }, + "txDetails": { + "title": "جزییات تراکنش ها", + "txHash": "هش تراکنش", + "feesOnTx": "کارمزد تراکنش", + "blockHeight": "شماره بلوک", + "paymentId": "شناسه پرداخت" + } + }, + "changeWalletPasswordPage": { + "title": "تغییر رمز عبور", + "oldPassword": { + "label": "رمز عبور قدیم", + "invalid": "رمز عبور اشتباه است" + }, + "newPassword": { + "label": "یک رمز عبور جدید انتخاب کنید", + "invalid": " یک رمز عبور قوی باید حداقل شامل هشت کاراکتر باشد ، بهمراه حروف بزرگ و کوچک و سمبل ها" + }, + "newPasswordConfirm": { + "label": "رمز عبور جدید خود را تایید کنید" + }, + "confirm": "تایید", + "modalSuccess": { + "title": "رمز عبور شما تغییر یافت", + "confirmText": "تایید" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "مخاطب" + }, + "electionsPage": { + "title": "انتخابات" + }, + "createWalletPage": { + "generatingStep": { + "title": "در حال ایجاد کیف پول", + "subtitle": "پروسه در حال اتمام است", + "waitingMessage": "در حال ایجاد" + }, + "finalizationStep": { + "title": "تبریک کیف پول شما آماده است", + "subtitle": "برای استفاده از کربو آماده شوید", + "passwordSelectionBlock": { + "label": "از کیف پول خود محافظت کنید" + }, + "passwordConfirmBlock": { + "label": "تایید رمز عبور" + }, + "validPassword": "از این رمز عبور استفاده کن", + "backupBlock": { + "title": "یک کپی از اطلاعات رمزگذاری شده خود برای استفاده در آینده تهیه کنید ", + "option1": "گزینه اول ", + "option2": "گزینه دوم ", + "titlePdf": "دریافت فایل پی دی اف", + "titleManualWrite": "تهیه رو نوشت از کلید ها", + "privateKeys": "کلید شخصی", + "mnemonicPhrase": "کد سید", + "separatorManualMethodsSolution": " و یا ", + "confirmManuallyWritten": "رونوشت را تهیه کردم", + "warningMessage": "از این اطلاعات به خوبی نگهداری و محافظت کنید
در صورت از دست دادن آن ها نمیتوانید کیف پول خود را بازگردانی کنید و یا امکان دارد کوین های شما به سرقت روند
طوری از آن ها نگهداری کنید که انگار میلیون ها دلار ارزش دارند
", + "finishButton": "متوجه شدم ادامه بده" + } + }, + "disclaimerBlock": { + "title": "ریسک استفاده از کیف پول کربو", + "content": "کیف پول آنلاین کربو برای استفاده آسان تر از کیف پول کربو طراحی شده و برای استفاده از آن نیازه به نگهداری از فایل های زنجیره بلوکی نمیباشد
به شما توصیه میکنیم از کیف پول خود به خوبی محافظت کنید" + } + }, + "donatePage": { + "title": "ارسال کادو", + "subtitle": "با ارسال کادو به توسعه کربو کمک کنید", + "webwalletBlock": { + "title": "ولت آنلاین", + "content": "ولت آنلاین توسط برنامه نویسان کربو توسعه داده میشود
اگر به تداوم پروژه اهمیت میدهید لطفا مقداری کربو به عنوان کادو برای ما بفرستید

" + }, + "masariFundBlock": { + "title": "کیف پول جهت ارسال کادو", + "content": "اگر مایل به ارسال کادو هستید آن را به آدرس کیف پول زیر ارسال نمایید" + } + }, + "supportPage": { + "title": "پشتیبانی", + "subtitle": "اگر به کمک نیاز دارید ما میتوانیم به شما کمک کنیم", + "getInTouchBlock": { + "title": "با ما در تماس باشید", + "content": "اگر ایده یا پیشنهادی دارید که به ارتقای این کیف پول کمک میکنید با ما در تماس باشید", + "discord": "سرور دیسکورد کربو" + } + }, + "networkPage": { + "title": "وضعیت شبکه", + "subtitle": "داخل شبکه ی کربو", + "statsBlock": { + "connectNode": "Masternode ارتباطی", + "hashrate": "هش ریت شبکه", + "height": "ارتفاع زنجیره بلوکی", + "difficulty": "سختی شبکه", + "lastTimeBlock": "آخرین بلاک پیدا شده", + "lastReward": "آخرین پاداش بلاک" + } + }, + "sendPage": { + "title": "ارسال کربو", + "sendBlock": { + "address": { + "label": "ارسال به آدرس", + "invalid": "آدرس اشتباه است", + "fundsTo": "کربو ها به این آدرس ارسال میشوند", + "receiver": "دریافت کننده", + "description": "توضیحات" + }, + "amount": { + "label": "مقدار جهت ارسال", + "invalid": "مقدار اشتباه" + }, + "paymentId": { + "label": "شناسه واریز", + "invalid": "شناسه ی واریز اشتباه است مقداری را بین شانزده تا شصت و چهار کاراکتر وارد نمایید" + }, + "sendButton": "ارسال", + "cancelButton": "لغو" + }, + "qrCodeScanning": { + "explication": "اسکن کیو آر کد" + }, + "notEnoughMoneyModal": { + "title": "متاسفیم", + "content": "شما به میزان کافی کربو برای ارسال ندارید", + "confirmText": "تایید" + }, + "thankYouDonationModal": { + "title": "برای ارسال کادو از شما متشکریم", + "content": "کمک شما بسیار تاثیرگذار است
کمک شما برای ادامه به کار پروژه کربو بسیار ضروری است", + "confirmText": "بستن" + }, + "transferSentModal": { + "title": "ارسال با موفقیت انجام شد", + "confirmText": "بستن" + }, + "transferExceptionModal": { + "title": "متاسفیم", + "content": "خطایی رخ داده است لطفا آن را گزارش دهید {details}", + "confirmText": "بستن" + }, + "invalidAmountModal": { + "title": "متاسفیم", + "content": "مقدار اشتباه است", + "confirmText": "بستن" + }, + "creatingTransferModal": { + "title": "در حال آماده سازی تراکنش", + "content": "لطفا اندکی صبر کنید" + }, + "finalizingTransferModal": { + "title": "تراکنش در حال انجام است", + "content": "لطفا اندکی صبر کنید" + }, + "confirmTransactionModal": { + "title": "آیا تراکنش را تایید میکنید", + "content": "'مقدار : {amount}
کارمزد : {fees}
مقدار کل : {total}", + "confirmText": "تایید", + "cancelText": "لغو" + }, + "waitingNfcModal": { + "title": "در انتظار ان اف سی", + "content": "لطفا به دستگاه دیگر نزدیک شوید" + } + }, + "receivePage": { + "title": "دریافت کربو", + "receiveBlock": { + "address": { + "title": "آدرس جهت دریافت کوین ها", + "label": "این آدرس را اضافه کنید اگر میخواهید کوین ها را دریافت کنید" + }, + "qrCode": { + "title": "یا از کیو آر کد استفاده کنید", + "labelAmount": "مقدار", + "labelRecipient": "نام دریافت کننده دلبخواه است", + "labelDescription": "توضیحات تراکنش دلبخواه است", + "updateButton": "به روز رسانی" + } + }, + "qrBlock": { + "title": "کد کیو آر شما" + }, + "waitingNfcToWriteModal": { + "title": "در انتظار ان اف سی", + "titleSuccess": "تگ ان اف سی در حال نوشتن", + "content": "لطفا به تگ ان اف سی دستگاه خود را نزدیک کنید" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "مقدار تگ نامناسب" + } + }, + "miningPage": { + "title": "اطلاعات استخراج", + "subtitle": "با استخراج شبکه کربو را بهبود بخشیده و به عنوان جایزه کربو دریافت کنید", + "contentBlock": { + "title": "چگونه شروع به استخراج کنید", + "intro": "استخراج به شبکه کربو بسیار کمک میکند و برای شما به عنوان جایزه کربو ارسال میشود ، شما به تجهیزات خاصی جهت استخراج نیاز ندارید", + "linkText": "برای خواندن راهنما اینجا کلیک کنید" + } + }, + "settingsPage": { + "title": "تنظیمات", + "subtitle": "تنظیمات را از اینجا تغییر دهید", + "versionBlock": { + "versionNumber": "شماره نسخه : ", + "versionCode": "کد نسخه : " + }, + "settingsBlock": { + "speed": { + "label": "به روز رسانی سرعت کیف پول که باعث استفاده منابع بیشتری میشود", + "fastest": "سریعترین", + "fast": "سریع", + "medium": "متوسط", + "slow": "آرام" + }, + "language": { + "label": "Language" + }, + "currency": { + "label": "پول ملی" + }, + "readMinerTx": { + "label": "تراکنش های ماینینگ فقط بصورت تکی" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "تغییر رمز عبور کیف پول", + "deleteWalletButton": "حذف کیف پول از روی سیستم شما", + "walletSettings": { + "creationHeight": { + "label": "ارتفاع زنجیره بلاکی هنگام ساخت کیف پول" + }, + "currentScanningHeight": { + "label": "ارتفاع کنونی جهت اسکن" + }, + "updateButton": "به روز رسانی" + }, + "deleteWalletModal": { + "title": "حذف کیف پول نسخه محلی", + "content": "آیا مطمین هستید که میخواهید کیف پول خود را حذف نمایید؟", + "confirmText": "بله مطمینم", + "cancelButtonText": "لغو" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "پارامترها", + "password": { + "label": "رمز عبور جهت محافظت از کیف پول شما" + }, + "passwordConfirm": { + "label": "تایید رمز عبور", + "invalid": "رمزعبور با رمز عبور وارد شده مطابقت ندارد" + }, + "importHeight": { + "label": "ارتفاع زنجیره بلوکی برای شروع" + } + } + }, + "importFromQrPage": { + "title": "کیف پول خود را به وسیله کد کیو آر درون ریزی کنید", + "subtitle": "کیف پول خود را به وسیله فایل درون ریزی کنید", + "qrCodeBlock": { + "title": "کد کیو آر", + "startScanButton": "شروع اسکن", + "importButton": "درون ریزی" + }, + "qrScanningBlock": { + "title": "متصل کردن کد کیو آر" + } + }, + "exportPage": { + "title": "اطلاعات خود را ذخیر کنید", + "publicAddressBlock": { + "title": "آدرس کیف پول شما" + }, + "pdfBlock": { + "title": "فایل پی دی اف", + "downloadButton": "دریافت" + }, + "warningBlock": { + "title": "اخطار", + "content": "لطفا اگر اطلاعات کیف پول خود را ذخیره کردید آن ها را با دیگران به اشتراک نگذارید
این تمام اطلاعاتی است که برای درون ریزی کیف پول خود در آینده نیاز دارید" + }, + "exportBlock": { + "title": "Извези СИРОВЕ податке", + "privateKeysButton": "Моји приватни кључеви", + "mnemonicKeysButton": "Моја мнемоничка фраза", + "fileButton": "Сачувај као фајл" + }, + "walletKeysModal": { + "title": "کلید های شخصی", + "confirmText": "تایید", + "content": "لطفا این اطلاعات را در یک مکان ایمن نگهداری کنیددر دست داشتن این اطلاعات به معنی داشتن حق کیف پول شماست و با داشتن این اطلاعات دیگران میتوانند به کیف پول شما دسترسی پیدا کنند !
کلید شخصی ارسال : {privSpendKey}
کلید شخصی مشاهده : {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "کلید های شخصی", + "confirmText": "تایید", + "content": "لطفا در مورد کد سید احتیاط کنید و آن را ایمن نگه داریدداشتن این کلید ها به شما اجازه دسترسی به این کیف پول در آینده را میدهد کد شما :
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "زبان مورد نظر برای کد سید خود را انتخاب کنید", + "confirmText": "تایید خروجی" + } + }, + "importPage": { + "title": "درون ریزی کیف پول", + "subtitle": "از کلیدهای قبلی", + "chooseMethod": "یک متد انتخاب کنید", + "fromKeys": "با استفاده از کلید ها", + "fromFile": "با استفاده از فایل ", + "fromMnemonic": "با استفاده از کد سید", + "fromQr": "با استفاده از کد تصویری کیو آر" + }, + "termsOfUsePage": { + "title": "شرایط استفاده", + "subtitle": "لطفا با دقت مطالعه نمایید" + }, + "importFromFilePage": { + "title": "دزون ریزی کیف پول با استفاده از فایل", + "subtitle": "از فایل دانلود شده قبل در همین کیف پول استفاده کنید", + "walletBlock": { + "title": "فایل کیف پول", + "label": "انتخاب کنید", + "importButton": "درون ریزی" + } + }, + "importFromMnemonicPage": { + "title": "درون ریزی با استفاده از کد سید", + "subtitle": "استفاده از کد سید برای درون ریزی کیف پول", + "mnemonicBlock": { + "title": "کد سید", + "mnemonic": { + "label": "کد سید باید بیست و پنج کلمه باشد", + "invalid": "کد سید اشتباه است", + "language": "زبان" + }, + "importButton": "درون ریزی" + } + }, + "importFromKeysPage": { + "title": "درون ریزی کیف پول با کلید ها", + "subtitle": "از کلید های شخصی برای درون ریزی کیف پول خود استفاده کنید", + "parametersBLock": { + "viewOnlyWallet": { + "label": "آیا تنها یک کیف پول صرفا قابل مشاهده میخواهید ؟", + "info": "لطفا توجه کنید که کیف پول های صرفا برای مشاهده تنها موجودی کیف پول شما را نشان میدهند و نمیتوانید کوین ارسال کنید" + } + }, + "keysBlock": { + "titleNotViewOnly": "کلید های کیف پول", + "titleViewOnly": "کیف پول صرفا قابل مشاهده", + "privateSpend": { + "label": "کلید شخصی شما" + }, + "privateView": { + "label": "کلید شخصی برای مشاهده", + "optional": "دلبخواه" + }, + "publicKey": { + "label": "کلید عمومی" + }, + "importButton": "درون ریزی" + } + } + }, + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": false + } + } +} diff --git a/src/translations/fr.json b/src/translations/fr.json index 183f4b32..9293bf52 100644 --- a/src/translations/fr.json +++ b/src/translations/fr.json @@ -1,495 +1,539 @@ { - "website":{ - "title":"Portefeuille officiel en ligne pour Karbo ", - "description":"Portefeuille en ligne officiel pour la monnaie Karbo, anonyme, sécurisé et entièrement géré dans votre navigateur for une sécurité optimale" + "website": { + "title": "Portefeuille officiel en ligne pour Qwertycoin ", + "description": "Portefeuille en ligne officiel pour la monnaie Qwertycoin, anonyme, sécurisé et entièrement géré dans votre navigateur for une sécurité optimale" }, "messages": { - "menu": { - "home": "Accueil", - "account": "Compte", - "send": "Envoyer", - "receive": "Recevoir", - "export": "Exporter", - "donate": "Contribuer", - "settings": "Paramètres", - "disconnect": "Déconnection", - "network": "Stats du réseau", - "mining": "Minage" - }, - "global": { - "loading": "Chargement", - "disableSecurity":"Désactiver cette sécurité. Je comprend les risques", - "passwordInvalidRequirements":"Le mot de passe doit avoir au moins 8 caractères, 1 lettre majuscule, 1 mettre minuscule, un chiffre et un caractère spécial", - "passwordConfirmationNotMatching":"Le mot de passe ne correspond pas au premier écrit", - "download":"Télécharger", - "newVersionModal":{ - "title":"Une nouvelle version est disponible", - "content":"Voulez vous recharger pour passer passer sur la nouvelle version ?", - "confirmText":"Oui", - "cancelText":"Plus tard" - }, - "openWalletModal":{ - "title":"Mot de passe", - "confirmText":"Ouvrir", - "cancelText":"Annuler" - }, - "invalidPasswordModal":{ - "title":"Oups...", - "content":"Votre mot de passe semble invalide", - "confirmText":"OK" - }, - "invalidMnemonicModal":{ - "title":"Oups...", - "content":"La phrase mnémotechnique est invalide", - "confirmText":"OK" - }, - "passwordNotComplexEnoughModal":{ - "title":"Le mot de passe n'est pas assez complexe", - "confirmText":"OK" - }, - "permissionRequiredForCameraModal":{ - "title":"Oups...", - "content":"Il est nécessaire de donner l'accès à la caméra afin de pouvoir scanner le QR Code", - "confirmText":"OK" - } - }, - "bottom": { - "termsOfUse": "Conditions générales d'utilisation", - "privacyPolicy": "Politique de confidentialité", - "support": "Support", - "donate": "Contribuer", - "network": "Stats du réseau", - "miningPool": "Pool de minage", - "github": "GitHub" - }, - "homepage": { - "mainTitle": "Portefeuille sécurisé pour Karbo", - "tagLine": "Le moyen le plus simple d'utiliser Karbo, n'importe où, n'importe quand", - "actions": { - "loadWallet": "Charger mon portefeuille", - "importWallet": "Importer un portefeuille", - "create": "Créer", - "createWallet": "Créer un portefeuille" - }, - "notes": { - "secure": { - "title": "Sécurisé", - "description": "Aucun serveur, entièrement chiffré !" - }, - "fast": { - "title": "Rapide", - "description": "Envoyer n'importe, n'importe ou" - }, - "technology": { - "title": "Technologie unique", - "description": "Connectée directement à la Blockchain Karbo !" - }, - "openSource": { - "title": "Entièrement open-source", - "description": "Disponible sur github" - } - } - }, - "accountPage": { - "title": "Mon compte", - "subtitle": "Apperçu de votre compte et de l'historique des transactions", - "synchronizingBlock": { - "text": "Synchronisation en cours " - }, - "balanceBlock": { - "title": "Votre solde", - "unlocked": "Disponible" - }, - "historyBlock": { - "title": "Historique des transactions", - "pendingTxStatus": "En attente", - "emptyWallet": "Vous n'avez aucun fond sur ce portefeuille", - "waitSync": "Veuillez attendre la fin de la synchronisation", - "beReallyPatient": "La première synchronisation peut prendre quelques minutes...", - "getCoinAddress": "Obtenir mon adresse pour recevoir des KRB" - }, - "txDetails":{ - "title":"Détails de la transaction", - "txHash":"Tx hash", - "feesOnTx":"Frais sur la tx", - "blockHeight":"Hauteur sur la blockchain", - "paymentId":"ID du paiement", - "txPrivKey":"Clé privée de transaction" - } - }, - "changeWalletPasswordPage":{ - "title":"Changer mon mot de passe", - "oldPassword":{ - "label":"Ancien", - "invalid":"Mot de passe invalid" - }, - "newPassword":{ - "label":"Nouveau mot de passe pour sécuriser" - }, - "newPasswordConfirm":{ - "label":"Confirmer mon nouveau mot de passe" - }, - "confirm":"Changer", - "modalSuccess":{ - "title":"Mot de passe changé !", - "confirmText":"OK" - } - }, - "createWalletPage":{ - "generatingStep":{ - "title":"Votre portefeuille se génère ...", - "subtitle":"Plus que quelques instants", - "waitingMessage":"Génération du portefeuille ..." - }, - "finalizationStep":{ - "title":"C'était simple. Votre portefeuille est prêt !", - "subtitle":"Soyer près à utiliser Karbo le plus simplement possible", - "passwordSelectionBlock":{ - "label":"Sécuriser mon portefeuille" - }, - "passwordConfirmBlock":{ - "label":"Confirmer le mot de passe" - }, - "validPassword":"Utiliser ce mot de passe", - "backupBlock":{ - "title":"Télécharger une copie chiffrée de mes identifiants pour un futur usage", - "option1": "Option 1: ", - "option2": "Option 2: ", - "titlePdf":"Télécharger une copie PDF", - "titleManualWrite":"Ecrire mes cléfs d'accès", - "privateKeys":"Cléfs privées", - "mnemonicPhrase":"Phrase mnémotechnique", - "separatorManualMethodsSolution":" ou ", - "confirmManuallyWritten":"Je les ais écrites", - "warningMessage":"**Ne les perdez pas!** Il est impossible des les récupérer si vous les perdez.
**Ne les paratagez pas!** Vos fonds peuvent être volé si vous utilisez ces informations sur des sites-tiers (malicieux/phishing).
**Faites une sauvegarde!** Sécutisez vos identifiants comme si si vous possédiez des millions de dollars.
", - "finishButton":"Je comprend. Continuer" - } - }, - "disclaimerBlock":{ - "title":"Risques liés à l'utilisation de KarboWallet", - "content":"KarboWallet est un service web. Il vous aide à utiliser Karbo facilement sans avoir un installer des logiciels.
Nous vous conseillons de traiter ce site comme vous traiteriez votre portefeuille." - } - }, - "donatePage":{ - "title":"Contribuer", - "subtitle":"Aidez à financer le développement et payer les factures de ce service", - "webwalletBlock":{ - "title":"Portefeuille en ligne", - "content":"Ce portefeuille est développé par Gnock sur son temps libre.
Si vous voulez aider au développement, payer les serveur et que vous aimez ce service, considérez une petite donation:

" - }, - "devFundBlock":{ - "title":"Fond de développement de Karbo", - "content":"Pour aidez Karbo globalement, vous pouvez donner à cette adresse" - } - }, - "supportPage":{ - "title":"Support", - "subtitle":"Vous avez besoins d'aide, nous somme la pour aider !", - "getInTouchBlock":{ - "title":"Reston en contact !", - "content":"Vous avez des idées, des retours pour aider à améliorer le service ? Contactez nous !", - "discord":"Discord Officiel de Karbo" - } - }, - "networkPage":{ - "title":"Statistiques du réseau", - "subtitle":"Détails sur le réseaux Karbo", - "statsBlock":{ - "hashrate":"Hashrate du réseau", - "height":"Hauteur de la Blockchain", - "difficulty":"Difficulty du réseau", - "lastTimeBlock":"Dernier block trouvé", - "lastReward":"Dernière récompense" - } - }, - "sendPage":{ - "title":"Envoyer des KRB", - "sendBlock":{ - "address":{ - "label":"Adresse de destination", - "placeholder":"Écrivez l'adresse où vous voulez envoyer des fonds", - "invalid":"L'adresse de destination est invalide", - "fundsTo":"Les fonds seront envoyé à ", - "receiver":"Destinataire", - "description":"Description" - }, - "amount":{ - "label":"Montant à envoyer", - "invalid":"Le montant est invalide" - }, - "paymentId":{ - "label":"Identifiant du payment (optionnel)", - "invalid":"L'identifiant du paiement est invalid. La longeur doit être de 16 ou 64 caractères" - }, - "sendButton":"Envoyer", - "cancelButton":"Annuler" - }, - "qrCodeScanning":{ - "explication":"Présentez le QR Code" - }, - "notEnoughMoneyModal":{ - "title":"Oups...", - "content":"Vous n'avez pas assez de fonds pour effectuer ce tranfert", - "confirmText":"OK" - }, - "thankYouDonationModal":{ - "title":"Merci pour votre donation !", - "content":"Votre aide est apprécié.
Cette donation contribuera à améliorer Karbo", - "confirmText":"Fermer" - }, - "transferSentModal":{ - "title":"Transfert envoyé avec succès!", - "confirmText":"Fermer" - }, - "transferExceptionModal":{ - "title":"Oups...", - "content":"Une erreur est survenue. Merci de nous envoyer de rapport: {details}", - "confirmText":"Fermer" - }, - "invalidAmountModal":{ - "title":"Oups...", - "content":"Montant invalide", - "confirmText":"Fermer" - }, - "creatingTransferModal":{ - "title":"Création du transfert ...", - "content":"Veuillez patienter ..." - }, - "finalizingTransferModal":{ - "title":"Finalisation du transfert ...", - "content":"Veuillez patienter ..." - }, - "confirmTransactionModal":{ - "title":"Confirmer le transfert ?", - "content":"Montant: {amount}
Frais: {fees}
Total: {total}", - "confirmText":"Confirmer", - "cancelText":"Annuler" - }, - "waitingNfcModal":{ - "title":"Attente du Nfc", - "content":"Veuillez rapprocher votre téléphone de l'autre appareil" - } - }, - "receivePage":{ - "title":"Recevoir des KRB", - "receiveBlock":{ - "address":{ - "title":"Votre adresse pour recevoir des fonds", - "label":"Donner cette adresse pour recevoir des fonds" - }, - "qrCode":{ - "title":"Ou personnalisez ce QR Code", - "labelAmount":"Montant (optionnel)", - "labelRecipient":"Nom du destinataire (optionnel)", - "labelDescription":"Description (optionnel)", - "updateButton":"Mettre à jour" - } - }, - "qrBlock":{ - "title":"Votre QR code customisé" - }, - "waitingNfcToWriteModal":{ - "title":"Waiting Nfc", - "titleSuccess":"Nfc Tag written", - "content":"Bring closer the NFC tag to write" - }, - "nfcErrorModal":{ - "titleInsufficientCapacity":"Tag capacity insufficient" - } - }, - "miningPage":{ - "title":"Miner directement depuis votre navigateur", - "subtitle":"Supportez lé réseau en minant et en améliorant la stabilité du réseau tout en étant réponsé en KRB", - "parameterBlock":{ - "title":"Paramètres", - "labelDestinationAddress":"Portefeuille de destination", - "labelThreads":"Nombre de threads (plus = plus de hashrate)", - "start":"Commençer", - "stop":"Arrêter" - }, - "statisticsBlocks":{ - "title":"Statistiques", - "validShares":"Partages valides", - "hashrate":"HashRate", - "maxHashrate":"HashRate max", - "dedicatedHardware":"Avec un logiciel spécifique pour le minage, vous pourriez obtenir entre 2 et 3 fois plus de hashrate.
Cela vous permettrait également de miner avec votre carte graphique (si vous en avez une).", - "miningHandledBy":"Le minage est géré par la pool get.masaricoin.com" - } - }, - "settingsPage":{ - "title":"Paramètres", - "subtitle":"Changez vos paramètres ici", - "versionBlock":{ - "versionNumber":"Numéro de version: ", - "versionCode":"Code de la version: " - }, - "settingsBlock":{ - "speed":{ - "label":"Vitesse d'actualisation du portefeuille (will consume more energy)", - "fastest":"Le plus vite", - "fast":"Rapide", - "medium":"Normal", - "slow":"Lent" - }, - "language":{ - "label":"Language" - }, - "readMinerTx":{ - "label":"Lire les transactions de minage (uniquement pour les personnes faisant du solo-minage)" - } - }, - "changePasswordButton":"Changer le mot de passe de mon portefeuille", - "deleteWalletButton":"Supprimer mon portefeuille (copie locale)", - "walletSettings":{ - "creationHeight":{ - "label":"Hauteur à laquelle le portefeuille a été créé" - }, - "currentScanningHeight": { - "label": "Hauteur actuelle de scan de la blockchain" - }, - "updateButton":"Mettre à jour" - }, - "deleteWalletModal":{ - "title":"Supprimer mon portefeuille (copie locale)", - "content":"Etes vous VRAIMENT sûr de vouloir supprimer votre portefeuille ?", - "confirmText":"Oui je suis sûr", - "cancelText":"Annuler" - } - }, - "importBasePage":{ - "parametersBlock":{ - "title":"Paramètres", - "password":{ - "label":"Mot de passe pour protéger le portefeuille" - }, - "passwordConfirm":{ - "label":"Confirmer le mot de passe", - "invalid":"Le mot de passe ne correspond pas au premier entré" - }, - "importHeight":{ - "label":"Hauteur de création du wallet" - } - } - }, - "importFromQrPage":{ - "title":"Importer depuis un QR code", - "subtitle":"Importation depuis une sauvegarder hors ligne", - "qrCodeBlock":{ - "title":"QR code", - "startScanButton":"Commençer le scan", - "importButton":"Importer" - }, - "qrScanningBlock":{ - "title":"Présentez le QR code" - } - }, - "exportPage":{ - "title":"Sauvegarder de vos identifiants", - "publicAddressBlock":{ - "title":"Votre adresse publique" - }, - "pdfBlock":{ - "title":"Sauvegarde en Pdf", - "downloadButton":"Télécharger" - }, - "warningBlock":{ - "title":"Attention", - "content":"Si vous choisissez de sauvegarder vos cléfs privées ou la phrase mnémotechnique, NE LE ECRIVEZ PAS dans un endroit non sécurisé (chiffré) ceci pour votre propre sécurité.
Le fichier est une solution alternative où les identifiants sont chiffrés et contient également une sauvegarde de l'historique de vos transactions" - }, - "exportBlock":{ - "title":"Exporter vos identifiants (non chiffrés)", - "privateKeysButton":"Obtenir mes cléfs privées", - "mnemonicKeysButton":"Obtenir ma phrase mnémotechnique", - "fileButton":"Exporter ver un fichier" - }, - "walletKeysModal":{ - "title":"Cléfs privées", - "confirmText":"OK", - "content":"Merci de stocker soigneusement ces cléfs. Les posséder signifie posséder les fonds associé !
Clé privée de dépense: {privSpendKey}
Clé privée de visualisation: {privViewKey}" - }, - "mnemonicKeyModal":{ - "title":"Clé privée", - "confirmText":"OK", - "content":"Merci de stocker soigneusement cette phrase mnémotechnique. La posséder signifie posséder les fonds associé ! La phrase est :
{mnemonic}" - }, - "mnemonicLangSelectionModal":{ - "title":"Dans quelle langue souhaitez vous exporter la phrase mnémotechnique ?", - "confirmText":"Exporter" - } - }, - "importPage":{ - "title":"Créer un portefeuille", - "subtitle":"Depuis des cléfs, une fichier ou une phrase mnémotechnique", - "chooseMethod":"Choisissez votre méthode d'import", - "fromKeys":"Depuis des cléfs privées", - "fromFile":"Depuis un fichier", - "fromMnemonic":"Depuis une phrase mnémotechnique", - "fromQr":"Depuis un QR code" - }, - "termsOfUsePage":{ - "title":"Conditions d'utilisations", - "subtitle":"Merci de les lire et d'y préter attention" - }, - "privacyPolicyPage":{ - "title":"Privacy Policy", - "subtitle":"Merci de les lire et d'y préter attention" - }, - "importFromFilePage":{ - "title":"Importer un portefeuille depuis un fichier", - "subtitle":"Utilisez votre sauvegarder pour récréer le portefeuille", - "walletBlock":{ - "title":"Fichier du portefeuille", - "label":"Sélectionner", - "importButton":"Importer" - } - }, - "importFromMnemonicPage":{ - "title":"Importer un portefeuille depuis une phrase mnémotechnique", - "subtitle":"Utiliser la phrase pour créer un portefeuille", - "mnemonicBlock":{ - "title":"Phrase mnémotechnique", - "mnemonic":{ - "label":"Phrase mnémotechnique : 25 mots", - "invalid":"la phrase mnémotechnique est invalide", - "language":"Langue" - }, - "importButton":"Importer" - } - }, - "importFromKeysPage":{ - "title":"Importer un portefeuille depuis des cléfs", - "subtitle":"Utilisez vos cléfs pour créer un portefeuille", - "parametersBlock":{ - "viewOnlyWallet":{ - "label":"Voulez vous faire un portefeuille uniquement pour visualiser les fonds" - } - }, - "keysBlock":{ - "titleNotViewOnly":"Cléfs privées", - "titleViewOnly":"Cléfs de visualisation uniquement", - "privateSpend":{ - "label":"Cléf privée de dépense" - }, - "privateView":{ - "label":"Cléf privée de visualisation", - "optional":"(optionnel)" - }, - "publicKey":{ - "label":"Cléf publique" - }, - "importButton":"Importer" - } - } + "menu": { + "home": "Accueil", + "account": "Compte", + "send": "Envoyer", + "receive": "Recevoir", + "export": "Exporter", + "donate": "Contribuer", + "elections": "Élections", + "contacts": "Contacts", + "settings": "Paramètres", + "disconnect": "Déconnection", + "network": "Stats du réseau", + "mining": "Minage" + }, + "global": { + "loading": "Chargement", + "disableSecurity": "Désactiver cette sécurité. Je comprend les risques", + "passwordInvalidRequirements": "Le mot de passe doit avoir au moins 8 caractères, 1 lettre majuscule, 1 mettre minuscule, un chiffre et un caractère spécial", + "passwordConfirmationNotMatching": "Le mot de passe ne correspond pas au premier écrit", + "download": "Télécharger", + "newVersionModal": { + "title": "Une nouvelle version est disponible", + "content": "Voulez vous recharger pour passer passer sur la nouvelle version ?", + "confirmText": "Oui", + "cancelText": "Plus tard" + }, + "openWalletModal": { + "title": "Mot de passe", + "confirmText": "Ouvrir", + "cancelText": "Annuler" + }, + "invalidPasswordModal": { + "title": "Oups...", + "content": "Votre mot de passe semble invalide", + "confirmText": "OK" + }, + "invalidMnemonicModal": { + "title": "Oups...", + "content": "La phrase mnémotechnique est invalide", + "confirmText": "OK" + }, + "passwordNotComplexEnoughModal": { + "title": "Le mot de passe n'est pas assez complexe", + "confirmText": "OK" + }, + "permissionRequiredForCameraModal": { + "title": "Oups...", + "content": "Il est nécessaire de donner l'accès à la caméra afin de pouvoir scanner le QR Code", + "confirmText": "OK" + } + }, + "bottom": { + "termsOfUse": "Conditions générales d'utilisation", + "privacyPolicy": "Politique de confidentialité", + "support": "Support", + "donate": "Contribuer", + "network": "Stats du réseau", + "miningPool": "Pool de minage", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Portefeuille sécurisé pour Qwertycoin", + "tagLine": "Le moyen le plus simple d'utiliser Qwertycoin, n'importe où, n'importe quand", + "tagLineTwo": "Le moyen le plus simple d'utiliser Qwertycoin", + "actions": { + "loadWallet": "Charger mon portefeuille", + "importWallet": "Importer un portefeuille", + "create": "Créer", + "createWallet": "Créer un portefeuille" + } + }, + "accountPage": { + "title": "Mon compte", + "subtitle": "Apperçu de votre compte et de l'historique des transactions", + "synchronizingBlock": { + "text": "Synchronisation en cours " + }, + "balanceBlock": { + "title": "Votre solde", + "unlocked": "Disponible" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Historique des transactions", + "pendingTxStatus": "En attente", + "emptyWallet": "Vous n'avez aucun fond sur ce portefeuille", + "waitSync": "Veuillez attendre la fin de la synchronisation", + "beReallyPatient": "La première synchronisation peut prendre quelques minutes...", + "getCoinAddress": "Obtenir mon adresse pour recevoir des QWC" + }, + "txDetails": { + "title": "Détails de la transaction", + "txHash": "Tx hash", + "feesOnTx": "Frais sur la tx", + "blockHeight": "Hauteur sur la blockchain", + "paymentId": "ID du paiement", + "unlockStatus": "Status", + "unlockConfirm": "Confirmations", + "txPrivKey": "Clé privée de transaction" + } + }, + "changeWalletPasswordPage": { + "title": "Changer mon mot de passe", + "oldPassword": { + "label": "Ancien", + "invalid": "Mot de passe invalid" + }, + "newPassword": { + "label": "Nouveau mot de passe pour sécuriser" + }, + "newPasswordConfirm": { + "label": "Confirmer mon nouveau mot de passe" + }, + "confirm": "Changer", + "modalSuccess": { + "title": "Mot de passe changé !", + "confirmText": "OK" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "Contacts" + }, + "electionsPage": { + "title": "Élections" + }, + "createWalletPage": { + "generatingStep": { + "title": "Votre portefeuille se génère ...", + "subtitle": "Plus que quelques instants", + "waitingMessage": "Génération du portefeuille ..." + }, + "finalizationStep": { + "title": "C'était simple. Votre portefeuille est prêt !", + "subtitle": "Soyer près à utiliser Qwertycoin le plus simplement possible", + "passwordSelectionBlock": { + "label": "Sécuriser mon portefeuille" + }, + "passwordConfirmBlock": { + "label": "Confirmer le mot de passe" + }, + "validPassword": "Utiliser ce mot de passe", + "backupBlock": { + "title": "Télécharger une copie chiffrée de mes identifiants pour un futur usage", + "option1": "Option 1: ", + "option2": "Option 2: ", + "titlePdf": "Télécharger une copie PDF", + "titleManualWrite": "Ecrire mes cléfs d'accès", + "privateKeys": "Cléfs privées", + "mnemonicPhrase": "Phrase mnémotechnique", + "separatorManualMethodsSolution": " ou ", + "confirmManuallyWritten": "Je les ais écrites", + "warningMessage": "**Ne les perdez pas!** Il est impossible des les récupérer si vous les perdez.
**Ne les paratagez pas!** Vos fonds peuvent être volé si vous utilisez ces informations sur des sites-tiers (malicieux/phishing).
**Faites une sauvegarde!** Sécutisez vos identifiants comme si si vous possédiez des millions de dollars.
", + "finishButton": "Je comprend. Continuer" + } + }, + "disclaimerBlock": { + "title": "Risques liés à l'utilisation de QwertycoinWallet", + "content": "QwertycoinWallet est un service web. Il vous aide à utiliser Qwertycoin facilement sans avoir un installer des logiciels.
Nous vous conseillons de traiter ce site comme vous traiteriez votre portefeuille." + } + }, + "donatePage": { + "title": "Contribuer", + "subtitle": "Aidez à financer le développement et payer les factures de ce service", + "webwalletBlock": { + "title": "Portefeuille en ligne", + "content": "Ce portefeuille est développé par Gnock sur son temps libre.
Si vous voulez aider au développement, payer les serveur et que vous aimez ce service, considérez une petite donation:

" + }, + "devFundBlock": { + "title": "Fond de développement de Qwertycoin", + "content": "Pour aidez Qwertycoin globalement, vous pouvez donner à cette adresse" + } + }, + "supportPage": { + "title": "Support", + "subtitle": "Vous avez besoins d'aide, nous somme la pour aider !", + "getInTouchBlock": { + "title": "Reston en contact !", + "content": "Vous avez des idées, des retours pour aider à améliorer le service ? Contactez nous !", + "discord": "Discord Officiel de Qwertycoin" + } + }, + "networkPage": { + "title": "Statistiques du réseau", + "subtitle": "Détails sur le réseaux Qwertycoin", + "statsBlock": { + "connectNode": "Masternode connecté", + "hashrate": "Hashrate du réseau", + "height": "Hauteur de la Blockchain", + "difficulty": "Difficulty du réseau", + "lastTimeBlock": "Dernier block trouvé", + "lastReward": "Dernière récompense" + } + }, + "sendPage": { + "title": "Envoyer des QWC", + "sendBlock": { + "address": { + "label": "Adresse de destination", + "placeholder": "Écrivez l'adresse où vous voulez envoyer des fonds", + "invalid": "L'adresse de destination est invalide", + "fundsTo": "Les fonds seront envoyé à ", + "receiver": "Destinataire", + "description": "Description" + }, + "amount": { + "label": "Montant à envoyer", + "invalid": "Le montant est invalide" + }, + "paymentId": { + "label": "Identifiant du payment (optionnel)", + "invalid": "L'identifiant du paiement est invalid. La longeur doit être de 16 ou 64 caractères" + }, + "sendButton": "Envoyer", + "cancelButton": "Annuler" + }, + "qrCodeScanning": { + "explication": "Présentez le QR Code" + }, + "notEnoughMoneyModal": { + "title": "Oups...", + "content": "Vous n'avez pas assez de fonds pour effectuer ce tranfert", + "confirmText": "OK" + }, + "thankYouDonationModal": { + "title": "Merci pour votre donation !", + "content": "Votre aide est apprécié.
Cette donation contribuera à améliorer Qwertycoin", + "confirmText": "Fermer" + }, + "transferSentModal": { + "title": "Transfert envoyé avec succès!", + "confirmText": "Fermer" + }, + "transferExceptionModal": { + "title": "Oups...", + "content": "Une erreur est survenue. Merci de nous envoyer de rapport: {details}", + "confirmText": "Fermer" + }, + "invalidAmountModal": { + "title": "Oups...", + "content": "Montant invalide", + "confirmText": "Fermer" + }, + "creatingTransferModal": { + "title": "Création du transfert ...", + "content": "Veuillez patienter ..." + }, + "finalizingTransferModal": { + "title": "Finalisation du transfert ...", + "content": "Veuillez patienter ..." + }, + "confirmTransactionModal": { + "title": "Confirmer le transfert ?", + "content": "Montant: {amount}
Frais: {fees}
Total: {total}", + "confirmText": "Confirmer", + "cancelText": "Annuler" + }, + "waitingNfcModal": { + "title": "Attente du Nfc", + "content": "Veuillez rapprocher votre téléphone de l'autre appareil" + } + }, + "receivePage": { + "title": "Recevoir des QWC", + "receiveBlock": { + "address": { + "title": "Votre adresse pour recevoir des fonds", + "label": "Donner cette adresse pour recevoir des fonds" + }, + "qrCode": { + "title": "Ou personnalisez ce QR Code", + "labelAmount": "Montant (optionnel)", + "labelRecipient": "Nom du destinataire (optionnel)", + "labelDescription": "Description (optionnel)", + "updateButton": "Mettre à jour" + } + }, + "qrBlock": { + "title": "Votre QR code customisé" + }, + "waitingNfcToWriteModal": { + "title": "Waiting Nfc", + "titleSuccess": "Nfc Tag written", + "content": "Bring closer the NFC tag to write" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Tag capacity insufficient" + } + }, + "miningPage": { + "title": "Miner directement depuis votre navigateur", + "subtitle": "Supportez lé réseau en minant et en améliorant la stabilité du réseau tout en étant réponsé en QWC", + "parameterBlock": { + "title": "Paramètres", + "labelDestinationAddress": "Portefeuille de destination", + "labelThreads": "Nombre de threads (plus = plus de hashrate)", + "start": "Commençer", + "stop": "Arrêter" + }, + "statisticsBlocks": { + "title": "Statistiques", + "validShares": "Partages valides", + "hashrate": "HashRate", + "maxHashrate": "HashRate max", + "dedicatedHardware": "Avec un logiciel spécifique pour le minage, vous pourriez obtenir entre 2 et 3 fois plus de hashrate.
Cela vous permettrait également de miner avec votre carte graphique (si vous en avez une).", + "miningHandledBy": "Le minage est géré par la pool pool.qwertycoin.org" + } + }, + "settingsPage": { + "title": "Paramètres", + "subtitle": "Changez vos paramètres ici", + "versionBlock": { + "versionNumber": "Numéro de version: ", + "versionCode": "Code de la version: " + }, + "settingsBlock": { + "speed": { + "label": "Vitesse d'actualisation du portefeuille (will consume more energy)", + "fastest": "Le plus vite", + "fast": "Rapide", + "medium": "Normal", + "slow": "Lent" + }, + "language": { + "label": "Language" + }, + "currency": { + "label": "monnaie nationale" + }, + "readMinerTx": { + "label": "Lire les transactions de minage (uniquement pour les personnes faisant du solo-minage)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Changer le mot de passe de mon portefeuille", + "deleteWalletButton": "Supprimer mon portefeuille (copie locale)", + "walletSettings": { + "creationHeight": { + "label": "Hauteur à laquelle le portefeuille a été créé" + }, + "currentScanningHeight": { + "label": "Hauteur actuelle de scan de la blockchain" + }, + "updateButton": "Mettre à jour" + }, + "deleteWalletModal": { + "title": "Supprimer mon portefeuille (copie locale)", + "content": "Etes vous VRAIMENT sûr de vouloir supprimer votre portefeuille ?", + "confirmText": "Oui je suis sûr", + "cancelText": "Annuler" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Paramètres", + "password": { + "label": "Mot de passe pour protéger le portefeuille" + }, + "passwordConfirm": { + "label": "Confirmer le mot de passe", + "invalid": "Le mot de passe ne correspond pas au premier entré" + }, + "importHeight": { + "label": "Hauteur de création du wallet" + } + } + }, + "importFromQrPage": { + "title": "Importer depuis un QR code", + "subtitle": "Importation depuis une sauvegarder hors ligne", + "qrCodeBlock": { + "title": "QR code", + "startScanButton": "Commençer le scan", + "importButton": "Importer" + }, + "qrScanningBlock": { + "title": "Présentez le QR code" + } + }, + "exportPage": { + "title": "Sauvegarder de vos identifiants", + "publicAddressBlock": { + "title": "Votre adresse publique" + }, + "pdfBlock": { + "title": "Sauvegarde en Pdf", + "downloadButton": "Télécharger" + }, + "warningBlock": { + "title": "Attention", + "content": "Si vous choisissez de sauvegarder vos cléfs privées ou la phrase mnémotechnique, NE LE ECRIVEZ PAS dans un endroit non sécurisé (chiffré) ceci pour votre propre sécurité.
Le fichier est une solution alternative où les identifiants sont chiffrés et contient également une sauvegarde de l'historique de vos transactions" + }, + "exportBlock": { + "title": "Exporter vos identifiants (non chiffrés)", + "privateKeysButton": "Obtenir mes cléfs privées", + "mnemonicKeysButton": "Obtenir ma phrase mnémotechnique", + "fileButton": "Exporter ver un fichier" + }, + "walletKeysModal": { + "title": "Cléfs privées", + "confirmText": "OK", + "content": "Merci de stocker soigneusement ces cléfs. Les posséder signifie posséder les fonds associé !
Clé privée de dépense: {privSpendKey}
Clé privée de visualisation: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Clé privée", + "confirmText": "OK", + "content": "Merci de stocker soigneusement cette phrase mnémotechnique. La posséder signifie posséder les fonds associé ! La phrase est :
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "Dans quelle langue souhaitez vous exporter la phrase mnémotechnique ?", + "confirmText": "Exporter" + } + }, + "importPage": { + "title": "Créer un portefeuille", + "subtitle": "Depuis des cléfs, une fichier ou une phrase mnémotechnique", + "chooseMethod": "Choisissez votre méthode d'import", + "fromKeys": "Depuis des cléfs privées", + "fromFile": "Depuis un fichier", + "fromMnemonic": "Depuis une phrase mnémotechnique", + "fromQr": "Depuis un QR code" + }, + "termsOfUsePage": { + "title": "Conditions d'utilisations", + "subtitle": "Merci de les lire et d'y préter attention" + }, + "privacyPolicyPage": { + "title": "Privacy Policy", + "subtitle": "Merci de les lire et d'y préter attention" + }, + "importFromFilePage": { + "title": "Importer un portefeuille depuis un fichier", + "subtitle": "Utilisez votre sauvegarder pour récréer le portefeuille", + "walletBlock": { + "title": "Fichier du portefeuille", + "label": "Sélectionner", + "importButton": "Importer" + } + }, + "importFromMnemonicPage": { + "title": "Importer un portefeuille depuis une phrase mnémotechnique", + "subtitle": "Utiliser la phrase pour créer un portefeuille", + "mnemonicBlock": { + "title": "Phrase mnémotechnique", + "mnemonic": { + "label": "Phrase mnémotechnique : 25 mots", + "invalid": "la phrase mnémotechnique est invalide", + "language": "Langue" + }, + "importButton": "Importer" + } + }, + "importFromKeysPage": { + "title": "Importer un portefeuille depuis des cléfs", + "subtitle": "Utilisez vos cléfs pour créer un portefeuille", + "parametersBlock": { + "viewOnlyWallet": { + "label": "Voulez vous faire un portefeuille uniquement pour visualiser les fonds" + } + }, + "keysBlock": { + "titleNotViewOnly": "Cléfs privées", + "titleViewOnly": "Cléfs de visualisation uniquement", + "privateSpend": { + "label": "Cléf privée de dépense" + }, + "privateView": { + "label": "Cléf privée de visualisation", + "optional": "(optionnel)" + }, + "publicKey": { + "label": "Cléf publique" + }, + "importButton": "Importer" + } + } }, - "number":{ - }, - "date":{ - "short": { - "year": "numeric", "month": "short", "day": "numeric" - }, - "long": { - "year": "numeric", "month": "short", "day": "numeric", - "weekday": "short", "hour": "numeric", "minute": "numeric", "hour12": false - } + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": false + } } -} \ No newline at end of file +} diff --git a/src/translations/gr.json b/src/translations/gr.json index 4cf33116..37700180 100644 --- a/src/translations/gr.json +++ b/src/translations/gr.json @@ -1,495 +1,539 @@ { - "website":{ - "title":"Επίσημο πορτοφόλι ιστού Karbo", - "description":"Επίσημο online πορτοφόλι για το νόμισμα Karbo - ανώνυμο, ασφαλές, και πλήρως διαχειριζόμενο από τον φυλλομετρητή σας για μέγιστη ασφάλεια" + "website": { + "title": "Επίσημο πορτοφόλι ιστού Qwertycoin", + "description": "Επίσημο online πορτοφόλι για το νόμισμα Qwertycoin - ανώνυμο, ασφαλές, και πλήρως διαχειριζόμενο από τον φυλλομετρητή σας για μέγιστη ασφάλεια" }, "messages": { - "menu": { - "home": "Αρχική", - "account": "Λογαριασμός", - "send": "Αποστολή", - "receive": "Λήψη", - "export": "Εξαγωγή", - "donate": "Δωρεά", - "settings": "Ρυθμίσεις", - "disconnect": "Αποσύνδεση", - "network": "Στατιστικά Δικτύου", - "mining": "Mining" - }, - "global": { - "loading": "Φόρτωση", - "disableSecurity":"Κατάργησε την ασφάλεια, κατανοώ τον κίνδυνο", - "passwordInvalidRequirements":"Ο κωδικός πρέπει να αποτελείται από τουλάχιστο 8 χαρακτήρες - 1 κεφαλαίο, 1 πεζό, 1 αριθμό και 1 σύμβολο", - "passwordConfirmationNotMatching":"Οι κωδικοί δεν ταιριάζουν μεταξύ τους", - "download":"Λήψη", - "newVersionModal":{ - "title":"Μια νέα έκδοση είναι διαθέσιμη", - "content":"Θέλετε να φορτώσετε τη νέα έκδοση;", - "confirmText":"Ναι", - "cancelText":"Πίσω" - }, - "openWalletModal":{ - "title":"Κωδικός Πορτοφολιού", - "confirmText":"Άνοιγμα", - "cancelText":"Ακύρωση" - }, - "invalidPasswordModal":{ - "title":"Ουπς...", - "content":"Ο κωδικός σας είναι άκυρος.", - "confirmText":"OK" - }, - "invalidMnemonicModal":{ - "title":"Ουπς...", - "content":"Η μνημονική φράση είναι άκυρη", - "confirmText":"OK" - }, - "passwordNotComplexEnoughModal":{ - "title":"Ο κωδικός δεν είναι αρκετά περίπλοκος", - "confirmText":"OK" - }, - "permissionRequiredForCameraModal":{ - "title":"Ουπς...", - "content":"Η άδεια προσπέλασης της κάμεράς σας είναι απαραίτητη για τη σάρωση του QR code", - "confirmText":"OK" - } - }, - "bottom": { - "termsOfUse": "Όροι χρήσης", - "privacyPolicy": "Πολιτική Απορρήτου", - "support": "Υποστήριξη", - "donate": "Δωρεά", - "network": "Στατιστικά Δικτύου", - "miningPool": "Mining Pool", - "github": "GitHub" - }, - "homepage": { - "mainTitle": "Ασφαλισμένο Πορτοφόλι Karbo", - "tagLine": "Ο απλούστερος τρόπος χρήσης του Karbo - οπουδήποτε, οποτεδήποτε", - "actions": { - "loadWallet": "Φόρτωσε το πορτοφόλι μου", - "importWallet": "Εισαγωγή πορτοφολιού", - "create": "Δημιουργία", - "createWallet": "Δημιουργία πορτοφολιού" - }, - "notes": { - "secure": { - "title": "Ασφαλές", - "description": "Χωρίς διακομιστές, πλήρως κρυπτογραφημένο!" - }, - "fast": { - "title": "Γρήγορο", - "description": "Στείλε οπουδήποτε, οποτεδήποτε!" - }, - "technology": { - "title": "Μοναδική Τεχνολογία", - "description": "Συνδεδεμένο κατευθείαν στο Karbo blockchain!" - }, - "openSource": { - "title": "100% ανοιχτού κώδικα", - "description": "Διαθέσιμο στο Github!" - } - } - }, - "accountPage": { - "title": "Λογαριασμός", - "subtitle": "Επισκόπηση του λογαριασμού σας και ιστορικό συναλλαγών", - "synchronizingBlock": { - "text": "Συγχρονισμός..." - }, - "balanceBlock": { - "title": "Το υπόλοιπό σας", - "unlocked": "Ξεκλείδωτο" - }, - "historyBlock": { - "title": "Ιστορικό συναλλαγών", - "pendingTxStatus": "Εκκρεμεί", - "emptyWallet": "Αυτή τη στιγμή δεν έχετε χρήματα σε αυτό το πορτοφόλι.", - "waitSync": "Παρακαλώ περιμένετε μέχρι να ανανεωθεί το πορτοφόλι", - "beReallyPatient": "Η αρχική ρύθμιση μπορεί να διαρκέσει λίγη ώρα...", - "getCoinAddress": "Λήψη MSR" - }, - "txDetails":{ - "title":"Λεπτομέρειες συναλλαγής", - "txHash":"Αναγνωριστικό συναλλαγής", - "feesOnTx":"Τέλη συναλλαγής", - "blockHeight":"Block height", - "paymentId":"Payment ID", - "txPrivKey":"Ιδιωτικό κλειδί συναλλαγής" - } - }, - "changeWalletPasswordPage":{ - "title":"Αλλάγή κωδικού", - "oldPassword":{ - "label":"Παλαιός κωδικός", - "invalid":"Ο κωδικός είναι άκυρος" - }, - "newPassword":{ - "label":"Διαλέξτε ένα νέα κωδικό για να προστατέψετε το πορτοφόλι σας" - }, - "newPasswordConfirm":{ - "label":"Επιβεβαιώστε το νέο κωδικό" - }, - "confirm":"Αλλαγή κωδικού", - "modalSuccess":{ - "title":"Ο κωδικός άλλαξε!", - "confirmText":"OK" - } - }, - "createWalletPage":{ - "generatingStep":{ - "title":"Το πορτοφόλι σας δημιουργείται...", - "subtitle":"Σχεδόν τελείωσε", - "waitingMessage":"Δημιουργία πορτοφολιού..." - }, - "finalizationStep":{ - "title":"Αυτό ήταν απλό. Ο λογαριασμός σας είναι έτοιμος!", - "subtitle":"Ετοιμαστείτε να χρησιμοποιήσετε το Karbo όπως δεν το έχετε ξανακάνει", - "passwordSelectionBlock":{ - "label":"Προστατέψτε το πορτοφόλι σας με έναν κωδικό" - }, - "passwordConfirmBlock":{ - "label":"Επιβεβαιώστε τον κωδικό" - }, - "validPassword":"Χρησιμοποιήστε αυτόν τον κωδικό", - "backupBlock":{ - "title":"Αποθηκεύστε τα ιδιωτικά σας αναγνωριστικά για επαναφορά.", - "option1":"Επιλογή 1: ", - "option2":"Επιλογή 2: ", - "titlePdf":"Κατεβάστε ένα αντίγραφο PDF", - "titleManualWrite":"Γράψε τα κλειδιά μου", - "privateKeys":"Ιδιωτικό κλειδί", - "mnemonicPhrase":"Μνημονική φράση", - "separatorManualMethodsSolution":" ή ", - "confirmManuallyWritten":"Έγραψα τη μνημονική μου φράση σε χαρτί", - "warningMessage":"**Μην το χάσετε!** Δεν μπορεί να ανακτηθεί αν το χάσετε.
**Μην το κοινοποιείτε!** Τα χρήματά σας θα κλαπούν εαν χρησιμοποιήσετε αυτό το αρχείο ή τη μνημονική φράση σε κακόβουλο ιστότοπο.
**Δημιουργήστε αντίγραφο ασφαλείας!** Ασφαλείστε το σαν να ασφαλίζατε τα εκατομμύρια ευρώ που μπορεί κάποτε να αξίζει.
", - "finishButton":"Καταλαβαίνω. Συνέχισε." - } - }, - "disclaimerBlock":{ - "title":"Κίνδυνος χρήσης του KarboWallet", - "content":"Το KarboWallet είναι ένα πορτοφόλι βασισμένο στον ιστό. Σας επιτρέπει να χρησιμοποιήσετε το Karbo χωρίς να χρειάζετε να λειτουργείτε έναν δικό σας κόμβο Karbo.
Σας συνιστούμε να θεωρείτε το KarboWallet ως ένα κανονικό πορτοφόλι" - } - }, - "donatePage":{ - "title":"Δωρεά", - "subtitle":"Βοηθήστε στην ανάπτυξη και στα έξοδα", - "webwalletBlock":{ - "title":"Webwallet", - "content":"Αυτό το πορτοφόλι ιστού αναπτύχθηκε από τον Gnock στον ελεύθερό του χρόνο.
Εαν θέλετε να βοηθήσετε στην ανάπτυξη, να συνεισφέρετε στα έξοδα των διακομιστών και σας αρέσει αυτή η εφαρμογή, παρακαλώ σκεφτείτε να κάνετε μια δωρεά:

" - }, - "KarboFundBlock":{ - "title":"Karbo Dev fund", - "content":"Για να βοηθήσετε το Karbo, μπορείτε να κάνετε δωρεά στις παρακάτω διευθύνσεις" - } - }, - "supportPage":{ - "title":"Υποστήριξη", - "subtitle":"Είμαστε εδώ για να βοηθήσουμε!", - "getInTouchBlock":{ - "title":"Ας έρθουμε σε επικοινωνία!", - "content":"'Εχετε ιδέες που θα μπορούσαν να μας βοηθήσουν να βελτιώσουμε το πορτοφόλι; Επικοινωνήστε μαζί μας!", - "discord":"Karbo Discord Channel" - } - }, - "networkPage":{ - "title":"Στατιστικά Δικτύου΄", - "subtitle":"Επισκόπηση τπυ δικτύου Karbo", - "statsBlock":{ - "hashrate":"Network hashrate", - "height":"Blockchain height", - "difficulty":"Network difficulty", - "lastTimeBlock":"Τελευταίο block που βρέθηκε", - "lastReward":"Τελευταία αμοιβή block" - } - }, - "sendPage":{ - "title":"Στείλτε MSR", - "sendBlock":{ - "address":{ - "label":"Διεύθυνση παραλήπτη", - "placeholder":"Γράψτε τη διεύθυνση όπου θέλετε να στείλετε χρήματα", - "invalid":"Η διεύθυνση παραλήπτη είναι άκυρη", - "fundsTo":"Τα χρήματά θα σταλούν στην ακόλουθη διεύθυνση", - "receiver":"Παραλήπτης", - "description":"Περιγραφή" - }, - "amount":{ - "label":"Ποσό προς αποστολή", - "invalid":"Το ποσό είναι άκυρο" - }, - "paymentId":{ - "label":"Payment ID (προαιρετικό)", - "invalid":"Το payment ID είναι άκυρο. Πρέπει να αποτελείται από 16 ή 64 χαρακτήρες" - }, - "sendButton":"Αποστολή", - "cancelButton":"Ακύρωση" - }, - "qrCodeScanning":{ - "explication":"Δείξε το QR code" - }, - "notEnoughMoneyModal":{ - "title":"Ουπς...", - "content":"Δεν έχετε αρκετά χρήματα στο πορτοφόλι σας για να εκτελέσετε αυτή τη συναλλαγή", - "confirmText":"OK" - }, - "thankYouDonationModal":{ - "title":"Ευχαριστούμε για τη δωρεά σας!", - "content":"Εκτιμούμε τη βοήθειά σας.
Αυτή η δωρεά θα βοηθήσει στο να κάνουμε το Karbo καλύτερο", - "confirmText":"OK" - }, - "transferSentModal":{ - "title":"Η συναλλαγή έγινε επιτυχώς!", - "confirmText":"OK" - }, - "transferExceptionModal":{ - "title":"Ουπς...", - "content":"Συνέβη ένα σφάλμα. Παρακαλώ αναφέρετε αυτό το σφάλμα: {details}", - "confirmText":"OK" - }, - "invalidAmountModal":{ - "title":"Ουπς...", - "content":"Άκυρο ποσό", - "confirmText":"OK" - }, - "creatingTransferModal":{ - "title":"Δημιουργία συναλλαγής ...", - "content":"Παρακαλώ περιμένετε..." - }, - "finalizingTransferModal":{ - "title":"Οριστικοποίηση συναλλαγής ...", - "content":"Παρακαλώ περιμένετε..." - }, - "confirmTransactionModal":{ - "title":"Αποδοχή συναλλαγής;", - "content":"Ποσό: {amount}
Τέλη: {fees}
Total: {total}", - "confirmText":"Αποδοχή", - "cancelText":"Ακύρωση" - }, - "waitingNfcModal":{ - "title":"Αναμονή NFC", - "content":"Πλησιάστε στην άλλη συσκευή" - } - }, - "receivePage":{ - "title":"Λήψη MSR", - "receiveBlock":{ - "address":{ - "title":"Η διεύθυνσή σας για λήψη χρημάτων:", - "label":"Δώστε αυτή τη διεύθυνση για να λάβετε χρήματα" - }, - "qrCode":{ - "title":"Ή εξατομικεύστε το QR code:", - "labelAmount":"Ποσό (προαιρετικό)", - "labelRecipient":"Όνομα παραλήπτη (προαιρετικό)", - "labelDescription":"Περιγραφή συναλλαγής (προαιρετικό)", - "updateButton":"Ανανέωση" - } - }, - "qrBlock":{ - "title":"Το εξατομικευμένο QR code σας" - }, - "waitingNfcToWriteModal":{ - "title":"Αναμονή NFC", - "titleSuccess":"Έγινε εγγραφή του NFC Tag", - "content":"Πλησιάστε το NFC tag για εγγραφή" - }, - "nfcErrorModal":{ - "titleInsufficientCapacity":"Ανεπαρκής χωρητικότητα Tag" - } - }, - "miningPage":{ - "title":"Κάντε mining μέσω του φυλλομετρητή σας", - "subtitle":"Υποστηρίξτε το δίκτυο και αμοιφθείτε με MSR", - "parameterBlock":{ - "title":"Παράμετροι", - "labelDestinationAddress":"Πορτοφόλι για κατάθεση αμοιβών από mining", - "labelThreads":"Αριθμός threads (περισσότερα = υψηλότερο hashrate)", - "start":"Έναρξη", - "stop":"Σταμάτημα" - }, - "statisticsBlocks":{ - "title":"Στατιστικά", - "validShares":"Έγκυρα shares", - "hashrate":"Hashrate", - "maxHashrate":"Μέγιστο Hashrate", - "dedicatedHardware":"Με εξειδικευμένο λογισμικό και υλισμοκό για mining μπορείτε να αμοιφθείτε περισσότερα και να βοηθήσει στην αποκέντρωση του δικτύου.", - "miningHandledBy":"Το mining σε αυτή τη σελίδα διαχειρίζεται από το pool get.Karbocoin.com" - } - }, - "settingsPage":{ - "title":"Ρυθμίσεις", - "subtitle":"Αλλάξτε τις παραμέτρους εδώ", - "versionBlock":{ - "versionNumber":"Version number: ", - "versionCode":"Version code: " - }, - "settingsBlock":{ - "speed":{ - "label":"Ρυθμός ανανέωσης πορτοφολιού (καταναλώνει περισσότερους πόρους)", - "fastest":"Ταχύτατο", - "fast":"Γρήγορο", - "medium":"Μεσαίο", - "slow":"Αργό" - }, - "language":{ - "label":"Γλώσσα" - }, - "readMinerTx":{ - "label":"Ανάγνωση συναλλαγών miner (Μόνο για όσους κάνουν solo mining)" - } - }, - "changePasswordButton":"Άλλαξε τον κωδικό του πορτοφολιού μου", - "deleteWalletButton":"Διέγραψε το πορτοφόλι μου (τοπικό αντίγραφο)", - "walletSettings":{ - "creationHeight":{ - "label":"Ύψος δημιουργίας του πορτοφολιού" - }, - "currentScanningHeight": { - "label": "Τρέχον ύψος σάρωσης" - }, - "updateButton":"Ανανέωση" - }, - "deleteWalletModal":{ - "title":"Διέγραψε το πορτοφόλι μου (τοπικό αντίγραφο)", - "content":"Είστε βέβαιοι ότι θέλετε ΠΡΑΓΜΑΤΙΚΑ να διαγράψετε το πορτοφόλι σας;", - "confirmText":"Ναι είμαι βέβαιος", - "cancelText":"Ακύρωση" - } - }, - "importBasePage":{ - "parametersBlock":{ - "title":"Παράμετροι", - "password":{ - "label":"Κωδικός προστασίας του πορτοφολιού σας" - }, - "passwordConfirm":{ - "label":"Επιβεβαιώστε τον κωδικό", - "invalid":"Οι κωδικοί δεν ταιριάζουν μεταξύ τους" - }, - "importHeight":{ - "label":"Ύψος από το οποίο θα γίνει η εισαγωγή:" - } - } - }, - "importFromQrPage":{ - "title":"Εισαγωγή πορτοφολιού από QR code", - "subtitle":"Εισαγωγή πορτοφολιού από εφεδρικό αντίγραφο εκτός σύνδεσης", - "qrCodeBlock":{ - "title":"QR code", - "startScanButton":"Έναρξη σάρωσης", - "importButton":"Εισαγωγή" - }, - "qrScanningBlock":{ - "title":"Δείξτε το QR code" - } - }, - "exportPage":{ - "title":"Backup your credentials", - "publicAddressBlock":{ - "title":"Your public address" - }, - "pdfBlock":{ - "title":"PDF Backup", - "downloadButton":"Download" - }, - "warningBlock":{ - "title":"Warning", - "content":"If you choose to save your private keys or your mnemonic phrase, PLEASE DO NOT store them in clear-text for your own safety.
The file is an alternate solution where your keys are encrypted and contains a backup of all your transactions to spare you a future synchronisation." - }, - "exportBlock":{ - "title":"Export your RAW credentials", - "privateKeysButton":"Get my private keys", - "mnemonicKeysButton":"Get my mnemonic phrase", - "fileButton":"Εξαγωγή σε αρχείο" - }, - "walletKeysModal":{ - "title":"Ιδιωτικά κλειδιά", - "confirmText":"OK", - "content":"Παρακαλώ αποθηκεύστε προσεκτικά αυτά τα κλειδιά. Η κατοχή τους σημαίνει κατοχή των χρημάτων του πορτοφολιού αυτού !
Κλειδί πληρωμής: {privSpendKey}
Ιδιωτικό κλειδί προβολής: {privViewKey}" - }, - "mnemonicKeyModal":{ - "title":"Μνημονική φράση", - "confirmText":"OK", - "content":"Παρακαλώ αποθηκεύστε προσεκτικά αυτή τη μνημονική φράση.Η κατοχή της σημαίνει κατοχή των χρημάτων του πορτοφολιού αυτού ! Η φράση είναι:
{mnemonic}" - }, - "mnemonicLangSelectionModal":{ - "title":"Σε ποιά γλώσσα θέλετε τη μνημονική φράση σας;", - "confirmText":"Εξαγωγή" - } - }, - "importPage":{ - "title":"Δημιουργία πορτοφολιού", - "subtitle":"Από προηγουμένως δημιουργημένα κλειδιά, αρχείο ή μνημονική φράση", - "chooseMethod":"Διαλέξτε την μέθοδο εισαγωγής:", - "fromKeys":"Απο κλειδιά", - "fromFile":"Από αρχείο", - "fromMnemonic":"Από μνημονική φράση", - "fromQr":"Από QR code" - }, - "termsOfUsePage":{ - "title":"Όροι χρήσης", - "subtitle":"Παρακαλώ διαβάστε τους προσεκτικά." - }, - "privacyPolicyPage":{ - "title":"Privacy Policy", - "subtitle":"Παρακαλώ διαβάστε τους προσεκτικά." - }, - "importFromFilePage":{ - "title":"Εισαγωγή πορτοφολιού από αντίγραφο ασφαλείας", - "subtitle":"Χρησιμοποιήστε το αντίγραφο ασφαλείας για να δημιουργήσετε ένα πορτοφόλι", - "walletBlock":{ - "title":"Αρχείο πορτοφολιού", - "label":"Επιλέξτε το αρχείο", - "importButton":"Εισαγωγή" - } - }, - "importFromMnemonicPage":{ - "title":"Εισαγωγή πορτοφολιού από μνημονική φράση", - "subtitle":"Χρησιμοποιήστε τη φράση σας για να δημιουργήσετε ένα πορτοφόλι", - "mnemonicBlock":{ - "title":"Μνημονική φράση", - "mnemonic":{ - "label":"Μνημονική φράση: 25 λέξεις", - "invalid":"Η μνημονική φράση είναι άκυρη", - "language":"Γλώσσα" - }, - "importButton":"Εισαγωγή" - } - }, - "importFromKeysPage":{ - "title":"Εισαγωγή πορτοφολιού από κλειδιά", - "subtitle":"Χρησιμοποιήστε τα κλειδιά σας για να δημιουργήσετε ένα πορτοφόλι", - "parametersBlock":{ - "viewOnlyWallet":{ - "label":"Θέλετε ένα πορτοφόλι μόνο για προβολή;" - } - }, - "keysBlock":{ - "titleNotViewOnly":"Κλειδιά πορτοφολιού", - "titleViewOnly":"Πορτοφόλι μόνο για προβολή", - "privateSpend":{ - "label":"Ιδιωτικό κλειδί πληρωμής" - }, - "privateView":{ - "label":"Ιδιωτικό κλειδί προβολής", - "optional":"(προαιρετικό)" - }, - "publicKey":{ - "label":"Δημόσιο Κλειδί" - }, - "importButton":"Εισαγωγή" - } - } + "menu": { + "home": "Αρχική", + "account": "Λογαριασμός", + "send": "Αποστολή", + "receive": "Λήψη", + "export": "Εξαγωγή", + "donate": "Δωρεά", + "elections": "Αρχαιρεσίες", + "contacts": "Επαφές", + "settings": "Ρυθμίσεις", + "disconnect": "Αποσύνδεση", + "network": "Στατιστικά Δικτύου", + "mining": "Mining" + }, + "global": { + "loading": "Φόρτωση", + "disableSecurity": "Κατάργησε την ασφάλεια, κατανοώ τον κίνδυνο", + "passwordInvalidRequirements": "Ο κωδικός πρέπει να αποτελείται από τουλάχιστο 8 χαρακτήρες - 1 κεφαλαίο, 1 πεζό, 1 αριθμό και 1 σύμβολο", + "passwordConfirmationNotMatching": "Οι κωδικοί δεν ταιριάζουν μεταξύ τους", + "download": "Λήψη", + "newVersionModal": { + "title": "Μια νέα έκδοση είναι διαθέσιμη", + "content": "Θέλετε να φορτώσετε τη νέα έκδοση;", + "confirmText": "Ναι", + "cancelText": "Πίσω" + }, + "openWalletModal": { + "title": "Κωδικός Πορτοφολιού", + "confirmText": "Άνοιγμα", + "cancelText": "Ακύρωση" + }, + "invalidPasswordModal": { + "title": "Ουπς...", + "content": "Ο κωδικός σας είναι άκυρος.", + "confirmText": "OK" + }, + "invalidMnemonicModal": { + "title": "Ουπς...", + "content": "Η μνημονική φράση είναι άκυρη", + "confirmText": "OK" + }, + "passwordNotComplexEnoughModal": { + "title": "Ο κωδικός δεν είναι αρκετά περίπλοκος", + "confirmText": "OK" + }, + "permissionRequiredForCameraModal": { + "title": "Ουπς...", + "content": "Η άδεια προσπέλασης της κάμεράς σας είναι απαραίτητη για τη σάρωση του QR code", + "confirmText": "OK" + } + }, + "bottom": { + "termsOfUse": "Όροι χρήσης", + "privacyPolicy": "Πολιτική Απορρήτου", + "support": "Υποστήριξη", + "donate": "Δωρεά", + "network": "Στατιστικά Δικτύου", + "miningPool": "Mining Pool", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Ασφαλισμένο Πορτοφόλι Qwertycoin", + "tagLine": "Ο απλούστερος τρόπος χρήσης του Qwertycoin - οπουδήποτε, οποτεδήποτε", + "tagLineTwo": "Ο απλούστερος τρόπος χρήσης του Qwertycoin", + "actions": { + "loadWallet": "Φόρτωσε το πορτοφόλι μου", + "importWallet": "Εισαγωγή πορτοφολιού", + "create": "Δημιουργία", + "createWallet": "Δημιουργία πορτοφολιού" + } + }, + "accountPage": { + "title": "Λογαριασμός", + "subtitle": "Επισκόπηση του λογαριασμού σας και ιστορικό συναλλαγών", + "synchronizingBlock": { + "text": "Συγχρονισμός..." + }, + "balanceBlock": { + "title": "Το υπόλοιπό σας", + "unlocked": "Ξεκλείδωτο" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Ιστορικό συναλλαγών", + "pendingTxStatus": "Εκκρεμεί", + "emptyWallet": "Αυτή τη στιγμή δεν έχετε χρήματα σε αυτό το πορτοφόλι.", + "waitSync": "Παρακαλώ περιμένετε μέχρι να ανανεωθεί το πορτοφόλι", + "beReallyPatient": "Η αρχική ρύθμιση μπορεί να διαρκέσει λίγη ώρα...", + "getCoinAddress": "Λήψη QWC" + }, + "txDetails": { + "title": "Λεπτομέρειες συναλλαγής", + "txHash": "Αναγνωριστικό συναλλαγής", + "feesOnTx": "Τέλη συναλλαγής", + "blockHeight": "Block height", + "unlockStatus": "Status", + "unlockConfirm": "Confirmations", + "paymentId": "Payment ID", + "txPrivKey": "Ιδιωτικό κλειδί συναλλαγής" + } + }, + "changeWalletPasswordPage": { + "title": "Αλλάγή κωδικού", + "oldPassword": { + "label": "Παλαιός κωδικός", + "invalid": "Ο κωδικός είναι άκυρος" + }, + "newPassword": { + "label": "Διαλέξτε ένα νέα κωδικό για να προστατέψετε το πορτοφόλι σας" + }, + "newPasswordConfirm": { + "label": "Επιβεβαιώστε το νέο κωδικό" + }, + "confirm": "Αλλαγή κωδικού", + "modalSuccess": { + "title": "Ο κωδικός άλλαξε!", + "confirmText": "OK" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "Επαφές" + }, + "electionsPage": { + "title": "Αρχαιρεσίες" + }, + "createWalletPage": { + "generatingStep": { + "title": "Το πορτοφόλι σας δημιουργείται...", + "subtitle": "Σχεδόν τελείωσε", + "waitingMessage": "Δημιουργία πορτοφολιού..." + }, + "finalizationStep": { + "title": "Αυτό ήταν απλό. Ο λογαριασμός σας είναι έτοιμος!", + "subtitle": "Ετοιμαστείτε να χρησιμοποιήσετε το Qwertycoin όπως δεν το έχετε ξανακάνει", + "passwordSelectionBlock": { + "label": "Προστατέψτε το πορτοφόλι σας με έναν κωδικό" + }, + "passwordConfirmBlock": { + "label": "Επιβεβαιώστε τον κωδικό" + }, + "validPassword": "Χρησιμοποιήστε αυτόν τον κωδικό", + "backupBlock": { + "title": "Αποθηκεύστε τα ιδιωτικά σας αναγνωριστικά για επαναφορά.", + "option1": "Επιλογή 1: ", + "option2": "Επιλογή 2: ", + "titlePdf": "Κατεβάστε ένα αντίγραφο PDF", + "titleManualWrite": "Γράψε τα κλειδιά μου", + "privateKeys": "Ιδιωτικό κλειδί", + "mnemonicPhrase": "Μνημονική φράση", + "separatorManualMethodsSolution": " ή ", + "confirmManuallyWritten": "Έγραψα τη μνημονική μου φράση σε χαρτί", + "warningMessage": "**Μην το χάσετε!** Δεν μπορεί να ανακτηθεί αν το χάσετε.
**Μην το κοινοποιείτε!** Τα χρήματά σας θα κλαπούν εαν χρησιμοποιήσετε αυτό το αρχείο ή τη μνημονική φράση σε κακόβουλο ιστότοπο.
**Δημιουργήστε αντίγραφο ασφαλείας!** Ασφαλείστε το σαν να ασφαλίζατε τα εκατομμύρια ευρώ που μπορεί κάποτε να αξίζει.
", + "finishButton": "Καταλαβαίνω. Συνέχισε." + } + }, + "disclaimerBlock": { + "title": "Κίνδυνος χρήσης του QwertycoinWallet", + "content": "Το QwertycoinWallet είναι ένα πορτοφόλι βασισμένο στον ιστό. Σας επιτρέπει να χρησιμοποιήσετε το Qwertycoin χωρίς να χρειάζετε να λειτουργείτε έναν δικό σας κόμβο Qwertycoin.
Σας συνιστούμε να θεωρείτε το QwertycoinWallet ως ένα κανονικό πορτοφόλι" + } + }, + "donatePage": { + "title": "Δωρεά", + "subtitle": "Βοηθήστε στην ανάπτυξη και στα έξοδα", + "webwalletBlock": { + "title": "Webwallet", + "content": "Αυτό το πορτοφόλι ιστού αναπτύχθηκε από τον Gnock στον ελεύθερό του χρόνο.
Εαν θέλετε να βοηθήσετε στην ανάπτυξη, να συνεισφέρετε στα έξοδα των διακομιστών και σας αρέσει αυτή η εφαρμογή, παρακαλώ σκεφτείτε να κάνετε μια δωρεά:

" + }, + "QwertycoinFundBlock": { + "title": "Qwertycoin Dev fund", + "content": "Για να βοηθήσετε το Qwertycoin, μπορείτε να κάνετε δωρεά στις παρακάτω διευθύνσεις" + } + }, + "supportPage": { + "title": "Υποστήριξη", + "subtitle": "Είμαστε εδώ για να βοηθήσουμε!", + "getInTouchBlock": { + "title": "Ας έρθουμε σε επικοινωνία!", + "content": "'Εχετε ιδέες που θα μπορούσαν να μας βοηθήσουν να βελτιώσουμε το πορτοφόλι; Επικοινωνήστε μαζί μας!", + "discord": "Qwertycoin Discord Channel" + } + }, + "networkPage": { + "title": "Στατιστικά Δικτύου΄", + "subtitle": "Επισκόπηση τπυ δικτύου Qwertycoin", + "statsBlock": { + "connectNode": "Συνδεδεμένο Masternode", + "hashrate": "Network hashrate", + "height": "Blockchain height", + "difficulty": "Network difficulty", + "lastTimeBlock": "Τελευταίο block που βρέθηκε", + "lastReward": "Τελευταία αμοιβή block" + } + }, + "sendPage": { + "title": "Στείλτε QWC", + "sendBlock": { + "address": { + "label": "Διεύθυνση παραλήπτη", + "placeholder": "Γράψτε τη διεύθυνση όπου θέλετε να στείλετε χρήματα", + "invalid": "Η διεύθυνση παραλήπτη είναι άκυρη", + "fundsTo": "Τα χρήματά θα σταλούν στην ακόλουθη διεύθυνση", + "receiver": "Παραλήπτης", + "description": "Περιγραφή" + }, + "amount": { + "label": "Ποσό προς αποστολή", + "invalid": "Το ποσό είναι άκυρο" + }, + "paymentId": { + "label": "Payment ID (προαιρετικό)", + "invalid": "Το payment ID είναι άκυρο. Πρέπει να αποτελείται από 16 ή 64 χαρακτήρες" + }, + "sendButton": "Αποστολή", + "cancelButton": "Ακύρωση" + }, + "qrCodeScanning": { + "explication": "Δείξε το QR code" + }, + "notEnoughMoneyModal": { + "title": "Ουπς...", + "content": "Δεν έχετε αρκετά χρήματα στο πορτοφόλι σας για να εκτελέσετε αυτή τη συναλλαγή", + "confirmText": "OK" + }, + "thankYouDonationModal": { + "title": "Ευχαριστούμε για τη δωρεά σας!", + "content": "Εκτιμούμε τη βοήθειά σας.
Αυτή η δωρεά θα βοηθήσει στο να κάνουμε το Qwertycoin καλύτερο", + "confirmText": "OK" + }, + "transferSentModal": { + "title": "Η συναλλαγή έγινε επιτυχώς!", + "confirmText": "OK" + }, + "transferExceptionModal": { + "title": "Ουπς...", + "content": "Συνέβη ένα σφάλμα. Παρακαλώ αναφέρετε αυτό το σφάλμα: {details}", + "confirmText": "OK" + }, + "invalidAmountModal": { + "title": "Ουπς...", + "content": "Άκυρο ποσό", + "confirmText": "OK" + }, + "creatingTransferModal": { + "title": "Δημιουργία συναλλαγής ...", + "content": "Παρακαλώ περιμένετε..." + }, + "finalizingTransferModal": { + "title": "Οριστικοποίηση συναλλαγής ...", + "content": "Παρακαλώ περιμένετε..." + }, + "confirmTransactionModal": { + "title": "Αποδοχή συναλλαγής;", + "content": "Ποσό: {amount}
Τέλη: {fees}
Total: {total}", + "confirmText": "Αποδοχή", + "cancelText": "Ακύρωση" + }, + "waitingNfcModal": { + "title": "Αναμονή NFC", + "content": "Πλησιάστε στην άλλη συσκευή" + } + }, + "receivePage": { + "title": "Λήψη QWC", + "receiveBlock": { + "address": { + "title": "Η διεύθυνσή σας για λήψη χρημάτων:", + "label": "Δώστε αυτή τη διεύθυνση για να λάβετε χρήματα" + }, + "qrCode": { + "title": "Ή εξατομικεύστε το QR code:", + "labelAmount": "Ποσό (προαιρετικό)", + "labelRecipient": "Όνομα παραλήπτη (προαιρετικό)", + "labelDescription": "Περιγραφή συναλλαγής (προαιρετικό)", + "updateButton": "Ανανέωση" + } + }, + "qrBlock": { + "title": "Το εξατομικευμένο QR code σας" + }, + "waitingNfcToWriteModal": { + "title": "Αναμονή NFC", + "titleSuccess": "Έγινε εγγραφή του NFC Tag", + "content": "Πλησιάστε το NFC tag για εγγραφή" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Ανεπαρκής χωρητικότητα Tag" + } + }, + "miningPage": { + "title": "Κάντε mining μέσω του φυλλομετρητή σας", + "subtitle": "Υποστηρίξτε το δίκτυο και αμοιφθείτε με QWC", + "parameterBlock": { + "title": "Παράμετροι", + "labelDestinationAddress": "Πορτοφόλι για κατάθεση αμοιβών από mining", + "labelThreads": "Αριθμός threads (περισσότερα = υψηλότερο hashrate)", + "start": "Έναρξη", + "stop": "Σταμάτημα" + }, + "statisticsBlocks": { + "title": "Στατιστικά", + "validShares": "Έγκυρα shares", + "hashrate": "Hashrate", + "maxHashrate": "Μέγιστο Hashrate", + "dedicatedHardware": "Με εξειδικευμένο λογισμικό και υλισμοκό για mining μπορείτε να αμοιφθείτε περισσότερα και να βοηθήσει στην αποκέντρωση του δικτύου.", + "miningHandledBy": "Το mining σε αυτή τη σελίδα διαχειρίζεται από το pool https://qwertycoin.org" + } + }, + "settingsPage": { + "title": "Ρυθμίσεις", + "subtitle": "Αλλάξτε τις παραμέτρους εδώ", + "versionBlock": { + "versionNumber": "Version number: ", + "versionCode": "Version code: " + }, + "settingsBlock": { + "speed": { + "label": "Ρυθμός ανανέωσης πορτοφολιού (καταναλώνει περισσότερους πόρους)", + "fastest": "Ταχύτατο", + "fast": "Γρήγορο", + "medium": "Μεσαίο", + "slow": "Αργό" + }, + "language": { + "label": "Γλώσσα" + }, + "currency": { + "label": "εθνικό νόμισμα" + }, + "readMinerTx": { + "label": "Ανάγνωση συναλλαγών miner (Μόνο για όσους κάνουν solo mining)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Άλλαξε τον κωδικό του πορτοφολιού μου", + "deleteWalletButton": "Διέγραψε το πορτοφόλι μου (τοπικό αντίγραφο)", + "walletSettings": { + "creationHeight": { + "label": "Ύψος δημιουργίας του πορτοφολιού" + }, + "currentScanningHeight": { + "label": "Τρέχον ύψος σάρωσης" + }, + "updateButton": "Ανανέωση" + }, + "deleteWalletModal": { + "title": "Διέγραψε το πορτοφόλι μου (τοπικό αντίγραφο)", + "content": "Είστε βέβαιοι ότι θέλετε ΠΡΑΓΜΑΤΙΚΑ να διαγράψετε το πορτοφόλι σας;", + "confirmText": "Ναι είμαι βέβαιος", + "cancelText": "Ακύρωση" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Παράμετροι", + "password": { + "label": "Κωδικός προστασίας του πορτοφολιού σας" + }, + "passwordConfirm": { + "label": "Επιβεβαιώστε τον κωδικό", + "invalid": "Οι κωδικοί δεν ταιριάζουν μεταξύ τους" + }, + "importHeight": { + "label": "Ύψος από το οποίο θα γίνει η εισαγωγή:" + } + } + }, + "importFromQrPage": { + "title": "Εισαγωγή πορτοφολιού από QR code", + "subtitle": "Εισαγωγή πορτοφολιού από εφεδρικό αντίγραφο εκτός σύνδεσης", + "qrCodeBlock": { + "title": "QR code", + "startScanButton": "Έναρξη σάρωσης", + "importButton": "Εισαγωγή" + }, + "qrScanningBlock": { + "title": "Δείξτε το QR code" + } + }, + "exportPage": { + "title": "Backup your credentials", + "publicAddressBlock": { + "title": "Your public address" + }, + "pdfBlock": { + "title": "PDF Backup", + "downloadButton": "Download" + }, + "warningBlock": { + "title": "Warning", + "content": "If you choose to save your private keys or your mnemonic phrase, PLEASE DO NOT store them in clear-text for your own safety.
The file is an alternate solution where your keys are encrypted and contains a backup of all your transactions to spare you a future synchronisation." + }, + "exportBlock": { + "title": "Export your RAW credentials", + "privateKeysButton": "Get my private keys", + "mnemonicKeysButton": "Get my mnemonic phrase", + "fileButton": "Εξαγωγή σε αρχείο" + }, + "walletKeysModal": { + "title": "Ιδιωτικά κλειδιά", + "confirmText": "OK", + "content": "Παρακαλώ αποθηκεύστε προσεκτικά αυτά τα κλειδιά. Η κατοχή τους σημαίνει κατοχή των χρημάτων του πορτοφολιού αυτού !
Κλειδί πληρωμής: {privSpendKey}
Ιδιωτικό κλειδί προβολής: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Μνημονική φράση", + "confirmText": "OK", + "content": "Παρακαλώ αποθηκεύστε προσεκτικά αυτή τη μνημονική φράση.Η κατοχή της σημαίνει κατοχή των χρημάτων του πορτοφολιού αυτού ! Η φράση είναι:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "Σε ποιά γλώσσα θέλετε τη μνημονική φράση σας;", + "confirmText": "Εξαγωγή" + } + }, + "importPage": { + "title": "Δημιουργία πορτοφολιού", + "subtitle": "Από προηγουμένως δημιουργημένα κλειδιά, αρχείο ή μνημονική φράση", + "chooseMethod": "Διαλέξτε την μέθοδο εισαγωγής:", + "fromKeys": "Απο κλειδιά", + "fromFile": "Από αρχείο", + "fromMnemonic": "Από μνημονική φράση", + "fromQr": "Από QR code" + }, + "termsOfUsePage": { + "title": "Όροι χρήσης", + "subtitle": "Παρακαλώ διαβάστε τους προσεκτικά." + }, + "privacyPolicyPage": { + "title": "Privacy Policy", + "subtitle": "Παρακαλώ διαβάστε τους προσεκτικά." + }, + "importFromFilePage": { + "title": "Εισαγωγή πορτοφολιού από αντίγραφο ασφαλείας", + "subtitle": "Χρησιμοποιήστε το αντίγραφο ασφαλείας για να δημιουργήσετε ένα πορτοφόλι", + "walletBlock": { + "title": "Αρχείο πορτοφολιού", + "label": "Επιλέξτε το αρχείο", + "importButton": "Εισαγωγή" + } + }, + "importFromMnemonicPage": { + "title": "Εισαγωγή πορτοφολιού από μνημονική φράση", + "subtitle": "Χρησιμοποιήστε τη φράση σας για να δημιουργήσετε ένα πορτοφόλι", + "mnemonicBlock": { + "title": "Μνημονική φράση", + "mnemonic": { + "label": "Μνημονική φράση: 25 λέξεις", + "invalid": "Η μνημονική φράση είναι άκυρη", + "language": "Γλώσσα" + }, + "importButton": "Εισαγωγή" + } + }, + "importFromKeysPage": { + "title": "Εισαγωγή πορτοφολιού από κλειδιά", + "subtitle": "Χρησιμοποιήστε τα κλειδιά σας για να δημιουργήσετε ένα πορτοφόλι", + "parametersBlock": { + "viewOnlyWallet": { + "label": "Θέλετε ένα πορτοφόλι μόνο για προβολή;" + } + }, + "keysBlock": { + "titleNotViewOnly": "Κλειδιά πορτοφολιού", + "titleViewOnly": "Πορτοφόλι μόνο για προβολή", + "privateSpend": { + "label": "Ιδιωτικό κλειδί πληρωμής" + }, + "privateView": { + "label": "Ιδιωτικό κλειδί προβολής", + "optional": "(προαιρετικό)" + }, + "publicKey": { + "label": "Δημόσιο Κλειδί" + }, + "importButton": "Εισαγωγή" + } + } }, - "number":{ - }, - "date":{ - "short": { - "year": "numeric", "month": "short", "day": "numeric" - }, - "long": { - "year": "numeric", "month": "short", "day": "numeric", - "weekday": "short", "hour": "numeric", "minute": "numeric", "hour12": true - } + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": true + } } -} \ No newline at end of file +} diff --git a/src/translations/he.json b/src/translations/he.json new file mode 100644 index 00000000..dd608c56 --- /dev/null +++ b/src/translations/he.json @@ -0,0 +1,539 @@ +{ + "website": { + "title": "Qwertycoin ארנק | פשוט, חלק, בטוח. ברוך הבא לעתיד.", + "description": "ארנק מקוון רשמי עבור מטבע Qwertycoin - מטופל באופן מלא בדפדפן שלך לאבטחה אופטימלית" + }, + "messages": { + "menu": { + "home": "בית", + "account": "חשבון", + "send": "שלח", + "receive": "קבל", + "export": "יצא", + "donate": "לתרום", + "elections": "בחירות", + "contacts": "אנשי קשר", + "settings": "הגדרות", + "disconnect": "להתנתק", + "network": "סטטיסטיקת רשת", + "mining": "כרייה" + }, + "global": { + "loading": "Loading", + "disableSecurity": "Disable this security, I understand the risk", + "passwordInvalidRequirements": "The password needs at least 8 characters - 1 upper case letter, 1 lower case letter, one number, and one special character", + "passwordConfirmationNotMatching": "The password does not match the first password you wrote", + "download": "Download", + "newVersionModal": { + "title": "A new version is available", + "content": "Do you want to reload to load the new version?", + "confirmText": "Yes", + "cancelText": "Back" + }, + "openWalletModal": { + "title": "Wallet Password", + "confirmText": "Open", + "cancelText": "בטל" + }, + "invalidPasswordModal": { + "title": "Oops...", + "content": "Your password seems invalid", + "confirmText": "OK" + }, + "invalidMnemonicModal": { + "title": "Oops...", + "content": "The mnemonic phrase is invalid", + "confirmText": "OK" + }, + "passwordNotComplexEnoughModal": { + "title": "The password is not complex enough", + "confirmText": "OK" + }, + "permissionRequiredForCameraModal": { + "title": "Oops...", + "content": "The permission to access your camera is required to scan the QR code", + "confirmText": "OK" + } + }, + "bottom": { + "termsOfUse": "Terms of Use", + "privacyPolicy": "Privacy Policy", + "support": "Support", + "donate": "Donate", + "network": "Network Stats", + "miningPool": "Mining Pool", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Qwertycoin Wallet", + "tagLine": "anywhere. anytime. anyplace. any device.", + "tagLineTwo": "The simplest way to use Qwertycoin", + "actions": { + "loadWallet": "Load my wallet", + "importWallet": "Import a wallet", + "create": "Create", + "createWallet": "Create a wallet" + } + }, + "accountPage": { + "title": "Account", + "subtitle": "Your account overview and transaction history", + "synchronizingBlock": { + "text": "Synchronizing..." + }, + "balanceBlock": { + "title": "Your balance", + "unlocked": "Unlocked" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Transaction history", + "pendingTxStatus": "Pending", + "emptyWallet": "You currently have no funds in this wallet.", + "waitSync": "Please wait until the wallet is updated", + "beReallyPatient": "The initial setup can take some time...", + "getCoinAddress": "Receive QWC" + }, + "txDetails": { + "title": "Transaction details", + "txHash": "Transaction Hash", + "feesOnTx": "Transaction fee", + "blockHeight": "Block height", + "paymentId": "Payment ID", + "unlockStatus": "Status", + "unlockConfirm": "Confirmations", + "txPrivKey": "Transaction Private Key" + } + }, + "changeWalletPasswordPage": { + "title": "Change your password", + "oldPassword": { + "label": "Old password", + "invalid": "The password is invalid" + }, + "newPassword": { + "label": "Choose a new password to protect your wallet" + }, + "newPasswordConfirm": { + "label": "Confirm the new password" + }, + "confirm": "Change the password", + "modalSuccess": { + "title": "Password changed!", + "confirmText": "OK" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "אנשי קשר" + }, + "electionsPage": { + "title": "בחירות" + }, + "createWalletPage": { + "generatingStep": { + "title": "Your wallet is being generated...", + "subtitle": "It's almost done", + "waitingMessage": "Generating your wallet..." + }, + "finalizationStep": { + "title": "That was simple. Your account is ready!", + "subtitle": "Be ready to use Qwertycoin like you never have", + "passwordSelectionBlock": { + "label": "Protect your wallet" + }, + "passwordConfirmBlock": { + "label": "Confirm the password" + }, + "validPassword": "Use this password", + "backupBlock": { + "title": "Save your private credentials for recovery.", + "option1": "Option 1: ", + "option2": "Option 2: ", + "titlePdf": "Download a PDF copy", + "titleManualWrite": "Write down my keys", + "privateKeys": "Private key", + "mnemonicPhrase": "Mnemonic phrase", + "separatorManualMethodsSolution": " or ", + "confirmManuallyWritten": "I wrote my seed phrase down", + "warningMessage": "**Do not lose it!** It cannot be recovered if you lose it.
**Do not share it!** Your funds will be stolen if you use this file or seed on a malicious/phishing site.
**Make a backup!** Secure it like the millions of dollars it may one day be worth.
", + "finishButton": "I understand. Continue." + } + }, + "disclaimerBlock": { + "title": "Risk of Using QwertycoinWallet", + "content": "QwertycoinWallet is a web-based interface. It helps you use Qwertycoin without running a full Qwertycoin node.
We recommend you treat QwertycoinWallet like you will treat your actual wallet." + } + }, + "donatePage": { + "title": "Donate", + "subtitle": "Help to fund the development and pay the bills", + "webwalletBlock": { + "title": "Webwallet", + "content": "If you want to help to pay for the servers, to support new features development, and like this app, please consider a donation:

" + }, + "devFundBlock": { + "title": "Qwertycoin Dev fund", + "content": "To help Qwertycoin, you can donate at these addresses" + } + }, + "supportPage": { + "title": "Support", + "subtitle": "We are here to help!", + "getInTouchBlock": { + "title": "Let's Get In Touch!", + "content": "Do you have ideas or feedback that could help us improve the wallet? Contact us!", + "discord": "Qwertycoin Discord Channel" + } + }, + "networkPage": { + "title": "Network stats", + "subtitle": "Insights on the Qwertycoin network", + "statsBlock": { + "connectNode": "Connected Masternode", + "hashrate": "Network hashrate", + "height": "Blockchain height", + "difficulty": "Network difficulty", + "lastTimeBlock": "Last block found", + "lastReward": "Last block reward" + } + }, + "sendPage": { + "title": "Send QWC", + "sendBlock": { + "address": { + "label": "Destination address", + "placeholder": "Write the address where you want to send funds", + "invalid": "The destination address is invalid", + "fundsTo": "The funds will be sent to", + "receiver": "Receiver", + "description": "Description" + }, + "amount": { + "label": "Amount to send", + "invalid": "The amount is invalid" + }, + "paymentId": { + "label": "Payment ID (optional)", + "invalid": "The payment ID is invalid. The length must be 16 or 64 characters" + }, + "sendButton": "Send", + "cancelButton": "בטל" + }, + "qrCodeScanning": { + "explication": "Present the QR code" + }, + "notEnoughMoneyModal": { + "title": "Oops...", + "content": "You don't have enough funds in your wallet to execute this transfer", + "confirmText": "OK" + }, + "thankYouDonationModal": { + "title": "Thank you for your donation!", + "content": "Your help is appreciated. This donation will help make Qwertycoin better", + "confirmText": "OK" + }, + "transferSentModal": { + "title": "Transfer sent successfully!", + "confirmText": "OK" + }, + "transferExceptionModal": { + "title": "Oops...", + "content": "An error occurred. Please report this error: {details}", + "confirmText": "OK" + }, + "invalidAmountModal": { + "title": "Oops...", + "content": "Invalid amount", + "confirmText": "OK" + }, + "creatingTransferModal": { + "title": "Creating transfer ...", + "content": "Please wait..." + }, + "finalizingTransferModal": { + "title": "Finalizing transfer ...", + "content": "Please wait..." + }, + "confirmTransactionModal": { + "title": "Confirm transfer?", + "content": "Amount: {amount}
Fees: {fees}
Total: {total}", + "confirmText": "Confirm", + "cancelText": "בטל" + }, + "waitingNfcModal": { + "title": "Waiting NFC", + "content": "Bring this device closer to the other device" + } + }, + "receivePage": { + "title": "Receive QWC", + "receiveBlock": { + "address": { + "title": "Your address to receive funds:", + "label": "Give this address to receive funds" + }, + "qrCode": { + "title": "Or personalize the QR code:", + "labelAmount": "Amount (optional)", + "labelRecipient": "Recipient name (optional)", + "labelDescription": "Transaction description (optional)", + "updateButton": "Update" + } + }, + "qrBlock": { + "title": "Your customized QR code" + }, + "waitingNfcToWriteModal": { + "title": "Waiting NFC", + "titleSuccess": "NFC Tag written", + "content": "Bring the NFC tag closer to this device to write" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Tag capacity insufficient" + } + }, + "miningPage": { + "title": "Mine directly in your browser", + "subtitle": "Support the network by mining and be rewarded with QWC", + "parameterBlock": { + "title": "Parameters", + "labelDestinationAddress": "Wallet to mine", + "labelThreads": "Number of threads (more = higher hashrate)", + "start": "Start", + "stop": "Stop" + }, + "statisticsBlocks": { + "title": "Statistics", + "validShares": "Valid shares", + "hashrate": "Hashrate", + "maxHashrate": "Max Hashrate", + "dedicatedHardware": "With dedicating mining software and hardware, you could earn more and help decentralize the network.", + "miningHandledBy": "This mining is handled by the mining pool pool.qwertycoin.org" + } + }, + "settingsPage": { + "title": "Settings", + "subtitle": "Change your parameters here", + "versionBlock": { + "versionNumber": "Version number: ", + "versionCode": "Version code: " + }, + "settingsBlock": { + "speed": { + "label": "Speed to update the wallet (will consume more resources)", + "fastest": "Fastest", + "fast": "Fast", + "medium": "Medium", + "slow": "Slow" + }, + "language": { + "label": "Language" + }, + "currency": { + "label": "National Currency" + }, + "readMinerTx": { + "label": "Read miner transactions (only for solo mining)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Change my wallet password", + "deleteWalletButton": "Delete my wallet (local copy)", + "walletSettings": { + "creationHeight": { + "label": "Creation height of the wallet" + }, + "currentScanningHeight": { + "label": "Current scanning height" + }, + "updateButton": "Update" + }, + "deleteWalletModal": { + "title": "Delete My Wallet (local copy)", + "content": "Are you sure you REALLY want to delete your wallet ?", + "confirmText": "Yes I'm sure", + "cancelText": "בטל" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Parameters", + "password": { + "label": "Password to protect your wallet" + }, + "passwordConfirm": { + "label": "Confirm the password", + "invalid": "The password does not match the first password you wrote" + }, + "importHeight": { + "label": "Height to import from:" + } + } + }, + "importFromQrPage": { + "title": "Importing wallet from a QR code", + "subtitle": "Import a wallet from an offline backup", + "qrCodeBlock": { + "title": "QR code", + "startScanButton": "Start the scan", + "importButton": "Import" + }, + "qrScanningBlock": { + "title": "Present the QR code" + } + }, + "exportPage": { + "title": "Backup your credentials", + "publicAddressBlock": { + "title": "Your public address" + }, + "pdfBlock": { + "title": "PDF Backup", + "downloadButton": "Download" + }, + "warningBlock": { + "title": "Warning", + "content": "If you choose to save your private keys or your mnemonic phrase, PLEASE DO NOT store them in clear-text for your own safety.
The file is an alternate solution where your keys are encrypted and contains a backup of all your transactions to spare you a future synchronisation." + }, + "exportBlock": { + "title": "Export your RAW credentials", + "privateKeysButton": "Get my private keys", + "mnemonicKeysButton": "Get my mnemonic phrase", + "fileButton": "Export to a file" + }, + "walletKeysModal": { + "title": "Private keys", + "confirmText": "OK", + "content": "Please carefully store these keys. Possessing them means possessing the funds associated !
Spend key: {privSpendKey}
Private view key: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Mnemonic phrase", + "confirmText": "OK", + "content": "Please store carefully this mnemonic phrase. Possessing it means possessing the funds associated ! The phrase is:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "In which language do you want your mnemonic phrase?", + "confirmText": "Export" + } + }, + "importPage": { + "title": "Create a wallet", + "subtitle": "From previously created keys, file, or mnemonic phrase", + "chooseMethod": "Choose your import method:", + "fromKeys": "From keys", + "fromFile": "From a file", + "fromMnemonic": "From a mnemonic phrase", + "fromQr": "From a QR code" + }, + "termsOfUsePage": { + "title": "Terms of use", + "subtitle": "Please read them carefully." + }, + "privacyPolicyPage": { + "title": "Privacy Policy", + "subtitle": "Please read them carefully." + }, + "importFromFilePage": { + "title": "Importing wallet from a backup file", + "subtitle": "Use your backup file to create a wallet", + "walletBlock": { + "title": "Wallet file", + "label": "Select the file", + "importButton": "Import" + } + }, + "importFromMnemonicPage": { + "title": "Importing wallet from a mnemonic phrase", + "subtitle": "Use your phrase to create a wallet", + "mnemonicBlock": { + "title": "Mnemonic phrase", + "mnemonic": { + "label": "Mnemonic phrase: 25 words", + "invalid": "The mnemonic phrase is invalid", + "language": "Language" + }, + "importButton": "Import" + } + }, + "importFromKeysPage": { + "title": "Importing wallet from keys", + "subtitle": "Use your keys to create a wallet", + "parametersBlock": { + "viewOnlyWallet": { + "label": "Do you want a view only wallet?" + } + }, + "keysBlock": { + "titleNotViewOnly": "Wallet keys", + "titleViewOnly": "View only wallet", + "privateSpend": { + "label": "Private spend key" + }, + "privateView": { + "label": "Private view key", + "optional": "(optional)" + }, + "publicKey": { + "label": "Public key" + }, + "importButton": "Import" + } + } + }, + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": true + } + } +} diff --git a/src/translations/hi.json b/src/translations/hi.json new file mode 100644 index 00000000..81d04c39 --- /dev/null +++ b/src/translations/hi.json @@ -0,0 +1,539 @@ +{ + "website": { + "title": "Qwertycoin वॉलेट | सरल, सहज, सुरक्षित। आने वाला कल आपका स्वागत करता है।", + "description": "Qwertycoin मुद्रा के लिए आधिकारिक ऑनलाइन वॉलेट - इष्टतम सुरक्षा के लिए पूरी तरह से आपके ब्राउज़र में संभाला जाता है" + }, + "messages": { + "menu": { + "home": "होम", + "account": "लेखा", + "send": "भेजना", + "receive": "प्राप्त करना", + "export": "निर्यात", + "donate": "दान करना", + "elections": "चुनाव", + "contacts": "संपर्क", + "settings": "सेटिंग्स", + "disconnect": "डिस्कनेक्ट", + "network": "नेटवर्क आँकड़े", + "mining": "खनिज" + }, + "global": { + "loading": "Loading", + "disableSecurity": "Disable this security, I understand the risk", + "passwordInvalidRequirements": "The password needs at least 8 characters - 1 upper case letter, 1 lower case letter, one number, and one special character", + "passwordConfirmationNotMatching": "The password does not match the first password you wrote", + "download": "Download", + "newVersionModal": { + "title": "A new version is available", + "content": "Do you want to reload to load the new version?", + "confirmText": "Yes", + "cancelText": "Back" + }, + "openWalletModal": { + "title": "Wallet Password", + "confirmText": "Open", + "cancelText": "Cancel" + }, + "invalidPasswordModal": { + "title": "Oops...", + "content": "Your password seems invalid", + "confirmText": "OK" + }, + "invalidMnemonicModal": { + "title": "Oops...", + "content": "The mnemonic phrase is invalid", + "confirmText": "OK" + }, + "passwordNotComplexEnoughModal": { + "title": "The password is not complex enough", + "confirmText": "OK" + }, + "permissionRequiredForCameraModal": { + "title": "Oops...", + "content": "The permission to access your camera is required to scan the QR code", + "confirmText": "OK" + } + }, + "bottom": { + "termsOfUse": "Terms of Use", + "privacyPolicy": "Privacy Policy", + "support": "Support", + "donate": "Donate", + "network": "Network Stats", + "miningPool": "Mining Pool", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Qwertycoin Wallet", + "tagLine": "anywhere. anytime. anyplace. any device.", + "tagLineTwo": "The simplest way to use Qwertycoin", + "actions": { + "loadWallet": "Load my wallet", + "importWallet": "Import a wallet", + "create": "Create", + "createWallet": "Create a wallet" + } + }, + "accountPage": { + "title": "Account", + "subtitle": "Your account overview and transaction history", + "synchronizingBlock": { + "text": "Synchronizing..." + }, + "balanceBlock": { + "title": "Your balance", + "unlocked": "Unlocked" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Transaction history", + "pendingTxStatus": "Pending", + "emptyWallet": "You currently have no funds in this wallet.", + "waitSync": "Please wait until the wallet is updated", + "beReallyPatient": "The initial setup can take some time...", + "getCoinAddress": "Receive QWC" + }, + "txDetails": { + "title": "Transaction details", + "txHash": "Transaction Hash", + "feesOnTx": "Transaction fee", + "blockHeight": "Block height", + "paymentId": "Payment ID", + "unlockStatus": "Status", + "unlockConfirm": "Confirmations", + "txPrivKey": "Transaction Private Key" + } + }, + "changeWalletPasswordPage": { + "title": "Change your password", + "oldPassword": { + "label": "Old password", + "invalid": "The password is invalid" + }, + "newPassword": { + "label": "Choose a new password to protect your wallet" + }, + "newPasswordConfirm": { + "label": "Confirm the new password" + }, + "confirm": "Change the password", + "modalSuccess": { + "title": "Password changed!", + "confirmText": "OK" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "संपर्क" + }, + "electionsPage": { + "title": "चुनाव" + }, + "createWalletPage": { + "generatingStep": { + "title": "Your wallet is being generated...", + "subtitle": "It's almost done", + "waitingMessage": "Generating your wallet..." + }, + "finalizationStep": { + "title": "That was simple. Your account is ready!", + "subtitle": "Be ready to use Qwertycoin like you never have", + "passwordSelectionBlock": { + "label": "Protect your wallet" + }, + "passwordConfirmBlock": { + "label": "Confirm the password" + }, + "validPassword": "Use this password", + "backupBlock": { + "title": "Save your private credentials for recovery.", + "option1": "Option 1: ", + "option2": "Option 2: ", + "titlePdf": "Download a PDF copy", + "titleManualWrite": "Write down my keys", + "privateKeys": "Private key", + "mnemonicPhrase": "Mnemonic phrase", + "separatorManualMethodsSolution": " or ", + "confirmManuallyWritten": "I wrote my seed phrase down", + "warningMessage": "**Do not lose it!** It cannot be recovered if you lose it.
**Do not share it!** Your funds will be stolen if you use this file or seed on a malicious/phishing site.
**Make a backup!** Secure it like the millions of dollars it may one day be worth.
", + "finishButton": "I understand. Continue." + } + }, + "disclaimerBlock": { + "title": "Risk of Using QwertycoinWallet", + "content": "QwertycoinWallet is a web-based interface. It helps you use Qwertycoin without running a full Qwertycoin node.
We recommend you treat QwertycoinWallet like you will treat your actual wallet." + } + }, + "donatePage": { + "title": "Donate", + "subtitle": "Help to fund the development and pay the bills", + "webwalletBlock": { + "title": "Webwallet", + "content": "If you want to help to pay for the servers, to support new features development, and like this app, please consider a donation:

" + }, + "devFundBlock": { + "title": "Qwertycoin Dev fund", + "content": "To help Qwertycoin, you can donate at these addresses" + } + }, + "supportPage": { + "title": "Support", + "subtitle": "We are here to help!", + "getInTouchBlock": { + "title": "Let's Get In Touch!", + "content": "Do you have ideas or feedback that could help us improve the wallet? Contact us!", + "discord": "Qwertycoin Discord Channel" + } + }, + "networkPage": { + "title": "Network stats", + "subtitle": "Insights on the Qwertycoin network", + "statsBlock": { + "connectNode": "कनेक्टेड मास्टर्नोड", + "hashrate": "Network hashrate", + "height": "Blockchain height", + "difficulty": "Network difficulty", + "lastTimeBlock": "Last block found", + "lastReward": "Last block reward" + } + }, + "sendPage": { + "title": "Send QWC", + "sendBlock": { + "address": { + "label": "Destination address", + "placeholder": "Write the address where you want to send funds", + "invalid": "The destination address is invalid", + "fundsTo": "The funds will be sent to", + "receiver": "Receiver", + "description": "Description" + }, + "amount": { + "label": "Amount to send", + "invalid": "The amount is invalid" + }, + "paymentId": { + "label": "Payment ID (optional)", + "invalid": "The payment ID is invalid. The length must be 16 or 64 characters" + }, + "sendButton": "Send", + "cancelButton": "Cancel" + }, + "qrCodeScanning": { + "explication": "Present the QR code" + }, + "notEnoughMoneyModal": { + "title": "Oops...", + "content": "You don't have enough funds in your wallet to execute this transfer", + "confirmText": "OK" + }, + "thankYouDonationModal": { + "title": "Thank you for your donation!", + "content": "Your help is appreciated. This donation will help make Qwertycoin better", + "confirmText": "OK" + }, + "transferSentModal": { + "title": "Transfer sent successfully!", + "confirmText": "OK" + }, + "transferExceptionModal": { + "title": "Oops...", + "content": "An error occurred. Please report this error: {details}", + "confirmText": "OK" + }, + "invalidAmountModal": { + "title": "Oops...", + "content": "Invalid amount", + "confirmText": "OK" + }, + "creatingTransferModal": { + "title": "Creating transfer ...", + "content": "Please wait..." + }, + "finalizingTransferModal": { + "title": "Finalizing transfer ...", + "content": "Please wait..." + }, + "confirmTransactionModal": { + "title": "Confirm transfer?", + "content": "Amount: {amount}
Fees: {fees}
Total: {total}", + "confirmText": "Confirm", + "cancelText": "Cancel" + }, + "waitingNfcModal": { + "title": "Waiting Nfc", + "content": "Bring closer to the other device" + } + }, + "receivePage": { + "title": "Receive QWC", + "receiveBlock": { + "address": { + "title": "Your address to receive funds:", + "label": "Give this address to receive funds" + }, + "qrCode": { + "title": "Or personalize the QR code:", + "labelAmount": "Amount (optional)", + "labelRecipient": "Recipient name (optional)", + "labelDescription": "Transaction description (optional)", + "updateButton": "Update" + } + }, + "qrBlock": { + "title": "Your customized QR code" + }, + "waitingNfcToWriteModal": { + "title": "Waiting Nfc", + "titleSuccess": "Nfc Tag written", + "content": "Bring closer the NFC tag to write" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Tag capacity insufficient" + } + }, + "miningPage": { + "title": "Mine directly in your browser", + "subtitle": "Support the network by mining and be rewarded with QWC", + "parameterBlock": { + "title": "Parameters", + "labelDestinationAddress": "Wallet to mine", + "labelThreads": "Number of threads (more = higher hashrate)", + "start": "Start", + "stop": "Stop" + }, + "statisticsBlocks": { + "title": "Statistics", + "validShares": "Valid shares", + "hashrate": "Hashrate", + "maxHashrate": "Max Hashrate", + "dedicatedHardware": "With dedicating mining software and hardware, you could earn more and help decentralize the network.", + "miningHandledBy": "This mining is handled by the mining pool pool.qwertycoin.org" + } + }, + "settingsPage": { + "title": "Settings", + "subtitle": "Change your parameters here", + "versionBlock": { + "versionNumber": "Version number: ", + "versionCode": "Version code: " + }, + "settingsBlock": { + "speed": { + "label": "Speed to update the wallet (will consume more resources)", + "fastest": "Fastest", + "fast": "Fast", + "medium": "Medium", + "slow": "Slow" + }, + "language": { + "label": "Language" + }, + "currency": { + "label": "राष्ट्रीय मुद्रा" + }, + "readMinerTx": { + "label": "Read miner transactions (only for solo mining)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Change my wallet password", + "deleteWalletButton": "Delete my wallet (local copy)", + "walletSettings": { + "creationHeight": { + "label": "Creation height of the wallet" + }, + "currentScanningHeight": { + "label": "Current scanning height" + }, + "updateButton": "Update" + }, + "deleteWalletModal": { + "title": "Delete My Wallet (local copy)", + "content": "Are you sure you REALLY want to delete your wallet ?", + "confirmText": "Yes I'm sure", + "cancelText": "Cancel" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Parameters", + "password": { + "label": "Password to protect your wallet" + }, + "passwordConfirm": { + "label": "Confirm the password", + "invalid": "The password does not match the first password you wrote" + }, + "importHeight": { + "label": "Height to import from:" + } + } + }, + "importFromQrPage": { + "title": "Importing wallet from a QR code", + "subtitle": "Import a wallet from an offline backup", + "qrCodeBlock": { + "title": "QR code", + "startScanButton": "Start the scan", + "importButton": "Import" + }, + "qrScanningBlock": { + "title": "Present the QR code" + } + }, + "exportPage": { + "title": "Backup your credentials", + "publicAddressBlock": { + "title": "Your public address" + }, + "pdfBlock": { + "title": "PDF Backup", + "downloadButton": "Download" + }, + "warningBlock": { + "title": "Warning", + "content": "If you choose to save your private keys or your mnemonic phrase, PLEASE DO NOT store them in clear-text for your own safety.
The file is an alternate solution where your keys are encrypted and contains a backup of all your transactions to spare you a future synchronisation." + }, + "exportBlock": { + "title": "Export your RAW credentials", + "privateKeysButton": "Get my private keys", + "mnemonicKeysButton": "Get my mnemonic phrase", + "fileButton": "Export to a file" + }, + "walletKeysModal": { + "title": "Private keys", + "confirmText": "OK", + "content": "Please carefully store these keys. Possessing them means possessing the funds associated !
Spend key: {privSpendKey}
Private view key: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Mnemonic phrase", + "confirmText": "OK", + "content": "Please store carefully this mnemonic phrase. Possessing it means possessing the funds associated ! The phrase is:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "In which language do you want your mnemonic phrase?", + "confirmText": "Export" + } + }, + "importPage": { + "title": "Create a wallet", + "subtitle": "From previously created keys, file, or mnemonic phrase", + "chooseMethod": "Choose your import method:", + "fromKeys": "From keys", + "fromFile": "From a file", + "fromMnemonic": "From a mnemonic phrase", + "fromQr": "From a QR code" + }, + "termsOfUsePage": { + "title": "Terms of use", + "subtitle": "Please read them carefully." + }, + "privacyPolicyPage": { + "title": "Privacy Policy", + "subtitle": "Please read them carefully." + }, + "importFromFilePage": { + "title": "Importing wallet from a backup file", + "subtitle": "Use your backup file to create a wallet", + "walletBlock": { + "title": "Wallet file", + "label": "Select the file", + "importButton": "Import" + } + }, + "importFromMnemonicPage": { + "title": "Importing wallet from a mnemonic phrase", + "subtitle": "Use your phrase to create a wallet", + "mnemonicBlock": { + "title": "Mnemonic phrase", + "mnemonic": { + "label": "Mnemonic phrase: 25 words", + "invalid": "The mnemonic phrase is invalid", + "language": "Language" + }, + "importButton": "Import" + } + }, + "importFromKeysPage": { + "title": "Importing wallet from keys", + "subtitle": "Use your keys to create a wallet", + "parametersBlock": { + "viewOnlyWallet": { + "label": "Do you want a view only wallet?" + } + }, + "keysBlock": { + "titleNotViewOnly": "Wallet keys", + "titleViewOnly": "View only wallet", + "privateSpend": { + "label": "Private spend key" + }, + "privateView": { + "label": "Private view key", + "optional": "(optional)" + }, + "publicKey": { + "label": "Public key" + }, + "importButton": "Import" + } + } + }, + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": true + } + } +} diff --git a/src/translations/hu.json b/src/translations/hu.json index a8e9593e..c257fa1c 100644 --- a/src/translations/hu.json +++ b/src/translations/hu.json @@ -1,495 +1,539 @@ { - "website":{ - "title":"Hivatalos Karbo webtárca", - "description":"A Karbo hivatalos online tárcája - névtelen, biztonságos és teljes mértékben böngészőből kezelt az optimális biztonság érdekében" + "website": { + "title": "Hivatalos Qwertycoin webtárca", + "description": "A Qwertycoin hivatalos online tárcája - névtelen, biztonságos és teljes mértékben böngészőből kezelt az optimális biztonság érdekében" }, "messages": { - "menu": { - "home": "Kezdőlap", - "account": "Számla", - "send": "Küldés", - "receive": "Fogadás", - "export": "Exportálás", - "donate": "Adományozás", - "settings": "Beállítások", - "disconnect": "Szétkapcsolás", - "network": "Hálózati statisztika", - "mining": "Bányászás" - }, - "global": { - "loading": "Betöltés", - "disableSecurity":"Biztonság kikapcsolása, megértettem a kockázatot", - "passwordInvalidRequirements":"A jelszónak legalább 8 karakterből kell állnia és tartalmaznia kell egy nagybetűt, egy kisbetűt, egy számot és egy különleges karaktert", - "passwordConfirmationNotMatching":"A megadott jelszavak nem egyeznek", - "download":"Letöltés", - "newVersionModal":{ - "title":"Elérhető egy új verzió", - "content":"Szeretnéd újratölteni az oldalt az új verzió használatához?", - "confirmText":"Igen", - "cancelText":"Vissza" - }, - "openWalletModal":{ - "title":"Tárca jelszava", - "confirmText":"Megnyitás", - "cancelText":"Mégsem" - }, - "invalidPasswordModal":{ - "title":"Hupsz...", - "content":"Érvénytelen jelszó", - "confirmText":"OK" - }, - "invalidMnemonicModal":{ - "title":"Hupsz...", - "content":"Érvénytelen mnemonikus szósor", - "confirmText":"OK" - }, - "passwordNotComplexEnoughModal":{ - "title":"A jelszó nem elég összetett", - "confirmText":"OK" - }, - "permissionRequiredForCameraModal":{ - "title":"Hupsz...", - "content":"A kamerához való hozzáférés szükséges a QR-kód beolvasásához", - "confirmText":"OK" - } - }, - "bottom": { - "termsOfUse": "Felhasználási feltételek", - "privacyPolicy": "Adatvédelmi irányelvek", - "support": "Ügyfélszolgálat", - "donate": "Adományozás", - "network": "Hálózati statisztika", - "miningPool": "Bányász pool", - "github": "GitHub" - }, - "homepage": { - "mainTitle": "Biztonságos Karbo tárca", - "tagLine": "A Karbo használatának legegyszerűbb módja - bárhol és bármikor", - "actions": { - "loadWallet": "Tárca betöltése", - "importWallet": "Tárcaimportálás", - "create": "Létrehozás", - "createWallet": "Tárca létrehozása" - }, - "notes": { - "secure": { - "title": "Biztonságos", - "description": "Nincsenek szerverek, teljesen titkosított!" - }, - "fast": { - "title": "Gyors", - "description": "Küldj bárhonnan, bármikor!" - }, - "technology": { - "title": "Egyedi technológia", - "description": "Közvetlen kapcsolat a Karbo blokklánccal!" - }, - "openSource": { - "title": "Teljesen nyílt forrású", - "description": "Elérhető a Githubon!" - } - } - }, - "accountPage": { - "title": "Számla", - "subtitle": "Számlaáttekintés és tranzakciós előzmények", - "synchronizingBlock": { - "text": "Szinkronizálás..." - }, - "balanceBlock": { - "title": "Egyenleg", - "unlocked": "Feloldva" - }, - "historyBlock": { - "title": "Tranzakciós előzmények", - "pendingTxStatus": "Függőben", - "emptyWallet": "Jelenleg nincsen egyenleged ebben a tárcában.", - "waitSync": "Kérlek, várj, míg a tárca naprakész lesz", - "beReallyPatient": "A kezdeti beállítás némi időbe telhet...", - "getCoinAddress": "KRB fogadása" - }, - "txDetails":{ - "title":"Tranzakciórészletek", - "txHash":"Tranzakció hash", - "feesOnTx":"Tranzakció díjai", - "blockHeight":"Blokk", - "paymentId":"Fizetési azonosító", - "txPrivKey":"Tranzakció magánkulcs" - } - }, - "changeWalletPasswordPage":{ - "title":"Jelszómódosítás", - "oldPassword":{ - "label":"Régi jelszó", - "invalid":"Érvénytelen jelszó" - }, - "newPassword":{ - "label":"Válassz új jelszót" - }, - "newPasswordConfirm":{ - "label":"Ismételd meg az új jelszót" - }, - "confirm":"Jelszómódosítás", - "modalSuccess":{ - "title":"Jelszó módosítva!", - "confirmText":"OK" - } - }, - "createWalletPage":{ - "generatingStep":{ - "title":"A tárcád létrehozása folyamatban...", - "subtitle":"Majdnem kész", - "waitingMessage":"Tárcád létrehozása..." - }, - "finalizationStep":{ - "title":"Ez egyszerű volt. A számlád rendelkezésre áll!", - "subtitle":"Állj készen a Karbo használatára", - "passwordSelectionBlock":{ - "label":"Védd a tárcád" - }, - "passwordConfirmBlock":{ - "label":"Erősítsd meg a jelszót" - }, - "validPassword":"Megadott jelszó használata", - "backupBlock":{ - "title":"Mentsd el a visszaállításra szolgáló privát adataidat.", - "option1":"1. ", - "option2":"2. ", - "titlePdf":"lehetőség: másolat letöltése PDF-ben", - "titleManualWrite":"lehetőség: kulcsok lejegyzése", - "privateKeys":"Privát kulcs", - "mnemonicPhrase":"Mnemonikus szósor", - "separatorManualMethodsSolution":" vagy ", - "confirmManuallyWritten":"Lejegyeztem", - "warningMessage":"**Ne veszítsd el!** Ha elveszted, nem lehet visszaállítani.
**Ne oszd meg!** Pénzedet ellophatják, ha ezt a fájlt megosztod mással, esetleg rosszindulatú, adathalász oldalon közzéteszed.
**Készíts biztonsági másolatot!** Tartsd úgy biztonságban, mint a több millió dollárt, amit egyszer érhet.
", - "finishButton":"Megértettem. Tovább." - } - }, - "disclaimerBlock":{ - "title":"A MasariWallet használatának kockázatai", - "content":"A KarboWallet egy webes felület, mely lehetővé teszi a Karbo használatát teljes csomópont futtatása nélkül.
Kezeld úgy a KarboWalletet, mintha az a valódi pénztárcád lenne." - } - }, - "donatePage":{ - "title":"Adományozás", - "subtitle":"Segíts a fejlesztés finanszírozásában és a számlák kifizetésében", - "webwalletBlock":{ - "title":"Webtárca", - "content":"A webtárcát Gnock fejleszti szabadidejében.
Ha szeretnéd segíteni a fejlesztést, a szerverek fizetését és tetszik az applikáció, úgy vedd fontolóra az adományozást:

" - }, - "devFundBlock":{ - "title":"Karbo fejlesztési alap", - "content":"Ha szeretnél segíteni a Karbonak, az alábbi címekre adományozhatsz" - } - }, - "supportPage":{ - "title":"Ügyfélszolgálat", - "subtitle":"Itt vagyunk, hogy segítsünk!", - "getInTouchBlock":{ - "title":"Lépjünk kapcsolatba!", - "content":"Visszajelzésed vagy ötleted van a tárcával kapcsolatban? Keress fel bennünket!", - "discord":"Karbo Discord-csatorna" - } - }, - "networkPage":{ - "title":"Hálózati statisztika", - "subtitle":"Betekintés a Karbo hálózatába", - "statsBlock":{ - "hashrate":"Hálózati hashrate", - "height":"Blokklánc hossza", - "difficulty":"Hálózati nehézség", - "lastTimeBlock":"Utolsó blokk ideje", - "lastReward":"Utolsó blokk jutalma" - } - }, - "sendPage":{ - "title":"KRB küldése", - "sendBlock":{ - "address":{ - "label":"Kedvezményezett címe", - "placeholder":"Írja be azt a címet, ahová pénzt szeretne küldeni", - "invalid":"A kedvezményezett címe érvénytelen", - "fundsTo":"A pénz ide kerül küldésre:", - "receiver":"Fogadás", - "description":"Leírás" - }, - "amount":{ - "label":"Küldendő mennyiség", - "invalid":"Érvénytelen mennyiség" - }, - "paymentId":{ - "label":"Fizetési azonosító (opcionális)", - "invalid":"Érvénytelen fizetési azonosító. Hosszának 16 vagy 64 karakternek kell lennie" - }, - "sendButton":"Küldés", - "cancelButton":"Mégsem" - }, - "qrCodeScanning":{ - "explication":"Mutasd be a QR-kódot" - }, - "notEnoughMoneyModal":{ - "title":"Hupsz...", - "content":"Egyenleged nem elegendő a tranzakció végrehajtásához", - "confirmText":"OK" - }, - "thankYouDonationModal":{ - "title":"Köszönjük az adományt!", - "content":"Értékeljük a segítséged.
Ez az adomány is segít jobbá tenni a Karbot.", - "confirmText":"OK" - }, - "transferSentModal":{ - "title":"Sikeres tranzakció!", - "confirmText":"OK" - }, - "transferExceptionModal":{ - "title":"Hupsz...", - "content":"Hiba történt. Kérlek, jelentsd az alábbi hibát: {details}", - "confirmText":"OK" - }, - "invalidAmountModal":{ - "title":"Hupsz...", - "content":"Érvénytelen mennyiség", - "confirmText":"OK" - }, - "creatingTransferModal":{ - "title":"Tranzakció létrehozása...", - "content":"Kérlek, várj..." - }, - "finalizingTransferModal":{ - "title":"Tranzakció véglegesítése...", - "content":"Kérlek, várj..." - }, - "confirmTransactionModal":{ - "title":"Megerősíted a tranzakciót?", - "content":"Mennyiség: {amount}
Díj: {fees}
Összesen: {total}", - "confirmText":"Megerősítés", - "cancelText":"Mégsem" - }, - "waitingNfcModal":{ - "title":"Waiting Nfc", - "content":"Bring closer to the other device" - } - }, - "receivePage":{ - "title":"KRB fogadása", - "receiveBlock":{ - "address":{ - "title":"Pénz fogadására szolgáló cím:", - "label":"Pénz fogadásához ezt a címet add meg" - }, - "qrCode":{ - "title":"Vagy használj egyéni QR-kódot", - "labelAmount":"Mennyiség (opcionális)", - "labelRecipient":"Kedvezményezett neve (opcionális)", - "labelDescription":"Tranzakció leírása (opcionális)", - "updateButton":"Frissítés" - } - }, - "qrBlock":{ - "title":"Egyéni QR-kód" - }, - "waitingNfcToWriteModal":{ - "title":"Waiting Nfc", - "titleSuccess":"Nfc Tag written", - "content":"Bring closer the NFC tag to write" - }, - "nfcErrorModal":{ - "titleInsufficientCapacity":"Tag capacity insufficient" - } - }, - "miningPage":{ - "title":"Bányássz közvetlenül böngészőből", - "subtitle":"Támogasd a hálózatot a bányászással és szerezz érte jutalmat Karboban", - "parameterBlock":{ - "title":"Paraméterek", - "labelDestinationAddress":"Céltárca", - "labelThreads":"Szálak száma (több = nagyobb hashrate)", - "start":"Indítás", - "stop":"Megállítás" - }, - "statisticsBlocks":{ - "title":"Statisztika", - "validShares":"Érvényes részesedés", - "hashrate":"Hashrate", - "maxHashrate":"Maximális hashrate", - "dedicatedHardware":"Bányászásra dedikált szoftver és hardver használatával nagyobb bevételre tehetsz szert és segíthetsz a hálózat decentralizálásában.", - "miningHandledBy":"Ezt a bányászást a get.masaricoin.com pool kezeli" - } - }, - "settingsPage":{ - "title":"Beállítások", - "subtitle":"Módosítsd a beállításaidat", - "versionBlock":{ - "versionNumber":"Version number: ", - "versionCode":"Version code: " - }, - "settingsBlock":{ - "speed":{ - "label":"Tárcafrissítés sebessége (több erőforrást igényel)", - "fastest":"Leggyorsabb", - "fast":"Gyors", - "medium":"Közepes", - "slow":"Lassú" - }, - "language":{ - "label":"Language" - }, - "readMinerTx":{ - "label":"Bányászási tranzakciók beolvasása (csak egyedülálló bányászás esetén)" - } - }, - "changePasswordButton":"Jelszómódosítás", - "deleteWalletButton":"Tárca törlése (helyi másolat)", - "walletSettings":{ - "creationHeight":{ - "label":"Tárcalétrehozási blokklánchossz" - }, - "currentScanningHeight": { - "label": "Jelenlegi beolvasási hossz" - }, - "updateButton":"Frissítés" - }, - "deleteWalletModal":{ - "title":"Tárca törlése (helyi másolat)", - "content":"Biztosan törölni szeretnéd a tárcádat?", - "confirmText":"Igen, biztosan", - "cancelText":"Mégsem" - } - }, - "importBasePage":{ - "parametersBlock":{ - "title":"Paraméterek", - "password":{ - "label":"Tárcajelszó" - }, - "passwordConfirm":{ - "label":"Jelszó megerősítése", - "invalid":"A jelszavak nem egyeznek" - }, - "importHeight":{ - "label":"Importálási blokklánchossz:" - } - } - }, - "importFromQrPage":{ - "title":"Tárca importálása QR-kóddal", - "subtitle":"Tárca importálása offline biztonsági mentésből", - "qrCodeBlock":{ - "title":"QR-kód", - "startScanButton":"Beolvasás", - "importButton":"Importálás" - }, - "qrScanningBlock":{ - "title":"Mutasd be a QR-kódot" - } - }, - "exportPage":{ - "title":"Készíts biztonsági mentést az adataidról", - "publicAddressBlock":{ - "title":"Nyilvános tárcacím" - }, - "pdfBlock":{ - "title":"Biztonsági mentés PDF-ben", - "downloadButton":"Letöltés" - }, - "warningBlock":{ - "title":"Figyelmeztetés", - "content":"Ha a privát kulcsaid vagy a mnemonikus szósorod mentését választod, úgy saját biztonságod érdekében ne tárold azokat egyszerű szövegként.
A fájl egy alternatív megoldásként szolgál, ez esetben a kulcsaid titkosítottak és tartalmazza a tranzakciód biztonsági mentését is, így megkímél egy jövőbeli szinkronizálástól." - }, - "exportBlock":{ - "title":"Nyers adatok exportálása", - "privateKeysButton":"Privát kulcsok beszerzése", - "mnemonicKeysButton":"Mnemonikus szósor beszerzése", - "fileButton":"Exportálás fájlba" - }, - "walletKeysModal":{ - "title":"Privát kulcsok", - "confirmText":"OK", - "content":"Kérlek, gondosan tárold a kulcsokat. Birtoklása a hozzá tartozó pénzösszeg birtoklását is jelenti.!
Privát költőkulcs: {privSpendKey}
Privát figyelőkulcs: {privViewKey}" - }, - "mnemonicKeyModal":{ - "title":"Mnemonikus szósor", - "confirmText":"OK", - "content":"Kérlek, gondosan tárold a mnemonikus szósort. Birtoklása a hozzá tartozó pénzösszeg birtoklását is jelenti.! A szósor:
{mnemonic}" - }, - "mnemonicLangSelectionModal":{ - "title":"Milyen nyelven kéred a mnemonikus szósorod?", - "confirmText":"Exportálás" - } - }, - "importPage":{ - "title":"Tárca létrehozása", - "subtitle":"Korábban létrehozott kulcsokkal, fájllal vagy mnemonikus szósorral", - "chooseMethod":"Válassz importálási módszert:", - "fromKeys":"Kulcsok", - "fromFile":"Fájl", - "fromMnemonic":"Mnemonikus szósor", - "fromQr":"QR-kód" - }, - "termsOfUsePage":{ - "title":"Felhasználási feltételek", - "subtitle":"Kérlek, alaposan olvasd el." - }, - "privacyPolicyPage":{ - "title":"Privacy Policy", - "subtitle":"Kérlek, alaposan olvasd el." - }, - "importFromFilePage":{ - "title":"Tárca importálása biztonsági mentési fájllal", - "subtitle":"Használd a biztonsági mentési fájlod a tárca létrehozásához", - "walletBlock":{ - "title":"Tárcafájl", - "label":"Tallózás", - "importButton":"Importálás" - } - }, - "importFromMnemonicPage":{ - "title":"Tárca importálása mnemonikus szósorral", - "subtitle":"Használd a szósorodat a tárca létrehozásához", - "mnemonicBlock":{ - "title":"Mnemonikus szósor", - "mnemonic":{ - "label":"Mnemonikus szósor: 25 szó", - "invalid":"Érvénytelen mnemonikus szósor", - "language":"Nyelv" - }, - "importButton":"Importálás" - } - }, - "importFromKeysPage":{ - "title":"Tárca importálása kulcsokkal", - "subtitle":"Használd a kulcsaidat a tárca létrehozásához", - "parametersBlock":{ - "viewOnlyWallet":{ - "label":"Csak megtekinthető (view only) tárcát szeretnél?" - } - }, - "keysBlock":{ - "titleNotViewOnly":"Tárcakulcsok", - "titleViewOnly":"sak megtekinthető tárca", - "privateSpend":{ - "label":"Privát költőkulcs" - }, - "privateView":{ - "label":"Privát figyelőkulcs", - "optional":"(opcionális)" - }, - "publicKey":{ - "label":"Nyilvános kulcs" - }, - "importButton":"Importálás" - } - } + "menu": { + "home": "Kezdőlap", + "account": "Számla", + "send": "Küldés", + "receive": "Fogadás", + "export": "Exportálás", + "donate": "Adományozás", + "elections": "Választások", + "contacts": "Kapcsolatok", + "settings": "Beállítások", + "disconnect": "Szétkapcsolás", + "network": "Hálózati statisztika", + "mining": "Bányászás" + }, + "global": { + "loading": "Betöltés", + "disableSecurity": "Biztonság kikapcsolása, megértettem a kockázatot", + "passwordInvalidRequirements": "A jelszónak legalább 8 karakterből kell állnia és tartalmaznia kell egy nagybetűt, egy kisbetűt, egy számot és egy különleges karaktert", + "passwordConfirmationNotMatching": "A megadott jelszavak nem egyeznek", + "download": "Letöltés", + "newVersionModal": { + "title": "Elérhető egy új verzió", + "content": "Szeretnéd újratölteni az oldalt az új verzió használatához?", + "confirmText": "Igen", + "cancelText": "Vissza" + }, + "openWalletModal": { + "title": "Tárca jelszava", + "confirmText": "Megnyitás", + "cancelText": "Mégsem" + }, + "invalidPasswordModal": { + "title": "Hupsz...", + "content": "Érvénytelen jelszó", + "confirmText": "OK" + }, + "invalidMnemonicModal": { + "title": "Hupsz...", + "content": "Érvénytelen mnemonikus szósor", + "confirmText": "OK" + }, + "passwordNotComplexEnoughModal": { + "title": "A jelszó nem elég összetett", + "confirmText": "OK" + }, + "permissionRequiredForCameraModal": { + "title": "Hupsz...", + "content": "A kamerához való hozzáférés szükséges a QR-kód beolvasásához", + "confirmText": "OK" + } + }, + "bottom": { + "termsOfUse": "Felhasználási feltételek", + "privacyPolicy": "Adatvédelmi irányelvek", + "support": "Ügyfélszolgálat", + "donate": "Adományozás", + "network": "Hálózati statisztika", + "miningPool": "Bányász pool", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Biztonságos Qwertycoin tárca", + "tagLine": "A Qwertycoin használatának legegyszerűbb módja - bárhol és bármikor", + "tagLineTwo": "A legegyszerűbb módja a Qwertycoin használatának", + "actions": { + "loadWallet": "Tárca betöltése", + "importWallet": "Tárcaimportálás", + "create": "Létrehozás", + "createWallet": "Tárca létrehozása" + } + }, + "accountPage": { + "title": "Számla", + "subtitle": "Számlaáttekintés és tranzakciós előzmények", + "synchronizingBlock": { + "text": "Szinkronizálás..." + }, + "balanceBlock": { + "title": "Egyenleg", + "unlocked": "Feloldva" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Tranzakciós előzmények", + "pendingTxStatus": "Függőben", + "emptyWallet": "Jelenleg nincsen egyenleged ebben a tárcában.", + "waitSync": "Kérlek, várj, míg a tárca naprakész lesz", + "beReallyPatient": "A kezdeti beállítás némi időbe telhet...", + "getCoinAddress": "QWC fogadása" + }, + "txDetails": { + "title": "Tranzakciórészletek", + "txHash": "Tranzakció hash", + "feesOnTx": "Tranzakció díjai", + "blockHeight": "Blokk", + "paymentId": "Fizetési azonosító", + "unlockStatus": "Status", + "unlockConfirm": "Confirmations", + "txPrivKey": "Tranzakció magánkulcs" + } + }, + "changeWalletPasswordPage": { + "title": "Jelszómódosítás", + "oldPassword": { + "label": "Régi jelszó", + "invalid": "Érvénytelen jelszó" + }, + "newPassword": { + "label": "Válassz új jelszót" + }, + "newPasswordConfirm": { + "label": "Ismételd meg az új jelszót" + }, + "confirm": "Jelszómódosítás", + "modalSuccess": { + "title": "Jelszó módosítva!", + "confirmText": "OK" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "Kapcsolatok" + }, + "electionsPage": { + "title": "Választások" + }, + "createWalletPage": { + "generatingStep": { + "title": "A tárcád létrehozása folyamatban...", + "subtitle": "Majdnem kész", + "waitingMessage": "Tárcád létrehozása..." + }, + "finalizationStep": { + "title": "Ez egyszerű volt. A számlád rendelkezésre áll!", + "subtitle": "Állj készen a Qwertycoin használatára", + "passwordSelectionBlock": { + "label": "Védd a tárcád" + }, + "passwordConfirmBlock": { + "label": "Erősítsd meg a jelszót" + }, + "validPassword": "Megadott jelszó használata", + "backupBlock": { + "title": "Mentsd el a visszaállításra szolgáló privát adataidat.", + "option1": "1. ", + "option2": "2. ", + "titlePdf": "lehetőség: másolat letöltése PDF-ben", + "titleManualWrite": "lehetőség: kulcsok lejegyzése", + "privateKeys": "Privát kulcs", + "mnemonicPhrase": "Mnemonikus szósor", + "separatorManualMethodsSolution": " vagy ", + "confirmManuallyWritten": "Lejegyeztem", + "warningMessage": "**Ne veszítsd el!** Ha elveszted, nem lehet visszaállítani.
**Ne oszd meg!** Pénzedet ellophatják, ha ezt a fájlt megosztod mással, esetleg rosszindulatú, adathalász oldalon közzéteszed.
**Készíts biztonsági másolatot!** Tartsd úgy biztonságban, mint a több millió dollárt, amit egyszer érhet.
", + "finishButton": "Megértettem. Tovább." + } + }, + "disclaimerBlock": { + "title": "A QwertycoinWallet használatának kockázatai", + "content": "A QwertycoinWallet egy webes felület, mely lehetővé teszi a Qwertycoin használatát teljes csomópont futtatása nélkül.
Kezeld úgy a QwertycoinWalletet, mintha az a valódi pénztárcád lenne." + } + }, + "donatePage": { + "title": "Adományozás", + "subtitle": "Segíts a fejlesztés finanszírozásában és a számlák kifizetésében", + "webwalletBlock": { + "title": "Webtárca", + "content": "A webtárcát Gnock fejleszti szabadidejében.
Ha szeretnéd segíteni a fejlesztést, a szerverek fizetését és tetszik az applikáció, úgy vedd fontolóra az adományozást:

" + }, + "devFundBlock": { + "title": "Qwertycoin fejlesztési alap", + "content": "Ha szeretnél segíteni a Qwertycoinnak, az alábbi címekre adományozhatsz" + } + }, + "supportPage": { + "title": "Ügyfélszolgálat", + "subtitle": "Itt vagyunk, hogy segítsünk!", + "getInTouchBlock": { + "title": "Lépjünk kapcsolatba!", + "content": "Visszajelzésed vagy ötleted van a tárcával kapcsolatban? Keress fel bennünket!", + "discord": "Qwertycoin Discord-csatorna" + } + }, + "networkPage": { + "title": "Hálózati statisztika", + "subtitle": "Betekintés a Qwertycoin hálózatába", + "statsBlock": { + "connectNode": "Csatlakoztatott Masternode", + "hashrate": "Hálózati hashrate", + "height": "Blokklánc hossza", + "difficulty": "Hálózati nehézség", + "lastTimeBlock": "Utolsó blokk ideje", + "lastReward": "Utolsó blokk jutalma" + } + }, + "sendPage": { + "title": "QWC küldése", + "sendBlock": { + "address": { + "label": "Kedvezményezett címe", + "placeholder": "Írja be azt a címet, ahová pénzt szeretne küldeni", + "invalid": "A kedvezményezett címe érvénytelen", + "fundsTo": "A pénz ide kerül küldésre:", + "receiver": "Fogadás", + "description": "Leírás" + }, + "amount": { + "label": "Küldendő mennyiség", + "invalid": "Érvénytelen mennyiség" + }, + "paymentId": { + "label": "Fizetési azonosító (opcionális)", + "invalid": "Érvénytelen fizetési azonosító. Hosszának 16 vagy 64 karakternek kell lennie" + }, + "sendButton": "Küldés", + "cancelButton": "Mégsem" + }, + "qrCodeScanning": { + "explication": "Mutasd be a QR-kódot" + }, + "notEnoughMoneyModal": { + "title": "Hupsz...", + "content": "Egyenleged nem elegendő a tranzakció végrehajtásához", + "confirmText": "OK" + }, + "thankYouDonationModal": { + "title": "Köszönjük az adományt!", + "content": "Értékeljük a segítséged.
Ez az adomány is segít jobbá tenni a Qwertycoint.", + "confirmText": "OK" + }, + "transferSentModal": { + "title": "Sikeres tranzakció!", + "confirmText": "OK" + }, + "transferExceptionModal": { + "title": "Hupsz...", + "content": "Hiba történt. Kérlek, jelentsd az alábbi hibát: {details}", + "confirmText": "OK" + }, + "invalidAmountModal": { + "title": "Hupsz...", + "content": "Érvénytelen mennyiség", + "confirmText": "OK" + }, + "creatingTransferModal": { + "title": "Tranzakció létrehozása...", + "content": "Kérlek, várj..." + }, + "finalizingTransferModal": { + "title": "Tranzakció véglegesítése...", + "content": "Kérlek, várj..." + }, + "confirmTransactionModal": { + "title": "Megerősíted a tranzakciót?", + "content": "Mennyiség: {amount}
Díj: {fees}
Összesen: {total}", + "confirmText": "Megerősítés", + "cancelText": "Mégsem" + }, + "waitingNfcModal": { + "title": "Waiting Nfc", + "content": "Bring closer to the other device" + } + }, + "receivePage": { + "title": "QWC fogadása", + "receiveBlock": { + "address": { + "title": "Pénz fogadására szolgáló cím:", + "label": "Pénz fogadásához ezt a címet add meg" + }, + "qrCode": { + "title": "Vagy használj egyéni QR-kódot", + "labelAmount": "Mennyiség (opcionális)", + "labelRecipient": "Kedvezményezett neve (opcionális)", + "labelDescription": "Tranzakció leírása (opcionális)", + "updateButton": "Frissítés" + } + }, + "qrBlock": { + "title": "Egyéni QR-kód" + }, + "waitingNfcToWriteModal": { + "title": "Waiting Nfc", + "titleSuccess": "Nfc Tag written", + "content": "Bring closer the NFC tag to write" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Tag capacity insufficient" + } + }, + "miningPage": { + "title": "Bányássz közvetlenül böngészőből", + "subtitle": "Támogasd a hálózatot a bányászással és szerezz érte jutalmat Qwertycoinban", + "parameterBlock": { + "title": "Paraméterek", + "labelDestinationAddress": "Céltárca", + "labelThreads": "Szálak száma (több = nagyobb hashrate)", + "start": "Indítás", + "stop": "Megállítás" + }, + "statisticsBlocks": { + "title": "Statisztika", + "validShares": "Érvényes részesedés", + "hashrate": "Hashrate", + "maxHashrate": "Maximális hashrate", + "dedicatedHardware": "Bányászásra dedikált szoftver és hardver használatával nagyobb bevételre tehetsz szert és segíthetsz a hálózat decentralizálásában.", + "miningHandledBy": "Ezt a bányászást a pool.qwertycoin.org pool kezeli" + } + }, + "settingsPage": { + "title": "Beállítások", + "subtitle": "Módosítsd a beállításaidat", + "versionBlock": { + "versionNumber": "Version number: ", + "versionCode": "Version code: " + }, + "settingsBlock": { + "speed": { + "label": "Tárcafrissítés sebessége (több erőforrást igényel)", + "fastest": "Leggyorsabb", + "fast": "Gyors", + "medium": "Közepes", + "slow": "Lassú" + }, + "language": { + "label": "Language" + }, + "currency": { + "label": "nemzeti valuta" + }, + "readMinerTx": { + "label": "Bányászási tranzakciók beolvasása (csak egyedülálló bányászás esetén)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Jelszómódosítás", + "deleteWalletButton": "Tárca törlése (helyi másolat)", + "walletSettings": { + "creationHeight": { + "label": "Tárcalétrehozási blokklánchossz" + }, + "currentScanningHeight": { + "label": "Jelenlegi beolvasási hossz" + }, + "updateButton": "Frissítés" + }, + "deleteWalletModal": { + "title": "Tárca törlése (helyi másolat)", + "content": "Biztosan törölni szeretnéd a tárcádat?", + "confirmText": "Igen, biztosan", + "cancelText": "Mégsem" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Paraméterek", + "password": { + "label": "Tárcajelszó" + }, + "passwordConfirm": { + "label": "Jelszó megerősítése", + "invalid": "A jelszavak nem egyeznek" + }, + "importHeight": { + "label": "Importálási blokklánchossz:" + } + } + }, + "importFromQrPage": { + "title": "Tárca importálása QR-kóddal", + "subtitle": "Tárca importálása offline biztonsági mentésből", + "qrCodeBlock": { + "title": "QR-kód", + "startScanButton": "Beolvasás", + "importButton": "Importálás" + }, + "qrScanningBlock": { + "title": "Mutasd be a QR-kódot" + } + }, + "exportPage": { + "title": "Készíts biztonsági mentést az adataidról", + "publicAddressBlock": { + "title": "Nyilvános tárcacím" + }, + "pdfBlock": { + "title": "Biztonsági mentés PDF-ben", + "downloadButton": "Letöltés" + }, + "warningBlock": { + "title": "Figyelmeztetés", + "content": "Ha a privát kulcsaid vagy a mnemonikus szósorod mentését választod, úgy saját biztonságod érdekében ne tárold azokat egyszerű szövegként.
A fájl egy alternatív megoldásként szolgál, ez esetben a kulcsaid titkosítottak és tartalmazza a tranzakciód biztonsági mentését is, így megkímél egy jövőbeli szinkronizálástól." + }, + "exportBlock": { + "title": "Nyers adatok exportálása", + "privateKeysButton": "Privát kulcsok beszerzése", + "mnemonicKeysButton": "Mnemonikus szósor beszerzése", + "fileButton": "Exportálás fájlba" + }, + "walletKeysModal": { + "title": "Privát kulcsok", + "confirmText": "OK", + "content": "Kérlek, gondosan tárold a kulcsokat. Birtoklása a hozzá tartozó pénzösszeg birtoklását is jelenti.!
Privát költőkulcs: {privSpendKey}
Privát figyelőkulcs: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Mnemonikus szósor", + "confirmText": "OK", + "content": "Kérlek, gondosan tárold a mnemonikus szósort. Birtoklása a hozzá tartozó pénzösszeg birtoklását is jelenti.! A szósor:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "Milyen nyelven kéred a mnemonikus szósorod?", + "confirmText": "Exportálás" + } + }, + "importPage": { + "title": "Tárca létrehozása", + "subtitle": "Korábban létrehozott kulcsokkal, fájllal vagy mnemonikus szósorral", + "chooseMethod": "Válassz importálási módszert:", + "fromKeys": "Kulcsok", + "fromFile": "Fájl", + "fromMnemonic": "Mnemonikus szósor", + "fromQr": "QR-kód" + }, + "termsOfUsePage": { + "title": "Felhasználási feltételek", + "subtitle": "Kérlek, alaposan olvasd el." + }, + "privacyPolicyPage": { + "title": "Privacy Policy", + "subtitle": "Kérlek, alaposan olvasd el." + }, + "importFromFilePage": { + "title": "Tárca importálása biztonsági mentési fájllal", + "subtitle": "Használd a biztonsági mentési fájlod a tárca létrehozásához", + "walletBlock": { + "title": "Tárcafájl", + "label": "Tallózás", + "importButton": "Importálás" + } + }, + "importFromMnemonicPage": { + "title": "Tárca importálása mnemonikus szósorral", + "subtitle": "Használd a szósorodat a tárca létrehozásához", + "mnemonicBlock": { + "title": "Mnemonikus szósor", + "mnemonic": { + "label": "Mnemonikus szósor: 25 szó", + "invalid": "Érvénytelen mnemonikus szósor", + "language": "Nyelv" + }, + "importButton": "Importálás" + } + }, + "importFromKeysPage": { + "title": "Tárca importálása kulcsokkal", + "subtitle": "Használd a kulcsaidat a tárca létrehozásához", + "parametersBlock": { + "viewOnlyWallet": { + "label": "Csak megtekinthető (view only) tárcát szeretnél?" + } + }, + "keysBlock": { + "titleNotViewOnly": "Tárcakulcsok", + "titleViewOnly": "sak megtekinthető tárca", + "privateSpend": { + "label": "Privát költőkulcs" + }, + "privateView": { + "label": "Privát figyelőkulcs", + "optional": "(opcionális)" + }, + "publicKey": { + "label": "Nyilvános kulcs" + }, + "importButton": "Importálás" + } + } }, - "number":{ - }, - "date":{ - "short": { - "year": "numeric", "month": "short", "day": "numeric" - }, - "long": { - "year": "numeric", "month": "short", "day": "numeric", - "weekday": "short", "hour": "numeric", "minute": "numeric", "hour12": false - } + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": false + } } } diff --git a/src/translations/it.json b/src/translations/it.json index 2277d0d7..bffd38d0 100644 --- a/src/translations/it.json +++ b/src/translations/it.json @@ -1,495 +1,538 @@ { - "website":{ - "title":"Portafoglio online ufficiale per Karbo", - "description":"Portafoglio online ufficiale per Karbo currency - anonimo, sicuro e completamente gestito nel tuo browser per una sicurezza ottimale" + "website": { + "title": "Portafoglio online ufficiale per Qwertycoin", + "description": "Portafoglio online ufficiale per Qwertycoin currency - anonimo, sicuro e completamente gestito nel tuo browser per una sicurezza ottimale" }, "messages": { - "menu": { - "home": "Home", - "account": "Account", - "send": "Invia", - "receive": "Ricevi", - "export": "Esporta", - "donate": "Dona", - "settings": "Impostazioni", - "disconnect": "Disconnetti", - "network": "Statistiche del network" - }, - "global": { - "loading": "Caricamento", - "disableSecurity":"Disabilita questa sicurezza, comprendo i rischi", - "passwordInvalidRequirements":"La password richiede almeno 8 caratteri: 1 lettera maiuscola, 1 lettera minuscola, un numero e un carattere speciale", - "passwordConfirmationNotMatching":"La password non corrisponde a quella precedentemente inserita", - "download":"Download", - "newVersionModal":{ - "title":"È disponibile una nuova versione", - "content":"Vuoi ricaricare la pagina per ottenere la nuova versione?", - "confirmText":"Si", - "cancelText":"Indietro" - }, - "openWalletModal":{ - "title":"Password portafoglio", - "confirmText":"Apri", - "cancelText":"Annulla" - }, - "invalidPasswordModal":{ - "title":"Oops...", - "content":"La tua password sembra invalida", - "confirmText":"Ok" - }, - "invalidMnemonicModal":{ - "title":"Oops...", - "content":"La frase mnemonica è invalida", - "confirmText":"Ok" - }, - "passwordNotComplexEnoughModal":{ - "title":"La password non è sufficientemente complessa", - "confirmText":"Ok" - }, - "permissionRequiredForCameraModal":{ - "title":"Oops...", - "content":"È necessario consentire l'accesso alla videocamera per eseguire la scansione del codice QR", - "confirmText":"Ok" - } - }, - "bottom": { - "termsOfUse": "Termini di utilizzo", - "privacyPolicy": "politica sulla riservatezza", - "support": "Supporto", - "donate": "Dona", - "network": "Statistiche del network", - "miningPool": "Mining Pool", - "github": "GitHub" - }, - "homepage": { - "mainTitle": "Portafoglio sicuro per Karbo", - "tagLine": "Il modo più semplice per usare Karbo - ovunque e in qualsiasi momento", - "actions": { - "loadWallet": "Carica il mio portafoglio", - "importWallet": "Importa un portafoglio", - "create": "Crea", - "createWallet": "Crea un portafoglio" - }, - "notes": { - "secure": { - "title": "Sicuro", - "description": "Nessun server, completamente crittografato!" - }, - "fast": { - "title": "Veloce", - "description": "Invia ovunque e in qualsiasi momento!" - }, - "technology": { - "title": "Tecnologia unica", - "description": "Collegato direttamente alla blockchain di Karbo!" - }, - "openSource": { - "title": "Completamente open-source", - "description": "Disponibile su Github!" - } - } - }, - "accountPage": { - "title": "Account", - "subtitle": "Panoramica del tuo account e cronologia delle transazioni", - "synchronizingBlock": { - "text": "Sincronizzazione... " - }, - "balanceBlock": { - "title": "Il tuo bilancio", - "unlocked": "Sbloccato" - }, - "historyBlock": { - "title": "Cronologia delle transazioni", - "pendingTxStatus": "In attesa", - "emptyWallet": "Al momento non disponi di fondi su questo portafoglio", - "waitSync": "Si prega di attendere la fine della sincronizzazione", - "beReallyPatient": "La prima sincronizzazione potrebbe richiedere alcuni minuti ...", - "getCoinAddress": "Ricevi MSR" - }, - "txDetails":{ - "title":"Dettagli transazione", - "txHash":"Tx hash", - "feesOnTx":"Commissione sulla Tx", - "blockHeight":"Altezza sulla blockchain", - "paymentId":"Payment ID", - "txPrivKey":"Chiave privata della transazione" - } - }, - "changeWalletPasswordPage":{ - "title":"Cambia la tua password", - "oldPassword":{ - "label":"Vecchia password", - "invalid":"La password è invalida" - }, - "newPassword":{ - "label":"Scegli una nuova password per proteggere il tuo portafoglio" - }, - "newPasswordConfirm":{ - "label":"Conferma la nuova password" - }, - "confirm":"Cambia la password", - "modalSuccess":{ - "title":"Password cambiata!", - "confirmText":"Ok" - } - }, - "createWalletPage":{ - "generatingStep":{ - "title":"Il tuo portafoglio sta per essere generato...", - "subtitle":"Mancano pochi istanti", - "waitingMessage":"Generazione del portafoglio..." - }, - "finalizationStep":{ - "title":"È stato semplice. Il tuo portafoglio è pronto!", - "subtitle":"Tenetevi pronti a usare Karbo come mai prima d'ora", - "passwordSelectionBlock":{ - "label":"Proteggi il tuo portafoglio" - }, - "passwordConfirmBlock":{ - "label":"Conferma la password" - }, - "validPassword":"Usa questa password", - "backupBlock":{ - "title":"Scarica una copia crittografata delle mie credenziali per uso futuro", - "option1":"Opzione 1: ", - "option2":"Opzione 2: ", - "titlePdf":"Scarica una copia PDF", - "titleManualWrite":"Scrivi le mie chiavi", - "privateKeys":"Chiavi private", - "mnemonicPhrase":"Frase mnemonica", - "separatorManualMethodsSolution":" o ", - "confirmManuallyWritten":"Li ho scritti", - "warningMessage":"**Non perderli!** È impossibile recuperarli se li perdi.
**Non condividerli!** I tuoi fondi potrebbero essere rubati se utilizzi queste informazioni su siti malevoli o di phishing.
**Crea un backup!** Proteggilo le tue credenziali come i milioni di dollari che un giorno potrebbe valere.
", - "finishButton":"Ho capito. Continua" - } - }, - "disclaimerBlock":{ - "title":"Rischi nell'usare KarboWallet", - "content":"KarboWallet è una interfaccia web-based. Ti aiuta ad usare Karbo senza eseguire un full node.
Vi consigliamo di trattare MaraiWallet come trattereste il vostro portafoglio attuale." - } - }, - "donatePage":{ - "title":"Dona", - "subtitle":"Aiutaci a finanziare lo sviluppo e a pagare le bollette", - "webwalletBlock":{ - "title":"Webwallet", - "content":"Questo webwallet è sviluppato da Gnock nel suo tempo libero.
Se vuoi aiutare lo sviluppo, aiutare a pagare server e ti piace questa applicazione, prendi in considerazione la possibilità di effettuare una piccola donazione.:

" - }, - "KarboFundBlock":{ - "title":"Fondo per lo sviluppo di Karbo", - "content":"Per aiutare Karbo puoi donare a questo indirizzo " - } - }, - "supportPage":{ - "title":"Support", - "subtitle":"Bisogno di aiuto? siamo qui per aiutarti!", - "getInTouchBlock":{ - "title":"Mettiamoci in contatto!", - "content":"Se hai idee o feedback per migliorare il portafoglio, contattaci!", - "discord":"Karbo Discord Channel" - } - }, - "networkPage":{ - "title":"Statistiche del network", - "subtitle":"Dettagli sul network Karbo", - "statsBlock":{ - "hashrate":"Network Hashrate", - "height":"Altezza blockchain", - "difficulty":"Difficoltà network", - "lastTimeBlock":"Ultimo blocco trovato", - "lastReward":"Ultima ricompensa" - } - }, - "sendPage":{ - "title":"Invia MSR", - "sendBlock":{ - "address":{ - "label":"Indirizzo di destinazione", - "placeholder":"Scrivi l'indirizzo nel quale vuoi inviare i fondi", - "invalid":"L'indirizzo di destinazione è errato", - "fundsTo":"I fondi verranno inviati a ", - "receiver":"Destinatario", - "description":"Descrizione" - }, - "amount":{ - "label":"Importo da inviare", - "invalid":"L'importo non è valido" - }, - "paymentId":{ - "label":"Payment ID (opzionale)", - "invalid":"Il Payment ID è invalido. La lunghezza deve essere di 16 o 64 caratteri" - }, - "sendButton":"Invia", - "cancelButton":"Annulla" - }, - "qrCodeScanning":{ - "explication":"Mostra il codice QR" - }, - "notEnoughMoneyModal":{ - "title":"Oops...", - "content":"Non hai abbastanza fondi nel tuo portafoglio per completare il trasferimento", - "confirmText":"Ok" - }, - "thankYouDonationModal":{ - "title":"Grazie per la tua donazione!", - "content":"Il tuo aiuto è molto apprezzato.
Questa donazione contribuirà a rendere Karbo ancora migliore", - "confirmText":"Ok" - }, - "transferSentModal":{ - "title":"Trasferimento inviato con successo!", - "confirmText":"Ok" - }, - "transferExceptionModal":{ - "title":"Oops...", - "content":"Si è verificato un errore. Si prega di segnalare questo errore: {details}", - "confirmText":"Ok" - }, - "invalidAmountModal":{ - "title":"Oops...", - "content":"Importo invalido", - "confirmText":"Ok" - }, - "creatingTransferModal":{ - "title":"Creazione del trasferimento...", - "content":"Per favore attendi..." - }, - "finalizingTransferModal":{ - "title":"Finalizzazione del trasferimento...", - "content":"Per favore attendi..." - }, - "confirmTransactionModal":{ - "title":"Confermare transferimento?", - "content":"Amount: {amount}
Fees: {fees}
Total: {total}", - "confirmText":"Conferma", - "cancelText":"Annulla" - }, - "waitingNfcModal":{ - "title":"Waiting Nfc", - "content":"Avvicinati di più all'altro device" - } - }, - "receivePage":{ - "title":"Ricevi MSR", - "receiveBlock":{ - "address":{ - "title":"Il tuo indirizzo per ricevere i fondi", - "label":"Dai questo indirizzo per ricevere fondi" - }, - "qrCode":{ - "title":"O personalizza il codice QR", - "labelAmount":"Importo (opzionale)", - "labelRecipient":"Nome del destinatario (opzionale)", - "labelDescription":"Descrizione della transazione (opzionale)", - "updateButton":"Update" - } - }, - "qrBlock":{ - "title":"Il tuo codice QR personalizzato" - }, - "waitingNfcToWriteModal":{ - "title":"Waiting Nfc", - "titleSuccess":"Nfc Tag written", - "content":"Avvicinati di più all'altro device" - }, - "nfcErrorModal":{ - "titleInsufficientCapacity":"Tag capacity insufficient" - } - }, - "miningPage":{ - "title":"Mina direttamente nel tuo browser", - "subtitle":"Supporta il network minando e ricevi MSR come ricompensa", - "parameterBlock":{ - "title":"Parametri", - "labelDestinationAddress":"Portafoglio di destinazione", - "labelThreads":"Numero di threads (più = Hashrate più elevato)", - "start":"Start", - "stop":"Stop" - }, - "statisticsBlocks":{ - "title":"Statistiche", - "validShares":"Valid shares", - "hashrate":"Hashrate", - "maxHashrate":"Max Hashrate", - "dedicatedHardware":"Con software e hardware dedicato al mining potresti raggiungere un hashrate da due a tre volte più elevato.", - "miningHandledBy":"Questo mining è gestito dalla pool get.Karbocoin.com" - } - }, - "settingsPage":{ - "title":"Impostazioni", - "subtitle":"Cambia i tuoi parametri qui", - "versionBlock":{ - "versionNumber":"Version number: ", - "versionCode":"Version code: " - }, - "settingsBlock":{ - "speed":{ - "label":"Speed to update the wallet (consumerà più energia)", - "fastest":"Più veloce", - "fast":"Veloce", - "medium":"Medio", - "slow":"Lento" - }, - "language":{ - "label":"Language" - }, - "readMinerTx":{ - "label":"Leggi transazioni del miner(solo mining)" - } - }, - "changePasswordButton":"Cambia la password del mio portafoglio", - "deleteWalletButton":"Elimina il mio portafoglio (copia locale)", - "walletSettings":{ - "creationHeight":{ - "label":"Altezza a cui è stato creato il portafoglio" - }, - "currentScanningHeight": { - "label": "Altezza di scansione attuale della blockchain" - }, - "updateButton":"Update" - }, - "deleteWalletModal":{ - "title":"Elimina il mio wallet (copia locale)", - "content":"Sei VERAMENTE sicuro di voler canecellare il tuo portafoglio?", - "confirmText":"Si, sono sicuro", - "cancelText":"Annulla" - } - }, - "importBasePage":{ - "parametersBlock":{ - "title":"Parameter", - "password":{ - "label":"Password per proteggere il tuo portafoglio" - }, - "passwordConfirm":{ - "label":"Conferma la password", - "invalid":"La password non coincide con quella precedentemente scritta" - }, - "importHeight":{ - "label":"Altezza di creazione del portafoglio" - } - } - }, - "importFromQrPage":{ - "title":"Importa portafoglio da codice QR", - "subtitle":"Importa un portafoglio da un backup offline", - "qrCodeBlock":{ - "title":"QR code", - "startScanButton":"Inizia la scansione", - "importButton":"Importa" - }, - "qrScanningBlock":{ - "title":"Presentare il codice QR" - } - }, - "exportPage":{ - "title":"Crea un backup delle tue credenziali", - "publicAddressBlock":{ - "title":"Il tuo indirizzo pubblico" - }, - "pdfBlock":{ - "title":"Backup in PDF", - "downloadButton":"Download" - }, - "warningBlock":{ - "title":"Attenzione", - "content":"Se scegli di salvare le tue chiavi private o la frase mnemonica, NON salvarla in un luogo non protetto(crittografato) per la tua sicurezza.
Il file è una soluzione alternativa dove le tue chiavi vengono crittografate e contiene un backup di tutte le tue transazioni per risparmiarti future sincronizzazioni." - }, - "exportBlock":{ - "title":"Esporta il tuo RAW delle credenziali", - "privateKeysButton":"Dammi la mia chiave privata", - "mnemonicKeysButton":"Dammi la mia frase mnemonica", - "fileButton":"Esporta in un file" - }, - "walletKeysModal":{ - "title":"Chiavi private", - "confirmText":"Ok", - "content":"Si prega di conservare attentamente queste chiavi. Possederle significa possedere i fondi associati!
Spend key: {privSpendKey}
Private view key: {privViewKey}" - }, - "mnemonicKeyModal":{ - "title":"Frase mnemonica", - "confirmText":"Ok", - "content":"Si prega di conservare attentamente questa frase mnemonica. Possederla significa possedere i fondi associati! La frase è:
{mnemonic}" - }, - "mnemonicLangSelectionModal":{ - "title":"In che lingua vuoi la tua frase mnemonica?", - "confirmText":"Esporta" - } - }, - "importPage":{ - "title":"Creare un portafoglio", - "subtitle":"Da chiavi, da file o da una frase mnemonica", - "chooseMethod":"Scegli il tuo metodo di importazione:", - "fromKeys":"Da chiavi", - "fromFile":"Da un file", - "fromMnemonic":"Da una frase mnemonica", - "fromQr":"Da un codice QR" - }, - "termsOfUsePage":{ - "title":"Termini di utilizzo", - "subtitle":"Per favore leggere attentamente" - }, - "privacyPolicyPage":{ - "title":"Privacy Policy", - "subtitle":"Per favore leggere attentamente" - }, - "importFromFilePage":{ - "title":"Importa un portafoglio da un file di backup", - "subtitle":"Usa il tuo backup per creare un portafoglio", - "walletBlock":{ - "title":"File del portafoglio", - "label":"Seleziona il file", - "importButton":"Importa" - } - }, - "importFromMnemonicPage":{ - "title":"Importa un portafoglio da una frase mnemonica", - "subtitle":"Usa la tua frase per creare un portafoglio", - "mnemonicBlock":{ - "title":"Frase mnemonica", - "mnemonic":{ - "label":"Frase mnemonica : 25 parole", - "invalid":"La frase mnemonica è invalida", - "language":"Lingua" - }, - "importButton":"Importa" - } - }, - "importFromKeysPage":{ - "title":"Importa un portafoglio da chiavi", - "subtitle":"Usa le tue chiavi per creare un portafoglio", - "parametersBlock":{ - "viewOnlyWallet":{ - "label":"Vuoi creare un portafoglio solo per vedere i fondi?" - } - }, - "keysBlock":{ - "titleNotViewOnly":"Wallet keys", - "titleViewOnly":"View-Only Wallet", - "privateSpend":{ - "label":"Private Spend Key" - }, - "privateView":{ - "label":"Private View Key", - "optional":"(optional)" - }, - "publicKey":{ - "label":"Public key" - }, - "importButton":"Importa" - } - } + "menu": { + "home": "Home", + "account": "Account", + "send": "Invia", + "receive": "Ricevi", + "export": "Esporta", + "donate": "Dona", + "elections": "Elezioni", + "contacts": "Contatti", + "settings": "Impostazioni", + "disconnect": "Disconnetti", + "network": "Statistiche del network" + }, + "global": { + "loading": "Caricamento", + "disableSecurity": "Disabilita questa sicurezza, comprendo i rischi", + "passwordInvalidRequirements": "La password richiede almeno 8 caratteri: 1 lettera maiuscola, 1 lettera minuscola, un numero e un carattere speciale", + "passwordConfirmationNotMatching": "La password non corrisponde a quella precedentemente inserita", + "download": "Download", + "newVersionModal": { + "title": "È disponibile una nuova versione", + "content": "Vuoi ricaricare la pagina per ottenere la nuova versione?", + "confirmText": "Si", + "cancelText": "Indietro" + }, + "openWalletModal": { + "title": "Password portafoglio", + "confirmText": "Apri", + "cancelText": "Annulla" + }, + "invalidPasswordModal": { + "title": "Oops...", + "content": "La tua password sembra invalida", + "confirmText": "Ok" + }, + "invalidMnemonicModal": { + "title": "Oops...", + "content": "La frase mnemonica è invalida", + "confirmText": "Ok" + }, + "passwordNotComplexEnoughModal": { + "title": "La password non è sufficientemente complessa", + "confirmText": "Ok" + }, + "permissionRequiredForCameraModal": { + "title": "Oops...", + "content": "È necessario consentire l'accesso alla videocamera per eseguire la scansione del codice QR", + "confirmText": "Ok" + } + }, + "bottom": { + "termsOfUse": "Termini di utilizzo", + "privacyPolicy": "politica sulla riservatezza", + "support": "Supporto", + "donate": "Dona", + "network": "Statistiche del network", + "miningPool": "Mining Pool", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Portafoglio sicuro per Qwertycoin", + "tagLine": "Il modo più semplice per usare Qwertycoin - ovunque e in qualsiasi momento", + "tagLineTwo": "Il modo più semplice per usare Qwertycoin", + "actions": { + "loadWallet": "Carica il mio portafoglio", + "importWallet": "Importa un portafoglio", + "create": "Crea", + "createWallet": "Crea un portafoglio" + } + }, + "accountPage": { + "title": "Account", + "subtitle": "Panoramica del tuo account e cronologia delle transazioni", + "synchronizingBlock": { + "text": "Sincronizzazione... " + }, + "balanceBlock": { + "title": "Il tuo bilancio", + "unlocked": "Sbloccato" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Cronologia delle transazioni", + "pendingTxStatus": "In attesa", + "emptyWallet": "Al momento non disponi di fondi su questo portafoglio", + "waitSync": "Si prega di attendere la fine della sincronizzazione", + "beReallyPatient": "La prima sincronizzazione potrebbe richiedere alcuni minuti ...", + "getCoinAddress": "Ricevi QWC" + }, + "txDetails": { + "title": "Dettagli transazione", + "txHash": "Tx hash", + "feesOnTx": "Commissione sulla Tx", + "blockHeight": "Altezza sulla blockchain", + "paymentId": "Payment ID", + "unlockStatus": "Status", + "unlockConfirm": "Confirmations", + "txPrivKey": "Chiave privata della transazione" + } + }, + "changeWalletPasswordPage": { + "title": "Cambia la tua password", + "oldPassword": { + "label": "Vecchia password", + "invalid": "La password è invalida" + }, + "newPassword": { + "label": "Scegli una nuova password per proteggere il tuo portafoglio" + }, + "newPasswordConfirm": { + "label": "Conferma la nuova password" + }, + "confirm": "Cambia la password", + "modalSuccess": { + "title": "Password cambiata!", + "confirmText": "Ok" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "Contatti" + }, + "electionsPage": { + "title": "Elezioni" + }, + "createWalletPage": { + "generatingStep": { + "title": "Il tuo portafoglio sta per essere generato...", + "subtitle": "Mancano pochi istanti", + "waitingMessage": "Generazione del portafoglio..." + }, + "finalizationStep": { + "title": "È stato semplice. Il tuo portafoglio è pronto!", + "subtitle": "Tenetevi pronti a usare Qwertycoin come mai prima d'ora", + "passwordSelectionBlock": { + "label": "Proteggi il tuo portafoglio" + }, + "passwordConfirmBlock": { + "label": "Conferma la password" + }, + "validPassword": "Usa questa password", + "backupBlock": { + "title": "Scarica una copia crittografata delle mie credenziali per uso futuro", + "option1": "Opzione 1: ", + "option2": "Opzione 2: ", + "titlePdf": "Scarica una copia PDF", + "titleManualWrite": "Scrivi le mie chiavi", + "privateKeys": "Chiavi private", + "mnemonicPhrase": "Frase mnemonica", + "separatorManualMethodsSolution": " o ", + "confirmManuallyWritten": "Li ho scritti", + "warningMessage": "**Non perderli!** È impossibile recuperarli se li perdi.
**Non condividerli!** I tuoi fondi potrebbero essere rubati se utilizzi queste informazioni su siti malevoli o di phishing.
**Crea un backup!** Proteggilo le tue credenziali come i milioni di dollari che un giorno potrebbe valere.
", + "finishButton": "Ho capito. Continua" + } + }, + "disclaimerBlock": { + "title": "Rischi nell'usare QwertycoinWallet", + "content": "QwertycoinWallet è una interfaccia web-based. Ti aiuta ad usare Qwertycoin senza eseguire un full node.
Vi consigliamo di trattare MaraiWallet come trattereste il vostro portafoglio attuale." + } + }, + "donatePage": { + "title": "Dona", + "subtitle": "Aiutaci a finanziare lo sviluppo e a pagare le bollette", + "webwalletBlock": { + "title": "Webwallet", + "content": "Questo webwallet è sviluppato da Gnock nel suo tempo libero.
Se vuoi aiutare lo sviluppo, aiutare a pagare server e ti piace questa applicazione, prendi in considerazione la possibilità di effettuare una piccola donazione.:

" + }, + "QwertycoinFundBlock": { + "title": "Fondo per lo sviluppo di Qwertycoin", + "content": "Per aiutare Qwertycoin puoi donare a questo indirizzo " + } + }, + "supportPage": { + "title": "Support", + "subtitle": "Bisogno di aiuto? siamo qui per aiutarti!", + "getInTouchBlock": { + "title": "Mettiamoci in contatto!", + "content": "Se hai idee o feedback per migliorare il portafoglio, contattaci!", + "discord": "Qwertycoin Discord Channel" + } + }, + "networkPage": { + "title": "Statistiche del network", + "subtitle": "Dettagli sul network Qwertycoin", + "statsBlock": { + "connectNode": "Connected Masternode", + "hashrate": "Network Hashrate", + "height": "Altezza blockchain", + "difficulty": "Difficoltà network", + "lastTimeBlock": "Ultimo blocco trovato", + "lastReward": "Ultima ricompensa" + } + }, + "sendPage": { + "title": "Invia QWC", + "sendBlock": { + "address": { + "label": "Indirizzo di destinazione", + "placeholder": "Scrivi l'indirizzo nel quale vuoi inviare i fondi", + "invalid": "L'indirizzo di destinazione è errato", + "fundsTo": "I fondi verranno inviati a ", + "receiver": "Destinatario", + "description": "Descrizione" + }, + "amount": { + "label": "Importo da inviare", + "invalid": "L'importo non è valido" + }, + "paymentId": { + "label": "Payment ID (opzionale)", + "invalid": "Il Payment ID è invalido. La lunghezza deve essere di 16 o 64 caratteri" + }, + "sendButton": "Invia", + "cancelButton": "Annulla" + }, + "qrCodeScanning": { + "explication": "Mostra il codice QR" + }, + "notEnoughMoneyModal": { + "title": "Oops...", + "content": "Non hai abbastanza fondi nel tuo portafoglio per completare il trasferimento", + "confirmText": "Ok" + }, + "thankYouDonationModal": { + "title": "Grazie per la tua donazione!", + "content": "Il tuo aiuto è molto apprezzato.
Questa donazione contribuirà a rendere Qwertycoin ancora migliore", + "confirmText": "Ok" + }, + "transferSentModal": { + "title": "Trasferimento inviato con successo!", + "confirmText": "Ok" + }, + "transferExceptionModal": { + "title": "Oops...", + "content": "Si è verificato un errore. Si prega di segnalare questo errore: {details}", + "confirmText": "Ok" + }, + "invalidAmountModal": { + "title": "Oops...", + "content": "Importo invalido", + "confirmText": "Ok" + }, + "creatingTransferModal": { + "title": "Creazione del trasferimento...", + "content": "Per favore attendi..." + }, + "finalizingTransferModal": { + "title": "Finalizzazione del trasferimento...", + "content": "Per favore attendi..." + }, + "confirmTransactionModal": { + "title": "Confermare transferimento?", + "content": "Amount: {amount}
Fees: {fees}
Total: {total}", + "confirmText": "Conferma", + "cancelText": "Annulla" + }, + "waitingNfcModal": { + "title": "Waiting Nfc", + "content": "Avvicinati di più all'altro device" + } + }, + "receivePage": { + "title": "Ricevi QWC", + "receiveBlock": { + "address": { + "title": "Il tuo indirizzo per ricevere i fondi", + "label": "Dai questo indirizzo per ricevere fondi" + }, + "qrCode": { + "title": "O personalizza il codice QR", + "labelAmount": "Importo (opzionale)", + "labelRecipient": "Nome del destinatario (opzionale)", + "labelDescription": "Descrizione della transazione (opzionale)", + "updateButton": "Update" + } + }, + "qrBlock": { + "title": "Il tuo codice QR personalizzato" + }, + "waitingNfcToWriteModal": { + "title": "Waiting Nfc", + "titleSuccess": "Nfc Tag written", + "content": "Avvicinati di più all'altro device" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Tag capacity insufficient" + } + }, + "miningPage": { + "title": "Mina direttamente nel tuo browser", + "subtitle": "Supporta il network minando e ricevi QWC come ricompensa", + "parameterBlock": { + "title": "Parametri", + "labelDestinationAddress": "Portafoglio di destinazione", + "labelThreads": "Numero di threads (più = Hashrate più elevato)", + "start": "Start", + "stop": "Stop" + }, + "statisticsBlocks": { + "title": "Statistiche", + "validShares": "Valid shares", + "hashrate": "Hashrate", + "maxHashrate": "Max Hashrate", + "dedicatedHardware": "Con software e hardware dedicato al mining potresti raggiungere un hashrate da due a tre volte più elevato.", + "miningHandledBy": "Questo mining è gestito dalla pool https://qwertycoin.org" + } + }, + "settingsPage": { + "title": "Impostazioni", + "subtitle": "Cambia i tuoi parametri qui", + "versionBlock": { + "versionNumber": "Version number: ", + "versionCode": "Version code: " + }, + "settingsBlock": { + "speed": { + "label": "Speed to update the wallet (consumerà più energia)", + "fastest": "Più veloce", + "fast": "Veloce", + "medium": "Medio", + "slow": "Lento" + }, + "language": { + "label": "Language" + }, + "currency": { + "label": "valuta nazionale" + }, + "readMinerTx": { + "label": "Leggi transazioni del miner(solo mining)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Cambia la password del mio portafoglio", + "deleteWalletButton": "Elimina il mio portafoglio (copia locale)", + "walletSettings": { + "creationHeight": { + "label": "Altezza a cui è stato creato il portafoglio" + }, + "currentScanningHeight": { + "label": "Altezza di scansione attuale della blockchain" + }, + "updateButton": "Update" + }, + "deleteWalletModal": { + "title": "Elimina il mio wallet (copia locale)", + "content": "Sei VERAMENTE sicuro di voler canecellare il tuo portafoglio?", + "confirmText": "Si, sono sicuro", + "cancelText": "Annulla" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Parameter", + "password": { + "label": "Password per proteggere il tuo portafoglio" + }, + "passwordConfirm": { + "label": "Conferma la password", + "invalid": "La password non coincide con quella precedentemente scritta" + }, + "importHeight": { + "label": "Altezza di creazione del portafoglio" + } + } + }, + "importFromQrPage": { + "title": "Importa portafoglio da codice QR", + "subtitle": "Importa un portafoglio da un backup offline", + "qrCodeBlock": { + "title": "QR code", + "startScanButton": "Inizia la scansione", + "importButton": "Importa" + }, + "qrScanningBlock": { + "title": "Presentare il codice QR" + } + }, + "exportPage": { + "title": "Crea un backup delle tue credenziali", + "publicAddressBlock": { + "title": "Il tuo indirizzo pubblico" + }, + "pdfBlock": { + "title": "Backup in PDF", + "downloadButton": "Download" + }, + "warningBlock": { + "title": "Attenzione", + "content": "Se scegli di salvare le tue chiavi private o la frase mnemonica, NON salvarla in un luogo non protetto(crittografato) per la tua sicurezza.
Il file è una soluzione alternativa dove le tue chiavi vengono crittografate e contiene un backup di tutte le tue transazioni per risparmiarti future sincronizzazioni." + }, + "exportBlock": { + "title": "Esporta il tuo RAW delle credenziali", + "privateKeysButton": "Dammi la mia chiave privata", + "mnemonicKeysButton": "Dammi la mia frase mnemonica", + "fileButton": "Esporta in un file" + }, + "walletKeysModal": { + "title": "Chiavi private", + "confirmText": "Ok", + "content": "Si prega di conservare attentamente queste chiavi. Possederle significa possedere i fondi associati!
Spend key: {privSpendKey}
Private view key: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Frase mnemonica", + "confirmText": "Ok", + "content": "Si prega di conservare attentamente questa frase mnemonica. Possederla significa possedere i fondi associati! La frase è:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "In che lingua vuoi la tua frase mnemonica?", + "confirmText": "Esporta" + } + }, + "importPage": { + "title": "Creare un portafoglio", + "subtitle": "Da chiavi, da file o da una frase mnemonica", + "chooseMethod": "Scegli il tuo metodo di importazione:", + "fromKeys": "Da chiavi", + "fromFile": "Da un file", + "fromMnemonic": "Da una frase mnemonica", + "fromQr": "Da un codice QR" + }, + "termsOfUsePage": { + "title": "Termini di utilizzo", + "subtitle": "Per favore leggere attentamente" + }, + "privacyPolicyPage": { + "title": "Privacy Policy", + "subtitle": "Per favore leggere attentamente" + }, + "importFromFilePage": { + "title": "Importa un portafoglio da un file di backup", + "subtitle": "Usa il tuo backup per creare un portafoglio", + "walletBlock": { + "title": "File del portafoglio", + "label": "Seleziona il file", + "importButton": "Importa" + } + }, + "importFromMnemonicPage": { + "title": "Importa un portafoglio da una frase mnemonica", + "subtitle": "Usa la tua frase per creare un portafoglio", + "mnemonicBlock": { + "title": "Frase mnemonica", + "mnemonic": { + "label": "Frase mnemonica : 25 parole", + "invalid": "La frase mnemonica è invalida", + "language": "Lingua" + }, + "importButton": "Importa" + } + }, + "importFromKeysPage": { + "title": "Importa un portafoglio da chiavi", + "subtitle": "Usa le tue chiavi per creare un portafoglio", + "parametersBlock": { + "viewOnlyWallet": { + "label": "Vuoi creare un portafoglio solo per vedere i fondi?" + } + }, + "keysBlock": { + "titleNotViewOnly": "Wallet keys", + "titleViewOnly": "View-Only Wallet", + "privateSpend": { + "label": "Private Spend Key" + }, + "privateView": { + "label": "Private View Key", + "optional": "(optional)" + }, + "publicKey": { + "label": "Public key" + }, + "importButton": "Importa" + } + } }, - "number":{ - - }, - "date":{ - "short": { - "year": "numeric", "month": "short", "day": "numeric" - }, - "long": { - "year": "numeric", "month": "short", "day": "numeric", - "weekday": "short", "hour": "numeric", "minute": "numeric", "hour12": false - } + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": false + } } } diff --git a/src/translations/ja.json b/src/translations/ja.json new file mode 100644 index 00000000..5e3ac017 --- /dev/null +++ b/src/translations/ja.json @@ -0,0 +1,539 @@ +{ + "website": { + "title": "Qwertycoin Wallet | シンプル、シームレス、安全 未来へようこそ。", + "description": "Official online wallet for Qwertycoin currency - fully handled in your browser for optimal security" + }, + "messages": { + "menu": { + "home": "ホーム", + "account": "アカウント", + "send": "送る", + "receive": "受け取る", + "export": "輸出する", + "donate": "寄付する", + "elections": "選挙", + "contacts": "連絡先", + "settings": "設定", + "disconnect": "切断する", + "network": "ネットワーク統計", + "mining": "採鉱" + }, + "global": { + "loading": "ロード中", + "disableSecurity": "このセキュリティを無効にしてください、私はリスクを理解しています", + "passwordInvalidRequirements": "The password needs at least 8 characters - 1 upper case letter, 1 lower case letter, one number, and one special character", + "passwordConfirmationNotMatching": "The password does not match the first password you wrote", + "download": "ダウンロード", + "newVersionModal": { + "title": "新しいバージョンが利用可能です", + "content": "新しいバージョンをロードするためにリロードしますか?", + "confirmText": "はい", + "cancelText": "バック" + }, + "openWalletModal": { + "title": "ウォレットパスワード", + "confirmText": "開いた", + "cancelText": "キャンセル" + }, + "invalidPasswordModal": { + "title": "おっとっと...", + "content": "Your password seems invalid", + "confirmText": "はい" + }, + "invalidMnemonicModal": { + "title": "おっとっと...", + "content": "The mnemonic phrase is invalid", + "confirmText": "はい" + }, + "passwordNotComplexEnoughModal": { + "title": "The password is not complex enough", + "confirmText": "はい" + }, + "permissionRequiredForCameraModal": { + "title": "おっとっと...", + "content": "The permission to access your camera is required to scan the QR code", + "confirmText": "はい" + } + }, + "bottom": { + "termsOfUse": "Terms of Use", + "privacyPolicy": "Privacy Policy", + "support": "Support", + "donate": "Donate", + "network": "Network Stats", + "miningPool": "Mining Pool", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Qwertycoin 財布", + "tagLine": "どこでも。いつでも。どこでも。 任意のデバイス", + "tagLineTwo": "最も簡単な使い方 Qwertycoin", + "actions": { + "loadWallet": "私の財布をロード", + "importWallet": "財布をインポートする", + "create": "作ります", + "createWallet": "財布を作成する" + } + }, + "accountPage": { + "title": "アカウント", + "subtitle": "アカウントの概要と取引履歴", + "synchronizingBlock": { + "text": "同期..." + }, + "balanceBlock": { + "title": "あなたのバランス", + "unlocked": "ロック解除" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "取引履歴", + "pendingTxStatus": "未定", + "emptyWallet": "あなたは現在この財布に資金を持っていません。", + "waitSync": "財布が更新されるまでお待ちください", + "beReallyPatient": "初期設定にはしばらく時間がかかります...", + "getCoinAddress": "QWCを受け取る" + }, + "txDetails": { + "title": "取引の詳細", + "txHash": "トランザクションハッシュ", + "feesOnTx": "取引料金", + "blockHeight": "ブロックの高さ", + "paymentId": "支払いID", + "unlockStatus": "ステータス", + "unlockConfirm": "確認", + "txPrivKey": "トランザクション秘密鍵" + } + }, + "changeWalletPasswordPage": { + "title": "パスワードを変更してください", + "oldPassword": { + "label": "以前のパスワード", + "invalid": "パスワードが無効です" + }, + "newPassword": { + "label": "あなたの財布を保護するために新しいパスワードを選択してください" + }, + "newPasswordConfirm": { + "label": "新しいパスワードを確認してください" + }, + "confirm": "パスワードを変更する", + "modalSuccess": { + "title": "パスワード変更済み!", + "confirmText": "はい" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "連絡先" + }, + "electionsPage": { + "title": "選挙" + }, + "createWalletPage": { + "generatingStep": { + "title": "あなたの財布は生成されています...", + "subtitle": "ほとんど終わった", + "waitingMessage": "財布を生成する..." + }, + "finalizationStep": { + "title": "それは簡単でした。 あなたのアカウントは準備ができています!", + "subtitle": "あなたが持っていないようにQwertycoinを使用する準備ができている", + "passwordSelectionBlock": { + "label": "あなたの財布を守る" + }, + "passwordConfirmBlock": { + "label": "パスワードを確認してください" + }, + "validPassword": "このパスワードを使う", + "backupBlock": { + "title": "Save your private credentials for recovery.", + "option1": "Option 1: ", + "option2": "Option 2: ", + "titlePdf": "Download a PDF copy", + "titleManualWrite": "Write down my keys", + "privateKeys": "Private key", + "mnemonicPhrase": "Mnemonic phrase", + "separatorManualMethodsSolution": " or ", + "confirmManuallyWritten": "I wrote my seed phrase down", + "warningMessage": "**Do not lose it!** It cannot be recovered if you lose it.
**Do not share it!** Your funds will be stolen if you use this file or seed on a malicious/phishing site.
**Make a backup!** Secure it like the millions of dollars it may one day be worth.
", + "finishButton": "I understand. Continue." + } + }, + "disclaimerBlock": { + "title": "Risk of Using QwertycoinWallet", + "content": "QwertycoinWallet is a web-based interface. It helps you use Qwertycoin without running a full Qwertycoin node.
We recommend you treat QwertycoinWallet like you will treat your actual wallet." + } + }, + "donatePage": { + "title": "寄付する", + "subtitle": "Help to fund the development and pay the bills", + "webwalletBlock": { + "title": "Webwallet", + "content": "If you want to help to pay for the servers, to support new features development, and like this app, please consider a donation:

" + }, + "devFundBlock": { + "title": "Qwertycoin Dev fund", + "content": "To help Qwertycoin, you can donate at these addresses" + } + }, + "supportPage": { + "title": "サポート", + "subtitle": "We are here to help!", + "getInTouchBlock": { + "title": "Let's Get In Touch!", + "content": "Do you have ideas or feedback that could help us improve the wallet? Contact us!", + "discord": "Qwertycoin Discord Channel" + } + }, + "networkPage": { + "title": "ネットワーク統計", + "subtitle": "Insights on the Qwertycoin network", + "statsBlock": { + "connectNode": "接続マスターノード", + "hashrate": "Network hashrate", + "height": "Blockchain height", + "difficulty": "Network difficulty", + "lastTimeBlock": "Last block found", + "lastReward": "Last block reward" + } + }, + "sendPage": { + "title": "QWCを送る", + "sendBlock": { + "address": { + "label": "Destination address", + "placeholder": "Write the address where you want to send funds", + "invalid": "The destination address is invalid", + "fundsTo": "The funds will be sent to", + "receiver": "Receiver", + "description": "Description" + }, + "amount": { + "label": "Amount to send", + "invalid": "The amount is invalid" + }, + "paymentId": { + "label": "Payment ID (optional)", + "invalid": "The payment ID is invalid. The length must be 16 or 64 characters" + }, + "sendButton": "Send", + "cancelButton": "Cancel" + }, + "qrCodeScanning": { + "explication": "Present the QR code" + }, + "notEnoughMoneyModal": { + "title": "おっとっと...", + "content": "You don't have enough funds in your wallet to execute this transfer", + "confirmText": "はい" + }, + "thankYouDonationModal": { + "title": "Thank you for your donation!", + "content": "Your help is appreciated. This donation will help make Qwertycoin better", + "confirmText": "はい" + }, + "transferSentModal": { + "title": "Transfer sent successfully!", + "confirmText": "はい" + }, + "transferExceptionModal": { + "title": "おっとっと...", + "content": "An error occurred. Please report this error: {details}", + "confirmText": "はい" + }, + "invalidAmountModal": { + "title": "おっとっと...", + "content": "Invalid amount", + "confirmText": "はい" + }, + "creatingTransferModal": { + "title": "Creating transfer ...", + "content": "Please wait..." + }, + "finalizingTransferModal": { + "title": "Finalizing transfer ...", + "content": "Please wait..." + }, + "confirmTransactionModal": { + "title": "Confirm transfer?", + "content": "Amount: {amount}
Fees: {fees}
Total: {total}", + "confirmText": "Confirm", + "cancelText": "Cancel" + }, + "waitingNfcModal": { + "title": "Waiting Nfc", + "content": "Bring closer to the other device" + } + }, + "receivePage": { + "title": "Receive QWC", + "receiveBlock": { + "address": { + "title": "Your address to receive funds:", + "label": "Give this address to receive funds" + }, + "qrCode": { + "title": "Or personalize the QR code:", + "labelAmount": "Amount (optional)", + "labelRecipient": "Recipient name (optional)", + "labelDescription": "Transaction description (optional)", + "updateButton": "Update" + } + }, + "qrBlock": { + "title": "Your customized QR code" + }, + "waitingNfcToWriteModal": { + "title": "Waiting Nfc", + "titleSuccess": "Nfc Tag written", + "content": "Bring closer the NFC tag to write" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Tag capacity insufficient" + } + }, + "miningPage": { + "title": "Mine directly in your browser", + "subtitle": "Support the network by mining and be rewarded with QWC", + "parameterBlock": { + "title": "Parameters", + "labelDestinationAddress": "Wallet to mine", + "labelThreads": "Number of threads (more = higher hashrate)", + "start": "Start", + "stop": "Stop" + }, + "statisticsBlocks": { + "title": "Statistics", + "validShares": "Valid shares", + "hashrate": "Hashrate", + "maxHashrate": "Max Hashrate", + "dedicatedHardware": "With dedicating mining software and hardware, you could earn more and help decentralize the network.", + "miningHandledBy": "This mining is handled by the mining pool pool.qwertycoin.org" + } + }, + "settingsPage": { + "title": "Settings", + "subtitle": "Change your parameters here", + "versionBlock": { + "versionNumber": "Version number: ", + "versionCode": "Version code: " + }, + "settingsBlock": { + "speed": { + "label": "Speed to update the wallet (will consume more resources)", + "fastest": "Fastest", + "fast": "Fast", + "medium": "Medium", + "slow": "Slow" + }, + "language": { + "label": "Language" + }, + "currency": { + "label": "国の通貨" + }, + "readMinerTx": { + "label": "Read miner transactions (only for solo mining)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Change my wallet password", + "deleteWalletButton": "Delete my wallet (local copy)", + "walletSettings": { + "creationHeight": { + "label": "Creation height of the wallet" + }, + "currentScanningHeight": { + "label": "Current scanning height" + }, + "updateButton": "Update" + }, + "deleteWalletModal": { + "title": "Delete My Wallet (local copy)", + "content": "Are you sure you REALLY want to delete your wallet ?", + "confirmText": "Yes I'm sure", + "cancelText": "Cancel" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Parameters", + "password": { + "label": "Password to protect your wallet" + }, + "passwordConfirm": { + "label": "Confirm the password", + "invalid": "The password does not match the first password you wrote" + }, + "importHeight": { + "label": "Height to import from:" + } + } + }, + "importFromQrPage": { + "title": "Importing wallet from a QR code", + "subtitle": "Import a wallet from an offline backup", + "qrCodeBlock": { + "title": "QR code", + "startScanButton": "Start the scan", + "importButton": "インポート" + }, + "qrScanningBlock": { + "title": "Present the QR code" + } + }, + "exportPage": { + "title": "Backup your credentials", + "publicAddressBlock": { + "title": "Your public address" + }, + "pdfBlock": { + "title": "PDF Backup", + "downloadButton": "Download" + }, + "warningBlock": { + "title": "Warning", + "content": "If you choose to save your private keys or your mnemonic phrase, PLEASE DO NOT store them in clear-text for your own safety.
The file is an alternate solution where your keys are encrypted and contains a backup of all your transactions to spare you a future synchronisation." + }, + "exportBlock": { + "title": "Export your RAW credentials", + "privateKeysButton": "Get my private keys", + "mnemonicKeysButton": "Get my mnemonic phrase", + "fileButton": "Export to a file" + }, + "walletKeysModal": { + "title": "秘密鍵", + "confirmText": "はい", + "content": "Please carefully store these keys. Possessing them means possessing the funds associated !
Spend key: {privSpendKey}
Private view key: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "ニーモニック句", + "confirmText": "はい", + "content": "Please store carefully this mnemonic phrase. Possessing it means possessing the funds associated ! The phrase is:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "どの言語であなたのニーモニックフレーズが欲しいですか?", + "confirmText": "輸出する" + } + }, + "importPage": { + "title": "財布を作成する", + "subtitle": "以前に作成されたキー、ファイル、またはニーモニック句から", + "chooseMethod": "インポート方法を選択してください。", + "fromKeys": "キーから", + "fromFile": "ファイルから", + "fromMnemonic": "ニーモニック句から", + "fromQr": "QRコードから" + }, + "termsOfUsePage": { + "title": "利用規約", + "subtitle": "よく読んでください。" + }, + "privacyPolicyPage": { + "title": "個人情報保護方針", + "subtitle": "よく読んでください。" + }, + "importFromFilePage": { + "title": "バックアップファイルからのWalletのインポート", + "subtitle": "バックアップファイルを使用してウォレットを作成します", + "walletBlock": { + "title": "ウォレットファイル", + "label": "ファイルを選択", + "importButton": "インポート" + } + }, + "importFromMnemonicPage": { + "title": "ニーモニックフレーズからのWalletのインポート", + "subtitle": "あなたのフレーズを使って財布を作りましょう", + "mnemonicBlock": { + "title": "ニーモニック句", + "mnemonic": { + "label": "記憶語句:25ワード", + "invalid": "ニーモニック句が無効です", + "language": "言語" + }, + "importButton": "インポート" + } + }, + "importFromKeysPage": { + "title": "鍵から財布をインポートする", + "subtitle": "鍵を使って財布を作る", + "parametersBlock": { + "viewOnlyWallet": { + "label": "ビュー専用財布がほしいですか。" + } + }, + "keysBlock": { + "titleNotViewOnly": "ウォレットキー", + "titleViewOnly": "財布のみ表示", + "privateSpend": { + "label": "プライベート費用キー" + }, + "privateView": { + "label": "プライベートビューキー", + "optional": "(オプション" + }, + "publicKey": { + "label": "公開鍵" + }, + "importButton": "インポート" + } + } + }, + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": true + } + } +} diff --git a/src/translations/ko.json b/src/translations/ko.json new file mode 100644 index 00000000..9d00d3b4 --- /dev/null +++ b/src/translations/ko.json @@ -0,0 +1,539 @@ +{ + "website": { + "title": "Qwertycoin 지갑 | 간단하고 안전합니다. 미래에 오신 것을 환영합니다.", + "description": "Qwertycoin 통화를위한 공식 온라인 지갑 - 최적의 보안을 위해 브라우저에서 완벽하게 처리됩니다. 본인만 사용하는 기기에서 접속해 주세요." + }, + "messages": { + "menu": { + "home": "홈", + "account": "계정", + "send": "보내기", + "receive": "받기", + "export": "내보내기", + "donate": "기부", + "elections": "선거", + "contacts": "콘택트 렌즈", + "settings": "설정", + "disconnect": "연결 끊기", + "network": "네트워크 통계", + "mining": "채굴" + }, + "global": { + "loading": "로드중", + "disableSecurity": "보안을 해제하며, 사용자는 그에 따른 위험을 인지합니다.", + "passwordInvalidRequirements": "비밀번호는 최소 8자리 이상이여야 하며, 1개 이상의 대문자, 소문자, 숫자 및 특수 문자로 구성해 주세요.", + "passwordConfirmationNotMatching": "비밀번호가 일치하지 않습니다", + "download": "다운로드", + "newVersionModal": { + "title": "새 버전이 나왔습니다.", + "content": "새 버전으로 다시 로딩 하시겠습니까?", + "confirmText": "예", + "cancelText": "취소" + }, + "openWalletModal": { + "title": "비밀번호", + "confirmText": "열기", + "cancelText": "취소" + }, + "invalidPasswordModal": { + "title": "비밀번호", + "content": "입력하신 비밀번호가 정확하지 않습니다.", + "confirmText": "확인" + }, + "invalidMnemonicModal": { + "title": "연상단어", + "content": "연상단어(Mneumonic Seed)의 입력이 잘못되었습니다.", + "confirmText": "확인" + }, + "passwordNotComplexEnoughModal": { + "title": "비밀번호의 구성이 보안요구사항을 준수하지 못합니다.", + "confirmText": "확인" + }, + "permissionRequiredForCameraModal": { + "title": "카메라", + "content": "QR code 스캔을 위한 카메라의 접근 권한이 필요합니다.", + "confirmText": "확인" + } + }, + "bottom": { + "termsOfUse": "이용약관", + "privacyPolicy": "개인정보정책", + "support": "도움받기", + "donate": "기부", + "network": "네트워크 통계", + "miningPool": "채굴", + "github": "Github" + }, + "homepage": { + "mainTitle": "쿼티코인 웹지갑", + "tagLine": "어디서든. 언제든. 모든 장치에서.", + "tagLineTwo": "쿼티코인을 사용하기 가장 간단한 방법", + "actions": { + "loadWallet": "지갑 불러오기", + "importWallet": "지갑 가져오기", + "create": "지갑 만들기", + "createWallet": "지갑 만들기" + } + }, + "accountPage": { + "title": "계정", + "subtitle": "계정 정보 및 트랜젝션 기록", + "synchronizingBlock": { + "text": "동기화중..." + }, + "balanceBlock": { + "title": "잔액", + "unlocked": "해제완료" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "트랜젝션 기록", + "pendingTxStatus": "처리중", + "emptyWallet": "현재 지갑에 잔액이 없습니다", + "waitSync": "지갑이 업데이트되고 있습니다. 잠시만 기다려주세요.", + "beReallyPatient": "초기 셋업중입니다. 잠시만 기다려주세요.", + "getCoinAddress": "쿼티코인 받기" + }, + "txDetails": { + "title": "트랜젝션 세부내용", + "txHash": "트랜젝션 해시", + "feesOnTx": "트랜젝션 비용", + "blockHeight": "블록넘버", + "paymentId": "페이먼트 ID", + "unlockStatus": "현황", + "unlockConfirm": "확인", + "txPrivKey": "트랜젝션 비공개 키" + } + }, + "changeWalletPasswordPage": { + "title": "비밀번호 변경", + "oldPassword": { + "label": "현재 비밀번호", + "invalid": "비밀번호가 일치하지 않습니다." + }, + "newPassword": { + "label": "새로운 비밀번호를 입력하세요." + }, + "newPasswordConfirm": { + "label": "새 비밀번호로 변경합니다." + }, + "confirm": "변경완료", + "modalSuccess": { + "title": "비밀번호가 변경되었습니다.", + "confirmText": "확인" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "콘택트 렌즈" + }, + "electionsPage": { + "title": "선거" + }, + "createWalletPage": { + "generatingStep": { + "title": "지갑이 생성되고 있습니다", + "subtitle": "거의 완료되었습니다", + "waitingMessage": "잠시만 기다려주세요" + }, + "finalizationStep": { + "title": "지갑 생성이 완료되었습니다", + "subtitle": "이전 방식과는 다르게 쿼티코인을 사용해보세요", + "passwordSelectionBlock": { + "label": "비밀번호 설정" + }, + "passwordConfirmBlock": { + "label": "비밀번호 확인" + }, + "validPassword": "이 비밀번호를 사용합니다.", + "backupBlock": { + "title": "비공개 키와 연상단어를 저장하여, 지갑을 복구할 수 있습니다.", + "option1": "옵션 1: ", + "option2": "옵션 2: ", + "titlePdf": "PDF로 다운받아 저장하기", + "titleManualWrite": "비공개 키 ", + "privateKeys": "비공개 키", + "mnemonicPhrase": "연상단어", + "separatorManualMethodsSolution": " 또는 ", + "confirmManuallyWritten": "연상단어를 적어두었습니다.", + "warningMessage": "**절대로 잃어버리면 안됩니다!** 잃어버릴 경우 찾을 수 없습니다.
**타인에게 공유하면 안됩니다!** 타인이 해당 정보를 이용하여 쿼티코인을 빼갈 수 있습니다. 비슷한 주소의 피싱 사이트를 조심하셔야 합니다.
**백업을 만드세요!** 언젠가는 큰 금액이 될지도 모르니까요.
", + "finishButton": "위 내용을 이해하며, 타인이 사용이 가능한 컴퓨터에서 접속할 경우, 해킹의 위험에 노출되며, 그에 따른 위험을 감수합니다." + } + }, + "disclaimerBlock": { + "title": "쿼티코인 웹지갑 서비스 사용 공지", + "content": "쿼티코인 웹지갑 서비스는 쿼티코인 노드없이도 사용할 수 있는 지갑입니다.
웹지갑과 관련되어 제공되는 정보(비밀번호, 비공개 키, 연상단어) 및 환경(컴퓨터 및 모바일 기기의 보안)을 일반 지갑에서와 같이 안전하게 보관하시길 권장합니다" + } + }, + "donatePage": { + "title": "기부", + "subtitle": "기부를 통해 쿼티코인 개발 및 운영유지에 도움을 주세요.", + "webwalletBlock": { + "title": "웹지갑", + "content": "기부해 주신 쿼티코인은 서버운영 및 유지, 새로운 기능 추가를 위한 개발에 쓰입니다. 다음 주소로 기부해 주세요:

" + }, + "devFundBlock": { + "title": "쿼티코인 개발자 모금", + "content": "다음 주소에도 기부하실 수 있습니다." + } + }, + "supportPage": { + "title": "도움받기", + "subtitle": "어떻게 도와드릴까요?", + "getInTouchBlock": { + "title": "코어팀에게 연락하고 싶습니다.", + "content": "웹지갑 서비스의 개선에 관련된 새로운 아이디어나 피드백이 있으신가요? 그렇다면 연락주세요!", + "discord": "쿼티코인 디스코드 채널" + } + }, + "networkPage": { + "title": "네트워크 통계", + "subtitle": "쿼티코인 네트워크 정보", + "statsBlock": { + "connectNode": "연결된 마스터 노드", + "hashrate": "네트워크 해시레이트", + "height": "블록 높이", + "difficulty": "네트워크 난이도", + "lastTimeBlock": "블록 발견 시간", + "lastReward": "블록 보상" + } + }, + "sendPage": { + "title": "쿼티코인 보내기", + "sendBlock": { + "address": { + "label": "주소", + "placeholder": "위 주소로 송금이 됩니다.", + "invalid": "입력해 주신 주소가 올바르지 않습니다.", + "fundsTo": "적어주신 주소로 쿼티코인이 전송됩니다.", + "receiver": "받는 이", + "description": "설명" + }, + "amount": { + "label": "보내는 금액", + "invalid": "입력하신 금액이 올바르지 않습니다." + }, + "paymentId": { + "label": "페이먼트 ID (옵션)", + "invalid": "페이먼트 ID가 올바르지 않습니다. 올바른 ID의 문자길이는 16 또는 64 문자입니다." + }, + "sendButton": "보내기", + "cancelButton": "취소" + }, + "qrCodeScanning": { + "explication": "QR코드를 보여주세요." + }, + "notEnoughMoneyModal": { + "title": "잔액부족", + "content": "지갑에 잔액이 부족합니다.", + "confirmText": "확인" + }, + "thankYouDonationModal": { + "title": "기부해 주셔서 감사합니다!", + "content": "당신의 도움에 깊이 감사드립니다. 당신의 기부가 쿼티코인을 발전시킵니다.", + "confirmText": "확인" + }, + "transferSentModal": { + "title": "송금이 성공적으로 완료되었습니다!", + "confirmText": "확인" + }, + "transferExceptionModal": { + "title": "에러", + "content": "에러가 났습니다. 해당 에러를 보고해주세요: {details}", + "confirmText": "확인" + }, + "invalidAmountModal": { + "title": "입력금액", + "content": "입력금액 오류", + "confirmText": "확인" + }, + "creatingTransferModal": { + "title": "송금중", + "content": "잠시만 기다려주세요..." + }, + "finalizingTransferModal": { + "title": "송금 완료중", + "content": "잠시만 기다려주세요..." + }, + "confirmTransactionModal": { + "title": "다음과 같이 송금 하시겠습니까?", + "content": "금액: {amount}
비용: {fees}
총액: {total}", + "confirmText": "확인", + "cancelText": "취소" + }, + "waitingNfcModal": { + "title": "NFC 통신 대기중", + "content": "기기에 더 가까이 가야합니다." + } + }, + "receivePage": { + "title": "쿼티코인 받기", + "receiveBlock": { + "address": { + "title": "주소:", + "label": "이 주소로 송금을 받습니다." + }, + "qrCode": { + "title": "QR코드 만들기:", + "labelAmount": "금액 (옵션)", + "labelRecipient": "받는사람 이름 (옵션)", + "labelDescription": "이체 관련 정보 (옵션)", + "updateButton": "업데이트" + } + }, + "qrBlock": { + "title": "생선된 QR코드" + }, + "waitingNfcToWriteModal": { + "title": "NFC 통신 대기중", + "titleSuccess": "NFC 태그 작성", + "content": "NFC 태그에 더 가까이 가야합니다." + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "태그의 용량이 충분하지 않습니다." + } + }, + "miningPage": { + "title": "브라우져에서 채굴하기", + "subtitle": "채굴을 통해 쿼티코인 네트워크에 도움을 주는 댓가로 쿼티코인을 받을 수 있습니다.", + "parameterBlock": { + "title": "기본정보", + "labelDestinationAddress": "코인을 받을 지갑주소", + "labelThreads": "CPU 쓰레드 갯수 (높을수록 채굴이 더 됩니다.)", + "start": "시작", + "stop": "멈춤" + }, + "statisticsBlocks": { + "title": "통계", + "validShares": "유효한 쉐어", + "hashrate": "해시레이트", + "maxHashrate": "최고 해시레이트", + "dedicatedHardware": "채굴용 소프트웨어와 하드웨어를 사용하면, 더 많은 코인을 받을 수 있으며, 네트워크의 탈중앙화에 도움이 됩니다.", + "miningHandledBy": "이 채굴 작업은 pool.qwertycoin.org에서 처리됩니다." + } + }, + "settingsPage": { + "title": "설정", + "subtitle": "여기서 바꿀 수 있습니다.", + "versionBlock": { + "versionNumber": "버전 넘버: ", + "versionCode": "버전 코드: " + }, + "settingsBlock": { + "speed": { + "label": "지갑 업데이트 속도 (속도가 빠를수록 컴퓨팅 자원이 더 소모됩니다.)", + "fastest": "가장 빠르게", + "fast": "빠르게", + "medium": "보통", + "slow": "천천히" + }, + "language": { + "label": "언어" + }, + "currency": { + "label": "국가 통화" + }, + "readMinerTx": { + "label": "채굴관련 송금 확인 (오직 단독 채굴에 적용됨)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "비밀번호 변경", + "deleteWalletButton": "웹지갑 지우기 (지금 사용하는 기기의 브라우저에 한정)", + "walletSettings": { + "creationHeight": { + "label": "지갑이 생성된 블록높이" + }, + "currentScanningHeight": { + "label": "현재 스캐닝 중인 블록높이" + }, + "updateButton": "업데이트" + }, + "deleteWalletModal": { + "title": "웹지갑 지우기 (지금 사용하는 기기의 브라우저에 한정)", + "content": "정말로 웹지갑을 지금 사용하는 기기에서 삭제합니까? 같은 웹지갑을 다른 웹브라우져에서 사용하고 삭제하지 않은 경우, 다른 웹브라우져에서는 사용이 가능합니다.", + "confirmText": "네, 삭제합니다.", + "cancelText": "취소합니다." + } + }, + "importBasePage": { + "parametersBlock": { + "title": "설정 값", + "password": { + "label": "비밀번호 설정" + }, + "passwordConfirm": { + "label": "비밀번호 확인", + "invalid": "패스워드가 일치하지 않습니다." + }, + "importHeight": { + "label": "불러들일 블록 높이(지갑 생성 블록 높이):" + } + } + }, + "importFromQrPage": { + "title": "QR 코드 사용하여 지갑 불러오기", + "subtitle": "오프라인 백업을 사용하여 지갑 불러오기", + "qrCodeBlock": { + "title": "QR 코드", + "startScanButton": "스캔시작", + "importButton": "불러오기" + }, + "qrScanningBlock": { + "title": "QR 코드를 보여주세요." + } + }, + "exportPage": { + "title": "지갑 정보를 백업해 두세요.", + "publicAddressBlock": { + "title": "지갑주소" + }, + "pdfBlock": { + "title": "PDF 백업", + "downloadButton": "다운로드" + }, + "warningBlock": { + "title": "경고", + "content": "비공개 키 또는 연상단어를 기록 및 저장할 경우, 보안을 위해 기기내에 글자 형식 파일로 보관하지 마세요.
이 파일은 지갑의 모든 키가 암호화되어 있으며 contains a backup of all your transactions to spare you a future synchronisation." + }, + "exportBlock": { + "title": "지갑 정보 내보내기", + "privateKeysButton": "비공개 키 보기", + "mnemonicKeysButton": "연상단어 보기", + "fileButton": "파일로 내보내기" + }, + "walletKeysModal": { + "title": "비공개 키", + "confirmText": "확인", + "content": "비공캐 키를 잘 보관하세요. 비공개 키로 지갑에 접근할 수 있습니다. !
스펜드 키: {privSpendKey}
비공개 뷰 키: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "연상단어", + "confirmText": "확인", + "content": "연상단어를 잘 보관하세요. 연상단어로 지갑에 접근할 수 있습니다. ! 연상단어:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "연상단어의 언어를 선택해 주세요.", + "confirmText": "내보내기" + } + }, + "importPage": { + "title": "지갑 만들기", + "subtitle": "키, 파일 또는 연상단어를 사용하여 가져오기", + "chooseMethod": "지갑을 가져올 방법을 선택해 주세요:", + "fromKeys": "키를 사용하여 가져오기", + "fromFile": "파일을 사용하여 가져오기", + "fromMnemonic": "연상단어 사용하여 가져오기", + "fromQr": "QR 코드 사용하여 가져오기" + }, + "termsOfUsePage": { + "title": "이용약관", + "subtitle": "자세히 읽어주세요." + }, + "privacyPolicyPage": { + "title": "개인 정보 정책", + "subtitle": "자세히 읽어주세요." + }, + "importFromFilePage": { + "title": "백업 파일을 사용하여 지갑 가져오기", + "subtitle": "백업 파일을 사용하여 지갑을 가져오세요.", + "walletBlock": { + "title": "지갑 파일", + "label": "파일 선택하기", + "importButton": "가져오기" + } + }, + "importFromMnemonicPage": { + "title": "연상단어를 사용하여 지갑 가져오기", + "subtitle": "연상단어를 사용하여 지갑을 가져오세요.", + "mnemonicBlock": { + "title": "연상단어", + "mnemonic": { + "label": "연상단어: 25개의 단어", + "invalid": "연상단어가 일치하지 않습니다.", + "language": "언어" + }, + "importButton": "불러오기" + } + }, + "importFromKeysPage": { + "title": "키를 사용하여 지갑 가져오기", + "subtitle": "키를 사용하여 지갑을 가져오세요.", + "parametersBlock": { + "viewOnlyWallet": { + "label": "보기 기능만 가능한 지갑을 만들고 싶으신가요?" + } + }, + "keysBlock": { + "titleNotViewOnly": "지갑 키", + "titleViewOnly": "보기용 지갑", + "privateSpend": { + "label": "비공개 스펜드 키" + }, + "privateView": { + "label": "비공개 뷰 키", + "optional": "(옵션)" + }, + "publicKey": { + "label": "공개 키" + }, + "importButton": "불러오기" + } + } + }, + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": true + } + } +} diff --git a/src/translations/pk.json b/src/translations/pk.json new file mode 100644 index 00000000..e27e0322 --- /dev/null +++ b/src/translations/pk.json @@ -0,0 +1,539 @@ +{ + "website": { + "title": "Qwertycoin والٹ | سادہ، ہموار، محفوظ. مستقبل میں خوش آمدید.", + "description": "Qwertycoin کرنسی کے لئے سرکاری آن لائن والٹ - آپ کے براؤزر میں مکمل طور پر سیکیورٹی کے لئے سنبھال لیا" + }, + "messages": { + "menu": { + "home": "گھر", + "account": "اکاؤنٹ", + "send": "بھیجیں", + "receive": "وصول کرو", + "export": "برآمد کریں", + "donate": "عطیہ", + "elections": "انتخابات", + "contacts": "رابطے", + "settings": "ترتیبات", + "disconnect": "منسلک کریں", + "network": "نیٹ ورک کے اعدادوشمار", + "mining": "کان کنی" + }, + "global": { + "loading": "Loading", + "disableSecurity": "Disable this security, I understand the risk", + "passwordInvalidRequirements": "The password needs at least 8 characters - 1 upper case letter, 1 lower case letter, one number, and one special character", + "passwordConfirmationNotMatching": "The password does not match the first password you wrote", + "download": "Download", + "newVersionModal": { + "title": "A new version is available", + "content": "Do you want to reload to load the new version?", + "confirmText": "Yes", + "cancelText": "Back" + }, + "openWalletModal": { + "title": "Wallet Password", + "confirmText": "Open", + "cancelText": "Cancel" + }, + "invalidPasswordModal": { + "title": "Oops...", + "content": "Your password seems invalid", + "confirmText": "OK" + }, + "invalidMnemonicModal": { + "title": "Oops...", + "content": "The mnemonic phrase is invalid", + "confirmText": "OK" + }, + "passwordNotComplexEnoughModal": { + "title": "The password is not complex enough", + "confirmText": "OK" + }, + "permissionRequiredForCameraModal": { + "title": "Oops...", + "content": "The permission to access your camera is required to scan the QR code", + "confirmText": "OK" + } + }, + "bottom": { + "termsOfUse": "Terms of Use", + "privacyPolicy": "Privacy Policy", + "support": "Support", + "donate": "Donate", + "network": "Network Stats", + "miningPool": "Mining Pool", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Qwertycoin Wallet", + "tagLine": "anywhere. anytime. anyplace. any device.", + "tagLineTwo": "The simplest way to use Qwertycoin", + "actions": { + "loadWallet": "Load my wallet", + "importWallet": "Import a wallet", + "create": "Create", + "createWallet": "Create a wallet" + } + }, + "accountPage": { + "title": "Account", + "subtitle": "Your account overview and transaction history", + "synchronizingBlock": { + "text": "Synchronizing..." + }, + "balanceBlock": { + "title": "Your balance", + "unlocked": "Unlocked" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Transaction history", + "pendingTxStatus": "Pending", + "emptyWallet": "You currently have no funds in this wallet.", + "waitSync": "Please wait until the wallet is updated", + "beReallyPatient": "The initial setup can take some time...", + "getCoinAddress": "Receive QWC" + }, + "txDetails": { + "title": "Transaction details", + "txHash": "Transaction Hash", + "feesOnTx": "Transaction fee", + "blockHeight": "Block height", + "paymentId": "Payment ID", + "unlockStatus": "Status", + "unlockConfirm": "Confirmations", + "txPrivKey": "Transaction Private Key" + } + }, + "changeWalletPasswordPage": { + "title": "Change your password", + "oldPassword": { + "label": "Old password", + "invalid": "The password is invalid" + }, + "newPassword": { + "label": "Choose a new password to protect your wallet" + }, + "newPasswordConfirm": { + "label": "Confirm the new password" + }, + "confirm": "Change the password", + "modalSuccess": { + "title": "Password changed!", + "confirmText": "OK" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "رابطے" + }, + "electionsPage": { + "title": "انتخابات" + }, + "createWalletPage": { + "generatingStep": { + "title": "Your wallet is being generated...", + "subtitle": "It's almost done", + "waitingMessage": "Generating your wallet..." + }, + "finalizationStep": { + "title": "That was simple. Your account is ready!", + "subtitle": "Be ready to use Qwertycoin like you never have", + "passwordSelectionBlock": { + "label": "Protect your wallet" + }, + "passwordConfirmBlock": { + "label": "Confirm the password" + }, + "validPassword": "Use this password", + "backupBlock": { + "title": "Save your private credentials for recovery.", + "option1": "Option 1: ", + "option2": "Option 2: ", + "titlePdf": "Download a PDF copy", + "titleManualWrite": "Write down my keys", + "privateKeys": "Private key", + "mnemonicPhrase": "Mnemonic phrase", + "separatorManualMethodsSolution": " or ", + "confirmManuallyWritten": "I wrote my seed phrase down", + "warningMessage": "**Do not lose it!** It cannot be recovered if you lose it.
**Do not share it!** Your funds will be stolen if you use this file or seed on a malicious/phishing site.
**Make a backup!** Secure it like the millions of dollars it may one day be worth.
", + "finishButton": "I understand. Continue." + } + }, + "disclaimerBlock": { + "title": "Risk of Using QwertycoinWallet", + "content": "QwertycoinWallet is a web-based interface. It helps you use Qwertycoin without running a full Qwertycoin node.
We recommend you treat QwertycoinWallet like you will treat your actual wallet." + } + }, + "donatePage": { + "title": "Donate", + "subtitle": "Help to fund the development and pay the bills", + "webwalletBlock": { + "title": "Webwallet", + "content": "If you want to help to pay for the servers, to support new features development, and like this app, please consider a donation:

" + }, + "devFundBlock": { + "title": "Qwertycoin Dev fund", + "content": "To help Qwertycoin, you can donate at these addresses" + } + }, + "supportPage": { + "title": "Support", + "subtitle": "We are here to help!", + "getInTouchBlock": { + "title": "Let's Get In Touch!", + "content": "Do you have ideas or feedback that could help us improve the wallet? Contact us!", + "discord": "Qwertycoin Discord Channel" + } + }, + "networkPage": { + "title": "Network stats", + "subtitle": "Insights on the Qwertycoin network", + "statsBlock": { + "connectNode": "Connected Masternode", + "hashrate": "Network hashrate", + "height": "Blockchain height", + "difficulty": "Network difficulty", + "lastTimeBlock": "Last block found", + "lastReward": "Last block reward" + } + }, + "sendPage": { + "title": "Send QWC", + "sendBlock": { + "address": { + "label": "Destination address", + "placeholder": "Write the address where you want to send funds", + "invalid": "The destination address is invalid", + "fundsTo": "The funds will be sent to", + "receiver": "Receiver", + "description": "Description" + }, + "amount": { + "label": "Amount to send", + "invalid": "The amount is invalid" + }, + "paymentId": { + "label": "Payment ID (optional)", + "invalid": "The payment ID is invalid. The length must be 16 or 64 characters" + }, + "sendButton": "Send", + "cancelButton": "Cancel" + }, + "qrCodeScanning": { + "explication": "Present the QR code" + }, + "notEnoughMoneyModal": { + "title": "Oops...", + "content": "You don't have enough funds in your wallet to execute this transfer", + "confirmText": "OK" + }, + "thankYouDonationModal": { + "title": "Thank you for your donation!", + "content": "Your help is appreciated. This donation will help make Qwertycoin better", + "confirmText": "OK" + }, + "transferSentModal": { + "title": "Transfer sent successfully!", + "confirmText": "OK" + }, + "transferExceptionModal": { + "title": "Oops...", + "content": "An error occurred. Please report this error: {details}", + "confirmText": "OK" + }, + "invalidAmountModal": { + "title": "Oops...", + "content": "Invalid amount", + "confirmText": "OK" + }, + "creatingTransferModal": { + "title": "Creating transfer ...", + "content": "Please wait..." + }, + "finalizingTransferModal": { + "title": "Finalizing transfer ...", + "content": "Please wait..." + }, + "confirmTransactionModal": { + "title": "Confirm transfer?", + "content": "Amount: {amount}
Fees: {fees}
Total: {total}", + "confirmText": "Confirm", + "cancelText": "Cancel" + }, + "waitingNfcModal": { + "title": "Waiting Nfc", + "content": "Bring closer to the other device" + } + }, + "receivePage": { + "title": "Receive QWC", + "receiveBlock": { + "address": { + "title": "Your address to receive funds:", + "label": "Give this address to receive funds" + }, + "qrCode": { + "title": "Or personalize the QR code:", + "labelAmount": "Amount (optional)", + "labelRecipient": "Recipient name (optional)", + "labelDescription": "Transaction description (optional)", + "updateButton": "Update" + } + }, + "qrBlock": { + "title": "Your customized QR code" + }, + "waitingNfcToWriteModal": { + "title": "Waiting Nfc", + "titleSuccess": "Nfc Tag written", + "content": "Bring closer the NFC tag to write" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Tag capacity insufficient" + } + }, + "miningPage": { + "title": "Mine directly in your browser", + "subtitle": "Support the network by mining and be rewarded with QWC", + "parameterBlock": { + "title": "Parameters", + "labelDestinationAddress": "Wallet to mine", + "labelThreads": "Number of threads (more = higher hashrate)", + "start": "Start", + "stop": "Stop" + }, + "statisticsBlocks": { + "title": "Statistics", + "validShares": "Valid shares", + "hashrate": "Hashrate", + "maxHashrate": "Max Hashrate", + "dedicatedHardware": "With dedicating mining software and hardware, you could earn more and help decentralize the network.", + "miningHandledBy": "This mining is handled by the mining pool pool.qwertycoin.org" + } + }, + "settingsPage": { + "title": "Settings", + "subtitle": "Change your parameters here", + "versionBlock": { + "versionNumber": "Version number: ", + "versionCode": "Version code: " + }, + "settingsBlock": { + "speed": { + "label": "Speed to update the wallet (will consume more resources)", + "fastest": "Fastest", + "fast": "Fast", + "medium": "Medium", + "slow": "Slow" + }, + "language": { + "label": "Language" + }, + "currency": { + "label": "National Currency" + }, + "readMinerTx": { + "label": "Read miner transactions (only for solo mining)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Change my wallet password", + "deleteWalletButton": "Delete my wallet (local copy)", + "walletSettings": { + "creationHeight": { + "label": "Creation height of the wallet" + }, + "currentScanningHeight": { + "label": "Current scanning height" + }, + "updateButton": "Update" + }, + "deleteWalletModal": { + "title": "Delete My Wallet (local copy)", + "content": "Are you sure you REALLY want to delete your wallet ?", + "confirmText": "Yes I'm sure", + "cancelText": "Cancel" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Parameters", + "password": { + "label": "Password to protect your wallet" + }, + "passwordConfirm": { + "label": "Confirm the password", + "invalid": "The password does not match the first password you wrote" + }, + "importHeight": { + "label": "Height to import from:" + } + } + }, + "importFromQrPage": { + "title": "Importing wallet from a QR code", + "subtitle": "Import a wallet from an offline backup", + "qrCodeBlock": { + "title": "QR code", + "startScanButton": "Start the scan", + "importButton": "Import" + }, + "qrScanningBlock": { + "title": "Present the QR code" + } + }, + "exportPage": { + "title": "Backup your credentials", + "publicAddressBlock": { + "title": "Your public address" + }, + "pdfBlock": { + "title": "PDF Backup", + "downloadButton": "Download" + }, + "warningBlock": { + "title": "Warning", + "content": "If you choose to save your private keys or your mnemonic phrase, PLEASE DO NOT store them in clear-text for your own safety.
The file is an alternate solution where your keys are encrypted and contains a backup of all your transactions to spare you a future synchronisation." + }, + "exportBlock": { + "title": "Export your RAW credentials", + "privateKeysButton": "Get my private keys", + "mnemonicKeysButton": "Get my mnemonic phrase", + "fileButton": "Export to a file" + }, + "walletKeysModal": { + "title": "Private keys", + "confirmText": "OK", + "content": "Please carefully store these keys. Possessing them means possessing the funds associated !
Spend key: {privSpendKey}
Private view key: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Mnemonic phrase", + "confirmText": "OK", + "content": "Please store carefully this mnemonic phrase. Possessing it means possessing the funds associated ! The phrase is:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "In which language do you want your mnemonic phrase?", + "confirmText": "Export" + } + }, + "importPage": { + "title": "Create a wallet", + "subtitle": "From previously created keys, file, or mnemonic phrase", + "chooseMethod": "Choose your import method:", + "fromKeys": "From keys", + "fromFile": "From a file", + "fromMnemonic": "From a mnemonic phrase", + "fromQr": "From a QR code" + }, + "termsOfUsePage": { + "title": "Terms of use", + "subtitle": "Please read them carefully." + }, + "privacyPolicyPage": { + "title": "Privacy Policy", + "subtitle": "Please read them carefully." + }, + "importFromFilePage": { + "title": "Importing wallet from a backup file", + "subtitle": "Use your backup file to create a wallet", + "walletBlock": { + "title": "Wallet file", + "label": "Select the file", + "importButton": "Import" + } + }, + "importFromMnemonicPage": { + "title": "Importing wallet from a mnemonic phrase", + "subtitle": "Use your phrase to create a wallet", + "mnemonicBlock": { + "title": "Mnemonic phrase", + "mnemonic": { + "label": "Mnemonic phrase: 25 words", + "invalid": "The mnemonic phrase is invalid", + "language": "Language" + }, + "importButton": "Import" + } + }, + "importFromKeysPage": { + "title": "Importing wallet from keys", + "subtitle": "Use your keys to create a wallet", + "parametersBlock": { + "viewOnlyWallet": { + "label": "Do you want a view only wallet?" + } + }, + "keysBlock": { + "titleNotViewOnly": "Wallet keys", + "titleViewOnly": "View only wallet", + "privateSpend": { + "label": "Private spend key" + }, + "privateView": { + "label": "Private view key", + "optional": "(optional)" + }, + "publicKey": { + "label": "Public key" + }, + "importButton": "Import" + } + } + }, + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": true + } + } +} diff --git a/src/translations/pl.json b/src/translations/pl.json new file mode 100644 index 00000000..e20746de --- /dev/null +++ b/src/translations/pl.json @@ -0,0 +1,539 @@ +{ + "website": { + "title": "Qwertycoin Wallet | Proste, bezproblemowe, bezpieczne. Witamy w przyszłości.", + "description": "Oficjalny portfel online dla waluty Qwertycoin - w pełni obsługiwany w przeglądarce dla optymalnego bezpieczeństwa" + }, + "messages": { + "menu": { + "home": "Dom", + "account": "Konto", + "send": "Wysłać", + "receive": "Otrzymać", + "export": "Eksport", + "donate": "Podarować", + "elections": "Wybory", + "contacts": "Łączność", + "settings": "Ustawienia", + "disconnect": "Rozłączyć się", + "network": "Statystyki sieciowe", + "mining": "Górnictwo" + }, + "global": { + "loading": "Loading", + "disableSecurity": "Disable this security, I understand the risk", + "passwordInvalidRequirements": "The password needs at least 8 characters - 1 upper case letter, 1 lower case letter, one number, and one special character", + "passwordConfirmationNotMatching": "The password does not match the first password you wrote", + "download": "Download", + "newVersionModal": { + "title": "A new version is available", + "content": "Do you want to reload to load the new version?", + "confirmText": "Yes", + "cancelText": "Back" + }, + "openWalletModal": { + "title": "Wallet Password", + "confirmText": "Open", + "cancelText": "Cancel" + }, + "invalidPasswordModal": { + "title": "Oops...", + "content": "Your password seems invalid", + "confirmText": "OK" + }, + "invalidMnemonicModal": { + "title": "Oops...", + "content": "The mnemonic phrase is invalid", + "confirmText": "OK" + }, + "passwordNotComplexEnoughModal": { + "title": "The password is not complex enough", + "confirmText": "OK" + }, + "permissionRequiredForCameraModal": { + "title": "Oops...", + "content": "The permission to access your camera is required to scan the QR code", + "confirmText": "OK" + } + }, + "bottom": { + "termsOfUse": "Terms of Use", + "privacyPolicy": "Privacy Policy", + "support": "Support", + "donate": "Donate", + "network": "Network Stats", + "miningPool": "Mining Pool", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Qwertycoin Wallet", + "tagLine": "anywhere. anytime. anyplace. any device.", + "tagLineTwo": "The simplest way to use Qwertycoin", + "actions": { + "loadWallet": "Load my wallet", + "importWallet": "Import a wallet", + "create": "Create", + "createWallet": "Create a wallet" + } + }, + "accountPage": { + "title": "Account", + "subtitle": "Your account overview and transaction history", + "synchronizingBlock": { + "text": "Synchronizing..." + }, + "balanceBlock": { + "title": "Your balance", + "unlocked": "Unlocked" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Transaction history", + "pendingTxStatus": "Pending", + "emptyWallet": "You currently have no funds in this wallet.", + "waitSync": "Please wait until the wallet is updated", + "beReallyPatient": "The initial setup can take some time...", + "getCoinAddress": "Receive QWC" + }, + "txDetails": { + "title": "Transaction details", + "txHash": "Transaction Hash", + "feesOnTx": "Transaction fee", + "blockHeight": "Block height", + "paymentId": "Payment ID", + "unlockStatus": "Status", + "unlockConfirm": "Confirmations", + "txPrivKey": "Transaction Private Key" + } + }, + "changeWalletPasswordPage": { + "title": "Change your password", + "oldPassword": { + "label": "Old password", + "invalid": "The password is invalid" + }, + "newPassword": { + "label": "Choose a new password to protect your wallet" + }, + "newPasswordConfirm": { + "label": "Confirm the new password" + }, + "confirm": "Change the password", + "modalSuccess": { + "title": "Password changed!", + "confirmText": "OK" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "Łączność" + }, + "electionsPage": { + "title": "Wybory" + }, + "createWalletPage": { + "generatingStep": { + "title": "Your wallet is being generated...", + "subtitle": "It's almost done", + "waitingMessage": "Generating your wallet..." + }, + "finalizationStep": { + "title": "That was simple. Your account is ready!", + "subtitle": "Be ready to use Qwertycoin like you never have", + "passwordSelectionBlock": { + "label": "Protect your wallet" + }, + "passwordConfirmBlock": { + "label": "Confirm the password" + }, + "validPassword": "Use this password", + "backupBlock": { + "title": "Save your private credentials for recovery.", + "option1": "Option 1: ", + "option2": "Option 2: ", + "titlePdf": "Download a PDF copy", + "titleManualWrite": "Write down my keys", + "privateKeys": "Private key", + "mnemonicPhrase": "Mnemonic phrase", + "separatorManualMethodsSolution": " or ", + "confirmManuallyWritten": "I wrote my seed phrase down", + "warningMessage": "**Do not lose it!** It cannot be recovered if you lose it.
**Do not share it!** Your funds will be stolen if you use this file or seed on a malicious/phishing site.
**Make a backup!** Secure it like the millions of dollars it may one day be worth.
", + "finishButton": "I understand. Continue." + } + }, + "disclaimerBlock": { + "title": "Risk of Using QwertycoinWallet", + "content": "QwertycoinWallet is a web-based interface. It helps you use Qwertycoin without running a full Qwertycoin node.
We recommend you treat QwertycoinWallet like you will treat your actual wallet." + } + }, + "donatePage": { + "title": "Donate", + "subtitle": "Help to fund the development and pay the bills", + "webwalletBlock": { + "title": "Webwallet", + "content": "If you want to help to pay for the servers, to support new features development, and like this app, please consider a donation:

" + }, + "devFundBlock": { + "title": "Qwertycoin Dev fund", + "content": "To help Qwertycoin, you can donate at these addresses" + } + }, + "supportPage": { + "title": "Support", + "subtitle": "We are here to help!", + "getInTouchBlock": { + "title": "Let's Get In Touch!", + "content": "Do you have ideas or feedback that could help us improve the wallet? Contact us!", + "discord": "Qwertycoin Discord Channel" + } + }, + "networkPage": { + "title": "Network stats", + "subtitle": "Insights on the Qwertycoin network", + "statsBlock": { + "connectNode": "Connected Masternode", + "hashrate": "Network hashrate", + "height": "Blockchain height", + "difficulty": "Network difficulty", + "lastTimeBlock": "Last block found", + "lastReward": "Last block reward" + } + }, + "sendPage": { + "title": "Send QWC", + "sendBlock": { + "address": { + "label": "Destination address", + "placeholder": "Write the address where you want to send funds", + "invalid": "The destination address is invalid", + "fundsTo": "The funds will be sent to", + "receiver": "Receiver", + "description": "Description" + }, + "amount": { + "label": "Amount to send", + "invalid": "The amount is invalid" + }, + "paymentId": { + "label": "Payment ID (optional)", + "invalid": "The payment ID is invalid. The length must be 16 or 64 characters" + }, + "sendButton": "Send", + "cancelButton": "Cancel" + }, + "qrCodeScanning": { + "explication": "Present the QR code" + }, + "notEnoughMoneyModal": { + "title": "Oops...", + "content": "You don't have enough funds in your wallet to execute this transfer", + "confirmText": "OK" + }, + "thankYouDonationModal": { + "title": "Thank you for your donation!", + "content": "Your help is appreciated. This donation will help make Qwertycoin better", + "confirmText": "OK" + }, + "transferSentModal": { + "title": "Transfer sent successfully!", + "confirmText": "OK" + }, + "transferExceptionModal": { + "title": "Oops...", + "content": "An error occurred. Please report this error: {details}", + "confirmText": "OK" + }, + "invalidAmountModal": { + "title": "Oops...", + "content": "Invalid amount", + "confirmText": "OK" + }, + "creatingTransferModal": { + "title": "Creating transfer ...", + "content": "Please wait..." + }, + "finalizingTransferModal": { + "title": "Finalizing transfer ...", + "content": "Please wait..." + }, + "confirmTransactionModal": { + "title": "Confirm transfer?", + "content": "Amount: {amount}
Fees: {fees}
Total: {total}", + "confirmText": "Confirm", + "cancelText": "Cancel" + }, + "waitingNfcModal": { + "title": "Waiting NFC", + "content": "Bring this device closer to the other device" + } + }, + "receivePage": { + "title": "Receive QWC", + "receiveBlock": { + "address": { + "title": "Your address to receive funds:", + "label": "Give this address to receive funds" + }, + "qrCode": { + "title": "Or personalize the QR code:", + "labelAmount": "Amount (optional)", + "labelRecipient": "Recipient name (optional)", + "labelDescription": "Transaction description (optional)", + "updateButton": "Update" + } + }, + "qrBlock": { + "title": "Your customized QR code" + }, + "waitingNfcToWriteModal": { + "title": "Waiting NFC", + "titleSuccess": "NFC Tag written", + "content": "Bring the NFC tag closer to this device to write" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Tag capacity insufficient" + } + }, + "miningPage": { + "title": "Mine directly in your browser", + "subtitle": "Support the network by mining and be rewarded with QWC", + "parameterBlock": { + "title": "Parameters", + "labelDestinationAddress": "Wallet to mine", + "labelThreads": "Number of threads (more = higher hashrate)", + "start": "Start", + "stop": "Stop" + }, + "statisticsBlocks": { + "title": "Statistics", + "validShares": "Valid shares", + "hashrate": "Hashrate", + "maxHashrate": "Max Hashrate", + "dedicatedHardware": "With dedicating mining software and hardware, you could earn more and help decentralize the network.", + "miningHandledBy": "This mining is handled by the mining pool pool.qwertycoin.org" + } + }, + "settingsPage": { + "title": "Settings", + "subtitle": "Change your parameters here", + "versionBlock": { + "versionNumber": "Version number: ", + "versionCode": "Version code: " + }, + "settingsBlock": { + "speed": { + "label": "Speed to update the wallet (will consume more resources)", + "fastest": "Fastest", + "fast": "Fast", + "medium": "Medium", + "slow": "Slow" + }, + "language": { + "label": "Language" + }, + "currency": { + "label": "National Currency" + }, + "readMinerTx": { + "label": "Read miner transactions (only for solo mining)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Change my wallet password", + "deleteWalletButton": "Delete my wallet (local copy)", + "walletSettings": { + "creationHeight": { + "label": "Creation height of the wallet" + }, + "currentScanningHeight": { + "label": "Current scanning height" + }, + "updateButton": "Update" + }, + "deleteWalletModal": { + "title": "Delete My Wallet (local copy)", + "content": "Are you sure you REALLY want to delete your wallet ?", + "confirmText": "Yes I'm sure", + "cancelText": "Cancel" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Parameters", + "password": { + "label": "Password to protect your wallet" + }, + "passwordConfirm": { + "label": "Confirm the password", + "invalid": "The password does not match the first password you wrote" + }, + "importHeight": { + "label": "Height to import from:" + } + } + }, + "importFromQrPage": { + "title": "Importing wallet from a QR code", + "subtitle": "Import a wallet from an offline backup", + "qrCodeBlock": { + "title": "QR code", + "startScanButton": "Start the scan", + "importButton": "Import" + }, + "qrScanningBlock": { + "title": "Present the QR code" + } + }, + "exportPage": { + "title": "Backup your credentials", + "publicAddressBlock": { + "title": "Your public address" + }, + "pdfBlock": { + "title": "PDF Backup", + "downloadButton": "Download" + }, + "warningBlock": { + "title": "Warning", + "content": "If you choose to save your private keys or your mnemonic phrase, PLEASE DO NOT store them in clear-text for your own safety.
The file is an alternate solution where your keys are encrypted and contains a backup of all your transactions to spare you a future synchronisation." + }, + "exportBlock": { + "title": "Export your RAW credentials", + "privateKeysButton": "Get my private keys", + "mnemonicKeysButton": "Get my mnemonic phrase", + "fileButton": "Export to a file" + }, + "walletKeysModal": { + "title": "Private keys", + "confirmText": "OK", + "content": "Please carefully store these keys. Possessing them means possessing the funds associated !
Spend key: {privSpendKey}
Private view key: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Mnemonic phrase", + "confirmText": "OK", + "content": "Please store carefully this mnemonic phrase. Possessing it means possessing the funds associated ! The phrase is:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "In which language do you want your mnemonic phrase?", + "confirmText": "Export" + } + }, + "importPage": { + "title": "Create a wallet", + "subtitle": "From previously created keys, file, or mnemonic phrase", + "chooseMethod": "Choose your import method:", + "fromKeys": "From keys", + "fromFile": "From a file", + "fromMnemonic": "From a mnemonic phrase", + "fromQr": "From a QR code" + }, + "termsOfUsePage": { + "title": "Terms of use", + "subtitle": "Please read them carefully." + }, + "privacyPolicyPage": { + "title": "Privacy Policy", + "subtitle": "Please read them carefully." + }, + "importFromFilePage": { + "title": "Importing wallet from a backup file", + "subtitle": "Use your backup file to create a wallet", + "walletBlock": { + "title": "Wallet file", + "label": "Select the file", + "importButton": "Import" + } + }, + "importFromMnemonicPage": { + "title": "Importing wallet from a mnemonic phrase", + "subtitle": "Use your phrase to create a wallet", + "mnemonicBlock": { + "title": "Mnemonic phrase", + "mnemonic": { + "label": "Mnemonic phrase: 25 words", + "invalid": "The mnemonic phrase is invalid", + "language": "Language" + }, + "importButton": "Import" + } + }, + "importFromKeysPage": { + "title": "Importing wallet from keys", + "subtitle": "Use your keys to create a wallet", + "parametersBlock": { + "viewOnlyWallet": { + "label": "Do you want a view only wallet?" + } + }, + "keysBlock": { + "titleNotViewOnly": "Wallet keys", + "titleViewOnly": "View only wallet", + "privateSpend": { + "label": "Private spend key" + }, + "privateView": { + "label": "Private view key", + "optional": "(optional)" + }, + "publicKey": { + "label": "Public key" + }, + "importButton": "Import" + } + } + }, + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": true + } + } +} diff --git a/src/translations/pt.json b/src/translations/pt.json new file mode 100644 index 00000000..9c1012ec --- /dev/null +++ b/src/translations/pt.json @@ -0,0 +1,509 @@ +{ + "website":{ + "title":"Carteira Qwertycoin | Simples, sem costura, seguro. Bem vindo ao futuro.", + "description":"Carteira online oficial da moeda Qwertycoin - totalmente manipulado em seu navegador para segurança ideal" + }, + "messages": { + "menu": { + "home": "Origem", + "account": "Conta", + "send": "Enviar", + "receive": "Receber", + "export": "Exportar", + "donate": "Doar", + "settings": "Ajustamento", + "disconnect": "Desconectar", + "network": "Estatísticas da rede", + "mining": "Mineração" + }, + "global": { + "loading": "Carregando", + "disableSecurity":"Desative essa segurança, eu entendo o risco", + "passwordInvalidRequirements":"A senha precisa de pelo menos 8 caracteres - 1 letra maiúscula, 1 letra minúscula, um número e um caractere especial.", + "passwordConfirmationNotMatching":"A senha não corresponde à primeira senha que você escreveu", + "download":"Baixar", + "newVersionModal":{ + "title":"Uma nova versão está disponível", + "content":"Deseja recarregar para carregar a nova versão?", + "confirmText":"Sim", + "cancelText":"Atrás" + }, + "openWalletModal":{ + "title":"Senha da carteira", + "confirmText":"Abrir", + "cancelText":"Cancelar" + }, + "invalidPasswordModal":{ + "title":"Opa...", + "content":"Sua senha parece inválida", + "confirmText":"OK" + }, + "invalidMnemonicModal":{ + "title":"Opa...", + "content":"The mnemonic phrase is invalid", + "confirmText":"OK" + }, + "passwordNotComplexEnoughModal":{ + "title":"A senha não é complexa o suficiente", + "confirmText":"OK" + }, + "permissionRequiredForCameraModal":{ + "title":"Opa...", + "content":"A permissão para acessar sua câmera é necessária para digitalizar o código QR", + "confirmText":"OK" + } + }, + "bottom": { + "termsOfUse": "Termos de uso", + "privacyPolicy": "Política de Privacidade", + "support": "Apoio", + "donate": "Doar", + "network": "Estatísticas da rede", + "miningPool": "Piscina de mineração", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Carteira Qwertycoin", + "tagLine": "qualquer lugar. a qualquer momento. qualquer dispositivo.", + "tagLineTwo": "A maneira mais simples de usar Qwertycoin", + "actions": { + "loadWallet": "Carregar minha carteira", + "importWallet": "Importar uma carteira", + "create": "Criar", + "createWallet": "Crie uma carteira" + } + }, + "accountPage": { + "title": "Conta", + "subtitle": "Visão geral da sua conta e histórico de transações", + "synchronizingBlock": { + "text": "Sincronizando..." + }, + "balanceBlock": { + "title": "Seu balanço", + "unlocked": "Desbloqueado" + }, + "currencyBlock" : { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Histórico de transações", + "pendingTxStatus": "Pendente", + "emptyWallet": "No momento, você não tem fundos nesta carteira.", + "waitSync": "Aguarde até que a carteira seja atualizada", + "beReallyPatient": "A configuração inicial pode levar algum tempo...", + "getCoinAddress": "Receba QWC" + }, + "txDetails":{ + "title":"Detalhes da transação", + "txHash":"Hash de transação", + "feesOnTx":"Taxa de transação", + "blockHeight":"Altura do bloco", + "paymentId":"ID de pagamento", + "unlockStatus":"Estado", + "unlockConfirm":"Confirmações", + "txPrivKey":"Chave privada de transação" + } + }, + "changeWalletPasswordPage":{ + "title":"Mude sua senha", + "oldPassword":{ + "label":"Senha Antiga", + "invalid":"A senha é inválida" + }, + "newPassword":{ + "label":"Escolha uma nova senha para proteger sua carteira" + }, + "newPasswordConfirm":{ + "label":"Confirme a nova senha" + }, + "confirm":"Mude a senha", + "modalSuccess":{ + "title":"Senha alterada!", + "confirmText":"OK" + } + }, + "createWalletPage":{ + "generatingStep":{ + "title":"Sua carteira está sendo gerada...", + "subtitle":"Está quase pronto", + "waitingMessage":"Gerando sua carteira..." + }, + "finalizationStep":{ + "title":"Isso foi simples. Sua conta está pronta!", + "subtitle":"Esteja pronto para usar o Qwertycoin como você nunca viu", + "passwordSelectionBlock":{ + "label":"Proteja sua carteira" + }, + "passwordConfirmBlock":{ + "label":"Confirme a senha" + }, + "validPassword":"Use esta senha", + "backupBlock":{ + "title":"Salve suas credenciais privadas para recuperação.", + "option1":"Opção 1: ", + "option2":"Opção 2: ", + "titlePdf":"Faça o download de uma cópia em PDF", + "titleManualWrite":"Anote minhas chaves", + "privateKeys":"Chave privada", + "mnemonicPhrase":"Frase mnemônica", + "separatorManualMethodsSolution":" ou ", + "confirmManuallyWritten":"Eu escrevi minha frase inicial", + "warningMessage":"**Não perca isso!** Não pode ser recuperado se você o perder..
**Não compartilhe!** Seus fundos serão roubados se você usar esse arquivo ou semente em um site malicioso / phishing.
**Faça um backup!** Proteja-o como os milhões de dólares que um dia valerão a pena.
", + "finishButton":"Compreendo. Continuar." + } + }, + "disclaimerBlock":{ + "title":"Risco de usar Carteira Qwertycoin", + "content":"Carteira Qwertycoin é uma interface baseada na Web. Ajuda você a usar o Qwertycoin sem executar um nó completo do Qwertycoin.
Recomendamos que você trate o QwertycoinWallet como tratará sua carteira real." + } + }, + "donatePage":{ + "title":"Doar", + "subtitle":"Ajude a financiar o desenvolvimento e pagar as contas", + "webwalletBlock":{ + "title":"Carteira Web", + "content":"Se você quiser ajudar a pagar pelos servidores, apoiar o desenvolvimento de novos recursos e, como este aplicativo, considere uma doação:

" + }, + "devFundBlock":{ + "title":"Fundo Qwertycoin Dev", + "content":"Para ajudar o Qwertycoin, você pode doar nesses endereços" + } + }, + "supportPage":{ + "title":"Apoio", + "subtitle":"Estamos aqui para ajudar!", + "getInTouchBlock":{ + "title":"Vamos entrar em contato!", + "content":"Você tem idéias ou comentários que podem nos ajudar a melhorar a carteira? Contate-Nos!", + "discord":"Canal Discord de Qwertycoin" + } + }, + "networkPage":{ + "title":"Estatísticas da rede", + "subtitle":"Informações sobre a rede Qwertycoin", + "statsBlock":{ + "connectNode": "Masternode conectado", + "hashrate":"Hash de rede", + "height":"Altura da Blockchain", + "difficulty":"Dificuldade de rede", + "lastTimeBlock":"Último bloco encontrado", + "lastReward":"Recompensa do último bloco" + } + }, + "sendPage":{ + "title":"Enviar QWC", + "sendBlock":{ + "address":{ + "label":"Endereço de destino", + "placeholder":"Escreva o endereço para onde deseja enviar fundos", + "invalid":"O endereço de destino é inválido", + "fundsTo":"Os fundos serão enviados para", + "receiver":"Receptor", + "description":"Descrição" + }, + "amount":{ + "label":"Quantidade a enviar", + "invalid":"O valor é inválido" + }, + "paymentId":{ + "label":"ID de pagamento (opcional)", + "invalid":"O ID do pagamento é inválido. O comprimento deve ter 16 ou 64 caracteres" + }, + "sendButton":"Enviar", + "cancelButton":"Cancelar" + }, + "qrCodeScanning":{ + "explication":"Apresente o código QR" + }, + "notEnoughMoneyModal":{ + "title":"Opa...", + "content":"Você não tem fundos suficientes na sua carteira para executar esta transferência", + "confirmText":"OK" + }, + "thankYouDonationModal":{ + "title":"Obrigado por sua doação!", + "content":"Sua ajuda é apreciada. Esta doação ajudará a melhorar o Qwertycoin", + "confirmText":"OK" + }, + "transferSentModal":{ + "title":"Transferência enviada com sucesso!", + "confirmText":"OK" + }, + "transferExceptionModal":{ + "title":"Opa...", + "content":"Um erro ocorreu. Por favor, reporte este erro: {details}", + "confirmText":"OK" + }, + "invalidAmountModal":{ + "title":"Opa...", + "content":"Montante inválido", + "confirmText":"OK" + }, + "creatingTransferModal":{ + "title":"Criando transferência ...", + "content":"Por favor, espere..." + }, + "finalizingTransferModal":{ + "title":"Finalizando a transferência ...", + "content":"Por favor, espere..." + }, + "confirmTransactionModal":{ + "title":"Confirmar transferência?", + "content":"Montante: {amount}
Honorários: {fees}
Total: {total}", + "confirmText":"Confirme", + "cancelText":"Cancelar" + }, + "waitingNfcModal":{ + "title":"Aguardando NFC", + "content":"Aproxime este dispositivo do outro dispositivo" + } + }, + "receivePage":{ + "title":"Receba QWC", + "receiveBlock":{ + "address":{ + "title":"Seu endereço para receber fundos:", + "label":"Dê este endereço para receber fundos" + }, + "qrCode":{ + "title":"Ou personalize o código QR:", + "labelAmount":"Montante (opcional)", + "labelRecipient":"Nome do destinatário (opcional)", + "labelDescription":"Descrição da transação (opcional)", + "updateButton":"Atualizar" + } + }, + "qrBlock":{ + "title":"Seu código QR personalizado" + }, + "waitingNfcToWriteModal":{ + "title":"Aguardando NFC", + "titleSuccess":"Etiqueta NFC escrita", + "content":"Aproxime a etiqueta NFC deste dispositivo para gravar" + }, + "nfcErrorModal":{ + "titleInsufficientCapacity":"Capacidade da etiqueta insuficiente" + } + }, + "miningPage":{ + "title":"Mine diretamente no seu navegador", + "subtitle":"Ofereça suporte à rede por mineração e seja recompensado com a QWC", + "parameterBlock":{ + "title":"Parâmetros", + "labelDestinationAddress":"Carteira para a minha", + "labelThreads":"Número de threads (mais = hash maior)", + "start":"Começar", + "stop":"Pare" + }, + "statisticsBlocks":{ + "title":"Estatisticas", + "validShares":"Compartilhamentos válidos", + "hashrate":"Taxa de hash", + "maxHashrate":"Taxa máxima de hash", + "dedicatedHardware":"Com a dedicação de software e hardware de mineração, você pode ganhar mais e ajudar a descentralizar a rede.", + "miningHandledBy":"Esta mineração é tratado pela associação mineira pool.qwertycoin.org" + } + }, + "settingsPage":{ + "title":"Ajustamento", + "subtitle":"Mude seus parâmetros aqui", + "versionBlock":{ + "versionNumber":"Número da versão: ", + "versionCode":"Código da versão: " + }, + "settingsBlock":{ + "speed":{ + "label":"Velocidade para atualizar a carteira (consumirá mais recursos)", + "fastest":"O mais rápido", + "fast":"Rápido", + "medium":"Médio", + "slow":"Lento" + }, + "language":{ + "label":"Língua" + }, + "currency":{ + "label":"Moeda nacional" + }, + "readMinerTx":{ + "label":"Ler transações de mineração (apenas para mineração solo)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton":"Alterar minha senha da carteira", + "deleteWalletButton":"Excluir minha carteira (cópia local)", + "walletSettings":{ + "creationHeight":{ + "label":"Altura de criação da carteira" + }, + "currentScanningHeight": { + "label": "Altura atual de digitalização" + }, + "updateButton":"Atualizar" + }, + "deleteWalletModal":{ + "title":"Excluir minha carteira (cópia local)", + "content":"Tem certeza de que REALMENTE deseja excluir sua carteira?", + "confirmText":"Sim eu tenho certeza", + "cancelText":"Cancelar" + } + }, + "importBasePage":{ + "parametersBlock":{ + "title":"Parâmetros", + "password":{ + "label":"Senha para proteger sua carteira" + }, + "passwordConfirm":{ + "label":"Confirme a senha", + "invalid":"A senha não corresponde à primeira senha que você escreveu" + }, + "importHeight":{ + "label":"Altura para importar de:" + } + } + }, + "importFromQrPage":{ + "title":"Importando carteira de um código QR", + "subtitle":"Importar uma carteira de um backup offline", + "qrCodeBlock":{ + "title":"Código QR", + "startScanButton":"Iniciar a verificação", + "importButton":"Importar" + }, + "qrScanningBlock":{ + "title":"Apresente o código QR" + } + }, + "exportPage":{ + "title":"Faça backup de suas credenciais", + "publicAddressBlock":{ + "title":"Seu endereço público" + }, + "pdfBlock":{ + "title":"Backup de PDF", + "downloadButton":"Baixar" + }, + "warningBlock":{ + "title":"Atenção", + "content":"Se você optar por salvar suas chaves privadas ou sua frase mnemônica, NÃO as armazene em texto não criptografado para sua própria segurança.
O arquivo é uma solução alternativa em que suas chaves são criptografadas e contêm um backup de todas as suas transações. para poupar uma futura sincronização." + }, + "exportBlock":{ + "title":"Exporte suas credenciais RAW", + "privateKeysButton":"Obter minhas chaves privadas", + "mnemonicKeysButton":"Pegue minha frase mnemônica", + "fileButton":"Exportar para um arquivo" + }, + "walletKeysModal":{ + "title":"Chaves privadas", + "confirmText":"OK", + "content":"Por favor, guarde essas chaves com cuidado. Possuí-los significa possuir os fundos associados !
Chave de gastos: {privSpendKey}
Chave de visualização privada: {privViewKey}" + }, + "mnemonicKeyModal":{ + "title":"Frase mnemônica", + "confirmText":"OK", + "content":"Por favor, guarde cuidadosamente esta frase mnemônica. Possuir significa possuir os fundos associados ! A frase é:
{mnemonic}" + }, + "mnemonicLangSelectionModal":{ + "title":"Em qual idioma você quer sua frase mnemônica?", + "confirmText":"Exportação" + } + }, + "importPage":{ + "title":"Crie uma carteira", + "subtitle":"De chaves, arquivos ou frases mnemônicas criadas anteriormente", + "chooseMethod":"Escolha o seu método de importação:", + "fromKeys":"Das chaves", + "fromFile":"De um arquivo", + "fromMnemonic":"De uma frase mnemônica", + "fromQr":"De um código QR" + }, + "termsOfUsePage":{ + "title":"Termos de uso", + "subtitle":"Por favor, leia-os cuidadosamente." + }, + "privacyPolicyPage":{ + "title":"Política de Privacidade", + "subtitle":"Por favor, leia-os cuidadosamente." + }, + "importFromFilePage":{ + "title":"Importando carteira de um arquivo de backup", + "subtitle":"Use seu arquivo de backup para criar uma carteira", + "walletBlock":{ + "title":"Arquivo da carteira", + "label":"Selecione o arquivo", + "importButton":"Importar" + } + }, + "importFromMnemonicPage":{ + "title":"Importando carteira de uma frase mnemônica", + "subtitle":"Use sua frase para criar uma carteira", + "mnemonicBlock":{ + "title":"Frase mnemônica", + "mnemonic":{ + "label":"Frase mnemônica: 25 palavras", + "invalid":"A frase mnemônica é inválida", + "language":"Língua" + }, + "importButton":"Importar" + } + }, + "importFromKeysPage":{ + "title":"Importando carteira de chaves", + "subtitle":"Use suas chaves para criar uma carteira", + "parametersBlock":{ + "viewOnlyWallet":{ + "label":"Você quer ver apenas uma carteira?" + } + }, + "keysBlock":{ + "titleNotViewOnly":"Chaves da carteira", + "titleViewOnly":"Ver apenas carteira", + "privateSpend":{ + "label":"Chave de gastos privados" + }, + "privateView":{ + "label":"Chave de visualização privada", + "optional":"(opcional)" + }, + "publicKey":{ + "label":"Chave pública" + }, + "importButton":"Importar" + } + } + }, + "number":{ + }, + "date":{ + "short": { + "year": "numeric", "month": "short", "day": "numeric" + }, + "long": { + "year": "numeric", "month": "short", "day": "numeric", + "weekday": "short", "hour": "numeric", "minute": "numeric", "hour12": true + } + } +} diff --git a/src/translations/ro.json b/src/translations/ro.json new file mode 100644 index 00000000..2ffc1c79 --- /dev/null +++ b/src/translations/ro.json @@ -0,0 +1,539 @@ +{ + "website": { + "title": "Portofel Qwertycoin | Simplu, fără probleme, sigur. Bine ați venit în viitor.", + "description": "Portofel oficial online pentru moneda Qwertycoin - manipulată integral în browserul dvs. pentru o securitate optimă" + }, + "messages": { + "menu": { + "home": "Acasă", + "account": "Cont", + "send": "Trimite", + "receive": "A primi", + "export": "Export", + "donate": "Dona", + "elections": "Alegeri", + "contacts": "Contacte", + "settings": "Setări", + "disconnect": "Deconecta", + "network": "Statistici de rețea", + "mining": "Minerit" + }, + "global": { + "loading": "Loading", + "disableSecurity": "Disable this security, I understand the risk", + "passwordInvalidRequirements": "The password needs at least 8 characters - 1 upper case letter, 1 lower case letter, one number, and one special character", + "passwordConfirmationNotMatching": "The password does not match the first password you wrote", + "download": "Download", + "newVersionModal": { + "title": "A new version is available", + "content": "Do you want to reload to load the new version?", + "confirmText": "Yes", + "cancelText": "Back" + }, + "openWalletModal": { + "title": "Wallet Password", + "confirmText": "Open", + "cancelText": "Cancel" + }, + "invalidPasswordModal": { + "title": "Oops...", + "content": "Your password seems invalid", + "confirmText": "OK" + }, + "invalidMnemonicModal": { + "title": "Oops...", + "content": "The mnemonic phrase is invalid", + "confirmText": "OK" + }, + "passwordNotComplexEnoughModal": { + "title": "The password is not complex enough", + "confirmText": "OK" + }, + "permissionRequiredForCameraModal": { + "title": "Oops...", + "content": "The permission to access your camera is required to scan the QR code", + "confirmText": "OK" + } + }, + "bottom": { + "termsOfUse": "Terms of Use", + "privacyPolicy": "Privacy Policy", + "support": "Support", + "donate": "Donate", + "network": "Network Stats", + "miningPool": "Mining Pool", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Qwertycoin Wallet", + "tagLine": "anywhere. anytime. anyplace. any device.", + "tagLineTwo": "The simplest way to use Qwertycoin", + "actions": { + "loadWallet": "Load my wallet", + "importWallet": "Import a wallet", + "create": "Create", + "createWallet": "Create a wallet" + } + }, + "accountPage": { + "title": "Account", + "subtitle": "Your account overview and transaction history", + "synchronizingBlock": { + "text": "Synchronizing..." + }, + "balanceBlock": { + "title": "Your balance", + "unlocked": "Unlocked" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Transaction history", + "pendingTxStatus": "Pending", + "emptyWallet": "You currently have no funds in this wallet.", + "waitSync": "Please wait until the wallet is updated", + "beReallyPatient": "The initial setup can take some time...", + "getCoinAddress": "Receive QWC" + }, + "txDetails": { + "title": "Transaction details", + "txHash": "Transaction Hash", + "feesOnTx": "Transaction fee", + "blockHeight": "Block height", + "paymentId": "Payment ID", + "unlockStatus": "Status", + "unlockConfirm": "Confirmations", + "txPrivKey": "Transaction Private Key" + } + }, + "changeWalletPasswordPage": { + "title": "Change your password", + "oldPassword": { + "label": "Old password", + "invalid": "The password is invalid" + }, + "newPassword": { + "label": "Choose a new password to protect your wallet" + }, + "newPasswordConfirm": { + "label": "Confirm the new password" + }, + "confirm": "Change the password", + "modalSuccess": { + "title": "Password changed!", + "confirmText": "OK" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "Contacte" + }, + "electionsPage": { + "title": "Alegeri" + }, + "createWalletPage": { + "generatingStep": { + "title": "Your wallet is being generated...", + "subtitle": "It's almost done", + "waitingMessage": "Generating your wallet..." + }, + "finalizationStep": { + "title": "That was simple. Your account is ready!", + "subtitle": "Be ready to use Qwertycoin like you never have", + "passwordSelectionBlock": { + "label": "Protect your wallet" + }, + "passwordConfirmBlock": { + "label": "Confirm the password" + }, + "validPassword": "Use this password", + "backupBlock": { + "title": "Save your private credentials for recovery.", + "option1": "Option 1: ", + "option2": "Option 2: ", + "titlePdf": "Download a PDF copy", + "titleManualWrite": "Write down my keys", + "privateKeys": "Private key", + "mnemonicPhrase": "Mnemonic phrase", + "separatorManualMethodsSolution": " or ", + "confirmManuallyWritten": "I wrote my seed phrase down", + "warningMessage": "**Do not lose it!** It cannot be recovered if you lose it.
**Do not share it!** Your funds will be stolen if you use this file or seed on a malicious/phishing site.
**Make a backup!** Secure it like the millions of dollars it may one day be worth.
", + "finishButton": "I understand. Continue." + } + }, + "disclaimerBlock": { + "title": "Risk of Using QwertycoinWallet", + "content": "QwertycoinWallet is a web-based interface. It helps you use Qwertycoin without running a full Qwertycoin node.
We recommend you treat QwertycoinWallet like you will treat your actual wallet." + } + }, + "donatePage": { + "title": "Donate", + "subtitle": "Help to fund the development and pay the bills", + "webwalletBlock": { + "title": "Webwallet", + "content": "If you want to help to pay for the servers, to support new features development, and like this app, please consider a donation:

" + }, + "devFundBlock": { + "title": "Qwertycoin Dev fund", + "content": "To help Qwertycoin, you can donate at these addresses" + } + }, + "supportPage": { + "title": "Support", + "subtitle": "We are here to help!", + "getInTouchBlock": { + "title": "Let's Get In Touch!", + "content": "Do you have ideas or feedback that could help us improve the wallet? Contact us!", + "discord": "Qwertycoin Discord Channel" + } + }, + "networkPage": { + "title": "Network stats", + "subtitle": "Insights on the Qwertycoin network", + "statsBlock": { + "connectNode": "Connected Masternode", + "hashrate": "Network hashrate", + "height": "Blockchain height", + "difficulty": "Network difficulty", + "lastTimeBlock": "Last block found", + "lastReward": "Last block reward" + } + }, + "sendPage": { + "title": "Send QWC", + "sendBlock": { + "address": { + "label": "Destination address", + "placeholder": "Write the address where you want to send funds", + "invalid": "The destination address is invalid", + "fundsTo": "The funds will be sent to", + "receiver": "Receiver", + "description": "Description" + }, + "amount": { + "label": "Amount to send", + "invalid": "The amount is invalid" + }, + "paymentId": { + "label": "Payment ID (optional)", + "invalid": "The payment ID is invalid. The length must be 16 or 64 characters" + }, + "sendButton": "Send", + "cancelButton": "Cancel" + }, + "qrCodeScanning": { + "explication": "Present the QR code" + }, + "notEnoughMoneyModal": { + "title": "Oops...", + "content": "You don't have enough funds in your wallet to execute this transfer", + "confirmText": "OK" + }, + "thankYouDonationModal": { + "title": "Thank you for your donation!", + "content": "Your help is appreciated. This donation will help make Qwertycoin better", + "confirmText": "OK" + }, + "transferSentModal": { + "title": "Transfer sent successfully!", + "confirmText": "OK" + }, + "transferExceptionModal": { + "title": "Oops...", + "content": "An error occurred. Please report this error: {details}", + "confirmText": "OK" + }, + "invalidAmountModal": { + "title": "Oops...", + "content": "Invalid amount", + "confirmText": "OK" + }, + "creatingTransferModal": { + "title": "Creating transfer ...", + "content": "Please wait..." + }, + "finalizingTransferModal": { + "title": "Finalizing transfer ...", + "content": "Please wait..." + }, + "confirmTransactionModal": { + "title": "Confirm transfer?", + "content": "Amount: {amount}
Fees: {fees}
Total: {total}", + "confirmText": "Confirm", + "cancelText": "Cancel" + }, + "waitingNfcModal": { + "title": "Waiting NFC", + "content": "Bring this device closer to the other device" + } + }, + "receivePage": { + "title": "Receive QWC", + "receiveBlock": { + "address": { + "title": "Your address to receive funds:", + "label": "Give this address to receive funds" + }, + "qrCode": { + "title": "Or personalize the QR code:", + "labelAmount": "Amount (optional)", + "labelRecipient": "Recipient name (optional)", + "labelDescription": "Transaction description (optional)", + "updateButton": "Update" + } + }, + "qrBlock": { + "title": "Your customized QR code" + }, + "waitingNfcToWriteModal": { + "title": "Waiting NFC", + "titleSuccess": "NFC Tag written", + "content": "Bring the NFC tag closer to this device to write" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Tag capacity insufficient" + } + }, + "miningPage": { + "title": "Mine directly in your browser", + "subtitle": "Support the network by mining and be rewarded with QWC", + "parameterBlock": { + "title": "Parameters", + "labelDestinationAddress": "Wallet to mine", + "labelThreads": "Number of threads (more = higher hashrate)", + "start": "Start", + "stop": "Stop" + }, + "statisticsBlocks": { + "title": "Statistics", + "validShares": "Valid shares", + "hashrate": "Hashrate", + "maxHashrate": "Max Hashrate", + "dedicatedHardware": "With dedicating mining software and hardware, you could earn more and help decentralize the network.", + "miningHandledBy": "This mining is handled by the mining pool pool.qwertycoin.org" + } + }, + "settingsPage": { + "title": "Settings", + "subtitle": "Change your parameters here", + "versionBlock": { + "versionNumber": "Version number: ", + "versionCode": "Version code: " + }, + "settingsBlock": { + "speed": { + "label": "Speed to update the wallet (will consume more resources)", + "fastest": "Fastest", + "fast": "Fast", + "medium": "Medium", + "slow": "Slow" + }, + "language": { + "label": "Language" + }, + "currency": { + "label": "National Currency" + }, + "readMinerTx": { + "label": "Read miner transactions (only for solo mining)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Change my wallet password", + "deleteWalletButton": "Delete my wallet (local copy)", + "walletSettings": { + "creationHeight": { + "label": "Creation height of the wallet" + }, + "currentScanningHeight": { + "label": "Current scanning height" + }, + "updateButton": "Update" + }, + "deleteWalletModal": { + "title": "Delete My Wallet (local copy)", + "content": "Are you sure you REALLY want to delete your wallet ?", + "confirmText": "Yes I'm sure", + "cancelText": "Cancel" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Parameters", + "password": { + "label": "Password to protect your wallet" + }, + "passwordConfirm": { + "label": "Confirm the password", + "invalid": "The password does not match the first password you wrote" + }, + "importHeight": { + "label": "Height to import from:" + } + } + }, + "importFromQrPage": { + "title": "Importing wallet from a QR code", + "subtitle": "Import a wallet from an offline backup", + "qrCodeBlock": { + "title": "QR code", + "startScanButton": "Start the scan", + "importButton": "Import" + }, + "qrScanningBlock": { + "title": "Present the QR code" + } + }, + "exportPage": { + "title": "Backup your credentials", + "publicAddressBlock": { + "title": "Your public address" + }, + "pdfBlock": { + "title": "PDF Backup", + "downloadButton": "Download" + }, + "warningBlock": { + "title": "Warning", + "content": "If you choose to save your private keys or your mnemonic phrase, PLEASE DO NOT store them in clear-text for your own safety.
The file is an alternate solution where your keys are encrypted and contains a backup of all your transactions to spare you a future synchronisation." + }, + "exportBlock": { + "title": "Export your RAW credentials", + "privateKeysButton": "Get my private keys", + "mnemonicKeysButton": "Get my mnemonic phrase", + "fileButton": "Export to a file" + }, + "walletKeysModal": { + "title": "Private keys", + "confirmText": "OK", + "content": "Please carefully store these keys. Possessing them means possessing the funds associated !
Spend key: {privSpendKey}
Private view key: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Mnemonic phrase", + "confirmText": "OK", + "content": "Please store carefully this mnemonic phrase. Possessing it means possessing the funds associated ! The phrase is:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "In which language do you want your mnemonic phrase?", + "confirmText": "Export" + } + }, + "importPage": { + "title": "Create a wallet", + "subtitle": "From previously created keys, file, or mnemonic phrase", + "chooseMethod": "Choose your import method:", + "fromKeys": "From keys", + "fromFile": "From a file", + "fromMnemonic": "From a mnemonic phrase", + "fromQr": "From a QR code" + }, + "termsOfUsePage": { + "title": "Terms of use", + "subtitle": "Please read them carefully." + }, + "privacyPolicyPage": { + "title": "Privacy Policy", + "subtitle": "Please read them carefully." + }, + "importFromFilePage": { + "title": "Importing wallet from a backup file", + "subtitle": "Use your backup file to create a wallet", + "walletBlock": { + "title": "Wallet file", + "label": "Select the file", + "importButton": "Import" + } + }, + "importFromMnemonicPage": { + "title": "Importing wallet from a mnemonic phrase", + "subtitle": "Use your phrase to create a wallet", + "mnemonicBlock": { + "title": "Mnemonic phrase", + "mnemonic": { + "label": "Mnemonic phrase: 25 words", + "invalid": "The mnemonic phrase is invalid", + "language": "Language" + }, + "importButton": "Import" + } + }, + "importFromKeysPage": { + "title": "Importing wallet from keys", + "subtitle": "Use your keys to create a wallet", + "parametersBlock": { + "viewOnlyWallet": { + "label": "Do you want a view only wallet?" + } + }, + "keysBlock": { + "titleNotViewOnly": "Wallet keys", + "titleViewOnly": "View only wallet", + "privateSpend": { + "label": "Private spend key" + }, + "privateView": { + "label": "Private view key", + "optional": "(optional)" + }, + "publicKey": { + "label": "Public key" + }, + "importButton": "Import" + } + } + }, + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": true + } + } +} diff --git a/src/translations/ru.json b/src/translations/ru.json index 5ebdcf3b..803eb8f3 100644 --- a/src/translations/ru.json +++ b/src/translations/ru.json @@ -1,492 +1,536 @@ { - "website":{ - "title":"Веб-кошелек Карбо", - "description":"Официальный онлайн кошелек криптовалюты Карбованец - анонимный, надежный, работающий полностью в вашем браузере для наилучшей безопасности" + "website": { + "title": "Веб-кошелек Qwertycoin", + "description": "Официальный онлайн кошелек криптовалюты Qwertycoin - анонимный, надежный, работающий полностью в вашем браузере для наилучшей безопасности" }, "messages": { - "menu": { - "home": "Обзор", - "account": "Аккаунт", - "send": "Отправить", - "receive": "Получить", - "export": "Экспорт", - "donate": "Пожертвовать", - "settings": "Настройки", - "disconnect": "Отключиться", - "network": "Статистика сети", - "mining": "Майнинг" - }, - "global": { - "loading": "Загрузка", - "disableSecurity":"Отключить эту предосторожность, я понимаю риск", - "passwordInvalidRequirements":"Пароль должен состоять по крайней мере из 8 символов - 1 большой буквы, 1 маленькой, одного числа, одного спецсимвола", - "passwordConfirmationNotMatching":"Подтверждение пароля не совпадает с первым", - "download":"Скачать", - "newVersionModal":{ - "title":"Есть новая версия", - "content":"Хотите перезагрузить чтобы обновить версию?", - "confirmText":"Да", - "cancelText":"Назад" - }, - "openWalletModal":{ - "title":"Пароль кошелька", - "confirmText":"Открыть", - "cancelText":"Отмена" - }, - "invalidPasswordModal":{ - "title":"Ой...", - "content":"Кажется пароль неверный", - "confirmText":"OK" - }, - "invalidMnemonicModal":{ - "title":"Ой...", - "content":"Фраза для восстановления неверная", - "confirmText":"OK" - }, - "passwordNotComplexEnoughModal":{ - "title":"Пароль недостаточно сложный", - "confirmText":"OK" - }, - "permissionRequiredForCameraModal":{ - "title":"Ой...", - "content":"Требуется разрешение на доступ к камере для сканирования QR кода", - "confirmText":"OK" - } - }, - "bottom": { - "termsOfUse": "Условия использования", - "privacyPolicy": "Политика конфиденциальности", - "support": "Поддержка", - "donate": "Пожертвовать", - "network": "Статистика сети", - "miningPool": "Майнинг", - "github": "GitHub" - }, - "homepage": { - "mainTitle": "Защищенный Кошелек Карбованца", - "tagLine": "Самый простой способ использования карбованцев – в любое время, в любом месте", - "actions": { - "loadWallet": "Загрузить мой кошелек", - "importWallet": "Импортировать кошелек", - "create": "Создать", - "createWallet": "Создать кошелек" - }, - "notes": { - "secure": { - "title": "Безопасный", - "description": "Без серверов, полностью зашифрован!" - }, - "fast": { - "title": "Быстрый", - "description": "Доступен когда надо!" - }, - "technology": { - "title": "Локальный", - "description": "Ключи в браузере" - }, - "openSource": { - "title": "Open-source", - "description": "Не доверяй - проверяй!" - } - } - }, - "accountPage": { - "title": "Аккаунт", - "subtitle": "Обзор вашей учетной записи и истории транзакций", - "synchronizingBlock": { - "text": "Синхронизация..." - }, - "balanceBlock": { - "title": "Ваш баланс", - "unlocked": "Доступно" - }, - "historyBlock": { - "title": "История транзакций", - "pendingTxStatus": "Ожидается", - "emptyWallet": "В этом кошельке пока нет средств.", - "waitSync": "Пожалуйста подождите пока кошелек обновляется", - "beReallyPatient": "Начальная установка может занять некоторое время...", - "getCoinAddress": "Получить KRB" - }, - "txDetails":{ - "title":"Детали транзакции", - "txHash":"Хеш", - "feesOnTx":"Комиссия", - "blockHeight":"Высота блока", - "paymentId":"Идентификатор платежа", - "txPrivKey":"Секретный ключ транзакции" - } - }, - "changeWalletPasswordPage":{ - "title":"Изменить ваш пароль", - "oldPassword":{ - "label":"Старый пароль", - "invalid":"Пароль недействительный" - }, - "newPassword":{ - "label":"Выберите новый пароль для зашиты вашего кошелька" - }, - "newPasswordConfirm":{ - "label":"Подтвердите новый пароль" - }, - "confirm":"Изменить пароль", - "modalSuccess":{ - "title":"Пароль изменен!", - "confirmText":"OK" - } - }, - "createWalletPage":{ - "generatingStep":{ - "title":"Создается кошелек...", - "subtitle":"Почти готово", - "waitingMessage":"Генерируется кошелек..." - }, - "finalizationStep":{ - "title":"Все. Ваш кошелек готов!", - "subtitle":"Приготовьтесь использовать Карбо как никогда до этого", - "passwordSelectionBlock":{ - "label":"Защитите ваш кошелек" - }, - "passwordConfirmBlock":{ - "label":"Подтвердите пароль" - }, - "validPassword":"Использовать этот пароль", - "backupBlock":{ - "title":"Сохраните ваши приватные данные чтобы иметь возможность восстановления.", - "option1":"Опция 1: ", - "option2":"Опция 2: ", - "titlePdf":"Скачать PDF", - "titleManualWrite":"Записать ключи", - "privateKeys":"Приватный ключ", - "mnemonicPhrase":"Мнемоническая фраза", - "separatorManualMethodsSolution":" или ", - "confirmManuallyWritten":"Я записал себе мнемоническую фразу", - "warningMessage":"**Не потеряйте!** Она не может быть восстановлена если вы ее потеряете.
**Никому не передавайте!** Ваши средства могут быть украдены если воспользуетесь этим файлом или фразой на вредоносном/фишинговом сайте.
**Сделайте резервную копию!** Берегите как миллион долларов, которого оно может одного прекрасного дня стоить.
", - "finishButton":"Я понял. Продолжить." - } - }, - "disclaimerBlock":{ - "title":"Риски использования KarboWallet", - "content":"KarboWallet это веб-интерфейс. Он помогает вам использовать Карбо без необходимости держать полный узел сети Карбо.
Мы рекомендуем относиться к KarboWallet со всей серьезностью, как к вашему бумажнику." - } - }, - "donatePage":{ - "title":"Пожертвовать", - "subtitle":"Помогите профинансировать разработку и оплату счетов", - "webwalletBlock":{ - "title":"Помошь Веб-кошельку", - "content":"Если вы хотите поддержать разработку, помочь с оплатой хостинга, если вам нравится аппликация, пожалуйста сделайте пожертвование:

" - }, - "devFundBlock":{ - "title":"Официальный фонд Карбо", - "content":"Чтобы поддержать Карбованец, вы можете сделать пожертвование на эти адреса" - } - }, - "supportPage":{ - "title":"Поддержка", - "subtitle":"Мы тут чтобы помочь!", - "getInTouchBlock":{ - "title":"Свяжитесь с нами!", - "content":"Есть идеи или пожелания по улучшению кошелька? Напишите нам!", - "discord":"Канал Karbo в Discord" - } - }, - "networkPage":{ - "title":"Статистика сети", - "subtitle":"Обзор сети Karbo", - "statsBlock":{ - "hashrate":"Хешрейт", - "height":"Высота блокчейна", - "difficulty":"Сложность", - "lastTimeBlock":"Время последнего блока", - "lastReward":"Награда за последний блок" - } - }, - "sendPage":{ - "title":"Отправить KRB", - "sendBlock":{ - "address":{ - "label":"Адрес получателя", - "placeholder":"Укажите адрес, на который хотите отправить средства", - "invalid":"Адрес получателя неверный", - "fundsTo":"Средства будут отправлены на", - "receiver":"Получатель", - "description":"Описание" - }, - "amount":{ - "label":"Сумма", - "invalid":"Сумма неверная" - }, - "paymentId":{ - "label":"Payment ID (необязательно)", - "invalid":"Идентификатор платежа неверный. Длина должна быть 16 или 64 символа" - }, - "sendButton":"Отправить", - "cancelButton":"Отменить" - }, - "qrCodeScanning":{ - "explication":"Показать QR код" - }, - "notEnoughMoneyModal":{ - "title":"Ой...", - "content":"В кошельке недостаточно средств для совершения этого перевода", - "confirmText":"OK" - }, - "thankYouDonationModal":{ - "title":"Спасибо за ваше пожертвование!", - "content":"Мы ценим вашу поддержку.
Это пожертвование поможет сделать Karbo лучше", - "confirmText":"OK" - }, - "transferSentModal":{ - "title":"Перевод успешно отправлен!", - "confirmText":"OK" - }, - "transferExceptionModal":{ - "title":"Ой...", - "content":"Случилась ошибка. Пожалуйста сообщите о ней: {details}", - "confirmText":"OK" - }, - "invalidAmountModal":{ - "title":"Ой...", - "content":"Неверная сумма", - "confirmText":"OK" - }, - "creatingTransferModal":{ - "title":"Создается перевод...", - "content":"Пожалуйста подождите..." - }, - "finalizingTransferModal":{ - "title":"Завершается перевод...", - "content":"Пожалуйста подождите..." - }, - "confirmTransactionModal":{ - "title":"Подтвердить перевод?", - "content":"Сумма: {amount}
Комиссии: {fees}
Всего: {total}", - "confirmText":"Подтвердить", - "cancelText":"Отменить" - }, - "waitingNfcModal":{ - "title":"Ожидание Nfc", - "content":"Поднесите ближе к другому устройству" - } - }, - "receivePage":{ - "title":"Получить KRB", - "receiveBlock":{ - "address":{ - "title":"Ваш адрес для получения:", - "label":"Дайте этот адрес чтобы получить средства" - }, - "qrCode":{ - "title":"Или персонализируйте QR код:", - "labelAmount":"Сумма (необязательно)", - "labelRecipient":"Название получателя (необязательно)", - "labelDescription":"Описание транзакции (необязательно)", - "updateButton":"Обновить" - } - }, - "qrBlock":{ - "title":"Ваш персональный QR код" - }, - "waitingNfcToWriteModal":{ - "title":"Ожидание Nfc", - "titleSuccess":"Nfc тег записан", - "content":"Поднесите NFC тег ближе для записи" - }, - "nfcErrorModal":{ - "titleInsufficientCapacity":"Вместимость тега недостаточная" - } - }, - "miningPage":{ - "title":"Информация о майнинге", - "subtitle":"Поддержите сеть майнингом и получите в награду KRB", - "parameterBlock":{ - "title":"Параметры", - "labelDestinationAddress":"Кошелек на который майнить", - "labelThreads":"Число потоков (больше = выше скорость)", - "start":"Старт", - "stop":"Стоп" - }, - "statisticsBlocks":{ - "title":"Статистика", - "validShares":"Валидные доли", - "hashrate":"Хешрейт", - "maxHashrate":"Макс. Хешрейт", - "dedicatedHardware":"Майнинг помогает в децентрализации сети и позволяет вам заработать Karbo.", - "miningHandledBy":"Майнинг проходит на пуле pool.karbowanec.com" - } - }, - "settingsPage":{ - "title":"Настройки", - "subtitle":"Тут вы можете изменить параметры", - "versionBlock":{ - "versionNumber":"Номер версии: ", - "versionCode":"Код версии: " - }, - "settingsBlock":{ - "speed":{ - "label":"Скорость обновления кошелька (будет потреблять больше ресурсов)", - "fastest":"Скорая", - "fast":"Быстрая", - "medium":"Средняя", - "slow":"Медленная" - }, - "language":{ - "label":"Язык" - }, - "readMinerTx":{ - "label":"Считывать транзакции майнинга (только для соло майнинга)" - } - }, - "changePasswordButton":"Изменть пароль моего кошелька", - "deleteWalletButton":"Удалить мой кошелек (локальную копию)", - "walletSettings":{ - "creationHeight":{ - "label":"Высота создания кошелька" - }, - "currentScanningHeight": { - "label": "Текущая высота сканирования" - }, - "updateButton":"Обновить" - }, - "deleteWalletModal":{ - "title":"Удалить мой кошелек (локальную копию)", - "content":"Вы ДЕЙСТВИТЕЛЬНО уверены что хотите удалить свой кошелек?", - "confirmText":"Да, я знаю что делаю", - "cancelText":"Отменить" - } - }, - "importBasePage":{ - "parametersBlock":{ - "title":"Параметры", - "password":{ - "label":"Пароль для защиты вашего кошелька" - }, - "passwordConfirm":{ - "label":"Подтвердите пароль", - "invalid":"Пароль не совпадает с первым введенным паролем" - }, - "importHeight":{ - "label":"С какой высоты начать импорт:" - } - } - }, - "importFromQrPage":{ - "title":"Импортировать кошелек из QR кода", - "subtitle":"Импортировать кошелек из оффлайновой резервной копии", - "qrCodeBlock":{ - "title":"QR код", - "startScanButton":"Начать сканирование", - "importButton":"Импортировать" - }, - "qrScanningBlock":{ - "title":"Покажите QR код" - } - }, - "exportPage":{ - "title":"Сделать резервную копию ваших данных", - "publicAddressBlock":{ - "title":"Ваш публичный адрес" - }, - "pdfBlock":{ - "title":"Резервная копия PDF", - "downloadButton":"Скачать" - }, - "warningBlock":{ - "title":"Внимание", - "content":"Если вы решите сохранить приватные ключи или мнемоническую фразу, кошелек НЕ СОХРАНИТ их в текстовом виде для вашей безопасности.
Файл является альтернативным решением где ваши ключи зашифрованы и содержит резервную копию всех ваших транзакций для ускорения синхронизации при восстановлении." - }, - "exportBlock":{ - "title":"Экспортировать сырые данные", - "privateKeysButton":"Получить мои приватные ключи", - "mnemonicKeysButton":"Получить мою мнемоническую фразу", - "fileButton":"Экспортировать в файл" - }, - "walletKeysModal":{ - "title":"Приватные ключи", - "confirmText":"OK", - "content":"Пожалуйста отнеситесь серьезно к сохранению этих ключей. Тот кто их имеет, владеет средствами на кошельке!
Ключ расходования: {privSpendKey}
Ключ слежения: {privViewKey}" - }, - "mnemonicKeyModal":{ - "title":"Мнемоническая фраза", - "confirmText":"OK", - "content":"Пожалуйста отнеситесь серьезно к сохранению этой мнемонической фразы. Тот кто ее имеет, владеет средствами на кошельке ! Фраза:
{mnemonic}" - }, - "mnemonicLangSelectionModal":{ - "title":"Выберите язык мнемонической фразы", - "confirmText":"Экспортировать" - } - }, - "importPage":{ - "title":"Создать кошелек", - "subtitle":"Из ранее созданных ключей, файла или мнемонической фразы", - "chooseMethod":"Выберите метод импорта:", - "fromKeys":"Из ключей", - "fromFile":"Из файла", - "fromMnemonic":"Из мнемонической фразы", - "fromQr":"Из QR кода" - }, - "termsOfUsePage":{ - "title":"Условия использования", - "subtitle":"Внимательно их прочитайте." - }, - "importFromFilePage":{ - "title":"Импорт кошелька из резервного фала", - "subtitle":"Использовать резервный файл для создания кошелька", - "walletBlock":{ - "title":"Файл кошелька", - "label":"Выберите файл", - "importButton":"Импортировать" - } - }, - "importFromMnemonicPage":{ - "title":"Импорт кошелька из мнемонической фразы", - "subtitle":"Использовать мнемоническую фразу для создания кошелька", - "mnemonicBlock":{ - "title":"Мнемоническая фраза", - "mnemonic":{ - "label":"Мнемоническая фраза: 25 слов", - "invalid":"Мнемоническая фраза недействительная", - "language":"Язык" - }, - "importButton":"Импортировать" - } - }, - "importFromKeysPage":{ - "title":"Импорт кошелька из ключей", - "subtitle":"Использовать приватные ключи для создания кошелька", - "parametersBlock":{ - "viewOnlyWallet": { - "label": "Хотите создать кошелек слежения?", - "info": "Обратите внимание, кошелек слежения предназначен только для просмотра входящих платежей, так что баланс может отображаться неправильно!" + "menu": { + "home": "Обзор", + "account": "Аккаунт", + "send": "Отправить", + "receive": "Получить", + "export": "Экспорт", + "donate": "Пожертвовать", + "elections": "Выборы", + "contacts": "контакты", + "settings": "Настройки", + "disconnect": "Отключиться", + "network": "Статистика сети", + "mining": "Майнинг" + }, + "global": { + "loading": "Загрузка", + "disableSecurity": "Отключить эту предосторожность, я понимаю риск", + "passwordInvalidRequirements": "Пароль должен состоять по крайней мере из 8 символов - 1 большой буквы, 1 маленькой, одного числа, одного спецсимвола", + "passwordConfirmationNotMatching": "Подтверждение пароля не совпадает с первым", + "download": "Скачать", + "newVersionModal": { + "title": "Есть новая версия", + "content": "Хотите перезагрузить чтобы обновить версию?", + "confirmText": "Да", + "cancelText": "Назад" + }, + "openWalletModal": { + "title": "Пароль кошелька", + "confirmText": "Открыть", + "cancelText": "Отмена" + }, + "invalidPasswordModal": { + "title": "Ой...", + "content": "Кажется пароль неверный", + "confirmText": "OK" + }, + "invalidMnemonicModal": { + "title": "Ой...", + "content": "Фраза для восстановления неверная", + "confirmText": "OK" + }, + "passwordNotComplexEnoughModal": { + "title": "Пароль недостаточно сложный", + "confirmText": "OK" + }, + "permissionRequiredForCameraModal": { + "title": "Ой...", + "content": "Требуется разрешение на доступ к камере для сканирования QR кода", + "confirmText": "OK" } - }, - "keysBlock":{ - "titleNotViewOnly":"Ключи кошелька", - "titleViewOnly":"Кошелек просмотра", - "privateSpend":{ - "label":"Приватный ключ расходования" - }, - "privateView":{ - "label":"Приватный ключ слежения", - "optional":"(необязательно)" - }, - "publicKey":{ - "label":"Публичный ключ" - }, - "importButton":"Импортировать" - } - } - }, - "number":{ + }, + "bottom": { + "termsOfUse": "Условия использования", + "privacyPolicy": "Политика конфиденциальности", + "support": "Поддержка", + "donate": "Пожертвовать", + "network": "Статистика сети", + "miningPool": "Майнинг", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Защищенный Кошелек Qwertycoin", + "tagLine": "в любом месте. в любой момент. любое место. любое устройство.", + "tagLineTwo": "Самый простой способ использовать Qwertycoin", + "actions": { + "loadWallet": "Загрузить мой кошелек", + "importWallet": "Импортировать кошелек", + "create": "Создать", + "createWallet": "Создать кошелек" + } + }, + "accountPage": { + "title": "Аккаунт", + "subtitle": "Обзор вашей учетной записи и истории транзакций", + "synchronizingBlock": { + "text": "Синхронизация..." + }, + "balanceBlock": { + "title": "Ваш баланс", + "unlocked": "Доступно" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "История транзакций", + "pendingTxStatus": "Ожидается", + "emptyWallet": "В этом кошельке пока нет средств.", + "waitSync": "Пожалуйста подождите пока кошелек обновляется", + "beReallyPatient": "Начальная установка может занять некоторое время...", + "getCoinAddress": "Получить QWC" + }, + "txDetails": { + "title": "Детали транзакции", + "txHash": "Хеш", + "feesOnTx": "Комиссия", + "blockHeight": "Высота блока", + "paymentId": "Идентификатор платежа", + "unlockStatus": "Status", + "unlockConfirm": "Confirmations", + "txPrivKey": "Секретный ключ транзакции" + } + }, + "changeWalletPasswordPage": { + "title": "Изменить ваш пароль", + "oldPassword": { + "label": "Старый пароль", + "invalid": "Пароль недействительный" + }, + "newPassword": { + "label": "Выберите новый пароль для зашиты вашего кошелька" + }, + "newPasswordConfirm": { + "label": "Подтвердите новый пароль" + }, + "confirm": "Изменить пароль", + "modalSuccess": { + "title": "Пароль изменен!", + "confirmText": "OK" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "контакты" + }, + "electionsPage": { + "title": "Выборы" + }, + "createWalletPage": { + "generatingStep": { + "title": "Создается кошелек...", + "subtitle": "Почти готово", + "waitingMessage": "Генерируется кошелек..." + }, + "finalizationStep": { + "title": "Все. Ваш кошелек готов!", + "subtitle": "Приготовьтесь использовать Qwertycoin как никогда до этого", + "passwordSelectionBlock": { + "label": "Защитите ваш кошелек" + }, + "passwordConfirmBlock": { + "label": "Подтвердите пароль" + }, + "validPassword": "Использовать этот пароль", + "backupBlock": { + "title": "Сохраните ваши приватные данные чтобы иметь возможность восстановления.", + "option1": "Опция 1: ", + "option2": "Опция 2: ", + "titlePdf": "Скачать PDF", + "titleManualWrite": "Записать ключи", + "privateKeys": "Приватный ключ", + "mnemonicPhrase": "Мнемоническая фраза", + "separatorManualMethodsSolution": " или ", + "confirmManuallyWritten": "Я записал себе мнемоническую фразу", + "warningMessage": "**Не потеряйте!** Она не может быть восстановлена если вы ее потеряете.
**Никому не передавайте!** Ваши средства могут быть украдены если воспользуетесь этим файлом или фразой на вредоносном/фишинговом сайте.
**Сделайте резервную копию!** Берегите как миллион долларов, которого оно может одного прекрасного дня стоить.
", + "finishButton": "Я понял. Продолжить." + } + }, + "disclaimerBlock": { + "title": "Риски использования QwertycoinWallet", + "content": "QwertycoinWallet это веб-интерфейс. Он помогает вам использовать Qwertycoin без необходимости держать полный узел сети Qwertycoin.
Мы рекомендуем относиться к QwertycoinWallet со всей серьезностью, как к вашему бумажнику." + } + }, + "donatePage": { + "title": "Пожертвовать", + "subtitle": "Помогите профинансировать разработку и оплату счетов", + "webwalletBlock": { + "title": "Помошь Веб-кошельку", + "content": "Если вы хотите поддержать разработку, помочь с оплатой хостинга, если вам нравится аппликация, пожалуйста сделайте пожертвование:

" + }, + "devFundBlock": { + "title": "Официальный фонд Qwertycoin", + "content": "Чтобы поддержать Qwertycoinванец, вы можете сделать пожертвование на эти адреса" + } + }, + "supportPage": { + "title": "Поддержка", + "subtitle": "Мы тут чтобы помочь!", + "getInTouchBlock": { + "title": "Свяжитесь с нами!", + "content": "Есть идеи или пожелания по улучшению кошелька? Напишите нам!", + "discord": "Канал Qwertycoin в Discord" + } + }, + "networkPage": { + "title": "Статистика сети", + "subtitle": "Обзор сети Qwertycoin", + "statsBlock": { + "connectNode": "Подключенный Мастернод", + "hashrate": "Хешрейт", + "height": "Высота блокчейна", + "difficulty": "Сложность", + "lastTimeBlock": "Время последнего блока", + "lastReward": "Награда за последний блок" + } + }, + "sendPage": { + "title": "Отправить QWC", + "sendBlock": { + "address": { + "label": "Адрес получателя", + "placeholder": "Укажите адрес, на который хотите отправить средства", + "invalid": "Адрес получателя неверный", + "fundsTo": "Средства будут отправлены на", + "receiver": "Получатель", + "description": "Описание" + }, + "amount": { + "label": "Сумма", + "invalid": "Сумма неверная" + }, + "paymentId": { + "label": "Payment ID (необязательно)", + "invalid": "Идентификатор платежа неверный. Длина должна быть 16 или 64 символа" + }, + "sendButton": "Отправить", + "cancelButton": "Отменить" + }, + "qrCodeScanning": { + "explication": "Показать QR код" + }, + "notEnoughMoneyModal": { + "title": "Ой...", + "content": "В кошельке недостаточно средств для совершения этого перевода", + "confirmText": "OK" + }, + "thankYouDonationModal": { + "title": "Спасибо за ваше пожертвование!", + "content": "Мы ценим вашу поддержку.
Это пожертвование поможет сделать Qwertycoin лучше", + "confirmText": "OK" + }, + "transferSentModal": { + "title": "Перевод успешно отправлен!", + "confirmText": "OK" + }, + "transferExceptionModal": { + "title": "Ой...", + "content": "Случилась ошибка. Пожалуйста сообщите о ней: {details}", + "confirmText": "OK" + }, + "invalidAmountModal": { + "title": "Ой...", + "content": "Неверная сумма", + "confirmText": "OK" + }, + "creatingTransferModal": { + "title": "Создается перевод...", + "content": "Пожалуйста подождите..." + }, + "finalizingTransferModal": { + "title": "Завершается перевод...", + "content": "Пожалуйста подождите..." + }, + "confirmTransactionModal": { + "title": "Подтвердить перевод?", + "content": "Сумма: {amount}
Комиссии: {fees}
Всего: {total}", + "confirmText": "Подтвердить", + "cancelText": "Отменить" + }, + "waitingNfcModal": { + "title": "Ожидание Nfc", + "content": "Поднесите ближе к другому устройству" + } + }, + "receivePage": { + "title": "Получить QWC", + "receiveBlock": { + "address": { + "title": "Ваш адрес для получения:", + "label": "Дайте этот адрес чтобы получить средства" + }, + "qrCode": { + "title": "Или персонализируйте QR код:", + "labelAmount": "Сумма (необязательно)", + "labelRecipient": "Название получателя (необязательно)", + "labelDescription": "Описание транзакции (необязательно)", + "updateButton": "Обновить" + } + }, + "qrBlock": { + "title": "Ваш персональный QR код" + }, + "waitingNfcToWriteModal": { + "title": "Ожидание Nfc", + "titleSuccess": "Nfc тег записан", + "content": "Поднесите NFC тег ближе для записи" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Вместимость тега недостаточная" + } + }, + "miningPage": { + "title": "Информация о майнинге", + "subtitle": "Поддержите сеть майнингом и получите в награду QWC", + "parameterBlock": { + "title": "Параметры", + "labelDestinationAddress": "Кошелек на который майнить", + "labelThreads": "Число потоков (больше = выше скорость)", + "start": "Старт", + "stop": "Стоп" + }, + "statisticsBlocks": { + "title": "Статистика", + "validShares": "Валидные доли", + "hashrate": "Хешрейт", + "maxHashrate": "Макс. Хешрейт", + "dedicatedHardware": "Майнинг помогает в децентрализации сети и позволяет вам заработать Qwertycoin.", + "miningHandledBy": "Майнинг проходит на пуле https://pool.qwertycoin.org" + } + }, + "settingsPage": { + "title": "Настройки", + "subtitle": "Тут вы можете изменить параметры", + "versionBlock": { + "versionNumber": "Номер версии: ", + "versionCode": "Код версии: " + }, + "settingsBlock": { + "speed": { + "label": "Скорость обновления кошелька (будет потреблять больше ресурсов)", + "fastest": "Скорая", + "fast": "Быстрая", + "medium": "Средняя", + "slow": "Медленная" + }, + "language": { + "label": "Язык" + }, + "currency": { + "label": "национальная валюта" + }, + "readMinerTx": { + "label": "Считывать транзакции майнинга (только для соло майнинга)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Изменть пароль моего кошелька", + "deleteWalletButton": "Удалить мой кошелек (локальную копию)", + "walletSettings": { + "creationHeight": { + "label": "Высота создания кошелька" + }, + "currentScanningHeight": { + "label": "Текущая высота сканирования" + }, + "updateButton": "Обновить" + }, + "deleteWalletModal": { + "title": "Удалить мой кошелек (локальную копию)", + "content": "Вы ДЕЙСТВИТЕЛЬНО уверены что хотите удалить свой кошелек?", + "confirmText": "Да, я знаю что делаю", + "cancelText": "Отменить" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Параметры", + "password": { + "label": "Пароль для защиты вашего кошелька" + }, + "passwordConfirm": { + "label": "Подтвердите пароль", + "invalid": "Пароль не совпадает с первым введенным паролем" + }, + "importHeight": { + "label": "С какой высоты начать импорт:" + } + } + }, + "importFromQrPage": { + "title": "Импортировать кошелек из QR кода", + "subtitle": "Импортировать кошелек из оффлайновой резервной копии", + "qrCodeBlock": { + "title": "QR код", + "startScanButton": "Начать сканирование", + "importButton": "Импортировать" + }, + "qrScanningBlock": { + "title": "Покажите QR код" + } + }, + "exportPage": { + "title": "Сделать резервную копию ваших данных", + "publicAddressBlock": { + "title": "Ваш публичный адрес" + }, + "pdfBlock": { + "title": "Резервная копия PDF", + "downloadButton": "Скачать" + }, + "warningBlock": { + "title": "Внимание", + "content": "Если вы решите сохранить приватные ключи или мнемоническую фразу, кошелек НЕ СОХРАНИТ их в текстовом виде для вашей безопасности.
Файл является альтернативным решением где ваши ключи зашифрованы и содержит резервную копию всех ваших транзакций для ускорения синхронизации при восстановлении." + }, + "exportBlock": { + "title": "Экспортировать сырые данные", + "privateKeysButton": "Получить мои приватные ключи", + "mnemonicKeysButton": "Получить мою мнемоническую фразу", + "fileButton": "Экспортировать в файл" + }, + "walletKeysModal": { + "title": "Приватные ключи", + "confirmText": "OK", + "content": "Пожалуйста отнеситесь серьезно к сохранению этих ключей. Тот кто их имеет, владеет средствами на кошельке!
Ключ расходования: {privSpendKey}
Ключ слежения: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Мнемоническая фраза", + "confirmText": "OK", + "content": "Пожалуйста отнеситесь серьезно к сохранению этой мнемонической фразы. Тот кто ее имеет, владеет средствами на кошельке ! Фраза:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "Выберите язык мнемонической фразы", + "confirmText": "Экспортировать" + } + }, + "importPage": { + "title": "Создать кошелек", + "subtitle": "Из ранее созданных ключей, файла или мнемонической фразы", + "chooseMethod": "Выберите метод импорта:", + "fromKeys": "Из ключей", + "fromFile": "Из файла", + "fromMnemonic": "Из мнемонической фразы", + "fromQr": "Из QR кода" + }, + "termsOfUsePage": { + "title": "Условия использования", + "subtitle": "Внимательно их прочитайте." + }, + "importFromFilePage": { + "title": "Импорт кошелька из резервного фала", + "subtitle": "Использовать резервный файл для создания кошелька", + "walletBlock": { + "title": "Файл кошелька", + "label": "Выберите файл", + "importButton": "Импортировать" + } + }, + "importFromMnemonicPage": { + "title": "Импорт кошелька из мнемонической фразы", + "subtitle": "Использовать мнемоническую фразу для создания кошелька", + "mnemonicBlock": { + "title": "Мнемоническая фраза", + "mnemonic": { + "label": "Мнемоническая фраза: 25 слов", + "invalid": "Мнемоническая фраза недействительная", + "language": "Язык" + }, + "importButton": "Импортировать" + } + }, + "importFromKeysPage": { + "title": "Импорт кошелька из ключей", + "subtitle": "Использовать приватные ключи для создания кошелька", + "parametersBlock": { + "viewOnlyWallet": { + "label": "Хотите создать кошелек слежения?", + "info": "Обратите внимание, кошелек слежения предназначен только для просмотра входящих платежей, так что баланс может отображаться неправильно!" + } + }, + "keysBlock": { + "titleNotViewOnly": "Ключи кошелька", + "titleViewOnly": "Кошелек просмотра", + "privateSpend": { + "label": "Приватный ключ расходования" + }, + "privateView": { + "label": "Приватный ключ слежения", + "optional": "(необязательно)" + }, + "publicKey": { + "label": "Публичный ключ" + }, + "importButton": "Импортировать" + } + } }, - "date":{ - "short": { - "year": "numeric", "month": "short", "day": "numeric" - }, - "long": { - "year": "numeric", "month": "short", "day": "numeric", - "weekday": "short", "hour": "numeric", "minute": "numeric", "hour12": true - } + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": true + } } -} \ No newline at end of file +} diff --git a/src/translations/sr.json b/src/translations/sr.json index 76ae64dc..005b3184 100644 --- a/src/translations/sr.json +++ b/src/translations/sr.json @@ -1,496 +1,540 @@ { - "website":{ - "title":"Официјални Карбо Веб Новчаник", - "description":"Официјални онлајн новчаник за Карбо валуту који је анониман, сигуран, и у потпуности се ослања на Ваш претраживач у циљу оптималне безбедности." + "website": { + "title": "Официјални Qwertycoin Веб Новчаник", + "description": "Официјални онлајн новчаник за Qwertycoin валуту који је анониман, сигуран, и у потпуности се ослања на Ваш претраживач у циљу оптималне безбедности." }, "messages": { - "menu": { - "home": "Почетна", - "account": "Налог", - "send": "Пошаљи", - "receive": "Прими", - "export": "Извоз", - "donate": "Донирај", - "settings": "Подешавања", - "disconnect": "Прекини везу", - "network": "Статистика Мреже", - "mining": "Рударење" - }, - "global": { - "loading": "Учитавам", - "disableSecurity":"Искључи безбедност, разумем и прихватам ризик", - "passwordInvalidRequirements":"Лозинка мора да се састоји из најмање 8 карактера, једног великог слова, једног малог слова, једног броја и једног симбола", - "passwordConfirmationNotMatching":"Лозинке се не подударају", - "download":"Преузми", - "newVersionModal":{ - "title":"Нова верзија је доступна", - "content":"Да ли желите да освежите страницу и учитате нову верзију ?", - "confirmText":"Да", - "cancelText":"Касније" - }, - "openWalletModal":{ - "title":"'Лозинка новчаника'", - "confirmText":"Отвори", - "cancelText":"Откажи" - }, - "invalidPasswordModal":{ - "title":"Упс...", - "content":"Неисправна лозинка", - "confirmText":"У реду" - }, - "invalidMnemonicModal":{ - "title":"Упс...", - "content":"Мнемоничка фраза није исправна", - "confirmText":"У реду" - }, - "passwordNotComplexEnoughModal":{ - "title":"Лозинка није довољно сложена", - "confirmText":"У реду" - }, - "permissionRequiredForCameraModal":{ - "title":"Упс...", - "content":"Потребна дозвола за приступ камери у циљу скенирања QR кода", - "confirmText":"У реду" - } - }, - "bottom": { - "termsOfUse": "Правила коришћења", - "privacyPolicy": "Правила о приватности", - "support": "Подршка", - "donate": "Донирај", - "network": "Статистика Мреже", - "miningPool": "Пул за рударење", - "github": "Гитхаб" - }, - "homepage": { - "mainTitle": "Безбедан Карбо Новчаник", - "tagLine": "Најједноставнији начин да користите Карбо, било када и било где!", - "actions": { - "loadWallet": "Учитај новчаник", - "importWallet": "Увези новчаник", - "create": "Направи", - "createWallet": "Направи новчаник" - }, - "notes": { - "secure": { - "title": "Сигурност", - "description": "Без сервера, потпуна енкрипција!" - }, - "fast": { - "title": "Брзина", - "description": "Шаљите било где, било када!" - }, - "technology": { - "title": "Јединствена технологија", - "description": "Повезан директно са Карбо Блокчејном!" - }, - "openSource": { - "title": "Open-source", - "description": "Доступно на ГитХаб" - } - } - }, - "accountPage": { - "title": "Налог", - "subtitle": "Преглед налога и трансакција", - "synchronizingBlock": { - "text": "Синхронизација у току" - }, - "balanceBlock": { - "title": "Ваша средства", - "unlocked": "Откључано" - }, - "historyBlock": { - "title": "Историја ваших трансакција", - "pendingTxStatus": "На чекању", - "emptyWallet": "Тренутно немате средстава у новчанику", - "waitSync": "Сачекајте да се новчаник освежи", - "beReallyPatient": "Овај поступак може да потраје...", - "getCoinAddress": "Адреса за пријем новчића" - }, - "txDetails":{ - "title":"Transaction details", - "txHash":"Tx hash", - "feesOnTx":"Fees on the tx", - "blockHeight":"Block height", - "paymentId":"Payment ID", - "txPrivKey":"Transaction Private Key" - } - }, - "changeWalletPasswordPage":{ - "title":"Промените лозинку", - "oldPassword":{ - "label":"Стара лозинка", - "invalid":"Погрешна лозинка" - }, - "newPassword":{ - "label":"Изаберите нову лозинку", - "invalid":" Лозинка мора да се састоји из најмање 8 карактера, једног великог слова, једног малог слова, једног броја и једног симбола" - }, - "newPasswordConfirm":{ - "label":"Потврдите нову лозинку" - }, - "confirm":"Промени лозинку", - "modalSuccess":{ - "title":"Лозинка промењена !", - "confirmText":"У реду" - } - }, - "createWalletPage":{ - "generatingStep":{ - "title":"Генерисање новчаника у току...", - "subtitle":"Процес је при крају", - "waitingMessage":"Генеришем новчаник..." - }, - "finalizationStep":{ - "title":"Просто као пасуљ. Ваш налог је спреман!", - "subtitle":"Спремите се да користите Карбо било где и било кад.", - "passwordSelectionBlock":{ - "label":"Заштитите ваше податке" - }, - "passwordConfirmBlock":{ - "label":"Потврдите лозинку" - }, - "validPassword":"Користите ову лозинку", - "backupBlock":{ - "title":"И преузмите шифровану копију ваших података за будућу употребу ", - "option1":"Опција 1: ", - "option2":"Опција 2: ", - "titlePdf":"Преузмите PDF фајл", - "titleManualWrite":"Запишите кључеве", - "privateKeys":"Приватни кључ", - "mnemonicPhrase":"Мнемоничка фраза", - "separatorManualMethodsSolution":" или ", - "confirmManuallyWritten":"Записао сам", - "warningMessage":"**Чувајте ове податке!** У случају губитка, подаци не могу бити враћени.
**Не делите податке ни са ким!** Ваша средства могу бити украдена уколико користите ове податке на другим сајтовима сумњивог садржаја.
**Направите резерву (backup)!** Обезбедите податке као да вреде милион долара.
", - "finishButton":"Разумем. Настави" - } - }, - "disclaimerBlock":{ - "title":"Ризици коришћења Карбо новчаника", - "content":"Карбо новчаник је интерфејс на мрежи. Осмишљен је да помогне при употреби Карбо валуте без потребе за покретањем софтвера на личном рачунару.
Предлажемо да се односите према Карбо новчанику као према свом личном који користите свакодневно." - } - }, - "donatePage":{ - "title":"Донирај", - "subtitle":"Помозите при финансирању развоја и плаћања рачуна.", - "webwalletBlock":{ - "title":"Веб новчаник", - "content":"Овај сервис је дело контрибутора под именом Gnock.
Уколико желите да помогнете при даљем развоју ове апликације, молимо вас да размислите о донацији.

" - }, - "devFundBlock":{ - "title":"Карбо новчаник за донације", - "content":"Уколико сте заинтересовани да помогнете, можете то учинити слањем средстава на следећу адресу" - } - }, - "supportPage":{ - "title":"Подршка", - "subtitle":"Уколико вам је потребна подршка, ту смо да помогнемо!", - "getInTouchBlock":{ - "title":"Контактирајте нас!", - "content":"Ако имате идеје или предлоге који би могли да помогну при даљем развоју овог сервиса, контактирајте нас!", - "discord":"Карбо Дискорд Сервер" - } - }, - "networkPage":{ - "title":"Статистика мреже", - "subtitle":"Увид у Карбо мрежу", - "statsBlock":{ - "hashrate":"Хешрејт мреже", - "height":"Блокчејн висина", - "difficulty":"Тешкоћа мреже", - "lastTimeBlock":"Последњи пронађени блок", - "lastReward":"Последња блок награда" - } - }, - "sendPage":{ - "title":"Шаљи МСР", - "sendBlock":{ - "address":{ - "label":"Пошаљи на адресу", - "placeholder":"Напишите адресу на коју желите да пошаљете средства", - "invalid":"Адреса неисправна", - "fundsTo":"Средства ће бити послата на", - "receiver":"Прималац", - "description":"Опис" - }, - "amount":{ - "label":"Количина за слање", - "invalid":"Количина неисправна" - }, - "paymentId":{ - "label":"ID уплате(произвољан корак)", - "invalid":"ID уплате неисправан. Дужина мора бити између 16 и 64 карактера" - }, - "sendButton":"Пошаљи", - "cancelButton":"Откажи" - }, - "qrCodeScanning":{ - "explication":"Скенирање QR кода" - }, - "notEnoughMoneyModal":{ - "title":"Упс...", - "content":"Немате довољно средстава за овај трансфер", - "confirmText":"У реду" - }, - "thankYouDonationModal":{ - "title":"Хвала вам на донацији!", - "content":"Ваша помоћ је добродошла.
Ваша донација ће помоћи при даљем развитку Карбо-ја", - "confirmText":"Затвори" - }, - "transferSentModal":{ - "title":"Трансфер успешан!", - "confirmText":"Затвори" - }, - "transferExceptionModal":{ - "title":"Упс...", - "content":"Дошло је до грешке. Молимо пријавите грешку: {details}", - "confirmText":"Затвори" - }, - "invalidAmountModal":{ - "title":"Упс...", - "content":"Количина погрешна", - "confirmText":"Затвори" - }, - "creatingTransferModal":{ - "title":"Припремам трансфер...", - "content":"Молимо сачекајте..." - }, - "finalizingTransferModal":{ - "title":"Финализирам трансфер...", - "content":"Молимо сачекајте..." - }, - "confirmTransactionModal":{ - "title":"Потврди трансфер?", - "content":"'Количина: {amount}
Провизија: {fees}
Укупно: {total}", - "confirmText":"Потврди", - "cancelText":"Откажи" - }, - "waitingNfcModal":{ - "title":"Waiting Nfc", - "content":"Bring closer to the other device" - } - }, - "receivePage":{ - "title":"Прими МСР", - "receiveBlock":{ - "address":{ - "title":"Адреса за примање новчића", - "label":"Приложите ову адресу уколико желите да примите новчиће" - }, - "qrCode":{ - "title":"Или помоћу QR кода", - "labelAmount":"Количина (произвољна опција)", - "labelRecipient":"Име примаоца(произвољна опција)", - "labelDescription":"Опис трансакције(произвољна опција)", - "updateButton":"Ажурирај" - } - }, - "qrBlock":{ - "title":"Ваш QR код" - }, - "waitingNfcToWriteModal":{ - "title":"Waiting Nfc", - "titleSuccess":"Nfc Tag written", - "content":"Bring closer the NFC tag to write" - }, - "nfcErrorModal":{ - "titleInsufficientCapacity":"Tag capacity insufficient" - } - }, - "miningPage":{ - "title":"Рударите директно из претраживача", - "subtitle":"Подржите мрежу и повећајте стабилност исте, бићете награђени МСР новчићима", - "parameterBlock":{ - "title":"Параметри", - "labelDestinationAddress":"Новчаник за рударење", - "labelThreads":"Број језгара(више = већи хешрејт)", - "start":"Старт", - "stop":"Стоп" - }, - "statisticsBlocks":{ - "title":"Статистика", - "validShares":"Валидних шерова", - "hashrate":"Хешрејт", - "maxHashrate":"Maксимални Хешрејт", - "dedicatedHardware":"Са одговарајућим софтвером за рударење можете очекивати 2 до 3 пута већи хешрејт.
Поред тога, софтвер за рударење вам омогућава да користите и графичку картицу.", - "miningHandledBy":"Рударење је омогућено и контролисано од стране get.masaricoin.com пула" - } - }, - "settingsPage":{ - "title":"Подешавања", - "subtitle":"Промените подешавања овде", - "versionBlock":{ - "versionNumber":"Version number: ", - "versionCode":"Version code: " - }, - "settingsBlock":{ - "speed":{ - "label":"Брзина ажурирања новчаника(утиче на потрошњу енергије)", - "fastest":"Најбрже", - "fast":"Брзо", - "medium":"Средње", - "slow":"Споро" - }, - "language":{ - "label":"Language" - }, - "readMinerTx":{ - "label":"Трансакције рудара(само за соло рударење)" - } - }, - "changePasswordButton":"Промени лозинку новчаника", - "deleteWalletButton":"Обриши мој новчаник(локална копија)", - "walletSettings":{ - "creationHeight":{ - "label":"Блок висина при креацији новчаника" - }, - "currentScanningHeight": { - "label": "Тренутна висина скенирања" - }, - "updateButton":"Ажурирај" - }, - "deleteWalletModal":{ - "title":"Обриши мој новчаник(локална копија)", - "content":"Да ли сте СИГУРНИ да желите брисање новчаника ?", - "confirmText":"Да, сигуран сам", - "cancelText":"Откажи" - } - }, - "importBasePage":{ - "parametersBlock":{ - "title":"Параметри", - "password":{ - "label":"Лозинка за заштиту новчаника" - }, - "passwordConfirm":{ - "label":"Потврдите лозинку", - "invalid":"Лозинка се не подудара са првим уносом" - }, - "importHeight":{ - "label":"Блок висина за увоз" - } - } - }, - "importFromQrPage":{ - "title":"Увоз новчаника преко QR кода", - "subtitle":"Увези новчаник из офлајн датотеке", - "qrCodeBlock":{ - "title":"QR код", - "startScanButton":"Покрени скенирање", - "importButton":"Увези" - }, - "qrScanningBlock":{ - "title":"Приложите QR код" - } - }, - "exportPage":{ - "title":"Сачувајте ваше податке", - "publicAddressBlock":{ - "title":"Ваша адреса" - }, - "pdfBlock":{ - "title":"Pdf чување", - "downloadButton":"Преузми" - }, - "warningBlock":{ - "title":"Упозорење", - "content":"Уколико се одлучите да сачувате податке вашег новчаника, МОЛИМО ВАС немојте их чувати на видном и лако доступном месту.
Овај фајл је алтернативно решење које садржи комплетан сет шифрованих параметара потребних за будућу ресторацију и синхронизацију." - }, - "exportBlock":{ - "title":"Извези СИРОВЕ податке", - "privateKeysButton":"Моји приватни кључеви", - "mnemonicKeysButton":"Моја мнемоничка фраза", - "fileButton":"Сачувај као фајл" - }, - "walletKeysModal":{ - "title":"Приватни кључеви", - "confirmText":"У реду", - "content":"Молимо бас да чувате ове податке на безбедном месту. Поседовање ових кључева значи поседовање свих средстава везаних за поменуте кључеве. !
Потрошачки кључ: {privSpendKey}
Приватни кључ: {privViewKey}" - }, - "mnemonicKeyModal":{ - "title":"Приватни кључеви", - "confirmText":"У реду", - "content":"Молимо вас да пажљиво чувате мнемоничку фразу. Поседовање исте вам омогућава приступ средствима везаним за овај новчаник ! Ваша фраза је:
{mnemonic}" - }, - "mnemonicLangSelectionModal":{ - "title":"Изаберите језик за мнемоничку фразу", - "confirmText":"Извези" - } - }, - "importPage":{ - "title":"Увези новчаник", - "subtitle":"Од претходно добијених кључева, фајла, или мнемоничке фразе", - "chooseMethod":"Изабери метод", - "fromKeys":"Помоћу кључева", - "fromFile":"Помоћу фајла", - "fromMnemonic":"Помоћу мнемоничке фразе", - "fromQr":"Помоћу QR кода" - }, - "termsOfUsePage":{ - "title":"Правила коришћења", - "subtitle":"Молимо пажљиво прочитајте" - }, - "privacyPolicyPage":{ - "title":"Privacy Policy", - "subtitle":"Молимо пажљиво прочитајте" - }, - "importFromFilePage":{ - "title":"Увоз новчаника помоћу фајла", - "subtitle":"Искористите преузети бекап фајл за увоз новчаника", - "walletBlock":{ - "title":"Фајл новчаника", - "label":"Изаберите фајл", - "importButton":"Увези" - } - }, - "importFromMnemonicPage":{ - "title":"Увоз новчаника помоћу мнемоничке фразе", - "subtitle":"Искористите постојећу фразу за увоз новчаника", - "mnemonicBlock":{ - "title":"Мнемоминчка фраза", - "mnemonic":{ - "label":"Мнемоничка фраза: 25 речи", - "invalid":"Неисправна мнемоничка фраза", - "language":"Језик" - }, - "importButton":"Увези" - } - }, - "importFromKeysPage":{ - "title":"Увоз новчаника помоћу кључева", - "subtitle":"Искористите кључеве за увоз новчаника", - "parametersBLock":{ - "viewOnlyWallet":{ - "label":"Да ли желите новчаник само за преглед (view-only) ?" - } - }, - "keysBlock":{ - "titleNotViewOnly":"Кључеви новчаника", - "titleViewOnly":"View-only новчаник", - "privateSpend":{ - "label":"Приватни потрошачки кључ" - }, - "privateView":{ - "label":"Приватни кључ за преглед", - "optional":"(произвољна опција)" - }, - "publicKey":{ - "label":"Јавни кључ" - }, - "importButton":"Увези" - } - } + "menu": { + "home": "Почетна", + "account": "Налог", + "send": "Пошаљи", + "receive": "Прими", + "export": "Извоз", + "donate": "Донирај", + "elections": "Избори", + "contacts": "Контакти", + "settings": "Подешавања", + "disconnect": "Прекини везу", + "network": "Статистика Мреже", + "mining": "Рударење" + }, + "global": { + "loading": "Учитавам", + "disableSecurity": "Искључи безбедност, разумем и прихватам ризик", + "passwordInvalidRequirements": "Лозинка мора да се састоји из најмање 8 карактера, једног великог слова, једног малог слова, једног броја и једног симбола", + "passwordConfirmationNotMatching": "Лозинке се не подударају", + "download": "Преузми", + "newVersionModal": { + "title": "Нова верзија је доступна", + "content": "Да ли желите да освежите страницу и учитате нову верзију ?", + "confirmText": "Да", + "cancelText": "Касније" + }, + "openWalletModal": { + "title": "'Лозинка новчаника'", + "confirmText": "Отвори", + "cancelText": "Откажи" + }, + "invalidPasswordModal": { + "title": "Упс...", + "content": "Неисправна лозинка", + "confirmText": "У реду" + }, + "invalidMnemonicModal": { + "title": "Упс...", + "content": "Мнемоничка фраза није исправна", + "confirmText": "У реду" + }, + "passwordNotComplexEnoughModal": { + "title": "Лозинка није довољно сложена", + "confirmText": "У реду" + }, + "permissionRequiredForCameraModal": { + "title": "Упс...", + "content": "Потребна дозвола за приступ камери у циљу скенирања QR кода", + "confirmText": "У реду" + } + }, + "bottom": { + "termsOfUse": "Правила коришћења", + "privacyPolicy": "Правила о приватности", + "support": "Подршка", + "donate": "Донирај", + "network": "Статистика Мреже", + "miningPool": "Пул за рударење", + "github": "Гитхаб" + }, + "homepage": { + "mainTitle": "Безбедан Qwertycoin Новчаник", + "tagLine": "Најједноставнији начин да користите Qwertycoin, било када и било где!", + "tagLineTwo": "The simplest way to use Qwertycoin", + "actions": { + "loadWallet": "Учитај новчаник", + "importWallet": "Увези новчаник", + "create": "Направи", + "createWallet": "Направи новчаник" + } + }, + "accountPage": { + "title": "Налог", + "subtitle": "Преглед налога и трансакција", + "synchronizingBlock": { + "text": "Синхронизација у току" + }, + "balanceBlock": { + "title": "Ваша средства", + "unlocked": "Откључано" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Историја ваших трансакција", + "pendingTxStatus": "На чекању", + "emptyWallet": "Тренутно немате средстава у новчанику", + "waitSync": "Сачекајте да се новчаник освежи", + "beReallyPatient": "Овај поступак може да потраје...", + "getCoinAddress": "Адреса за пријем новчића" + }, + "txDetails": { + "title": "Transaction details", + "txHash": "Tx hash", + "feesOnTx": "Fees on the tx", + "blockHeight": "Block height", + "paymentId": "Payment ID", + "unlockStatus": "Status", + "unlockConfirm": "Confirmations", + "txPrivKey": "Transaction Private Key" + } + }, + "changeWalletPasswordPage": { + "title": "Промените лозинку", + "oldPassword": { + "label": "Стара лозинка", + "invalid": "Погрешна лозинка" + }, + "newPassword": { + "label": "Изаберите нову лозинку", + "invalid": " Лозинка мора да се састоји из најмање 8 карактера, једног великог слова, једног малог слова, једног броја и једног симбола" + }, + "newPasswordConfirm": { + "label": "Потврдите нову лозинку" + }, + "confirm": "Промени лозинку", + "modalSuccess": { + "title": "Лозинка промењена !", + "confirmText": "У реду" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "Контакти" + }, + "electionsPage": { + "title": "Избори" + }, + "createWalletPage": { + "generatingStep": { + "title": "Генерисање новчаника у току...", + "subtitle": "Процес је при крају", + "waitingMessage": "Генеришем новчаник..." + }, + "finalizationStep": { + "title": "Просто као пасуљ. Ваш налог је спреман!", + "subtitle": "Спремите се да користите Qwertycoin било где и било кад.", + "passwordSelectionBlock": { + "label": "Заштитите ваше податке" + }, + "passwordConfirmBlock": { + "label": "Потврдите лозинку" + }, + "validPassword": "Користите ову лозинку", + "backupBlock": { + "title": "И преузмите шифровану копију ваших података за будућу употребу ", + "option1": "Опција 1: ", + "option2": "Опција 2: ", + "titlePdf": "Преузмите PDF фајл", + "titleManualWrite": "Запишите кључеве", + "privateKeys": "Приватни кључ", + "mnemonicPhrase": "Мнемоничка фраза", + "separatorManualMethodsSolution": " или ", + "confirmManuallyWritten": "Записао сам", + "warningMessage": "**Чувајте ове податке!** У случају губитка, подаци не могу бити враћени.
**Не делите податке ни са ким!** Ваша средства могу бити украдена уколико користите ове податке на другим сајтовима сумњивог садржаја.
**Направите резерву (backup)!** Обезбедите податке као да вреде милион долара.
", + "finishButton": "Разумем. Настави" + } + }, + "disclaimerBlock": { + "title": "Ризици коришћења Qwertycoin новчаника", + "content": "Qwertycoin новчаник је интерфејс на мрежи. Осмишљен је да помогне при употреби Qwertycoin валуте без потребе за покретањем софтвера на личном рачунару.
Предлажемо да се односите према Qwertycoin новчанику као према свом личном који користите свакодневно." + } + }, + "donatePage": { + "title": "Донирај", + "subtitle": "Помозите при финансирању развоја и плаћања рачуна.", + "webwalletBlock": { + "title": "Веб новчаник", + "content": "Овај сервис је дело контрибутора под именом Gnock.
Уколико желите да помогнете при даљем развоју ове апликације, молимо вас да размислите о донацији.

" + }, + "devFundBlock": { + "title": "Qwertycoin новчаник за донације", + "content": "Уколико сте заинтересовани да помогнете, можете то учинити слањем средстава на следећу адресу" + } + }, + "supportPage": { + "title": "Подршка", + "subtitle": "Уколико вам је потребна подршка, ту смо да помогнемо!", + "getInTouchBlock": { + "title": "Контактирајте нас!", + "content": "Ако имате идеје или предлоге који би могли да помогну при даљем развоју овог сервиса, контактирајте нас!", + "discord": "Qwertycoin Дискорд Сервер" + } + }, + "networkPage": { + "title": "Статистика мреже", + "subtitle": "Увид у Qwertycoin мрежу", + "statsBlock": { + "connectNode": "Цоннецтед Мастерноде", + "hashrate": "Хешрејт мреже", + "height": "Блокчејн висина", + "difficulty": "Тешкоћа мреже", + "lastTimeBlock": "Последњи пронађени блок", + "lastReward": "Последња блок награда" + } + }, + "sendPage": { + "title": "Шаљи МСР", + "sendBlock": { + "address": { + "label": "Пошаљи на адресу", + "placeholder": "Напишите адресу на коју желите да пошаљете средства", + "invalid": "Адреса неисправна", + "fundsTo": "Средства ће бити послата на", + "receiver": "Прималац", + "description": "Опис" + }, + "amount": { + "label": "Количина за слање", + "invalid": "Количина неисправна" + }, + "paymentId": { + "label": "ID уплате(произвољан корак)", + "invalid": "ID уплате неисправан. Дужина мора бити између 16 и 64 карактера" + }, + "sendButton": "Пошаљи", + "cancelButton": "Откажи" + }, + "qrCodeScanning": { + "explication": "Скенирање QR кода" + }, + "notEnoughMoneyModal": { + "title": "Упс...", + "content": "Немате довољно средстава за овај трансфер", + "confirmText": "У реду" + }, + "thankYouDonationModal": { + "title": "Хвала вам на донацији!", + "content": "Ваша помоћ је добродошла.
Ваша донација ће помоћи при даљем развитку Qwertycoin-ја", + "confirmText": "Затвори" + }, + "transferSentModal": { + "title": "Трансфер успешан!", + "confirmText": "Затвори" + }, + "transferExceptionModal": { + "title": "Упс...", + "content": "Дошло је до грешке. Молимо пријавите грешку: {details}", + "confirmText": "Затвори" + }, + "invalidAmountModal": { + "title": "Упс...", + "content": "Количина погрешна", + "confirmText": "Затвори" + }, + "creatingTransferModal": { + "title": "Припремам трансфер...", + "content": "Молимо сачекајте..." + }, + "finalizingTransferModal": { + "title": "Финализирам трансфер...", + "content": "Молимо сачекајте..." + }, + "confirmTransactionModal": { + "title": "Потврди трансфер?", + "content": "'Количина: {amount}
Провизија: {fees}
Укупно: {total}", + "confirmText": "Потврди", + "cancelText": "Откажи" + }, + "waitingNfcModal": { + "title": "Waiting Nfc", + "content": "Bring closer to the other device" + } + }, + "receivePage": { + "title": "Прими МСР", + "receiveBlock": { + "address": { + "title": "Адреса за примање новчића", + "label": "Приложите ову адресу уколико желите да примите новчиће" + }, + "qrCode": { + "title": "Или помоћу QR кода", + "labelAmount": "Количина (произвољна опција)", + "labelRecipient": "Име примаоца(произвољна опција)", + "labelDescription": "Опис трансакције(произвољна опција)", + "updateButton": "Ажурирај" + } + }, + "qrBlock": { + "title": "Ваш QR код" + }, + "waitingNfcToWriteModal": { + "title": "Waiting Nfc", + "titleSuccess": "Nfc Tag written", + "content": "Bring closer the NFC tag to write" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Tag capacity insufficient" + } + }, + "miningPage": { + "title": "Рударите директно из претраживача", + "subtitle": "Подржите мрежу и повећајте стабилност исте, бићете награђени МСР новчићима", + "parameterBlock": { + "title": "Параметри", + "labelDestinationAddress": "Новчаник за рударење", + "labelThreads": "Број језгара(више = већи хешрејт)", + "start": "Старт", + "stop": "Стоп" + }, + "statisticsBlocks": { + "title": "Статистика", + "validShares": "Валидних шерова", + "hashrate": "Хешрејт", + "maxHashrate": "Maксимални Хешрејт", + "dedicatedHardware": "Са одговарајућим софтвером за рударење можете очекивати 2 до 3 пута већи хешрејт.
Поред тога, софтвер за рударење вам омогућава да користите и графичку картицу.", + "miningHandledBy": "Рударење је омогућено и контролисано од стране pool.qwertycoin.org пула" + } + }, + "settingsPage": { + "title": "Подешавања", + "subtitle": "Промените подешавања овде", + "versionBlock": { + "versionNumber": "Version number: ", + "versionCode": "Version code: " + }, + "settingsBlock": { + "speed": { + "label": "Брзина ажурирања новчаника(утиче на потрошњу енергије)", + "fastest": "Најбрже", + "fast": "Брзо", + "medium": "Средње", + "slow": "Споро" + }, + "language": { + "label": "Language" + }, + "currency": { + "label": "nacionalna валута" + }, + "readMinerTx": { + "label": "Трансакције рудара(само за соло рударење)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Промени лозинку новчаника", + "deleteWalletButton": "Обриши мој новчаник(локална копија)", + "walletSettings": { + "creationHeight": { + "label": "Блок висина при креацији новчаника" + }, + "currentScanningHeight": { + "label": "Тренутна висина скенирања" + }, + "updateButton": "Ажурирај" + }, + "deleteWalletModal": { + "title": "Обриши мој новчаник(локална копија)", + "content": "Да ли сте СИГУРНИ да желите брисање новчаника ?", + "confirmText": "Да, сигуран сам", + "cancelText": "Откажи" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Параметри", + "password": { + "label": "Лозинка за заштиту новчаника" + }, + "passwordConfirm": { + "label": "Потврдите лозинку", + "invalid": "Лозинка се не подудара са првим уносом" + }, + "importHeight": { + "label": "Блок висина за увоз" + } + } + }, + "importFromQrPage": { + "title": "Увоз новчаника преко QR кода", + "subtitle": "Увези новчаник из офлајн датотеке", + "qrCodeBlock": { + "title": "QR код", + "startScanButton": "Покрени скенирање", + "importButton": "Увези" + }, + "qrScanningBlock": { + "title": "Приложите QR код" + } + }, + "exportPage": { + "title": "Сачувајте ваше податке", + "publicAddressBlock": { + "title": "Ваша адреса" + }, + "pdfBlock": { + "title": "Pdf чување", + "downloadButton": "Преузми" + }, + "warningBlock": { + "title": "Упозорење", + "content": "Уколико се одлучите да сачувате податке вашег новчаника, МОЛИМО ВАС немојте их чувати на видном и лако доступном месту.
Овај фајл је алтернативно решење које садржи комплетан сет шифрованих параметара потребних за будућу ресторацију и синхронизацију." + }, + "exportBlock": { + "title": "Извези СИРОВЕ податке", + "privateKeysButton": "Моји приватни кључеви", + "mnemonicKeysButton": "Моја мнемоничка фраза", + "fileButton": "Сачувај као фајл" + }, + "walletKeysModal": { + "title": "Приватни кључеви", + "confirmText": "У реду", + "content": "Молимо бас да чувате ове податке на безбедном месту. Поседовање ових кључева значи поседовање свих средстава везаних за поменуте кључеве. !
Потрошачки кључ: {privSpendKey}
Приватни кључ: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Приватни кључеви", + "confirmText": "У реду", + "content": "Молимо вас да пажљиво чувате мнемоничку фразу. Поседовање исте вам омогућава приступ средствима везаним за овај новчаник ! Ваша фраза је:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "Изаберите језик за мнемоничку фразу", + "confirmText": "Извези" + } + }, + "importPage": { + "title": "Увези новчаник", + "subtitle": "Од претходно добијених кључева, фајла, или мнемоничке фразе", + "chooseMethod": "Изабери метод", + "fromKeys": "Помоћу кључева", + "fromFile": "Помоћу фајла", + "fromMnemonic": "Помоћу мнемоничке фразе", + "fromQr": "Помоћу QR кода" + }, + "termsOfUsePage": { + "title": "Правила коришћења", + "subtitle": "Молимо пажљиво прочитајте" + }, + "privacyPolicyPage": { + "title": "Privacy Policy", + "subtitle": "Молимо пажљиво прочитајте" + }, + "importFromFilePage": { + "title": "Увоз новчаника помоћу фајла", + "subtitle": "Искористите преузети бекап фајл за увоз новчаника", + "walletBlock": { + "title": "Фајл новчаника", + "label": "Изаберите фајл", + "importButton": "Увези" + } + }, + "importFromMnemonicPage": { + "title": "Увоз новчаника помоћу мнемоничке фразе", + "subtitle": "Искористите постојећу фразу за увоз новчаника", + "mnemonicBlock": { + "title": "Мнемоминчка фраза", + "mnemonic": { + "label": "Мнемоничка фраза: 25 речи", + "invalid": "Неисправна мнемоничка фраза", + "language": "Језик" + }, + "importButton": "Увези" + } + }, + "importFromKeysPage": { + "title": "Увоз новчаника помоћу кључева", + "subtitle": "Искористите кључеве за увоз новчаника", + "parametersBLock": { + "viewOnlyWallet": { + "label": "Да ли желите новчаник само за преглед (view-only) ?" + } + }, + "keysBlock": { + "titleNotViewOnly": "Кључеви новчаника", + "titleViewOnly": "View-only новчаник", + "privateSpend": { + "label": "Приватни потрошачки кључ" + }, + "privateView": { + "label": "Приватни кључ за преглед", + "optional": "(произвољна опција)" + }, + "publicKey": { + "label": "Јавни кључ" + }, + "importButton": "Увези" + } + } }, - "number":{ - }, - "date":{ - "short": { - "year": "numeric", "month": "short", "day": "numeric" - }, - "long": { - "year": "numeric", "month": "short", "day": "numeric", - "weekday": "short", "hour": "numeric", "minute": "numeric", "hour12": false - } + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": false + } } -} \ No newline at end of file +} diff --git a/src/translations/tr.json b/src/translations/tr.json new file mode 100644 index 00000000..1626dfe2 --- /dev/null +++ b/src/translations/tr.json @@ -0,0 +1,539 @@ +{ + "website": { + "title": "Qwertycoin Cüzdanı | Basit, kesintisiz, güvenli. Geleceğe Hoşgeldiniz.", + "description": "Qwertycoin para birimi için resmi çevrimiçi cüzdan - en iyi güvenlik için tarayıcınızda tamamen kullanılır" + }, + "messages": { + "menu": { + "home": "Ev", + "account": "hesap", + "send": "göndermek", + "receive": "Teslim almak", + "export": "ihracat", + "donate": "bağışlamak", + "elections": "Seçimler", + "contacts": "İletişim", + "settings": "Ayarlar", + "disconnect": "Çıkış Yap", + "network": "Ağ İstatistikleri", + "mining": "madencilik" + }, + "global": { + "loading": "Loading", + "disableSecurity": "Disable this security, I understand the risk", + "passwordInvalidRequirements": "The password needs at least 8 characters - 1 upper case letter, 1 lower case letter, one number, and one special character", + "passwordConfirmationNotMatching": "The password does not match the first password you wrote", + "download": "Download", + "newVersionModal": { + "title": "A new version is available", + "content": "Do you want to reload to load the new version?", + "confirmText": "Yes", + "cancelText": "Back" + }, + "openWalletModal": { + "title": "Wallet Password", + "confirmText": "Open", + "cancelText": "Cancel" + }, + "invalidPasswordModal": { + "title": "Oops...", + "content": "Your password seems invalid", + "confirmText": "OK" + }, + "invalidMnemonicModal": { + "title": "Oops...", + "content": "The mnemonic phrase is invalid", + "confirmText": "OK" + }, + "passwordNotComplexEnoughModal": { + "title": "The password is not complex enough", + "confirmText": "OK" + }, + "permissionRequiredForCameraModal": { + "title": "Oops...", + "content": "The permission to access your camera is required to scan the QR code", + "confirmText": "OK" + } + }, + "bottom": { + "termsOfUse": "Terms of Use", + "privacyPolicy": "Privacy Policy", + "support": "Support", + "donate": "Donate", + "network": "Network Stats", + "miningPool": "Mining Pool", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Qwertycoin Wallet", + "tagLine": "anywhere. anytime. anyplace. any device.", + "tagLineTwo": "The simplest way to use Qwertycoin", + "actions": { + "loadWallet": "Load my wallet", + "importWallet": "Import a wallet", + "create": "Create", + "createWallet": "Create a wallet" + } + }, + "accountPage": { + "title": "Account", + "subtitle": "Your account overview and transaction history", + "synchronizingBlock": { + "text": "Synchronizing..." + }, + "balanceBlock": { + "title": "Your balance", + "unlocked": "Unlocked" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Transaction history", + "pendingTxStatus": "Pending", + "emptyWallet": "You currently have no funds in this wallet.", + "waitSync": "Please wait until the wallet is updated", + "beReallyPatient": "The initial setup can take some time...", + "getCoinAddress": "Receive QWC" + }, + "txDetails": { + "title": "Transaction details", + "txHash": "Transaction Hash", + "feesOnTx": "Transaction fee", + "blockHeight": "Block height", + "paymentId": "Payment ID", + "unlockStatus": "Status", + "unlockConfirm": "Confirmations", + "txPrivKey": "Transaction Private Key" + } + }, + "changeWalletPasswordPage": { + "title": "Change your password", + "oldPassword": { + "label": "Old password", + "invalid": "The password is invalid" + }, + "newPassword": { + "label": "Choose a new password to protect your wallet" + }, + "newPasswordConfirm": { + "label": "Confirm the new password" + }, + "confirm": "Change the password", + "modalSuccess": { + "title": "Password changed!", + "confirmText": "OK" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "İletişim" + }, + "electionsPage": { + "title": "Seçimler" + }, + "createWalletPage": { + "generatingStep": { + "title": "Your wallet is being generated...", + "subtitle": "It's almost done", + "waitingMessage": "Generating your wallet..." + }, + "finalizationStep": { + "title": "That was simple. Your account is ready!", + "subtitle": "Be ready to use Qwertycoin like you never have", + "passwordSelectionBlock": { + "label": "Protect your wallet" + }, + "passwordConfirmBlock": { + "label": "Confirm the password" + }, + "validPassword": "Use this password", + "backupBlock": { + "title": "Save your private credentials for recovery.", + "option1": "Option 1: ", + "option2": "Option 2: ", + "titlePdf": "Download a PDF copy", + "titleManualWrite": "Write down my keys", + "privateKeys": "Private key", + "mnemonicPhrase": "Mnemonic phrase", + "separatorManualMethodsSolution": " or ", + "confirmManuallyWritten": "I wrote my seed phrase down", + "warningMessage": "**Do not lose it!** It cannot be recovered if you lose it.
**Do not share it!** Your funds will be stolen if you use this file or seed on a malicious/phishing site.
**Make a backup!** Secure it like the millions of dollars it may one day be worth.
", + "finishButton": "I understand. Continue." + } + }, + "disclaimerBlock": { + "title": "Risk of Using QwertycoinWallet", + "content": "QwertycoinWallet is a web-based interface. It helps you use Qwertycoin without running a full Qwertycoin node.
We recommend you treat QwertycoinWallet like you will treat your actual wallet." + } + }, + "donatePage": { + "title": "Donate", + "subtitle": "Help to fund the development and pay the bills", + "webwalletBlock": { + "title": "Webwallet", + "content": "If you want to help to pay for the servers, to support new features development, and like this app, please consider a donation:

" + }, + "devFundBlock": { + "title": "Qwertycoin Dev fund", + "content": "To help Qwertycoin, you can donate at these addresses" + } + }, + "supportPage": { + "title": "Support", + "subtitle": "We are here to help!", + "getInTouchBlock": { + "title": "Let's Get In Touch!", + "content": "Do you have ideas or feedback that could help us improve the wallet? Contact us!", + "discord": "Qwertycoin Discord Channel" + } + }, + "networkPage": { + "title": "Network stats", + "subtitle": "Insights on the Qwertycoin network", + "statsBlock": { + "connectNode": "Connected Masternode", + "hashrate": "Network hashrate", + "height": "Blockchain height", + "difficulty": "Network difficulty", + "lastTimeBlock": "Last block found", + "lastReward": "Last block reward" + } + }, + "sendPage": { + "title": "Send QWC", + "sendBlock": { + "address": { + "label": "Destination address", + "placeholder": "Write the address where you want to send funds", + "invalid": "The destination address is invalid", + "fundsTo": "The funds will be sent to", + "receiver": "Receiver", + "description": "Description" + }, + "amount": { + "label": "Amount to send", + "invalid": "The amount is invalid" + }, + "paymentId": { + "label": "Payment ID (optional)", + "invalid": "The payment ID is invalid. The length must be 16 or 64 characters" + }, + "sendButton": "Send", + "cancelButton": "Cancel" + }, + "qrCodeScanning": { + "explication": "Present the QR code" + }, + "notEnoughMoneyModal": { + "title": "Oops...", + "content": "You don't have enough funds in your wallet to execute this transfer", + "confirmText": "OK" + }, + "thankYouDonationModal": { + "title": "Thank you for your donation!", + "content": "Your help is appreciated. This donation will help make Qwertycoin better", + "confirmText": "OK" + }, + "transferSentModal": { + "title": "Transfer sent successfully!", + "confirmText": "OK" + }, + "transferExceptionModal": { + "title": "Oops...", + "content": "An error occurred. Please report this error: {details}", + "confirmText": "OK" + }, + "invalidAmountModal": { + "title": "Oops...", + "content": "Invalid amount", + "confirmText": "OK" + }, + "creatingTransferModal": { + "title": "Creating transfer ...", + "content": "Please wait..." + }, + "finalizingTransferModal": { + "title": "Finalizing transfer ...", + "content": "Please wait..." + }, + "confirmTransactionModal": { + "title": "Confirm transfer?", + "content": "Amount: {amount}
Fees: {fees}
Total: {total}", + "confirmText": "Confirm", + "cancelText": "Cancel" + }, + "waitingNfcModal": { + "title": "Waiting NFC", + "content": "Bring this device closer to the other device" + } + }, + "receivePage": { + "title": "Receive QWC", + "receiveBlock": { + "address": { + "title": "Your address to receive funds:", + "label": "Give this address to receive funds" + }, + "qrCode": { + "title": "Or personalize the QR code:", + "labelAmount": "Amount (optional)", + "labelRecipient": "Recipient name (optional)", + "labelDescription": "Transaction description (optional)", + "updateButton": "Update" + } + }, + "qrBlock": { + "title": "Your customized QR code" + }, + "waitingNfcToWriteModal": { + "title": "Waiting NFC", + "titleSuccess": "NFC Tag written", + "content": "Bring the NFC tag closer to this device to write" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Tag capacity insufficient" + } + }, + "miningPage": { + "title": "Mine directly in your browser", + "subtitle": "Support the network by mining and be rewarded with QWC", + "parameterBlock": { + "title": "Parameters", + "labelDestinationAddress": "Wallet to mine", + "labelThreads": "Number of threads (more = higher hashrate)", + "start": "Start", + "stop": "Stop" + }, + "statisticsBlocks": { + "title": "Statistics", + "validShares": "Valid shares", + "hashrate": "Hashrate", + "maxHashrate": "Max Hashrate", + "dedicatedHardware": "With dedicating mining software and hardware, you could earn more and help decentralize the network.", + "miningHandledBy": "This mining is handled by the mining pool pool.qwertycoin.org" + } + }, + "settingsPage": { + "title": "Settings", + "subtitle": "Change your parameters here", + "versionBlock": { + "versionNumber": "Version number: ", + "versionCode": "Version code: " + }, + "settingsBlock": { + "speed": { + "label": "Speed to update the wallet (will consume more resources)", + "fastest": "Fastest", + "fast": "Fast", + "medium": "Medium", + "slow": "Slow" + }, + "language": { + "label": "Language" + }, + "currency": { + "label": "National Currency" + }, + "readMinerTx": { + "label": "Read miner transactions (only for solo mining)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Change my wallet password", + "deleteWalletButton": "Delete my wallet (local copy)", + "walletSettings": { + "creationHeight": { + "label": "Creation height of the wallet" + }, + "currentScanningHeight": { + "label": "Current scanning height" + }, + "updateButton": "Update" + }, + "deleteWalletModal": { + "title": "Delete My Wallet (local copy)", + "content": "Are you sure you REALLY want to delete your wallet ?", + "confirmText": "Yes I'm sure", + "cancelText": "Cancel" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Parameters", + "password": { + "label": "Password to protect your wallet" + }, + "passwordConfirm": { + "label": "Confirm the password", + "invalid": "The password does not match the first password you wrote" + }, + "importHeight": { + "label": "Height to import from:" + } + } + }, + "importFromQrPage": { + "title": "Importing wallet from a QR code", + "subtitle": "Import a wallet from an offline backup", + "qrCodeBlock": { + "title": "QR code", + "startScanButton": "Start the scan", + "importButton": "Import" + }, + "qrScanningBlock": { + "title": "Present the QR code" + } + }, + "exportPage": { + "title": "Backup your credentials", + "publicAddressBlock": { + "title": "Your public address" + }, + "pdfBlock": { + "title": "PDF Backup", + "downloadButton": "Download" + }, + "warningBlock": { + "title": "Warning", + "content": "If you choose to save your private keys or your mnemonic phrase, PLEASE DO NOT store them in clear-text for your own safety.
The file is an alternate solution where your keys are encrypted and contains a backup of all your transactions to spare you a future synchronisation." + }, + "exportBlock": { + "title": "Export your RAW credentials", + "privateKeysButton": "Get my private keys", + "mnemonicKeysButton": "Get my mnemonic phrase", + "fileButton": "Export to a file" + }, + "walletKeysModal": { + "title": "Private keys", + "confirmText": "OK", + "content": "Please carefully store these keys. Possessing them means possessing the funds associated !
Spend key: {privSpendKey}
Private view key: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Mnemonic phrase", + "confirmText": "OK", + "content": "Please store carefully this mnemonic phrase. Possessing it means possessing the funds associated ! The phrase is:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "In which language do you want your mnemonic phrase?", + "confirmText": "Export" + } + }, + "importPage": { + "title": "Create a wallet", + "subtitle": "From previously created keys, file, or mnemonic phrase", + "chooseMethod": "Choose your import method:", + "fromKeys": "From keys", + "fromFile": "From a file", + "fromMnemonic": "From a mnemonic phrase", + "fromQr": "From a QR code" + }, + "termsOfUsePage": { + "title": "Terms of use", + "subtitle": "Please read them carefully." + }, + "privacyPolicyPage": { + "title": "Privacy Policy", + "subtitle": "Please read them carefully." + }, + "importFromFilePage": { + "title": "Importing wallet from a backup file", + "subtitle": "Use your backup file to create a wallet", + "walletBlock": { + "title": "Wallet file", + "label": "Select the file", + "importButton": "Import" + } + }, + "importFromMnemonicPage": { + "title": "Importing wallet from a mnemonic phrase", + "subtitle": "Use your phrase to create a wallet", + "mnemonicBlock": { + "title": "Mnemonic phrase", + "mnemonic": { + "label": "Mnemonic phrase: 25 words", + "invalid": "The mnemonic phrase is invalid", + "language": "Language" + }, + "importButton": "Import" + } + }, + "importFromKeysPage": { + "title": "Importing wallet from keys", + "subtitle": "Use your keys to create a wallet", + "parametersBlock": { + "viewOnlyWallet": { + "label": "Do you want a view only wallet?" + } + }, + "keysBlock": { + "titleNotViewOnly": "Wallet keys", + "titleViewOnly": "View only wallet", + "privateSpend": { + "label": "Private spend key" + }, + "privateView": { + "label": "Private view key", + "optional": "(optional)" + }, + "publicKey": { + "label": "Public key" + }, + "importButton": "Import" + } + } + }, + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": true + } + } +} diff --git a/src/translations/uk.json b/src/translations/uk.json index 7bd5b816..0e11b614 100644 --- a/src/translations/uk.json +++ b/src/translations/uk.json @@ -1,492 +1,536 @@ { - "website":{ - "title":"Веб-гаманець Карбо", - "description":"Офіційний онлайн гаманець криптовалюти Карбованець - анонімний, надійний, працює повністю у вашому браузері для найвищої безпеки" + "website": { + "title": "Веб-гаманець Qwertycoin", + "description": "Офіційний онлайн гаманець криптовалюти Qwertycoin - анонімний, надійний, працює повністю у вашому браузері для найвищої безпеки" }, "messages": { - "menu": { - "home": "Огляд", - "account": "Огляд", - "send": "Надіслати", - "receive": "Отримати", - "export": "Експорт", - "donate": "Пожертвувати", - "settings": "Налаштування", - "disconnect": "Відключитися", - "network": "Статистика мережі", - "mining": "Майнінг" - }, - "global": { - "loading": "Триває завантаження", - "disableSecurity":"Відключити цю пересторогу, я розумію ризик", - "passwordInvalidRequirements":"Пароль повинен складатися принаймні з 8 символів - 1 великої літери, 1 маленької, одного числа, одного спецсимвола", - "passwordConfirmationNotMatching":"Підтвердження пароля не збігається з першим", - "download":"Завантажити", - "newVersionModal":{ - "title":"Є нова версія", - "content":"Хочете перезавантажити щоб оновити версію?", - "confirmText":"Так", - "cancelText":"Назад" - }, - "openWalletModal":{ - "title":"Пароль гаманця", - "confirmText":"Відкрити", - "cancelText":"Скасувати" - }, - "invalidPasswordModal":{ - "title":"Ой...", - "content":"Здається пароль невірний", - "confirmText":"Гаразд" - }, - "invalidMnemonicModal":{ - "title":"Ой...", - "content":"Фраза для відновлення невірна", - "confirmText":"Гаразд" - }, - "passwordNotComplexEnoughModal":{ - "title":"Пароль недостатньо складний", - "confirmText":"Гаразд" - }, - "permissionRequiredForCameraModal":{ - "title":"Ой...", - "content":"Потрібен дозвіл на доступ до камери для сканування QR коду", - "confirmText":"Гаразд" - } - }, - "bottom": { - "termsOfUse": "Умови використання", - "privacyPolicy": "Політика конфіденційності", - "support": "Допомога", - "donate": "Пожертвувати", - "network": "Мережа", - "miningPool": "Майнінг", - "github": "GitHub" - }, - "homepage": { - "mainTitle": "Безпечний Гаманець Карбованця", - "tagLine": "Найпростіший спосіб використання карбованців – в будь-який час, в будь-якому місці", - "actions": { - "loadWallet": "Завантажити мій гаманець", - "importWallet": "Імпортувати гаманець", - "create": "Створити", - "createWallet": "Створити гаманець" - }, - "notes": { - "secure": { - "title": "Безпечний", - "description": "Без серверів, повністю зашифрований!" - }, - "fast": { - "title": "Швидкий", - "description": "Доступний коли треба!" - }, - "technology": { - "title": "Локальний", - "description": "Ключі в браузері" - }, - "openSource": { - "title": "Open-source", - "description": "Не довіряй - перевіряй!" - } - } - }, - "accountPage": { - "title": "Аккаунт", - "subtitle": "Огляд вашого профілю та історії транзакцій", - "synchronizingBlock": { - "text": "Синхронізація..." - }, - "balanceBlock": { - "title": "Ваш баланс", - "unlocked": "Доступно" - }, - "historyBlock": { - "title": "Історія транзакцій", - "pendingTxStatus": "Очікується", - "emptyWallet": "У цьому гаманці поки немає коштів.", - "waitSync": "Будь ласка, зачекайте гаманець оновлює дані", - "beReallyPatient": "Початкова установка може зайняти деякий час...", - "getCoinAddress": "Отримати KRB" - }, - "txDetails":{ - "title":"Деталі транзакції", - "txHash":"Хеш", - "feesOnTx":"Комісія", - "blockHeight":"Висота блоку", - "paymentId":"Ідентифікатор платежу", - "txPrivKey":"Секретний ключ транзакції" - } - }, - "changeWalletPasswordPage":{ - "title":"Змінити ваш пароль", - "oldPassword":{ - "label":"Старий пароль", - "invalid":"Пароль недійсний" - }, - "newPassword":{ - "label":"Виберіть новий пароль для захисту вашого гаманця" - }, - "newPasswordConfirm":{ - "label":"Підтвердіть новий пароль" - }, - "confirm":"Змінити пароль", - "modalSuccess":{ - "title":"Пароль змінений!", - "confirmText":"Гаразд" - } - }, - "createWalletPage":{ - "generatingStep":{ - "title":"Створюється гаманець...", - "subtitle":"Майже готово", - "waitingMessage":"Генерується гаманець..." - }, - "finalizationStep":{ - "title":"Все. Ваш гаманець готовий!", - "subtitle":"Приготуйтеся використовувати Карбо як ніколи до цього", - "passwordSelectionBlock":{ - "label":"Захистіть ваш гаманець" - }, - "passwordConfirmBlock":{ - "label":"Підтвердіть пароль" - }, - "validPassword":"Використовувати цей пароль", - "backupBlock":{ - "title":"Збережіть ваші приватні дані щоб мати можливість відновлення.", - "option1":"Опція 1: ", - "option2":"Опція 2: ", - "titlePdf":"Завантажити PDF", - "titleManualWrite":"Записати ключі", - "privateKeys":"Приватний ключ", - "mnemonicPhrase":"Мнемонічна фраза", - "separatorManualMethodsSolution":" або ", - "confirmManuallyWritten":"Я записав собі мнемонічну фразу", - "warningMessage":"**Hе втратьте!** Вона не може бути відновлена якщо ви її втратите.
**Нікому не передавайте!** Ваші кошти можуть бути вкрадені якщо скористаєтеся цим файлом або фразою на шкідливому / фішинговому сайті.
**Зробіть резервну копію!** Бережіть як мільйон доларів, якого воно може одного прекрасного дня коштувати.
", - "finishButton":"Я зрозумів. Продовжити." - } - }, - "disclaimerBlock":{ - "title":"Ризики використання KarboWallet", - "content":"KarboWallet це веб-інтерфейс. Він допомагає вам використовувати Карбо без необхідності тримати повний вузол мережі Карбо.
Ми рекомендуємо ставитися до KarboWallet з усією серйозністю, як до вашого гаманця." - } - }, - "donatePage":{ - "title":"Пожертвувати", - "subtitle":"Допоможіть профінансувати розробку і оплату рахунків", - "webwalletBlock":{ - "title":"Допомога Веб-гаманцю", - "content":"Якщо ви хочете підтримати розробку, допомогти з оплатою хостингу, якщо вам подобається аплікація, будь ласка зробіть пожертву:

" - }, - "devFundBlock":{ - "title":"Офіційний фонд Карбо", - "content":"Щоб підтримати Карбованець, ви можете зробити пожертвування на ці адреси" - } - }, - "supportPage":{ - "title":"Підтримка", - "subtitle":"Ми тут щоб допомогти!", - "getInTouchBlock":{ - "title":"Зв'яжіться з нами!", - "content":"Є ідеї або побажання щодо поліпшення гаманця? Напишіть нам!", - "discord":"Канал Karbo в Discord" - } - }, - "networkPage":{ - "title":"Статистика мережі", - "subtitle":"Огляд мережі Карбо", - "statsBlock":{ - "hashrate":"Хешрейт", - "height":"Висота блокчейну", - "difficulty":"Складність", - "lastTimeBlock":"Час останнього блоку", - "lastReward":"Нагорода за останній блок" - } - }, - "sendPage":{ - "title":"Надіслати KRB", - "sendBlock":{ - "address":{ - "label":"Адреса одержувача", - "placeholder":"Вкажіть адресу, на яку хочете відправити кошти", - "invalid":"Адреса одержувача неправильна", - "fundsTo":"Кошти будуть відправлені на", - "receiver":"Одержувач", - "description":"Опис" - }, - "amount":{ - "label":"Сума", - "invalid":"Сума неправильна" - }, - "paymentId":{ - "label":"Payment ID (не обов'язково)", - "invalid":"Ідентифікатор платежу невірний. Довжина повинна бути 16 або 64 символи" - }, - "sendButton":"Надіслати", - "cancelButton":"Скасувати" - }, - "qrCodeScanning":{ - "explication":"Показати QR код" - }, - "notEnoughMoneyModal":{ - "title":"Ой...", - "content":"У гаманці недостатньо коштів для здійснення цього перекладу", - "confirmText":"Гаразд" - }, - "thankYouDonationModal":{ - "title":"Спасибі за ваше пожертвування!", - "content":"Ми цінуємо вашу підтримку.
Це пожертвування допоможе зробити Карбо краще", - "confirmText":"Гаразд" - }, - "transferSentModal":{ - "title":"Переказ успішно відправлений!", - "confirmText":"Гаразд" - }, - "transferExceptionModal":{ - "title":"Ой...", - "content":"Сталася помилка. Будь ласка повідомте про неї: {details}", - "confirmText":"Гаразд" - }, - "invalidAmountModal":{ - "title":"Ой...", - "content":"Неправильна сума", - "confirmText":"Гаразд" - }, - "creatingTransferModal":{ - "title":"Створюється переказ...", - "content":"Будь ласка зачекайте..." - }, - "finalizingTransferModal":{ - "title":"Завершується переказ...", - "content":"Будь ласка зачекайте..." - }, - "confirmTransactionModal":{ - "title":"Підтвердити переказ?", - "content":"Сума: {amount}
Комісії: {fees}
Всього: {total}", - "confirmText":"Підтвердити", - "cancelText":"Скасувати" - }, - "waitingNfcModal":{ - "title":"Очікування Nfc", - "content":"Піднесіть ближче до іншого пристрою" - } - }, - "receivePage":{ - "title":"Отримати KRB", - "receiveBlock":{ - "address":{ - "title":"Ваша адреса для отримання:", - "label":"Дайте цю адресу щоб отримати кошти" - }, - "qrCode":{ - "title":"Або персоналізуйте QR код:", - "labelAmount":"Сума (не обов'язково)", - "labelRecipient":"Назва одержувача (не обов'язково)", - "labelDescription":"Опис транзакції (не обов'язково)", - "updateButton":"Оновити" - } - }, - "qrBlock":{ - "title":"Ваш персональний QR код" - }, - "waitingNfcToWriteModal":{ - "title":"Очікування Nfc", - "titleSuccess":"Nfc тег записано", - "content":"Піднесіть NFC тег ближче для запису" - }, - "nfcErrorModal":{ - "titleInsufficientCapacity":"Місткість тега недостатня" - } - }, - "miningPage":{ - "title":"Інформація про майнінг", - "subtitle":"Підтримайте мережу майнінгом і отримайте в нагороду KRB", - "parameterBlock":{ - "title":"Параметри", - "labelDestinationAddress":"Гаманець на який майнити", - "labelThreads":"Кількість потоків (більше = вище швидкість)", - "start":"Старт", - "stop":"Стоп" - }, - "statisticsBlocks":{ - "title":"Статистика", - "validShares":"Валідні частки", - "hashrate":"Хешрейт", - "maxHashrate":"Макс. Хешрейт", - "dedicatedHardware":"Майнінг допомагає в децентралізації мережі і дозволяє вам заробити карбованці.", - "miningHandledBy":"Майнінг проходить на пулі pool.karbowanec.com" - } - }, - "settingsPage":{ - "title":"Налаштування", - "subtitle":"Тут ви можете змінити параметри", - "versionBlock":{ - "versionNumber":"Номер версії: ", - "versionCode":"Код версії: " - }, - "settingsBlock":{ - "speed":{ - "label":"Швидкість оновлення гаманця (споживатиме більше ресурсів)", - "fastest":"Найшвидша", - "fast":"Швидка", - "medium":"Середня", - "slow":"Повільна" - }, - "language":{ - "label":"Мова" - }, - "readMinerTx":{ - "label":"Зчитувати транзакції майнінгу (тільки для соло майнінгу)" - } - }, - "changePasswordButton":"Змінити пароль мого гаманця", - "deleteWalletButton":"Видалити мій гаманець (локальну копію)", - "walletSettings":{ - "creationHeight":{ - "label":"Висота створення гаманця" - }, - "currentScanningHeight": { - "label": "Поточна висота сканування" - }, - "updateButton":"Оновити" - }, - "deleteWalletModal":{ - "title":"Видалити мій гаманець (локальну копію)", - "content":"Ви ДІЙСНО впевнені що хочете видалити свій гаманець?", - "confirmText":"Так, я знаю що роблю", - "cancelText":"Скасувати" - } - }, - "importBasePage":{ - "parametersBlock":{ - "title":"Параметри", - "password":{ - "label":"Пароль для захисту вашого гаманця" - }, - "passwordConfirm":{ - "label":"Підтвердіть пароль", - "invalid":"Пароль не збігається з першим введенням паролем" - }, - "importHeight":{ - "label":"З якої висоти почати імпорт:" - } - } - }, - "importFromQrPage":{ - "title":"Імпортувати гаманець з QR коду", - "subtitle":"Імпортувати гаманець з офлайнової резервної копії", - "qrCodeBlock":{ - "title":"QR код", - "startScanButton":"Почати сканування", - "importButton":"Імпортувати" - }, - "qrScanningBlock":{ - "title":"Покажіть QR код" - } - }, - "exportPage":{ - "title":"Зробити резервну копію ваших даних", - "publicAddressBlock":{ - "title":"Ваша публічна адреса" - }, - "pdfBlock":{ - "title":"Резервна копія PDF", - "downloadButton":"Завантажити" - }, - "warningBlock":{ - "title":"Увага", - "content":"Якщо ви вирішите зберегти приватні ключі або мнемонічну фразу, гаманець НЕ ЗБЕРЕЖЕ їх в текстовому вигляді для вашої безпеки.
Файл є альтернативним рішенням де ваші ключі зашифровані і містить резервну копію всіх ваших транзакцій для прискорення синхронізації при відновленні." - }, - "exportBlock":{ - "title":"Експортувати сирі дані", - "privateKeysButton":"Отримати мої приватні ключі", - "mnemonicKeysButton":"Отримати мою мнемонічну фразу", - "fileButton":"Експортувати у файл" - }, - "walletKeysModal":{ - "title":"Приватні ключі", - "confirmText":"Гаразд", - "content":"Будь ласка поставтеся серйозно до збереження цих ключів. Той хто їх має, володіє коштами на гаманці!
Ключ витрачання: {privSpendKey}
Ключ стеження: {privViewKey}" - }, - "mnemonicKeyModal":{ - "title":"Мнемонічна фраза", - "confirmText":"Гаразд", - "content":"Будь ласка поставтеся серйозно до збереження цієї мнемонічною фрази. Той хто її має, володіє коштами на гаманці ! Фраза:
{mnemonic}" - }, - "mnemonicLangSelectionModal":{ - "title":"Виберіть мову мнемонічної фрази", - "confirmText":"Експортувати" - } - }, - "importPage":{ - "title":"Створити гаманець", - "subtitle":"З раніше створених ключів, файлу або мнемонічною фрази", - "chooseMethod":"Виберіть метод імпорту:", - "fromKeys":"З ключів", - "fromFile":"З файлу", - "fromMnemonic":"З мнемонічної фрази", - "fromQr":"З QR коду" - }, - "termsOfUsePage":{ - "title":"Умови використання", - "subtitle":"Уважно їх прочитайте." - }, - "importFromFilePage":{ - "title":"Імпорт гаманця з резервного фала", - "subtitle":"Використати резервний файл для створення гаманця", - "walletBlock":{ - "title":"Файл гаманця", - "label":"Виберіть файл", - "importButton":"Імпортувати" - } - }, - "importFromMnemonicPage":{ - "title":"Імпорт гаманця з мнемонічної фрази", - "subtitle":"Використати мнемонічну фразу для створення гаманця", - "mnemonicBlock":{ - "title":"Мнемонічна фраза", - "mnemonic":{ - "label":"Мнемонічна фраза: 25 слів", - "invalid":"Мнемонічна фраза неправильна", - "language":"Мова" - }, - "importButton":"Імпортувати" - } - }, - "importFromKeysPage":{ - "title":"Імпорт гаманця з ключів", - "subtitle":"Використати приватні ключі для створення гаманця", - "parametersBlock":{ - "viewOnlyWallet": { - "label": "Хочете створити гаманець стеження?", - "info": "Зверніть увагу, гаманець стеження призначений тільки для перегляду вхідних платежів, так що баланс може відображатися неправильно!" + "menu": { + "home": "Огляд", + "account": "Огляд", + "send": "Надіслати", + "receive": "Отримати", + "export": "Експорт", + "donate": "Пожертвувати", + "elections": "Вибори", + "contacts": "Контакти", + "settings": "Налаштування", + "disconnect": "Відключитися", + "network": "Статистика мережі", + "mining": "Майнінг" + }, + "global": { + "loading": "Триває завантаження", + "disableSecurity": "Відключити цю пересторогу, я розумію ризик", + "passwordInvalidRequirements": "Пароль повинен складатися принаймні з 8 символів - 1 великої літери, 1 маленької, одного числа, одного спецсимвола", + "passwordConfirmationNotMatching": "Підтвердження пароля не збігається з першим", + "download": "Завантажити", + "newVersionModal": { + "title": "Є нова версія", + "content": "Хочете перезавантажити щоб оновити версію?", + "confirmText": "Так", + "cancelText": "Назад" + }, + "openWalletModal": { + "title": "Пароль гаманця", + "confirmText": "Відкрити", + "cancelText": "Скасувати" + }, + "invalidPasswordModal": { + "title": "Ой...", + "content": "Здається пароль невірний", + "confirmText": "Гаразд" + }, + "invalidMnemonicModal": { + "title": "Ой...", + "content": "Фраза для відновлення невірна", + "confirmText": "Гаразд" + }, + "passwordNotComplexEnoughModal": { + "title": "Пароль недостатньо складний", + "confirmText": "Гаразд" + }, + "permissionRequiredForCameraModal": { + "title": "Ой...", + "content": "Потрібен дозвіл на доступ до камери для сканування QR коду", + "confirmText": "Гаразд" } - }, - "keysBlock":{ - "titleNotViewOnly":"Ключі гаманця", - "titleViewOnly":"Гаманець стеження", - "privateSpend":{ - "label":"Приватний ключ витрачання" - }, - "privateView":{ - "label":"Приватний ключ стеження", - "optional":"(не обов'язково)" - }, - "publicKey":{ - "label":"Публічний ключ" - }, - "importButton":"Імпортувати" - } - } - }, - "number":{ + }, + "bottom": { + "termsOfUse": "Умови використання", + "privacyPolicy": "Політика конфіденційності", + "support": "Допомога", + "donate": "Пожертвувати", + "network": "Мережа", + "miningPool": "Майнінг", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Безпечний Гаманець Qwertycoinванця", + "tagLine": "де завгодно. в будь-який час. будь яке місце. будь-який пристрій.", + "tagLineTwo": "Найпростіший спосіб використання Qwertycoin", + "actions": { + "loadWallet": "Завантажити мій гаманець", + "importWallet": "Імпортувати гаманець", + "create": "Створити", + "createWallet": "Створити гаманець" + } + }, + "accountPage": { + "title": "Аккаунт", + "subtitle": "Огляд вашого профілю та історії транзакцій", + "synchronizingBlock": { + "text": "Синхронізація..." + }, + "balanceBlock": { + "title": "Ваш баланс", + "unlocked": "Доступно" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Історія транзакцій", + "pendingTxStatus": "Очікується", + "emptyWallet": "У цьому гаманці поки немає коштів.", + "waitSync": "Будь ласка, зачекайте гаманець оновлює дані", + "beReallyPatient": "Початкова установка може зайняти деякий час...", + "getCoinAddress": "Отримати QWC" + }, + "txDetails": { + "title": "Деталі транзакції", + "txHash": "Хеш", + "feesOnTx": "Комісія", + "blockHeight": "Висота блоку", + "paymentId": "Ідентифікатор платежу", + "unlockStatus": "Status", + "unlockConfirm": "Confirmations", + "txPrivKey": "Секретний ключ транзакції" + } + }, + "changeWalletPasswordPage": { + "title": "Змінити ваш пароль", + "oldPassword": { + "label": "Старий пароль", + "invalid": "Пароль недійсний" + }, + "newPassword": { + "label": "Виберіть новий пароль для захисту вашого гаманця" + }, + "newPasswordConfirm": { + "label": "Підтвердіть новий пароль" + }, + "confirm": "Змінити пароль", + "modalSuccess": { + "title": "Пароль змінений!", + "confirmText": "Гаразд" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "Контакти" + }, + "electionsPage": { + "title": "Вибори" + }, + "createWalletPage": { + "generatingStep": { + "title": "Створюється гаманець...", + "subtitle": "Майже готово", + "waitingMessage": "Генерується гаманець..." + }, + "finalizationStep": { + "title": "Все. Ваш гаманець готовий!", + "subtitle": "Приготуйтеся використовувати Qwertycoin як ніколи до цього", + "passwordSelectionBlock": { + "label": "Захистіть ваш гаманець" + }, + "passwordConfirmBlock": { + "label": "Підтвердіть пароль" + }, + "validPassword": "Використовувати цей пароль", + "backupBlock": { + "title": "Збережіть ваші приватні дані щоб мати можливість відновлення.", + "option1": "Опція 1: ", + "option2": "Опція 2: ", + "titlePdf": "Завантажити PDF", + "titleManualWrite": "Записати ключі", + "privateKeys": "Приватний ключ", + "mnemonicPhrase": "Мнемонічна фраза", + "separatorManualMethodsSolution": " або ", + "confirmManuallyWritten": "Я записав собі мнемонічну фразу", + "warningMessage": "**Hе втратьте!** Вона не може бути відновлена якщо ви її втратите.
**Нікому не передавайте!** Ваші кошти можуть бути вкрадені якщо скористаєтеся цим файлом або фразою на шкідливому / фішинговому сайті.
**Зробіть резервну копію!** Бережіть як мільйон доларів, якого воно може одного прекрасного дня коштувати.
", + "finishButton": "Я зрозумів. Продовжити." + } + }, + "disclaimerBlock": { + "title": "Ризики використання QwertycoinWallet", + "content": "QwertycoinWallet це веб-інтерфейс. Він допомагає вам використовувати Qwertycoin без необхідності тримати повний вузол мережі Qwertycoin.
Ми рекомендуємо ставитися до QwertycoinWallet з усією серйозністю, як до вашого гаманця." + } + }, + "donatePage": { + "title": "Пожертвувати", + "subtitle": "Допоможіть профінансувати розробку і оплату рахунків", + "webwalletBlock": { + "title": "Допомога Веб-гаманцю", + "content": "Якщо ви хочете підтримати розробку, допомогти з оплатою хостингу, якщо вам подобається аплікація, будь ласка зробіть пожертву:

" + }, + "devFundBlock": { + "title": "Офіційний фонд Qwertycoin", + "content": "Щоб підтримати Qwertycoinванець, ви можете зробити пожертвування на ці адреси" + } + }, + "supportPage": { + "title": "Підтримка", + "subtitle": "Ми тут щоб допомогти!", + "getInTouchBlock": { + "title": "Зв'яжіться з нами!", + "content": "Є ідеї або побажання щодо поліпшення гаманця? Напишіть нам!", + "discord": "Канал Qwertycoin в Discord" + } + }, + "networkPage": { + "title": "Статистика мережі", + "subtitle": "Огляд мережі Qwertycoin", + "statsBlock": { + "connectNode": "Підключено Masternode", + "hashrate": "Хешрейт", + "height": "Висота блокчейну", + "difficulty": "Складність", + "lastTimeBlock": "Час останнього блоку", + "lastReward": "Нагорода за останній блок" + } + }, + "sendPage": { + "title": "Надіслати QWC", + "sendBlock": { + "address": { + "label": "Адреса одержувача", + "placeholder": "Вкажіть адресу, на яку хочете відправити кошти", + "invalid": "Адреса одержувача неправильна", + "fundsTo": "Кошти будуть відправлені на", + "receiver": "Одержувач", + "description": "Опис" + }, + "amount": { + "label": "Сума", + "invalid": "Сума неправильна" + }, + "paymentId": { + "label": "Payment ID (не обов'язково)", + "invalid": "Ідентифікатор платежу невірний. Довжина повинна бути 16 або 64 символи" + }, + "sendButton": "Надіслати", + "cancelButton": "Скасувати" + }, + "qrCodeScanning": { + "explication": "Показати QR код" + }, + "notEnoughMoneyModal": { + "title": "Ой...", + "content": "У гаманці недостатньо коштів для здійснення цього перекладу", + "confirmText": "Гаразд" + }, + "thankYouDonationModal": { + "title": "Спасибі за ваше пожертвування!", + "content": "Ми цінуємо вашу підтримку.
Це пожертвування допоможе зробити Qwertycoin краще", + "confirmText": "Гаразд" + }, + "transferSentModal": { + "title": "Переказ успішно відправлений!", + "confirmText": "Гаразд" + }, + "transferExceptionModal": { + "title": "Ой...", + "content": "Сталася помилка. Будь ласка повідомте про неї: {details}", + "confirmText": "Гаразд" + }, + "invalidAmountModal": { + "title": "Ой...", + "content": "Неправильна сума", + "confirmText": "Гаразд" + }, + "creatingTransferModal": { + "title": "Створюється переказ...", + "content": "Будь ласка зачекайте..." + }, + "finalizingTransferModal": { + "title": "Завершується переказ...", + "content": "Будь ласка зачекайте..." + }, + "confirmTransactionModal": { + "title": "Підтвердити переказ?", + "content": "Сума: {amount}
Комісії: {fees}
Всього: {total}", + "confirmText": "Підтвердити", + "cancelText": "Скасувати" + }, + "waitingNfcModal": { + "title": "Очікування Nfc", + "content": "Піднесіть ближче до іншого пристрою" + } + }, + "receivePage": { + "title": "Отримати QWC", + "receiveBlock": { + "address": { + "title": "Ваша адреса для отримання:", + "label": "Дайте цю адресу щоб отримати кошти" + }, + "qrCode": { + "title": "Або персоналізуйте QR код:", + "labelAmount": "Сума (не обов'язково)", + "labelRecipient": "Назва одержувача (не обов'язково)", + "labelDescription": "Опис транзакції (не обов'язково)", + "updateButton": "Оновити" + } + }, + "qrBlock": { + "title": "Ваш персональний QR код" + }, + "waitingNfcToWriteModal": { + "title": "Очікування Nfc", + "titleSuccess": "Nfc тег записано", + "content": "Піднесіть NFC тег ближче для запису" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Місткість тега недостатня" + } + }, + "miningPage": { + "title": "Інформація про майнінг", + "subtitle": "Підтримайте мережу майнінгом і отримайте в нагороду QWC", + "parameterBlock": { + "title": "Параметри", + "labelDestinationAddress": "Гаманець на який майнити", + "labelThreads": "Кількість потоків (більше = вище швидкість)", + "start": "Старт", + "stop": "Стоп" + }, + "statisticsBlocks": { + "title": "Статистика", + "validShares": "Валідні частки", + "hashrate": "Хешрейт", + "maxHashrate": "Макс. Хешрейт", + "dedicatedHardware": "Майнінг допомагає в децентралізації мережі і дозволяє вам заробити Qwertycoinванці.", + "miningHandledBy": "Майнінг проходить на пулі https://pool.qwertycoin.org" + } + }, + "settingsPage": { + "title": "Налаштування", + "subtitle": "Тут ви можете змінити параметри", + "versionBlock": { + "versionNumber": "Номер версії: ", + "versionCode": "Код версії: " + }, + "settingsBlock": { + "speed": { + "label": "Швидкість оновлення гаманця (споживатиме більше ресурсів)", + "fastest": "Найшвидша", + "fast": "Швидка", + "medium": "Середня", + "slow": "Повільна" + }, + "language": { + "label": "Мова" + }, + "currency": { + "label": "національна валюта" + }, + "readMinerTx": { + "label": "Зчитувати транзакції майнінгу (тільки для соло майнінгу)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Змінити пароль мого гаманця", + "deleteWalletButton": "Видалити мій гаманець (локальну копію)", + "walletSettings": { + "creationHeight": { + "label": "Висота створення гаманця" + }, + "currentScanningHeight": { + "label": "Поточна висота сканування" + }, + "updateButton": "Оновити" + }, + "deleteWalletModal": { + "title": "Видалити мій гаманець (локальну копію)", + "content": "Ви ДІЙСНО впевнені що хочете видалити свій гаманець?", + "confirmText": "Так, я знаю що роблю", + "cancelText": "Скасувати" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Параметри", + "password": { + "label": "Пароль для захисту вашого гаманця" + }, + "passwordConfirm": { + "label": "Підтвердіть пароль", + "invalid": "Пароль не збігається з першим введенням паролем" + }, + "importHeight": { + "label": "З якої висоти почати імпорт:" + } + } + }, + "importFromQrPage": { + "title": "Імпортувати гаманець з QR коду", + "subtitle": "Імпортувати гаманець з офлайнової резервної копії", + "qrCodeBlock": { + "title": "QR код", + "startScanButton": "Почати сканування", + "importButton": "Імпортувати" + }, + "qrScanningBlock": { + "title": "Покажіть QR код" + } + }, + "exportPage": { + "title": "Зробити резервну копію ваших даних", + "publicAddressBlock": { + "title": "Ваша публічна адреса" + }, + "pdfBlock": { + "title": "Резервна копія PDF", + "downloadButton": "Завантажити" + }, + "warningBlock": { + "title": "Увага", + "content": "Якщо ви вирішите зберегти приватні ключі або мнемонічну фразу, гаманець НЕ ЗБЕРЕЖЕ їх в текстовому вигляді для вашої безпеки.
Файл є альтернативним рішенням де ваші ключі зашифровані і містить резервну копію всіх ваших транзакцій для прискорення синхронізації при відновленні." + }, + "exportBlock": { + "title": "Експортувати сирі дані", + "privateKeysButton": "Отримати мої приватні ключі", + "mnemonicKeysButton": "Отримати мою мнемонічну фразу", + "fileButton": "Експортувати у файл" + }, + "walletKeysModal": { + "title": "Приватні ключі", + "confirmText": "Гаразд", + "content": "Будь ласка поставтеся серйозно до збереження цих ключів. Той хто їх має, володіє коштами на гаманці!
Ключ витрачання: {privSpendKey}
Ключ стеження: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Мнемонічна фраза", + "confirmText": "Гаразд", + "content": "Будь ласка поставтеся серйозно до збереження цієї мнемонічною фрази. Той хто її має, володіє коштами на гаманці ! Фраза:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "Виберіть мову мнемонічної фрази", + "confirmText": "Експортувати" + } + }, + "importPage": { + "title": "Створити гаманець", + "subtitle": "З раніше створених ключів, файлу або мнемонічною фрази", + "chooseMethod": "Виберіть метод імпорту:", + "fromKeys": "З ключів", + "fromFile": "З файлу", + "fromMnemonic": "З мнемонічної фрази", + "fromQr": "З QR коду" + }, + "termsOfUsePage": { + "title": "Умови використання", + "subtitle": "Уважно їх прочитайте." + }, + "importFromFilePage": { + "title": "Імпорт гаманця з резервного фала", + "subtitle": "Використати резервний файл для створення гаманця", + "walletBlock": { + "title": "Файл гаманця", + "label": "Виберіть файл", + "importButton": "Імпортувати" + } + }, + "importFromMnemonicPage": { + "title": "Імпорт гаманця з мнемонічної фрази", + "subtitle": "Використати мнемонічну фразу для створення гаманця", + "mnemonicBlock": { + "title": "Мнемонічна фраза", + "mnemonic": { + "label": "Мнемонічна фраза: 25 слів", + "invalid": "Мнемонічна фраза неправильна", + "language": "Мова" + }, + "importButton": "Імпортувати" + } + }, + "importFromKeysPage": { + "title": "Імпорт гаманця з ключів", + "subtitle": "Використати приватні ключі для створення гаманця", + "parametersBlock": { + "viewOnlyWallet": { + "label": "Хочете створити гаманець стеження?", + "info": "Зверніть увагу, гаманець стеження призначений тільки для перегляду вхідних платежів, так що баланс може відображатися неправильно!" + } + }, + "keysBlock": { + "titleNotViewOnly": "Ключі гаманця", + "titleViewOnly": "Гаманець стеження", + "privateSpend": { + "label": "Приватний ключ витрачання" + }, + "privateView": { + "label": "Приватний ключ стеження", + "optional": "(не обов'язково)" + }, + "publicKey": { + "label": "Публічний ключ" + }, + "importButton": "Імпортувати" + } + } }, - "date":{ - "short": { - "year": "numeric", "month": "short", "day": "numeric" - }, - "long": { - "year": "numeric", "month": "short", "day": "numeric", - "weekday": "short", "hour": "numeric", "minute": "numeric", "hour12": true - } + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": true + } } -} \ No newline at end of file +} diff --git a/src/translations/vn.json b/src/translations/vn.json new file mode 100644 index 00000000..4e6872b6 --- /dev/null +++ b/src/translations/vn.json @@ -0,0 +1,539 @@ +{ + "website": { + "title": "Ví Qwertycoin | Đơn giản, liền mạch, an toàn. Chào mừng đến với tương lai.", + "description": "Ví trực tuyến chính thức cho tiền Qwertycoin - được xử lý hoàn toàn trong trình duyệt của bạn để bảo mật tối ưu" + }, + "messages": { + "menu": { + "home": "Nhà", + "account": "Tài khoản", + "send": "Gửi", + "receive": "Nhận được", + "export": "Xuất khẩu", + "donate": "Quyên góp", + "elections": "Bầu cử", + "contacts": "Liên hệ", + "settings": "Cài đặt", + "disconnect": "Ngắt kết nối", + "network": "Thống kê mạng", + "mining": "Khai thác mỏ" + }, + "global": { + "loading": "Tải", + "disableSecurity": "Vô hiệu hóa bảo mật này, tôi hiểu rủi ro", + "passwordInvalidRequirements": "The password needs at least 8 characters - 1 upper case letter, 1 lower case letter, one number, and one special character", + "passwordConfirmationNotMatching": "The password does not match the first password you wrote", + "download": "Tải về", + "newVersionModal": { + "title": "Một phiên bản mới có sẵn", + "content": "Bạn có muốn tải lại để tải phiên bản mới?", + "confirmText": "Vâng", + "cancelText": "Trở lại" + }, + "openWalletModal": { + "title": "Mật khẩu ví", + "confirmText": "Mở", + "cancelText": "Hủy bỏ" + }, + "invalidPasswordModal": { + "title": "Rất tiếc ...", + "content": "Mật khẩu của bạn có vẻ không hợp lệ", + "confirmText": "được" + }, + "invalidMnemonicModal": { + "title": "Rất tiếc ...", + "content": "The mnemonic phrase is invalid", + "confirmText": "được" + }, + "passwordNotComplexEnoughModal": { + "title": "The password is not complex enough", + "confirmText": "được" + }, + "permissionRequiredForCameraModal": { + "title": "Rất tiếc ...", + "content": "The permission to access your camera is required to scan the QR code", + "confirmText": "được" + } + }, + "bottom": { + "termsOfUse": "Điều khoản sử dụng", + "privacyPolicy": "Chính sách bảo mật", + "support": "Ủng hộ", + "donate": "Quyên góp", + "network": "Thống kê mạng", + "miningPool": "Hồ bơi khai thác", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Qwertycoin Ví", + "tagLine": "bất cứ nơi nào Bất cứ lúc nào. bất cứ nơi nào. bất kỳ thiết bị.", + "tagLineTwo": "Cách đơn giản nhất để sử dụng Qwertycoin", + "actions": { + "loadWallet": "Nạp ví của tôi", + "importWallet": "Nhập ví", + "create": "Tạo nên", + "createWallet": "Tạo nên..." + } + }, + "accountPage": { + "title": "Account", + "subtitle": "Your account overview and transaction history", + "synchronizingBlock": { + "text": "Synchronizing..." + }, + "balanceBlock": { + "title": "Your balance", + "unlocked": "Unlocked" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "Transaction history", + "pendingTxStatus": "Pending", + "emptyWallet": "You currently have no funds in this wallet.", + "waitSync": "Please wait until the wallet is updated", + "beReallyPatient": "The initial setup can take some time...", + "getCoinAddress": "Receive QWC" + }, + "txDetails": { + "title": "Transaction details", + "txHash": "Transaction Hash", + "feesOnTx": "Transaction fee", + "blockHeight": "Block height", + "paymentId": "Payment ID", + "unlockStatus": "Status", + "unlockConfirm": "Confirmations", + "txPrivKey": "Transaction Private Key" + } + }, + "changeWalletPasswordPage": { + "title": "Change your password", + "oldPassword": { + "label": "Old password", + "invalid": "The password is invalid" + }, + "newPassword": { + "label": "Choose a new password to protect your wallet" + }, + "newPasswordConfirm": { + "label": "Confirm the new password" + }, + "confirm": "Change the password", + "modalSuccess": { + "title": "Password changed!", + "confirmText": "được" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "Cancel", + "confirm": "Add", + "contactAddress": "Address", + "contactName": "Name", + "getNewContacts": "Add Contact", + "newContact": "New Contact", + "noContacts": "You don't have any contacts yet.", + "title": "Your Contacts" + }, + "contactDetailsBlock": { + "address": "Address", + "sendTo": "Send to ", + "title": "Contactdetails" + }, + "subtitle": "Get in touch with other people", + "title": "Liên hệ" + }, + "electionsPage": { + "title": "Bầu cử" + }, + "createWalletPage": { + "generatingStep": { + "title": "Your wallet is being generated...", + "subtitle": "It's almost done", + "waitingMessage": "Generating your wallet..." + }, + "finalizationStep": { + "title": "That was simple. Your account is ready!", + "subtitle": "Be ready to use Qwertycoin like you never have", + "passwordSelectionBlock": { + "label": "Protect your wallet" + }, + "passwordConfirmBlock": { + "label": "Confirm the password" + }, + "validPassword": "Use this password", + "backupBlock": { + "title": "Save your private credentials for recovery.", + "option1": "Option 1: ", + "option2": "Option 2: ", + "titlePdf": "Download a PDF copy", + "titleManualWrite": "Write down my keys", + "privateKeys": "Private key", + "mnemonicPhrase": "Mnemonic phrase", + "separatorManualMethodsSolution": " or ", + "confirmManuallyWritten": "I wrote my seed phrase down", + "warningMessage": "**Do not lose it!** It cannot be recovered if you lose it.
**Do not share it!** Your funds will be stolen if you use this file or seed on a malicious/phishing site.
**Make a backup!** Secure it like the millions of dollars it may one day be worth.
", + "finishButton": "I understand. Continue." + } + }, + "disclaimerBlock": { + "title": "Risk of Using QwertycoinWallet", + "content": "QwertycoinWallet is a web-based interface. It helps you use Qwertycoin without running a full Qwertycoin node.
We recommend you treat QwertycoinWallet like you will treat your actual wallet." + } + }, + "donatePage": { + "title": "Donate", + "subtitle": "Help to fund the development and pay the bills", + "webwalletBlock": { + "title": "Webwallet", + "content": "If you want to help to pay for the servers, to support new features development, and like this app, please consider a donation:

" + }, + "devFundBlock": { + "title": "Qwertycoin Dev fund", + "content": "To help Qwertycoin, you can donate at these addresses" + } + }, + "supportPage": { + "title": "Support", + "subtitle": "We are here to help!", + "getInTouchBlock": { + "title": "Let's Get In Touch!", + "content": "Do you have ideas or feedback that could help us improve the wallet? Contact us!", + "discord": "Qwertycoin Discord Channel" + } + }, + "networkPage": { + "title": "Network stats", + "subtitle": "Insights on the Qwertycoin network", + "statsBlock": { + "connectNode": "Connected Masternode", + "hashrate": "Network hashrate", + "height": "Blockchain height", + "difficulty": "Network difficulty", + "lastTimeBlock": "Last block found", + "lastReward": "Last block reward" + } + }, + "sendPage": { + "title": "Send QWC", + "sendBlock": { + "address": { + "label": "Destination address", + "placeholder": "Write the address where you want to send funds", + "invalid": "The destination address is invalid", + "fundsTo": "The funds will be sent to", + "receiver": "Receiver", + "description": "Description" + }, + "amount": { + "label": "Amount to send", + "invalid": "The amount is invalid" + }, + "paymentId": { + "label": "Payment ID (optional)", + "invalid": "The payment ID is invalid. The length must be 16 or 64 characters" + }, + "sendButton": "Send", + "cancelButton": "Hủy bỏ" + }, + "qrCodeScanning": { + "explication": "Present the QR code" + }, + "notEnoughMoneyModal": { + "title": "Rất tiếc ...", + "content": "You don't have enough funds in your wallet to execute this transfer", + "confirmText": "được" + }, + "thankYouDonationModal": { + "title": "Thank you for your donation!", + "content": "Your help is appreciated. This donation will help make Qwertycoin better", + "confirmText": "được" + }, + "transferSentModal": { + "title": "Transfer sent successfully!", + "confirmText": "được" + }, + "transferExceptionModal": { + "title": "Rất tiếc ...", + "content": "An error occurred. Please report this error: {details}", + "confirmText": "được" + }, + "invalidAmountModal": { + "title": "Rất tiếc ...", + "content": "Invalid amount", + "confirmText": "được" + }, + "creatingTransferModal": { + "title": "Creating transfer ...", + "content": "Please wait..." + }, + "finalizingTransferModal": { + "title": "Finalizing transfer ...", + "content": "Please wait..." + }, + "confirmTransactionModal": { + "title": "Confirm transfer?", + "content": "Amount: {amount}
Fees: {fees}
Total: {total}", + "confirmText": "Confirm", + "cancelText": "Hủy bỏ" + }, + "waitingNfcModal": { + "title": "Waiting NFC", + "content": "Bring this device closer to the other device" + } + }, + "receivePage": { + "title": "Receive QWC", + "receiveBlock": { + "address": { + "title": "Your address to receive funds:", + "label": "Give this address to receive funds" + }, + "qrCode": { + "title": "Or personalize the QR code:", + "labelAmount": "Amount (optional)", + "labelRecipient": "Recipient name (optional)", + "labelDescription": "Transaction description (optional)", + "updateButton": "Update" + } + }, + "qrBlock": { + "title": "Your customized QR code" + }, + "waitingNfcToWriteModal": { + "title": "Waiting NFC", + "titleSuccess": "NFC Tag written", + "content": "Bring the NFC tag closer to this device to write" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "Tag capacity insufficient" + } + }, + "miningPage": { + "title": "Mine directly in your browser", + "subtitle": "Support the network by mining and be rewarded with QWC", + "parameterBlock": { + "title": "Parameters", + "labelDestinationAddress": "Wallet to mine", + "labelThreads": "Number of threads (more = higher hashrate)", + "start": "Start", + "stop": "Stop" + }, + "statisticsBlocks": { + "title": "Statistics", + "validShares": "Valid shares", + "hashrate": "Hashrate", + "maxHashrate": "Max Hashrate", + "dedicatedHardware": "With dedicating mining software and hardware, you could earn more and help decentralize the network.", + "miningHandledBy": "This mining is handled by the mining pool pool.qwertycoin.org" + } + }, + "settingsPage": { + "title": "Settings", + "subtitle": "Change your parameters here", + "versionBlock": { + "versionNumber": "Version number: ", + "versionCode": "Version code: " + }, + "settingsBlock": { + "speed": { + "label": "Speed to update the wallet (will consume more resources)", + "fastest": "Fastest", + "fast": "Fast", + "medium": "Medium", + "slow": "Slow" + }, + "language": { + "label": "Language" + }, + "currency": { + "label": "National Currency" + }, + "readMinerTx": { + "label": "Read miner transactions (only for solo mining)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "Change my wallet password", + "deleteWalletButton": "Delete my wallet (local copy)", + "walletSettings": { + "creationHeight": { + "label": "Creation height of the wallet" + }, + "currentScanningHeight": { + "label": "Current scanning height" + }, + "updateButton": "Update" + }, + "deleteWalletModal": { + "title": "Delete My Wallet (local copy)", + "content": "Are you sure you REALLY want to delete your wallet ?", + "confirmText": "Yes I'm sure", + "cancelText": "Hủy bỏ" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "Parameters", + "password": { + "label": "Password to protect your wallet" + }, + "passwordConfirm": { + "label": "Confirm the password", + "invalid": "The password does not match the first password you wrote" + }, + "importHeight": { + "label": "Height to import from:" + } + } + }, + "importFromQrPage": { + "title": "Importing wallet from a QR code", + "subtitle": "Import a wallet from an offline backup", + "qrCodeBlock": { + "title": "QR code", + "startScanButton": "Start the scan", + "importButton": "Import" + }, + "qrScanningBlock": { + "title": "Present the QR code" + } + }, + "exportPage": { + "title": "Backup your credentials", + "publicAddressBlock": { + "title": "Your public address" + }, + "pdfBlock": { + "title": "PDF Backup", + "downloadButton": "Download" + }, + "warningBlock": { + "title": "Warning", + "content": "If you choose to save your private keys or your mnemonic phrase, PLEASE DO NOT store them in clear-text for your own safety.
The file is an alternate solution where your keys are encrypted and contains a backup of all your transactions to spare you a future synchronisation." + }, + "exportBlock": { + "title": "Export your RAW credentials", + "privateKeysButton": "Get my private keys", + "mnemonicKeysButton": "Get my mnemonic phrase", + "fileButton": "Export to a file" + }, + "walletKeysModal": { + "title": "Private keys", + "confirmText": "được", + "content": "Please carefully store these keys. Possessing them means possessing the funds associated !
Spend key: {privSpendKey}
Private view key: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "Mnemonic phrase", + "confirmText": "được", + "content": "Please store carefully this mnemonic phrase. Possessing it means possessing the funds associated ! The phrase is:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "In which language do you want your mnemonic phrase?", + "confirmText": "Export" + } + }, + "importPage": { + "title": "Create a wallet", + "subtitle": "From previously created keys, file, or mnemonic phrase", + "chooseMethod": "Choose your import method:", + "fromKeys": "From keys", + "fromFile": "From a file", + "fromMnemonic": "From a mnemonic phrase", + "fromQr": "From a QR code" + }, + "termsOfUsePage": { + "title": "Terms of use", + "subtitle": "Please read them carefully." + }, + "privacyPolicyPage": { + "title": "Privacy Policy", + "subtitle": "Please read them carefully." + }, + "importFromFilePage": { + "title": "Importing wallet from a backup file", + "subtitle": "Use your backup file to create a wallet", + "walletBlock": { + "title": "Wallet file", + "label": "Select the file", + "importButton": "Import" + } + }, + "importFromMnemonicPage": { + "title": "Importing wallet from a mnemonic phrase", + "subtitle": "Use your phrase to create a wallet", + "mnemonicBlock": { + "title": "Mnemonic phrase", + "mnemonic": { + "label": "Mnemonic phrase: 25 words", + "invalid": "The mnemonic phrase is invalid", + "language": "Language" + }, + "importButton": "Import" + } + }, + "importFromKeysPage": { + "title": "Importing wallet from keys", + "subtitle": "Use your keys to create a wallet", + "parametersBlock": { + "viewOnlyWallet": { + "label": "Do you want a view only wallet?" + } + }, + "keysBlock": { + "titleNotViewOnly": "Wallet keys", + "titleViewOnly": "View only wallet", + "privateSpend": { + "label": "Private spend key" + }, + "privateView": { + "label": "Private view key", + "optional": "(optional)" + }, + "publicKey": { + "label": "Public key" + }, + "importButton": "Import" + } + } + }, + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": true + } + } +} diff --git a/src/translations/zh.json b/src/translations/zh.json new file mode 100644 index 00000000..7294d79c --- /dev/null +++ b/src/translations/zh.json @@ -0,0 +1,539 @@ +{ + "website": { + "title": "Qwertycoin钱包| 简单,无缝,安全。 欢迎来到未来。", + "description": "Qwertycoin币的官方在线钱包 - 完全在浏览器端处理,兼顾最优化的安全性。" + }, + "messages": { + "menu": { + "home": "主页", + "account": "帐户", + "send": "发送", + "receive": "接收", + "export": "导出", + "donate": "捐助", + "elections": "选举", + "contacts": "往来", + "settings": "设置", + "disconnect": "断开", + "network": "网络", + "mining": "挖矿" + }, + "global": { + "loading": "载入中", + "disableSecurity": "禁用此安全性,我已完全了解风险", + "passwordInvalidRequirements": "密码长度需要大于8位 - 至少包含1个大写字母,1个小写字母,1个数字,以及1个特殊字符。", + "passwordConfirmationNotMatching": "两次输入的密码不匹配", + "download": "下载", + "newVersionModal": { + "title": "有新版本可以更新", + "content": "要重新加载新版本吗?", + "confirmText": "是", + "cancelText": "返回" + }, + "openWalletModal": { + "title": "钱包密码", + "confirmText": "打开", + "cancelText": "取消" + }, + "invalidPasswordModal": { + "title": "糟糕!", + "content": "您的密码似乎无效", + "confirmText": "确认" + }, + "invalidMnemonicModal": { + "title": "糟糕!", + "content": "助记词无效", + "confirmText": "确认" + }, + "passwordNotComplexEnoughModal": { + "title": "密码太简单", + "confirmText": "确认" + }, + "permissionRequiredForCameraModal": { + "title": "糟糕!", + "content": "扫描二维码需要访问您相机的权限", + "confirmText": "确认" + } + }, + "bottom": { + "termsOfUse": "使用条款", + "privacyPolicy": "隐私政策", + "support": "支持", + "donate": "捐助", + "network": "网络统计", + "miningPool": "矿池", + "github": "GitHub" + }, + "homepage": { + "mainTitle": "Qwertycoin钱包", + "tagLine": "无论何时、何地、何种设备。", + "tagLineTwo": "使用Qwertycoin最简单的方法", + "actions": { + "loadWallet": "加载我的钱包", + "importWallet": "导入钱包", + "create": "创建", + "createWallet": "创建一个钱包" + } + }, + "accountPage": { + "title": "帐户", + "subtitle": "您的帐户概览和交易记录", + "synchronizingBlock": { + "text": "同步中..." + }, + "balanceBlock": { + "title": "您的余额", + "unlocked": "解锁" + }, + "currencyBlock": { + "btc": "BTC", + "eth": "ETH", + "ltc": "LTC", + "usd": "USD", + "eur": "EUR", + "aud": "AUD", + "cad": "CAD", + "chf": "CHF", + "cny": "CNY", + "gbp": "GBP", + "jpy": "JPY", + "kwd": "KWD", + "krw": "KRW", + "rub": "RUB", + "try": "TRY", + "vnd": "VND" + }, + "historyBlock": { + "title": "交易记录", + "pendingTxStatus": "等待中", + "emptyWallet": "您的钱包目前没有资金。", + "waitSync": "请等待钱包更新完毕", + "beReallyPatient": "初始化设置可能比较耗时......", + "getCoinAddress": "收到QWC" + }, + "txDetails": { + "title": "交易明细", + "txHash": "交易哈希", + "feesOnTx": "手续费", + "blockHeight": "区块高度", + "paymentId": "付款ID", + "unlockStatus": "状态", + "unlockConfirm": "确认数", + "txPrivKey": "交易私钥" + } + }, + "changeWalletPasswordPage": { + "title": "更改您的密码", + "oldPassword": { + "label": "旧密码", + "invalid": "密码无效" + }, + "newPassword": { + "label": "选择一个新密码来保护您的钱包" + }, + "newPasswordConfirm": { + "label": "确认新密码" + }, + "confirm": "更改密码", + "modalSuccess": { + "title": "密码已更改!", + "confirmText": "确认" + } + }, + "contactPage": { + "contactBlock": { + "cancel": "取消", + "confirm": "新增", + "contactAddress": "地址", + "contactName": "名字", + "getNewContacts": "添加联系人", + "newContact": "新建联系人", + "noContacts": "您当前有0个联系人。", + "title": "您的联系人" + }, + "contactDetailsBlock": { + "address": "地址", + "sendTo": "发送到 ", + "title": "联系人详情" + }, + "subtitle": "多和其他人联系", + "title": "往来" + }, + "electionsPage": { + "title": "选举" + }, + "createWalletPage": { + "generatingStep": { + "title": "您的钱包正在生成......", + "subtitle": "差不多快好了", + "waitingMessage": "正在生成您的钱包......" + }, + "finalizationStep": { + "title": "这很简单,您的帐户已准备就绪!", + "subtitle": "准备迎接Qwertycoin钱包的全新体验吧!", + "passwordSelectionBlock": { + "label": "保护您的钱包" + }, + "passwordConfirmBlock": { + "label": "确认密码" + }, + "validPassword": "使用此密码", + "backupBlock": { + "title": "保存您的私人凭据以便后期用于恢复钱包。", + "option1": "选项1:", + "option2": "选项2:", + "titlePdf": "下载PDF副本", + "titleManualWrite": "在纸上写下我的私钥", + "privateKeys": "私钥", + "mnemonicPhrase": "助记词", + "separatorManualMethodsSolution": " 或者 ", + "confirmManuallyWritten": "我已经将我的助记词写下来了", + "warningMessage": "**千万别弄丢了!** 如果您弄丢了将无法恢复您的钱包I。
**不要跟任何人分享!** 如果您在可疑电脑或者钓鱼网站上使用这个文件或者助记词,那么您钱包里的资产将很可能会被盗走。
**做好备份!** 将它看做未来的某一天将会价值百万那样备份好,保护好。
", + "finishButton": "我确认知悉,点击继续。" + } + }, + "disclaimerBlock": { + "title": "Qwertycoin钱包安全风险须知", + "content": "Qwertycoin钱包是一个基于Web的界面. 它能帮助你在无须运行一个完整的QwertyCoin节点就可以使用QwertyCoin。
我们建议像对待您真实的钱包那样对待Qwertycoin钱包。" + } + }, + "donatePage": { + "title": "捐助", + "subtitle": "帮助资助开发并支付账单", + "webwalletBlock": { + "title": "Webwallet", + "content": "如果您愿意帮助支付服务器费用,用来支持开发新的功能,或者您喜欢这个应用,那么可以考虑捐助我们:

" + }, + "devFundBlock": { + "title": "Qwertycoin开发者基金", + "content": "想捐助Qwertycoin, 您可以捐助到如下这些地址" + } + }, + "supportPage": { + "title": "支持", + "subtitle": "我们在这里提供帮助!", + "getInTouchBlock": { + "title": "让我们联系吧!", + "content": "您若有能帮助我们改善钱包哦的建议或者想法,欢迎联系我们!", + "discord": "Qwertycoin Discord频道" + } + }, + "networkPage": { + "title": "网络统计", + "subtitle": "Qwertycoin网络详情", + "statsBlock": { + "connectNode": "连接的Masternode", + "hashrate": "网络哈希值", + "height": "区块高度", + "difficulty": "网络难度", + "lastTimeBlock": "最新出块", + "lastReward": "最新出块奖励" + } + }, + "sendPage": { + "title": "发送QWC", + "sendBlock": { + "address": { + "label": "目标地址", + "placeholder": "写下您要汇款目标地址", + "invalid": "非法的目标地址", + "fundsTo": "资金将被发送到", + "receiver": "接收者", + "description": "描述" + }, + "amount": { + "label": "发送金额", + "invalid": "金额无效" + }, + "paymentId": { + "label": "付款ID(可选)", + "invalid": "非法的付款ID. 长度必须是64位。" + }, + "sendButton": "发送", + "cancelButton": "取消" + }, + "qrCodeScanning": { + "explication": "展示二维码" + }, + "notEnoughMoneyModal": { + "title": "糟糕!", + "content": "您没有足够的资金,转账无法完成。", + "confirmText": "确认" + }, + "thankYouDonationModal": { + "title": "感谢您的捐赠!", + "content": "感谢您的帮助。您的捐助将会使Qwertycoin变得更好。", + "confirmText": "确认" + }, + "transferSentModal": { + "title": "转移成功!", + "confirmText": "确认" + }, + "transferExceptionModal": { + "title": "糟糕!", + "content": "发生错误,请上报此错误: {details}", + "confirmText": "确认" + }, + "invalidAmountModal": { + "title": "糟糕!", + "content": "不合法的数量", + "confirmText": "确认" + }, + "creatingTransferModal": { + "title": "转账创建中......", + "content": "请耐心等待..." + }, + "finalizingTransferModal": { + "title": "转账完成......", + "content": "请耐心等待..." + }, + "confirmTransactionModal": { + "title": "确认转账?", + "content": "数量: {amount}
交易费: {fees}
总额: {total}", + "confirmText": "确认", + "cancelText": "取消" + }, + "waitingNfcModal": { + "title": "等待Nfc", + "content": "靠近其他设备一些" + } + }, + "receivePage": { + "title": "收到QWC", + "receiveBlock": { + "address": { + "title": "您收到资金的地址:", + "label": "给这个地址接收资金" + }, + "qrCode": { + "title": "或者个性化二维码:", + "labelAmount": "金额(可选)", + "labelRecipient": "收据名称 (可选)", + "labelDescription": "交易描述 (可选)", + "updateButton": "更新" + } + }, + "qrBlock": { + "title": "您的自定义二维码" + }, + "waitingNfcToWriteModal": { + "title": "等待 Nfc", + "titleSuccess": "Nfc标签识别成功", + "content": "请靠近NFC标签来识别" + }, + "nfcErrorModal": { + "titleInsufficientCapacity": "标签剩余不足" + } + }, + "miningPage": { + "title": "直接在浏览器中挖矿", + "subtitle": "通过挖矿为网络做贡献,并得到QWC奖励", + "parameterBlock": { + "title": "参数", + "labelDestinationAddress": "挖矿的钱包", + "labelThreads": "线程数 (more=更高的算力)", + "start": "开始", + "stop": "停止" + }, + "statisticsBlocks": { + "title": "统计数据", + "validShares": "有效份额", + "hashrate": "算力", + "maxHashrate": "最大算力", + "dedicatedHardware": "使用算力贡献的挖矿硬件和挖矿软件,你可以获得更多奖励,帮助去中心化的网络。", + "miningHandledBy": "本次挖矿由矿池pool.qwertycoin.org处理" + } + }, + "settingsPage": { + "title": "设置", + "subtitle": "在这里更改您的参数", + "versionBlock": { + "versionNumber": "版本号:", + "versionCode": "版本代码:" + }, + "settingsBlock": { + "speed": { + "label": "更新钱包的速度(将会消耗更多资源)", + "fastest": "最快", + "fast": "快", + "medium": "中等", + "slow": "慢" + }, + "language": { + "label": "语言" + }, + "currency": { + "label": "本国货币" + }, + "readMinerTx": { + "label": "读取挖矿交易信息(仅适用于Solo挖矿)" + }, + "customNode": { + "label": "Use custom node" + }, + "nodeUrl": { + "label": "Node URL" + }, + "chooseNode": "Choose your node:" + }, + "changePasswordButton": "更改我的钱包密码", + "deleteWalletButton": "删除我的钱包(本地副本)", + "walletSettings": { + "creationHeight": { + "label": "钱包创建的区块高度" + }, + "currentScanningHeight": { + "label": "当前扫描高度" + }, + "updateButton": "更新" + }, + "deleteWalletModal": { + "title": "删除我的钱包(本地副本)", + "content": "确定要删除您的钱包吗?", + "confirmText": "是的,我确定", + "cancelText": "取消" + } + }, + "importBasePage": { + "parametersBlock": { + "title": "参数", + "password": { + "label": "保护您的钱包的密码" + }, + "passwordConfirm": { + "label": "确认密码", + "invalid": "2次密码不匹配" + }, + "importHeight": { + "label": "从该区块高度开始导入:" + } + } + }, + "importFromQrPage": { + "title": "从二维码导入钱包", + "subtitle": "从线下备份导入钱包", + "qrCodeBlock": { + "title": "二维码", + "startScanButton": "开始扫描", + "importButton": "导入" + }, + "qrScanningBlock": { + "title": "展示二维码" + } + }, + "exportPage": { + "title": "备份您的证书", + "publicAddressBlock": { + "title": "您的公开地址" + }, + "pdfBlock": { + "title": "PDF备份", + "downloadButton": "下载" + }, + "warningBlock": { + "title": "警告", + "content": "如果您选择保存您的私钥和助记词,为了您的资金安全,请务必不要将它们明文存储在任何地方。
这些文件是您的私钥,包含您的之后用来钱包同步所需的所有交易信息内容。The file is an alternate solution where your keys are encrypted。" + }, + "exportBlock": { + "title": "导出证书", + "privateKeysButton": "获取我的私钥", + "mnemonicKeysButton": "获取我的助记词", + "fileButton": "导出到一个文件" + }, + "walletKeysModal": { + "title": "私钥", + "confirmText": "确认", + "content": "请妥善保存好您的私钥。保存好私钥就等于保存好了它所关联的账户资金 !
Spend key: {privSpendKey}
Private view key: {privViewKey}" + }, + "mnemonicKeyModal": { + "title": "助记词", + "confirmText": "确认", + "content": "请妥善保存好您的助记词。保存好助记词就等于保存好了它所关联的账户资金 ! 您的助记词是:
{mnemonic}" + }, + "mnemonicLangSelectionModal": { + "title": "你想用哪种语言写你的助记词?", + "confirmText": "导出" + } + }, + "importPage": { + "title": "创建一个钱包", + "subtitle": "从以前创建过的密钥,文件或助记词", + "chooseMethod": "选择导入方法:", + "fromKeys": "从秘钥", + "fromFile": "从文件", + "fromMnemonic": "从助记词", + "fromQr": "从二维码" + }, + "termsOfUsePage": { + "title": "使用条款", + "subtitle": "请仔细阅读。" + }, + "privacyPolicyPage": { + "title": "隐私政策", + "subtitle": "请仔细阅读。" + }, + "importFromFilePage": { + "title": "从备份文件导入钱包", + "subtitle": "使用备份文件创建钱包", + "walletBlock": { + "title": "钱包文件", + "label": "选择文件", + "importButton": "导入" + } + }, + "importFromMnemonicPage": { + "title": "从助记词导入钱包", + "subtitle": "使用您的助记词来创建钱包", + "mnemonicBlock": { + "title": "助记词", + "mnemonic": { + "label": "助记词:25个字", + "invalid": "助记词无效", + "language": "语言" + }, + "importButton": "导入" + } + }, + "importFromKeysPage": { + "title": "从秘钥导入钱包", + "subtitle": "使用您的密钥创建钱包", + "parametersBlock": { + "viewOnlyWallet": { + "label": "你想要一个只允许查看的钱包吗?" + } + }, + "keysBlock": { + "titleNotViewOnly": "钱包钥匙", + "titleViewOnly": "仅查看钱包", + "privateSpend": { + "label": "私人消费钥匙" + }, + "privateView": { + "label": "私人视图密钥", + "optional": "(可选的)" + }, + "publicKey": { + "label": "公钥" + }, + "importButton": "导入" + } + } + }, + "number": {}, + "date": { + "short": { + "year": "numeric", + "month": "short", + "day": "numeric" + }, + "long": { + "year": "numeric", + "month": "short", + "day": "numeric", + "weekday": "short", + "hour": "numeric", + "minute": "numeric", + "hour12": true + } + } +} diff --git a/src/workers/TransferProcessing.ts b/src/workers/TransferProcessing.ts index dc90f8f2..e4fb24a8 100644 --- a/src/workers/TransferProcessing.ts +++ b/src/workers/TransferProcessing.ts @@ -2,53 +2,77 @@ import {TransactionsExplorer} from "../model/TransactionsExplorer"; import {Wallet, WalletOptions} from "../model/Wallet"; import {Mnemonic} from "../model/Mnemonic"; import {Transaction} from "../model/Transaction"; +import {Constants} from "../model/Constants"; +import {RawDaemon_Transaction} from "../model/blockchain/BlockchainExplorer"; //bridge for cnUtil with the new mnemonic class (self).mn_random = Mnemonic.mn_random; (self).mn_decode = Mnemonic.mn_decode; (self).mn_encode = Mnemonic.mn_encode; -let currentWallet : Wallet|null = null; +let currentWallet: Wallet | null = null; -onmessage = function(data : MessageEvent){ +onmessage = function (data: MessageEvent) { // if(data.isTrusted){ - let event : any = data.data; - if(event.type === 'initWallet'){ + let event: any = data.data; + if (event.type === 'initWallet') { + currentWallet = Wallet.loadFromRaw(event.wallet); + postMessage('readyWallet'); + } else if (event.type === 'process') { + if (typeof event.wallet !== 'undefined') { currentWallet = Wallet.loadFromRaw(event.wallet); - postMessage('readyWallet'); - }else if (event.type === 'process'){ - if(typeof event.wallet !== 'undefined'){ - currentWallet = Wallet.loadFromRaw(event.wallet); - } + } + + if (currentWallet === null) { + postMessage('missing_wallet'); + return; + } + + let readMinersTx = typeof currentWallet.options.checkMinerTx !== 'undefined' && currentWallet.options.checkMinerTx; + + let rawTransactions: RawDaemon_Transaction[] = event.transactions; + let transactions: any[] = []; - if(currentWallet === null){ - postMessage('missing_wallet'); - return; + for (let rawTransaction of rawTransactions) { + if (!readMinersTx && TransactionsExplorer.isMinerTx(rawTransaction)) { + continue; } - let rawTransactions : RawDaemonTransaction[] = event.transactions; - let transactions: any[] = []; - - for(let rawTransaction of rawTransactions){ - let transaction = TransactionsExplorer.parse(rawTransaction, currentWallet); - if(transaction !== null){ - currentWallet.addNew(transaction); - //if (transaction.getAmount() !== 0) //fusion - //{ - transactions.push(transaction.export()); - //} + let transaction = TransactionsExplorer.parse(rawTransaction, currentWallet); + if (Constants.DEBUG_STATE) { + if (transaction !== null) { + console.log(`parsed tx ${transaction['hash']} from rawTransaction`); } } + if (transaction !== null) { + currentWallet.addNew(transaction); + if (Constants.DEBUG_STATE) { + console.log(`Added tx ${transaction.hash} to currentWallet`); + } - postMessage({ - type:'processed', - transactions:transactions - }); + transactions.push(transaction.export()); + if (Constants.DEBUG_STATE) { + console.log(`pushed tx ${transaction.hash} to transactions[]`); + } + } } - // let transaction = TransactionsExplorer.parse(rawTransaction, height, this.wallet); + postMessage({ + type: 'processed', + transactions: transactions + }); + } + // let transaction = TransactionsExplorer.parse(rawTransaction, height, this.wallet); // }else { // console.warn('Non trusted data', data.data, JSON.stringify(data.data)); // } + + if (Constants.DEBUG_STATE) { + // @ts-ignore + let tempAll = currentWallet.getAll() + if (tempAll.length > 0) { + console.log(tempAll); + } + } }; -postMessage('ready'); \ No newline at end of file +postMessage('ready'); diff --git a/src/workers/TransferProcessingEntrypoint.ts b/src/workers/TransferProcessingEntrypoint.ts index 83ac1a30..02e4810e 100644 --- a/src/workers/TransferProcessingEntrypoint.ts +++ b/src/workers/TransferProcessingEntrypoint.ts @@ -7,9 +7,7 @@ importScripts('../lib/require.js'); importScripts('../lib/biginteger.js'); importScripts('../config.js'); importScripts('../lib/base58.js'); -importScripts('../lib/cn_utils.js'); importScripts('../lib/crypto.js'); -// importScripts('../lib/mnemonic.js'); importScripts('../lib/nacl-fast.js'); importScripts('../lib/nacl-util.min.js'); importScripts('../lib/sha3.js'); diff --git a/src_api/blockchain.php b/src_api/blockchain.php deleted file mode 100644 index 3b3b898e..00000000 --- a/src_api/blockchain.php +++ /dev/null @@ -1,364 +0,0 @@ -$txHashes, - 'decode_as_json'=>true - )); - curl_setopt_array($curl, array(CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => 'http://'.$daemonAddress.':'.$rpcPort.'/gettransactions', CURLOPT_POST => 1, CURLOPT_POSTFIELDS => $body)); - - $resp = curl_exec($curl); - curl_close($curl); - $array = json_decode($resp, true); - - return $array; -} - -function getBlockchainHeight(){ - global $rpcPort; - global $daemonAddress; - $curl = curl_init(); - - curl_setopt_array($curl, array(CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => 'http://'.$daemonAddress.':'.$rpcPort.'/getheight', CURLOPT_POST => 1, CURLOPT_POSTFIELDS => '')); - - $resp = curl_exec($curl); - curl_close($curl); - $array = json_decode($resp, true); - return $array['height']; -} - - -$outCount = 0;//to start at 0 - -function createOptimizedBock($startHeight, $endHeight){ - global $outCount; - global $rpcPort; - global $daemonAddress; - $txHashesPerBlock = array(); - $txHashes = array(); - $txHashesMap = array(); - $txOutCountMap = array(); - - $finalTransactions = array(); - $curl = curl_init(); - - $minerTxs = []; - - $blockTimes = array(); - - for($height = $startHeight; $height <= $endHeight; ++$height){ - //get the block hash - $body = json_encode(array("jsonrpc" => "2.0", "id" => "0", "method" => "on_getblockhash", "params" => array($height))); - curl_setopt_array($curl, array(CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => 'http://'.$daemonAddress.':'.$rpcPort.'/json_rpc', CURLOPT_POST => 1, CURLOPT_POSTFIELDS => $body)); - $resp = curl_exec($curl); - $array = json_decode($resp, true); - $hash = $array["result"]; - //get the block details - $body = json_encode(array("jsonrpc" => "2.0", "id" => "0", "method" => "f_block_json", "params" => array("hash" => $hash))); - curl_setopt_array($curl, array(CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => 'http://'.$daemonAddress.':'.$rpcPort.'/json_rpc', CURLOPT_POST => 1, CURLOPT_POSTFIELDS => $body)); - $resp = curl_exec($curl); - $array = json_decode($resp, true); - $blockJson = $array["result"]["block"]; - - // var_dump($array); - //$blockJson = json_decode($array['result']['json'], true); - /* - $minerTx = $blockJson['transactions'][0]; - $minerTx['height'] = $height; - $minerTx['vin'] = []; - $minerTxs[] = $minerTx; - */ - $blockTxHashes = array(); - $blockTimes[$height] = $blockJson['timestamp']; - $txs = $blockJson['transactions']; - foreach($txs as $tx){ - $blockTxHashes[] = $tx["hash"]; - //$tx["block_timestamp"] = $blockJson['timestamp']; - } - $txHashesPerBlock[$height] = $blockTxHashes; - - foreach($blockTxHashes as $txHash){ - $txHashesMap[$txHash] = $height; - $txHashes[] = $txHash; - $txOutCountMap[$txHash] = $outCount; - } - - } - - - for($height = $startHeight; $height <= $endHeight; ++$height){ - /*foreach($minerTxs as $minerTx){ - if($minerTx['height'] === $height){ - $minerTx['global_index_start'] = $outCount; - $minerTx['ts'] = $blockTimes[$height]; - $finalTransactions[] = $minerTx; - ++$outCount; - break; - } - } - */ - $body = json_encode(array( - 'transactionHashes'=>$txHashesPerBlock[$height] - )); - - curl_setopt_array($curl, array(CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => 'http://'.$daemonAddress.':'.$rpcPort.'/get_transaction_details_by_hashes', CURLOPT_POST => 1, CURLOPT_POSTFIELDS => $body)); - - $resp = curl_exec($curl); - - $decodedJson = json_decode($resp, true); - - if(!isset($decodedJson['transactions'])){ - $rawTransactions = []; - }else{ - $rawTransactions = $decodedJson['transactions']; - } - -// var_dump($decodedJson['txs']); -// var_dump($rawTransactions); - - for($iTransaction = 0; $iTransaction < count($rawTransactions); ++$iTransaction){ - //$rawTransactionJson = $rawTransactionsJson[$iTransaction]; - $rawTransaction = $rawTransactions[$iTransaction]; - // var_dump($txHashesMap[$txHashes[$iTransaction]].'<=>'.$height.'=>'.count($rawTransactions)); -// if($txHashesMap[$txHashes[$iTransaction]] === $height){ - // ++$outCount; - $finalTransaction = $rawTransaction; - unset($finalTransaction['signatures']); - unset($finalTransaction['ts']); - unset($finalTransaction['unlockTime']); - unset($finalTransaction['signaturesSize']); - $finalTransaction['global_index_start'] = $outCount; - $finalTransaction['ts'] = $blockJson['timestamp']; //$rawTransaction['block_timestamp']; - $finalTransaction['height'] = $height; - $finalTransaction['hash'] = $rawTransaction['hash']; - // var_dump('-->'.$txHashesMap[$txHashes[$iTransaction]]); - $finalTransactions[] = $finalTransaction; - - - $voutCount = count($finalTransaction['outputs']); - //var_dump('vout of ' . $voutCount . ' at height ' . $finalTransaction["height"]); - $outCount += $voutCount; -// } - } - // var_dump($outCount); - } - - curl_close($curl); - - // return array_merge($finalTransactions,$minerTxs); - return $finalTransactions; -} - -/* -function createOptimizedBock2($startHeight, $endHeight){ - global $rpcPort; - global $outCount; - $txHashesPerBlock = array(); - $txHashes = array(); - $txHashesMap = array(); - - $finalTransactions = array(); - - for($height = $startHeight; $height < $endHeight; ++$height){ - $body = json_encode(array("jsonrpc" => "2.0", "id" => "0", "method" => "getblock", "params" => array("height" => $height))); - - $curl = curl_init(); - - curl_setopt_array($curl, array(CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => 'http://'.$daemonAddress.':'.$rpcPort.'/json_rpc', CURLOPT_POST => 1, CURLOPT_POSTFIELDS => $body)); - - $resp = curl_exec($curl); - curl_close($curl); - $array = json_decode($resp, true); - - // var_dump($array); - $blockJson = json_decode($array['result']['json'], true); - $blockTxHashes = ($blockJson['tx_hashes']); - - $txHashesPerBlock[$height] = $blockTxHashes; - foreach($blockTxHashes as $txHash){ - $txHashesMap[$txHash] = $height; - $txHashes[] = $txHash; - } - - ++$outCount;//minx tx - - if(count($txHashesPerBlock[$height]) > 0){ - $rawTransactions = getTxWithHashes($txHashesPerBlock[$height])['txs_as_json']; - $iTransaction = 0; - foreach($rawTransactions as $rawTransaction){ - ++$outCount; - $finalTransaction = json_decode($rawTransaction, true); - unset($finalTransaction['rctsig_prunable']); - $finalTransaction['height'] = $txHashesPerBlock[$height]; - $finalTransaction['global_index_start'] = $outCount; - $finalTransactions[] = $finalTransaction; - ++$iTransaction; - $outCount+=count($finalTransaction['vout'])-1; - } - } - } - - return $finalTransactions; -} -*/ - -function retrieveCache($startHeight, $endHeight, $decoded=true){ - global $cacheLocation; - $content = @file_get_contents($cacheLocation.'/'.$startHeight.'-'.$endHeight); - if($content === false) - return null; - if($decoded) - $content = json_decode($content, true); - return $content; -} - -function saveCache($startHeight, $endHeight, $content){ - global $cacheLocation; - file_put_contents($cacheLocation.'/'.$startHeight.'-'.$endHeight, json_encode($content)); -} - -if(getenv('generate') !== 'true'){ - if(!is_int($_GET['height']+0)){ - http_response_code(400); - exit; - } - $startHeight = (int)$_GET['height']; - $realStartHeight = $startHeight; - $startHeight = floor($startHeight/100)*100; - $endHeight = $startHeight + 100; - if($startHeight < 0) $startHeight = 0; - - $blockchainHeight = getBlockchainHeight(); - if($blockchainHeight === null) $blockchainHeight = $endHeight+100; - if($endHeight > $blockchainHeight){ - $endHeight = $blockchainHeight; - } - - // var_dump($startHeight, $endHeight); - // exit; - $cacheContent = retrieveCache($startHeight, $endHeight, false); - if($cacheContent === null){ - http_response_code(400); - }else{ - $cacheContent = json_decode($cacheContent, true); - $txForUser = []; - foreach($cacheContent as $tx){ - if($tx['height'] >= $realStartHeight){ - $txForUser[] = $tx; - } - } - - header('Content-Type: application/json'); - echo json_encode($txForUser); - } -}else{ - $lastRunStored = @file_get_contents('./lastRun.txt'); - if($lastRunStored===false) - $lastRunStored = 0; - else - $lastRunStored = (int)$lastRunStored; - - if($lastRunStored+1/**60*/ >= time())//concurrent run, 1min lock - exit; - file_put_contents('./lastRun.txt', time()); - - $lastScanHeight = 0; - $timeStart = time(); - $lastOutCount = 0; - while(time() - $timeStart < 59*60){ - $blockchainHeight = getBlockchainHeight(); - $lastBlockCacheContent = null; - for($startHeight = $lastScanHeight; $startHeight <= $blockchainHeight; $startHeight += 100){ - - $endHeight = $startHeight + 100; - $realStartHeight = $startHeight; - // if($realStartHeight < 1) $realStartHeight = 1; - if($endHeight > $blockchainHeight){ - $endHeight = $blockchainHeight; - } - - echo 'scanning ' . $startHeight . ' to ' . $endHeight . "
"; - - $cacheContent = retrieveCache($realStartHeight, $endHeight, false); - // var_dump('==>',$lastBlockCacheContent,$cacheContent); - if($cacheContent === null){ - if($realStartHeight > 1){ - $lastBlockCacheContent = retrieveCache($realStartHeight-100, $realStartHeight, false); - $decodedContent = json_decode($lastBlockCacheContent, true); - if(count($decodedContent) > 0){ - $lastTr = $decodedContent[count($decodedContent) - 1]; - $outCount = $lastTr['global_index_start'] + count($lastTr['outputs']); - //var_dump('out count='.$outCount.' '.$lastTr['global_index_start'].' '.count($lastTr['outputs'])); - }else{ - var_dump('Missing compacted block file. Weird case'); - exit; - } - $lastBlockCacheContent = null; - } - - //var_dump("generating..."); - $cacheContent = createOptimizedBock($realStartHeight, $endHeight); - saveCache($realStartHeight, $endHeight, $cacheContent); - $cacheContent = json_encode($cacheContent); - }else{ -// if($cacheContent !== '[]' && $cacheContent !== null){ -// $lastBlockCacheContent = $cacheContent; -// } - } - - var_dump($outCount); - } - - $lastOutCount = $outCount; - - //var_dump('cleaning ...'); - - $allBlocksFiles = scandir($cacheLocation); - foreach($allBlocksFiles as $filename){ - if($filename !== '.' && $filename !== '..'){ - $blocksNumbers = explode('-', $filename); - if(count($blocksNumbers) === 2 && $blocksNumbers[1] % 100 !== 0){ - if($blocksNumbers[1]+1 < $blockchainHeight){//to be sure if other client are using the last one - unlink($cacheLocation . '/' . $filename); - } - } - } - } - - $lastScanHeight = floor($blockchainHeight/100)*100; - - file_put_contents('./lastRun.txt', time()); - sleep(10); - } -} - -//$finalTransactions = createOptimizedBock($startHeight, $endHeight); -//ini_set('zlib.output_compression_level', 1); -//if (extension_loaded('zlib') && !ini_get('zlib.output_compression')){ -// header('Content-Encoding: gzip'); -// ob_start('ob_gzhandler'); -//} -//ob_start("ob_gzhandler"); -//$data = gzcompress($cacheContent,9); - -//ob_end_clean(); -//echo strlen($data); -//echo '|'; -//echo strlen($cacheContent); -//ob_end_flush(); \ No newline at end of file diff --git a/src_api/config.php b/src_api/config.php deleted file mode 100644 index b4435786..00000000 --- a/src_api/config.php +++ /dev/null @@ -1,7 +0,0 @@ - "2.0", "id" => "0", "method" => "f_on_transactions_pool_json", "params" => '')); -curl_setopt_array($curl, array(CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => 'http://'.$daemonAddress.':'.$rpcPort.'/json_rpc', CURLOPT_POST => 1, CURLOPT_POSTFIELDS => $body)); -$resp = curl_exec($curl); - -//now get the Tx details -$jsonMempool = json_decode($resp, true); -$rawTransactions = $jsonMempool["result"]["transactions"]; -$txHashes = array(); -for($iTransaction = 0; $iTransaction < count($rawTransactions); ++$iTransaction){ - $txHashes[] = $rawTransactions[$iTransaction]["hash"]; -} - -$body = json_encode(array( - 'transactionHashes'=>$txHashes -)); -curl_setopt_array($curl, array(CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => 'http://'.$daemonAddress.':'.$rpcPort.'/get_transaction_details_by_hashes', CURLOPT_POST => 1, CURLOPT_POSTFIELDS => $body)); -$resp = curl_exec($curl); -$decodedJson = json_decode($resp, true); -curl_close($curl); - -/* -$blobString1 = '"tx_blob": "'; -$blobString2 = '"tx_blob":"'; -$posTxBlob = 0; -$searchTxBlock1 = 0; -$searchTxBlock2 = 0; -while(($searchTxBlock1 = strpos($resp,$blobString1)) !== false || ($searchTxBlock2 = strpos($resp,$blobString2)) !== false ){ -// var_dump($searchTxBlock1.' '.$searchTxBlock2); - if($searchTxBlock1 !== false){ - $posTxBlob = $searchTxBlock1; - $posEndTxBlock = $posTxBlob + strlen($blobString1); - } - else if($searchTxBlock2 !== false){ - $posTxBlob = $searchTxBlock2; - $posEndTxBlock = $posTxBlob + strlen($blobString2); - } - - $i = 0; - do{ - ++$posEndTxBlock; - $posEndTxBlock = strpos($resp, '"', $posEndTxBlock); - ++$i; - }while($posEndTxBlock !== false && $resp[$posEndTxBlock-1] === '\\'); - - $resp = substr($resp, 0, $posTxBlob).substr($resp, $posEndTxBlock+2); -} - -$jsonMempool = json_decode($resp, true); -if(isset($jsonMempool["result"]['transactions'])){ -// var_dump('isset'); - foreach($jsonMempool['transactions'] as $key=>$tx){ - unset($tx['tx_blob']); - $tx['tx_json'] = json_decode($tx['tx_json']); - $jsonMempool['transactions'][$key] = $tx; - } -} -*/ -$jsonMempool = json_decode($resp, true); -header('Content-Type: application/json'); -echo json_encode($jsonMempool['transactions']); - diff --git a/src_api/getheight.php b/src_api/getheight.php deleted file mode 100644 index d344fd31..00000000 --- a/src_api/getheight.php +++ /dev/null @@ -1,31 +0,0 @@ - 1, CURLOPT_URL => 'http://'.$daemonAddress.':'.$rpcPort.'/getheight')); -$resp = curl_exec($curl); -curl_close($curl); -//var_dump($resp); -$array = json_decode($resp, true); -//var_dump($array); -if($array === null) - http_response_code(400); -else - echo $array['height']; \ No newline at end of file diff --git a/src_api/network.php b/src_api/network.php deleted file mode 100644 index a7eb5ed9..00000000 --- a/src_api/network.php +++ /dev/null @@ -1,46 +0,0 @@ - "2.0", "id" => "0", "method" => "getlastblockheader")); -curl_setopt_array($curl, array(CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => 'http://'.$daemonAddress.':'.$rpcPort.'/json_rpc', CURLOPT_POST => 1, CURLOPT_POSTFIELDS => $body)); - -$resp = curl_exec($curl); -curl_close($curl); -//var_dump($resp); -$array = json_decode($resp, true); -//var_dump($array); -if($array === null) - http_response_code(400); -else{ - $blockHeader = $array['result']['block_header']; - header('Content-Type: application/json'); - echo json_encode(array( - 'major_version'=>$blockHeader['major_version'], - 'hash'=>$blockHeader['hash'], - 'reward'=>$blockHeader['reward'], - 'height'=>$blockHeader['height'], - 'timestamp'=>$blockHeader['timestamp'], - 'difficulty'=>$blockHeader['difficulty'], - 'hashrate'=>$blockHeader['difficulty']*60*2, - )); -} - - - diff --git a/src_api/openAlias.php b/src_api/openAlias.php deleted file mode 100644 index bf9a831b..00000000 --- a/src_api/openAlias.php +++ /dev/null @@ -1,60 +0,0 @@ -= 1){ - if(trim($subparts[0]) === 'recipient_address'){ - $recipient_address = trim($subparts[1]); - }else if(trim($subparts[0]) === 'recipient_name'){ - $recipient_name = trim($subparts[1]); - } - } - } - } - } - } - -} -if($recipient_address !== null){ - header('Content-Type: application/json'); - echo json_encode(array( - 'address'=>$recipient_address, - 'name'=>$recipient_name, - )); -}else{ - http_response_code(404); -} \ No newline at end of file diff --git a/src_api/sendrawtransaction.php b/src_api/sendrawtransaction.php deleted file mode 100644 index 4cdaa1fd..00000000 --- a/src_api/sendrawtransaction.php +++ /dev/null @@ -1,29 +0,0 @@ - 1, CURLOPT_URL => 'http://'.$daemonAddress.':'.$rpcPort.'/sendrawtransaction', CURLOPT_POST => 1, CURLOPT_POSTFIELDS => $body)); - -$resp = curl_exec($curl); -curl_close($curl); - -header('Content-Type: application/json'); -echo $resp; \ No newline at end of file diff --git a/src_client_api/api.js b/src_client_api/api.js deleted file mode 100644 index 24883352..00000000 --- a/src_client_api/api.js +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2018, Gnock - * Copyright (c) 2018, The Masari Project - * - * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -var MasariApi = new function(){ - - this.ready = false; - this.apiDomain = 'http://localhost:38090'; - this.timeoutErrorTime = 10000; - this.timeoutError = 10000; - - var self = this; - - this.promisesResolves = {}; - this.promisesReject = {}; - - this.iframe = null; - this.popupParameters = undefined; - // this.popupParameters = "menubar=no, status=no, scrollbars=no, menubar=no, width=200, height=100"; - - this.registerPromise = function(eventName, resolve, reject){ - this.promisesReject[eventName] = reject; - this.promisesResolves[eventName] = resolve; - }; - - this.unregisterPromise = function(eventName){ - if(typeof this.promisesReject[eventName] !== 'undefined') delete this.promisesReject[eventName]; - if(typeof this.promisesResolves[eventName] !== 'undefined') delete this.promisesResolves[eventName]; - }; - - this.init = function(){ - window.addEventListener('message', function(e){ - if(e.origin === self.apiDomain){ - console.log(e); - var eventType = e.data.type; - var eventData = e.data.payload; - console.log('event type:',eventType); - // if(eventType === 'ready'){ - self.promisesResolves[eventType](eventData); - self.unregisterPromise(eventType); - // } - } - }); - - return new Promise(function(resolve, reject){ - self.registerPromise('ready', resolve, reject); - var ifrm = document.createElement("iframe"); - ifrm.setAttribute("src", self.apiDomain+"/api.html"); - ifrm.style.width = "0"; - ifrm.style.height = "0"; - ifrm.style.display = 'none'; - - self.timeoutError = setTimeout(function(){ - self.promisesReject['ready'](eventData); - self.unregisterPromise('ready'); - },self.timeoutErrorTime); - - ifrm.addEventListener('load', function(){ - clearTimeout(self.timeoutError); - self.timeoutError = 0; - }); - - self.iframe = ifrm; - document.body.appendChild(ifrm); - }); - }; - - this.hasWallet = function(){ - return new Promise(function(resolve, reject){ - self.registerPromise('hasWallet', resolve, reject); - self.iframe.contentWindow.postMessage('hasWallet', '*'); - }); - }; - - this.makeTransfer = function(options){ - var url = this.apiDomain+'/#!send?'; - if(typeof options.amount !== 'undefined')url += 'amount='+options.amount+'&'; - if(typeof options.address !== 'undefined')url += 'address='+options.address+'&'; - if(typeof options.description !== 'undefined')url += 'txDesc='+options.description+'&'; - if(typeof options.destName !== 'undefined')url += 'destName='+options.destName+'&'; - - window.open(url,"Masari",this.popupParameters); - - return Promise.resolve(); - }; - -}; \ No newline at end of file diff --git a/src_client_api/index.html b/src_client_api/index.html deleted file mode 100644 index b5e28744..00000000 --- a/src_client_api/index.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - Title - - - - - - - - - - - - \ No newline at end of file diff --git a/src_native/Makefile b/src_native/Makefile deleted file mode 100644 index 53850723..00000000 --- a/src_native/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -TARGET = prog -LIBS = -lm -CC = em++ -O3 -s SINGLE_FILE=1 -s NO_FILESYSTEM=1 -s 'EXTRA_EXPORTED_RUNTIME_METHODS=["ccall", "cwrap"]' --llvm-lto 1 -s TOTAL_MEMORY=67108864 -s WASM=1 -s "BINARYEN_TRAP_MODE='allow'" -s EXPORTED_FUNCTIONS="['_generate_key_derivation', '_derive_public_key']" -s ASSERTIONS=1 --shell-file html_template/shell_minimal.html -CFLAGS = -Wall -msse2 - - -# SINGLE_FILE=1 - -# -s ASSERTIONS=1 -# -s SINGLE_FILE=1 -.PHONY: default all clean - -default: $(TARGET) -all: default - -OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c)) -HEADERS = $(wildcard *.h) - -%.o: %.c $(HEADERS) $(CC) $(CFLAGS) -c $< -o $@ - -.PRECIOUS: $(TARGET) $(OBJECTS) - -$(TARGET): $(OBJECTS) - $(CC) $(OBJECTS) -Wall $(LIBS) -o cn.html - -clean: - -rm -f *.o - -rm -f $(TARGET) diff --git a/src_native/base64.h b/src_native/base64.h deleted file mode 100644 index e1362bde..00000000 --- a/src_native/base64.h +++ /dev/null @@ -1,258 +0,0 @@ -// https://github.com/tkislan/base64 - -#ifndef BASE64_H -#define BASE64_H - -#include - -const char kBase64Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - -class Base64 { - public: - static bool Encode(const std::string &in, std::string *out) { - int i = 0, j = 0; - size_t enc_len = 0; - unsigned char a3[3]; - unsigned char a4[4]; - - out->resize(EncodedLength(in)); - - int input_len = in.size(); - std::string::const_iterator input = in.begin(); - - while (input_len--) { - a3[i++] = *(input++); - if (i == 3) { - a3_to_a4(a4, a3); - - for (i = 0; i < 4; i++) { - (*out)[enc_len++] = kBase64Alphabet[a4[i]]; - } - - i = 0; - } - } - - if (i) { - for (j = i; j < 3; j++) { - a3[j] = '\0'; - } - - a3_to_a4(a4, a3); - - for (j = 0; j < i + 1; j++) { - (*out)[enc_len++] = kBase64Alphabet[a4[j]]; - } - - while ((i++ < 3)) { - (*out)[enc_len++] = '='; - } - } - - return (enc_len == out->size()); - } - - static bool Encode(const char *input, size_t input_length, char *out, size_t out_length) { - int i = 0, j = 0; - char *out_begin = out; - unsigned char a3[3]; - unsigned char a4[4]; - - size_t encoded_length = EncodedLength(input_length); - - if (out_length < encoded_length) return false; - - while (input_length--) { - a3[i++] = *input++; - if (i == 3) { - a3_to_a4(a4, a3); - - for (i = 0; i < 4; i++) { - *out++ = kBase64Alphabet[a4[i]]; - } - - i = 0; - } - } - - if (i) { - for (j = i; j < 3; j++) { - a3[j] = '\0'; - } - - a3_to_a4(a4, a3); - - for (j = 0; j < i + 1; j++) { - *out++ = kBase64Alphabet[a4[j]]; - } - - while ((i++ < 3)) { - *out++ = '='; - } - } - - return (out == (out_begin + encoded_length)); - } - - static bool Decode(const std::string &in, std::string *out) { - int i = 0, j = 0; - size_t dec_len = 0; - unsigned char a3[3]; - unsigned char a4[4]; - - int input_len = in.size(); - std::string::const_iterator input = in.begin(); - - out->resize(DecodedLength(in)); - - while (input_len--) { - if (*input == '=') { - break; - } - - a4[i++] = *(input++); - if (i == 4) { - for (i = 0; i <4; i++) { - a4[i] = b64_lookup(a4[i]); - } - - a4_to_a3(a3,a4); - - for (i = 0; i < 3; i++) { - (*out)[dec_len++] = a3[i]; - } - - i = 0; - } - } - - if (i) { - for (j = i; j < 4; j++) { - a4[j] = '\0'; - } - - for (j = 0; j < 4; j++) { - a4[j] = b64_lookup(a4[j]); - } - - a4_to_a3(a3,a4); - - for (j = 0; j < i - 1; j++) { - (*out)[dec_len++] = a3[j]; - } - } - - return (dec_len == out->size()); - } - - static bool Decode(const char *input, size_t input_length, char *out, size_t out_length) { - int i = 0, j = 0; - char *out_begin = out; - unsigned char a3[3]; - unsigned char a4[4]; - - size_t decoded_length = DecodedLength(input, input_length); - - if (out_length < decoded_length) return false; - - while (input_length--) { - if (*input == '=') { - break; - } - - a4[i++] = *(input++); - if (i == 4) { - for (i = 0; i <4; i++) { - a4[i] = b64_lookup(a4[i]); - } - - a4_to_a3(a3,a4); - - for (i = 0; i < 3; i++) { - *out++ = a3[i]; - } - - i = 0; - } - } - - if (i) { - for (j = i; j < 4; j++) { - a4[j] = '\0'; - } - - for (j = 0; j < 4; j++) { - a4[j] = b64_lookup(a4[j]); - } - - a4_to_a3(a3,a4); - - for (j = 0; j < i - 1; j++) { - *out++ = a3[j]; - } - } - - return (out == (out_begin + decoded_length)); - } - - static int DecodedLength(const char *in, size_t in_length) { - int numEq = 0; - - const char *in_end = in + in_length; - while (*--in_end == '=') ++numEq; - - return ((6 * in_length) / 8) - numEq; - } - - static int DecodedLength(const std::string &in) { - int numEq = 0; - int n = in.size(); - - for (std::string::const_reverse_iterator it = in.rbegin(); *it == '='; ++it) { - ++numEq; - } - - return ((6 * n) / 8) - numEq; - } - - inline static int EncodedLength(size_t length) { - return (length + 2 - ((length + 2) % 3)) / 3 * 4; - } - - inline static int EncodedLength(const std::string &in) { - return EncodedLength(in.length()); - } - - inline static void StripPadding(std::string *in) { - while (!in->empty() && *(in->rbegin()) == '=') in->resize(in->size() - 1); - } - - private: - static inline void a3_to_a4(unsigned char * a4, unsigned char * a3) { - a4[0] = (a3[0] & 0xfc) >> 2; - a4[1] = ((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4); - a4[2] = ((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6); - a4[3] = (a3[2] & 0x3f); - } - - static inline void a4_to_a3(unsigned char * a3, unsigned char * a4) { - a3[0] = (a4[0] << 2) + ((a4[1] & 0x30) >> 4); - a3[1] = ((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2); - a3[2] = ((a4[2] & 0x3) << 6) + a4[3]; - } - - static inline unsigned char b64_lookup(unsigned char c) { - if(c >='A' && c <='Z') return c - 'A'; - if(c >='a' && c <='z') return c - 71; - if(c >='0' && c <='9') return c + 4; - if(c == '+') return 62; - if(c == '/') return 63; - return 255; - } -}; - - - -#endif // BASE64_H diff --git a/src_native/blake.c b/src_native/blake.c deleted file mode 100644 index 464a0dee..00000000 --- a/src_native/blake.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * The blake256_* and blake224_* functions are largely copied from - * blake256_light.c and blake224_light.c from the BLAKE website: - * - * http://131002.net/blake/ - * - * The hmac_* functions implement HMAC-BLAKE-256 and HMAC-BLAKE-224. - * HMAC is specified by RFC 2104. - */ - -#include -#include - -typedef struct { - uint32_t h[8], s[4], t[2]; - int buflen, nullt; - uint8_t buf[64]; -} state; - -typedef struct { - state inner; - state outer; -} hmac_state; - - -#define U8TO32(p) \ - (((uint32_t)((p)[0]) << 24) | ((uint32_t)((p)[1]) << 16) | \ - ((uint32_t)((p)[2]) << 8) | ((uint32_t)((p)[3]) )) -#define U32TO8(p, v) \ - (p)[0] = (uint8_t)((v) >> 24); (p)[1] = (uint8_t)((v) >> 16); \ - (p)[2] = (uint8_t)((v) >> 8); (p)[3] = (uint8_t)((v) ); - -const uint8_t sigma[][16] = { - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15}, - {14,10, 4, 8, 9,15,13, 6, 1,12, 0, 2,11, 7, 5, 3}, - {11, 8,12, 0, 5, 2,15,13,10,14, 3, 6, 7, 1, 9, 4}, - { 7, 9, 3, 1,13,12,11,14, 2, 6, 5,10, 4, 0,15, 8}, - { 9, 0, 5, 7, 2, 4,10,15,14, 1,11,12, 6, 8, 3,13}, - { 2,12, 6,10, 0,11, 8, 3, 4,13, 7, 5,15,14, 1, 9}, - {12, 5, 1,15,14,13, 4,10, 0, 7, 6, 3, 9, 2, 8,11}, - {13,11, 7,14,12, 1, 3, 9, 5, 0,15, 4, 8, 6, 2,10}, - { 6,15,14, 9,11, 3, 0, 8,12, 2,13, 7, 1, 4,10, 5}, - {10, 2, 8, 4, 7, 6, 1, 5,15,11, 9,14, 3,12,13, 0}, - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15}, - {14,10, 4, 8, 9,15,13, 6, 1,12, 0, 2,11, 7, 5, 3}, - {11, 8,12, 0, 5, 2,15,13,10,14, 3, 6, 7, 1, 9, 4}, - { 7, 9, 3, 1,13,12,11,14, 2, 6, 5,10, 4, 0,15, 8} -}; - -const uint32_t cst[16] = { - 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, - 0xA4093822, 0x299F31D0, 0x082EFA98, 0xEC4E6C89, - 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, - 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917 -}; - -static const uint8_t padding[] = { - 0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; - - -void blake256_compress(state *S, const uint8_t *block) { - uint32_t v[16], m[16], i; - -#define ROT(x,n) (((x)<<(32-n))|((x)>>(n))) -#define G(a,b,c,d,e) \ - v[a] += (m[sigma[i][e]] ^ cst[sigma[i][e+1]]) + v[b]; \ - v[d] = ROT(v[d] ^ v[a],16); \ - v[c] += v[d]; \ - v[b] = ROT(v[b] ^ v[c],12); \ - v[a] += (m[sigma[i][e+1]] ^ cst[sigma[i][e]])+v[b]; \ - v[d] = ROT(v[d] ^ v[a], 8); \ - v[c] += v[d]; \ - v[b] = ROT(v[b] ^ v[c], 7); - - for (i = 0; i < 16; ++i) m[i] = U8TO32(block + i * 4); - for (i = 0; i < 8; ++i) v[i] = S->h[i]; - v[ 8] = S->s[0] ^ 0x243F6A88; - v[ 9] = S->s[1] ^ 0x85A308D3; - v[10] = S->s[2] ^ 0x13198A2E; - v[11] = S->s[3] ^ 0x03707344; - v[12] = 0xA4093822; - v[13] = 0x299F31D0; - v[14] = 0x082EFA98; - v[15] = 0xEC4E6C89; - - if (S->nullt == 0) { - v[12] ^= S->t[0]; - v[13] ^= S->t[0]; - v[14] ^= S->t[1]; - v[15] ^= S->t[1]; - } - - for (i = 0; i < 14; ++i) { - G(0, 4, 8, 12, 0); - G(1, 5, 9, 13, 2); - G(2, 6, 10, 14, 4); - G(3, 7, 11, 15, 6); - G(3, 4, 9, 14, 14); - G(2, 7, 8, 13, 12); - G(0, 5, 10, 15, 8); - G(1, 6, 11, 12, 10); - } - - for (i = 0; i < 16; ++i) S->h[i % 8] ^= v[i]; - for (i = 0; i < 8; ++i) S->h[i] ^= S->s[i % 4]; -} - -void blake256_init(state *S) { - S->h[0] = 0x6A09E667; - S->h[1] = 0xBB67AE85; - S->h[2] = 0x3C6EF372; - S->h[3] = 0xA54FF53A; - S->h[4] = 0x510E527F; - S->h[5] = 0x9B05688C; - S->h[6] = 0x1F83D9AB; - S->h[7] = 0x5BE0CD19; - S->t[0] = S->t[1] = S->buflen = S->nullt = 0; - S->s[0] = S->s[1] = S->s[2] = S->s[3] = 0; -} - -void blake224_init(state *S) { - S->h[0] = 0xC1059ED8; - S->h[1] = 0x367CD507; - S->h[2] = 0x3070DD17; - S->h[3] = 0xF70E5939; - S->h[4] = 0xFFC00B31; - S->h[5] = 0x68581511; - S->h[6] = 0x64F98FA7; - S->h[7] = 0xBEFA4FA4; - S->t[0] = S->t[1] = S->buflen = S->nullt = 0; - S->s[0] = S->s[1] = S->s[2] = S->s[3] = 0; -} - -// datalen = number of bits -void blake256_update(state *S, const uint8_t *data, uint64_t datalen) { - int left = S->buflen >> 3; - int fill = 64 - left; - - if (left && (((datalen >> 3) & 0x3F) >= (unsigned) fill)) { - memcpy((void *) (S->buf + left), (void *) data, fill); - S->t[0] += 512; - if (S->t[0] == 0) S->t[1]++; - blake256_compress(S, S->buf); - data += fill; - datalen -= (fill << 3); - left = 0; - } - - while (datalen >= 512) { - S->t[0] += 512; - if (S->t[0] == 0) S->t[1]++; - blake256_compress(S, data); - data += 64; - datalen -= 512; - } - - if (datalen > 0) { - memcpy((void *) (S->buf + left), (void *) data, datalen >> 3); - S->buflen = (left << 3) + datalen; - } else { - S->buflen = 0; - } -} - -// datalen = number of bits -void blake224_update(state *S, const uint8_t *data, uint64_t datalen) { - blake256_update(S, data, datalen); -} - -void blake256_final_h(state *S, uint8_t *digest, uint8_t pa, uint8_t pb) { - uint8_t msglen[8]; - uint32_t lo = S->t[0] + S->buflen, hi = S->t[1]; - if (lo < (unsigned) S->buflen) hi++; - U32TO8(msglen + 0, hi); - U32TO8(msglen + 4, lo); - - if (S->buflen == 440) { /* one padding byte */ - S->t[0] -= 8; - blake256_update(S, &pa, 8); - } else { - if (S->buflen < 440) { /* enough space to fill the block */ - if (S->buflen == 0) S->nullt = 1; - S->t[0] -= 440 - S->buflen; - blake256_update(S, padding, 440 - S->buflen); - } else { /* need 2 compressions */ - S->t[0] -= 512 - S->buflen; - blake256_update(S, padding, 512 - S->buflen); - S->t[0] -= 440; - blake256_update(S, padding + 1, 440); - S->nullt = 1; - } - blake256_update(S, &pb, 8); - S->t[0] -= 8; - } - S->t[0] -= 64; - blake256_update(S, msglen, 64); - - U32TO8(digest + 0, S->h[0]); - U32TO8(digest + 4, S->h[1]); - U32TO8(digest + 8, S->h[2]); - U32TO8(digest + 12, S->h[3]); - U32TO8(digest + 16, S->h[4]); - U32TO8(digest + 20, S->h[5]); - U32TO8(digest + 24, S->h[6]); - U32TO8(digest + 28, S->h[7]); -} - -void blake256_final(state *S, uint8_t *digest) { - blake256_final_h(S, digest, 0x81, 0x01); -} - -void blake224_final(state *S, uint8_t *digest) { - blake256_final_h(S, digest, 0x80, 0x00); -} - -// inlen = number of bytes -void blake256_hash(uint8_t *out, const uint8_t *in, uint64_t inlen) { - state S; - blake256_init(&S); - blake256_update(&S, in, inlen * 8); - blake256_final(&S, out); -} - -void blake(const uint8_t *input, uint64_t len, uint8_t *output) -{ - blake256_hash(output, input, len); -} - -// inlen = number of bytes -void blake224_hash(uint8_t *out, const uint8_t *in, uint64_t inlen) { - state S; - blake224_init(&S); - blake224_update(&S, in, inlen * 8); - blake224_final(&S, out); -} - -// keylen = number of bytes -void hmac_blake256_init(hmac_state *S, const uint8_t *_key, uint64_t keylen) { - const uint8_t *key = _key; - uint8_t keyhash[32]; - uint8_t pad[64]; - uint64_t i; - - if (keylen > 64) { - blake256_hash(keyhash, key, keylen); - key = keyhash; - keylen = 32; - } - - blake256_init(&S->inner); - memset(pad, 0x36, 64); - for (i = 0; i < keylen; ++i) { - pad[i] ^= key[i]; - } - blake256_update(&S->inner, pad, 512); - - blake256_init(&S->outer); - memset(pad, 0x5c, 64); - for (i = 0; i < keylen; ++i) { - pad[i] ^= key[i]; - } - blake256_update(&S->outer, pad, 512); - - memset(keyhash, 0, 32); -} - -// keylen = number of bytes -void hmac_blake224_init(hmac_state *S, const uint8_t *_key, uint64_t keylen) { - const uint8_t *key = _key; - uint8_t keyhash[32]; - uint8_t pad[64]; - uint64_t i; - - if (keylen > 64) { - blake256_hash(keyhash, key, keylen); - key = keyhash; - keylen = 28; - } - - blake224_init(&S->inner); - memset(pad, 0x36, 64); - for (i = 0; i < keylen; ++i) { - pad[i] ^= key[i]; - } - blake224_update(&S->inner, pad, 512); - - blake224_init(&S->outer); - memset(pad, 0x5c, 64); - for (i = 0; i < keylen; ++i) { - pad[i] ^= key[i]; - } - blake224_update(&S->outer, pad, 512); - - memset(keyhash, 0, 32); -} - -// datalen = number of bits -void hmac_blake256_update(hmac_state *S, const uint8_t *data, uint64_t datalen) { - // update the inner state - blake256_update(&S->inner, data, datalen); -} - -// datalen = number of bits -void hmac_blake224_update(hmac_state *S, const uint8_t *data, uint64_t datalen) { - // update the inner state - blake224_update(&S->inner, data, datalen); -} - -void hmac_blake256_final(hmac_state *S, uint8_t *digest) { - uint8_t ihash[32]; - blake256_final(&S->inner, ihash); - blake256_update(&S->outer, ihash, 256); - blake256_final(&S->outer, digest); - memset(ihash, 0, 32); -} - -void hmac_blake224_final(hmac_state *S, uint8_t *digest) { - uint8_t ihash[32]; - blake224_final(&S->inner, ihash); - blake224_update(&S->outer, ihash, 224); - blake224_final(&S->outer, digest); - memset(ihash, 0, 32); -} - -// keylen = number of bytes; inlen = number of bytes -void hmac_blake256_hash(uint8_t *out, const uint8_t *key, uint64_t keylen, const uint8_t *in, uint64_t inlen) { - hmac_state S; - hmac_blake256_init(&S, key, keylen); - hmac_blake256_update(&S, in, inlen * 8); - hmac_blake256_final(&S, out); -} - -// keylen = number of bytes; inlen = number of bytes -void hmac_blake224_hash(uint8_t *out, const uint8_t *key, uint64_t keylen, const uint8_t *in, uint64_t inlen) { - hmac_state S; - hmac_blake224_init(&S, key, keylen); - hmac_blake224_update(&S, in, inlen * 8); - hmac_blake224_final(&S, out); -} diff --git a/src_native/blake.h b/src_native/blake.h deleted file mode 100644 index 8fa43f3b..00000000 --- a/src_native/blake.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef BLAKE_H -#define BLAKE_H - -#ifdef __cplusplus -extern "C" { -#endif - -void blake(const uint8_t *input, uint64_t len, uint8_t *output); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src_native/blake.o b/src_native/blake.o deleted file mode 100644 index 3081b64a..00000000 Binary files a/src_native/blake.o and /dev/null differ diff --git a/src_native/cn.html b/src_native/cn.html deleted file mode 100644 index 400e23bc..00000000 --- a/src_native/cn.html +++ /dev/null @@ -1,130 +0,0 @@ - - - \ No newline at end of file diff --git a/src_native/common/CMakeLists.txt b/src_native/common/CMakeLists.txt deleted file mode 100644 index 66fd8d7a..00000000 --- a/src_native/common/CMakeLists.txt +++ /dev/null @@ -1,95 +0,0 @@ -# Copyright (c) 2014-2018, The Monero Project -# -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, are -# permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this list of -# conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, this list -# of conditions and the following disclaimer in the documentation and/or other -# materials provided with the distribution. -# -# 3. Neither the name of the copyright holder nor the names of its contributors may be -# used to endorse or promote products derived from this software without specific -# prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -include_directories(SYSTEM ${OPENSSL_INCLUDE_DIR}) - -set(common_sources - base58.cpp - command_line.cpp - dns_utils.cpp - download.cpp - util.cpp - i18n.cpp - password.cpp - perf_timer.cpp - threadpool.cpp - updates.cpp) - -if (STACK_TRACE) - list(APPEND common_sources stack_trace.cpp) -endif() - -set(common_headers) - -set(common_private_headers - apply_permutation.h - base58.h - boost_serialization_helper.h - command_line.h - common_fwd.h - dns_utils.h - download.h - http_connection.h - int-util.h - pod-class.h - rpc_client.h - scoped_message_writer.h - unordered_containers_boost_serialization.h - util.h - varint.h - i18n.h - password.h - perf_timer.h - stack_trace.h - threadpool.h - updates.h) - -monero_private_headers(common - ${common_private_headers}) -monero_add_library(common - ${common_sources} - ${common_headers} - ${common_private_headers} - DEPENDS generate_translations_header) -target_link_libraries(common - PUBLIC - epee - cncrypto - ${UNBOUND_LIBRARY} - ${LIBUNWIND_LIBRARIES} - ${Boost_DATE_TIME_LIBRARY} - ${Boost_FILESYSTEM_LIBRARY} - ${Boost_SYSTEM_LIBRARY} - ${Boost_THREAD_LIBRARY} - ${Boost_REGEX_LIBRARY} - PRIVATE - ${OPENSSL_LIBRARIES} - ${EXTRA_LIBRARIES}) - -#monero_install_headers(common -# ${common_headers}) diff --git a/src_native/common/apply_permutation.h b/src_native/common/apply_permutation.h deleted file mode 100644 index ff346bab..00000000 --- a/src_native/common/apply_permutation.h +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2017-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Most of this file is originally copyright (c) 2017 Raymond Chen, Microsoft -// This algorithm is adapted from Raymond Chen's code: -// https://blogs.msdn.microsoft.com/oldnewthing/20170109-00/?p=95145 - -#pragma once - -#include -#include -#include "misc_log_ex.h" - -namespace tools -{ - -template -void apply_permutation(std::vector permutation, const F &swap) -{ - //sanity check - for (size_t n = 0; n < permutation.size(); ++n) - CHECK_AND_ASSERT_THROW_MES(std::find(permutation.begin(), permutation.end(), n) != permutation.end(), "Bad permutation"); - - for (size_t i = 0; i < permutation.size(); ++i) - { - size_t current = i; - while (i != permutation[current]) - { - size_t next = permutation[current]; - swap(current, next); - permutation[current] = current; - current = next; - } - permutation[current] = current; - } -} - -template -void apply_permutation(const std::vector &permutation, std::vector &v) -{ - CHECK_AND_ASSERT_THROW_MES(permutation.size() == v.size(), "Mismatched vector sizes"); - apply_permutation(permutation, [&v](size_t i0, size_t i1){ std::swap(v[i0], v[i1]); }); -} - -} diff --git a/src_native/common/base58.cpp b/src_native/common/base58.cpp deleted file mode 100644 index 75556cad..00000000 --- a/src_native/common/base58.cpp +++ /dev/null @@ -1,272 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#include "base58.h" - -#include -#include -#include - -#include "crypto/hash.h" -#include "int-util.h" -#include "util.h" -#include "varint.h" - -namespace tools -{ - namespace base58 - { - namespace - { - const char alphabet[] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; - const size_t alphabet_size = sizeof(alphabet) - 1; - const size_t encoded_block_sizes[] = {0, 2, 3, 5, 6, 7, 9, 10, 11}; - const size_t full_block_size = sizeof(encoded_block_sizes) / sizeof(encoded_block_sizes[0]) - 1; - const size_t full_encoded_block_size = encoded_block_sizes[full_block_size]; - const size_t addr_checksum_size = 4; - - struct reverse_alphabet - { - reverse_alphabet() - { - m_data.resize(alphabet[alphabet_size - 1] - alphabet[0] + 1, -1); - - for (size_t i = 0; i < alphabet_size; ++i) - { - size_t idx = static_cast(alphabet[i] - alphabet[0]); - m_data[idx] = static_cast(i); - } - } - - int operator()(char letter) const - { - size_t idx = static_cast(letter - alphabet[0]); - return idx < m_data.size() ? m_data[idx] : -1; - } - - static reverse_alphabet instance; - - private: - std::vector m_data; - }; - - reverse_alphabet reverse_alphabet::instance; - - struct decoded_block_sizes - { - decoded_block_sizes() - { - m_data.resize(encoded_block_sizes[full_block_size] + 1, -1); - for (size_t i = 0; i <= full_block_size; ++i) - { - m_data[encoded_block_sizes[i]] = static_cast(i); - } - } - - int operator()(size_t encoded_block_size) const - { - assert(encoded_block_size <= full_encoded_block_size); - return m_data[encoded_block_size]; - } - - static decoded_block_sizes instance; - - private: - std::vector m_data; - }; - - decoded_block_sizes decoded_block_sizes::instance; - - uint64_t uint_8be_to_64(const uint8_t* data, size_t size) - { - assert(1 <= size && size <= sizeof(uint64_t)); - - uint64_t res = 0; - switch (9 - size) - { - case 1: res |= *data++; /* FALLTHRU */ - case 2: res <<= 8; res |= *data++; /* FALLTHRU */ - case 3: res <<= 8; res |= *data++; /* FALLTHRU */ - case 4: res <<= 8; res |= *data++; /* FALLTHRU */ - case 5: res <<= 8; res |= *data++; /* FALLTHRU */ - case 6: res <<= 8; res |= *data++; /* FALLTHRU */ - case 7: res <<= 8; res |= *data++; /* FALLTHRU */ - case 8: res <<= 8; res |= *data; break; - default: assert(false); - } - - return res; - } - - void uint_64_to_8be(uint64_t num, size_t size, uint8_t* data) - { - assert(1 <= size && size <= sizeof(uint64_t)); - - uint64_t num_be = SWAP64BE(num); - memcpy(data, reinterpret_cast(&num_be) + sizeof(uint64_t) - size, size); - } - - void encode_block(const char* block, size_t size, char* res) - { - assert(1 <= size && size <= full_block_size); - - uint64_t num = uint_8be_to_64(reinterpret_cast(block), size); - int i = static_cast(encoded_block_sizes[size]) - 1; - while (0 < num) - { - uint64_t remainder = num % alphabet_size; - num /= alphabet_size; - res[i] = alphabet[remainder]; - --i; - } - } - - bool decode_block(const char* block, size_t size, char* res) - { - assert(1 <= size && size <= full_encoded_block_size); - - int res_size = decoded_block_sizes::instance(size); - if (res_size <= 0) - return false; // Invalid block size - - uint64_t res_num = 0; - uint64_t order = 1; - for (size_t i = size - 1; i < size; --i) - { - int digit = reverse_alphabet::instance(block[i]); - if (digit < 0) - return false; // Invalid symbol - - uint64_t product_hi; - uint64_t tmp = res_num + mul128(order, digit, &product_hi); - if (tmp < res_num || 0 != product_hi) - return false; // Overflow - - res_num = tmp; - order *= alphabet_size; // Never overflows, 58^10 < 2^64 - } - - if (static_cast(res_size) < full_block_size && (UINT64_C(1) << (8 * res_size)) <= res_num) - return false; // Overflow - - uint_64_to_8be(res_num, res_size, reinterpret_cast(res)); - - return true; - } - } - - std::string encode(const std::string& data) - { - if (data.empty()) - return std::string(); - - size_t full_block_count = data.size() / full_block_size; - size_t last_block_size = data.size() % full_block_size; - size_t res_size = full_block_count * full_encoded_block_size + encoded_block_sizes[last_block_size]; - - std::string res(res_size, alphabet[0]); - for (size_t i = 0; i < full_block_count; ++i) - { - encode_block(data.data() + i * full_block_size, full_block_size, &res[i * full_encoded_block_size]); - } - - if (0 < last_block_size) - { - encode_block(data.data() + full_block_count * full_block_size, last_block_size, &res[full_block_count * full_encoded_block_size]); - } - - return res; - } - - bool decode(const std::string& enc, std::string& data) - { - if (enc.empty()) - { - data.clear(); - return true; - } - - size_t full_block_count = enc.size() / full_encoded_block_size; - size_t last_block_size = enc.size() % full_encoded_block_size; - int last_block_decoded_size = decoded_block_sizes::instance(last_block_size); - if (last_block_decoded_size < 0) - return false; // Invalid enc length - size_t data_size = full_block_count * full_block_size + last_block_decoded_size; - - data.resize(data_size, 0); - for (size_t i = 0; i < full_block_count; ++i) - { - if (!decode_block(enc.data() + i * full_encoded_block_size, full_encoded_block_size, &data[i * full_block_size])) - return false; - } - - if (0 < last_block_size) - { - if (!decode_block(enc.data() + full_block_count * full_encoded_block_size, last_block_size, - &data[full_block_count * full_block_size])) - return false; - } - - return true; - } - - std::string encode_addr(uint64_t tag, const std::string& data) - { - std::string buf = get_varint_data(tag); - buf += data; - crypto::hash hash = crypto::cn_fast_hash(buf.data(), buf.size()); - const char* hash_data = reinterpret_cast(&hash); - buf.append(hash_data, addr_checksum_size); - return encode(buf); - } - - bool decode_addr(std::string addr, uint64_t& tag, std::string& data) - { - std::string addr_data; - bool r = decode(addr, addr_data); - if (!r) return false; - if (addr_data.size() <= addr_checksum_size) return false; - - std::string checksum(addr_checksum_size, '\0'); - checksum = addr_data.substr(addr_data.size() - addr_checksum_size); - - addr_data.resize(addr_data.size() - addr_checksum_size); - crypto::hash hash = crypto::cn_fast_hash(addr_data.data(), addr_data.size()); - std::string expected_checksum(reinterpret_cast(&hash), addr_checksum_size); - if (expected_checksum != checksum) return false; - - int read = tools::read_varint(addr_data.begin(), addr_data.end(), tag); - if (read <= 0) return false; - - data = addr_data.substr(read); - return true; - } - } -} diff --git a/src_native/common/base58.h b/src_native/common/base58.h deleted file mode 100644 index 02ca9695..00000000 --- a/src_native/common/base58.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once - -#include -#include - -namespace tools -{ - namespace base58 - { - std::string encode(const std::string& data); - bool decode(const std::string& enc, std::string& data); - - std::string encode_addr(uint64_t tag, const std::string& data); - bool decode_addr(std::string addr, uint64_t& tag, std::string& data); - } -} diff --git a/src_native/common/boost_serialization_helper.h b/src_native/common/boost_serialization_helper.h deleted file mode 100644 index 3f5c623f..00000000 --- a/src_native/common/boost_serialization_helper.h +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once - -#include -#include -#include -#include - - -namespace tools -{ - template - bool serialize_obj_to_file(t_object& obj, const std::string& file_path) - { - TRY_ENTRY(); -#if defined(_MSC_VER) - // Need to know HANDLE of file to call FlushFileBuffers - HANDLE data_file_handle = ::CreateFile(file_path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (INVALID_HANDLE_VALUE == data_file_handle) - return false; - - int data_file_descriptor = _open_osfhandle((intptr_t)data_file_handle, 0); - if (-1 == data_file_descriptor) - { - ::CloseHandle(data_file_handle); - return false; - } - - const std::unique_ptr data_file_file{_fdopen(data_file_descriptor, "wb")}; - if (nullptr == data_file_file) - { - // Call CloseHandle is not necessary - _close(data_file_descriptor); - return false; - } - - // HACK: undocumented constructor, this code may not compile - std::ofstream data_file(data_file_file.get()); - if (data_file.fail()) - { - // Call CloseHandle and _close are not necessary - return false; - } -#else - std::ofstream data_file; - data_file.open(file_path , std::ios_base::binary | std::ios_base::out| std::ios::trunc); - if (data_file.fail()) - return false; -#endif - - boost::archive::portable_binary_oarchive a(data_file); - a << obj; - if (data_file.fail()) - return false; - - data_file.flush(); -#if defined(_MSC_VER) - // To make sure the file is fully stored on disk - ::FlushFileBuffers(data_file_handle); -#endif - - return true; - CATCH_ENTRY_L0("serialize_obj_to_file", false); - } - - template - bool unserialize_obj_from_file(t_object& obj, const std::string& file_path) - { - TRY_ENTRY(); - - std::ifstream data_file; - data_file.open( file_path, std::ios_base::binary | std::ios_base::in); - if(data_file.fail()) - return false; - try - { - // first try reading in portable mode - boost::archive::portable_binary_iarchive a(data_file); - a >> obj; - } - catch(...) - { - // if failed, try reading in unportable mode - boost::filesystem::copy_file(file_path, file_path + ".unportable", boost::filesystem::copy_option::overwrite_if_exists); - data_file.close(); - data_file.open( file_path, std::ios_base::binary | std::ios_base::in); - if(data_file.fail()) - return false; - boost::archive::binary_iarchive a(data_file); - a >> obj; - } - return !data_file.fail(); - CATCH_ENTRY_L0("unserialize_obj_from_file", false); - } -} diff --git a/src_native/common/command_line.cpp b/src_native/common/command_line.cpp deleted file mode 100644 index 7980b381..00000000 --- a/src_native/common/command_line.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#include "command_line.h" -#include -#include -#include -#include "common/i18n.h" -#include "cryptonote_config.h" -#include "string_tools.h" - -namespace command_line -{ - namespace - { - const char* tr(const char* str) - { - return i18n_translate(str, "command_line"); - } - } - - bool is_yes(const std::string& str) - { - if (str == "y" || str == "Y") - return true; - - boost::algorithm::is_iequal ignore_case{}; - if (boost::algorithm::equals("yes", str, ignore_case)) - return true; - if (boost::algorithm::equals(command_line::tr("yes"), str, ignore_case)) - return true; - - return false; - } - - bool is_no(const std::string& str) - { - if (str == "n" || str == "N") - return true; - - boost::algorithm::is_iequal ignore_case{}; - if (boost::algorithm::equals("no", str, ignore_case)) - return true; - if (boost::algorithm::equals(command_line::tr("no"), str, ignore_case)) - return true; - - return false; - } - - const arg_descriptor arg_help = {"help", "Produce help message"}; - const arg_descriptor arg_version = {"version", "Output version information"}; -} diff --git a/src_native/common/command_line.h b/src_native/common/command_line.h deleted file mode 100644 index 3a869bb2..00000000 --- a/src_native/common/command_line.h +++ /dev/null @@ -1,299 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once - -#include -#include -#include -#include -#include - -#include -#include -#include -#include "include_base_utils.h" - -namespace command_line -{ - - //! \return True if `str` is `is_iequal("y" || "yes" || `tr("yes"))`. - bool is_yes(const std::string& str); - //! \return True if `str` is `is_iequal("n" || "no" || `tr("no"))`. - bool is_no(const std::string& str); - - template - struct arg_descriptor; - - template - struct arg_descriptor - { - typedef T value_type; - - const char* name; - const char* description; - T default_value; - bool not_use_default; - }; - - template - struct arg_descriptor, false> - { - typedef std::vector value_type; - - const char* name; - const char* description; - }; - - template - struct arg_descriptor - { - static_assert(!std::is_same::value, "Boolean switch can't be required"); - - typedef T value_type; - - const char* name; - const char* description; - }; - - template - struct arg_descriptor - { - typedef T value_type; - - const char* name; - const char* description; - - T default_value; - - const arg_descriptor& ref; - std::function depf; - - bool not_use_default; - }; - - template - struct arg_descriptor - { - typedef T value_type; - - const char* name; - const char* description; - - T default_value; - - std::array *, NUM_DEPS> ref; - std::function, bool, T)> depf; - - bool not_use_default; - }; - - template - boost::program_options::typed_value* make_semantic(const arg_descriptor& /*arg*/) - { - return boost::program_options::value()->required(); - } - - template - boost::program_options::typed_value* make_semantic(const arg_descriptor& arg) - { - auto semantic = boost::program_options::value(); - if (!arg.not_use_default) - semantic->default_value(arg.default_value); - return semantic; - } - - template - boost::program_options::typed_value* make_semantic(const arg_descriptor& arg) - { - auto semantic = boost::program_options::value(); - if (!arg.not_use_default) { - std::ostringstream format; - format << arg.depf(false, true, arg.default_value) << ", " - << arg.depf(true, true, arg.default_value) << " if '" - << arg.ref.name << "'"; - semantic->default_value(arg.depf(arg.ref.default_value, true, arg.default_value), format.str()); - } - return semantic; - } - - template - boost::program_options::typed_value* make_semantic(const arg_descriptor& arg) - { - auto semantic = boost::program_options::value(); - if (!arg.not_use_default) { - std::array depval; - depval.fill(false); - std::ostringstream format; - format << arg.depf(depval, true, arg.default_value); - for (size_t i = 0; i < depval.size(); ++i) - { - depval.fill(false); - depval[i] = true; - format << ", " << arg.depf(depval, true, arg.default_value) << " if '" << arg.ref[i]->name << "'"; - } - for (size_t i = 0; i < depval.size(); ++i) - depval[i] = arg.ref[i]->default_value; - semantic->default_value(arg.depf(depval, true, arg.default_value), format.str()); - } - return semantic; - } - - template - boost::program_options::typed_value* make_semantic(const arg_descriptor& arg, const T& def) - { - auto semantic = boost::program_options::value(); - if (!arg.not_use_default) - semantic->default_value(def); - return semantic; - } - - template - boost::program_options::typed_value, char>* make_semantic(const arg_descriptor, false>& /*arg*/) - { - auto semantic = boost::program_options::value< std::vector >(); - semantic->default_value(std::vector(), ""); - return semantic; - } - - template - void add_arg(boost::program_options::options_description& description, const arg_descriptor& arg, bool unique = true) - { - if (0 != description.find_nothrow(arg.name, false)) - { - CHECK_AND_ASSERT_MES(!unique, void(), "Argument already exists: " << arg.name); - return; - } - - description.add_options()(arg.name, make_semantic(arg), arg.description); - } - - template - void add_arg(boost::program_options::options_description& description, const arg_descriptor& arg, const T& def, bool unique = true) - { - if (0 != description.find_nothrow(arg.name, false)) - { - CHECK_AND_ASSERT_MES(!unique, void(), "Argument already exists: " << arg.name); - return; - } - - description.add_options()(arg.name, make_semantic(arg, def), arg.description); - } - - template<> - inline void add_arg(boost::program_options::options_description& description, const arg_descriptor& arg, bool unique) - { - if (0 != description.find_nothrow(arg.name, false)) - { - CHECK_AND_ASSERT_MES(!unique, void(), "Argument already exists: " << arg.name); - return; - } - - description.add_options()(arg.name, boost::program_options::bool_switch(), arg.description); - } - - template - boost::program_options::basic_parsed_options parse_command_line(int argc, const charT* const argv[], - const boost::program_options::options_description& desc, bool allow_unregistered = false) - { - auto parser = boost::program_options::command_line_parser(argc, argv); - parser.options(desc); - if (allow_unregistered) - { - parser.allow_unregistered(); - } - return parser.run(); - } - - template - bool handle_error_helper(const boost::program_options::options_description& desc, F parser) - { - try - { - return parser(); - } - catch (const std::exception& e) - { - std::cerr << "Failed to parse arguments: " << e.what() << std::endl; - std::cerr << desc << std::endl; - return false; - } - catch (...) - { - std::cerr << "Failed to parse arguments: unknown exception" << std::endl; - std::cerr << desc << std::endl; - return false; - } - } - - template - typename std::enable_if::value, bool>::type has_arg(const boost::program_options::variables_map& vm, const arg_descriptor& arg) - { - auto value = vm[arg.name]; - return !value.empty(); - } - - template - bool is_arg_defaulted(const boost::program_options::variables_map& vm, const arg_descriptor& arg) - { - return vm[arg.name].defaulted(); - } - - template - T get_arg(const boost::program_options::variables_map& vm, const arg_descriptor& arg) - { - return arg.depf(get_arg(vm, arg.ref), is_arg_defaulted(vm, arg), vm[arg.name].template as()); - } - - template - T get_arg(const boost::program_options::variables_map& vm, const arg_descriptor& arg) - { - std::array depval; - for (size_t i = 0; i < depval.size(); ++i) - depval[i] = get_arg(vm, *arg.ref[i]); - return arg.depf(depval, is_arg_defaulted(vm, arg), vm[arg.name].template as()); - } - - template - T get_arg(const boost::program_options::variables_map& vm, const arg_descriptor& arg) - { - return vm[arg.name].template as(); - } - - template - inline bool has_arg(const boost::program_options::variables_map& vm, const arg_descriptor& arg) - { - return get_arg(vm, arg); - } - - - extern const arg_descriptor arg_help; - extern const arg_descriptor arg_version; -} diff --git a/src_native/common/common_fwd.h b/src_native/common/common_fwd.h deleted file mode 100644 index 2924d9cb..00000000 --- a/src_native/common/common_fwd.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once - -namespace tools -{ - class DNSResolver; - struct login; - class password_container; - class t_http_connection; - class threadpool; -} diff --git a/src_native/common/dns_utils.cpp b/src_native/common/dns_utils.cpp deleted file mode 100644 index ea287a01..00000000 --- a/src_native/common/dns_utils.cpp +++ /dev/null @@ -1,570 +0,0 @@ -// Copyright (c) 2017-2018, The Masari Project -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "common/dns_utils.h" -// check local first (in the event of static or in-source compilation of libunbound) -#include "unbound.h" - -#include -#include "include_base_utils.h" -#include -#include -#include -#include -#include -using namespace epee; -namespace bf = boost::filesystem; - -#undef MONERO_DEFAULT_LOG_CATEGORY -#define MONERO_DEFAULT_LOG_CATEGORY "net.dns" - -static const char *DEFAULT_DNS_PUBLIC_ADDR[] = -{ - "194.150.168.168", // CCC (Germany) - "81.3.27.54", // Lightning Wire Labs (Germany) - "31.3.135.232", // OpenNIC (Switzerland) - "80.67.169.40", // FDN (France) - "209.58.179.186", // Cyberghost (Singapore) -}; - -static boost::mutex instance_lock; - -namespace -{ - -/* - * The following two functions were taken from unbound-anchor.c, from - * the unbound library packaged with this source. The license and source - * can be found in $PROJECT_ROOT/external/unbound - */ - -/* Cert builtin commented out until it's used, as the compiler complains - -// return the built in root update certificate -static const char* -get_builtin_cert(void) -{ - return -// The ICANN CA fetched at 24 Sep 2010. Valid to 2028 -"-----BEGIN CERTIFICATE-----\n" -"MIIDdzCCAl+gAwIBAgIBATANBgkqhkiG9w0BAQsFADBdMQ4wDAYDVQQKEwVJQ0FO\n" -"TjEmMCQGA1UECxMdSUNBTk4gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxFjAUBgNV\n" -"BAMTDUlDQU5OIFJvb3QgQ0ExCzAJBgNVBAYTAlVTMB4XDTA5MTIyMzA0MTkxMloX\n" -"DTI5MTIxODA0MTkxMlowXTEOMAwGA1UEChMFSUNBTk4xJjAkBgNVBAsTHUlDQU5O\n" -"IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRYwFAYDVQQDEw1JQ0FOTiBSb290IENB\n" -"MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKDb\n" -"cLhPNNqc1NB+u+oVvOnJESofYS9qub0/PXagmgr37pNublVThIzyLPGCJ8gPms9S\n" -"G1TaKNIsMI7d+5IgMy3WyPEOECGIcfqEIktdR1YWfJufXcMReZwU4v/AdKzdOdfg\n" -"ONiwc6r70duEr1IiqPbVm5T05l1e6D+HkAvHGnf1LtOPGs4CHQdpIUcy2kauAEy2\n" -"paKcOcHASvbTHK7TbbvHGPB+7faAztABLoneErruEcumetcNfPMIjXKdv1V1E3C7\n" -"MSJKy+jAqqQJqjZoQGB0necZgUMiUv7JK1IPQRM2CXJllcyJrm9WFxY0c1KjBO29\n" -"iIKK69fcglKcBuFShUECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B\n" -"Af8EBAMCAf4wHQYDVR0OBBYEFLpS6UmDJIZSL8eZzfyNa2kITcBQMA0GCSqGSIb3\n" -"DQEBCwUAA4IBAQAP8emCogqHny2UYFqywEuhLys7R9UKmYY4suzGO4nkbgfPFMfH\n" -"6M+Zj6owwxlwueZt1j/IaCayoKU3QsrYYoDRolpILh+FPwx7wseUEV8ZKpWsoDoD\n" -"2JFbLg2cfB8u/OlE4RYmcxxFSmXBg0yQ8/IoQt/bxOcEEhhiQ168H2yE5rxJMt9h\n" -"15nu5JBSewrCkYqYYmaxyOC3WrVGfHZxVI7MpIFcGdvSb2a1uyuua8l0BKgk3ujF\n" -"0/wsHNeP22qNyVO+XVBzrM8fk8BSUFuiT/6tZTYXRtEt5aKQZgXbKU5dUF3jT9qg\n" -"j/Br5BZw3X/zd325TvnswzMC1+ljLzHnQGGk\n" -"-----END CERTIFICATE-----\n" - ; -} -*/ - -/** return the built in root DS trust anchor */ -static const char* -get_builtin_ds(void) -{ - return -". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5\n"; -} - -/************************************************************ - ************************************************************ - ***********************************************************/ - -} // anonymous namespace - -namespace tools -{ - -// fuck it, I'm tired of dealing with getnameinfo()/inet_ntop/etc -std::string ipv4_to_string(const char* src, size_t len) -{ - assert(len >= 4); - - std::stringstream ss; - unsigned int bytes[4]; - for (int i = 0; i < 4; i++) - { - unsigned char a = src[i]; - bytes[i] = a; - } - ss << bytes[0] << "." - << bytes[1] << "." - << bytes[2] << "." - << bytes[3]; - return ss.str(); -} - -// this obviously will need to change, but is here to reflect the above -// stop-gap measure and to make the tests pass at least... -std::string ipv6_to_string(const char* src, size_t len) -{ - assert(len >= 8); - - std::stringstream ss; - unsigned int bytes[8]; - for (int i = 0; i < 8; i++) - { - unsigned char a = src[i]; - bytes[i] = a; - } - ss << bytes[0] << ":" - << bytes[1] << ":" - << bytes[2] << ":" - << bytes[3] << ":" - << bytes[4] << ":" - << bytes[5] << ":" - << bytes[6] << ":" - << bytes[7]; - return ss.str(); -} - -std::string txt_to_string(const char* src, size_t len) -{ - return std::string(src+1, len-1); -} - -// custom smart pointer. -// TODO: see if std::auto_ptr and the like support custom destructors -template -class scoped_ptr -{ -public: - scoped_ptr(): - ptr(nullptr) - { - } - scoped_ptr(type *p): - ptr(p) - { - } - ~scoped_ptr() - { - freefunc(ptr); - } - operator type *() { return ptr; } - type **operator &() { return &ptr; } - type *operator->() { return ptr; } - operator const type*() const { return &ptr; } - -private: - type* ptr; -}; - -typedef class scoped_ptr ub_result_ptr; - -struct DNSResolverData -{ - ub_ctx* m_ub_context; -}; - -// work around for bug https://www.nlnetlabs.nl/bugs-script/show_bug.cgi?id=515 needed for it to compile on e.g. Debian 7 -class string_copy { -public: - string_copy(const char *s): str(strdup(s)) {} - ~string_copy() { free(str); } - operator char*() { return str; } - -public: - char *str; -}; - -DNSResolver::DNSResolver() : m_data(new DNSResolverData()) -{ - int use_dns_public = 0; - std::vector dns_public_addr; - if (auto res = getenv("DNS_PUBLIC")) - { - dns_public_addr = tools::dns_utils::parse_dns_public(res); - if (!dns_public_addr.empty()) - { - MGINFO("Using public DNS server(s): " << boost::join(dns_public_addr, ", ") << " (TCP)"); - use_dns_public = 1; - } - else - { - MERROR("Failed to parse DNS_PUBLIC"); - } - } - - // init libunbound context - m_data->m_ub_context = ub_ctx_create(); - - if (use_dns_public) - { - for (const auto &ip: dns_public_addr) - ub_ctx_set_fwd(m_data->m_ub_context, ip.c_str()); - ub_ctx_set_option(m_data->m_ub_context, string_copy("do-udp:"), string_copy("no")); - ub_ctx_set_option(m_data->m_ub_context, string_copy("do-tcp:"), string_copy("yes")); - } - else { - // look for "/etc/resolv.conf" and "/etc/hosts" or platform equivalent - ub_ctx_resolvconf(m_data->m_ub_context, NULL); - ub_ctx_hosts(m_data->m_ub_context, NULL); - } - - ub_ctx_add_ta(m_data->m_ub_context, string_copy(::get_builtin_ds())); -} - -DNSResolver::~DNSResolver() -{ - if (m_data) - { - if (m_data->m_ub_context != NULL) - { - ub_ctx_delete(m_data->m_ub_context); - } - delete m_data; - } -} - -std::vector DNSResolver::get_record(const std::string& url, int record_type, std::string (*reader)(const char *,size_t), bool& dnssec_available, bool& dnssec_valid) -{ - std::vector addresses; - dnssec_available = false; - dnssec_valid = false; - - if (!check_address_syntax(url.c_str())) - { - return addresses; - } - - // destructor takes care of cleanup - ub_result_ptr result; - - // call DNS resolver, blocking. if return value not zero, something went wrong - if (!ub_resolve(m_data->m_ub_context, string_copy(url.c_str()), record_type, DNS_CLASS_IN, &result)) - { - dnssec_available = (result->secure || (!result->secure && result->bogus)); - dnssec_valid = result->secure && !result->bogus; - if (result->havedata) - { - for (size_t i=0; result->data[i] != NULL; i++) - { - addresses.push_back((*reader)(result->data[i], result->len[i])); - } - } - } - - return addresses; -} - -std::vector DNSResolver::get_ipv4(const std::string& url, bool& dnssec_available, bool& dnssec_valid) -{ - return get_record(url, DNS_TYPE_A, ipv4_to_string, dnssec_available, dnssec_valid); -} - -std::vector DNSResolver::get_ipv6(const std::string& url, bool& dnssec_available, bool& dnssec_valid) -{ - return get_record(url, DNS_TYPE_AAAA, ipv6_to_string, dnssec_available, dnssec_valid); -} - -std::vector DNSResolver::get_txt_record(const std::string& url, bool& dnssec_available, bool& dnssec_valid) -{ - return get_record(url, DNS_TYPE_TXT, txt_to_string, dnssec_available, dnssec_valid); -} - -std::string DNSResolver::get_dns_format_from_oa_address(const std::string& oa_addr) -{ - std::string addr(oa_addr); - auto first_at = addr.find("@"); - if (first_at == std::string::npos) - return addr; - - // convert name@domain.tld to name.domain.tld - addr.replace(first_at, 1, "."); - - return addr; -} - -DNSResolver& DNSResolver::instance() -{ - boost::lock_guard lock(instance_lock); - - static DNSResolver staticInstance; - return staticInstance; -} - -DNSResolver DNSResolver::create() -{ - return DNSResolver(); -} - -bool DNSResolver::check_address_syntax(const char *addr) const -{ - // if string doesn't contain a dot, we won't consider it a url for now. - if (strchr(addr,'.') == NULL) - { - return false; - } - return true; -} - -namespace dns_utils -{ - -//----------------------------------------------------------------------- -// TODO: parse the string in a less stupid way, probably with regex -std::string address_from_txt_record(const std::string& s) -{ - // make sure the txt record has "oa1:msr" and find it - auto pos = s.find("oa1:msr"); - if (pos == std::string::npos) - return {}; - // search from there to find "recipient_address=" - pos = s.find("recipient_address=", pos); - if (pos == std::string::npos) - return {}; - pos += 18; // move past "recipient_address=" - // find the next semicolon - auto pos2 = s.find(";", pos); - if (pos2 != std::string::npos) - { - // length of address == 95, we can at least validate that much here - if (pos2 - pos == 95) - { - return s.substr(pos, 95); - } - else if (pos2 - pos == 106) // length of address == 106 --> integrated address - { - return s.substr(pos, 106); - } - } - return {}; -} -/** - * @brief gets a monero address from the TXT record of a DNS entry - * - * gets the monero address from the TXT record of the DNS entry associated - * with . If this lookup fails, or the TXT record does not contain an - * XMR address in the correct format, returns an empty string. - * will be set true or false according to whether or not the DNS query passes - * DNSSEC validation. - * - * @param url the url to look up - * @param dnssec_valid return-by-reference for DNSSEC status of query - * - * @return a monero address (as a string) or an empty string - */ -std::vector addresses_from_url(const std::string& url, bool& dnssec_valid) -{ - std::vector addresses; - // get txt records - bool dnssec_available, dnssec_isvalid; - std::string oa_addr = DNSResolver::instance().get_dns_format_from_oa_address(url); - auto records = DNSResolver::instance().get_txt_record(oa_addr, dnssec_available, dnssec_isvalid); - - // TODO: update this to allow for conveying that dnssec was not available - if (dnssec_available && dnssec_isvalid) - { - dnssec_valid = true; - } - else dnssec_valid = false; - - // for each txt record, try to find a monero address in it. - for (auto& rec : records) - { - std::string addr = address_from_txt_record(rec); - if (addr.size()) - { - addresses.push_back(addr); - } - } - return addresses; -} - -std::string get_account_address_as_str_from_url(const std::string& url, bool& dnssec_valid, std::function&, bool)> dns_confirm) -{ - // attempt to get address from dns query - auto addresses = addresses_from_url(url, dnssec_valid); - if (addresses.empty()) - { - LOG_ERROR("wrong address: " << url); - return {}; - } - return dns_confirm(url, addresses, dnssec_valid); -} - -namespace -{ - bool dns_records_match(const std::vector& a, const std::vector& b) - { - if (a.size() != b.size()) return false; - - for (const auto& record_in_a : a) - { - bool ok = false; - for (const auto& record_in_b : b) - { - if (record_in_a == record_in_b) - { - ok = true; - break; - } - } - if (!ok) return false; - } - - return true; - } -} - -bool load_txt_records_from_dns(std::vector &good_records, const std::vector &dns_urls) -{ - // Prevent infinite recursion when distributing - if (dns_urls.empty()) return false; - - std::vector > records; - records.resize(dns_urls.size()); - - std::random_device rd; - std::mt19937 gen(rd()); - std::uniform_int_distribution dis(0, dns_urls.size() - 1); - size_t first_index = dis(gen); - - // send all requests in parallel - std::vector threads(dns_urls.size()); - std::deque avail(dns_urls.size(), false), valid(dns_urls.size(), false); - for (size_t n = 0; n < dns_urls.size(); ++n) - { - threads[n] = boost::thread([n, dns_urls, &records, &avail, &valid](){ - records[n] = tools::DNSResolver::instance().get_txt_record(dns_urls[n], avail[n], valid[n]); - }); - } - for (size_t n = 0; n < dns_urls.size(); ++n) - threads[n].join(); - - size_t cur_index = first_index; - do - { - const std::string &url = dns_urls[cur_index]; - if (!avail[cur_index]) - { - records[cur_index].clear(); - LOG_PRINT_L2("DNSSEC not available for checkpoint update at URL: " << url << ", skipping."); - } - if (!valid[cur_index]) - { - records[cur_index].clear(); - LOG_PRINT_L2("DNSSEC validation failed for checkpoint update at URL: " << url << ", skipping."); - } - - cur_index++; - if (cur_index == dns_urls.size()) - { - cur_index = 0; - } - } while (cur_index != first_index); - - size_t num_valid_records = 0; - - for( const auto& record_set : records) - { - if (record_set.size() != 0) - { - num_valid_records++; - } - } - - if (num_valid_records < 2) - { - LOG_PRINT_L2("WARNING: no two valid MasariPulse DNS checkpoint records were received"); - return false; - } - - int good_records_index = -1; - for (size_t i = 0; i < records.size() - 1; ++i) - { - if (records[i].size() == 0) continue; - - for (size_t j = i + 1; j < records.size(); ++j) - { - if (dns_records_match(records[i], records[j])) - { - good_records_index = i; - break; - } - } - if (good_records_index >= 0) break; - } - - if (good_records_index < 0) - { - LOG_PRINT_L2("WARNING: no two MasariPulse DNS checkpoint records matched"); - return false; - } - - good_records = records[good_records_index]; - return true; -} - -std::vector parse_dns_public(const char *s) -{ - unsigned ip0, ip1, ip2, ip3; - char c; - std::vector dns_public_addr; - if (!strcmp(s, "tcp")) - { - for (size_t i = 0; i < sizeof(DEFAULT_DNS_PUBLIC_ADDR) / sizeof(DEFAULT_DNS_PUBLIC_ADDR[0]); ++i) - dns_public_addr.push_back(DEFAULT_DNS_PUBLIC_ADDR[i]); - LOG_PRINT_L0("Using default public DNS server(s): " << boost::join(dns_public_addr, ", ") << " (TCP)"); - } - else if (sscanf(s, "tcp://%u.%u.%u.%u%c", &ip0, &ip1, &ip2, &ip3, &c) == 4) - { - if (ip0 > 255 || ip1 > 255 || ip2 > 255 || ip3 > 255) - { - MERROR("Invalid IP: " << s << ", using default"); - } - else - { - dns_public_addr.push_back(std::string(s + strlen("tcp://"))); - } - } - else - { - MERROR("Invalid DNS_PUBLIC contents, ignored"); - } - return dns_public_addr; -} - -} // namespace tools::dns_utils - -} // namespace tools diff --git a/src_native/common/dns_utils.h b/src_native/common/dns_utils.h deleted file mode 100644 index f46bca3d..00000000 --- a/src_native/common/dns_utils.h +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#pragma once - -#include -#include -#include - -namespace tools -{ - -// RFC defines for record types and classes for DNS, gleaned from ldns source -const static int DNS_CLASS_IN = 1; -const static int DNS_TYPE_A = 1; -const static int DNS_TYPE_TXT = 16; -const static int DNS_TYPE_AAAA = 8; - -struct DNSResolverData; - -/** - * @brief Provides high-level access to DNS resolution - * - * This class is designed to provide a high-level abstraction to DNS resolution - * functionality, including access to TXT records and such. It will also - * handle DNSSEC validation of the results. - */ -class DNSResolver -{ -private: - - /** - * @brief Constructs an instance of DNSResolver - * - * Constructs a class instance and does setup stuff for the backend resolver. - */ - DNSResolver(); - -public: - - /** - * @brief takes care of freeing C pointers and such - */ - ~DNSResolver(); - - /** - * @brief gets ipv4 addresses from DNS query of a URL - * - * returns a vector of all IPv4 "A" records for given URL. - * If no "A" records found, returns an empty vector. - * - * @param url A string containing a URL to query for - * - * @param dnssec_available - * - * @return vector of strings containing ipv4 addresses - */ - std::vector get_ipv4(const std::string& url, bool& dnssec_available, bool& dnssec_valid); - - /** - * @brief gets ipv6 addresses from DNS query - * - * returns a vector of all IPv6 "A" records for given URL. - * If no "A" records found, returns an empty vector. - * - * @param url A string containing a URL to query for - * - * @return vector of strings containing ipv6 addresses - */ - std::vector get_ipv6(const std::string& url, bool& dnssec_available, bool& dnssec_valid); - - /** - * @brief gets all TXT records from a DNS query for the supplied URL; - * if no TXT record present returns an empty vector. - * - * @param url A string containing a URL to query for - * - * @return A vector of strings containing a TXT record; or an empty vector - */ - // TODO: modify this to accommodate DNSSEC - std::vector get_txt_record(const std::string& url, bool& dnssec_available, bool& dnssec_valid); - - /** - * @brief Gets a DNS address from OpenAlias format - * - * If the address looks good, but contains one @ symbol, replace that with a . - * e.g. donate@getmonero.org becomes donate.getmonero.org - * - * @param oa_addr OpenAlias address - * - * @return dns_addr DNS address - */ - std::string get_dns_format_from_oa_address(const std::string& oa_addr); - - /** - * @brief Gets the singleton instance of DNSResolver - * - * @return returns a pointer to the singleton - */ - static DNSResolver& instance(); - - /** - * @brief Gets a new instance of DNSResolver - * - * @return returns a pointer to the new object - */ - static DNSResolver create(); - -private: - - /** - * @brief gets all records of a given type from a DNS query for the supplied URL; - * if no such record is present returns an empty vector. - * - * @param url A string containing a URL to query for - * @param record_type the record type to retrieve (DNS_TYPE_A, etc) - * @param reader a function that converts a record data to a string - * - * @return A vector of strings containing the requested record; or an empty vector - */ - // TODO: modify this to accommodate DNSSEC - std::vector get_record(const std::string& url, int record_type, std::string (*reader)(const char *,size_t), bool& dnssec_available, bool& dnssec_valid); - - /** - * @brief Checks a string to see if it looks like a URL - * - * @param addr the string to be checked - * - * @return true if it looks enough like a URL, false if not - */ - bool check_address_syntax(const char *addr) const; - - DNSResolverData *m_data; -}; // class DNSResolver - -namespace dns_utils -{ - -std::string address_from_txt_record(const std::string& s); -std::vector addresses_from_url(const std::string& url, bool& dnssec_valid); - -std::string get_account_address_as_str_from_url(const std::string& url, bool& dnssec_valid, std::function&, bool)> confirm_dns); - -bool load_txt_records_from_dns(std::vector &records, const std::vector &dns_urls); - -std::vector parse_dns_public(const char *s); - -} // namespace tools::dns_utils - -} // namespace tools diff --git a/src_native/common/download.cpp b/src_native/common/download.cpp deleted file mode 100644 index 6698a5ab..00000000 --- a/src_native/common/download.cpp +++ /dev/null @@ -1,313 +0,0 @@ -// Copyright (c) 2017-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include -#include -#include -#include "cryptonote_config.h" -#include "include_base_utils.h" -#include "file_io_utils.h" -#include "net/http_client.h" -#include "download.h" - -#undef MONERO_DEFAULT_LOG_CATEGORY -#define MONERO_DEFAULT_LOG_CATEGORY "net.dl" - -namespace tools -{ - struct download_thread_control - { - const std::string path; - const std::string uri; - std::function result_cb; - std::function progress_cb; - bool stop; - bool stopped; - bool success; - boost::thread thread; - boost::mutex mutex; - - download_thread_control(const std::string &path, const std::string &uri, std::function result_cb, std::function progress_cb): - path(path), uri(uri), result_cb(result_cb), progress_cb(progress_cb), stop(false), stopped(false), success(false) {} - ~download_thread_control() { if (thread.joinable()) thread.detach(); } - }; - - static void download_thread(download_async_handle control) - { - static std::atomic thread_id(0); - - MLOG_SET_THREAD_NAME("DL" + std::to_string(thread_id++)); - - struct stopped_setter - { - stopped_setter(const download_async_handle &control): control(control) {} - ~stopped_setter() { control->stopped = true; } - download_async_handle control; - } stopped_setter(control); - - try - { - boost::unique_lock lock(control->mutex); - std::ios_base::openmode mode = std::ios_base::out | std::ios_base::binary; - uint64_t existing_size = 0; - if (epee::file_io_utils::get_file_size(control->path, existing_size) && existing_size > 0) - { - MINFO("Resuming downloading " << control->uri << " to " << control->path << " from " << existing_size); - mode |= std::ios_base::app; - } - else - { - MINFO("Downloading " << control->uri << " to " << control->path); - mode |= std::ios_base::trunc; - } - std::ofstream f; - f.open(control->path, mode); - if (!f.good()) { - MERROR("Failed to open file " << control->path); - control->result_cb(control->path, control->uri, control->success); - return; - } - class download_client: public epee::net_utils::http::http_simple_client - { - public: - download_client(download_async_handle control, std::ofstream &f, uint64_t offset = 0): - control(control), f(f), content_length(-1), total(0), offset(offset) {} - virtual ~download_client() { f.close(); } - virtual bool on_header(const epee::net_utils::http::http_response_info &headers) - { - for (const auto &kv: headers.m_header_info.m_etc_fields) - MDEBUG("Header: " << kv.first << ": " << kv.second); - ssize_t length; - if (epee::string_tools::get_xtype_from_string(length, headers.m_header_info.m_content_length) && length >= 0) - { - MINFO("Content-Length: " << length); - content_length = length; - boost::filesystem::path path(control->path); - boost::filesystem::space_info si = boost::filesystem::space(path); - if (si.available < (size_t)content_length) - { - const uint64_t avail = (si.available + 1023) / 1024, needed = (content_length + 1023) / 1024; - MERROR("Not enough space to download " << needed << " kB to " << path << " (" << avail << " kB available)"); - return false; - } - } - if (offset > 0) - { - // we requested a range, so check if we're getting it, otherwise truncate - bool got_range = false; - const std::string prefix = "bytes=" + std::to_string(offset) + "-"; - for (const auto &kv: headers.m_header_info.m_etc_fields) - { - if (kv.first == "Content-Range" && strncmp(kv.second.c_str(), prefix.c_str(), prefix.size())) - { - got_range = true; - break; - } - } - if (!got_range) - { - MWARNING("We did not get the requested range, downloading from start"); - f.close(); - f.open(control->path, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc); - } - } - return true; - } - virtual bool handle_target_data(std::string &piece_of_transfer) - { - try - { - boost::lock_guard lock(control->mutex); - if (control->stop) - return false; - f << piece_of_transfer; - total += piece_of_transfer.size(); - if (control->progress_cb && !control->progress_cb(control->path, control->uri, total, content_length)) - return false; - return f.good(); - } - catch (const std::exception &e) - { - MERROR("Error writing data: " << e.what()); - return false; - } - } - private: - download_async_handle control; - std::ofstream &f; - ssize_t content_length; - size_t total; - uint64_t offset; - } client(control, f, existing_size); - epee::net_utils::http::url_content u_c; - if (!epee::net_utils::parse_url(control->uri, u_c)) - { - MERROR("Failed to parse URL " << control->uri); - control->result_cb(control->path, control->uri, control->success); - return; - } - if (u_c.host.empty()) - { - MERROR("Failed to determine address from URL " << control->uri); - control->result_cb(control->path, control->uri, control->success); - return; - } - - lock.unlock(); - - bool ssl = u_c.schema == "https"; - uint16_t port = u_c.port ? u_c.port : ssl ? 443 : 80; - MDEBUG("Connecting to " << u_c.host << ":" << port); - client.set_server(u_c.host, std::to_string(port), boost::none, ssl); - if (!client.connect(std::chrono::seconds(30))) - { - boost::lock_guard lock(control->mutex); - MERROR("Failed to connect to " << control->uri); - control->result_cb(control->path, control->uri, control->success); - return; - } - MDEBUG("GETting " << u_c.uri); - const epee::net_utils::http::http_response_info *info = NULL; - epee::net_utils::http::fields_list fields; - if (existing_size > 0) - { - const std::string range = "bytes=" + std::to_string(existing_size) + "-"; - MDEBUG("Asking for range: " << range); - fields.push_back(std::make_pair("Range", range)); - } - if (!client.invoke_get(u_c.uri, std::chrono::seconds(30), "", &info, fields)) - { - boost::lock_guard lock(control->mutex); - MERROR("Failed to connect to " << control->uri); - client.disconnect(); - control->result_cb(control->path, control->uri, control->success); - return; - } - if (control->stop) - { - boost::lock_guard lock(control->mutex); - MDEBUG("Download cancelled"); - client.disconnect(); - control->result_cb(control->path, control->uri, control->success); - return; - } - if (!info) - { - boost::lock_guard lock(control->mutex); - MERROR("Failed invoking GET command to " << control->uri << ", no status info returned"); - client.disconnect(); - control->result_cb(control->path, control->uri, control->success); - return; - } - MDEBUG("response code: " << info->m_response_code); - MDEBUG("response length: " << info->m_header_info.m_content_length); - MDEBUG("response comment: " << info->m_response_comment); - MDEBUG("response body: " << info->m_body); - for (const auto &f: info->m_additional_fields) - MDEBUG("additional field: " << f.first << ": " << f.second); - if (info->m_response_code != 200 && info->m_response_code != 206) - { - boost::lock_guard lock(control->mutex); - MERROR("Status code " << info->m_response_code); - client.disconnect(); - control->result_cb(control->path, control->uri, control->success); - return; - } - client.disconnect(); - f.close(); - MDEBUG("Download complete"); - lock.lock(); - control->success = true; - control->result_cb(control->path, control->uri, control->success); - return; - } - catch (const std::exception &e) - { - MERROR("Exception in download thread: " << e.what()); - // fall through and call result_cb not from the catch block to avoid another exception - } - boost::lock_guard lock(control->mutex); - control->result_cb(control->path, control->uri, control->success); - } - - bool download(const std::string &path, const std::string &url, std::function cb) - { - bool success = false; - download_async_handle handle = download_async(path, url, [&success](const std::string&, const std::string&, bool result) {success = result;}, cb); - download_wait(handle); - return success; - } - - download_async_handle download_async(const std::string &path, const std::string &url, std::function result, std::function progress) - { - download_async_handle control = std::make_shared(path, url, result, progress); - control->thread = boost::thread([control](){ download_thread(control); }); - return control; - } - - bool download_finished(const download_async_handle &control) - { - CHECK_AND_ASSERT_MES(control != 0, false, "NULL async download handle"); - boost::lock_guard lock(control->mutex); - return control->stopped; - } - - bool download_error(const download_async_handle &control) - { - CHECK_AND_ASSERT_MES(control != 0, false, "NULL async download handle"); - boost::lock_guard lock(control->mutex); - return !control->success; - } - - bool download_wait(const download_async_handle &control) - { - CHECK_AND_ASSERT_MES(control != 0, false, "NULL async download handle"); - { - boost::lock_guard lock(control->mutex); - if (control->stopped) - return true; - } - control->thread.join(); - return true; - } - - bool download_cancel(const download_async_handle &control) - { - CHECK_AND_ASSERT_MES(control != 0, false, "NULL async download handle"); - { - boost::lock_guard lock(control->mutex); - if (control->stopped) - return true; - control->stop = true; - } - control->thread.join(); - return true; - } -} diff --git a/src_native/common/download.h b/src_native/common/download.h deleted file mode 100644 index 3097394b..00000000 --- a/src_native/common/download.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (c) 2017-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#pragma once - -#include - -namespace tools -{ - struct download_thread_control; - typedef std::shared_ptr download_async_handle; - - bool download(const std::string &path, const std::string &url, std::function progress = NULL); - download_async_handle download_async(const std::string &path, const std::string &url, std::function result, std::function progress = NULL); - bool download_error(const download_async_handle &h); - bool download_finished(const download_async_handle &h); - bool download_wait(const download_async_handle &h); - bool download_cancel(const download_async_handle &h); -} diff --git a/src_native/common/http_connection.h b/src_native/common/http_connection.h deleted file mode 100644 index 9fc6be26..00000000 --- a/src_native/common/http_connection.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#pragma once - -#include -#include "string_tools.h" -#include "net/http_client.h" - -namespace tools { - -class t_http_connection { -private: - epee::net_utils::http::http_simple_client * mp_http_client; - bool m_ok; -public: - static constexpr std::chrono::seconds TIMEOUT() - { - return std::chrono::minutes(3) + std::chrono::seconds(30); - } - - t_http_connection(epee::net_utils::http::http_simple_client* p_http_client) - : mp_http_client(p_http_client) - , m_ok(false) - { - m_ok = mp_http_client->connect(TIMEOUT()); - } - - ~t_http_connection() - { - if (m_ok) - { - mp_http_client->disconnect(); - } - } - - bool is_open() const - { - return m_ok; - } -}; // class t_http_connection - -} // namespace tools diff --git a/src_native/common/i18n.cpp b/src_native/common/i18n.cpp deleted file mode 100644 index 4a89876f..00000000 --- a/src_native/common/i18n.cpp +++ /dev/null @@ -1,318 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include -#include -#include -#include -#include "include_base_utils.h" -#include "file_io_utils.h" -#include "common/util.h" -#include "common/i18n.h" -#include "translation_files.h" - -#undef MONERO_DEFAULT_LOG_CATEGORY -#define MONERO_DEFAULT_LOG_CATEGORY "i18n" - -static const unsigned char qm_magic[16] = {0x3c, 0xb8, 0x64, 0x18, 0xca, 0xef, 0x9c, 0x95, 0xcd, 0x21, 0x1c, 0xbf, 0x60, 0xa1, 0xbd, 0xdd}; - -static std::map i18n_entries; - -/* Logging isn't initialized yet when this is run */ -/* add std::flush, because std::endl doesn't seem to flush, contrary to expected */ -// #define i18n_log(x) do { std::cout << __FILE__ << ":" << __LINE__ << ": " << x << std::endl; std::cout << std::flush; } while(0) -#define i18n_log(x) ((void)0) - -std::string i18n_get_language() -{ - const char *e; - - e = getenv("LANG"); - i18n_log("LANG=" << e); - if (!e || !*e) { - e = getenv("LC_ALL"); - i18n_log("LC_ALL=" << e); - } - if (!e || !*e) - e = "en"; - - std::string language = e; - language = language.substr(0, language.find(".")); - std::transform(language.begin(), language.end(), language.begin(), tolower); - return language; -} - -static uint32_t be32(const unsigned char *data) -{ - return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; -} - -static std::string utf16(const unsigned char *data, uint32_t len) -{ - std::string s; - while (len >= 2) { - uint32_t code = (data[0] << 8) | data[1]; - data += 2; - len -= 2; - if (code >= 0xd800 && code <= 0xdbfff && len >= 2) { - uint32_t next = (data[0] << 8) | data[1]; - if (next >= 0xdc00 && next <= 0xdfff) { - code = (code << 10) + next - 0x35dfc00; - data += 2; - len -= 2; - } - } - if (code <= 0x7f) { - s += (char)code; - } - else if (code <= 0x7ff) { - s += 0xc0 | (code >> 6); - s += 0x80 | (code & 0x3f); - } - else if (code <= 0xffff) { - s += 0xe0 | (code >> 12); - s += 0x80 | ((code >> 6) & 0x3f); - s += 0x80 | (code & 0x3f); - } - else { - s += 0xf0 | (code >> 18); - s += 0x80 | ((code >> 12) & 0x3f); - s += 0x80 | ((code >> 6) & 0x3f); - s += 0x80 | (code & 0x3f); - } - } - return s; -} - -static std::string utf8(const unsigned char *data, uint32_t len) -{ - /* assume well formedness */ - return std::string((const char *)data,len); -} - -int i18n_set_language(const char *directory, const char *base, std::string language) -{ - std::string filename, contents; - const unsigned char *data; - size_t datalen; - size_t idx; - unsigned char chunk_type; - uint32_t chunk_size; - uint32_t num_messages = (uint32_t)-1; - uint32_t messages_idx = (uint32_t)-1; - uint32_t offsets_idx = (uint32_t)-1; - std::string translation, source, context; - - i18n_log("i18n_set_language(" << directory << "," << base << ")"); - if (!directory || !base) - return -1; - - if (language.empty()) - language = i18n_get_language(); - filename = std::string(directory) + "/" + base + "_" + language + ".qm"; - i18n_log("Loading translations for language " << language); - - boost::system::error_code ignored_ec; - if (boost::filesystem::exists(filename, ignored_ec)) { - if (!epee::file_io_utils::load_file_to_string(filename, contents)) { - i18n_log("Failed to load translations file: " << filename); - return -1; - } - } else { - i18n_log("Translations file not found: " << filename); - filename = std::string(base) + "_" + language + ".qm"; - if (!find_embedded_file(filename, contents)) { - i18n_log("Embedded translations file not found: " << filename); - const char *underscore = strchr(language.c_str(), '_'); - if (underscore) { - std::string fallback_language = std::string(language, 0, underscore - language.c_str()); - filename = std::string(directory) + "/" + base + "_" + fallback_language + ".qm"; - i18n_log("Loading translations for language " << fallback_language); - if (boost::filesystem::exists(filename, ignored_ec)) { - if (!epee::file_io_utils::load_file_to_string(filename, contents)) { - i18n_log("Failed to load translations file: " << filename); - return -1; - } - } else { - i18n_log("Translations file not found: " << filename); - filename = std::string(base) + "_" + fallback_language + ".qm"; - if (!find_embedded_file(filename, contents)) { - i18n_log("Embedded translations file not found: " << filename); - return -1; - } - } - } else { - return -1; - } - } - } - - data = (const unsigned char*)contents.c_str(); - datalen = contents.size(); - idx = 0; - i18n_log("Translations file size: " << datalen); - - /* Format of the QM file (AFAICT): - * 16 bytes magic - * chunk list: N instances of chunks: - * 1 byte: chunk type (0x42: offsets, 0x69: messages) - * 4 bytes: chunk length, big endian - * D bytes: "chunk length" bytes of data - * - * 0x42 chunk: N instances of subchunks: - * 1 byte: subchunk type - * 0x01: end, no data - * 0x02: unsupported - * 0x03: translation - * 4 bytes: string length, big endian - * N bytes: string data, UTF-16 (or UCS2-BE ?) - * 0x04: unsupported - * 0x05: obsolete, unsupported - * 0x06: source text - * 0x07: context - * 0x08: obsolete, unsupported - * other: unsupported - * 4 bytes: subchunk length, big endian - except for 0x01, which has none - * S bytes: "chunk length" bytes of data - * 0x69 chunk: - * string data indexed by the 0x42 chunk data - */ - if (datalen < sizeof(qm_magic) || memcmp(data, qm_magic, sizeof(qm_magic))) { - i18n_log("Bad translations file format: " << filename); - return -1; - } - idx += sizeof(qm_magic); - - while (idx < datalen) { - if (idx + 5 > datalen) { - i18n_log("Bad translations file format: " << filename); - return -1; - } - chunk_type = data[idx++]; - chunk_size = be32(data+idx); - idx += 4; - - i18n_log("Found " << chunk_type << " of " << chunk_size << " bytes"); - if (chunk_size >= datalen || idx > datalen - chunk_size) { - i18n_log("Bad translations file format: " << filename); - return -1; - } - - switch (chunk_type) { - case 0x42: - i18n_log("Found offsets at " << idx); - /* two 32 bit integers, and possible padding */ - offsets_idx = idx; - num_messages = chunk_size / 8; - break; - case 0x69: - i18n_log("Found messages at " << idx); - messages_idx = idx; - break; - default: - i18n_log("Found unsupported chunk type: " << chunk_type); - break; - } - - idx += chunk_size; - } - - if (offsets_idx == (uint32_t)-1) { - i18n_log("No offsets chunk found"); - return -1; - } - if (messages_idx == (uint32_t)-1) { - i18n_log("No messages chunk found"); - return -1; - } - - for (uint32_t m = 0; m < num_messages; ++m) { - be32(data+offsets_idx+m*8); // unused - idx = be32(data+offsets_idx+m*8+4); - idx += messages_idx; - - if (idx > datalen || idx + 1 > datalen) { - i18n_log("Bad translations file format: " << filename); - return -1; - } - - while (1) { - if (idx + 5 > datalen) { - i18n_log("Bad translations file format: " << filename); - return -1; - } - chunk_type = data[idx++]; - chunk_size = 0; - if (chunk_type == 0x01) { - i18n_entries[context + std::string("",1) + source] = translation; - context = std::string(); - source = std::string(); - translation = std::string(); - break; - } - - chunk_size = be32(data+idx); - idx += 4; - i18n_log("Found " << chunk_type << " of " << chunk_size << " bytes"); - if (chunk_size >= datalen || idx > datalen - chunk_size) { - i18n_log("Bad translations file format: " << filename); - return -1; - } - switch (chunk_type) { - case 0x03: // translation, UTF-16 - translation = utf16(data+idx, chunk_size); - i18n_log("Found translation: " << translation); - break; - case 0x06: // source, UTF-8 - source = utf8(data+idx, chunk_size); - i18n_log("Found source: " << source); - break; - case 0x07: // context, UTF-8 - context = utf8(data+idx, chunk_size); - i18n_log("Found context: " << context); - break; - } - idx += chunk_size; - } - } - - return 0; -} - -/* The entries is constant by that time */ -const char *i18n_translate(const char *s, const std::string &context) -{ - const std::string key = context + std::string("", 1) + s; - std::map::const_iterator i = i18n_entries.find(key); - if (i == i18n_entries.end()) - return s; - return (*i).second.c_str(); -} - - diff --git a/src_native/common/i18n.h b/src_native/common/i18n.h deleted file mode 100644 index d21d0027..00000000 --- a/src_native/common/i18n.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#pragma once - -#define QT_TRANSLATE_NOOP(context,str) i18n_translate(str,context) - -std::string i18n_get_language(); -int i18n_set_language(const char *directory, const char *base, std::string language = std::string()); -const char *i18n_translate(const char *str, const std::string &context); -static inline std::string get_default_i18n_context() { return std::string(); } -static inline const char *tr(const char *str) { return i18n_translate(str,get_default_i18n_context()); } diff --git a/src_native/common/int-util.h b/src_native/common/int-util.h deleted file mode 100644 index 3bcc085e..00000000 --- a/src_native/common/int-util.h +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once - -#include -#include -#include -#include - -#ifndef _MSC_VER -#include -#endif - -#if defined(__ANDROID__) -#include -#endif - -#if defined(__sun) && defined(__SVR4) -#include -#endif - -#if defined(_MSC_VER) -#include - -static inline uint32_t rol32(uint32_t x, int r) { - static_assert(sizeof(uint32_t) == sizeof(unsigned int), "this code assumes 32-bit integers"); - return _rotl(x, r); -} - -static inline uint64_t rol64(uint64_t x, int r) { - return _rotl64(x, r); -} - -#else - -static inline uint32_t rol32(uint32_t x, int r) { - return (x << (r & 31)) | (x >> (-r & 31)); -} - -static inline uint64_t rol64(uint64_t x, int r) { - return (x << (r & 63)) | (x >> (-r & 63)); -} - -#endif - -static inline uint64_t hi_dword(uint64_t val) { - return val >> 32; -} - -static inline uint64_t lo_dword(uint64_t val) { - return val & 0xFFFFFFFF; -} - -static inline uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, uint64_t* product_hi) { - // multiplier = ab = a * 2^32 + b - // multiplicand = cd = c * 2^32 + d - // ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d - uint64_t a = hi_dword(multiplier); - uint64_t b = lo_dword(multiplier); - uint64_t c = hi_dword(multiplicand); - uint64_t d = lo_dword(multiplicand); - - uint64_t ac = a * c; - uint64_t ad = a * d; - uint64_t bc = b * c; - uint64_t bd = b * d; - - uint64_t adbc = ad + bc; - uint64_t adbc_carry = adbc < ad ? 1 : 0; - - // multiplier * multiplicand = product_hi * 2^64 + product_lo - uint64_t product_lo = bd + (adbc << 32); - uint64_t product_lo_carry = product_lo < bd ? 1 : 0; - *product_hi = ac + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry; - assert(ac <= *product_hi); - - return product_lo; -} - -static inline uint64_t div_with_reminder(uint64_t dividend, uint32_t divisor, uint32_t* remainder) { - dividend |= ((uint64_t)*remainder) << 32; - *remainder = dividend % divisor; - return dividend / divisor; -} - -// Long division with 2^32 base -static inline uint32_t div128_32(uint64_t dividend_hi, uint64_t dividend_lo, uint32_t divisor, uint64_t* quotient_hi, uint64_t* quotient_lo) { - uint64_t dividend_dwords[4]; - uint32_t remainder = 0; - - dividend_dwords[3] = hi_dword(dividend_hi); - dividend_dwords[2] = lo_dword(dividend_hi); - dividend_dwords[1] = hi_dword(dividend_lo); - dividend_dwords[0] = lo_dword(dividend_lo); - - *quotient_hi = div_with_reminder(dividend_dwords[3], divisor, &remainder) << 32; - *quotient_hi |= div_with_reminder(dividend_dwords[2], divisor, &remainder); - *quotient_lo = div_with_reminder(dividend_dwords[1], divisor, &remainder) << 32; - *quotient_lo |= div_with_reminder(dividend_dwords[0], divisor, &remainder); - - return remainder; -} - -#define IDENT32(x) ((uint32_t) (x)) -#define IDENT64(x) ((uint64_t) (x)) - -#define SWAP32(x) ((((uint32_t) (x) & 0x000000ff) << 24) | \ - (((uint32_t) (x) & 0x0000ff00) << 8) | \ - (((uint32_t) (x) & 0x00ff0000) >> 8) | \ - (((uint32_t) (x) & 0xff000000) >> 24)) -#define SWAP64(x) ((((uint64_t) (x) & 0x00000000000000ff) << 56) | \ - (((uint64_t) (x) & 0x000000000000ff00) << 40) | \ - (((uint64_t) (x) & 0x0000000000ff0000) << 24) | \ - (((uint64_t) (x) & 0x00000000ff000000) << 8) | \ - (((uint64_t) (x) & 0x000000ff00000000) >> 8) | \ - (((uint64_t) (x) & 0x0000ff0000000000) >> 24) | \ - (((uint64_t) (x) & 0x00ff000000000000) >> 40) | \ - (((uint64_t) (x) & 0xff00000000000000) >> 56)) - -static inline uint32_t ident32(uint32_t x) { return x; } -static inline uint64_t ident64(uint64_t x) { return x; } - -#ifndef __OpenBSD__ -# if defined(__ANDROID__) && defined(__swap32) && !defined(swap32) -# define swap32 __swap32 -# elif !defined(swap32) -static inline uint32_t swap32(uint32_t x) { - x = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8); - return (x << 16) | (x >> 16); -} -# endif -# if defined(__ANDROID__) && defined(__swap64) && !defined(swap64) -# define swap64 __swap64 -# elif !defined(swap64) -static inline uint64_t swap64(uint64_t x) { - x = ((x & 0x00ff00ff00ff00ff) << 8) | ((x & 0xff00ff00ff00ff00) >> 8); - x = ((x & 0x0000ffff0000ffff) << 16) | ((x & 0xffff0000ffff0000) >> 16); - return (x << 32) | (x >> 32); -} -# endif -#endif /* __OpenBSD__ */ - -#if defined(__GNUC__) -#define UNUSED __attribute__((unused)) -#else -#define UNUSED -#endif -static inline void mem_inplace_ident(void *mem UNUSED, size_t n UNUSED) { } -#undef UNUSED - -static inline void mem_inplace_swap32(void *mem, size_t n) { - size_t i; - for (i = 0; i < n; i++) { - ((uint32_t *) mem)[i] = swap32(((const uint32_t *) mem)[i]); - } -} -static inline void mem_inplace_swap64(void *mem, size_t n) { - size_t i; - for (i = 0; i < n; i++) { - ((uint64_t *) mem)[i] = swap64(((const uint64_t *) mem)[i]); - } -} - -static inline void memcpy_ident32(void *dst, const void *src, size_t n) { - memcpy(dst, src, 4 * n); -} -static inline void memcpy_ident64(void *dst, const void *src, size_t n) { - memcpy(dst, src, 8 * n); -} - -static inline void memcpy_swap32(void *dst, const void *src, size_t n) { - size_t i; - for (i = 0; i < n; i++) { - ((uint32_t *) dst)[i] = swap32(((const uint32_t *) src)[i]); - } -} -static inline void memcpy_swap64(void *dst, const void *src, size_t n) { - size_t i; - for (i = 0; i < n; i++) { - ((uint64_t *) dst)[i] = swap64(((const uint64_t *) src)[i]); - } -} - -#ifdef _MSC_VER -# define LITTLE_ENDIAN 1234 -# define BIG_ENDIAN 4321 -# define BYTE_ORDER LITTLE_ENDIAN -#endif - -#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || !defined(BIG_ENDIAN) -static_assert(false, "BYTE_ORDER is undefined. Perhaps, GNU extensions are not enabled"); -#endif - -#if BYTE_ORDER == LITTLE_ENDIAN -#define SWAP32LE IDENT32 -#define SWAP32BE SWAP32 -#define swap32le ident32 -#define swap32be swap32 -#define mem_inplace_swap32le mem_inplace_ident -#define mem_inplace_swap32be mem_inplace_swap32 -#define memcpy_swap32le memcpy_ident32 -#define memcpy_swap32be memcpy_swap32 -#define SWAP64LE IDENT64 -#define SWAP64BE SWAP64 -#define swap64le ident64 -#define swap64be swap64 -#define mem_inplace_swap64le mem_inplace_ident -#define mem_inplace_swap64be mem_inplace_swap64 -#define memcpy_swap64le memcpy_ident64 -#define memcpy_swap64be memcpy_swap64 -#endif - -#if BYTE_ORDER == BIG_ENDIAN -#define SWAP32BE IDENT32 -#define SWAP32LE SWAP32 -#define swap32be ident32 -#define swap32le swap32 -#define mem_inplace_swap32be mem_inplace_ident -#define mem_inplace_swap32le mem_inplace_swap32 -#define memcpy_swap32be memcpy_ident32 -#define memcpy_swap32le memcpy_swap32 -#define SWAP64BE IDENT64 -#define SWAP64LE SWAP64 -#define swap64be ident64 -#define swap64le swap64 -#define mem_inplace_swap64be mem_inplace_ident -#define mem_inplace_swap64le mem_inplace_swap64 -#define memcpy_swap64be memcpy_ident64 -#define memcpy_swap64le memcpy_swap64 -#endif diff --git a/src_native/common/json_util.h b/src_native/common/json_util.h deleted file mode 100644 index 661022a6..00000000 --- a/src_native/common/json_util.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2016-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#pragma once - -#define GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, name, type, jtype, mandatory, def) \ - type field_##name = def; \ - bool field_##name##_found = false; \ - (void)field_##name##_found; \ - do if (json.HasMember(#name)) \ - { \ - if (json[#name].Is##jtype()) \ - { \ - field_##name = json[#name].Get##jtype(); \ - field_##name##_found = true; \ - } \ - else \ - { \ - LOG_ERROR("Field " << #name << " found in JSON, but not " << #jtype); \ - return false; \ - } \ - } \ - else if (mandatory) \ - { \ - LOG_ERROR("Field " << #name << " not found in JSON"); \ - return false; \ - } while(0) - diff --git a/src_native/common/password.cpp b/src_native/common/password.cpp deleted file mode 100644 index 9336a14f..00000000 --- a/src_native/common/password.cpp +++ /dev/null @@ -1,269 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#include "password.h" - -#include -#include -#include - -#if defined(_WIN32) -#include -#include -#else -#include -#include -#endif - -#include "memwipe.h" - -#define EOT 0x4 - -namespace -{ -#if defined(_WIN32) - bool is_cin_tty() noexcept - { - return 0 != _isatty(_fileno(stdin)); - } - - bool read_from_tty(epee::wipeable_string& pass) - { - static constexpr const char BACKSPACE = 8; - - HANDLE h_cin = ::GetStdHandle(STD_INPUT_HANDLE); - - DWORD mode_old; - ::GetConsoleMode(h_cin, &mode_old); - DWORD mode_new = mode_old & ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT); - ::SetConsoleMode(h_cin, mode_new); - - bool r = true; - pass.reserve(tools::password_container::max_password_size); - while (pass.size() < tools::password_container::max_password_size) - { - DWORD read; - char ch; - r = (TRUE == ::ReadConsoleA(h_cin, &ch, 1, &read, NULL)); - r &= (1 == read); - if (!r) - { - break; - } - else if (ch == '\n' || ch == '\r') - { - std::cout << std::endl; - break; - } - else if (ch == BACKSPACE) - { - if (!pass.empty()) - { - pass.pop_back(); - } - } - else - { - pass.push_back(ch); - } - } - - ::SetConsoleMode(h_cin, mode_old); - - return r; - } - -#else // end WIN32 - - bool is_cin_tty() noexcept - { - return 0 != isatty(fileno(stdin)); - } - - int getch() noexcept - { - struct termios tty_old; - tcgetattr(STDIN_FILENO, &tty_old); - - struct termios tty_new; - tty_new = tty_old; - tty_new.c_lflag &= ~(ICANON | ECHO); - tcsetattr(STDIN_FILENO, TCSANOW, &tty_new); - - int ch = getchar(); - - tcsetattr(STDIN_FILENO, TCSANOW, &tty_old); - - return ch; - } - - bool read_from_tty(epee::wipeable_string& aPass) - { - static constexpr const char BACKSPACE = 127; - - aPass.reserve(tools::password_container::max_password_size); - while (aPass.size() < tools::password_container::max_password_size) - { - int ch = getch(); - if (EOF == ch || ch == EOT) - { - return false; - } - else if (ch == '\n' || ch == '\r') - { - std::cout << std::endl; - break; - } - else if (ch == BACKSPACE) - { - if (!aPass.empty()) - { - aPass.pop_back(); - } - } - else - { - aPass.push_back(ch); - } - } - - return true; - } - -#endif // end !WIN32 - - bool read_from_tty(const bool verify, const char *message, epee::wipeable_string& pass1, epee::wipeable_string& pass2) - { - while (true) - { - if (message) - std::cout << message <<": "; - if (!read_from_tty(pass1)) - return false; - if (verify) - { - std::cout << "Confirm password: "; - if (!read_from_tty(pass2)) - return false; - if(pass1!=pass2) - { - std::cout << "Passwords do not match! Please try again." << std::endl; - pass1.clear(); - pass2.clear(); - } - else //new password matches - return true; - } - else - return true; - //No need to verify password entered at this point in the code - } - - return false; - } - - bool read_from_file(epee::wipeable_string& pass) - { - pass.reserve(tools::password_container::max_password_size); - for (size_t i = 0; i < tools::password_container::max_password_size; ++i) - { - char ch = static_cast(std::cin.get()); - if (std::cin.eof() || ch == '\n' || ch == '\r') - { - break; - } - else if (std::cin.fail()) - { - return false; - } - else - { - pass.push_back(ch); - } - } - return true; - } - -} // anonymous namespace - -namespace tools -{ - // deleted via private member - password_container::password_container() noexcept : m_password() {} - password_container::password_container(std::string&& password) noexcept - : m_password(std::move(password)) - { - } - - password_container::~password_container() noexcept - { - m_password.clear(); - } - - std::atomic password_container::is_prompting(false); - - boost::optional password_container::prompt(const bool verify, const char *message) - { - is_prompting = true; - password_container pass1{}; - password_container pass2{}; - if (is_cin_tty() ? read_from_tty(verify, message, pass1.m_password, pass2.m_password) : read_from_file(pass1.m_password)) - { - is_prompting = false; - return {std::move(pass1)}; - } - - is_prompting = false; - return boost::none; - } - - boost::optional login::parse(std::string&& userpass, bool verify, const std::function(bool)> &prompt) - { - login out{}; - - const auto loc = userpass.find(':'); - if (loc == std::string::npos) - { - auto result = prompt(verify); - if (!result) - return boost::none; - - out.password = std::move(*result); - } - else - { - out.password = password_container{userpass.substr(loc + 1)}; - } - - out.username = userpass.substr(0, loc); - password_container wipe{std::move(userpass)}; - return {std::move(out)}; - } -} diff --git a/src_native/common/password.h b/src_native/common/password.h deleted file mode 100644 index 61937b93..00000000 --- a/src_native/common/password.h +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once - -#include -#include -#include -#include "wipeable_string.h" - -namespace tools -{ - class password_container - { - public: - static constexpr const size_t max_password_size = 1024; - - //! Empty password - password_container() noexcept; - - //! `password` is used as password - password_container(std::string&& password) noexcept; - - //! \return A password from stdin TTY prompt or `std::cin` pipe. - static boost::optional prompt(bool verify, const char *mesage = "Password"); - static std::atomic is_prompting; - - password_container(const password_container&) = delete; - password_container(password_container&& rhs) = default; - - //! Wipes internal password - ~password_container() noexcept; - - password_container& operator=(const password_container&) = delete; - password_container& operator=(password_container&&) = default; - - const epee::wipeable_string &password() const noexcept { return m_password; } - - private: - epee::wipeable_string m_password; - }; - - struct login - { - login() = default; - - /*! - Extracts username and password from the format `username:password`. A - blank username or password is allowed. If the `:` character is not - present, `password_container::prompt` will be called by forwarding the - `verify` and `message` arguments. - - \param userpass Is "consumed", and the memory contents are wiped. - \param verify is passed to `password_container::prompt` if necessary. - \param message is passed to `password_container::prompt` if necessary. - - \return The username and password, or boost::none if - `password_container::prompt` fails. - */ - static boost::optional parse(std::string&& userpass, bool verify, const std::function(bool)> &prompt); - - login(const login&) = delete; - login(login&&) = default; - ~login() = default; - login& operator=(const login&) = delete; - login& operator=(login&&) = default; - - std::string username; - password_container password; - }; -} diff --git a/src_native/common/perf_timer.cpp b/src_native/common/perf_timer.cpp deleted file mode 100644 index 16abdfd9..00000000 --- a/src_native/common/perf_timer.cpp +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright (c) 2016-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include "misc_os_dependent.h" -#include "perf_timer.h" - -#undef MONERO_DEFAULT_LOG_CATEGORY -#define MONERO_DEFAULT_LOG_CATEGORY "perf" - -namespace -{ - uint64_t get_tick_count() - { -#if defined(__x86_64__) - uint32_t hi, lo; - __asm__ volatile("rdtsc" : "=a"(lo), "=d"(hi)); - return (((uint64_t)hi) << 32) | (uint64_t)lo; -#else - return epee::misc_utils::get_ns_count(); -#endif - } - -#ifdef __x86_64__ - uint64_t get_ticks_per_ns() - { - uint64_t t0 = epee::misc_utils::get_ns_count(), t1; - uint64_t r0 = get_tick_count(); - - while (1) - { - t1 = epee::misc_utils::get_ns_count(); - if (t1 - t0 > 1*1000000000) break; // work one second - } - - uint64_t r1 = get_tick_count(); - uint64_t tpns256 = 256 * (r1 - r0) / (t1 - t0); - return tpns256 ? tpns256 : 1; - } -#endif - -#ifdef __x86_64__ - uint64_t ticks_per_ns = get_ticks_per_ns(); -#endif - - uint64_t ticks_to_ns(uint64_t ticks) - { -#if defined(__x86_64__) - return 256 * ticks / ticks_per_ns; -#else - return ticks; -#endif - } -} - -namespace tools -{ - -el::Level performance_timer_log_level = el::Level::Debug; - -static __thread std::vector *performance_timers = NULL; - -void set_performance_timer_log_level(el::Level level) -{ - if (level != el::Level::Debug && level != el::Level::Trace && level != el::Level::Info - && level != el::Level::Warning && level != el::Level::Error && level != el::Level::Fatal) - { - MERROR("Wrong log level: " << el::LevelHelper::convertToString(level) << ", using Debug"); - level = el::Level::Debug; - } - performance_timer_log_level = level; -} - -PerformanceTimer::PerformanceTimer(const std::string &s, uint64_t unit, el::Level l): name(s), unit(unit), level(l), started(false), paused(false) -{ - ticks = get_tick_count(); - if (!performance_timers) - { - MLOG(level, "PERF ----------"); - performance_timers = new std::vector(); - } - else - { - PerformanceTimer *pt = performance_timers->back(); - if (!pt->started && !pt->paused) - { - size_t size = 0; for (const auto *tmp: *performance_timers) if (!tmp->paused) ++size; - MLOG(pt->level, "PERF " << std::string((size-1) * 2, ' ') << " " << pt->name); - pt->started = true; - } - } - performance_timers->push_back(this); -} - -PerformanceTimer::~PerformanceTimer() -{ - performance_timers->pop_back(); - if (!paused) - ticks = get_tick_count() - ticks; - char s[12]; - snprintf(s, sizeof(s), "%8llu ", (unsigned long long)(ticks_to_ns(ticks) / (1000000000 / unit))); - size_t size = 0; for (const auto *tmp: *performance_timers) if (!tmp->paused || tmp==this) ++size; - MLOG(level, "PERF " << s << std::string(size * 2, ' ') << " " << name); - if (performance_timers->empty()) - { - delete performance_timers; - performance_timers = NULL; - } -} - -void PerformanceTimer::pause() -{ - if (paused) - return; - ticks = get_tick_count() - ticks; - paused = true; -} - -void PerformanceTimer::resume() -{ - if (!paused) - return; - ticks = get_tick_count() - ticks; - paused = false; -} - -} diff --git a/src_native/common/perf_timer.h b/src_native/common/perf_timer.h deleted file mode 100644 index 0e910caf..00000000 --- a/src_native/common/perf_timer.h +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2016-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#pragma once - -#include -#include -#include -#include "misc_log_ex.h" - -#undef MONERO_DEFAULT_LOG_CATEGORY -#define MONERO_DEFAULT_LOG_CATEGORY "perf" - -namespace tools -{ - -class PerformanceTimer; - -extern el::Level performance_timer_log_level; - -class PerformanceTimer -{ -public: - PerformanceTimer(const std::string &s, uint64_t unit, el::Level l = el::Level::Debug); - ~PerformanceTimer(); - void pause(); - void resume(); - -private: - std::string name; - uint64_t unit; - el::Level level; - uint64_t ticks; - bool started; - bool paused; -}; - -void set_performance_timer_log_level(el::Level level); - -#define PERF_TIMER_UNIT(name, unit) tools::PerformanceTimer pt_##name(#name, unit, tools::performance_timer_log_level) -#define PERF_TIMER_UNIT_L(name, unit, l) tools::PerformanceTimer pt_##name(#name, unit, l) -#define PERF_TIMER(name) PERF_TIMER_UNIT(name, 1000) -#define PERF_TIMER_L(name, l) PERF_TIMER_UNIT_L(name, 1000, l) -#define PERF_TIMER_START_UNIT(name, unit) std::unique_ptr pt_##name(new tools::PerformanceTimer(#name, unit, el::Level::Info)) -#define PERF_TIMER_START(name) PERF_TIMER_START_UNIT(name, 1000) -#define PERF_TIMER_STOP(name) do { pt_##name.reset(NULL); } while(0) -#define PERF_TIMER_PAUSE(name) pt_##name->pause() -#define PERF_TIMER_RESUME(name) pt_##name->resume() - -} diff --git a/src_native/common/pod-class.h b/src_native/common/pod-class.h deleted file mode 100644 index 5f6709ee..00000000 --- a/src_native/common/pod-class.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once - -// FIXME: Why is this ifdef needed? Hopefully making it struct won't break things. - -/* -#if defined(_MSC_VER) -#define POD_CLASS struct -#else -#define POD_CLASS class -#endif -*/ - -#define POD_CLASS struct diff --git a/src_native/common/rpc_client.h b/src_native/common/rpc_client.h deleted file mode 100644 index 9665966a..00000000 --- a/src_native/common/rpc_client.h +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#pragma once - -#include - -#include "common/http_connection.h" -#include "common/scoped_message_writer.h" -#include "rpc/core_rpc_server_commands_defs.h" -#include "storages/http_abstract_invoke.h" -#include "net/http_auth.h" -#include "net/http_client.h" -#include "string_tools.h" - -namespace tools -{ - class t_rpc_client final - { - private: - epee::net_utils::http::http_simple_client m_http_client; - public: - t_rpc_client( - uint32_t ip - , uint16_t port - , boost::optional user - ) - : m_http_client{} - { - m_http_client.set_server( - epee::string_tools::get_ip_string_from_int32(ip), std::to_string(port), std::move(user) - ); - } - - template - bool basic_json_rpc_request( - T_req & req - , T_res & res - , std::string const & method_name - ) - { - t_http_connection connection(&m_http_client); - - bool ok = connection.is_open(); - if (!ok) - { - fail_msg_writer() << "Couldn't connect to daemon: " << m_http_client.get_host() << ":" << m_http_client.get_port(); - return false; - } - ok = epee::net_utils::invoke_http_json_rpc("/json_rpc", method_name, req, res, m_http_client, t_http_connection::TIMEOUT()); - if (!ok) - { - fail_msg_writer() << "basic_json_rpc_request: Daemon request failed"; - return false; - } - else - { - return true; - } - } - - template - bool json_rpc_request( - T_req & req - , T_res & res - , std::string const & method_name - , std::string const & fail_msg - ) - { - t_http_connection connection(&m_http_client); - - bool ok = connection.is_open(); - if (!ok) - { - fail_msg_writer() << "Couldn't connect to daemon: " << m_http_client.get_host() << ":" << m_http_client.get_port(); - return false; - } - ok = epee::net_utils::invoke_http_json_rpc("/json_rpc", method_name, req, res, m_http_client, t_http_connection::TIMEOUT()); - if (!ok || res.status != CORE_RPC_STATUS_OK) // TODO - handle CORE_RPC_STATUS_BUSY ? - { - fail_msg_writer() << fail_msg << " -- json_rpc_request: " << res.status; - return false; - } - else - { - return true; - } - } - - template - bool rpc_request( - T_req & req - , T_res & res - , std::string const & relative_url - , std::string const & fail_msg - ) - { - t_http_connection connection(&m_http_client); - - bool ok = connection.is_open(); - if (!ok) - { - fail_msg_writer() << "Couldn't connect to daemon: " << m_http_client.get_host() << ":" << m_http_client.get_port(); - return false; - } - ok = epee::net_utils::invoke_http_json(relative_url, req, res, m_http_client, t_http_connection::TIMEOUT()); - if (!ok || res.status != CORE_RPC_STATUS_OK) // TODO - handle CORE_RPC_STATUS_BUSY ? - { - fail_msg_writer() << fail_msg << "-- rpc_request: " << res.status; - return false; - } - else - { - return true; - } - } - - bool check_connection() - { - t_http_connection connection(&m_http_client); - return connection.is_open(); - } - }; -} diff --git a/src_native/common/scoped_message_writer.h b/src_native/common/scoped_message_writer.h deleted file mode 100644 index d7517bab..00000000 --- a/src_native/common/scoped_message_writer.h +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#pragma once - -#include "misc_log_ex.h" -#include - -#ifdef HAVE_READLINE - #include "readline_buffer.h" - #define PAUSE_READLINE() \ - rdln::suspend_readline pause_readline; -#else - #define PAUSE_READLINE() -#endif - -namespace tools -{ - -/************************************************************************/ -/* */ -/************************************************************************/ -class scoped_message_writer -{ -private: - bool m_flush; - std::stringstream m_oss; - epee::console_colors m_color; - bool m_bright; - el::Level m_log_level; -public: - scoped_message_writer( - epee::console_colors color = epee::console_color_default - , bool bright = false - , std::string&& prefix = std::string() - , el::Level log_level = el::Level::Info - ) - : m_flush(true) - , m_color(color) - , m_bright(bright) - , m_log_level(log_level) - { - m_oss << prefix; - } - - scoped_message_writer(scoped_message_writer&& rhs) - : m_flush(std::move(rhs.m_flush)) -#if defined(_MSC_VER) - , m_oss(std::move(rhs.m_oss)) -#else - // GCC bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54316 - , m_oss(rhs.m_oss.str(), std::ios_base::out | std::ios_base::ate) -#endif - , m_color(std::move(rhs.m_color)) - , m_log_level(std::move(rhs.m_log_level)) - { - rhs.m_flush = false; - } - - scoped_message_writer(scoped_message_writer& rhs) = delete; - scoped_message_writer& operator=(scoped_message_writer& rhs) = delete; - scoped_message_writer& operator=(scoped_message_writer&& rhs) = delete; - - template - std::ostream& operator<<(const T& val) - { - m_oss << val; - return m_oss; - } - - ~scoped_message_writer() - { - if (m_flush) - { - m_flush = false; - - MCLOG_FILE(m_log_level, "msgwriter", m_oss.str()); - - if (epee::console_color_default == m_color) - { - std::cout << m_oss.str(); - } - else - { - PAUSE_READLINE(); - set_console_color(m_color, m_bright); - std::cout << m_oss.str(); - epee::reset_console_color(); - } - std::cout << std::endl; - } - } -}; - -inline scoped_message_writer success_msg_writer(bool color = true) -{ - return scoped_message_writer(color ? epee::console_color_green : epee::console_color_default, false, std::string(), el::Level::Info); -} - -inline scoped_message_writer msg_writer(epee::console_colors color = epee::console_color_default) -{ - return scoped_message_writer(color, false, std::string(), el::Level::Info); -} - -inline scoped_message_writer fail_msg_writer() -{ - return scoped_message_writer(epee::console_color_red, true, "Error: ", el::Level::Error); -} - -} // namespace tools diff --git a/src_native/common/sfinae_helpers.h b/src_native/common/sfinae_helpers.h deleted file mode 100644 index fa5052a2..00000000 --- a/src_native/common/sfinae_helpers.h +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (c) 2016-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#pragma once - -// the loose definitions of types in this file are, well, loose. -// -// these helpers aren't here for absolute type certainty at compile-time, -// but rather to help with templated functions telling types apart. - -namespace sfinae -{ - - typedef char true_type; - - struct false_type { true_type a[2]; }; - - template - struct is_not_container - { - private: - - // does not have const iterator - template static false_type c_iter(typename C::const_iterator*); - template static true_type c_iter(...); - - // does not have value_type - template static false_type v_type(typename C::value_type*); - template static true_type v_type(...); - - // does not have key_type - template static false_type k_type(typename C::key_type*); - template static true_type k_type(...); - - // does not have mapped_type - template static false_type m_type(typename C::mapped_type*); - template static true_type m_type(...); - - public: - - static const bool value = ( - ( - sizeof(c_iter(0)) == sizeof(true_type) && - sizeof(v_type(0)) == sizeof(true_type) && - sizeof(k_type(0)) == sizeof(true_type) && - sizeof(m_type(0)) == sizeof(true_type) - ) - || std::is_same::value - ); - - typedef T type; - }; - - template - struct is_vector_like - { - private: - - // has const iterator - template static true_type c_iter(typename C::const_iterator*); - template static false_type c_iter(...); - - // has value_type - template static true_type v_type(typename C::value_type*); - template static false_type v_type(...); - - // does not have key_type - template static false_type k_type(typename C::key_type*); - template static true_type k_type(...); - - // does not have mapped_type - template static false_type m_type(typename C::mapped_type*); - template static true_type m_type(...); - - public: - - static const bool value = ( - sizeof(c_iter(0)) == sizeof(true_type) && - sizeof(v_type(0)) == sizeof(true_type) && - sizeof(k_type(0)) == sizeof(true_type) && - sizeof(m_type(0)) == sizeof(true_type) && - !std::is_same::value - ); - - typedef T type; - }; - - template - struct is_map_like - { - private: - - // has const iterator - template static true_type c_iter(typename C::const_iterator*); - template static false_type c_iter(...); - - // has value_type - template static true_type v_type(typename C::value_type*); - template static false_type v_type(...); - - // has key_type - template static true_type k_type(typename C::key_type*); - template static false_type k_type(...); - - // has mapped_type - template static true_type m_type(typename C::mapped_type*); - template static false_type m_type(...); - - public: - - static const bool value = ( - sizeof(c_iter(0)) == sizeof(true_type) && - sizeof(v_type(0)) == sizeof(true_type) && - sizeof(k_type(0)) == sizeof(true_type) && - sizeof(m_type(0)) == sizeof(true_type) && - !std::is_same::value - ); - - typedef T type; - }; - -} // namespace sfinae diff --git a/src_native/common/stack_trace.cpp b/src_native/common/stack_trace.cpp deleted file mode 100644 index 9c2bf4b5..00000000 --- a/src_native/common/stack_trace.cpp +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (c) 2016-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#if !defined __GNUC__ || defined __MINGW32__ || defined __MINGW64__ || defined __ANDROID__ -#define USE_UNWIND -#else -#define ELPP_FEATURE_CRASH_LOG 1 -#endif -#include "easylogging++/easylogging++.h" - -#include -#ifdef USE_UNWIND -#define UNW_LOCAL_ONLY -#include -#include -#endif -#ifndef STATICLIB -#include -#endif -#include -#include "common/stack_trace.h" -#include "misc_log_ex.h" - -#undef MONERO_DEFAULT_LOG_CATEGORY -#define MONERO_DEFAULT_LOG_CATEGORY "stacktrace" - -#define ST_LOG(x) CINFO(el::base::Writer,el::base::DispatchAction::FileOnlyLog,MONERO_DEFAULT_LOG_CATEGORY) << x - -// from http://stackoverflow.com/questions/11665829/how-can-i-print-stack-trace-for-caught-exceptions-in-c-code-injection-in-c - -// The decl of __cxa_throw in /usr/include/.../cxxabi.h uses -// 'std::type_info *', but GCC's built-in protype uses 'void *'. -#ifdef __clang__ -#define CXA_THROW_INFO_T std::type_info -#else // !__clang__ -#define CXA_THROW_INFO_T void -#endif // !__clang__ - -#ifdef STATICLIB -#define CXA_THROW __wrap___cxa_throw -extern "C" -__attribute__((noreturn)) -void __real___cxa_throw(void *ex, CXA_THROW_INFO_T *info, void (*dest)(void*)); -#else // !STATICLIB -#define CXA_THROW __cxa_throw -extern "C" -typedef -#ifdef __clang__ // only clang, not GCC, lets apply the attr in typedef -__attribute__((noreturn)) -#endif // __clang__ -void (cxa_throw_t)(void *ex, CXA_THROW_INFO_T *info, void (*dest)(void*)); -#endif // !STATICLIB - -extern "C" -__attribute__((noreturn)) -void CXA_THROW(void *ex, CXA_THROW_INFO_T *info, void (*dest)(void*)) -{ - - int status; - char *dsym = abi::__cxa_demangle(((const std::type_info*)info)->name(), NULL, NULL, &status); - tools::log_stack_trace((std::string("Exception: ")+((!status && dsym) ? dsym : (const char*)info)).c_str()); - free(dsym); - -#ifndef STATICLIB -#ifndef __clang__ // for GCC the attr can't be applied in typedef like for clang - __attribute__((noreturn)) -#endif // !__clang__ - cxa_throw_t *__real___cxa_throw = (cxa_throw_t*)dlsym(RTLD_NEXT, "__cxa_throw"); -#endif // !STATICLIB - __real___cxa_throw(ex, info, dest); -} - -namespace -{ - std::string stack_trace_log; -} - -namespace tools -{ - -void set_stack_trace_log(const std::string &log) -{ - stack_trace_log = log; -} - -void log_stack_trace(const char *msg) -{ -#ifdef USE_UNWIND - unw_context_t ctx; - unw_cursor_t cur; - unw_word_t ip, off; - unsigned level; - char sym[512], *dsym; - int status; - const char *log = stack_trace_log.empty() ? NULL : stack_trace_log.c_str(); -#endif - - if (msg) - ST_LOG(msg); - ST_LOG("Unwound call stack:"); - -#ifdef USE_UNWIND - if (unw_getcontext(&ctx) < 0) { - ST_LOG("Failed to create unwind context"); - return; - } - if (unw_init_local(&cur, &ctx) < 0) { - ST_LOG("Failed to find the first unwind frame"); - return; - } - for (level = 1; level < 999; ++level) { // 999 for safety - int ret = unw_step(&cur); - if (ret < 0) { - ST_LOG("Failed to find the next frame"); - return; - } - if (ret == 0) - break; - if (unw_get_reg(&cur, UNW_REG_IP, &ip) < 0) { - ST_LOG(" " << std::setw(4) << level); - continue; - } - if (unw_get_proc_name(&cur, sym, sizeof(sym), &off) < 0) { - ST_LOG(" " << std::setw(4) << level << std::setbase(16) << std::setw(20) << "0x" << ip); - continue; - } - dsym = abi::__cxa_demangle(sym, NULL, NULL, &status); - ST_LOG(" " << std::setw(4) << level << std::setbase(16) << std::setw(20) << "0x" << ip << " " << (!status && dsym ? dsym : sym) << " + " << "0x" << off); - free(dsym); - } -#else - std::stringstream ss; - ss << el::base::debug::StackTrace(); - std::vector lines; - std::string s = ss.str(); - boost::split(lines, s, boost::is_any_of("\n")); - for (const auto &line: lines) - ST_LOG(line); -#endif -} - -} // namespace tools diff --git a/src_native/common/stack_trace.h b/src_native/common/stack_trace.h deleted file mode 100644 index 272fb89a..00000000 --- a/src_native/common/stack_trace.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2016-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef MONERO_EXCEPTION_H -#define MONERO_EXCEPTION_H - -#include - -namespace tools -{ - -void set_stack_trace_log(const std::string &log); -void log_stack_trace(const char *msg); - -} // namespace tools - -#endif diff --git a/src_native/common/threadpool.cpp b/src_native/common/threadpool.cpp deleted file mode 100644 index 51e07157..00000000 --- a/src_native/common/threadpool.cpp +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) 2017-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include "misc_log_ex.h" -#include "common/threadpool.h" - -#include -#include -#include - -#include "cryptonote_config.h" -#include "common/util.h" - -static __thread int depth = 0; - -namespace tools -{ -threadpool::threadpool() : running(true), active(0) { - boost::thread::attributes attrs; - attrs.set_stack_size(THREAD_STACK_SIZE); - max = tools::get_max_concurrency(); - size_t i = max; - while(i--) { - threads.push_back(boost::thread(attrs, boost::bind(&threadpool::run, this))); - } -} - -threadpool::~threadpool() { - { - const boost::unique_lock lock(mutex); - running = false; - has_work.notify_all(); - } - for (size_t i = 0; i f) { - entry e = {obj, f}; - boost::unique_lock lock(mutex); - if ((active == max && !queue.empty()) || depth > 0) { - // if all available threads are already running - // and there's work waiting, just run in current thread - lock.unlock(); - ++depth; - f(); - --depth; - } else { - if (obj) - obj->inc(); - queue.push_back(e); - has_work.notify_one(); - } -} - -int threadpool::get_max_concurrency() { - return max; -} - -threadpool::waiter::~waiter() -{ - { - boost::unique_lock lock(mt); - if (num) - MERROR("wait should have been called before waiter dtor - waiting now"); - } - try - { - wait(); - } - catch (const std::exception &e) - { - /* ignored */ - } -} - -void threadpool::waiter::wait() { - boost::unique_lock lock(mt); - while(num) cv.wait(lock); -} - -void threadpool::waiter::inc() { - const boost::unique_lock lock(mt); - num++; -} - -void threadpool::waiter::dec() { - const boost::unique_lock lock(mt); - num--; - if (!num) - cv.notify_one(); -} - -void threadpool::run() { - boost::unique_lock lock(mutex); - while (running) { - entry e; - while(queue.empty() && running) - has_work.wait(lock); - if (!running) break; - - active++; - e = queue.front(); - queue.pop_front(); - lock.unlock(); - ++depth; - e.f(); - --depth; - - if (e.wo) - e.wo->dec(); - lock.lock(); - active--; - } -} -} diff --git a/src_native/common/threadpool.h b/src_native/common/threadpool.h deleted file mode 100644 index 34152541..00000000 --- a/src_native/common/threadpool.h +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (c) 2017-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace tools -{ -//! A global thread pool -class threadpool -{ -public: - static threadpool& getInstance() { - static threadpool instance; - return instance; - } - - // The waiter lets the caller know when all of its - // tasks are completed. - class waiter { - boost::mutex mt; - boost::condition_variable cv; - int num; - public: - void inc(); - void dec(); - void wait(); //! Wait for a set of tasks to finish. - waiter() : num(0){} - ~waiter(); - }; - - // Submit a task to the pool. The waiter pointer may be - // NULL if the caller doesn't care to wait for the - // task to finish. - void submit(waiter *waiter, std::function f); - - int get_max_concurrency(); - - private: - threadpool(); - ~threadpool(); - typedef struct entry { - waiter *wo; - std::function f; - } entry; - std::deque queue; - boost::condition_variable has_work; - boost::mutex mutex; - std::vector threads; - int active; - int max; - bool running; - void run(); -}; - -} diff --git a/src_native/common/unordered_containers_boost_serialization.h b/src_native/common/unordered_containers_boost_serialization.h deleted file mode 100644 index d78dc6a3..00000000 --- a/src_native/common/unordered_containers_boost_serialization.h +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once - -#include -#include -#include - -namespace boost -{ - namespace serialization - { - template - inline void save(Archive &a, const std::unordered_map &x, const boost::serialization::version_type ver) - { - size_t s = x.size(); - a << s; - for(auto& v: x) - { - a << v.first; - a << v.second; - } - } - - template - inline void load(Archive &a, std::unordered_map &x, const boost::serialization::version_type ver) - { - x.clear(); - size_t s = 0; - a >> s; - for(size_t i = 0; i != s; i++) - { - h_key k; - hval v; - a >> k; - a >> v; - x.insert(std::pair(k, v)); - } - } - - - template - inline void save(Archive &a, const std::unordered_multimap &x, const boost::serialization::version_type ver) - { - size_t s = x.size(); - a << s; - for(auto& v: x) - { - a << v.first; - a << v.second; - } - } - - template - inline void load(Archive &a, std::unordered_multimap &x, const boost::serialization::version_type ver) - { - x.clear(); - size_t s = 0; - a >> s; - for(size_t i = 0; i != s; i++) - { - h_key k; - hval v; - a >> k; - a >> v; - x.emplace(k, v); - } - } - - - template - inline void save(Archive &a, const std::unordered_set &x, const boost::serialization::version_type ver) - { - size_t s = x.size(); - a << s; - for(auto& v: x) - { - a << v; - } - } - - template - inline void load(Archive &a, std::unordered_set &x, const boost::serialization::version_type ver) - { - x.clear(); - size_t s = 0; - a >> s; - for(size_t i = 0; i != s; i++) - { - hval v; - a >> v; - x.insert(v); - } - } - - - template - inline void serialize(Archive &a, std::unordered_map &x, const boost::serialization::version_type ver) - { - split_free(a, x, ver); - } - - template - inline void serialize(Archive &a, std::unordered_multimap &x, const boost::serialization::version_type ver) - { - split_free(a, x, ver); - } - - template - inline void serialize(Archive &a, std::unordered_set &x, const boost::serialization::version_type ver) - { - split_free(a, x, ver); - } - } -} diff --git a/src_native/common/updates.cpp b/src_native/common/updates.cpp deleted file mode 100644 index e9dc27a8..00000000 --- a/src_native/common/updates.cpp +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 2017-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include -#include "misc_log_ex.h" -#include "util.h" -#include "dns_utils.h" -#include "updates.h" - -#undef MONERO_DEFAULT_LOG_CATEGORY -#define MONERO_DEFAULT_LOG_CATEGORY "updates" - -namespace tools -{ - bool check_updates(const std::string &software, const std::string &buildtag, std::string &version, std::string &hash) - { - std::vector records; - bool found = false; - - MDEBUG("Checking updates for " << buildtag << " " << software); - - // All four MoneroPulse domains have DNSSEC on and valid - // TODO-TK - static const std::vector dns_urls = {}; - - if (!tools::dns_utils::load_txt_records_from_dns(records, dns_urls)) - return false; - - for (const auto& record : records) - { - std::vector fields; - boost::split(fields, record, boost::is_any_of(":")); - if (fields.size() != 4) - { - MWARNING("Updates record does not have 4 fields: " << record); - continue; - } - - if (software != fields[0] || buildtag != fields[1]) - continue; - - bool alnum = true; - for (auto c: hash) - if (!isalnum(c)) - alnum = false; - if (hash.size() != 64 && !alnum) - { - MWARNING("Invalid hash: " << hash); - continue; - } - - // use highest version - if (found) - { - int cmp = vercmp(version.c_str(), fields[2].c_str()); - if (cmp > 0) - continue; - if (cmp == 0 && hash != fields[3]) - MWARNING("Two matches found for " << software << " version " << version << " on " << buildtag); - } - - version = fields[2]; - hash = fields[3]; - - MINFO("Found new version " << version << " with hash " << hash); - found = true; - } - return found; - } - - std::string get_update_url(const std::string &software, const std::string &subdir, const std::string &buildtag, const std::string &version, bool user) - { - const char *base = user ? "https://downloads.getmonero.org/" : "https://updates.getmonero.org/"; -#ifdef _WIN32 - static const char *extension = strncmp(buildtag.c_str(), "install-", 8) ? ".zip" : ".exe"; -#else - static const char extension[] = ".tar.bz2"; -#endif - - std::string url; - - url = base; - if (!subdir.empty()) - url += subdir + "/"; - url = url + software + "-" + buildtag + "-v" + version + extension; - return url; - } -} diff --git a/src_native/common/updates.h b/src_native/common/updates.h deleted file mode 100644 index 6ec22f18..00000000 --- a/src_native/common/updates.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2017-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#pragma once - -#include - -namespace tools -{ - bool check_updates(const std::string &software, const std::string &buildtag, std::string &version, std::string &hash); - std::string get_update_url(const std::string &software, const std::string &subdir, const std::string &buildtag, const std::string &version, bool user); -} diff --git a/src_native/common/util.cpp b/src_native/common/util.cpp deleted file mode 100644 index e7206fbb..00000000 --- a/src_native/common/util.cpp +++ /dev/null @@ -1,712 +0,0 @@ -// Copyright (c) 2017-2018, The Masari Project -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#include - -#ifdef __GLIBC__ -#include -#endif - -#include "unbound.h" - -#include "include_base_utils.h" -#include "file_io_utils.h" -#include "wipeable_string.h" -using namespace epee; - -#include "crypto/crypto.h" -#include "util.h" -#include "memwipe.h" -#include "cryptonote_config.h" -#include "net/http_client.h" // epee::net_utils::... - -#ifdef WIN32 - #include - #include - #include -#else - #include - #include - #include -#endif -#include -#include -#include -#include - -namespace tools -{ - std::function signal_handler::m_handler; - - private_file::private_file() noexcept : m_handle(), m_filename() {} - - private_file::private_file(std::FILE* handle, std::string&& filename) noexcept - : m_handle(handle), m_filename(std::move(filename)) {} - - private_file private_file::create(std::string name) - { -#ifdef WIN32 - struct close_handle - { - void operator()(HANDLE handle) const noexcept - { - CloseHandle(handle); - } - }; - - std::unique_ptr process = nullptr; - { - HANDLE temp{}; - const bool fail = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, std::addressof(temp)) == 0; - process.reset(temp); - if (fail) - return {}; - } - - DWORD sid_size = 0; - GetTokenInformation(process.get(), TokenOwner, nullptr, 0, std::addressof(sid_size)); - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) - return {}; - - std::unique_ptr sid{new char[sid_size]}; - if (!GetTokenInformation(process.get(), TokenOwner, sid.get(), sid_size, std::addressof(sid_size))) - return {}; - - const PSID psid = reinterpret_cast(sid.get())->Owner; - const DWORD daclSize = - sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(psid) - sizeof(DWORD); - - const std::unique_ptr dacl{new char[daclSize]}; - if (!InitializeAcl(reinterpret_cast(dacl.get()), daclSize, ACL_REVISION)) - return {}; - - if (!AddAccessAllowedAce(reinterpret_cast(dacl.get()), ACL_REVISION, (READ_CONTROL | FILE_GENERIC_READ | DELETE), psid)) - return {}; - - SECURITY_DESCRIPTOR descriptor{}; - if (!InitializeSecurityDescriptor(std::addressof(descriptor), SECURITY_DESCRIPTOR_REVISION)) - return {}; - - if (!SetSecurityDescriptorDacl(std::addressof(descriptor), true, reinterpret_cast(dacl.get()), false)) - return {}; - - SECURITY_ATTRIBUTES attributes{sizeof(SECURITY_ATTRIBUTES), std::addressof(descriptor), false}; - std::unique_ptr file{ - CreateFile( - name.c_str(), - GENERIC_WRITE, FILE_SHARE_READ, - std::addressof(attributes), - CREATE_NEW, (FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE), - nullptr - ) - }; - if (file) - { - const int fd = _open_osfhandle(reinterpret_cast(file.get()), 0); - if (0 <= fd) - { - file.release(); - std::FILE* real_file = _fdopen(fd, "w"); - if (!real_file) - { - _close(fd); - } - return {real_file, std::move(name)}; - } - } -#else - const int fdr = open(name.c_str(), (O_RDONLY | O_CREAT), S_IRUSR); - if (0 <= fdr) - { - struct stat rstats = {}; - if (fstat(fdr, std::addressof(rstats)) != 0) - { - close(fdr); - return {}; - } - fchmod(fdr, (S_IRUSR | S_IWUSR)); - const int fdw = open(name.c_str(), O_RDWR); - fchmod(fdr, rstats.st_mode); - close(fdr); - - if (0 <= fdw) - { - struct stat wstats = {}; - if (fstat(fdw, std::addressof(wstats)) == 0 && - rstats.st_dev == wstats.st_dev && rstats.st_ino == wstats.st_ino && - flock(fdw, (LOCK_EX | LOCK_NB)) == 0 && ftruncate(fdw, 0) == 0) - { - std::FILE* file = fdopen(fdw, "w"); - if (file) return {file, std::move(name)}; - } - close(fdw); - } - } -#endif - return {}; - } - - private_file::~private_file() noexcept - { - try - { - boost::system::error_code ec{}; - boost::filesystem::remove(filename(), ec); - } - catch (...) {} - } - -#ifdef WIN32 - std::string get_windows_version_display_string() - { - typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO); - typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD); -#define BUFSIZE 10000 - - char pszOS[BUFSIZE] = {0}; - OSVERSIONINFOEX osvi; - SYSTEM_INFO si; - PGNSI pGNSI; - PGPI pGPI; - BOOL bOsVersionInfoEx; - DWORD dwType; - - ZeroMemory(&si, sizeof(SYSTEM_INFO)); - ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); - - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO*) &osvi); - - if(!bOsVersionInfoEx) return pszOS; - - // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise. - - pGNSI = (PGNSI) GetProcAddress( - GetModuleHandle(TEXT("kernel32.dll")), - "GetNativeSystemInfo"); - if(NULL != pGNSI) - pGNSI(&si); - else GetSystemInfo(&si); - - if ( VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && - osvi.dwMajorVersion > 4 ) - { - StringCchCopy(pszOS, BUFSIZE, TEXT("Microsoft ")); - - // Test for the specific product. - - if ( osvi.dwMajorVersion == 6 ) - { - if( osvi.dwMinorVersion == 0 ) - { - if( osvi.wProductType == VER_NT_WORKSTATION ) - StringCchCat(pszOS, BUFSIZE, TEXT("Windows Vista ")); - else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2008 " )); - } - - if ( osvi.dwMinorVersion == 1 ) - { - if( osvi.wProductType == VER_NT_WORKSTATION ) - StringCchCat(pszOS, BUFSIZE, TEXT("Windows 7 ")); - else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2008 R2 " )); - } - - pGPI = (PGPI) GetProcAddress( - GetModuleHandle(TEXT("kernel32.dll")), - "GetProductInfo"); - - pGPI( osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType); - - switch( dwType ) - { - case PRODUCT_ULTIMATE: - StringCchCat(pszOS, BUFSIZE, TEXT("Ultimate Edition" )); - break; - case PRODUCT_PROFESSIONAL: - StringCchCat(pszOS, BUFSIZE, TEXT("Professional" )); - break; - case PRODUCT_HOME_PREMIUM: - StringCchCat(pszOS, BUFSIZE, TEXT("Home Premium Edition" )); - break; - case PRODUCT_HOME_BASIC: - StringCchCat(pszOS, BUFSIZE, TEXT("Home Basic Edition" )); - break; - case PRODUCT_ENTERPRISE: - StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition" )); - break; - case PRODUCT_BUSINESS: - StringCchCat(pszOS, BUFSIZE, TEXT("Business Edition" )); - break; - case PRODUCT_STARTER: - StringCchCat(pszOS, BUFSIZE, TEXT("Starter Edition" )); - break; - case PRODUCT_CLUSTER_SERVER: - StringCchCat(pszOS, BUFSIZE, TEXT("Cluster Server Edition" )); - break; - case PRODUCT_DATACENTER_SERVER: - StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition" )); - break; - case PRODUCT_DATACENTER_SERVER_CORE: - StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition (core installation)" )); - break; - case PRODUCT_ENTERPRISE_SERVER: - StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition" )); - break; - case PRODUCT_ENTERPRISE_SERVER_CORE: - StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition (core installation)" )); - break; - case PRODUCT_ENTERPRISE_SERVER_IA64: - StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition for Itanium-based Systems" )); - break; - case PRODUCT_SMALLBUSINESS_SERVER: - StringCchCat(pszOS, BUFSIZE, TEXT("Small Business Server" )); - break; - case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM: - StringCchCat(pszOS, BUFSIZE, TEXT("Small Business Server Premium Edition" )); - break; - case PRODUCT_STANDARD_SERVER: - StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition" )); - break; - case PRODUCT_STANDARD_SERVER_CORE: - StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition (core installation)" )); - break; - case PRODUCT_WEB_SERVER: - StringCchCat(pszOS, BUFSIZE, TEXT("Web Server Edition" )); - break; - } - } - - if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 ) - { - if( GetSystemMetrics(SM_SERVERR2) ) - StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Server 2003 R2, ")); - else if ( osvi.wSuiteMask & VER_SUITE_STORAGE_SERVER ) - StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Storage Server 2003")); - else if ( osvi.wSuiteMask & VER_SUITE_WH_SERVER ) - StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Home Server")); - else if( osvi.wProductType == VER_NT_WORKSTATION && - si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64) - { - StringCchCat(pszOS, BUFSIZE, TEXT( "Windows XP Professional x64 Edition")); - } - else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2003, ")); - - // Test for the server type. - if ( osvi.wProductType != VER_NT_WORKSTATION ) - { - if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64 ) - { - if( osvi.wSuiteMask & VER_SUITE_DATACENTER ) - StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Edition for Itanium-based Systems" )); - else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) - StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise Edition for Itanium-based Systems" )); - } - - else if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 ) - { - if( osvi.wSuiteMask & VER_SUITE_DATACENTER ) - StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter x64 Edition" )); - else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) - StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise x64 Edition" )); - else StringCchCat(pszOS, BUFSIZE, TEXT( "Standard x64 Edition" )); - } - - else - { - if ( osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER ) - StringCchCat(pszOS, BUFSIZE, TEXT( "Compute Cluster Edition" )); - else if( osvi.wSuiteMask & VER_SUITE_DATACENTER ) - StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Edition" )); - else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) - StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise Edition" )); - else if ( osvi.wSuiteMask & VER_SUITE_BLADE ) - StringCchCat(pszOS, BUFSIZE, TEXT( "Web Edition" )); - else StringCchCat(pszOS, BUFSIZE, TEXT( "Standard Edition" )); - } - } - } - - if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 ) - { - StringCchCat(pszOS, BUFSIZE, TEXT("Windows XP ")); - if( osvi.wSuiteMask & VER_SUITE_PERSONAL ) - StringCchCat(pszOS, BUFSIZE, TEXT( "Home Edition" )); - else StringCchCat(pszOS, BUFSIZE, TEXT( "Professional" )); - } - - if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 ) - { - StringCchCat(pszOS, BUFSIZE, TEXT("Windows 2000 ")); - - if ( osvi.wProductType == VER_NT_WORKSTATION ) - { - StringCchCat(pszOS, BUFSIZE, TEXT( "Professional" )); - } - else - { - if( osvi.wSuiteMask & VER_SUITE_DATACENTER ) - StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Server" )); - else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) - StringCchCat(pszOS, BUFSIZE, TEXT( "Advanced Server" )); - else StringCchCat(pszOS, BUFSIZE, TEXT( "Server" )); - } - } - - // Include service pack (if any) and build number. - - if( strlen(osvi.szCSDVersion) > 0 ) - { - StringCchCat(pszOS, BUFSIZE, TEXT(" ") ); - StringCchCat(pszOS, BUFSIZE, osvi.szCSDVersion); - } - - TCHAR buf[80]; - - StringCchPrintf( buf, 80, TEXT(" (build %d)"), osvi.dwBuildNumber); - StringCchCat(pszOS, BUFSIZE, buf); - - if ( osvi.dwMajorVersion >= 6 ) - { - if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 ) - StringCchCat(pszOS, BUFSIZE, TEXT( ", 64-bit" )); - else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL ) - StringCchCat(pszOS, BUFSIZE, TEXT(", 32-bit")); - } - - return pszOS; - } - else - { - printf( "This sample does not support this version of Windows.\n"); - return pszOS; - } - } -#else -std::string get_nix_version_display_string() -{ - struct utsname un; - - if(uname(&un) < 0) - return std::string("*nix: failed to get os version"); - return std::string() + un.sysname + " " + un.version + " " + un.release; -} -#endif - - - - std::string get_os_version_string() - { -#ifdef WIN32 - return get_windows_version_display_string(); -#else - return get_nix_version_display_string(); -#endif - } - - - -#ifdef WIN32 - std::string get_special_folder_path(int nfolder, bool iscreate) - { - WCHAR psz_path[MAX_PATH] = L""; - - if (SHGetSpecialFolderPathW(NULL, psz_path, nfolder, iscreate)) - { - int size_needed = WideCharToMultiByte(CP_UTF8, 0, psz_path, wcslen(psz_path), NULL, 0, NULL, NULL); - std::string folder_name(size_needed, 0); - WideCharToMultiByte(CP_UTF8, 0, psz_path, wcslen(psz_path), &folder_name[0], size_needed, NULL, NULL); - return folder_name; - } - - LOG_ERROR("SHGetSpecialFolderPathW() failed, could not obtain requested path."); - return ""; - } -#endif - - std::string get_default_data_dir() - { - /* Please for the love of god refactor the ifdefs out of this */ - - // namespace fs = boost::filesystem; - // Windows < Vista: C:\Documents and Settings\Username\Application Data\CRYPTONOTE_NAME - // Windows >= Vista: C:\Users\Username\AppData\Roaming\CRYPTONOTE_NAME - // Unix & Mac: ~/.CRYPTONOTE_NAME - std::string config_folder; - -#ifdef WIN32 - config_folder = get_special_folder_path(CSIDL_COMMON_APPDATA, true) + "\\" + CRYPTONOTE_NAME; -#else - std::string pathRet; - char* pszHome = getenv("HOME"); - if (pszHome == NULL || strlen(pszHome) == 0) - pathRet = "/"; - else - pathRet = pszHome; - config_folder = (pathRet + "/." + CRYPTONOTE_NAME); -#endif - - return config_folder; - } - - bool create_directories_if_necessary(const std::string& path) - { - namespace fs = boost::filesystem; - boost::system::error_code ec; - fs::path fs_path(path); - if (fs::is_directory(fs_path, ec)) - { - return true; - } - - bool res = fs::create_directories(fs_path, ec); - if (res) - { - LOG_PRINT_L2("Created directory: " << path); - } - else - { - LOG_PRINT_L2("Can't create directory: " << path << ", err: "<< ec.message()); - } - - return res; - } - - std::error_code replace_file(const std::string& replacement_name, const std::string& replaced_name) - { - int code; -#if defined(WIN32) - // Maximizing chances for success - WCHAR wide_replacement_name[1000]; - MultiByteToWideChar(CP_UTF8, 0, replacement_name.c_str(), replacement_name.size() + 1, wide_replacement_name, 1000); - WCHAR wide_replaced_name[1000]; - MultiByteToWideChar(CP_UTF8, 0, replaced_name.c_str(), replaced_name.size() + 1, wide_replaced_name, 1000); - - DWORD attributes = ::GetFileAttributesW(wide_replaced_name); - if (INVALID_FILE_ATTRIBUTES != attributes) - { - ::SetFileAttributesW(wide_replaced_name, attributes & (~FILE_ATTRIBUTE_READONLY)); - } - - bool ok = 0 != ::MoveFileExW(wide_replacement_name, wide_replaced_name, MOVEFILE_REPLACE_EXISTING); - code = ok ? 0 : static_cast(::GetLastError()); -#else - bool ok = 0 == std::rename(replacement_name.c_str(), replaced_name.c_str()); - code = ok ? 0 : errno; -#endif - return std::error_code(code, std::system_category()); - } - - static bool unbound_built_with_threads() - { - ub_ctx *ctx = ub_ctx_create(); - if (!ctx) return false; // cheat a bit, should not happen unless OOM - ub_ctx_zone_add(ctx, "masari", "unbound"); // this calls ub_ctx_finalize first, then errors out with UB_SYNTAX - // if no threads, bails out early with UB_NOERROR, otherwise fails with UB_AFTERFINAL id already finalized - bool with_threads = ub_ctx_async(ctx, 1) != 0; // UB_AFTERFINAL is not defined in public headers, check any error - ub_ctx_delete(ctx); - MINFO("libunbound was built " << (with_threads ? "with" : "without") << " threads"); - return with_threads; - } - - bool sanitize_locale() - { - // boost::filesystem throws for "invalid" locales, such as en_US.UTF-8, or kjsdkfs, - // so reset it here before any calls to it - try - { - boost::filesystem::path p {std::string("test")}; - p /= std::string("test"); - } - catch (...) - { -#if defined(__MINGW32__) || defined(__MINGW__) - putenv("LC_ALL=C"); - putenv("LANG=C"); -#else - setenv("LC_ALL", "C", 1); - setenv("LANG", "C", 1); -#endif - return true; - } - return false; - } - bool on_startup() - { - mlog_configure("", true); - - sanitize_locale(); - -#ifdef __GLIBC__ - const char *ver = gnu_get_libc_version(); - if (!strcmp(ver, "2.25")) - MCLOG_RED(el::Level::Warning, "global", "Running with glibc " << ver << ", hangs may occur - change glibc version if possible"); -#endif - -#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(LIBRESSL_VERSION_TEXT) - SSL_library_init(); -#else - OPENSSL_init_ssl(0, NULL); -#endif - - if (!unbound_built_with_threads()) - MCLOG_RED(el::Level::Warning, "global", "libunbound was not built with threads enabled - crashes may occur"); - - return true; - } - void set_strict_default_file_permissions(bool strict) - { -#if defined(__MINGW32__) || defined(__MINGW__) - // no clue about the odd one out -#else - mode_t mode = strict ? 077 : 0; - umask(mode); -#endif - } - - namespace - { - boost::mutex max_concurrency_lock; - unsigned max_concurrency = boost::thread::hardware_concurrency(); - } - - void set_max_concurrency(unsigned n) - { - if (n < 1) - n = boost::thread::hardware_concurrency(); - unsigned hwc = boost::thread::hardware_concurrency(); - if (n > hwc) - n = hwc; - boost::lock_guard lock(max_concurrency_lock); - max_concurrency = n; - } - - unsigned get_max_concurrency() - { - boost::lock_guard lock(max_concurrency_lock); - return max_concurrency; - } - - bool is_local_address(const std::string &address) - { - // extract host - epee::net_utils::http::url_content u_c; - if (!epee::net_utils::parse_url(address, u_c)) - { - MWARNING("Failed to determine whether address '" << address << "' is local, assuming not"); - return false; - } - if (u_c.host.empty()) - { - MWARNING("Failed to determine whether address '" << address << "' is local, assuming not"); - return false; - } - - // resolve to IP - boost::asio::io_service io_service; - boost::asio::ip::tcp::resolver resolver(io_service); - boost::asio::ip::tcp::resolver::query query(u_c.host, ""); - boost::asio::ip::tcp::resolver::iterator i = resolver.resolve(query); - while (i != boost::asio::ip::tcp::resolver::iterator()) - { - const boost::asio::ip::tcp::endpoint &ep = *i; - if (ep.address().is_loopback()) - { - MDEBUG("Address '" << address << "' is local"); - return true; - } - ++i; - } - - MDEBUG("Address '" << address << "' is not local"); - return false; - } - int vercmp(const char *v0, const char *v1) - { - std::vector f0, f1; - boost::split(f0, v0, boost::is_any_of(".-")); - boost::split(f1, v1, boost::is_any_of(".-")); - for (size_t i = 0; i < std::max(f0.size(), f1.size()); ++i) { - if (i >= f0.size()) - return -1; - if (i >= f1.size()) - return 1; - int f0i = atoi(f0[i].c_str()), f1i = atoi(f1[i].c_str()); - int n = f0i - f1i; - if (n) - return n; - } - return 0; - } - - bool sha256sum(const uint8_t *data, size_t len, crypto::hash &hash) - { - SHA256_CTX ctx; - if (!SHA256_Init(&ctx)) - return false; - if (!SHA256_Update(&ctx, data, len)) - return false; - if (!SHA256_Final((unsigned char*)hash.data, &ctx)) - return false; - return true; - } - - bool sha256sum(const std::string &filename, crypto::hash &hash) - { - if (!epee::file_io_utils::is_file_exist(filename)) - return false; - std::ifstream f; - f.exceptions(std::ifstream::failbit | std::ifstream::badbit); - f.open(filename, std::ios_base::binary | std::ios_base::in | std::ios::ate); - if (!f) - return false; - std::ifstream::pos_type file_size = f.tellg(); - SHA256_CTX ctx; - if (!SHA256_Init(&ctx)) - return false; - size_t size_left = file_size; - f.seekg(0, std::ios::beg); - while (size_left) - { - char buf[4096]; - std::ifstream::pos_type read_size = size_left > sizeof(buf) ? sizeof(buf) : size_left; - f.read(buf, read_size); - if (!f || !f.good()) - return false; - if (!SHA256_Update(&ctx, buf, read_size)) - return false; - size_left -= read_size; - } - f.close(); - if (!SHA256_Final((unsigned char*)hash.data, &ctx)) - return false; - return true; - } -} diff --git a/src_native/common/util.h b/src_native/common/util.h deleted file mode 100644 index 056ca4a7..00000000 --- a/src_native/common/util.h +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once - -//#include -//#include -#include -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#include "windows.h" -#include "misc_log_ex.h" -#endif - -#include "crypto/hash.h" - -/*! \brief Various Tools - * - * - * - */ -namespace tools -{ - //! Functional class for closing C file handles. - struct close_file - { - void operator()(std::FILE* handle) const noexcept - { - if (handle) - { - std::fclose(handle); - } - } - }; - - //! A file restricted to process owner AND process. Deletes file on destruction. - class private_file { - std::unique_ptr m_handle; - std::string m_filename; - - private_file(std::FILE* handle, std::string&& filename) noexcept; - public: - - //! `handle() == nullptr && filename.empty()`. - private_file() noexcept; - - /*! \return File only readable by owner and only used by this process - OR `private_file{}` on error. */ - static private_file create(std::string filename); - - private_file(private_file&&) = default; - private_file& operator=(private_file&&) = default; - - //! Deletes `filename()` and closes `handle()`. - ~private_file() noexcept; - - std::FILE* handle() const noexcept { return m_handle.get(); } - const std::string& filename() const noexcept { return m_filename; } - }; - - /*! \brief Returns the default data directory. - * - * \details Windows < Vista: C:\\Documents and Settings\\Username\\Application Data\\CRYPTONOTE_NAME - * - * Windows >= Vista: C:\\Users\\Username\\AppData\\Roaming\\CRYPTONOTE_NAME - * - * Mac: ~/Library/Application Support/CRYPTONOTE_NAME - * - * Unix: ~/.CRYPTONOTE_NAME - */ - std::string get_default_data_dir(); - -#ifdef WIN32 - /** - * @brief - * - * @param nfolder - * @param iscreate - * - * @return - */ - std::string get_special_folder_path(int nfolder, bool iscreate); -#endif - - /*! \brief Returns the OS version string - * - * \details This is a wrapper around the primitives - * get_windows_version_display_string() and - * get_nix_version_display_string() - */ - std::string get_os_version_string(); - - /*! \brief creates directories for a path - * - * wrapper around boost::filesyste::create_directories. - * (ensure-directory-exists): greenspun's tenth rule in action! - */ - bool create_directories_if_necessary(const std::string& path); - /*! \brief std::rename wrapper for nix and something strange for windows. - */ - std::error_code replace_file(const std::string& replacement_name, const std::string& replaced_name); - - bool sanitize_locale(); - - bool on_startup(); - - /*! \brief Defines a signal handler for win32 and *nix - */ - class signal_handler - { - public: - /*! \brief installs a signal handler */ - template - static bool install(T t) - { -#if defined(WIN32) - bool r = TRUE == ::SetConsoleCtrlHandler(&win_handler, TRUE); - if (r) - { - m_handler = t; - } - return r; -#else - static struct sigaction sa; - memset(&sa, 0, sizeof(struct sigaction)); - sa.sa_handler = posix_handler; - sa.sa_flags = 0; - /* Only blocks SIGINT, SIGTERM and SIGPIPE */ - sigaction(SIGINT, &sa, NULL); - signal(SIGTERM, posix_handler); - signal(SIGPIPE, SIG_IGN); - m_handler = t; - return true; -#endif - } - - private: -#if defined(WIN32) - /*! \brief Handler for win */ - static BOOL WINAPI win_handler(DWORD type) - { - if (CTRL_C_EVENT == type || CTRL_BREAK_EVENT == type) - { - handle_signal(type); - } - else - { - MGINFO_RED("Got control signal " << type << ". Exiting without saving..."); - return FALSE; - } - return TRUE; - } -#else - /*! \brief handler for NIX */ - static void posix_handler(int type) - { - handle_signal(type); - } -#endif - - /*! \brief calles m_handler */ - static void handle_signal(int type) - { - static boost::mutex m_mutex; - boost::unique_lock lock(m_mutex); - m_handler(type); - } - - /*! \brief where the installed handler is stored */ - static std::function m_handler; - }; - - void set_strict_default_file_permissions(bool strict); - - void set_max_concurrency(unsigned n); - unsigned get_max_concurrency(); - - bool is_local_address(const std::string &address); - int vercmp(const char *v0, const char *v1); // returns < 0, 0, > 0, similar to strcmp, but more human friendly than lexical - does not attempt to validate - - bool sha256sum(const uint8_t *data, size_t len, crypto::hash &hash); - bool sha256sum(const std::string &filename, crypto::hash &hash); -} diff --git a/src_native/common/varint.h b/src_native/common/varint.h deleted file mode 100644 index 151d13db..00000000 --- a/src_native/common/varint.h +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once - -#include -#include -#include -#include -#include -/*! \file varint.h - * \brief provides the implementation of varint's - * - * The representation of varints is rather odd. The first bit of each - * octet is significant, it represents wheter there is another part - * waiting to be read. For example 0x8002 would return 0x200, even - * though 0x02 does not have its msb set. The actual way they are read - * is as follows: Strip the msb of each byte, then from left to right, - * read in what remains, placing it in reverse, into the buffer. Thus, - * the following bit stream: 0xff02 would return 0x027f. 0xff turns - * into 0x7f, is placed on the beginning of the buffer, then 0x02 is - * unchanged, since its msb is not set, and placed at the end of the - * buffer. - */ - -namespace tools { - - /*! \brief Error codes for varint - */ - enum { - /* \brief Represents the overflow error */ - EVARINT_OVERFLOW = -1, - /* \brief Represents a non conical represnetation */ - EVARINT_REPRESENT = -2, - }; - - /*! \brief writes a varint to a stream. - */ - template - /* Requires T to be both an integral type and unsigned, should be a compile error if it is not */ - typename std::enable_if::value && std::is_unsigned::value, void>::type - write_varint(OutputIt &&dest, T i) { - /* Make sure that there is one after this */ - while (i >= 0x80) { - *dest = (static_cast(i) & 0x7f) | 0x80; - ++dest; - i >>= 7; /* I should be in multiples of 7, this should just get the next part */ - } - /* writes the last one to dest */ - *dest = static_cast(i); - dest++; /* Seems kinda pointless... */ - } - - /*! \brief Returns the string that represents the varint - */ - template - std::string get_varint_data(const T& v) - { - std::stringstream ss; - write_varint(std::ostreambuf_iterator(ss), v); - return ss.str(); - } - /*! \brief reads in the varint that is pointed to by InputIt into write - */ - template - typename std::enable_if::value && std::is_unsigned::value && 0 <= bits && bits <= std::numeric_limits::digits, int>::type - read_varint(InputIt &&first, InputIt &&last, T &write) { - int read = 0; - write = 0; - for (int shift = 0;; shift += 7) { - if (first == last) { - return read; - } - unsigned char byte = *first; - ++first; - ++read; - if (shift + 7 >= bits && byte >= 1 << (bits - shift)) { - return EVARINT_OVERFLOW; - } - if (byte == 0 && shift != 0) { - return EVARINT_REPRESENT; - } - - write |= static_cast(byte & 0x7f) << shift; /* Does the actually placing into write, stripping the first bit */ - - /* If there is no next */ - if ((byte & 0x80) == 0) { - break; - } - } - return read; - } - - /*! \brief Wrapper around the other read_varint, - * Sets template parameters for you. - */ - template - int read_varint(InputIt &&first, InputIt &&last, T &i) { - return read_varint::digits, InputIt, T>(std::move(first), std::move(last), i); - } -} diff --git a/src_native/crypto-ops-data.c b/src_native/crypto-ops-data.c deleted file mode 100644 index 4ff4310d..00000000 --- a/src_native/crypto-ops-data.c +++ /dev/null @@ -1,873 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#include - -#include "crypto-ops.h" - -/* sqrt(x) is such an integer y that 0 <= y <= p - 1, y % 2 = 0, and y^2 = x (mod p). */ -/* d = -121665 / 121666 */ -const fe fe_d = {-10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116}; /* d */ -const fe fe_sqrtm1 = {-32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482}; /* sqrt(-1) */ -const fe fe_d2 = {-21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199}; /* 2 * d */ - -/* base[i][j] = (j+1)*256^i*B */ -const ge_precomp ge_base[32][8] = { - { - {{25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605}, - {-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378}, - {-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546}}, - {{-12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303}, - {-21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081}, - {26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697}}, - {{15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024}, - {16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574}, - {30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357}}, - {{-17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540}, - {23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397}, - {7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325}}, - {{10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380}, - {4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306}, - {19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942}}, - {{-15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777}, - {-8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737}, - {-18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652}}, - {{5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766}, - {-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701}, - {28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300}}, - {{14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726}, - {-7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955}, - {27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425}} - }, { - {{-13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171}, - {27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510}, - {17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660}}, - {{-10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639}, - {29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963}, - {5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950}}, - {{-27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568}, - {12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335}, - {25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628}}, - {{-26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007}, - {-2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772}, - {-22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653}}, - {{2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567}, - {13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686}, - {21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372}}, - {{-13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887}, - {-23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954}, - {-29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953}}, - {{24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833}, - {-16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532}, - {-22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876}}, - {{2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268}, - {33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214}, - {1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038}} - }, { - {{6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800}, - {4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645}, - {-4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664}}, - {{1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933}, - {-25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182}, - {-17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222}}, - {{-18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991}, - {20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880}, - {9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092}}, - {{-16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295}, - {19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788}, - {8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553}}, - {{-15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026}, - {11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347}, - {-18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033}}, - {{-23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395}, - {-27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278}, - {1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890}}, - {{32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995}, - {-30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596}, - {-11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891}}, - {{31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060}, - {11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608}, - {-20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606}} - }, { - {{7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389}, - {-19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016}, - {-11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341}}, - {{-22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505}, - {14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553}, - {-28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655}}, - {{15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220}, - {12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631}, - {-4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099}}, - {{26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556}, - {14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749}, - {236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930}}, - {{1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391}, - {5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253}, - {20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066}}, - {{24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958}, - {-11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082}, - {-28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383}}, - {{-30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521}, - {-11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807}, - {23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948}}, - {{9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134}, - {-32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455}, - {27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629}} - }, { - {{-8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069}, - {-32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746}, - {24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919}}, - {{11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837}, - {8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906}, - {-28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771}}, - {{-25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817}, - {10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098}, - {10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409}}, - {{-12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504}, - {-26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727}, - {28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420}}, - {{-32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003}, - {-1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605}, - {-30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384}}, - {{-26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701}, - {-23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683}, - {29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708}}, - {{-3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563}, - {-19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260}, - {-5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387}}, - {{-19443170, -15512900, -20797467, -12445323, -29824447, 10229461, -27444329, -15000531, -5996870, 15664672}, - {23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686}, - {-24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665}} - }, { - {{11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182}, - {-31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277}, - {14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628}}, - {{-4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474}, - {-26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539}, - {-25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822}}, - {{-10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970}, - {19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756}, - {-24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508}}, - {{-26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683}, - {-10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655}, - {-20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158}}, - {{-4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125}, - {-15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839}, - {-20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664}}, - {{27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294}, - {-18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899}, - {-11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070}}, - {{3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294}, - {-15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949}, - {-21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083}}, - {{31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420}, - {-5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940}, - {29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396}} - }, { - {{-12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567}, - {20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127}, - {-16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294}}, - {{-12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887}, - {22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964}, - {16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195}}, - {{9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244}, - {24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999}, - {-1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762}}, - {{-18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274}, - {-33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236}, - {-16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605}}, - {{-13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761}, - {-22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884}, - {-6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482}}, - {{-24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638}, - {-11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490}, - {-32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170}}, - {{5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736}, - {10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124}, - {-17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392}}, - {{8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029}, - {6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048}, - {28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958}} - }, { - {{24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593}, - {26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071}, - {-11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692}}, - {{11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687}, - {-160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441}, - {-20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001}}, - {{-938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460}, - {-19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007}, - {-21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762}}, - {{15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005}, - {-9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674}, - {4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035}}, - {{7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590}, - {-2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957}, - {-30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812}}, - {{33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740}, - {-18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122}, - {-27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158}}, - {{8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885}, - {26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140}, - {19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857}}, - {{801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155}, - {19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260}, - {19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483}} - }, { - {{-3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677}, - {32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815}, - {22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751}}, - {{-16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203}, - {-11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208}, - {1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230}}, - {{16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850}, - {-21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389}, - {-9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968}}, - {{-11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689}, - {14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880}, - {5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304}}, - {{30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632}, - {-3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412}, - {20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566}}, - {{-20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038}, - {-26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232}, - {-1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943}}, - {{17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856}, - {23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738}, - {15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971}}, - {{-27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718}, - {-13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697}, - {-11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883}} - }, { - {{5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912}, - {-26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358}, - {3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849}}, - {{29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307}, - {-14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977}, - {-6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335}}, - {{-29265967, -14186805, -13538216, -12117373, -19457059, -10655384, -31462369, -2948985, 24018831, 15026644}, - {-22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616}, - {-27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735}}, - {{-21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099}, - {29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341}, - {-936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336}}, - {{-23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646}, - {31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425}, - {-17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388}}, - {{-31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743}, - {-16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822}, - {-8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462}}, - {{18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985}, - {9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702}, - {-22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797}}, - {{21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293}, - {27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100}, - {19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688}} - }, { - {{12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186}, - {2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610}, - {-2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707}}, - {{7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220}, - {915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025}, - {32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044}}, - {{32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992}, - {-4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027}, - {21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197}}, - {{8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901}, - {31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952}, - {19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878}}, - {{-28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390}, - {32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730}, - {2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730}}, - {{-19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180}, - {-30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272}, - {-15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715}}, - {{-22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970}, - {-31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772}, - {-17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865}}, - {{15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750}, - {20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373}, - {32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348}} - }, { - {{9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144}, - {-22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195}, - {5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086}}, - {{-13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684}, - {-8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518}, - {-2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233}}, - {{-5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793}, - {-2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794}, - {580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435}}, - {{23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921}, - {13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518}, - {2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563}}, - {{14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278}, - {-27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024}, - {4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030}}, - {{10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783}, - {27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717}, - {6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844}}, - {{14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333}, - {16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048}, - {22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760}}, - {{-4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760}, - {-15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757}, - {-2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112}} - }, { - {{-19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468}, - {3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184}, - {10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289}}, - {{15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066}, - {24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882}, - {13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226}}, - {{16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101}, - {29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279}, - {-6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811}}, - {{27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709}, - {20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714}, - {-2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121}}, - {{9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464}, - {12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847}, - {13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400}}, - {{4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414}, - {-15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158}, - {17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045}}, - {{-461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415}, - {-5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459}, - {-31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079}}, - {{21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412}, - {-20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743}, - {-14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836}} - }, { - {{12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022}, - {18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429}, - {-6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065}}, - {{30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861}, - {10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000}, - {-33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101}}, - {{32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815}, - {29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642}, - {10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966}}, - {{25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574}, - {-21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742}, - {-18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689}}, - {{12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020}, - {-10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772}, - {3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982}}, - {{-14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953}, - {-16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218}, - {-17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265}}, - {{29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073}, - {-3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325}, - {-11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798}}, - {{-4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870}, - {-7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863}, - {-13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927}} - }, { - {{-2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267}, - {-9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663}, - {22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862}}, - {{-25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673}, - {15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943}, - {15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020}}, - {{-4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238}, - {11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064}, - {14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795}}, - {{15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052}, - {-10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904}, - {29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531}}, - {{-13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979}, - {-5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841}, - {10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431}}, - {{10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324}, - {-31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940}, - {10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320}}, - {{-15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184}, - {14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114}, - {30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878}}, - {{12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784}, - {-2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091}, - {-16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585}} - }, { - {{-8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208}, - {10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864}, - {17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661}}, - {{7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233}, - {26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212}, - {-12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525}}, - {{-24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068}, - {9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397}, - {-8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988}}, - {{5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889}, - {32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038}, - {14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697}}, - {{20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875}, - {-25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905}, - {-25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656}}, - {{11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818}, - {27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714}, - {10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203}}, - {{20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931}, - {-30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024}, - {-23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084}}, - {{-1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204}, - {20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817}, - {27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667}} - }, { - {{11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504}, - {-12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768}, - {-19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255}}, - {{6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790}, - {1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438}, - {-22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333}}, - {{17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971}, - {31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905}, - {29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409}}, - {{12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409}, - {6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499}, - {-8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363}}, - {{28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664}, - {-11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324}, - {-21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940}}, - {{13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990}, - {-17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914}, - {-25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290}}, - {{24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257}, - {-6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433}, - {-16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236}}, - {{-12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045}, - {11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093}, - {-1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347}} - }, { - {{-28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191}, - {-15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507}, - {-12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906}}, - {{3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018}, - {-16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109}, - {-23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926}}, - {{-24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528}, - {8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625}, - {-32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286}}, - {{2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033}, - {27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866}, - {21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896}}, - {{30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075}, - {26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347}, - {-22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437}}, - {{-5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165}, - {-18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588}, - {-32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193}}, - {{-19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017}, - {-28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883}, - {21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961}}, - {{8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043}, - {29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663}, - {-20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362}} - }, { - {{-33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860}, - {2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466}, - {-24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063}}, - {{-26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997}, - {-1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295}, - {-13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369}}, - {{9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385}, - {18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109}, - {2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906}}, - {{4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424}, - {-19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185}, - {7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962}}, - {{-7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325}, - {10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593}, - {696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404}}, - {{-11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644}, - {17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801}, - {26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804}}, - {{-31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884}, - {-586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577}, - {-9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849}}, - {{32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473}, - {-8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644}, - {-2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319}} - }, { - {{-11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599}, - {-9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768}, - {-27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084}}, - {{-27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328}, - {-15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369}, - {20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920}}, - {{12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815}, - {-32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025}, - {-21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397}}, - {{-20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448}, - {6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981}, - {30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165}}, - {{32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501}, - {17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073}, - {-1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861}}, - {{14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845}, - {-1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211}, - {18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870}}, - {{10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096}, - {33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803}, - {-32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168}}, - {{30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965}, - {-14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505}, - {18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598}} - }, { - {{5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782}, - {5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900}, - {-31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479}}, - {{-12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208}, - {8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232}, - {17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719}}, - {{16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271}, - {-4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326}, - {-8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132}}, - {{14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300}, - {8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570}, - {15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670}}, - {{-2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994}, - {-12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913}, - {31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317}}, - {{-25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730}, - {842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096}, - {-4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078}}, - {{-15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411}, - {-19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905}, - {-9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654}}, - {{-28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870}, - {-23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498}, - {12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579}} - }, { - {{14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677}, - {10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647}, - {-2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743}}, - {{-25173001, -11307165, 29759956, 11776784, -22262383, -15820455, 10993114, -12850837, -17620701, -9408468}, - {21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375}, - {-25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155}}, - {{6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725}, - {-12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612}, - {-10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943}}, - {{-30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944}, - {30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928}, - {9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406}}, - {{22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139}, - {-8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963}, - {-31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693}}, - {{1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734}, - {-448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680}, - {-24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410}}, - {{-9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931}, - {-16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654}, - {22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710}}, - {{29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180}, - {-26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684}, - {-10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895}} - }, { - {{22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501}, - {-11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413}, - {6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880}}, - {{-8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874}, - {22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962}, - {-7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899}}, - {{21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152}, - {9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063}, - {7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080}}, - {{-9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146}, - {-17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183}, - {-19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133}}, - {{-32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421}, - {-3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622}, - {-4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197}}, - {{2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663}, - {31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753}, - {4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755}}, - {{-9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862}, - {-26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118}, - {26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171}}, - {{15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380}, - {16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824}, - {28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270}} - }, { - {{-817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438}, - {-31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584}, - {-594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562}}, - {{30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471}, - {18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610}, - {19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269}}, - {{-30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650}, - {14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369}, - {19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461}}, - {{30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462}, - {-5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793}, - {-2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218}}, - {{-24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226}, - {18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019}, - {-15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037}}, - {{31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171}, - {-17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132}, - {-28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841}}, - {{21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181}, - {-33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210}, - {-1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040}}, - {{3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935}, - {24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105}, - {-28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814}} - }, { - {{793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852}, - {5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581}, - {-4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646}}, - {{10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844}, - {10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025}, - {27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453}}, - {{-23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068}, - {4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192}, - {-17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921}}, - {{-9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259}, - {-12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426}, - {-5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072}}, - {{-17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305}, - {13669248, -16095482, -12481974, -10203039, -14569770, -11893198, -24995986, 11293807, -28588204, -9421832}, - {28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943}}, - {{-16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011}, - {24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447}, - {17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494}}, - {{-28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245}, - {-20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859}, - {28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915}}, - {{16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707}, - {10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848}, - {-11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224}} - }, { - {{-25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391}, - {15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215}, - {-23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101}}, - {{23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713}, - {21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849}, - {-7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930}}, - {{-29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940}, - {-21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031}, - {-17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404}}, - {{-25817338, -3107312, -13494599, -3182506, 30896459, -13921729, -32251644, -12707869, -19464434, -3340243}, - {-23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116}, - {-24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525}}, - {{-23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509}, - {-10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883}, - {15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865}}, - {{-3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660}, - {4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273}, - {-28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138}}, - {{-25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560}, - {-10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135}, - {2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941}}, - {{-4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739}, - {18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756}, - {-30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819}} - }, { - {{-6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347}, - {-27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028}, - {21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075}}, - {{16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799}, - {-2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609}, - {-25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817}}, - {{-23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989}, - {-30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523}, - {4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278}}, - {{31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045}, - {19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377}, - {24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480}}, - {{17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016}, - {510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426}, - {18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525}}, - {{13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396}, - {9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080}, - {12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892}}, - {{15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275}, - {11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074}, - {20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140}}, - {{-16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717}, - {-1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101}, - {24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127}} - }, { - {{-12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632}, - {-26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415}, - {-31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160}}, - {{31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876}, - {22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625}, - {-15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478}}, - {{27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164}, - {26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595}, - {-7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248}}, - {{-16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858}, - {15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193}, - {8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184}}, - {{-18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942}, - {-1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635}, - {21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948}}, - {{11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935}, - {-25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415}, - {-15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416}}, - {{-7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018}, - {4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778}, - {366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659}}, - {{-24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385}, - {18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503}, - {476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329}} - }, { - {{20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056}, - {-13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838}, - {24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948}}, - {{-3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691}, - {-15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118}, - {-23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517}}, - {{-20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269}, - {-6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904}, - {-23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589}}, - {{-28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193}, - {-7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910}, - {-30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930}}, - {{-7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667}, - {25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481}, - {-9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876}}, - {{22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640}, - {-8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278}, - {-21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112}}, - {{26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272}, - {17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012}, - {-10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221}}, - {{30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046}, - {13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345}, - {-19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310}} - }, { - {{19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937}, - {31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636}, - {-9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008}}, - {{-2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429}, - {-15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576}, - {31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066}}, - {{-9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490}, - {-12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104}, - {33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053}}, - {{31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275}, - {-20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511}, - {22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095}}, - {{-28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439}, - {23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939}, - {-23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424}}, - {{2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310}, - {3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608}, - {-32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079}}, - {{-23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101}, - {21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418}, - {18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576}}, - {{30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356}, - {9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996}, - {-26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099}} - }, { - {{-26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728}, - {-13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658}, - {-10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242}}, - {{-21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001}, - {-4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766}, - {18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373}}, - {{26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458}, - {-17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628}, - {-13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657}}, - {{-23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062}, - {25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616}, - {31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014}}, - {{24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383}, - {-25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814}, - {-20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718}}, - {{30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417}, - {2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222}, - {33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444}}, - {{-20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597}, - {23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970}, - {1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799}}, - {{-5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647}, - {13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511}, - {-29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032}} - }, { - {{9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834}, - {-23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461}, - {29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062}}, - {{-25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516}, - {-20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547}, - {-24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240}}, - {{-17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038}, - {-33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741}, - {16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103}}, - {{-19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747}, - {-1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323}, - {31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016}}, - {{-14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373}, - {15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228}, - {-2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141}}, - {{16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399}, - {11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831}, - {-185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376}}, - {{-32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313}, - {-18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958}, - {-6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577}}, - {{-22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743}, - {29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684}, - {-20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476}} - } -}; - -const ge_precomp ge_Bi[8] = { - {{25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605}, - {-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378}, - {-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546}}, {{15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024}, - {16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574}, - {30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357}}, {{10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380}, - {4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306}, - {19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942}}, {{5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766}, - {-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701}, - {28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300}}, {{-22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877}, - {-6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951}, - {4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784}}, {{-25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436}, - {25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918}, - {23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877}}, {{-33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800}, - {-25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305}, - {-13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300}}, {{-3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876}, - {-24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619}, - {-3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683}} -}; - -/* A = 2 * (1 - d) / (1 + d) = 486662 */ -const fe fe_ma2 = {-12721188, -3529, 0, 0, 0, 0, 0, 0, 0, 0}; /* -A^2 */ -const fe fe_ma = {-486662, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* -A */ -const fe fe_fffb1 = {-31702527, -2466483, -26106795, -12203692, -12169197, -321052, 14850977, -10296299, -16929438, -407568}; /* sqrt(-2 * A * (A + 2)) */ -const fe fe_fffb2 = {8166131, -6741800, -17040804, 3154616, 21461005, 1466302, -30876704, -6368709, 10503587, -13363080}; /* sqrt(2 * A * (A + 2)) */ -const fe fe_fffb3 = {-13620103, 14639558, 4532995, 7679154, 16815101, -15883539, -22863840, -14813421, 13716513, -6477756}; /* sqrt(-sqrt(-1) * A * (A + 2)) */ -const fe fe_fffb4 = {-21786234, -12173074, 21573800, 4524538, -4645904, 16204591, 8012863, -8444712, 3212926, 6885324}; /* sqrt(sqrt(-1) * A * (A + 2)) */ -const ge_p3 ge_p3_identity = { {0}, {1, 0}, {1, 0}, {0} }; diff --git a/src_native/crypto-ops-data.o b/src_native/crypto-ops-data.o deleted file mode 100644 index 1d1d0c16..00000000 Binary files a/src_native/crypto-ops-data.o and /dev/null differ diff --git a/src_native/crypto-ops.c b/src_native/crypto-ops.c deleted file mode 100644 index efc7fc40..00000000 --- a/src_native/crypto-ops.c +++ /dev/null @@ -1,3732 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#include -#include - -//#include "warnings.h" -#include "crypto-ops.h" - -//DISABLE_VS_WARNINGS(4146 4244) - -/* Predeclarations */ - -static void fe_mul(fe, const fe, const fe); -static void fe_sq(fe, const fe); -static void ge_madd(ge_p1p1 *, const ge_p3 *, const ge_precomp *); -static void ge_msub(ge_p1p1 *, const ge_p3 *, const ge_precomp *); -static void ge_p2_0(ge_p2 *); -static void ge_p3_dbl(ge_p1p1 *, const ge_p3 *); -static void fe_divpowm1(fe, const fe, const fe); - -/* Common functions */ - -uint64_t load_3(const unsigned char *in) { - uint64_t result; - result = (uint64_t) in[0]; - result |= ((uint64_t) in[1]) << 8; - result |= ((uint64_t) in[2]) << 16; - return result; -} - -uint64_t load_4(const unsigned char *in) -{ - uint64_t result; - result = (uint64_t) in[0]; - result |= ((uint64_t) in[1]) << 8; - result |= ((uint64_t) in[2]) << 16; - result |= ((uint64_t) in[3]) << 24; - return result; -} - -/* From fe_0.c */ - -/* -h = 0 -*/ - -static void fe_0(fe h) { - h[0] = 0; - h[1] = 0; - h[2] = 0; - h[3] = 0; - h[4] = 0; - h[5] = 0; - h[6] = 0; - h[7] = 0; - h[8] = 0; - h[9] = 0; -} - -/* From fe_1.c */ - -/* -h = 1 -*/ - -static void fe_1(fe h) { - h[0] = 1; - h[1] = 0; - h[2] = 0; - h[3] = 0; - h[4] = 0; - h[5] = 0; - h[6] = 0; - h[7] = 0; - h[8] = 0; - h[9] = 0; -} - -/* From fe_add.c */ - -/* -h = f + g -Can overlap h with f or g. - -Preconditions: - |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. - |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. - -Postconditions: - |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. -*/ - -void fe_add(fe h, const fe f, const fe g) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t h0 = f0 + g0; - int32_t h1 = f1 + g1; - int32_t h2 = f2 + g2; - int32_t h3 = f3 + g3; - int32_t h4 = f4 + g4; - int32_t h5 = f5 + g5; - int32_t h6 = f6 + g6; - int32_t h7 = f7 + g7; - int32_t h8 = f8 + g8; - int32_t h9 = f9 + g9; - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; -} - -/* From fe_cmov.c */ - -/* -Replace (f,g) with (g,g) if b == 1; -replace (f,g) with (f,g) if b == 0. - -Preconditions: b in {0,1}. -*/ - -static void fe_cmov(fe f, const fe g, unsigned int b) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t x0 = f0 ^ g0; - int32_t x1 = f1 ^ g1; - int32_t x2 = f2 ^ g2; - int32_t x3 = f3 ^ g3; - int32_t x4 = f4 ^ g4; - int32_t x5 = f5 ^ g5; - int32_t x6 = f6 ^ g6; - int32_t x7 = f7 ^ g7; - int32_t x8 = f8 ^ g8; - int32_t x9 = f9 ^ g9; - assert((((b - 1) & ~b) | ((b - 2) & ~(b - 1))) == (unsigned int) -1); - b = -b; - x0 &= b; - x1 &= b; - x2 &= b; - x3 &= b; - x4 &= b; - x5 &= b; - x6 &= b; - x7 &= b; - x8 &= b; - x9 &= b; - f[0] = f0 ^ x0; - f[1] = f1 ^ x1; - f[2] = f2 ^ x2; - f[3] = f3 ^ x3; - f[4] = f4 ^ x4; - f[5] = f5 ^ x5; - f[6] = f6 ^ x6; - f[7] = f7 ^ x7; - f[8] = f8 ^ x8; - f[9] = f9 ^ x9; -} - -/* From fe_copy.c */ - -/* -h = f -*/ - -static void fe_copy(fe h, const fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - h[0] = f0; - h[1] = f1; - h[2] = f2; - h[3] = f3; - h[4] = f4; - h[5] = f5; - h[6] = f6; - h[7] = f7; - h[8] = f8; - h[9] = f9; -} - -/* From fe_invert.c */ - -void fe_invert(fe out, const fe z) { - fe t0; - fe t1; - fe t2; - fe t3; - int i; - - fe_sq(t0, z); - fe_sq(t1, t0); - fe_sq(t1, t1); - fe_mul(t1, z, t1); - fe_mul(t0, t0, t1); - fe_sq(t2, t0); - fe_mul(t1, t1, t2); - fe_sq(t2, t1); - for (i = 0; i < 4; ++i) { - fe_sq(t2, t2); - } - fe_mul(t1, t2, t1); - fe_sq(t2, t1); - for (i = 0; i < 9; ++i) { - fe_sq(t2, t2); - } - fe_mul(t2, t2, t1); - fe_sq(t3, t2); - for (i = 0; i < 19; ++i) { - fe_sq(t3, t3); - } - fe_mul(t2, t3, t2); - fe_sq(t2, t2); - for (i = 0; i < 9; ++i) { - fe_sq(t2, t2); - } - fe_mul(t1, t2, t1); - fe_sq(t2, t1); - for (i = 0; i < 49; ++i) { - fe_sq(t2, t2); - } - fe_mul(t2, t2, t1); - fe_sq(t3, t2); - for (i = 0; i < 99; ++i) { - fe_sq(t3, t3); - } - fe_mul(t2, t3, t2); - fe_sq(t2, t2); - for (i = 0; i < 49; ++i) { - fe_sq(t2, t2); - } - fe_mul(t1, t2, t1); - fe_sq(t1, t1); - for (i = 0; i < 4; ++i) { - fe_sq(t1, t1); - } - fe_mul(out, t1, t0); - - return; -} - -/* From fe_isnegative.c */ - -/* -return 1 if f is in {1,3,5,...,q-2} -return 0 if f is in {0,2,4,...,q-1} - -Preconditions: - |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. -*/ - -static int fe_isnegative(const fe f) { - unsigned char s[32]; - fe_tobytes(s, f); - return s[0] & 1; -} - -/* From fe_isnonzero.c, modified */ - -static int fe_isnonzero(const fe f) { - unsigned char s[32]; - fe_tobytes(s, f); - return (((int) (s[0] | s[1] | s[2] | s[3] | s[4] | s[5] | s[6] | s[7] | s[8] | - s[9] | s[10] | s[11] | s[12] | s[13] | s[14] | s[15] | s[16] | s[17] | - s[18] | s[19] | s[20] | s[21] | s[22] | s[23] | s[24] | s[25] | s[26] | - s[27] | s[28] | s[29] | s[30] | s[31]) - 1) >> 8) + 1; -} - -/* From fe_mul.c */ - -/* -h = f * g -Can overlap h with f or g. - -Preconditions: - |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. - |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. - -Postconditions: - |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. -*/ - -/* -Notes on implementation strategy: - -Using schoolbook multiplication. -Karatsuba would save a little in some cost models. - -Most multiplications by 2 and 19 are 32-bit precomputations; -cheaper than 64-bit postcomputations. - -There is one remaining multiplication by 19 in the carry chain; -one *19 precomputation can be merged into this, -but the resulting data flow is considerably less clean. - -There are 12 carries below. -10 of them are 2-way parallelizable and vectorizable. -Can get away with 11 carries, but then data flow is much deeper. - -With tighter constraints on inputs can squeeze carries into int32. -*/ - -static void fe_mul(fe h, const fe f, const fe g) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */ - int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ - int32_t g3_19 = 19 * g3; - int32_t g4_19 = 19 * g4; - int32_t g5_19 = 19 * g5; - int32_t g6_19 = 19 * g6; - int32_t g7_19 = 19 * g7; - int32_t g8_19 = 19 * g8; - int32_t g9_19 = 19 * g9; - int32_t f1_2 = 2 * f1; - int32_t f3_2 = 2 * f3; - int32_t f5_2 = 2 * f5; - int32_t f7_2 = 2 * f7; - int32_t f9_2 = 2 * f9; - int64_t f0g0 = f0 * (int64_t) g0; - int64_t f0g1 = f0 * (int64_t) g1; - int64_t f0g2 = f0 * (int64_t) g2; - int64_t f0g3 = f0 * (int64_t) g3; - int64_t f0g4 = f0 * (int64_t) g4; - int64_t f0g5 = f0 * (int64_t) g5; - int64_t f0g6 = f0 * (int64_t) g6; - int64_t f0g7 = f0 * (int64_t) g7; - int64_t f0g8 = f0 * (int64_t) g8; - int64_t f0g9 = f0 * (int64_t) g9; - int64_t f1g0 = f1 * (int64_t) g0; - int64_t f1g1_2 = f1_2 * (int64_t) g1; - int64_t f1g2 = f1 * (int64_t) g2; - int64_t f1g3_2 = f1_2 * (int64_t) g3; - int64_t f1g4 = f1 * (int64_t) g4; - int64_t f1g5_2 = f1_2 * (int64_t) g5; - int64_t f1g6 = f1 * (int64_t) g6; - int64_t f1g7_2 = f1_2 * (int64_t) g7; - int64_t f1g8 = f1 * (int64_t) g8; - int64_t f1g9_38 = f1_2 * (int64_t) g9_19; - int64_t f2g0 = f2 * (int64_t) g0; - int64_t f2g1 = f2 * (int64_t) g1; - int64_t f2g2 = f2 * (int64_t) g2; - int64_t f2g3 = f2 * (int64_t) g3; - int64_t f2g4 = f2 * (int64_t) g4; - int64_t f2g5 = f2 * (int64_t) g5; - int64_t f2g6 = f2 * (int64_t) g6; - int64_t f2g7 = f2 * (int64_t) g7; - int64_t f2g8_19 = f2 * (int64_t) g8_19; - int64_t f2g9_19 = f2 * (int64_t) g9_19; - int64_t f3g0 = f3 * (int64_t) g0; - int64_t f3g1_2 = f3_2 * (int64_t) g1; - int64_t f3g2 = f3 * (int64_t) g2; - int64_t f3g3_2 = f3_2 * (int64_t) g3; - int64_t f3g4 = f3 * (int64_t) g4; - int64_t f3g5_2 = f3_2 * (int64_t) g5; - int64_t f3g6 = f3 * (int64_t) g6; - int64_t f3g7_38 = f3_2 * (int64_t) g7_19; - int64_t f3g8_19 = f3 * (int64_t) g8_19; - int64_t f3g9_38 = f3_2 * (int64_t) g9_19; - int64_t f4g0 = f4 * (int64_t) g0; - int64_t f4g1 = f4 * (int64_t) g1; - int64_t f4g2 = f4 * (int64_t) g2; - int64_t f4g3 = f4 * (int64_t) g3; - int64_t f4g4 = f4 * (int64_t) g4; - int64_t f4g5 = f4 * (int64_t) g5; - int64_t f4g6_19 = f4 * (int64_t) g6_19; - int64_t f4g7_19 = f4 * (int64_t) g7_19; - int64_t f4g8_19 = f4 * (int64_t) g8_19; - int64_t f4g9_19 = f4 * (int64_t) g9_19; - int64_t f5g0 = f5 * (int64_t) g0; - int64_t f5g1_2 = f5_2 * (int64_t) g1; - int64_t f5g2 = f5 * (int64_t) g2; - int64_t f5g3_2 = f5_2 * (int64_t) g3; - int64_t f5g4 = f5 * (int64_t) g4; - int64_t f5g5_38 = f5_2 * (int64_t) g5_19; - int64_t f5g6_19 = f5 * (int64_t) g6_19; - int64_t f5g7_38 = f5_2 * (int64_t) g7_19; - int64_t f5g8_19 = f5 * (int64_t) g8_19; - int64_t f5g9_38 = f5_2 * (int64_t) g9_19; - int64_t f6g0 = f6 * (int64_t) g0; - int64_t f6g1 = f6 * (int64_t) g1; - int64_t f6g2 = f6 * (int64_t) g2; - int64_t f6g3 = f6 * (int64_t) g3; - int64_t f6g4_19 = f6 * (int64_t) g4_19; - int64_t f6g5_19 = f6 * (int64_t) g5_19; - int64_t f6g6_19 = f6 * (int64_t) g6_19; - int64_t f6g7_19 = f6 * (int64_t) g7_19; - int64_t f6g8_19 = f6 * (int64_t) g8_19; - int64_t f6g9_19 = f6 * (int64_t) g9_19; - int64_t f7g0 = f7 * (int64_t) g0; - int64_t f7g1_2 = f7_2 * (int64_t) g1; - int64_t f7g2 = f7 * (int64_t) g2; - int64_t f7g3_38 = f7_2 * (int64_t) g3_19; - int64_t f7g4_19 = f7 * (int64_t) g4_19; - int64_t f7g5_38 = f7_2 * (int64_t) g5_19; - int64_t f7g6_19 = f7 * (int64_t) g6_19; - int64_t f7g7_38 = f7_2 * (int64_t) g7_19; - int64_t f7g8_19 = f7 * (int64_t) g8_19; - int64_t f7g9_38 = f7_2 * (int64_t) g9_19; - int64_t f8g0 = f8 * (int64_t) g0; - int64_t f8g1 = f8 * (int64_t) g1; - int64_t f8g2_19 = f8 * (int64_t) g2_19; - int64_t f8g3_19 = f8 * (int64_t) g3_19; - int64_t f8g4_19 = f8 * (int64_t) g4_19; - int64_t f8g5_19 = f8 * (int64_t) g5_19; - int64_t f8g6_19 = f8 * (int64_t) g6_19; - int64_t f8g7_19 = f8 * (int64_t) g7_19; - int64_t f8g8_19 = f8 * (int64_t) g8_19; - int64_t f8g9_19 = f8 * (int64_t) g9_19; - int64_t f9g0 = f9 * (int64_t) g0; - int64_t f9g1_38 = f9_2 * (int64_t) g1_19; - int64_t f9g2_19 = f9 * (int64_t) g2_19; - int64_t f9g3_38 = f9_2 * (int64_t) g3_19; - int64_t f9g4_19 = f9 * (int64_t) g4_19; - int64_t f9g5_38 = f9_2 * (int64_t) g5_19; - int64_t f9g6_19 = f9 * (int64_t) g6_19; - int64_t f9g7_38 = f9_2 * (int64_t) g7_19; - int64_t f9g8_19 = f9 * (int64_t) g8_19; - int64_t f9g9_38 = f9_2 * (int64_t) g9_19; - int64_t h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38; - int64_t h1 = f0g1+f1g0 +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19; - int64_t h2 = f0g2+f1g1_2 +f2g0 +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38; - int64_t h3 = f0g3+f1g2 +f2g1 +f3g0 +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19; - int64_t h4 = f0g4+f1g3_2 +f2g2 +f3g1_2 +f4g0 +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38; - int64_t h5 = f0g5+f1g4 +f2g3 +f3g2 +f4g1 +f5g0 +f6g9_19+f7g8_19+f8g7_19+f9g6_19; - int64_t h6 = f0g6+f1g5_2 +f2g4 +f3g3_2 +f4g2 +f5g1_2 +f6g0 +f7g9_38+f8g8_19+f9g7_38; - int64_t h7 = f0g7+f1g6 +f2g5 +f3g4 +f4g3 +f5g2 +f6g1 +f7g0 +f8g9_19+f9g8_19; - int64_t h8 = f0g8+f1g7_2 +f2g6 +f3g5_2 +f4g4 +f5g3_2 +f6g2 +f7g1_2 +f8g0 +f9g9_38; - int64_t h9 = f0g9+f1g8 +f2g7 +f3g6 +f4g5 +f5g4 +f6g3 +f7g2 +f8g1 +f9g0 ; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - - /* - |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38)) - i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8 - |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19)) - i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 - */ - - carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; - carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; - /* |h0| <= 2^25 */ - /* |h4| <= 2^25 */ - /* |h1| <= 1.71*2^59 */ - /* |h5| <= 1.71*2^59 */ - - carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; - carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; - /* |h1| <= 2^24; from now on fits into int32 */ - /* |h5| <= 2^24; from now on fits into int32 */ - /* |h2| <= 1.41*2^60 */ - /* |h6| <= 1.41*2^60 */ - - carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; - carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; - /* |h2| <= 2^25; from now on fits into int32 unchanged */ - /* |h6| <= 2^25; from now on fits into int32 unchanged */ - /* |h3| <= 1.71*2^59 */ - /* |h7| <= 1.71*2^59 */ - - carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; - carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; - /* |h3| <= 2^24; from now on fits into int32 unchanged */ - /* |h7| <= 2^24; from now on fits into int32 unchanged */ - /* |h4| <= 1.72*2^34 */ - /* |h8| <= 1.41*2^60 */ - - carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; - carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; - /* |h4| <= 2^25; from now on fits into int32 unchanged */ - /* |h8| <= 2^25; from now on fits into int32 unchanged */ - /* |h5| <= 1.01*2^24 */ - /* |h9| <= 1.71*2^59 */ - - carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; - /* |h9| <= 2^24; from now on fits into int32 unchanged */ - /* |h0| <= 1.1*2^39 */ - - carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; - /* |h0| <= 2^25; from now on fits into int32 unchanged */ - /* |h1| <= 1.01*2^24 */ - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; -} - -/* From fe_neg.c */ - -/* -h = -f - -Preconditions: - |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. - -Postconditions: - |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. -*/ - -static void fe_neg(fe h, const fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t h0 = -f0; - int32_t h1 = -f1; - int32_t h2 = -f2; - int32_t h3 = -f3; - int32_t h4 = -f4; - int32_t h5 = -f5; - int32_t h6 = -f6; - int32_t h7 = -f7; - int32_t h8 = -f8; - int32_t h9 = -f9; - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; -} - -/* From fe_sq.c */ - -/* -h = f * f -Can overlap h with f. - -Preconditions: - |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. - -Postconditions: - |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. -*/ - -/* -See fe_mul.c for discussion of implementation strategy. -*/ - -static void fe_sq(fe h, const fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t f0_2 = 2 * f0; - int32_t f1_2 = 2 * f1; - int32_t f2_2 = 2 * f2; - int32_t f3_2 = 2 * f3; - int32_t f4_2 = 2 * f4; - int32_t f5_2 = 2 * f5; - int32_t f6_2 = 2 * f6; - int32_t f7_2 = 2 * f7; - int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ - int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ - int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ - int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ - int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ - int64_t f0f0 = f0 * (int64_t) f0; - int64_t f0f1_2 = f0_2 * (int64_t) f1; - int64_t f0f2_2 = f0_2 * (int64_t) f2; - int64_t f0f3_2 = f0_2 * (int64_t) f3; - int64_t f0f4_2 = f0_2 * (int64_t) f4; - int64_t f0f5_2 = f0_2 * (int64_t) f5; - int64_t f0f6_2 = f0_2 * (int64_t) f6; - int64_t f0f7_2 = f0_2 * (int64_t) f7; - int64_t f0f8_2 = f0_2 * (int64_t) f8; - int64_t f0f9_2 = f0_2 * (int64_t) f9; - int64_t f1f1_2 = f1_2 * (int64_t) f1; - int64_t f1f2_2 = f1_2 * (int64_t) f2; - int64_t f1f3_4 = f1_2 * (int64_t) f3_2; - int64_t f1f4_2 = f1_2 * (int64_t) f4; - int64_t f1f5_4 = f1_2 * (int64_t) f5_2; - int64_t f1f6_2 = f1_2 * (int64_t) f6; - int64_t f1f7_4 = f1_2 * (int64_t) f7_2; - int64_t f1f8_2 = f1_2 * (int64_t) f8; - int64_t f1f9_76 = f1_2 * (int64_t) f9_38; - int64_t f2f2 = f2 * (int64_t) f2; - int64_t f2f3_2 = f2_2 * (int64_t) f3; - int64_t f2f4_2 = f2_2 * (int64_t) f4; - int64_t f2f5_2 = f2_2 * (int64_t) f5; - int64_t f2f6_2 = f2_2 * (int64_t) f6; - int64_t f2f7_2 = f2_2 * (int64_t) f7; - int64_t f2f8_38 = f2_2 * (int64_t) f8_19; - int64_t f2f9_38 = f2 * (int64_t) f9_38; - int64_t f3f3_2 = f3_2 * (int64_t) f3; - int64_t f3f4_2 = f3_2 * (int64_t) f4; - int64_t f3f5_4 = f3_2 * (int64_t) f5_2; - int64_t f3f6_2 = f3_2 * (int64_t) f6; - int64_t f3f7_76 = f3_2 * (int64_t) f7_38; - int64_t f3f8_38 = f3_2 * (int64_t) f8_19; - int64_t f3f9_76 = f3_2 * (int64_t) f9_38; - int64_t f4f4 = f4 * (int64_t) f4; - int64_t f4f5_2 = f4_2 * (int64_t) f5; - int64_t f4f6_38 = f4_2 * (int64_t) f6_19; - int64_t f4f7_38 = f4 * (int64_t) f7_38; - int64_t f4f8_38 = f4_2 * (int64_t) f8_19; - int64_t f4f9_38 = f4 * (int64_t) f9_38; - int64_t f5f5_38 = f5 * (int64_t) f5_38; - int64_t f5f6_38 = f5_2 * (int64_t) f6_19; - int64_t f5f7_76 = f5_2 * (int64_t) f7_38; - int64_t f5f8_38 = f5_2 * (int64_t) f8_19; - int64_t f5f9_76 = f5_2 * (int64_t) f9_38; - int64_t f6f6_19 = f6 * (int64_t) f6_19; - int64_t f6f7_38 = f6 * (int64_t) f7_38; - int64_t f6f8_38 = f6_2 * (int64_t) f8_19; - int64_t f6f9_38 = f6 * (int64_t) f9_38; - int64_t f7f7_38 = f7 * (int64_t) f7_38; - int64_t f7f8_38 = f7_2 * (int64_t) f8_19; - int64_t f7f9_76 = f7_2 * (int64_t) f9_38; - int64_t f8f8_19 = f8 * (int64_t) f8_19; - int64_t f8f9_38 = f8 * (int64_t) f9_38; - int64_t f9f9_38 = f9 * (int64_t) f9_38; - int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38; - int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38; - int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19; - int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38; - int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38; - int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38; - int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19; - int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38; - int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38; - int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - - carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; - carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; - - carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; - carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; - - carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; - carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; - - carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; - carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; - - carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; - carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; - - carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; - - carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; -} - -/* From fe_sq2.c */ - -/* -h = 2 * f * f -Can overlap h with f. - -Preconditions: - |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. - -Postconditions: - |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. -*/ - -/* -See fe_mul.c for discussion of implementation strategy. -*/ - -static void fe_sq2(fe h, const fe f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t f0_2 = 2 * f0; - int32_t f1_2 = 2 * f1; - int32_t f2_2 = 2 * f2; - int32_t f3_2 = 2 * f3; - int32_t f4_2 = 2 * f4; - int32_t f5_2 = 2 * f5; - int32_t f6_2 = 2 * f6; - int32_t f7_2 = 2 * f7; - int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ - int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ - int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ - int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ - int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ - int64_t f0f0 = f0 * (int64_t) f0; - int64_t f0f1_2 = f0_2 * (int64_t) f1; - int64_t f0f2_2 = f0_2 * (int64_t) f2; - int64_t f0f3_2 = f0_2 * (int64_t) f3; - int64_t f0f4_2 = f0_2 * (int64_t) f4; - int64_t f0f5_2 = f0_2 * (int64_t) f5; - int64_t f0f6_2 = f0_2 * (int64_t) f6; - int64_t f0f7_2 = f0_2 * (int64_t) f7; - int64_t f0f8_2 = f0_2 * (int64_t) f8; - int64_t f0f9_2 = f0_2 * (int64_t) f9; - int64_t f1f1_2 = f1_2 * (int64_t) f1; - int64_t f1f2_2 = f1_2 * (int64_t) f2; - int64_t f1f3_4 = f1_2 * (int64_t) f3_2; - int64_t f1f4_2 = f1_2 * (int64_t) f4; - int64_t f1f5_4 = f1_2 * (int64_t) f5_2; - int64_t f1f6_2 = f1_2 * (int64_t) f6; - int64_t f1f7_4 = f1_2 * (int64_t) f7_2; - int64_t f1f8_2 = f1_2 * (int64_t) f8; - int64_t f1f9_76 = f1_2 * (int64_t) f9_38; - int64_t f2f2 = f2 * (int64_t) f2; - int64_t f2f3_2 = f2_2 * (int64_t) f3; - int64_t f2f4_2 = f2_2 * (int64_t) f4; - int64_t f2f5_2 = f2_2 * (int64_t) f5; - int64_t f2f6_2 = f2_2 * (int64_t) f6; - int64_t f2f7_2 = f2_2 * (int64_t) f7; - int64_t f2f8_38 = f2_2 * (int64_t) f8_19; - int64_t f2f9_38 = f2 * (int64_t) f9_38; - int64_t f3f3_2 = f3_2 * (int64_t) f3; - int64_t f3f4_2 = f3_2 * (int64_t) f4; - int64_t f3f5_4 = f3_2 * (int64_t) f5_2; - int64_t f3f6_2 = f3_2 * (int64_t) f6; - int64_t f3f7_76 = f3_2 * (int64_t) f7_38; - int64_t f3f8_38 = f3_2 * (int64_t) f8_19; - int64_t f3f9_76 = f3_2 * (int64_t) f9_38; - int64_t f4f4 = f4 * (int64_t) f4; - int64_t f4f5_2 = f4_2 * (int64_t) f5; - int64_t f4f6_38 = f4_2 * (int64_t) f6_19; - int64_t f4f7_38 = f4 * (int64_t) f7_38; - int64_t f4f8_38 = f4_2 * (int64_t) f8_19; - int64_t f4f9_38 = f4 * (int64_t) f9_38; - int64_t f5f5_38 = f5 * (int64_t) f5_38; - int64_t f5f6_38 = f5_2 * (int64_t) f6_19; - int64_t f5f7_76 = f5_2 * (int64_t) f7_38; - int64_t f5f8_38 = f5_2 * (int64_t) f8_19; - int64_t f5f9_76 = f5_2 * (int64_t) f9_38; - int64_t f6f6_19 = f6 * (int64_t) f6_19; - int64_t f6f7_38 = f6 * (int64_t) f7_38; - int64_t f6f8_38 = f6_2 * (int64_t) f8_19; - int64_t f6f9_38 = f6 * (int64_t) f9_38; - int64_t f7f7_38 = f7 * (int64_t) f7_38; - int64_t f7f8_38 = f7_2 * (int64_t) f8_19; - int64_t f7f9_76 = f7_2 * (int64_t) f9_38; - int64_t f8f8_19 = f8 * (int64_t) f8_19; - int64_t f8f9_38 = f8 * (int64_t) f9_38; - int64_t f9f9_38 = f9 * (int64_t) f9_38; - int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38; - int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38; - int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19; - int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38; - int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38; - int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38; - int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19; - int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38; - int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38; - int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - - h0 += h0; - h1 += h1; - h2 += h2; - h3 += h3; - h4 += h4; - h5 += h5; - h6 += h6; - h7 += h7; - h8 += h8; - h9 += h9; - - carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; - carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; - - carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; - carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; - - carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; - carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; - - carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; - carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; - - carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; - carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; - - carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; - - carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; - - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; -} - -/* From fe_sub.c */ - -/* -h = f - g -Can overlap h with f or g. - -Preconditions: - |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. - |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. - -Postconditions: - |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. -*/ - -static void fe_sub(fe h, const fe f, const fe g) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - int32_t h0 = f0 - g0; - int32_t h1 = f1 - g1; - int32_t h2 = f2 - g2; - int32_t h3 = f3 - g3; - int32_t h4 = f4 - g4; - int32_t h5 = f5 - g5; - int32_t h6 = f6 - g6; - int32_t h7 = f7 - g7; - int32_t h8 = f8 - g8; - int32_t h9 = f9 - g9; - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; -} - -/* From fe_tobytes.c */ - -/* -Preconditions: - |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. - -Write p=2^255-19; q=floor(h/p). -Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). - -Proof: - Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. - Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4. - - Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). - Then 0> 25; - q = (h0 + q) >> 26; - q = (h1 + q) >> 25; - q = (h2 + q) >> 26; - q = (h3 + q) >> 25; - q = (h4 + q) >> 26; - q = (h5 + q) >> 25; - q = (h6 + q) >> 26; - q = (h7 + q) >> 25; - q = (h8 + q) >> 26; - q = (h9 + q) >> 25; - - /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ - h0 += 19 * q; - /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ - - carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26; - carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25; - carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26; - carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25; - carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26; - carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25; - carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26; - carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25; - carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26; - carry9 = h9 >> 25; h9 -= carry9 << 25; - /* h10 = carry9 */ - - /* - Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. - Have h0+...+2^230 h9 between 0 and 2^255-1; - evidently 2^255 h10-2^255 q = 0. - Goal: Output h0+...+2^230 h9. - */ - - s[0] = h0 >> 0; - s[1] = h0 >> 8; - s[2] = h0 >> 16; - s[3] = (h0 >> 24) | (h1 << 2); - s[4] = h1 >> 6; - s[5] = h1 >> 14; - s[6] = (h1 >> 22) | (h2 << 3); - s[7] = h2 >> 5; - s[8] = h2 >> 13; - s[9] = (h2 >> 21) | (h3 << 5); - s[10] = h3 >> 3; - s[11] = h3 >> 11; - s[12] = (h3 >> 19) | (h4 << 6); - s[13] = h4 >> 2; - s[14] = h4 >> 10; - s[15] = h4 >> 18; - s[16] = h5 >> 0; - s[17] = h5 >> 8; - s[18] = h5 >> 16; - s[19] = (h5 >> 24) | (h6 << 1); - s[20] = h6 >> 7; - s[21] = h6 >> 15; - s[22] = (h6 >> 23) | (h7 << 3); - s[23] = h7 >> 5; - s[24] = h7 >> 13; - s[25] = (h7 >> 21) | (h8 << 4); - s[26] = h8 >> 4; - s[27] = h8 >> 12; - s[28] = (h8 >> 20) | (h9 << 6); - s[29] = h9 >> 2; - s[30] = h9 >> 10; - s[31] = h9 >> 18; -} - -/* From ge_add.c */ - -void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { - fe t0; - fe_add(r->X, p->Y, p->X); - fe_sub(r->Y, p->Y, p->X); - fe_mul(r->Z, r->X, q->YplusX); - fe_mul(r->Y, r->Y, q->YminusX); - fe_mul(r->T, q->T2d, p->T); - fe_mul(r->X, p->Z, q->Z); - fe_add(t0, r->X, r->X); - fe_sub(r->X, r->Z, r->Y); - fe_add(r->Y, r->Z, r->Y); - fe_add(r->Z, t0, r->T); - fe_sub(r->T, t0, r->T); -} - -/* From ge_double_scalarmult.c, modified */ - -static void slide(signed char *r, const unsigned char *a) { - int i; - int b; - int k; - - for (i = 0; i < 256; ++i) { - r[i] = 1 & (a[i >> 3] >> (i & 7)); - } - - for (i = 0; i < 256; ++i) { - if (r[i]) { - for (b = 1; b <= 6 && i + b < 256; ++b) { - if (r[i + b]) { - if (r[i] + (r[i + b] << b) <= 15) { - r[i] += r[i + b] << b; r[i + b] = 0; - } else if (r[i] - (r[i + b] << b) >= -15) { - r[i] -= r[i + b] << b; - for (k = i + b; k < 256; ++k) { - if (!r[k]) { - r[k] = 1; - break; - } - r[k] = 0; - } - } else - break; - } - } - } - } -} - -void ge_dsm_precomp(ge_dsmp r, const ge_p3 *s) { - ge_p1p1 t; - ge_p3 s2, u; - ge_p3_to_cached(&r[0], s); - ge_p3_dbl(&t, s); ge_p1p1_to_p3(&s2, &t); - ge_add(&t, &s2, &r[0]); ge_p1p1_to_p3(&u, &t); ge_p3_to_cached(&r[1], &u); - ge_add(&t, &s2, &r[1]); ge_p1p1_to_p3(&u, &t); ge_p3_to_cached(&r[2], &u); - ge_add(&t, &s2, &r[2]); ge_p1p1_to_p3(&u, &t); ge_p3_to_cached(&r[3], &u); - ge_add(&t, &s2, &r[3]); ge_p1p1_to_p3(&u, &t); ge_p3_to_cached(&r[4], &u); - ge_add(&t, &s2, &r[4]); ge_p1p1_to_p3(&u, &t); ge_p3_to_cached(&r[5], &u); - ge_add(&t, &s2, &r[5]); ge_p1p1_to_p3(&u, &t); ge_p3_to_cached(&r[6], &u); - ge_add(&t, &s2, &r[6]); ge_p1p1_to_p3(&u, &t); ge_p3_to_cached(&r[7], &u); -} - -/* -r = a * A + b * B -where a = a[0]+256*a[1]+...+256^31 a[31]. -and b = b[0]+256*b[1]+...+256^31 b[31]. -B is the Ed25519 base point (x,4/5) with x positive. -*/ - -void ge_double_scalarmult_base_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b) { - signed char aslide[256]; - signed char bslide[256]; - ge_dsmp Ai; /* A, 3A, 5A, 7A, 9A, 11A, 13A, 15A */ - ge_p1p1 t; - ge_p3 u; - int i; - - slide(aslide, a); - slide(bslide, b); - ge_dsm_precomp(Ai, A); - - ge_p2_0(r); - - for (i = 255; i >= 0; --i) { - if (aslide[i] || bslide[i]) break; - } - - for (; i >= 0; --i) { - ge_p2_dbl(&t, r); - - if (aslide[i] > 0) { - ge_p1p1_to_p3(&u, &t); - ge_add(&t, &u, &Ai[aslide[i]/2]); - } else if (aslide[i] < 0) { - ge_p1p1_to_p3(&u, &t); - ge_sub(&t, &u, &Ai[(-aslide[i])/2]); - } - - if (bslide[i] > 0) { - ge_p1p1_to_p3(&u, &t); - ge_madd(&t, &u, &ge_Bi[bslide[i]/2]); - } else if (bslide[i] < 0) { - ge_p1p1_to_p3(&u, &t); - ge_msub(&t, &u, &ge_Bi[(-bslide[i])/2]); - } - - ge_p1p1_to_p2(r, &t); - } -} - -void ge_double_scalarmult_base_vartime_p3(ge_p3 *r3, const unsigned char *a, const ge_p3 *A, const unsigned char *b) { - signed char aslide[256]; - signed char bslide[256]; - ge_dsmp Ai; /* A, 3A, 5A, 7A, 9A, 11A, 13A, 15A */ - ge_p1p1 t; - ge_p3 u; - ge_p2 r; - int i; - - slide(aslide, a); - slide(bslide, b); - ge_dsm_precomp(Ai, A); - - ge_p2_0(&r); - - for (i = 255; i >= 0; --i) { - if (aslide[i] || bslide[i]) break; - } - - for (; i >= 0; --i) { - ge_p2_dbl(&t, &r); - - if (aslide[i] > 0) { - ge_p1p1_to_p3(&u, &t); - ge_add(&t, &u, &Ai[aslide[i]/2]); - } else if (aslide[i] < 0) { - ge_p1p1_to_p3(&u, &t); - ge_sub(&t, &u, &Ai[(-aslide[i])/2]); - } - - if (bslide[i] > 0) { - ge_p1p1_to_p3(&u, &t); - ge_madd(&t, &u, &ge_Bi[bslide[i]/2]); - } else if (bslide[i] < 0) { - ge_p1p1_to_p3(&u, &t); - ge_msub(&t, &u, &ge_Bi[(-bslide[i])/2]); - } - - if (i == 0) - ge_p1p1_to_p3(r3, &t); - else - ge_p1p1_to_p2(&r, &t); - } -} - -/* From ge_frombytes.c, modified */ - -int ge_frombytes_vartime(ge_p3 *h, const unsigned char *s) { - fe u; - fe v; - fe vxx; - fe check; - - /* From fe_frombytes.c */ - - int64_t h0 = load_4(s); - int64_t h1 = load_3(s + 4) << 6; - int64_t h2 = load_3(s + 7) << 5; - int64_t h3 = load_3(s + 10) << 3; - int64_t h4 = load_3(s + 13) << 2; - int64_t h5 = load_4(s + 16); - int64_t h6 = load_3(s + 20) << 7; - int64_t h7 = load_3(s + 23) << 5; - int64_t h8 = load_3(s + 26) << 4; - int64_t h9 = (load_3(s + 29) & 8388607) << 2; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - - /* Validate the number to be canonical */ - if (h9 == 33554428 && h8 == 268435440 && h7 == 536870880 && h6 == 2147483520 && - h5 == 4294967295 && h4 == 67108860 && h3 == 134217720 && h2 == 536870880 && - h1 == 1073741760 && h0 >= 4294967277) { - return -1; - } - - carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; - carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; - carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; - carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; - carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; - - carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; - carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; - carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; - carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; - carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; - - h->Y[0] = h0; - h->Y[1] = h1; - h->Y[2] = h2; - h->Y[3] = h3; - h->Y[4] = h4; - h->Y[5] = h5; - h->Y[6] = h6; - h->Y[7] = h7; - h->Y[8] = h8; - h->Y[9] = h9; - - /* End fe_frombytes.c */ - - fe_1(h->Z); - fe_sq(u, h->Y); - fe_mul(v, u, fe_d); - fe_sub(u, u, h->Z); /* u = y^2-1 */ - fe_add(v, v, h->Z); /* v = dy^2+1 */ - - fe_divpowm1(h->X, u, v); /* x = uv^3(uv^7)^((q-5)/8) */ - - fe_sq(vxx, h->X); - fe_mul(vxx, vxx, v); - fe_sub(check, vxx, u); /* vx^2-u */ - if (fe_isnonzero(check)) { - fe_add(check, vxx, u); /* vx^2+u */ - if (fe_isnonzero(check)) { - return -1; - } - fe_mul(h->X, h->X, fe_sqrtm1); - } - - if (fe_isnegative(h->X) != (s[31] >> 7)) { - /* If x = 0, the sign must be positive */ - if (!fe_isnonzero(h->X)) { - return -1; - } - fe_neg(h->X, h->X); - } - - fe_mul(h->T, h->X, h->Y); - return 0; -} - -/* From ge_madd.c */ - -/* -r = p + q -*/ - -static void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { - fe t0; - fe_add(r->X, p->Y, p->X); - fe_sub(r->Y, p->Y, p->X); - fe_mul(r->Z, r->X, q->yplusx); - fe_mul(r->Y, r->Y, q->yminusx); - fe_mul(r->T, q->xy2d, p->T); - fe_add(t0, p->Z, p->Z); - fe_sub(r->X, r->Z, r->Y); - fe_add(r->Y, r->Z, r->Y); - fe_add(r->Z, t0, r->T); - fe_sub(r->T, t0, r->T); -} - -/* From ge_msub.c */ - -/* -r = p - q -*/ - -static void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { - fe t0; - fe_add(r->X, p->Y, p->X); - fe_sub(r->Y, p->Y, p->X); - fe_mul(r->Z, r->X, q->yminusx); - fe_mul(r->Y, r->Y, q->yplusx); - fe_mul(r->T, q->xy2d, p->T); - fe_add(t0, p->Z, p->Z); - fe_sub(r->X, r->Z, r->Y); - fe_add(r->Y, r->Z, r->Y); - fe_sub(r->Z, t0, r->T); - fe_add(r->T, t0, r->T); -} - -/* From ge_p1p1_to_p2.c */ - -/* -r = p -*/ - -void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) { - fe_mul(r->X, p->X, p->T); - fe_mul(r->Y, p->Y, p->Z); - fe_mul(r->Z, p->Z, p->T); -} - -/* From ge_p1p1_to_p3.c */ - -/* -r = p -*/ - -void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) { - fe_mul(r->X, p->X, p->T); - fe_mul(r->Y, p->Y, p->Z); - fe_mul(r->Z, p->Z, p->T); - fe_mul(r->T, p->X, p->Y); -} - -/* From ge_p2_0.c */ - -static void ge_p2_0(ge_p2 *h) { - fe_0(h->X); - fe_1(h->Y); - fe_1(h->Z); -} - -/* From ge_p2_dbl.c */ - -/* -r = 2 * p -*/ - -void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) { - fe t0; - fe_sq(r->X, p->X); - fe_sq(r->Z, p->Y); - fe_sq2(r->T, p->Z); - fe_add(r->Y, p->X, p->Y); - fe_sq(t0, r->Y); - fe_add(r->Y, r->Z, r->X); - fe_sub(r->Z, r->Z, r->X); - fe_sub(r->X, t0, r->Y); - fe_sub(r->T, r->T, r->Z); -} - -/* From ge_p3_0.c */ - -static void ge_p3_0(ge_p3 *h) { - fe_0(h->X); - fe_1(h->Y); - fe_1(h->Z); - fe_0(h->T); -} - -/* From ge_p3_dbl.c */ - -/* -r = 2 * p -*/ - -static void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) { - ge_p2 q; - ge_p3_to_p2(&q, p); - ge_p2_dbl(r, &q); -} - -/* From ge_p3_to_cached.c */ - -/* -r = p -*/ - -void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) { - fe_add(r->YplusX, p->Y, p->X); - fe_sub(r->YminusX, p->Y, p->X); - fe_copy(r->Z, p->Z); - fe_mul(r->T2d, p->T, fe_d2); -} - -/* From ge_p3_to_p2.c */ - -/* -r = p -*/ - -void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) { - fe_copy(r->X, p->X); - fe_copy(r->Y, p->Y); - fe_copy(r->Z, p->Z); -} - -/* From ge_p3_tobytes.c */ - -void ge_p3_tobytes(unsigned char *s, const ge_p3 *h) { - fe recip; - fe x; - fe y; - - fe_invert(recip, h->Z); - fe_mul(x, h->X, recip); - fe_mul(y, h->Y, recip); - fe_tobytes(s, y); - s[31] ^= fe_isnegative(x) << 7; -} - -/* From ge_precomp_0.c */ - -static void ge_precomp_0(ge_precomp *h) { - fe_1(h->yplusx); - fe_1(h->yminusx); - fe_0(h->xy2d); -} - -/* From ge_scalarmult_base.c */ - -static unsigned char equal(signed char b, signed char c) { - unsigned char ub = b; - unsigned char uc = c; - unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ - uint32_t y = x; /* 0: yes; 1..255: no */ - y -= 1; /* 4294967295: yes; 0..254: no */ - y >>= 31; /* 1: yes; 0: no */ - return y; -} - -static unsigned char negative(signed char b) { - unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ - x >>= 63; /* 1: yes; 0: no */ - return x; -} - -static void ge_precomp_cmov(ge_precomp *t, const ge_precomp *u, unsigned char b) { - fe_cmov(t->yplusx, u->yplusx, b); - fe_cmov(t->yminusx, u->yminusx, b); - fe_cmov(t->xy2d, u->xy2d, b); -} - -static void select(ge_precomp *t, int pos, signed char b) { - ge_precomp minust; - unsigned char bnegative = negative(b); - unsigned char babs = b - (((-bnegative) & b) << 1); - - ge_precomp_0(t); - ge_precomp_cmov(t, &ge_base[pos][0], equal(babs, 1)); - ge_precomp_cmov(t, &ge_base[pos][1], equal(babs, 2)); - ge_precomp_cmov(t, &ge_base[pos][2], equal(babs, 3)); - ge_precomp_cmov(t, &ge_base[pos][3], equal(babs, 4)); - ge_precomp_cmov(t, &ge_base[pos][4], equal(babs, 5)); - ge_precomp_cmov(t, &ge_base[pos][5], equal(babs, 6)); - ge_precomp_cmov(t, &ge_base[pos][6], equal(babs, 7)); - ge_precomp_cmov(t, &ge_base[pos][7], equal(babs, 8)); - fe_copy(minust.yplusx, t->yminusx); - fe_copy(minust.yminusx, t->yplusx); - fe_neg(minust.xy2d, t->xy2d); - ge_precomp_cmov(t, &minust, bnegative); -} - -/* -h = a * B -where a = a[0]+256*a[1]+...+256^31 a[31] -B is the Ed25519 base point (x,4/5) with x positive. - -Preconditions: - a[31] <= 127 -*/ - -void ge_scalarmult_base(ge_p3 *h, const unsigned char *a) { - signed char e[64]; - signed char carry; - ge_p1p1 r; - ge_p2 s; - ge_precomp t; - int i; - - for (i = 0; i < 32; ++i) { - e[2 * i + 0] = (a[i] >> 0) & 15; - e[2 * i + 1] = (a[i] >> 4) & 15; - } - /* each e[i] is between 0 and 15 */ - /* e[63] is between 0 and 7 */ - - carry = 0; - for (i = 0; i < 63; ++i) { - e[i] += carry; - carry = e[i] + 8; - carry >>= 4; - e[i] -= carry << 4; - } - e[63] += carry; - /* each e[i] is between -8 and 8 */ - - ge_p3_0(h); - for (i = 1; i < 64; i += 2) { - select(&t, i / 2, e[i]); - ge_madd(&r, h, &t); ge_p1p1_to_p3(h, &r); - } - - ge_p3_dbl(&r, h); ge_p1p1_to_p2(&s, &r); - ge_p2_dbl(&r, &s); ge_p1p1_to_p2(&s, &r); - ge_p2_dbl(&r, &s); ge_p1p1_to_p2(&s, &r); - ge_p2_dbl(&r, &s); ge_p1p1_to_p3(h, &r); - - for (i = 0; i < 64; i += 2) { - select(&t, i / 2, e[i]); - ge_madd(&r, h, &t); ge_p1p1_to_p3(h, &r); - } -} - -/* From ge_sub.c */ - -/* -r = p - q -*/ - -void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { - fe t0; - fe_add(r->X, p->Y, p->X); - fe_sub(r->Y, p->Y, p->X); - fe_mul(r->Z, r->X, q->YminusX); - fe_mul(r->Y, r->Y, q->YplusX); - fe_mul(r->T, q->T2d, p->T); - fe_mul(r->X, p->Z, q->Z); - fe_add(t0, r->X, r->X); - fe_sub(r->X, r->Z, r->Y); - fe_add(r->Y, r->Z, r->Y); - fe_sub(r->Z, t0, r->T); - fe_add(r->T, t0, r->T); -} - -/* From ge_tobytes.c */ - -void ge_tobytes(unsigned char *s, const ge_p2 *h) { - fe recip; - fe x; - fe y; - - fe_invert(recip, h->Z); - fe_mul(x, h->X, recip); - fe_mul(y, h->Y, recip); - fe_tobytes(s, y); - s[31] ^= fe_isnegative(x) << 7; -} - -/* From sc_reduce.c */ - -/* -Input: - s[0]+256*s[1]+...+256^63*s[63] = s - -Output: - s[0]+256*s[1]+...+256^31*s[31] = s mod l - where l = 2^252 + 27742317777372353535851937790883648493. - Overwrites s in place. -*/ - -void sc_reduce(unsigned char *s) { - int64_t s0 = 2097151 & load_3(s); - int64_t s1 = 2097151 & (load_4(s + 2) >> 5); - int64_t s2 = 2097151 & (load_3(s + 5) >> 2); - int64_t s3 = 2097151 & (load_4(s + 7) >> 7); - int64_t s4 = 2097151 & (load_4(s + 10) >> 4); - int64_t s5 = 2097151 & (load_3(s + 13) >> 1); - int64_t s6 = 2097151 & (load_4(s + 15) >> 6); - int64_t s7 = 2097151 & (load_3(s + 18) >> 3); - int64_t s8 = 2097151 & load_3(s + 21); - int64_t s9 = 2097151 & (load_4(s + 23) >> 5); - int64_t s10 = 2097151 & (load_3(s + 26) >> 2); - int64_t s11 = 2097151 & (load_4(s + 28) >> 7); - int64_t s12 = 2097151 & (load_4(s + 31) >> 4); - int64_t s13 = 2097151 & (load_3(s + 34) >> 1); - int64_t s14 = 2097151 & (load_4(s + 36) >> 6); - int64_t s15 = 2097151 & (load_3(s + 39) >> 3); - int64_t s16 = 2097151 & load_3(s + 42); - int64_t s17 = 2097151 & (load_4(s + 44) >> 5); - int64_t s18 = 2097151 & (load_3(s + 47) >> 2); - int64_t s19 = 2097151 & (load_4(s + 49) >> 7); - int64_t s20 = 2097151 & (load_4(s + 52) >> 4); - int64_t s21 = 2097151 & (load_3(s + 55) >> 1); - int64_t s22 = 2097151 & (load_4(s + 57) >> 6); - int64_t s23 = (load_4(s + 60) >> 3); - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - int64_t carry10; - int64_t carry11; - int64_t carry12; - int64_t carry13; - int64_t carry14; - int64_t carry15; - int64_t carry16; - - s11 += s23 * 666643; - s12 += s23 * 470296; - s13 += s23 * 654183; - s14 -= s23 * 997805; - s15 += s23 * 136657; - s16 -= s23 * 683901; - - s10 += s22 * 666643; - s11 += s22 * 470296; - s12 += s22 * 654183; - s13 -= s22 * 997805; - s14 += s22 * 136657; - s15 -= s22 * 683901; - - s9 += s21 * 666643; - s10 += s21 * 470296; - s11 += s21 * 654183; - s12 -= s21 * 997805; - s13 += s21 * 136657; - s14 -= s21 * 683901; - - s8 += s20 * 666643; - s9 += s20 * 470296; - s10 += s20 * 654183; - s11 -= s20 * 997805; - s12 += s20 * 136657; - s13 -= s20 * 683901; - - s7 += s19 * 666643; - s8 += s19 * 470296; - s9 += s19 * 654183; - s10 -= s19 * 997805; - s11 += s19 * 136657; - s12 -= s19 * 683901; - - s6 += s18 * 666643; - s7 += s18 * 470296; - s8 += s18 * 654183; - s9 -= s18 * 997805; - s10 += s18 * 136657; - s11 -= s18 * 683901; - - carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; - carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; - carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; - carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; - carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; - carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; - - carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; - carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; - carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; - carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; - carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; - - s5 += s17 * 666643; - s6 += s17 * 470296; - s7 += s17 * 654183; - s8 -= s17 * 997805; - s9 += s17 * 136657; - s10 -= s17 * 683901; - - s4 += s16 * 666643; - s5 += s16 * 470296; - s6 += s16 * 654183; - s7 -= s16 * 997805; - s8 += s16 * 136657; - s9 -= s16 * 683901; - - s3 += s15 * 666643; - s4 += s15 * 470296; - s5 += s15 * 654183; - s6 -= s15 * 997805; - s7 += s15 * 136657; - s8 -= s15 * 683901; - - s2 += s14 * 666643; - s3 += s14 * 470296; - s4 += s14 * 654183; - s5 -= s14 * 997805; - s6 += s14 * 136657; - s7 -= s14 * 683901; - - s1 += s13 * 666643; - s2 += s13 * 470296; - s3 += s13 * 654183; - s4 -= s13 * 997805; - s5 += s13 * 136657; - s6 -= s13 * 683901; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - - carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; - carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; - carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; - carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; - carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; - carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; - - carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; - carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; - carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; - carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; - carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; - carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - - carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; - carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; - carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; - carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; - carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; - carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; - carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; - carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; - carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; - carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; - carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; - carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - - carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; - carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; - carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; - carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; - carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; - carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; - carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; - carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; - carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; - carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; - carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; - - s[0] = s0 >> 0; - s[1] = s0 >> 8; - s[2] = (s0 >> 16) | (s1 << 5); - s[3] = s1 >> 3; - s[4] = s1 >> 11; - s[5] = (s1 >> 19) | (s2 << 2); - s[6] = s2 >> 6; - s[7] = (s2 >> 14) | (s3 << 7); - s[8] = s3 >> 1; - s[9] = s3 >> 9; - s[10] = (s3 >> 17) | (s4 << 4); - s[11] = s4 >> 4; - s[12] = s4 >> 12; - s[13] = (s4 >> 20) | (s5 << 1); - s[14] = s5 >> 7; - s[15] = (s5 >> 15) | (s6 << 6); - s[16] = s6 >> 2; - s[17] = s6 >> 10; - s[18] = (s6 >> 18) | (s7 << 3); - s[19] = s7 >> 5; - s[20] = s7 >> 13; - s[21] = s8 >> 0; - s[22] = s8 >> 8; - s[23] = (s8 >> 16) | (s9 << 5); - s[24] = s9 >> 3; - s[25] = s9 >> 11; - s[26] = (s9 >> 19) | (s10 << 2); - s[27] = s10 >> 6; - s[28] = (s10 >> 14) | (s11 << 7); - s[29] = s11 >> 1; - s[30] = s11 >> 9; - s[31] = s11 >> 17; -} - -/* New code */ - -static void fe_divpowm1(fe r, const fe u, const fe v) { - fe v3, uv7, t0, t1, t2; - int i; - - fe_sq(v3, v); - fe_mul(v3, v3, v); /* v3 = v^3 */ - fe_sq(uv7, v3); - fe_mul(uv7, uv7, v); - fe_mul(uv7, uv7, u); /* uv7 = uv^7 */ - - /*fe_pow22523(uv7, uv7);*/ - - /* From fe_pow22523.c */ - - fe_sq(t0, uv7); - fe_sq(t1, t0); - fe_sq(t1, t1); - fe_mul(t1, uv7, t1); - fe_mul(t0, t0, t1); - fe_sq(t0, t0); - fe_mul(t0, t1, t0); - fe_sq(t1, t0); - for (i = 0; i < 4; ++i) { - fe_sq(t1, t1); - } - fe_mul(t0, t1, t0); - fe_sq(t1, t0); - for (i = 0; i < 9; ++i) { - fe_sq(t1, t1); - } - fe_mul(t1, t1, t0); - fe_sq(t2, t1); - for (i = 0; i < 19; ++i) { - fe_sq(t2, t2); - } - fe_mul(t1, t2, t1); - for (i = 0; i < 10; ++i) { - fe_sq(t1, t1); - } - fe_mul(t0, t1, t0); - fe_sq(t1, t0); - for (i = 0; i < 49; ++i) { - fe_sq(t1, t1); - } - fe_mul(t1, t1, t0); - fe_sq(t2, t1); - for (i = 0; i < 99; ++i) { - fe_sq(t2, t2); - } - fe_mul(t1, t2, t1); - for (i = 0; i < 50; ++i) { - fe_sq(t1, t1); - } - fe_mul(t0, t1, t0); - fe_sq(t0, t0); - fe_sq(t0, t0); - fe_mul(t0, t0, uv7); - - /* End fe_pow22523.c */ - /* t0 = (uv^7)^((q-5)/8) */ - fe_mul(t0, t0, v3); - fe_mul(r, t0, u); /* u^(m+1)v^(-(m+1)) */ -} - -static void ge_cached_0(ge_cached *r) { - fe_1(r->YplusX); - fe_1(r->YminusX); - fe_1(r->Z); - fe_0(r->T2d); -} - -static void ge_cached_cmov(ge_cached *t, const ge_cached *u, unsigned char b) { - fe_cmov(t->YplusX, u->YplusX, b); - fe_cmov(t->YminusX, u->YminusX, b); - fe_cmov(t->Z, u->Z, b); - fe_cmov(t->T2d, u->T2d, b); -} - -/* Assumes that a[31] <= 127 */ -void ge_scalarmult(ge_p2 *r, const unsigned char *a, const ge_p3 *A) { - signed char e[64]; - int carry, carry2, i; - ge_cached Ai[8]; /* 1 * A, 2 * A, ..., 8 * A */ - ge_p1p1 t; - ge_p3 u; - - carry = 0; /* 0..1 */ - for (i = 0; i < 31; i++) { - carry += a[i]; /* 0..256 */ - carry2 = (carry + 8) >> 4; /* 0..16 */ - e[2 * i] = carry - (carry2 << 4); /* -8..7 */ - carry = (carry2 + 8) >> 4; /* 0..1 */ - e[2 * i + 1] = carry2 - (carry << 4); /* -8..7 */ - } - carry += a[31]; /* 0..128 */ - carry2 = (carry + 8) >> 4; /* 0..8 */ - e[62] = carry - (carry2 << 4); /* -8..7 */ - e[63] = carry2; /* 0..8 */ - - ge_p3_to_cached(&Ai[0], A); - for (i = 0; i < 7; i++) { - ge_add(&t, A, &Ai[i]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[i + 1], &u); - } - - ge_p2_0(r); - for (i = 63; i >= 0; i--) { - signed char b = e[i]; - unsigned char bnegative = negative(b); - unsigned char babs = b - (((-bnegative) & b) << 1); - ge_cached cur, minuscur; - ge_p2_dbl(&t, r); - ge_p1p1_to_p2(r, &t); - ge_p2_dbl(&t, r); - ge_p1p1_to_p2(r, &t); - ge_p2_dbl(&t, r); - ge_p1p1_to_p2(r, &t); - ge_p2_dbl(&t, r); - ge_p1p1_to_p3(&u, &t); - ge_cached_0(&cur); - ge_cached_cmov(&cur, &Ai[0], equal(babs, 1)); - ge_cached_cmov(&cur, &Ai[1], equal(babs, 2)); - ge_cached_cmov(&cur, &Ai[2], equal(babs, 3)); - ge_cached_cmov(&cur, &Ai[3], equal(babs, 4)); - ge_cached_cmov(&cur, &Ai[4], equal(babs, 5)); - ge_cached_cmov(&cur, &Ai[5], equal(babs, 6)); - ge_cached_cmov(&cur, &Ai[6], equal(babs, 7)); - ge_cached_cmov(&cur, &Ai[7], equal(babs, 8)); - fe_copy(minuscur.YplusX, cur.YminusX); - fe_copy(minuscur.YminusX, cur.YplusX); - fe_copy(minuscur.Z, cur.Z); - fe_neg(minuscur.T2d, cur.T2d); - ge_cached_cmov(&cur, &minuscur, bnegative); - ge_add(&t, &u, &cur); - ge_p1p1_to_p2(r, &t); - } -} - -void ge_scalarmult_p3(ge_p3 *r3, const unsigned char *a, const ge_p3 *A) { - signed char e[64]; - int carry, carry2, i; - ge_cached Ai[8]; /* 1 * A, 2 * A, ..., 8 * A */ - ge_p1p1 t; - ge_p3 u; - ge_p2 r; - - carry = 0; /* 0..1 */ - for (i = 0; i < 31; i++) { - carry += a[i]; /* 0..256 */ - carry2 = (carry + 8) >> 4; /* 0..16 */ - e[2 * i] = carry - (carry2 << 4); /* -8..7 */ - carry = (carry2 + 8) >> 4; /* 0..1 */ - e[2 * i + 1] = carry2 - (carry << 4); /* -8..7 */ - } - carry += a[31]; /* 0..128 */ - carry2 = (carry + 8) >> 4; /* 0..8 */ - e[62] = carry - (carry2 << 4); /* -8..7 */ - e[63] = carry2; /* 0..8 */ - - ge_p3_to_cached(&Ai[0], A); - for (i = 0; i < 7; i++) { - ge_add(&t, A, &Ai[i]); - ge_p1p1_to_p3(&u, &t); - ge_p3_to_cached(&Ai[i + 1], &u); - } - - ge_p2_0(&r); - for (i = 63; i >= 0; i--) { - signed char b = e[i]; - unsigned char bnegative = negative(b); - unsigned char babs = b - (((-bnegative) & b) << 1); - ge_cached cur, minuscur; - ge_p2_dbl(&t, &r); - ge_p1p1_to_p2(&r, &t); - ge_p2_dbl(&t, &r); - ge_p1p1_to_p2(&r, &t); - ge_p2_dbl(&t, &r); - ge_p1p1_to_p2(&r, &t); - ge_p2_dbl(&t, &r); - ge_p1p1_to_p3(&u, &t); - ge_cached_0(&cur); - ge_cached_cmov(&cur, &Ai[0], equal(babs, 1)); - ge_cached_cmov(&cur, &Ai[1], equal(babs, 2)); - ge_cached_cmov(&cur, &Ai[2], equal(babs, 3)); - ge_cached_cmov(&cur, &Ai[3], equal(babs, 4)); - ge_cached_cmov(&cur, &Ai[4], equal(babs, 5)); - ge_cached_cmov(&cur, &Ai[5], equal(babs, 6)); - ge_cached_cmov(&cur, &Ai[6], equal(babs, 7)); - ge_cached_cmov(&cur, &Ai[7], equal(babs, 8)); - fe_copy(minuscur.YplusX, cur.YminusX); - fe_copy(minuscur.YminusX, cur.YplusX); - fe_copy(minuscur.Z, cur.Z); - fe_neg(minuscur.T2d, cur.T2d); - ge_cached_cmov(&cur, &minuscur, bnegative); - ge_add(&t, &u, &cur); - if (i == 0) - ge_p1p1_to_p3(r3, &t); - else - ge_p1p1_to_p2(&r, &t); - } -} - -void ge_double_scalarmult_precomp_vartime2(ge_p2 *r, const unsigned char *a, const ge_dsmp Ai, const unsigned char *b, const ge_dsmp Bi) { - signed char aslide[256]; - signed char bslide[256]; - ge_p1p1 t; - ge_p3 u; - int i; - - slide(aslide, a); - slide(bslide, b); - - ge_p2_0(r); - - for (i = 255; i >= 0; --i) { - if (aslide[i] || bslide[i]) break; - } - - for (; i >= 0; --i) { - ge_p2_dbl(&t, r); - - if (aslide[i] > 0) { - ge_p1p1_to_p3(&u, &t); - ge_add(&t, &u, &Ai[aslide[i]/2]); - } else if (aslide[i] < 0) { - ge_p1p1_to_p3(&u, &t); - ge_sub(&t, &u, &Ai[(-aslide[i])/2]); - } - - if (bslide[i] > 0) { - ge_p1p1_to_p3(&u, &t); - ge_add(&t, &u, &Bi[bslide[i]/2]); - } else if (bslide[i] < 0) { - ge_p1p1_to_p3(&u, &t); - ge_sub(&t, &u, &Bi[(-bslide[i])/2]); - } - - ge_p1p1_to_p2(r, &t); - } -} - -void ge_double_scalarmult_precomp_vartime2_p3(ge_p3 *r3, const unsigned char *a, const ge_dsmp Ai, const unsigned char *b, const ge_dsmp Bi) { - signed char aslide[256]; - signed char bslide[256]; - ge_p1p1 t; - ge_p3 u; - ge_p2 r; - int i; - - slide(aslide, a); - slide(bslide, b); - - ge_p2_0(&r); - - for (i = 255; i >= 0; --i) { - if (aslide[i] || bslide[i]) break; - } - - for (; i >= 0; --i) { - ge_p2_dbl(&t, &r); - - if (aslide[i] > 0) { - ge_p1p1_to_p3(&u, &t); - ge_add(&t, &u, &Ai[aslide[i]/2]); - } else if (aslide[i] < 0) { - ge_p1p1_to_p3(&u, &t); - ge_sub(&t, &u, &Ai[(-aslide[i])/2]); - } - - if (bslide[i] > 0) { - ge_p1p1_to_p3(&u, &t); - ge_add(&t, &u, &Bi[bslide[i]/2]); - } else if (bslide[i] < 0) { - ge_p1p1_to_p3(&u, &t); - ge_sub(&t, &u, &Bi[(-bslide[i])/2]); - } - - if (i == 0) - ge_p1p1_to_p3(r3, &t); - else - ge_p1p1_to_p2(&r, &t); - } -} - -void ge_double_scalarmult_precomp_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b, const ge_dsmp Bi) { - ge_dsmp Ai; /* A, 3A, 5A, 7A, 9A, 11A, 13A, 15A */ - - ge_dsm_precomp(Ai, A); - ge_double_scalarmult_precomp_vartime2(r, a, Ai, b, Bi); -} - -void ge_mul8(ge_p1p1 *r, const ge_p2 *t) { - ge_p2 u; - ge_p2_dbl(r, t); - ge_p1p1_to_p2(&u, r); - ge_p2_dbl(r, &u); - ge_p1p1_to_p2(&u, r); - ge_p2_dbl(r, &u); -} - -void ge_fromfe_frombytes_vartime(ge_p2 *r, const unsigned char *s) { - fe u, v, w, x, y, z; - unsigned char sign; - - /* From fe_frombytes.c */ - - int64_t h0 = load_4(s); - int64_t h1 = load_3(s + 4) << 6; - int64_t h2 = load_3(s + 7) << 5; - int64_t h3 = load_3(s + 10) << 3; - int64_t h4 = load_3(s + 13) << 2; - int64_t h5 = load_4(s + 16); - int64_t h6 = load_3(s + 20) << 7; - int64_t h7 = load_3(s + 23) << 5; - int64_t h8 = load_3(s + 26) << 4; - int64_t h9 = load_3(s + 29) << 2; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - - carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; - carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; - carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; - carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; - carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; - - carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; - carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; - carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; - carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; - carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; - - u[0] = h0; - u[1] = h1; - u[2] = h2; - u[3] = h3; - u[4] = h4; - u[5] = h5; - u[6] = h6; - u[7] = h7; - u[8] = h8; - u[9] = h9; - - /* End fe_frombytes.c */ - - fe_sq2(v, u); /* 2 * u^2 */ - fe_1(w); - fe_add(w, v, w); /* w = 2 * u^2 + 1 */ - fe_sq(x, w); /* w^2 */ - fe_mul(y, fe_ma2, v); /* -2 * A^2 * u^2 */ - fe_add(x, x, y); /* x = w^2 - 2 * A^2 * u^2 */ - fe_divpowm1(r->X, w, x); /* (w / x)^(m + 1) */ - fe_sq(y, r->X); - fe_mul(x, y, x); - fe_sub(y, w, x); - fe_copy(z, fe_ma); - if (fe_isnonzero(y)) { - fe_add(y, w, x); - if (fe_isnonzero(y)) { - goto negative; - } else { - fe_mul(r->X, r->X, fe_fffb1); - } - } else { - fe_mul(r->X, r->X, fe_fffb2); - } - fe_mul(r->X, r->X, u); /* u * sqrt(2 * A * (A + 2) * w / x) */ - fe_mul(z, z, v); /* -2 * A * u^2 */ - sign = 0; - goto setsign; -negative: - fe_mul(x, x, fe_sqrtm1); - fe_sub(y, w, x); - if (fe_isnonzero(y)) { - assert((fe_add(y, w, x), !fe_isnonzero(y))); - fe_mul(r->X, r->X, fe_fffb3); - } else { - fe_mul(r->X, r->X, fe_fffb4); - } - /* r->X = sqrt(A * (A + 2) * w / x) */ - /* z = -A */ - sign = 1; -setsign: - if (fe_isnegative(r->X) != sign) { - assert(fe_isnonzero(r->X)); - fe_neg(r->X, r->X); - } - fe_add(r->Z, z, w); - fe_sub(r->Y, z, w); - fe_mul(r->X, r->X, r->Z); -#if !defined(NDEBUG) - { - fe check_x, check_y, check_iz, check_v; - fe_invert(check_iz, r->Z); - fe_mul(check_x, r->X, check_iz); - fe_mul(check_y, r->Y, check_iz); - fe_sq(check_x, check_x); - fe_sq(check_y, check_y); - fe_mul(check_v, check_x, check_y); - fe_mul(check_v, fe_d, check_v); - fe_add(check_v, check_v, check_x); - fe_sub(check_v, check_v, check_y); - fe_1(check_x); - fe_add(check_v, check_v, check_x); - assert(!fe_isnonzero(check_v)); - } -#endif -} - -void sc_0(unsigned char *s) { - int i; - for (i = 0; i < 32; i++) { - s[i] = 0; - } -} - -void sc_reduce32(unsigned char *s) { - int64_t s0 = 2097151 & load_3(s); - int64_t s1 = 2097151 & (load_4(s + 2) >> 5); - int64_t s2 = 2097151 & (load_3(s + 5) >> 2); - int64_t s3 = 2097151 & (load_4(s + 7) >> 7); - int64_t s4 = 2097151 & (load_4(s + 10) >> 4); - int64_t s5 = 2097151 & (load_3(s + 13) >> 1); - int64_t s6 = 2097151 & (load_4(s + 15) >> 6); - int64_t s7 = 2097151 & (load_3(s + 18) >> 3); - int64_t s8 = 2097151 & load_3(s + 21); - int64_t s9 = 2097151 & (load_4(s + 23) >> 5); - int64_t s10 = 2097151 & (load_3(s + 26) >> 2); - int64_t s11 = (load_4(s + 28) >> 7); - int64_t s12 = 0; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - int64_t carry10; - int64_t carry11; - - carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; - carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; - carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; - carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; - carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; - carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; - - carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; - carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; - carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; - carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; - carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; - carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - - carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; - carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; - carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; - carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; - carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; - carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; - carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; - carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; - carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; - carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; - carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; - carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - - carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; - carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; - carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; - carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; - carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; - carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; - carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; - carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; - carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; - carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; - carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; - - s[0] = s0 >> 0; - s[1] = s0 >> 8; - s[2] = (s0 >> 16) | (s1 << 5); - s[3] = s1 >> 3; - s[4] = s1 >> 11; - s[5] = (s1 >> 19) | (s2 << 2); - s[6] = s2 >> 6; - s[7] = (s2 >> 14) | (s3 << 7); - s[8] = s3 >> 1; - s[9] = s3 >> 9; - s[10] = (s3 >> 17) | (s4 << 4); - s[11] = s4 >> 4; - s[12] = s4 >> 12; - s[13] = (s4 >> 20) | (s5 << 1); - s[14] = s5 >> 7; - s[15] = (s5 >> 15) | (s6 << 6); - s[16] = s6 >> 2; - s[17] = s6 >> 10; - s[18] = (s6 >> 18) | (s7 << 3); - s[19] = s7 >> 5; - s[20] = s7 >> 13; - s[21] = s8 >> 0; - s[22] = s8 >> 8; - s[23] = (s8 >> 16) | (s9 << 5); - s[24] = s9 >> 3; - s[25] = s9 >> 11; - s[26] = (s9 >> 19) | (s10 << 2); - s[27] = s10 >> 6; - s[28] = (s10 >> 14) | (s11 << 7); - s[29] = s11 >> 1; - s[30] = s11 >> 9; - s[31] = s11 >> 17; -} - -void sc_add(unsigned char *s, const unsigned char *a, const unsigned char *b) { - int64_t a0 = 2097151 & load_3(a); - int64_t a1 = 2097151 & (load_4(a + 2) >> 5); - int64_t a2 = 2097151 & (load_3(a + 5) >> 2); - int64_t a3 = 2097151 & (load_4(a + 7) >> 7); - int64_t a4 = 2097151 & (load_4(a + 10) >> 4); - int64_t a5 = 2097151 & (load_3(a + 13) >> 1); - int64_t a6 = 2097151 & (load_4(a + 15) >> 6); - int64_t a7 = 2097151 & (load_3(a + 18) >> 3); - int64_t a8 = 2097151 & load_3(a + 21); - int64_t a9 = 2097151 & (load_4(a + 23) >> 5); - int64_t a10 = 2097151 & (load_3(a + 26) >> 2); - int64_t a11 = (load_4(a + 28) >> 7); - int64_t b0 = 2097151 & load_3(b); - int64_t b1 = 2097151 & (load_4(b + 2) >> 5); - int64_t b2 = 2097151 & (load_3(b + 5) >> 2); - int64_t b3 = 2097151 & (load_4(b + 7) >> 7); - int64_t b4 = 2097151 & (load_4(b + 10) >> 4); - int64_t b5 = 2097151 & (load_3(b + 13) >> 1); - int64_t b6 = 2097151 & (load_4(b + 15) >> 6); - int64_t b7 = 2097151 & (load_3(b + 18) >> 3); - int64_t b8 = 2097151 & load_3(b + 21); - int64_t b9 = 2097151 & (load_4(b + 23) >> 5); - int64_t b10 = 2097151 & (load_3(b + 26) >> 2); - int64_t b11 = (load_4(b + 28) >> 7); - int64_t s0 = a0 + b0; - int64_t s1 = a1 + b1; - int64_t s2 = a2 + b2; - int64_t s3 = a3 + b3; - int64_t s4 = a4 + b4; - int64_t s5 = a5 + b5; - int64_t s6 = a6 + b6; - int64_t s7 = a7 + b7; - int64_t s8 = a8 + b8; - int64_t s9 = a9 + b9; - int64_t s10 = a10 + b10; - int64_t s11 = a11 + b11; - int64_t s12 = 0; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - int64_t carry10; - int64_t carry11; - - carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; - carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; - carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; - carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; - carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; - carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; - - carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; - carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; - carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; - carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; - carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; - carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - - carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; - carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; - carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; - carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; - carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; - carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; - carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; - carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; - carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; - carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; - carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; - carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - - carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; - carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; - carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; - carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; - carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; - carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; - carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; - carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; - carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; - carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; - carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; - - s[0] = s0 >> 0; - s[1] = s0 >> 8; - s[2] = (s0 >> 16) | (s1 << 5); - s[3] = s1 >> 3; - s[4] = s1 >> 11; - s[5] = (s1 >> 19) | (s2 << 2); - s[6] = s2 >> 6; - s[7] = (s2 >> 14) | (s3 << 7); - s[8] = s3 >> 1; - s[9] = s3 >> 9; - s[10] = (s3 >> 17) | (s4 << 4); - s[11] = s4 >> 4; - s[12] = s4 >> 12; - s[13] = (s4 >> 20) | (s5 << 1); - s[14] = s5 >> 7; - s[15] = (s5 >> 15) | (s6 << 6); - s[16] = s6 >> 2; - s[17] = s6 >> 10; - s[18] = (s6 >> 18) | (s7 << 3); - s[19] = s7 >> 5; - s[20] = s7 >> 13; - s[21] = s8 >> 0; - s[22] = s8 >> 8; - s[23] = (s8 >> 16) | (s9 << 5); - s[24] = s9 >> 3; - s[25] = s9 >> 11; - s[26] = (s9 >> 19) | (s10 << 2); - s[27] = s10 >> 6; - s[28] = (s10 >> 14) | (s11 << 7); - s[29] = s11 >> 1; - s[30] = s11 >> 9; - s[31] = s11 >> 17; -} - -void sc_sub(unsigned char *s, const unsigned char *a, const unsigned char *b) { - int64_t a0 = 2097151 & load_3(a); - int64_t a1 = 2097151 & (load_4(a + 2) >> 5); - int64_t a2 = 2097151 & (load_3(a + 5) >> 2); - int64_t a3 = 2097151 & (load_4(a + 7) >> 7); - int64_t a4 = 2097151 & (load_4(a + 10) >> 4); - int64_t a5 = 2097151 & (load_3(a + 13) >> 1); - int64_t a6 = 2097151 & (load_4(a + 15) >> 6); - int64_t a7 = 2097151 & (load_3(a + 18) >> 3); - int64_t a8 = 2097151 & load_3(a + 21); - int64_t a9 = 2097151 & (load_4(a + 23) >> 5); - int64_t a10 = 2097151 & (load_3(a + 26) >> 2); - int64_t a11 = (load_4(a + 28) >> 7); - int64_t b0 = 2097151 & load_3(b); - int64_t b1 = 2097151 & (load_4(b + 2) >> 5); - int64_t b2 = 2097151 & (load_3(b + 5) >> 2); - int64_t b3 = 2097151 & (load_4(b + 7) >> 7); - int64_t b4 = 2097151 & (load_4(b + 10) >> 4); - int64_t b5 = 2097151 & (load_3(b + 13) >> 1); - int64_t b6 = 2097151 & (load_4(b + 15) >> 6); - int64_t b7 = 2097151 & (load_3(b + 18) >> 3); - int64_t b8 = 2097151 & load_3(b + 21); - int64_t b9 = 2097151 & (load_4(b + 23) >> 5); - int64_t b10 = 2097151 & (load_3(b + 26) >> 2); - int64_t b11 = (load_4(b + 28) >> 7); - int64_t s0 = a0 - b0; - int64_t s1 = a1 - b1; - int64_t s2 = a2 - b2; - int64_t s3 = a3 - b3; - int64_t s4 = a4 - b4; - int64_t s5 = a5 - b5; - int64_t s6 = a6 - b6; - int64_t s7 = a7 - b7; - int64_t s8 = a8 - b8; - int64_t s9 = a9 - b9; - int64_t s10 = a10 - b10; - int64_t s11 = a11 - b11; - int64_t s12 = 0; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - int64_t carry10; - int64_t carry11; - - carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; - carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; - carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; - carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; - carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; - carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; - - carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; - carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; - carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; - carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; - carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; - carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - - carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; - carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; - carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; - carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; - carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; - carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; - carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; - carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; - carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; - carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; - carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; - carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - - carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; - carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; - carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; - carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; - carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; - carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; - carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; - carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; - carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; - carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; - carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; - - s[0] = s0 >> 0; - s[1] = s0 >> 8; - s[2] = (s0 >> 16) | (s1 << 5); - s[3] = s1 >> 3; - s[4] = s1 >> 11; - s[5] = (s1 >> 19) | (s2 << 2); - s[6] = s2 >> 6; - s[7] = (s2 >> 14) | (s3 << 7); - s[8] = s3 >> 1; - s[9] = s3 >> 9; - s[10] = (s3 >> 17) | (s4 << 4); - s[11] = s4 >> 4; - s[12] = s4 >> 12; - s[13] = (s4 >> 20) | (s5 << 1); - s[14] = s5 >> 7; - s[15] = (s5 >> 15) | (s6 << 6); - s[16] = s6 >> 2; - s[17] = s6 >> 10; - s[18] = (s6 >> 18) | (s7 << 3); - s[19] = s7 >> 5; - s[20] = s7 >> 13; - s[21] = s8 >> 0; - s[22] = s8 >> 8; - s[23] = (s8 >> 16) | (s9 << 5); - s[24] = s9 >> 3; - s[25] = s9 >> 11; - s[26] = (s9 >> 19) | (s10 << 2); - s[27] = s10 >> 6; - s[28] = (s10 >> 14) | (s11 << 7); - s[29] = s11 >> 1; - s[30] = s11 >> 9; - s[31] = s11 >> 17; -} - -/* -Input: - a[0]+256*a[1]+...+256^31*a[31] = a - b[0]+256*b[1]+...+256^31*b[31] = b - c[0]+256*c[1]+...+256^31*c[31] = c - -Output: - s[0]+256*s[1]+...+256^31*s[31] = (c-ab) mod l - where l = 2^252 + 27742317777372353535851937790883648493. -*/ - -void sc_mulsub(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c) { - int64_t a0 = 2097151 & load_3(a); - int64_t a1 = 2097151 & (load_4(a + 2) >> 5); - int64_t a2 = 2097151 & (load_3(a + 5) >> 2); - int64_t a3 = 2097151 & (load_4(a + 7) >> 7); - int64_t a4 = 2097151 & (load_4(a + 10) >> 4); - int64_t a5 = 2097151 & (load_3(a + 13) >> 1); - int64_t a6 = 2097151 & (load_4(a + 15) >> 6); - int64_t a7 = 2097151 & (load_3(a + 18) >> 3); - int64_t a8 = 2097151 & load_3(a + 21); - int64_t a9 = 2097151 & (load_4(a + 23) >> 5); - int64_t a10 = 2097151 & (load_3(a + 26) >> 2); - int64_t a11 = (load_4(a + 28) >> 7); - int64_t b0 = 2097151 & load_3(b); - int64_t b1 = 2097151 & (load_4(b + 2) >> 5); - int64_t b2 = 2097151 & (load_3(b + 5) >> 2); - int64_t b3 = 2097151 & (load_4(b + 7) >> 7); - int64_t b4 = 2097151 & (load_4(b + 10) >> 4); - int64_t b5 = 2097151 & (load_3(b + 13) >> 1); - int64_t b6 = 2097151 & (load_4(b + 15) >> 6); - int64_t b7 = 2097151 & (load_3(b + 18) >> 3); - int64_t b8 = 2097151 & load_3(b + 21); - int64_t b9 = 2097151 & (load_4(b + 23) >> 5); - int64_t b10 = 2097151 & (load_3(b + 26) >> 2); - int64_t b11 = (load_4(b + 28) >> 7); - int64_t c0 = 2097151 & load_3(c); - int64_t c1 = 2097151 & (load_4(c + 2) >> 5); - int64_t c2 = 2097151 & (load_3(c + 5) >> 2); - int64_t c3 = 2097151 & (load_4(c + 7) >> 7); - int64_t c4 = 2097151 & (load_4(c + 10) >> 4); - int64_t c5 = 2097151 & (load_3(c + 13) >> 1); - int64_t c6 = 2097151 & (load_4(c + 15) >> 6); - int64_t c7 = 2097151 & (load_3(c + 18) >> 3); - int64_t c8 = 2097151 & load_3(c + 21); - int64_t c9 = 2097151 & (load_4(c + 23) >> 5); - int64_t c10 = 2097151 & (load_3(c + 26) >> 2); - int64_t c11 = (load_4(c + 28) >> 7); - int64_t s0; - int64_t s1; - int64_t s2; - int64_t s3; - int64_t s4; - int64_t s5; - int64_t s6; - int64_t s7; - int64_t s8; - int64_t s9; - int64_t s10; - int64_t s11; - int64_t s12; - int64_t s13; - int64_t s14; - int64_t s15; - int64_t s16; - int64_t s17; - int64_t s18; - int64_t s19; - int64_t s20; - int64_t s21; - int64_t s22; - int64_t s23; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - int64_t carry10; - int64_t carry11; - int64_t carry12; - int64_t carry13; - int64_t carry14; - int64_t carry15; - int64_t carry16; - int64_t carry17; - int64_t carry18; - int64_t carry19; - int64_t carry20; - int64_t carry21; - int64_t carry22; - - s0 = c0 - a0*b0; - s1 = c1 - (a0*b1 + a1*b0); - s2 = c2 - (a0*b2 + a1*b1 + a2*b0); - s3 = c3 - (a0*b3 + a1*b2 + a2*b1 + a3*b0); - s4 = c4 - (a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0); - s5 = c5 - (a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0); - s6 = c6 - (a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0); - s7 = c7 - (a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0); - s8 = c8 - (a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0); - s9 = c9 - (a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0); - s10 = c10 - (a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0); - s11 = c11 - (a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0); - s12 = -(a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1); - s13 = -(a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2); - s14 = -(a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3); - s15 = -(a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4); - s16 = -(a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5); - s17 = -(a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6); - s18 = -(a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7); - s19 = -(a8*b11 + a9*b10 + a10*b9 + a11*b8); - s20 = -(a9*b11 + a10*b10 + a11*b9); - s21 = -(a10*b11 + a11*b10); - s22 = -a11*b11; - s23 = 0; - - carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; - carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; - carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; - carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; - carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; - carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; - carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; - carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; - carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; - carry18 = (s18 + (1<<20)) >> 21; s19 += carry18; s18 -= carry18 << 21; - carry20 = (s20 + (1<<20)) >> 21; s21 += carry20; s20 -= carry20 << 21; - carry22 = (s22 + (1<<20)) >> 21; s23 += carry22; s22 -= carry22 << 21; - - carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; - carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; - carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; - carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; - carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; - carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; - carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; - carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; - carry17 = (s17 + (1<<20)) >> 21; s18 += carry17; s17 -= carry17 << 21; - carry19 = (s19 + (1<<20)) >> 21; s20 += carry19; s19 -= carry19 << 21; - carry21 = (s21 + (1<<20)) >> 21; s22 += carry21; s21 -= carry21 << 21; - - s11 += s23 * 666643; - s12 += s23 * 470296; - s13 += s23 * 654183; - s14 -= s23 * 997805; - s15 += s23 * 136657; - s16 -= s23 * 683901; - - s10 += s22 * 666643; - s11 += s22 * 470296; - s12 += s22 * 654183; - s13 -= s22 * 997805; - s14 += s22 * 136657; - s15 -= s22 * 683901; - - s9 += s21 * 666643; - s10 += s21 * 470296; - s11 += s21 * 654183; - s12 -= s21 * 997805; - s13 += s21 * 136657; - s14 -= s21 * 683901; - - s8 += s20 * 666643; - s9 += s20 * 470296; - s10 += s20 * 654183; - s11 -= s20 * 997805; - s12 += s20 * 136657; - s13 -= s20 * 683901; - - s7 += s19 * 666643; - s8 += s19 * 470296; - s9 += s19 * 654183; - s10 -= s19 * 997805; - s11 += s19 * 136657; - s12 -= s19 * 683901; - - s6 += s18 * 666643; - s7 += s18 * 470296; - s8 += s18 * 654183; - s9 -= s18 * 997805; - s10 += s18 * 136657; - s11 -= s18 * 683901; - - carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; - carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; - carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; - carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; - carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; - carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; - - carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; - carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; - carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; - carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; - carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; - - s5 += s17 * 666643; - s6 += s17 * 470296; - s7 += s17 * 654183; - s8 -= s17 * 997805; - s9 += s17 * 136657; - s10 -= s17 * 683901; - - s4 += s16 * 666643; - s5 += s16 * 470296; - s6 += s16 * 654183; - s7 -= s16 * 997805; - s8 += s16 * 136657; - s9 -= s16 * 683901; - - s3 += s15 * 666643; - s4 += s15 * 470296; - s5 += s15 * 654183; - s6 -= s15 * 997805; - s7 += s15 * 136657; - s8 -= s15 * 683901; - - s2 += s14 * 666643; - s3 += s14 * 470296; - s4 += s14 * 654183; - s5 -= s14 * 997805; - s6 += s14 * 136657; - s7 -= s14 * 683901; - - s1 += s13 * 666643; - s2 += s13 * 470296; - s3 += s13 * 654183; - s4 -= s13 * 997805; - s5 += s13 * 136657; - s6 -= s13 * 683901; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - - carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; - carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; - carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; - carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; - carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; - carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; - - carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; - carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; - carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; - carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; - carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; - carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - - carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; - carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; - carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; - carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; - carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; - carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; - carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; - carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; - carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; - carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; - carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; - carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - - carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; - carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; - carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; - carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; - carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; - carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; - carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; - carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; - carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; - carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; - carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; - - s[0] = s0 >> 0; - s[1] = s0 >> 8; - s[2] = (s0 >> 16) | (s1 << 5); - s[3] = s1 >> 3; - s[4] = s1 >> 11; - s[5] = (s1 >> 19) | (s2 << 2); - s[6] = s2 >> 6; - s[7] = (s2 >> 14) | (s3 << 7); - s[8] = s3 >> 1; - s[9] = s3 >> 9; - s[10] = (s3 >> 17) | (s4 << 4); - s[11] = s4 >> 4; - s[12] = s4 >> 12; - s[13] = (s4 >> 20) | (s5 << 1); - s[14] = s5 >> 7; - s[15] = (s5 >> 15) | (s6 << 6); - s[16] = s6 >> 2; - s[17] = s6 >> 10; - s[18] = (s6 >> 18) | (s7 << 3); - s[19] = s7 >> 5; - s[20] = s7 >> 13; - s[21] = s8 >> 0; - s[22] = s8 >> 8; - s[23] = (s8 >> 16) | (s9 << 5); - s[24] = s9 >> 3; - s[25] = s9 >> 11; - s[26] = (s9 >> 19) | (s10 << 2); - s[27] = s10 >> 6; - s[28] = (s10 >> 14) | (s11 << 7); - s[29] = s11 >> 1; - s[30] = s11 >> 9; - s[31] = s11 >> 17; -} - -//copied from above and modified -/* -Input: - a[0]+256*a[1]+...+256^31*a[31] = a - b[0]+256*b[1]+...+256^31*b[31] = b - -Output: - s[0]+256*s[1]+...+256^31*s[31] = (ab) mod l - where l = 2^252 + 27742317777372353535851937790883648493. -*/ -void sc_mul(unsigned char *s, const unsigned char *a, const unsigned char *b) { - int64_t a0 = 2097151 & load_3(a); - int64_t a1 = 2097151 & (load_4(a + 2) >> 5); - int64_t a2 = 2097151 & (load_3(a + 5) >> 2); - int64_t a3 = 2097151 & (load_4(a + 7) >> 7); - int64_t a4 = 2097151 & (load_4(a + 10) >> 4); - int64_t a5 = 2097151 & (load_3(a + 13) >> 1); - int64_t a6 = 2097151 & (load_4(a + 15) >> 6); - int64_t a7 = 2097151 & (load_3(a + 18) >> 3); - int64_t a8 = 2097151 & load_3(a + 21); - int64_t a9 = 2097151 & (load_4(a + 23) >> 5); - int64_t a10 = 2097151 & (load_3(a + 26) >> 2); - int64_t a11 = (load_4(a + 28) >> 7); - int64_t b0 = 2097151 & load_3(b); - int64_t b1 = 2097151 & (load_4(b + 2) >> 5); - int64_t b2 = 2097151 & (load_3(b + 5) >> 2); - int64_t b3 = 2097151 & (load_4(b + 7) >> 7); - int64_t b4 = 2097151 & (load_4(b + 10) >> 4); - int64_t b5 = 2097151 & (load_3(b + 13) >> 1); - int64_t b6 = 2097151 & (load_4(b + 15) >> 6); - int64_t b7 = 2097151 & (load_3(b + 18) >> 3); - int64_t b8 = 2097151 & load_3(b + 21); - int64_t b9 = 2097151 & (load_4(b + 23) >> 5); - int64_t b10 = 2097151 & (load_3(b + 26) >> 2); - int64_t b11 = (load_4(b + 28) >> 7); - int64_t s0; - int64_t s1; - int64_t s2; - int64_t s3; - int64_t s4; - int64_t s5; - int64_t s6; - int64_t s7; - int64_t s8; - int64_t s9; - int64_t s10; - int64_t s11; - int64_t s12; - int64_t s13; - int64_t s14; - int64_t s15; - int64_t s16; - int64_t s17; - int64_t s18; - int64_t s19; - int64_t s20; - int64_t s21; - int64_t s22; - int64_t s23; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - int64_t carry10; - int64_t carry11; - int64_t carry12; - int64_t carry13; - int64_t carry14; - int64_t carry15; - int64_t carry16; - int64_t carry17; - int64_t carry18; - int64_t carry19; - int64_t carry20; - int64_t carry21; - int64_t carry22; - - s0 = a0*b0; - s1 = (a0*b1 + a1*b0); - s2 = (a0*b2 + a1*b1 + a2*b0); - s3 = (a0*b3 + a1*b2 + a2*b1 + a3*b0); - s4 = (a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0); - s5 = (a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0); - s6 = (a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0); - s7 = (a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0); - s8 = (a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0); - s9 = (a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0); - s10 = (a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0); - s11 = (a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0); - s12 = (a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1); - s13 = (a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2); - s14 = (a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3); - s15 = (a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4); - s16 = (a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5); - s17 = (a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6); - s18 = (a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7); - s19 = (a8*b11 + a9*b10 + a10*b9 + a11*b8); - s20 = (a9*b11 + a10*b10 + a11*b9); - s21 = (a10*b11 + a11*b10); - s22 = a11*b11; - s23 = 0; - - carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; - carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; - carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; - carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; - carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; - carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; - carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; - carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; - carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; - carry18 = (s18 + (1<<20)) >> 21; s19 += carry18; s18 -= carry18 << 21; - carry20 = (s20 + (1<<20)) >> 21; s21 += carry20; s20 -= carry20 << 21; - carry22 = (s22 + (1<<20)) >> 21; s23 += carry22; s22 -= carry22 << 21; - - carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; - carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; - carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; - carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; - carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; - carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; - carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; - carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; - carry17 = (s17 + (1<<20)) >> 21; s18 += carry17; s17 -= carry17 << 21; - carry19 = (s19 + (1<<20)) >> 21; s20 += carry19; s19 -= carry19 << 21; - carry21 = (s21 + (1<<20)) >> 21; s22 += carry21; s21 -= carry21 << 21; - - s11 += s23 * 666643; - s12 += s23 * 470296; - s13 += s23 * 654183; - s14 -= s23 * 997805; - s15 += s23 * 136657; - s16 -= s23 * 683901; - - s10 += s22 * 666643; - s11 += s22 * 470296; - s12 += s22 * 654183; - s13 -= s22 * 997805; - s14 += s22 * 136657; - s15 -= s22 * 683901; - - s9 += s21 * 666643; - s10 += s21 * 470296; - s11 += s21 * 654183; - s12 -= s21 * 997805; - s13 += s21 * 136657; - s14 -= s21 * 683901; - - s8 += s20 * 666643; - s9 += s20 * 470296; - s10 += s20 * 654183; - s11 -= s20 * 997805; - s12 += s20 * 136657; - s13 -= s20 * 683901; - - s7 += s19 * 666643; - s8 += s19 * 470296; - s9 += s19 * 654183; - s10 -= s19 * 997805; - s11 += s19 * 136657; - s12 -= s19 * 683901; - - s6 += s18 * 666643; - s7 += s18 * 470296; - s8 += s18 * 654183; - s9 -= s18 * 997805; - s10 += s18 * 136657; - s11 -= s18 * 683901; - - carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; - carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; - carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; - carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; - carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; - carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; - - carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; - carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; - carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; - carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; - carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; - - s5 += s17 * 666643; - s6 += s17 * 470296; - s7 += s17 * 654183; - s8 -= s17 * 997805; - s9 += s17 * 136657; - s10 -= s17 * 683901; - - s4 += s16 * 666643; - s5 += s16 * 470296; - s6 += s16 * 654183; - s7 -= s16 * 997805; - s8 += s16 * 136657; - s9 -= s16 * 683901; - - s3 += s15 * 666643; - s4 += s15 * 470296; - s5 += s15 * 654183; - s6 -= s15 * 997805; - s7 += s15 * 136657; - s8 -= s15 * 683901; - - s2 += s14 * 666643; - s3 += s14 * 470296; - s4 += s14 * 654183; - s5 -= s14 * 997805; - s6 += s14 * 136657; - s7 -= s14 * 683901; - - s1 += s13 * 666643; - s2 += s13 * 470296; - s3 += s13 * 654183; - s4 -= s13 * 997805; - s5 += s13 * 136657; - s6 -= s13 * 683901; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - - carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; - carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; - carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; - carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; - carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; - carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; - - carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; - carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; - carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; - carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; - carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; - carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - - carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; - carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; - carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; - carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; - carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; - carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; - carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; - carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; - carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; - carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; - carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; - carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - - carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; - carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; - carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; - carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; - carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; - carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; - carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; - carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; - carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; - carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; - carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; - - s[0] = s0 >> 0; - s[1] = s0 >> 8; - s[2] = (s0 >> 16) | (s1 << 5); - s[3] = s1 >> 3; - s[4] = s1 >> 11; - s[5] = (s1 >> 19) | (s2 << 2); - s[6] = s2 >> 6; - s[7] = (s2 >> 14) | (s3 << 7); - s[8] = s3 >> 1; - s[9] = s3 >> 9; - s[10] = (s3 >> 17) | (s4 << 4); - s[11] = s4 >> 4; - s[12] = s4 >> 12; - s[13] = (s4 >> 20) | (s5 << 1); - s[14] = s5 >> 7; - s[15] = (s5 >> 15) | (s6 << 6); - s[16] = s6 >> 2; - s[17] = s6 >> 10; - s[18] = (s6 >> 18) | (s7 << 3); - s[19] = s7 >> 5; - s[20] = s7 >> 13; - s[21] = s8 >> 0; - s[22] = s8 >> 8; - s[23] = (s8 >> 16) | (s9 << 5); - s[24] = s9 >> 3; - s[25] = s9 >> 11; - s[26] = (s9 >> 19) | (s10 << 2); - s[27] = s10 >> 6; - s[28] = (s10 >> 14) | (s11 << 7); - s[29] = s11 >> 1; - s[30] = s11 >> 9; - s[31] = s11 >> 17; -} - -//copied from above and modified -/* -Input: - a[0]+256*a[1]+...+256^31*a[31] = a - b[0]+256*b[1]+...+256^31*b[31] = b - c[0]+256*c[1]+...+256^31*c[31] = c - -Output: - s[0]+256*s[1]+...+256^31*s[31] = (c+ab) mod l - where l = 2^252 + 27742317777372353535851937790883648493. -*/ - -void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c) { - int64_t a0 = 2097151 & load_3(a); - int64_t a1 = 2097151 & (load_4(a + 2) >> 5); - int64_t a2 = 2097151 & (load_3(a + 5) >> 2); - int64_t a3 = 2097151 & (load_4(a + 7) >> 7); - int64_t a4 = 2097151 & (load_4(a + 10) >> 4); - int64_t a5 = 2097151 & (load_3(a + 13) >> 1); - int64_t a6 = 2097151 & (load_4(a + 15) >> 6); - int64_t a7 = 2097151 & (load_3(a + 18) >> 3); - int64_t a8 = 2097151 & load_3(a + 21); - int64_t a9 = 2097151 & (load_4(a + 23) >> 5); - int64_t a10 = 2097151 & (load_3(a + 26) >> 2); - int64_t a11 = (load_4(a + 28) >> 7); - int64_t b0 = 2097151 & load_3(b); - int64_t b1 = 2097151 & (load_4(b + 2) >> 5); - int64_t b2 = 2097151 & (load_3(b + 5) >> 2); - int64_t b3 = 2097151 & (load_4(b + 7) >> 7); - int64_t b4 = 2097151 & (load_4(b + 10) >> 4); - int64_t b5 = 2097151 & (load_3(b + 13) >> 1); - int64_t b6 = 2097151 & (load_4(b + 15) >> 6); - int64_t b7 = 2097151 & (load_3(b + 18) >> 3); - int64_t b8 = 2097151 & load_3(b + 21); - int64_t b9 = 2097151 & (load_4(b + 23) >> 5); - int64_t b10 = 2097151 & (load_3(b + 26) >> 2); - int64_t b11 = (load_4(b + 28) >> 7); - int64_t c0 = 2097151 & load_3(c); - int64_t c1 = 2097151 & (load_4(c + 2) >> 5); - int64_t c2 = 2097151 & (load_3(c + 5) >> 2); - int64_t c3 = 2097151 & (load_4(c + 7) >> 7); - int64_t c4 = 2097151 & (load_4(c + 10) >> 4); - int64_t c5 = 2097151 & (load_3(c + 13) >> 1); - int64_t c6 = 2097151 & (load_4(c + 15) >> 6); - int64_t c7 = 2097151 & (load_3(c + 18) >> 3); - int64_t c8 = 2097151 & load_3(c + 21); - int64_t c9 = 2097151 & (load_4(c + 23) >> 5); - int64_t c10 = 2097151 & (load_3(c + 26) >> 2); - int64_t c11 = (load_4(c + 28) >> 7); - int64_t s0; - int64_t s1; - int64_t s2; - int64_t s3; - int64_t s4; - int64_t s5; - int64_t s6; - int64_t s7; - int64_t s8; - int64_t s9; - int64_t s10; - int64_t s11; - int64_t s12; - int64_t s13; - int64_t s14; - int64_t s15; - int64_t s16; - int64_t s17; - int64_t s18; - int64_t s19; - int64_t s20; - int64_t s21; - int64_t s22; - int64_t s23; - int64_t carry0; - int64_t carry1; - int64_t carry2; - int64_t carry3; - int64_t carry4; - int64_t carry5; - int64_t carry6; - int64_t carry7; - int64_t carry8; - int64_t carry9; - int64_t carry10; - int64_t carry11; - int64_t carry12; - int64_t carry13; - int64_t carry14; - int64_t carry15; - int64_t carry16; - int64_t carry17; - int64_t carry18; - int64_t carry19; - int64_t carry20; - int64_t carry21; - int64_t carry22; - - s0 = c0 + a0*b0; - s1 = c1 + (a0*b1 + a1*b0); - s2 = c2 + (a0*b2 + a1*b1 + a2*b0); - s3 = c3 + (a0*b3 + a1*b2 + a2*b1 + a3*b0); - s4 = c4 + (a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0); - s5 = c5 + (a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0); - s6 = c6 + (a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0); - s7 = c7 + (a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0); - s8 = c8 + (a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0); - s9 = c9 + (a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0); - s10 = c10 + (a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0); - s11 = c11 + (a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0); - s12 = (a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1); - s13 = (a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2); - s14 = (a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3); - s15 = (a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4); - s16 = (a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5); - s17 = (a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6); - s18 = (a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7); - s19 = (a8*b11 + a9*b10 + a10*b9 + a11*b8); - s20 = (a9*b11 + a10*b10 + a11*b9); - s21 = (a10*b11 + a11*b10); - s22 = a11*b11; - s23 = 0; - - carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; - carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; - carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; - carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; - carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; - carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; - carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; - carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; - carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; - carry18 = (s18 + (1<<20)) >> 21; s19 += carry18; s18 -= carry18 << 21; - carry20 = (s20 + (1<<20)) >> 21; s21 += carry20; s20 -= carry20 << 21; - carry22 = (s22 + (1<<20)) >> 21; s23 += carry22; s22 -= carry22 << 21; - - carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; - carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; - carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; - carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; - carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; - carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; - carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; - carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; - carry17 = (s17 + (1<<20)) >> 21; s18 += carry17; s17 -= carry17 << 21; - carry19 = (s19 + (1<<20)) >> 21; s20 += carry19; s19 -= carry19 << 21; - carry21 = (s21 + (1<<20)) >> 21; s22 += carry21; s21 -= carry21 << 21; - - s11 += s23 * 666643; - s12 += s23 * 470296; - s13 += s23 * 654183; - s14 -= s23 * 997805; - s15 += s23 * 136657; - s16 -= s23 * 683901; - - s10 += s22 * 666643; - s11 += s22 * 470296; - s12 += s22 * 654183; - s13 -= s22 * 997805; - s14 += s22 * 136657; - s15 -= s22 * 683901; - - s9 += s21 * 666643; - s10 += s21 * 470296; - s11 += s21 * 654183; - s12 -= s21 * 997805; - s13 += s21 * 136657; - s14 -= s21 * 683901; - - s8 += s20 * 666643; - s9 += s20 * 470296; - s10 += s20 * 654183; - s11 -= s20 * 997805; - s12 += s20 * 136657; - s13 -= s20 * 683901; - - s7 += s19 * 666643; - s8 += s19 * 470296; - s9 += s19 * 654183; - s10 -= s19 * 997805; - s11 += s19 * 136657; - s12 -= s19 * 683901; - - s6 += s18 * 666643; - s7 += s18 * 470296; - s8 += s18 * 654183; - s9 -= s18 * 997805; - s10 += s18 * 136657; - s11 -= s18 * 683901; - - carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; - carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; - carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; - carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; - carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; - carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; - - carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; - carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; - carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; - carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; - carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; - - s5 += s17 * 666643; - s6 += s17 * 470296; - s7 += s17 * 654183; - s8 -= s17 * 997805; - s9 += s17 * 136657; - s10 -= s17 * 683901; - - s4 += s16 * 666643; - s5 += s16 * 470296; - s6 += s16 * 654183; - s7 -= s16 * 997805; - s8 += s16 * 136657; - s9 -= s16 * 683901; - - s3 += s15 * 666643; - s4 += s15 * 470296; - s5 += s15 * 654183; - s6 -= s15 * 997805; - s7 += s15 * 136657; - s8 -= s15 * 683901; - - s2 += s14 * 666643; - s3 += s14 * 470296; - s4 += s14 * 654183; - s5 -= s14 * 997805; - s6 += s14 * 136657; - s7 -= s14 * 683901; - - s1 += s13 * 666643; - s2 += s13 * 470296; - s3 += s13 * 654183; - s4 -= s13 * 997805; - s5 += s13 * 136657; - s6 -= s13 * 683901; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - - carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; - carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; - carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; - carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; - carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; - carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; - - carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; - carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; - carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; - carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; - carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; - carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - - carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; - carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; - carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; - carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; - carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; - carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; - carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; - carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; - carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; - carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; - carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; - carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - - carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; - carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; - carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; - carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; - carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; - carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; - carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; - carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; - carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; - carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; - carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; - - s[0] = s0 >> 0; - s[1] = s0 >> 8; - s[2] = (s0 >> 16) | (s1 << 5); - s[3] = s1 >> 3; - s[4] = s1 >> 11; - s[5] = (s1 >> 19) | (s2 << 2); - s[6] = s2 >> 6; - s[7] = (s2 >> 14) | (s3 << 7); - s[8] = s3 >> 1; - s[9] = s3 >> 9; - s[10] = (s3 >> 17) | (s4 << 4); - s[11] = s4 >> 4; - s[12] = s4 >> 12; - s[13] = (s4 >> 20) | (s5 << 1); - s[14] = s5 >> 7; - s[15] = (s5 >> 15) | (s6 << 6); - s[16] = s6 >> 2; - s[17] = s6 >> 10; - s[18] = (s6 >> 18) | (s7 << 3); - s[19] = s7 >> 5; - s[20] = s7 >> 13; - s[21] = s8 >> 0; - s[22] = s8 >> 8; - s[23] = (s8 >> 16) | (s9 << 5); - s[24] = s9 >> 3; - s[25] = s9 >> 11; - s[26] = (s9 >> 19) | (s10 << 2); - s[27] = s10 >> 6; - s[28] = (s10 >> 14) | (s11 << 7); - s[29] = s11 >> 1; - s[30] = s11 >> 9; - s[31] = s11 >> 17; -} - -/* Assumes that a != INT64_MIN */ -static int64_t signum(int64_t a) { - return (a >> 63) - ((-a) >> 63); -} - -int sc_check(const unsigned char *s) { - int64_t s0 = load_4(s); - int64_t s1 = load_4(s + 4); - int64_t s2 = load_4(s + 8); - int64_t s3 = load_4(s + 12); - int64_t s4 = load_4(s + 16); - int64_t s5 = load_4(s + 20); - int64_t s6 = load_4(s + 24); - int64_t s7 = load_4(s + 28); - return (signum(1559614444 - s0) + (signum(1477600026 - s1) << 1) + (signum(2734136534 - s2) << 2) + (signum(350157278 - s3) << 3) + (signum(-s4) << 4) + (signum(-s5) << 5) + (signum(-s6) << 6) + (signum(268435456 - s7) << 7)) >> 8; -} - -int sc_isnonzero(const unsigned char *s) { - return (((int) (s[0] | s[1] | s[2] | s[3] | s[4] | s[5] | s[6] | s[7] | s[8] | - s[9] | s[10] | s[11] | s[12] | s[13] | s[14] | s[15] | s[16] | s[17] | - s[18] | s[19] | s[20] | s[21] | s[22] | s[23] | s[24] | s[25] | s[26] | - s[27] | s[28] | s[29] | s[30] | s[31]) - 1) >> 8) + 1; -} diff --git a/src_native/crypto-ops.h b/src_native/crypto-ops.h deleted file mode 100644 index dc3c6079..00000000 --- a/src_native/crypto-ops.h +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once - -/* From fe.h */ - -typedef int32_t fe[10]; - -/* From ge.h */ - -typedef struct { - fe X; - fe Y; - fe Z; -} ge_p2; - -typedef struct { - fe X; - fe Y; - fe Z; - fe T; -} ge_p3; - -typedef struct { - fe X; - fe Y; - fe Z; - fe T; -} ge_p1p1; - -typedef struct { - fe yplusx; - fe yminusx; - fe xy2d; -} ge_precomp; - -typedef struct { - fe YplusX; - fe YminusX; - fe Z; - fe T2d; -} ge_cached; - -/* From ge_add.c */ - -void ge_add(ge_p1p1 *, const ge_p3 *, const ge_cached *); - -/* From ge_double_scalarmult.c, modified */ - -typedef ge_cached ge_dsmp[8]; -extern const ge_precomp ge_Bi[8]; -void ge_dsm_precomp(ge_dsmp r, const ge_p3 *s); -void ge_double_scalarmult_base_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *); -void ge_double_scalarmult_base_vartime_p3(ge_p3 *, const unsigned char *, const ge_p3 *, const unsigned char *); - -/* From ge_frombytes.c, modified */ - -extern const fe fe_sqrtm1; -extern const fe fe_d; -int ge_frombytes_vartime(ge_p3 *, const unsigned char *); - -/* From ge_p1p1_to_p2.c */ - -void ge_p1p1_to_p2(ge_p2 *, const ge_p1p1 *); - -/* From ge_p1p1_to_p3.c */ - -void ge_p1p1_to_p3(ge_p3 *, const ge_p1p1 *); - -/* From ge_p2_dbl.c */ - -void ge_p2_dbl(ge_p1p1 *, const ge_p2 *); - -/* From ge_p3_to_cached.c */ - -extern const fe fe_d2; -void ge_p3_to_cached(ge_cached *, const ge_p3 *); - -/* From ge_p3_to_p2.c */ - -void ge_p3_to_p2(ge_p2 *, const ge_p3 *); - -/* From ge_p3_tobytes.c */ - -void ge_p3_tobytes(unsigned char *, const ge_p3 *); - -/* From ge_scalarmult_base.c */ - -extern const ge_precomp ge_base[32][8]; -void ge_scalarmult_base(ge_p3 *, const unsigned char *); - -/* From ge_tobytes.c */ - -void ge_tobytes(unsigned char *, const ge_p2 *); - -/* From sc_reduce.c */ - -void sc_reduce(unsigned char *); - -/* New code */ - -void ge_scalarmult(ge_p2 *, const unsigned char *, const ge_p3 *); -void ge_scalarmult_p3(ge_p3 *, const unsigned char *, const ge_p3 *); -void ge_double_scalarmult_precomp_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *, const ge_dsmp); -void ge_double_scalarmult_precomp_vartime2(ge_p2 *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp); -void ge_double_scalarmult_precomp_vartime2_p3(ge_p3 *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp); -void ge_mul8(ge_p1p1 *, const ge_p2 *); -extern const fe fe_ma2; -extern const fe fe_ma; -extern const fe fe_fffb1; -extern const fe fe_fffb2; -extern const fe fe_fffb3; -extern const fe fe_fffb4; -extern const ge_p3 ge_p3_identity; -void ge_fromfe_frombytes_vartime(ge_p2 *, const unsigned char *); -void sc_0(unsigned char *); -void sc_reduce32(unsigned char *); -void sc_add(unsigned char *, const unsigned char *, const unsigned char *); -void sc_sub(unsigned char *, const unsigned char *, const unsigned char *); -void sc_mulsub(unsigned char *, const unsigned char *, const unsigned char *, const unsigned char *); -void sc_mul(unsigned char *, const unsigned char *, const unsigned char *); -void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c); -int sc_check(const unsigned char *); -int sc_isnonzero(const unsigned char *); /* Doesn't normalize */ - -// internal -uint64_t load_3(const unsigned char *in); -uint64_t load_4(const unsigned char *in); -void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); -void fe_add(fe h, const fe f, const fe g); -void fe_tobytes(unsigned char *, const fe); -void fe_invert(fe out, const fe z); diff --git a/src_native/crypto-ops.o b/src_native/crypto-ops.o deleted file mode 100644 index f5bbf5b5..00000000 Binary files a/src_native/crypto-ops.o and /dev/null differ diff --git a/src_native/crypto.cpp b/src_native/crypto.cpp deleted file mode 100644 index d843a169..00000000 --- a/src_native/crypto.cpp +++ /dev/null @@ -1,577 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#include -#include -#include -#include -#include -#include -#include -//#include -//#include -//#include - -#include "common/varint.h" -//#include "warnings.h" -#include "crypto.h" -#include "hash.h" - -namespace { - static void local_abort(const char *msg) - { - fprintf(stderr, "%s\n", msg); -#ifdef NDEBUG - _exit(1); -#else - abort(); -#endif - } -} - -namespace crypto { - - using std::abort; - using std::int32_t; - using std::int64_t; - using std::size_t; - using std::uint32_t; - using std::uint64_t; - - extern "C" { -#include "crypto-ops.h" -//#include "random.h" - } - -// boost::mutex random_lock; - - static inline unsigned char *operator &(ec_point &point) { - return &reinterpret_cast(point); - } - - static inline const unsigned char *operator &(const ec_point &point) { - return &reinterpret_cast(point); - } - - static inline unsigned char *operator &(ec_scalar &scalar) { - return &reinterpret_cast(scalar); - } - - static inline const unsigned char *operator &(const ec_scalar &scalar) { - return &reinterpret_cast(scalar); - } - - /* generate a random 32-byte (256-bit) integer and copy it to res */ - static inline void random_scalar_not_thread_safe(ec_scalar &res) { - unsigned char tmp[64]; - generate_random_bytes_not_thread_safe(64, tmp); - sc_reduce(tmp); - memcpy(&res, tmp, 32); - } - static inline void random_scalar(ec_scalar &res) { - boost::lock_guard lock(random_lock); - random_scalar_not_thread_safe(res); - } - - void hash_to_scalar(const void *data, size_t length, ec_scalar &res) { - cn_fast_hash(data, length, reinterpret_cast(res)); - sc_reduce32(&res); - } - - /* - * generate public and secret keys from a random 256-bit integer - * TODO: allow specifying random value (for wallet recovery) - * - */ - secret_key crypto_ops::generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key, bool recover) { - ge_p3 point; - - secret_key rng; - - if (recover) - { - rng = recovery_key; - } - else - { - random_scalar(rng); - } - sec = rng; - sc_reduce32(&sec); // reduce in case second round of keys (sendkeys) - - ge_scalarmult_base(&point, &sec); - ge_p3_tobytes(&pub, &point); - - return rng; - } - - bool crypto_ops::check_key(const public_key &key) { - ge_p3 point; - return ge_frombytes_vartime(&point, &key) == 0; - } - - bool crypto_ops::secret_key_to_public_key(const secret_key &sec, public_key &pub) { - ge_p3 point; - if (sc_check(&sec) != 0) { - return false; - } - ge_scalarmult_base(&point, &sec); - ge_p3_tobytes(&pub, &point); - return true; - } - - bool crypto_ops::generate_key_derivation(const public_key &key1, const secret_key &key2, key_derivation &derivation) { - ge_p3 point; - ge_p2 point2; - ge_p1p1 point3; - assert(sc_check(&key2) == 0); - if (ge_frombytes_vartime(&point, &key1) != 0) { - return false; - } - ge_scalarmult(&point2, &key2, &point); - ge_mul8(&point3, &point2); - ge_p1p1_to_p2(&point2, &point3); - ge_tobytes(&derivation, &point2); - return true; - } - - void crypto_ops::derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res) { - struct { - key_derivation derivation; - char output_index[(sizeof(size_t) * 8 + 6) / 7]; - } buf; - char *end = buf.output_index; - buf.derivation = derivation; - tools::write_varint(end, output_index); - assert(end <= buf.output_index + sizeof buf.output_index); - hash_to_scalar(&buf, end - reinterpret_cast(&buf), res); - } - - bool crypto_ops::derive_public_key(const key_derivation &derivation, size_t output_index, - const public_key &base, public_key &derived_key) { - ec_scalar scalar; - ge_p3 point1; - ge_p3 point2; - ge_cached point3; - ge_p1p1 point4; - ge_p2 point5; - if (ge_frombytes_vartime(&point1, &base) != 0) { - return false; - } - derivation_to_scalar(derivation, output_index, scalar); - ge_scalarmult_base(&point2, &scalar); - ge_p3_to_cached(&point3, &point2); - ge_add(&point4, &point1, &point3); - ge_p1p1_to_p2(&point5, &point4); - ge_tobytes(&derived_key, &point5); - return true; - } - - void crypto_ops::derive_secret_key(const key_derivation &derivation, size_t output_index, - const secret_key &base, secret_key &derived_key) { - ec_scalar scalar; - assert(sc_check(&base) == 0); - derivation_to_scalar(derivation, output_index, scalar); - sc_add(&derived_key, &base, &scalar); - } - - bool crypto_ops::derive_subaddress_public_key(const public_key &out_key, const key_derivation &derivation, std::size_t output_index, public_key &derived_key) { - ec_scalar scalar; - ge_p3 point1; - ge_p3 point2; - ge_cached point3; - ge_p1p1 point4; - ge_p2 point5; - if (ge_frombytes_vartime(&point1, &out_key) != 0) { - return false; - } - derivation_to_scalar(derivation, output_index, scalar); - ge_scalarmult_base(&point2, &scalar); - ge_p3_to_cached(&point3, &point2); - ge_sub(&point4, &point1, &point3); - ge_p1p1_to_p2(&point5, &point4); - ge_tobytes(&derived_key, &point5); - return true; - } - - struct s_comm { - hash h; - ec_point key; - ec_point comm; - }; - - struct s_comm_2 { - hash msg; - ec_point D; - ec_point X; - ec_point Y; - }; - - void crypto_ops::generate_signature(const hash &prefix_hash, const public_key &pub, const secret_key &sec, signature &sig) { - ge_p3 tmp3; - ec_scalar k; - s_comm buf; -#if !defined(NDEBUG) - { - ge_p3 t; - public_key t2; - assert(sc_check(&sec) == 0); - ge_scalarmult_base(&t, &sec); - ge_p3_tobytes(&t2, &t); - assert(pub == t2); - } -#endif - buf.h = prefix_hash; - buf.key = pub; - random_scalar(k); - ge_scalarmult_base(&tmp3, &k); - ge_p3_tobytes(&buf.comm, &tmp3); - hash_to_scalar(&buf, sizeof(s_comm), sig.c); - sc_mulsub(&sig.r, &sig.c, &sec, &k); - } - - bool crypto_ops::check_signature(const hash &prefix_hash, const public_key &pub, const signature &sig) { - ge_p2 tmp2; - ge_p3 tmp3; - ec_scalar c; - s_comm buf; - assert(check_key(pub)); - buf.h = prefix_hash; - buf.key = pub; - if (ge_frombytes_vartime(&tmp3, &pub) != 0) { - return false; - } - if (sc_check(&sig.c) != 0 || sc_check(&sig.r) != 0) { - return false; - } - ge_double_scalarmult_base_vartime(&tmp2, &sig.c, &tmp3, &sig.r); - ge_tobytes(&buf.comm, &tmp2); - hash_to_scalar(&buf, sizeof(s_comm), c); - sc_sub(&c, &c, &sig.c); - return sc_isnonzero(&c) == 0; - } - - void crypto_ops::generate_tx_proof(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional &B, const public_key &D, const secret_key &r, signature &sig) { - // sanity check - ge_p3 R_p3; - ge_p3 A_p3; - ge_p3 B_p3; - ge_p3 D_p3; - if (ge_frombytes_vartime(&R_p3, &R) != 0) throw std::runtime_error("tx pubkey is invalid"); - if (ge_frombytes_vartime(&A_p3, &A) != 0) throw std::runtime_error("recipient view pubkey is invalid"); - if (B && ge_frombytes_vartime(&B_p3, &*B) != 0) throw std::runtime_error("recipient spend pubkey is invalid"); - if (ge_frombytes_vartime(&D_p3, &D) != 0) throw std::runtime_error("key derivation is invalid"); -#if !defined(NDEBUG) - { - assert(sc_check(&r) == 0); - // check R == r*G or R == r*B - public_key dbg_R; - if (B) - { - ge_p2 dbg_R_p2; - ge_scalarmult(&dbg_R_p2, &r, &B_p3); - ge_tobytes(&dbg_R, &dbg_R_p2); - } - else - { - ge_p3 dbg_R_p3; - ge_scalarmult_base(&dbg_R_p3, &r); - ge_p3_tobytes(&dbg_R, &dbg_R_p3); - } - assert(R == dbg_R); - // check D == r*A - ge_p2 dbg_D_p2; - ge_scalarmult(&dbg_D_p2, &r, &A_p3); - public_key dbg_D; - ge_tobytes(&dbg_D, &dbg_D_p2); - assert(D == dbg_D); - } -#endif - - // pick random k - ec_scalar k; - random_scalar(k); - - s_comm_2 buf; - buf.msg = prefix_hash; - buf.D = D; - - if (B) - { - // compute X = k*B - ge_p2 X_p2; - ge_scalarmult(&X_p2, &k, &B_p3); - ge_tobytes(&buf.X, &X_p2); - } - else - { - // compute X = k*G - ge_p3 X_p3; - ge_scalarmult_base(&X_p3, &k); - ge_p3_tobytes(&buf.X, &X_p3); - } - - // compute Y = k*A - ge_p2 Y_p2; - ge_scalarmult(&Y_p2, &k, &A_p3); - ge_tobytes(&buf.Y, &Y_p2); - - // sig.c = Hs(Msg || D || X || Y) - hash_to_scalar(&buf, sizeof(buf), sig.c); - - // sig.r = k - sig.c*r - sc_mulsub(&sig.r, &sig.c, &r, &k); - } - - bool crypto_ops::check_tx_proof(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional &B, const public_key &D, const signature &sig) { - // sanity check - ge_p3 R_p3; - ge_p3 A_p3; - ge_p3 B_p3; - ge_p3 D_p3; - if (ge_frombytes_vartime(&R_p3, &R) != 0) return false; - if (ge_frombytes_vartime(&A_p3, &A) != 0) return false; - if (B && ge_frombytes_vartime(&B_p3, &*B) != 0) return false; - if (ge_frombytes_vartime(&D_p3, &D) != 0) return false; - if (sc_check(&sig.c) != 0 || sc_check(&sig.r) != 0) return false; - - // compute sig.c*R - ge_p3 cR_p3; - { - ge_p2 cR_p2; - ge_scalarmult(&cR_p2, &sig.c, &R_p3); - public_key cR; - ge_tobytes(&cR, &cR_p2); - if (ge_frombytes_vartime(&cR_p3, &cR) != 0) return false; - } - - ge_p1p1 X_p1p1; - if (B) - { - // compute X = sig.c*R + sig.r*B - ge_p2 rB_p2; - ge_scalarmult(&rB_p2, &sig.r, &B_p3); - public_key rB; - ge_tobytes(&rB, &rB_p2); - ge_p3 rB_p3; - if (ge_frombytes_vartime(&rB_p3, &rB) != 0) return false; - ge_cached rB_cached; - ge_p3_to_cached(&rB_cached, &rB_p3); - ge_add(&X_p1p1, &cR_p3, &rB_cached); - } - else - { - // compute X = sig.c*R + sig.r*G - ge_p3 rG_p3; - ge_scalarmult_base(&rG_p3, &sig.r); - ge_cached rG_cached; - ge_p3_to_cached(&rG_cached, &rG_p3); - ge_add(&X_p1p1, &cR_p3, &rG_cached); - } - ge_p2 X_p2; - ge_p1p1_to_p2(&X_p2, &X_p1p1); - - // compute sig.c*D - ge_p2 cD_p2; - ge_scalarmult(&cD_p2, &sig.c, &D_p3); - - // compute sig.r*A - ge_p2 rA_p2; - ge_scalarmult(&rA_p2, &sig.r, &A_p3); - - // compute Y = sig.c*D + sig.r*A - public_key cD; - public_key rA; - ge_tobytes(&cD, &cD_p2); - ge_tobytes(&rA, &rA_p2); - ge_p3 cD_p3; - ge_p3 rA_p3; - if (ge_frombytes_vartime(&cD_p3, &cD) != 0) return false; - if (ge_frombytes_vartime(&rA_p3, &rA) != 0) return false; - ge_cached rA_cached; - ge_p3_to_cached(&rA_cached, &rA_p3); - ge_p1p1 Y_p1p1; - ge_add(&Y_p1p1, &cD_p3, &rA_cached); - ge_p2 Y_p2; - ge_p1p1_to_p2(&Y_p2, &Y_p1p1); - - // compute c2 = Hs(Msg || D || X || Y) - s_comm_2 buf; - buf.msg = prefix_hash; - buf.D = D; - ge_tobytes(&buf.X, &X_p2); - ge_tobytes(&buf.Y, &Y_p2); - ec_scalar c2; - hash_to_scalar(&buf, sizeof(s_comm_2), c2); - - // test if c2 == sig.c - sc_sub(&c2, &c2, &sig.c); - return sc_isnonzero(&c2) == 0; - } - - static void hash_to_ec(const public_key &key, ge_p3 &res) { - hash h; - ge_p2 point; - ge_p1p1 point2; - cn_fast_hash(std::addressof(key), sizeof(public_key), h); - ge_fromfe_frombytes_vartime(&point, reinterpret_cast(&h)); - ge_mul8(&point2, &point); - ge_p1p1_to_p3(&res, &point2); - } - - void crypto_ops::generate_key_image(const public_key &pub, const secret_key &sec, key_image &image) { - ge_p3 point; - ge_p2 point2; - assert(sc_check(&sec) == 0); - hash_to_ec(pub, point); - ge_scalarmult(&point2, &sec, &point); - ge_tobytes(&image, &point2); - } - -PUSH_WARNINGS -DISABLE_VS_WARNINGS(4200) - struct ec_point_pair { - ec_point a, b; - }; - struct rs_comm { - hash h; - struct ec_point_pair ab[]; - }; -POP_WARNINGS - - static inline size_t rs_comm_size(size_t pubs_count) { - return sizeof(rs_comm) + pubs_count * sizeof(ec_point_pair); - } - - void crypto_ops::generate_ring_signature(const hash &prefix_hash, const key_image &image, - const public_key *const *pubs, size_t pubs_count, - const secret_key &sec, size_t sec_index, - signature *sig) { - size_t i; - ge_p3 image_unp; - ge_dsmp image_pre; - ec_scalar sum, k, h; - boost::shared_ptr buf(reinterpret_cast(malloc(rs_comm_size(pubs_count))), free); - if (!buf) - local_abort("malloc failure"); - assert(sec_index < pubs_count); -#if !defined(NDEBUG) - { - ge_p3 t; - public_key t2; - key_image t3; - assert(sc_check(&sec) == 0); - ge_scalarmult_base(&t, &sec); - ge_p3_tobytes(&t2, &t); - assert(*pubs[sec_index] == t2); - generate_key_image(*pubs[sec_index], sec, t3); - assert(image == t3); - for (i = 0; i < pubs_count; i++) { - assert(check_key(*pubs[i])); - } - } -#endif - if (ge_frombytes_vartime(&image_unp, &image) != 0) { - local_abort("invalid key image"); - } - ge_dsm_precomp(image_pre, &image_unp); - sc_0(&sum); - buf->h = prefix_hash; - for (i = 0; i < pubs_count; i++) { - ge_p2 tmp2; - ge_p3 tmp3; - if (i == sec_index) { - random_scalar(k); - ge_scalarmult_base(&tmp3, &k); - ge_p3_tobytes(&buf->ab[i].a, &tmp3); - hash_to_ec(*pubs[i], tmp3); - ge_scalarmult(&tmp2, &k, &tmp3); - ge_tobytes(&buf->ab[i].b, &tmp2); - } else { - random_scalar(sig[i].c); - random_scalar(sig[i].r); - if (ge_frombytes_vartime(&tmp3, &*pubs[i]) != 0) { - local_abort("invalid pubkey"); - } - ge_double_scalarmult_base_vartime(&tmp2, &sig[i].c, &tmp3, &sig[i].r); - ge_tobytes(&buf->ab[i].a, &tmp2); - hash_to_ec(*pubs[i], tmp3); - ge_double_scalarmult_precomp_vartime(&tmp2, &sig[i].r, &tmp3, &sig[i].c, image_pre); - ge_tobytes(&buf->ab[i].b, &tmp2); - sc_add(&sum, &sum, &sig[i].c); - } - } - hash_to_scalar(buf.get(), rs_comm_size(pubs_count), h); - sc_sub(&sig[sec_index].c, &h, &sum); - sc_mulsub(&sig[sec_index].r, &sig[sec_index].c, &sec, &k); - } - - bool crypto_ops::check_ring_signature(const hash &prefix_hash, const key_image &image, - const public_key *const *pubs, size_t pubs_count, - const signature *sig) { - size_t i; - ge_p3 image_unp; - ge_dsmp image_pre; - ec_scalar sum, h; - boost::shared_ptr buf(reinterpret_cast(malloc(rs_comm_size(pubs_count))), free); - if (!buf) - return false; -#if !defined(NDEBUG) - for (i = 0; i < pubs_count; i++) { - assert(check_key(*pubs[i])); - } -#endif - if (ge_frombytes_vartime(&image_unp, &image) != 0) { - return false; - } - ge_dsm_precomp(image_pre, &image_unp); - sc_0(&sum); - buf->h = prefix_hash; - for (i = 0; i < pubs_count; i++) { - ge_p2 tmp2; - ge_p3 tmp3; - if (sc_check(&sig[i].c) != 0 || sc_check(&sig[i].r) != 0) { - return false; - } - if (ge_frombytes_vartime(&tmp3, &*pubs[i]) != 0) { - return false; - } - ge_double_scalarmult_base_vartime(&tmp2, &sig[i].c, &tmp3, &sig[i].r); - ge_tobytes(&buf->ab[i].a, &tmp2); - hash_to_ec(*pubs[i], tmp3); - ge_double_scalarmult_precomp_vartime(&tmp2, &sig[i].r, &tmp3, &sig[i].c, image_pre); - ge_tobytes(&buf->ab[i].b, &tmp2); - sc_add(&sum, &sum, &sig[i].c); - } - hash_to_scalar(buf.get(), rs_comm_size(pubs_count), h); - sc_sub(&h, &h, &sum); - return sc_isnonzero(&h) == 0; - } -} diff --git a/src_native/crypto.h b/src_native/crypto.h deleted file mode 100644 index 61eacec5..00000000 --- a/src_native/crypto.h +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once - -#include -#include -//#include -//#include -//#include -//#include -#include -#include - -#include "common/pod-class.h" -//#include "common/util.h" -//#include "memwipe.h" -#include "generic-ops.h" -//#include "hex.h" -//#include "span.h" -//#include "hash.h" - -namespace crypto { - -// extern "C" { -//#include "random.h" -// } - -// extern boost::mutex random_lock; - -#pragma pack(push, 1) - struct ec_point { - char data[32]; - }; - - struct ec_scalar { - char data[32]; - }; - - struct public_key : ec_point { - friend class crypto_ops; - }; -/* -// using secret_key = tools::scrubbed; - - struct public_keyV { - std::vector keys; - int rows; - }; - - struct secret_keyV { - std::vector keys; - int rows; - }; - - struct public_keyM { - int cols; - int rows; - std::vector column_vectors; - }; -*/ - struct key_derivation : ec_point { - friend class crypto_ops; - }; -/* - struct key_image : ec_point { - friend class crypto_ops; - }; - - struct signature { - ec_scalar c, r; - - friend class crypto_ops; - };*/ -#pragma pack(pop) - - class crypto_ops { - public: - crypto_ops(); - crypto_ops(const crypto_ops &); - void operator=(const crypto_ops &); - ~crypto_ops(); - -// static secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key = secret_key(), bool recover = false); -// friend secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key, bool recover); -// static bool check_key(const public_key &); -// friend bool check_key(const public_key &); -// static bool secret_key_to_public_key(const secret_key &, public_key &); -// friend bool secret_key_to_public_key(const secret_key &, public_key &); -// static bool generate_key_derivation(const public_key &, const secret_key &, key_derivation &); -// friend bool generate_key_derivation(const public_key &, const secret_key &, key_derivation &); - static void derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res); -// friend void derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res); - static bool derive_public_key(const key_derivation &, std::size_t, const public_key &, public_key &); -// friend bool derive_public_key(const key_derivation &, std::size_t, const public_key &, public_key &); -// static void derive_secret_key(const key_derivation &, std::size_t, const secret_key &, secret_key &); -// friend void derive_secret_key(const key_derivation &, std::size_t, const secret_key &, secret_key &); -// static bool derive_subaddress_public_key(const public_key &, const key_derivation &, std::size_t, public_key &); -// friend bool derive_subaddress_public_key(const public_key &, const key_derivation &, std::size_t, public_key &); -// static void generate_signature(const hash &, const public_key &, const secret_key &, signature &); -// friend void generate_signature(const hash &, const public_key &, const secret_key &, signature &); -// static bool check_signature(const hash &, const public_key &, const signature &); -// friend bool check_signature(const hash &, const public_key &, const signature &); -// static void generate_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional &, const public_key &, const secret_key &, signature &); -// friend void generate_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional &, const public_key &, const secret_key &, signature &); -// static bool check_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional &, const public_key &, const signature &); -// friend bool check_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional &, const public_key &, const signature &); -// static void generate_key_image(const public_key &, const secret_key &, key_image &); -// friend void generate_key_image(const public_key &, const secret_key &, key_image &); -// static void generate_ring_signature(const hash &, const key_image &, -// const public_key *const *, std::size_t, const secret_key &, std::size_t, signature *); -// friend void generate_ring_signature(const hash &, const key_image &, -// const public_key *const *, std::size_t, const secret_key &, std::size_t, signature *); -// static bool check_ring_signature(const hash &, const key_image &, -// const public_key *const *, std::size_t, const signature *); -// friend bool check_ring_signature(const hash &, const key_image &, -// const public_key *const *, std::size_t, const signature *); - }; - -// inline void derivation_to_scalar(const key_derivation &derivation, size_t output_index, ec_scalar &res) { -// return crypto_ops::derivation_to_scalar(derivation, output_index, res); -// } - -} \ No newline at end of file diff --git a/src_native/generic-ops.h b/src_native/generic-ops.h deleted file mode 100644 index 62bc758c..00000000 --- a/src_native/generic-ops.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once - -#include -#include -#include - -#define CRYPTO_MAKE_COMPARABLE(type) \ -namespace crypto { \ - inline bool operator==(const type &_v1, const type &_v2) { \ - return std::memcmp(&_v1, &_v2, sizeof(type)) == 0; \ - } \ - inline bool operator!=(const type &_v1, const type &_v2) { \ - return std::memcmp(&_v1, &_v2, sizeof(type)) != 0; \ - } \ -} - -#define CRYPTO_MAKE_HASHABLE(type) \ -CRYPTO_MAKE_COMPARABLE(type) \ -namespace crypto { \ - static_assert(sizeof(std::size_t) <= sizeof(type), "Size of " #type " must be at least that of size_t"); \ - inline std::size_t hash_value(const type &_v) { \ - return reinterpret_cast(_v); \ - } \ -} \ -namespace std { \ - template<> \ - struct hash { \ - std::size_t operator()(const crypto::type &_v) const { \ - return reinterpret_cast(_v); \ - } \ - }; \ -} diff --git a/src_native/groestl.c b/src_native/groestl.c deleted file mode 100644 index 5277c8b4..00000000 --- a/src_native/groestl.c +++ /dev/null @@ -1,393 +0,0 @@ -/* hash.c April 2012 - * Groestl ANSI C code optimised for 32-bit machines - * Author: Thomas Krinninger - * - * This work is based on the implementation of - * Soeren S. Thomsen and Krystian Matusiewicz - * - * - */ - -#include -#include "groestl_tables.h" - -typedef unsigned char BitSequence; -typedef unsigned long long DataLength; -typedef enum {SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2} HashReturn; - -/* some sizes (number of bytes) */ -#define ROWS 8 -#define LENGTHFIELDLEN ROWS -#define COLS512 8 - -#define SIZE512 (ROWS*COLS512) - -#define ROUNDS512 10 -#define HASH_BIT_LEN 256 - -#define ROTL32(v, n) ((((v)<<(n))|((v)>>(32-(n))))&li_32(ffffffff)) - -#define li_32(h) 0x##h##u -#define EXT_BYTE(var,n) ((uint8_t)((uint32_t)(var) >> (8*n))) -#define u32BIG(a) \ - ((ROTL32(a,8) & li_32(00FF00FF)) | \ - (ROTL32(a,24) & li_32(FF00FF00))) - -/* NIST API begin */ -typedef struct { - uint32_t chaining[SIZE512/sizeof(uint32_t)]; /* actual state */ - uint32_t block_counter1, - block_counter2; /* message block counter(s) */ - BitSequence buffer[SIZE512]; /* data buffer */ - int buf_ptr; /* data buffer pointer */ - int bits_in_last_byte; /* no. of message bits in last byte of - data buffer */ -} groestlHashState; - -#define P_TYPE 0 -#define Q_TYPE 1 - -const uint8_t shift_Values[2][8] = {{0,1,2,3,4,5,6,7},{1,3,5,7,0,2,4,6}}; - -const uint8_t indices_cyclic[15] = {0,1,2,3,4,5,6,7,0,1,2,3,4,5,6}; - - -#define ROTATE_COLUMN_DOWN(v1, v2, amount_bytes, temp_var) {temp_var = (v1<<(8*amount_bytes))|(v2>>(8*(4-amount_bytes))); \ - v2 = (v2<<(8*amount_bytes))|(v1>>(8*(4-amount_bytes))); \ - v1 = temp_var;} - - -#define COLUMN(x,y,i,c0,c1,c2,c3,c4,c5,c6,c7,tv1,tv2,tu,tl,t) \ - tu = T[2*(uint32_t)x[4*c0+0]]; \ - tl = T[2*(uint32_t)x[4*c0+0]+1]; \ - tv1 = T[2*(uint32_t)x[4*c1+1]]; \ - tv2 = T[2*(uint32_t)x[4*c1+1]+1]; \ - ROTATE_COLUMN_DOWN(tv1,tv2,1,t) \ - tu ^= tv1; \ - tl ^= tv2; \ - tv1 = T[2*(uint32_t)x[4*c2+2]]; \ - tv2 = T[2*(uint32_t)x[4*c2+2]+1]; \ - ROTATE_COLUMN_DOWN(tv1,tv2,2,t) \ - tu ^= tv1; \ - tl ^= tv2; \ - tv1 = T[2*(uint32_t)x[4*c3+3]]; \ - tv2 = T[2*(uint32_t)x[4*c3+3]+1]; \ - ROTATE_COLUMN_DOWN(tv1,tv2,3,t) \ - tu ^= tv1; \ - tl ^= tv2; \ - tl ^= T[2*(uint32_t)x[4*c4+0]]; \ - tu ^= T[2*(uint32_t)x[4*c4+0]+1]; \ - tv1 = T[2*(uint32_t)x[4*c5+1]]; \ - tv2 = T[2*(uint32_t)x[4*c5+1]+1]; \ - ROTATE_COLUMN_DOWN(tv1,tv2,1,t) \ - tl ^= tv1; \ - tu ^= tv2; \ - tv1 = T[2*(uint32_t)x[4*c6+2]]; \ - tv2 = T[2*(uint32_t)x[4*c6+2]+1]; \ - ROTATE_COLUMN_DOWN(tv1,tv2,2,t) \ - tl ^= tv1; \ - tu ^= tv2; \ - tv1 = T[2*(uint32_t)x[4*c7+3]]; \ - tv2 = T[2*(uint32_t)x[4*c7+3]+1]; \ - ROTATE_COLUMN_DOWN(tv1,tv2,3,t) \ - tl ^= tv1; \ - tu ^= tv2; \ - y[i] = tu; \ - y[i+1] = tl; - - -/* compute one round of P (short variants) */ -static void RND512P(uint8_t *x, uint32_t *y, uint32_t r) { - uint32_t temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp; - uint32_t* x32 = (uint32_t*)x; - x32[ 0] ^= 0x00000000^r; - x32[ 2] ^= 0x00000010^r; - x32[ 4] ^= 0x00000020^r; - x32[ 6] ^= 0x00000030^r; - x32[ 8] ^= 0x00000040^r; - x32[10] ^= 0x00000050^r; - x32[12] ^= 0x00000060^r; - x32[14] ^= 0x00000070^r; - COLUMN(x,y, 0, 0, 2, 4, 6, 9, 11, 13, 15, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); - COLUMN(x,y, 2, 2, 4, 6, 8, 11, 13, 15, 1, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); - COLUMN(x,y, 4, 4, 6, 8, 10, 13, 15, 1, 3, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); - COLUMN(x,y, 6, 6, 8, 10, 12, 15, 1, 3, 5, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); - COLUMN(x,y, 8, 8, 10, 12, 14, 1, 3, 5, 7, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); - COLUMN(x,y,10, 10, 12, 14, 0, 3, 5, 7, 9, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); - COLUMN(x,y,12, 12, 14, 0, 2, 5, 7, 9, 11, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); - COLUMN(x,y,14, 14, 0, 2, 4, 7, 9, 11, 13, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); -} - -/* compute one round of Q (short variants) */ -static void RND512Q(uint8_t *x, uint32_t *y, uint32_t r) { - uint32_t temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp; - uint32_t* x32 = (uint32_t*)x; - x32[ 0] = ~x32[ 0]; - x32[ 1] ^= 0xffffffff^r; - x32[ 2] = ~x32[ 2]; - x32[ 3] ^= 0xefffffff^r; - x32[ 4] = ~x32[ 4]; - x32[ 5] ^= 0xdfffffff^r; - x32[ 6] = ~x32[ 6]; - x32[ 7] ^= 0xcfffffff^r; - x32[ 8] = ~x32[ 8]; - x32[ 9] ^= 0xbfffffff^r; - x32[10] = ~x32[10]; - x32[11] ^= 0xafffffff^r; - x32[12] = ~x32[12]; - x32[13] ^= 0x9fffffff^r; - x32[14] = ~x32[14]; - x32[15] ^= 0x8fffffff^r; - COLUMN(x,y, 0, 2, 6, 10, 14, 1, 5, 9, 13, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); - COLUMN(x,y, 2, 4, 8, 12, 0, 3, 7, 11, 15, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); - COLUMN(x,y, 4, 6, 10, 14, 2, 5, 9, 13, 1, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); - COLUMN(x,y, 6, 8, 12, 0, 4, 7, 11, 15, 3, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); - COLUMN(x,y, 8, 10, 14, 2, 6, 9, 13, 1, 5, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); - COLUMN(x,y,10, 12, 0, 4, 8, 11, 15, 3, 7, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); - COLUMN(x,y,12, 14, 2, 6, 10, 13, 1, 5, 9, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); - COLUMN(x,y,14, 0, 4, 8, 12, 15, 3, 7, 11, temp_v1, temp_v2, temp_upper_value, temp_lower_value, temp); -} - -/* compute compression function (short variants) */ -static void F512(uint32_t *h, const uint32_t *m) { - int i; - uint32_t Ptmp[2*COLS512]; - uint32_t Qtmp[2*COLS512]; - uint32_t y[2*COLS512]; - uint32_t z[2*COLS512]; - - for (i = 0; i < 2*COLS512; i++) { - z[i] = m[i]; - Ptmp[i] = h[i]^m[i]; - } - - /* compute Q(m) */ - RND512Q((uint8_t*)z, y, 0x00000000); - RND512Q((uint8_t*)y, z, 0x01000000); - RND512Q((uint8_t*)z, y, 0x02000000); - RND512Q((uint8_t*)y, z, 0x03000000); - RND512Q((uint8_t*)z, y, 0x04000000); - RND512Q((uint8_t*)y, z, 0x05000000); - RND512Q((uint8_t*)z, y, 0x06000000); - RND512Q((uint8_t*)y, z, 0x07000000); - RND512Q((uint8_t*)z, y, 0x08000000); - RND512Q((uint8_t*)y, Qtmp, 0x09000000); - - /* compute P(h+m) */ - RND512P((uint8_t*)Ptmp, y, 0x00000000); - RND512P((uint8_t*)y, z, 0x00000001); - RND512P((uint8_t*)z, y, 0x00000002); - RND512P((uint8_t*)y, z, 0x00000003); - RND512P((uint8_t*)z, y, 0x00000004); - RND512P((uint8_t*)y, z, 0x00000005); - RND512P((uint8_t*)z, y, 0x00000006); - RND512P((uint8_t*)y, z, 0x00000007); - RND512P((uint8_t*)z, y, 0x00000008); - RND512P((uint8_t*)y, Ptmp, 0x00000009); - - /* compute P(h+m) + Q(m) + h */ - for (i = 0; i < 2*COLS512; i++) { - h[i] ^= Ptmp[i]^Qtmp[i]; - } -} - - -/* digest up to msglen bytes of input (full blocks only) */ -static void Transform(groestlHashState *ctx, - const uint8_t *input, - int msglen) { - - /* digest message, one block at a time */ - for (; msglen >= SIZE512; - msglen -= SIZE512, input += SIZE512) { - F512(ctx->chaining,(uint32_t*)input); - - /* increment block counter */ - ctx->block_counter1++; - if (ctx->block_counter1 == 0) ctx->block_counter2++; - } -} - -/* given state h, do h <- P(h)+h */ -static void OutputTransformation(groestlHashState *ctx) { - int j; - uint32_t temp[2*COLS512]; - uint32_t y[2*COLS512]; - uint32_t z[2*COLS512]; - - - - for (j = 0; j < 2*COLS512; j++) { - temp[j] = ctx->chaining[j]; - } - RND512P((uint8_t*)temp, y, 0x00000000); - RND512P((uint8_t*)y, z, 0x00000001); - RND512P((uint8_t*)z, y, 0x00000002); - RND512P((uint8_t*)y, z, 0x00000003); - RND512P((uint8_t*)z, y, 0x00000004); - RND512P((uint8_t*)y, z, 0x00000005); - RND512P((uint8_t*)z, y, 0x00000006); - RND512P((uint8_t*)y, z, 0x00000007); - RND512P((uint8_t*)z, y, 0x00000008); - RND512P((uint8_t*)y, temp, 0x00000009); - for (j = 0; j < 2*COLS512; j++) { - ctx->chaining[j] ^= temp[j]; - } -} - -/* initialise context */ -static void Init(groestlHashState* ctx) { - int i = 0; - /* allocate memory for state and data buffer */ - - for(;i<(SIZE512/sizeof(uint32_t));i++) - { - ctx->chaining[i] = 0; - } - - /* set initial value */ - ctx->chaining[2*COLS512-1] = u32BIG((uint32_t)HASH_BIT_LEN); - - /* set other variables */ - ctx->buf_ptr = 0; - ctx->block_counter1 = 0; - ctx->block_counter2 = 0; - ctx->bits_in_last_byte = 0; -} - -/* update state with databitlen bits of input */ -static void Update(groestlHashState* ctx, - const BitSequence* input, - DataLength databitlen) { - int index = 0; - int msglen = (int)(databitlen/8); - int rem = (int)(databitlen%8); - - /* if the buffer contains data that has not yet been digested, first - add data to buffer until full */ - if (ctx->buf_ptr) { - while (ctx->buf_ptr < SIZE512 && index < msglen) { - ctx->buffer[(int)ctx->buf_ptr++] = input[index++]; - } - if (ctx->buf_ptr < SIZE512) { - /* buffer still not full, return */ - if (rem) { - ctx->bits_in_last_byte = rem; - ctx->buffer[(int)ctx->buf_ptr++] = input[index]; - } - return; - } - - /* digest buffer */ - ctx->buf_ptr = 0; - Transform(ctx, ctx->buffer, SIZE512); - } - - /* digest bulk of message */ - Transform(ctx, input+index, msglen-index); - index += ((msglen-index)/SIZE512)*SIZE512; - - /* store remaining data in buffer */ - while (index < msglen) { - ctx->buffer[(int)ctx->buf_ptr++] = input[index++]; - } - - /* if non-integral number of bytes have been supplied, store - remaining bits in last byte, together with information about - number of bits */ - if (rem) { - ctx->bits_in_last_byte = rem; - ctx->buffer[(int)ctx->buf_ptr++] = input[index]; - } -} - -#define BILB ctx->bits_in_last_byte - -/* finalise: process remaining data (including padding), perform - output transformation, and write hash result to 'output' */ -static void Final(groestlHashState* ctx, - BitSequence* output) { - int i, j = 0, hashbytelen = HASH_BIT_LEN/8; - uint8_t *s = (BitSequence*)ctx->chaining; - - /* pad with '1'-bit and first few '0'-bits */ - if (BILB) { - ctx->buffer[(int)ctx->buf_ptr-1] &= ((1<buffer[(int)ctx->buf_ptr-1] ^= 0x1<<(7-BILB); - BILB = 0; - } - else ctx->buffer[(int)ctx->buf_ptr++] = 0x80; - - /* pad with '0'-bits */ - if (ctx->buf_ptr > SIZE512-LENGTHFIELDLEN) { - /* padding requires two blocks */ - while (ctx->buf_ptr < SIZE512) { - ctx->buffer[(int)ctx->buf_ptr++] = 0; - } - /* digest first padding block */ - Transform(ctx, ctx->buffer, SIZE512); - ctx->buf_ptr = 0; - } - while (ctx->buf_ptr < SIZE512-LENGTHFIELDLEN) { - ctx->buffer[(int)ctx->buf_ptr++] = 0; - } - - /* length padding */ - ctx->block_counter1++; - if (ctx->block_counter1 == 0) ctx->block_counter2++; - ctx->buf_ptr = SIZE512; - - while (ctx->buf_ptr > SIZE512-(int)sizeof(uint32_t)) { - ctx->buffer[(int)--ctx->buf_ptr] = (uint8_t)ctx->block_counter1; - ctx->block_counter1 >>= 8; - } - while (ctx->buf_ptr > SIZE512-LENGTHFIELDLEN) { - ctx->buffer[(int)--ctx->buf_ptr] = (uint8_t)ctx->block_counter2; - ctx->block_counter2 >>= 8; - } - /* digest final padding block */ - Transform(ctx, ctx->buffer, SIZE512); - /* perform output transformation */ - OutputTransformation(ctx); - - /* store hash result in output */ - for (i = SIZE512-hashbytelen; i < SIZE512; i++,j++) { - output[j] = s[i]; - } - - /* zeroise relevant variables and deallocate memory */ - for (i = 0; i < COLS512; i++) { - ctx->chaining[i] = 0; - } - for (i = 0; i < SIZE512; i++) { - ctx->buffer[i] = 0; - } -} - -/* hash bit sequence */ -void groestl(const BitSequence* data, - DataLength databitlen, - BitSequence* hashval) { - - groestlHashState context; - - /* initialise */ - Init(&context); - - - /* process message */ - Update(&context, data, databitlen); - - /* finalise */ - Final(&context, hashval); -} -/* -static int crypto_hash(unsigned char *out, - const unsigned char *in, - unsigned long long len) -{ - groestl(in, 8*len, out); - return 0; -} - -*/ diff --git a/src_native/groestl.h b/src_native/groestl.h deleted file mode 100644 index 29287fc0..00000000 --- a/src_native/groestl.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef GROESTL_H -#define GROESTL_H - -#ifdef __cplusplus -extern "C" { -#endif - -extern void groestl(const unsigned char *input, - unsigned long long len, - unsigned char *output); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src_native/groestl.o b/src_native/groestl.o deleted file mode 100644 index a75efad1..00000000 Binary files a/src_native/groestl.o and /dev/null differ diff --git a/src_native/groestl_tables.h b/src_native/groestl_tables.h deleted file mode 100644 index a23295c3..00000000 --- a/src_native/groestl_tables.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __tables_h -#define __tables_h - - -const uint32_t T[512] = {0xa5f432c6, 0xc6a597f4, 0x84976ff8, 0xf884eb97, 0x99b05eee, 0xee99c7b0, 0x8d8c7af6, 0xf68df78c, 0xd17e8ff, 0xff0de517, 0xbddc0ad6, 0xd6bdb7dc, 0xb1c816de, 0xdeb1a7c8, 0x54fc6d91, 0x915439fc -, 0x50f09060, 0x6050c0f0, 0x3050702, 0x2030405, 0xa9e02ece, 0xcea987e0, 0x7d87d156, 0x567dac87, 0x192bcce7, 0xe719d52b, 0x62a613b5, 0xb56271a6, 0xe6317c4d, 0x4de69a31, 0x9ab559ec, 0xec9ac3b5 -, 0x45cf408f, 0x8f4505cf, 0x9dbca31f, 0x1f9d3ebc, 0x40c04989, 0x894009c0, 0x879268fa, 0xfa87ef92, 0x153fd0ef, 0xef15c53f, 0xeb2694b2, 0xb2eb7f26, 0xc940ce8e, 0x8ec90740, 0xb1de6fb, 0xfb0bed1d -, 0xec2f6e41, 0x41ec822f, 0x67a91ab3, 0xb3677da9, 0xfd1c435f, 0x5ffdbe1c, 0xea256045, 0x45ea8a25, 0xbfdaf923, 0x23bf46da, 0xf7025153, 0x53f7a602, 0x96a145e4, 0xe496d3a1, 0x5bed769b, 0x9b5b2ded -, 0xc25d2875, 0x75c2ea5d, 0x1c24c5e1, 0xe11cd924, 0xaee9d43d, 0x3dae7ae9, 0x6abef24c, 0x4c6a98be, 0x5aee826c, 0x6c5ad8ee, 0x41c3bd7e, 0x7e41fcc3, 0x206f3f5, 0xf502f106, 0x4fd15283, 0x834f1dd1 -, 0x5ce48c68, 0x685cd0e4, 0xf4075651, 0x51f4a207, 0x345c8dd1, 0xd134b95c, 0x818e1f9, 0xf908e918, 0x93ae4ce2, 0xe293dfae, 0x73953eab, 0xab734d95, 0x53f59762, 0x6253c4f5, 0x3f416b2a, 0x2a3f5441 -, 0xc141c08, 0x80c1014, 0x52f66395, 0x955231f6, 0x65afe946, 0x46658caf, 0x5ee27f9d, 0x9d5e21e2, 0x28784830, 0x30286078, 0xa1f8cf37, 0x37a16ef8, 0xf111b0a, 0xa0f1411, 0xb5c4eb2f, 0x2fb55ec4 -, 0x91b150e, 0xe091c1b, 0x365a7e24, 0x2436485a, 0x9bb6ad1b, 0x1b9b36b6, 0x3d4798df, 0xdf3da547, 0x266aa7cd, 0xcd26816a, 0x69bbf54e, 0x4e699cbb, 0xcd4c337f, 0x7fcdfe4c, 0x9fba50ea, 0xea9fcfba -, 0x1b2d3f12, 0x121b242d, 0x9eb9a41d, 0x1d9e3ab9, 0x749cc458, 0x5874b09c, 0x2e724634, 0x342e6872, 0x2d774136, 0x362d6c77, 0xb2cd11dc, 0xdcb2a3cd, 0xee299db4, 0xb4ee7329, 0xfb164d5b, 0x5bfbb616 -, 0xf601a5a4, 0xa4f65301, 0x4dd7a176, 0x764decd7, 0x61a314b7, 0xb76175a3, 0xce49347d, 0x7dcefa49, 0x7b8ddf52, 0x527ba48d, 0x3e429fdd, 0xdd3ea142, 0x7193cd5e, 0x5e71bc93, 0x97a2b113, 0x139726a2 -, 0xf504a2a6, 0xa6f55704, 0x68b801b9, 0xb96869b8, 0x0, 0x0, 0x2c74b5c1, 0xc12c9974, 0x60a0e040, 0x406080a0, 0x1f21c2e3, 0xe31fdd21, 0xc8433a79, 0x79c8f243, 0xed2c9ab6, 0xb6ed772c -, 0xbed90dd4, 0xd4beb3d9, 0x46ca478d, 0x8d4601ca, 0xd9701767, 0x67d9ce70, 0x4bddaf72, 0x724be4dd, 0xde79ed94, 0x94de3379, 0xd467ff98, 0x98d42b67, 0xe82393b0, 0xb0e87b23, 0x4ade5b85, 0x854a11de -, 0x6bbd06bb, 0xbb6b6dbd, 0x2a7ebbc5, 0xc52a917e, 0xe5347b4f, 0x4fe59e34, 0x163ad7ed, 0xed16c13a, 0xc554d286, 0x86c51754, 0xd762f89a, 0x9ad72f62, 0x55ff9966, 0x6655ccff, 0x94a7b611, 0x119422a7 -, 0xcf4ac08a, 0x8acf0f4a, 0x1030d9e9, 0xe910c930, 0x60a0e04, 0x406080a, 0x819866fe, 0xfe81e798, 0xf00baba0, 0xa0f05b0b, 0x44ccb478, 0x7844f0cc, 0xbad5f025, 0x25ba4ad5, 0xe33e754b, 0x4be3963e -, 0xf30eaca2, 0xa2f35f0e, 0xfe19445d, 0x5dfeba19, 0xc05bdb80, 0x80c01b5b, 0x8a858005, 0x58a0a85, 0xadecd33f, 0x3fad7eec, 0xbcdffe21, 0x21bc42df, 0x48d8a870, 0x7048e0d8, 0x40cfdf1, 0xf104f90c -, 0xdf7a1963, 0x63dfc67a, 0xc1582f77, 0x77c1ee58, 0x759f30af, 0xaf75459f, 0x63a5e742, 0x426384a5, 0x30507020, 0x20304050, 0x1a2ecbe5, 0xe51ad12e, 0xe12effd, 0xfd0ee112, 0x6db708bf, 0xbf6d65b7 -, 0x4cd45581, 0x814c19d4, 0x143c2418, 0x1814303c, 0x355f7926, 0x26354c5f, 0x2f71b2c3, 0xc32f9d71, 0xe13886be, 0xbee16738, 0xa2fdc835, 0x35a26afd, 0xcc4fc788, 0x88cc0b4f, 0x394b652e, 0x2e395c4b -, 0x57f96a93, 0x93573df9, 0xf20d5855, 0x55f2aa0d, 0x829d61fc, 0xfc82e39d, 0x47c9b37a, 0x7a47f4c9, 0xacef27c8, 0xc8ac8bef, 0xe73288ba, 0xbae76f32, 0x2b7d4f32, 0x322b647d, 0x95a442e6, 0xe695d7a4 -, 0xa0fb3bc0, 0xc0a09bfb, 0x98b3aa19, 0x199832b3, 0xd168f69e, 0x9ed12768, 0x7f8122a3, 0xa37f5d81, 0x66aaee44, 0x446688aa, 0x7e82d654, 0x547ea882, 0xabe6dd3b, 0x3bab76e6, 0x839e950b, 0xb83169e -, 0xca45c98c, 0x8cca0345, 0x297bbcc7, 0xc729957b, 0xd36e056b, 0x6bd3d66e, 0x3c446c28, 0x283c5044, 0x798b2ca7, 0xa779558b, 0xe23d81bc, 0xbce2633d, 0x1d273116, 0x161d2c27, 0x769a37ad, 0xad76419a -, 0x3b4d96db, 0xdb3bad4d, 0x56fa9e64, 0x6456c8fa, 0x4ed2a674, 0x744ee8d2, 0x1e223614, 0x141e2822, 0xdb76e492, 0x92db3f76, 0xa1e120c, 0xc0a181e, 0x6cb4fc48, 0x486c90b4, 0xe4378fb8, 0xb8e46b37 -, 0x5de7789f, 0x9f5d25e7, 0x6eb20fbd, 0xbd6e61b2, 0xef2a6943, 0x43ef862a, 0xa6f135c4, 0xc4a693f1, 0xa8e3da39, 0x39a872e3, 0xa4f7c631, 0x31a462f7, 0x37598ad3, 0xd337bd59, 0x8b8674f2, 0xf28bff86 -, 0x325683d5, 0xd532b156, 0x43c54e8b, 0x8b430dc5, 0x59eb856e, 0x6e59dceb, 0xb7c218da, 0xdab7afc2, 0x8c8f8e01, 0x18c028f, 0x64ac1db1, 0xb16479ac, 0xd26df19c, 0x9cd2236d, 0xe03b7249, 0x49e0923b -, 0xb4c71fd8, 0xd8b4abc7, 0xfa15b9ac, 0xacfa4315, 0x709faf3, 0xf307fd09, 0x256fa0cf, 0xcf25856f, 0xafea20ca, 0xcaaf8fea, 0x8e897df4, 0xf48ef389, 0xe9206747, 0x47e98e20, 0x18283810, 0x10182028 -, 0xd5640b6f, 0x6fd5de64, 0x888373f0, 0xf088fb83, 0x6fb1fb4a, 0x4a6f94b1, 0x7296ca5c, 0x5c72b896, 0x246c5438, 0x3824706c, 0xf1085f57, 0x57f1ae08, 0xc7522173, 0x73c7e652, 0x51f36497, 0x975135f3 -, 0x2365aecb, 0xcb238d65, 0x7c8425a1, 0xa17c5984, 0x9cbf57e8, 0xe89ccbbf, 0x21635d3e, 0x3e217c63, 0xdd7cea96, 0x96dd377c, 0xdc7f1e61, 0x61dcc27f, 0x86919c0d, 0xd861a91, 0x85949b0f, 0xf851e94 -, 0x90ab4be0, 0xe090dbab, 0x42c6ba7c, 0x7c42f8c6, 0xc4572671, 0x71c4e257, 0xaae529cc, 0xccaa83e5, 0xd873e390, 0x90d83b73, 0x50f0906, 0x6050c0f, 0x103f4f7, 0xf701f503, 0x12362a1c, 0x1c123836 -, 0xa3fe3cc2, 0xc2a39ffe, 0x5fe18b6a, 0x6a5fd4e1, 0xf910beae, 0xaef94710, 0xd06b0269, 0x69d0d26b, 0x91a8bf17, 0x17912ea8, 0x58e87199, 0x995829e8, 0x2769533a, 0x3a277469, 0xb9d0f727, 0x27b94ed0 -, 0x384891d9, 0xd938a948, 0x1335deeb, 0xeb13cd35, 0xb3cee52b, 0x2bb356ce, 0x33557722, 0x22334455, 0xbbd604d2, 0xd2bbbfd6, 0x709039a9, 0xa9704990, 0x89808707, 0x7890e80, 0xa7f2c133, 0x33a766f2 -, 0xb6c1ec2d, 0x2db65ac1, 0x22665a3c, 0x3c227866, 0x92adb815, 0x15922aad, 0x2060a9c9, 0xc9208960, 0x49db5c87, 0x874915db, 0xff1ab0aa, 0xaaff4f1a, 0x7888d850, 0x5078a088, 0x7a8e2ba5, 0xa57a518e -, 0x8f8a8903, 0x38f068a, 0xf8134a59, 0x59f8b213, 0x809b9209, 0x980129b, 0x1739231a, 0x1a173439, 0xda751065, 0x65daca75, 0x315384d7, 0xd731b553, 0xc651d584, 0x84c61351, 0xb8d303d0, 0xd0b8bbd3 -, 0xc35edc82, 0x82c31f5e, 0xb0cbe229, 0x29b052cb, 0x7799c35a, 0x5a77b499, 0x11332d1e, 0x1e113c33, 0xcb463d7b, 0x7bcbf646, 0xfc1fb7a8, 0xa8fc4b1f, 0xd6610c6d, 0x6dd6da61, 0x3a4e622c, 0x2c3a584e}; - -#endif /* __tables_h */ diff --git a/src_native/hash-ops.h b/src_native/hash-ops.h deleted file mode 100644 index 6661f1d2..00000000 --- a/src_native/hash-ops.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once - -//#if !defined(__cplusplus) - -#include -#include -#include -#include - -#include "common/int-util.h" -//#include "warnings.h" - -static inline void *padd(void *p, size_t i) { - return (char *) p + i; -} - -static inline const void *cpadd(const void *p, size_t i) { - return (const char *) p + i; -} - -//PUSH_WARNINGS -//DISABLE_VS_WARNINGS(4267) -static_assert(sizeof(size_t) == 4 || sizeof(size_t) == 8, "size_t must be 4 or 8 bytes long"); -static inline void place_length(uint8_t *buffer, size_t bufsize, size_t length) { - if (sizeof(size_t) == 4) { - *(uint32_t *) padd(buffer, bufsize - 4) = swap32be(length); - } else { - *(uint64_t *) padd(buffer, bufsize - 8) = swap64be(length); - } -} -//POP_WARNINGS - -#pragma pack(push, 1) -union hash_state { - uint8_t b[200]; - uint64_t w[25]; -}; -#pragma pack(pop) -static_assert(sizeof(union hash_state) == 200, "Invalid structure size"); - -void hash_permutation(union hash_state *state); -void hash_process(union hash_state *state, const uint8_t *buf, size_t count); - -//#endif - -enum { - HASH_SIZE = 32, - HASH_DATA_AREA = 136 -}; - -void cn_fast_hash(const void *data, size_t length, char *hash); -void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed); - -void hash_extra_blake(const void *data, size_t length, char *hash); -void hash_extra_groestl(const void *data, size_t length, char *hash); -void hash_extra_jh(const void *data, size_t length, char *hash); -void hash_extra_skein(const void *data, size_t length, char *hash); - -void tree_hash(const char (*hashes)[HASH_SIZE], size_t count, char *root_hash); diff --git a/src_native/hash.c b/src_native/hash.c deleted file mode 100644 index cab59a02..00000000 --- a/src_native/hash.c +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#include -#include -#include - -#include "hash-ops.h" -#include "keccak.h" - -void hash_permutation(union hash_state *state) { - keccakf((uint64_t*)state, 24); -} - -void hash_process(union hash_state *state, const uint8_t *buf, size_t count) { - keccak1600(buf, count, (uint8_t*)state); -} - -void cn_fast_hash(const void *data, size_t length, char *hash) { - union hash_state state; - hash_process(&state, reinterpret_cast(data), length); - memcpy(hash, &state, HASH_SIZE); -} diff --git a/src_native/hash.h b/src_native/hash.h deleted file mode 100644 index fa0bcd3a..00000000 --- a/src_native/hash.h +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2014-2018, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once - -#include -#include - -#include "common/pod-class.h" -#include "generic-ops.h" -//#include "hex.h" -//#include "span.h" - -#include "hash-ops.h" - -namespace crypto { - -#pragma pack(push, 1) - POD_CLASS hash { - char data[HASH_SIZE]; - }; - POD_CLASS hash8 { - char data[8]; - }; -#pragma pack(pop) - - static_assert(sizeof(hash) == HASH_SIZE, "Invalid structure size"); - static_assert(sizeof(hash8) == 8, "Invalid structure size"); - - /* - Cryptonight hash functions - */ - - inline void cn_fast_hash(const void *data, std::size_t length, hash &hash) { - cn_fast_hash(data, length, reinterpret_cast(&hash)); - } - - inline hash cn_fast_hash(const void *data, std::size_t length) { - hash h; - cn_fast_hash(data, length, reinterpret_cast(&h)); - return h; - } - - inline void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant = 0) { - cn_slow_hash(data, length, reinterpret_cast(&hash), variant, 0/*prehashed*/); - } - - inline void cn_slow_hash_prehashed(const void *data, std::size_t length, hash &hash, int variant = 0) { - cn_slow_hash(data, length, reinterpret_cast(&hash), variant, 1/*prehashed*/); - } - - inline void tree_hash(const hash *hashes, std::size_t count, hash &root_hash) { - tree_hash(reinterpret_cast(hashes), count, reinterpret_cast(&root_hash)); - } - -// inline std::ostream &operator <<(std::ostream &o, const crypto::hash &v) { -// epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; -// } -// inline std::ostream &operator <<(std::ostream &o, const crypto::hash8 &v) { -// epee::to_hex::formatted(o, epee::as_byte_span(v)); return o; -// } -} - -CRYPTO_MAKE_HASHABLE(hash) -CRYPTO_MAKE_COMPARABLE(hash8) diff --git a/src_native/hash.o b/src_native/hash.o deleted file mode 100644 index 489b2fce..00000000 Binary files a/src_native/hash.o and /dev/null differ diff --git a/src_native/html_template/shell_minimal.html b/src_native/html_template/shell_minimal.html deleted file mode 100644 index d37c32e9..00000000 --- a/src_native/html_template/shell_minimal.html +++ /dev/null @@ -1 +0,0 @@ -{{{ SCRIPT }}} \ No newline at end of file diff --git a/src_native/int-util.h b/src_native/int-util.h deleted file mode 100644 index 34288805..00000000 --- a/src_native/int-util.h +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright (c) 2014-2017, The Monero Project -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without modification, are -// permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this list of -// conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright notice, this list -// of conditions and the following disclaimer in the documentation and/or other -// materials provided with the distribution. -// -// 3. Neither the name of the copyright holder nor the names of its contributors may be -// used to endorse or promote products derived from this software without specific -// prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL -// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, -// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF -// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - -#pragma once - -#include -#include -#include -#include -#include - -#if defined(__ANDROID__) -#include -#endif - -#if defined(_MSC_VER) -#include - -static inline uint32_t rol32(uint32_t x, int r) { - static_assert(sizeof(uint32_t) == sizeof(unsigned int), "this code assumes 32-bit integers"); - return _rotl(x, r); -} - -static inline uint64_t rol64(uint64_t x, int r) { - return _rotl64(x, r); -} - -#else - -static inline uint32_t rol32(uint32_t x, int r) { - return (x << (r & 31)) | (x >> (-r & 31)); -} - -static inline uint64_t rol64(uint64_t x, int r) { - return (x << (r & 63)) | (x >> (-r & 63)); -} - -#endif - -static inline uint64_t hi_dword(uint64_t val) { - return val >> 32; -} - -static inline uint64_t lo_dword(uint64_t val) { - return val & 0xFFFFFFFF; -} - -static inline uint64_t mul128(uint64_t multiplier, uint64_t multiplicand, uint64_t* product_hi) { - // multiplier = ab = a * 2^32 + b - // multiplicand = cd = c * 2^32 + d - // ab * cd = a * c * 2^64 + (a * d + b * c) * 2^32 + b * d - uint64_t a = hi_dword(multiplier); - uint64_t b = lo_dword(multiplier); - uint64_t c = hi_dword(multiplicand); - uint64_t d = lo_dword(multiplicand); - - uint64_t ac = a * c; - uint64_t ad = a * d; - uint64_t bc = b * c; - uint64_t bd = b * d; - - uint64_t adbc = ad + bc; - uint64_t adbc_carry = adbc < ad ? 1 : 0; - - // multiplier * multiplicand = product_hi * 2^64 + product_lo - uint64_t product_lo = bd + (adbc << 32); - uint64_t product_lo_carry = product_lo < bd ? 1 : 0; - *product_hi = ac + (adbc >> 32) + (adbc_carry << 32) + product_lo_carry; - assert(ac <= *product_hi); - - return product_lo; -} - -static inline uint64_t div_with_reminder(uint64_t dividend, uint32_t divisor, uint32_t* remainder) { - dividend |= ((uint64_t)*remainder) << 32; - *remainder = dividend % divisor; - return dividend / divisor; -} - -// Long division with 2^32 base -static inline uint32_t div128_32(uint64_t dividend_hi, uint64_t dividend_lo, uint32_t divisor, uint64_t* quotient_hi, uint64_t* quotient_lo) { - uint64_t dividend_dwords[4]; - uint32_t remainder = 0; - - dividend_dwords[3] = hi_dword(dividend_hi); - dividend_dwords[2] = lo_dword(dividend_hi); - dividend_dwords[1] = hi_dword(dividend_lo); - dividend_dwords[0] = lo_dword(dividend_lo); - - *quotient_hi = div_with_reminder(dividend_dwords[3], divisor, &remainder) << 32; - *quotient_hi |= div_with_reminder(dividend_dwords[2], divisor, &remainder); - *quotient_lo = div_with_reminder(dividend_dwords[1], divisor, &remainder) << 32; - *quotient_lo |= div_with_reminder(dividend_dwords[0], divisor, &remainder); - - return remainder; -} - -#define IDENT32(x) ((uint32_t) (x)) -#define IDENT64(x) ((uint64_t) (x)) - -#define SWAP32(x) ((((uint32_t) (x) & 0x000000ff) << 24) | \ - (((uint32_t) (x) & 0x0000ff00) << 8) | \ - (((uint32_t) (x) & 0x00ff0000) >> 8) | \ - (((uint32_t) (x) & 0xff000000) >> 24)) -#define SWAP64(x) ((((uint64_t) (x) & 0x00000000000000ff) << 56) | \ - (((uint64_t) (x) & 0x000000000000ff00) << 40) | \ - (((uint64_t) (x) & 0x0000000000ff0000) << 24) | \ - (((uint64_t) (x) & 0x00000000ff000000) << 8) | \ - (((uint64_t) (x) & 0x000000ff00000000) >> 8) | \ - (((uint64_t) (x) & 0x0000ff0000000000) >> 24) | \ - (((uint64_t) (x) & 0x00ff000000000000) >> 40) | \ - (((uint64_t) (x) & 0xff00000000000000) >> 56)) - -static inline uint32_t ident32(uint32_t x) { return x; } -static inline uint64_t ident64(uint64_t x) { return x; } - -#ifndef __OpenBSD__ -# if defined(__ANDROID__) && defined(__swap32) && !defined(swap32) -# define swap32 __swap32 -# elif !defined(swap32) -static inline uint32_t swap32(uint32_t x) { - x = ((x & 0x00ff00ff) << 8) | ((x & 0xff00ff00) >> 8); - return (x << 16) | (x >> 16); -} -# endif -# if defined(__ANDROID__) && defined(__swap64) && !defined(swap64) -# define swap64 __swap64 -# elif !defined(swap64) -static inline uint64_t swap64(uint64_t x) { - x = ((x & 0x00ff00ff00ff00ff) << 8) | ((x & 0xff00ff00ff00ff00) >> 8); - x = ((x & 0x0000ffff0000ffff) << 16) | ((x & 0xffff0000ffff0000) >> 16); - return (x << 32) | (x >> 32); -} -# endif -#endif /* __OpenBSD__ */ - -#if defined(__GNUC__) -#define UNUSED __attribute__((unused)) -#else -#define UNUSED -#endif -static inline void mem_inplace_ident(void *mem UNUSED, size_t n UNUSED) { } -#undef UNUSED - -static inline void mem_inplace_swap32(void *mem, size_t n) { - size_t i; - for (i = 0; i < n; i++) { - ((uint32_t *) mem)[i] = swap32(((const uint32_t *) mem)[i]); - } -} -static inline void mem_inplace_swap64(void *mem, size_t n) { - size_t i; - for (i = 0; i < n; i++) { - ((uint64_t *) mem)[i] = swap64(((const uint64_t *) mem)[i]); - } -} - -static inline void memcpy_ident32(void *dst, const void *src, size_t n) { - memcpy(dst, src, 4 * n); -} -static inline void memcpy_ident64(void *dst, const void *src, size_t n) { - memcpy(dst, src, 8 * n); -} - -static inline void memcpy_swap32(void *dst, const void *src, size_t n) { - size_t i; - for (i = 0; i < n; i++) { - ((uint32_t *) dst)[i] = swap32(((const uint32_t *) src)[i]); - } -} -static inline void memcpy_swap64(void *dst, const void *src, size_t n) { - size_t i; - for (i = 0; i < n; i++) { - ((uint64_t *) dst)[i] = swap64(((const uint64_t *) src)[i]); - } -} - -#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || !defined(BIG_ENDIAN) -static_assert(false, "BYTE_ORDER is undefined. Perhaps, GNU extensions are not enabled"); -#endif - -#if BYTE_ORDER == LITTLE_ENDIAN -#define SWAP32LE IDENT32 -#define SWAP32BE SWAP32 -#define swap32le ident32 -#define swap32be swap32 -#define mem_inplace_swap32le mem_inplace_ident -#define mem_inplace_swap32be mem_inplace_swap32 -#define memcpy_swap32le memcpy_ident32 -#define memcpy_swap32be memcpy_swap32 -#define SWAP64LE IDENT64 -#define SWAP64BE SWAP64 -#define swap64le ident64 -#define swap64be swap64 -#define mem_inplace_swap64le mem_inplace_ident -#define mem_inplace_swap64be mem_inplace_swap64 -#define memcpy_swap64le memcpy_ident64 -#define memcpy_swap64be memcpy_swap64 -#endif - -#if BYTE_ORDER == BIG_ENDIAN -#define SWAP32BE IDENT32 -#define SWAP32LE SWAP32 -#define swap32be ident32 -#define swap32le swap32 -#define mem_inplace_swap32be mem_inplace_ident -#define mem_inplace_swap32le mem_inplace_swap32 -#define memcpy_swap32be memcpy_ident32 -#define memcpy_swap32le memcpy_swap32 -#define SWAP64BE IDENT64 -#define SWAP64LE SWAP64 -#define swap64be ident64 -#define swap64le swap64 -#define mem_inplace_swap64be mem_inplace_ident -#define mem_inplace_swap64le mem_inplace_swap64 -#define memcpy_swap64be memcpy_ident64 -#define memcpy_swap64le memcpy_swap64 -#endif diff --git a/src_native/jh.h b/src_native/jh.h deleted file mode 100644 index 959ba057..00000000 --- a/src_native/jh.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef JH_H -#define JH_H -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern void jh(unsigned bit_len, const uint8_t input[], - size_t input_bit_length, uint8_t output[]); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src_native/jh_ansi_opt64.c b/src_native/jh_ansi_opt64.c deleted file mode 100644 index 7aa0310e..00000000 --- a/src_native/jh_ansi_opt64.c +++ /dev/null @@ -1,377 +0,0 @@ -/*This program gives the 64-bit optimized bitslice implementation of JH using ANSI C - - -------------------------------- - Performance - - Microprocessor: Intel CORE 2 processor (Core 2 Duo Mobile T6600 2.2GHz) - Operating System: 64-bit Ubuntu 10.04 (Linux kernel 2.6.32-22-generic) - Speed for long message: - 1) 45.8 cycles/byte compiler: Intel C++ Compiler 11.1 compilation option: icc -O2 - 2) 56.8 cycles/byte compiler: gcc 4.4.3 compilation option: gcc -O3 - - -------------------------------- - Last Modified: January 16, 2011 -*/ - - - -#include -#include -#include - -typedef unsigned long long uint64; - -typedef unsigned char BitSequence; -typedef unsigned long long DataLength; -typedef enum {SUCCESS = 0, FAIL = 1, BAD_HASHLEN = 2} HashReturn; - -/*define data alignment for different C compilers*/ -#if defined(__GNUC__) - #define DATA_ALIGN16(x) x __attribute__ ((aligned(16))) -#else - #define DATA_ALIGN16(x) __declspec(align(16)) x -#endif - - -typedef struct { - int hashbitlen; /*the message digest size*/ - unsigned long long databitlen; /*the message size in bits*/ - unsigned long long datasize_in_buffer; /*the size of the message remained in buffer; assumed to be multiple of 8bits except for the last partial block at the end of the message*/ - DATA_ALIGN16(uint64 x[8][2]); /*the 1024-bit state, ( x[i][0] || x[i][1] ) is the ith row of the state in the pseudocode*/ - unsigned char buffer[64]; /*the 512-bit message block to be hashed;*/ -} hashState; - - -/*The initial hash value H(0)*/ -static const unsigned char JH224_H0[128]={0x2d,0xfe,0xdd,0x62,0xf9,0x9a,0x98,0xac,0xae,0x7c,0xac,0xd6,0x19,0xd6,0x34,0xe7,0xa4,0x83,0x10,0x5,0xbc,0x30,0x12,0x16,0xb8,0x60,0x38,0xc6,0xc9,0x66,0x14,0x94,0x66,0xd9,0x89,0x9f,0x25,0x80,0x70,0x6f,0xce,0x9e,0xa3,0x1b,0x1d,0x9b,0x1a,0xdc,0x11,0xe8,0x32,0x5f,0x7b,0x36,0x6e,0x10,0xf9,0x94,0x85,0x7f,0x2,0xfa,0x6,0xc1,0x1b,0x4f,0x1b,0x5c,0xd8,0xc8,0x40,0xb3,0x97,0xf6,0xa1,0x7f,0x6e,0x73,0x80,0x99,0xdc,0xdf,0x93,0xa5,0xad,0xea,0xa3,0xd3,0xa4,0x31,0xe8,0xde,0xc9,0x53,0x9a,0x68,0x22,0xb4,0xa9,0x8a,0xec,0x86,0xa1,0xe4,0xd5,0x74,0xac,0x95,0x9c,0xe5,0x6c,0xf0,0x15,0x96,0xd,0xea,0xb5,0xab,0x2b,0xbf,0x96,0x11,0xdc,0xf0,0xdd,0x64,0xea,0x6e}; -static const unsigned char JH256_H0[128]={0xeb,0x98,0xa3,0x41,0x2c,0x20,0xd3,0xeb,0x92,0xcd,0xbe,0x7b,0x9c,0xb2,0x45,0xc1,0x1c,0x93,0x51,0x91,0x60,0xd4,0xc7,0xfa,0x26,0x0,0x82,0xd6,0x7e,0x50,0x8a,0x3,0xa4,0x23,0x9e,0x26,0x77,0x26,0xb9,0x45,0xe0,0xfb,0x1a,0x48,0xd4,0x1a,0x94,0x77,0xcd,0xb5,0xab,0x26,0x2,0x6b,0x17,0x7a,0x56,0xf0,0x24,0x42,0xf,0xff,0x2f,0xa8,0x71,0xa3,0x96,0x89,0x7f,0x2e,0x4d,0x75,0x1d,0x14,0x49,0x8,0xf7,0x7d,0xe2,0x62,0x27,0x76,0x95,0xf7,0x76,0x24,0x8f,0x94,0x87,0xd5,0xb6,0x57,0x47,0x80,0x29,0x6c,0x5c,0x5e,0x27,0x2d,0xac,0x8e,0xd,0x6c,0x51,0x84,0x50,0xc6,0x57,0x5,0x7a,0xf,0x7b,0xe4,0xd3,0x67,0x70,0x24,0x12,0xea,0x89,0xe3,0xab,0x13,0xd3,0x1c,0xd7,0x69}; -static const unsigned char JH384_H0[128]={0x48,0x1e,0x3b,0xc6,0xd8,0x13,0x39,0x8a,0x6d,0x3b,0x5e,0x89,0x4a,0xde,0x87,0x9b,0x63,0xfa,0xea,0x68,0xd4,0x80,0xad,0x2e,0x33,0x2c,0xcb,0x21,0x48,0xf,0x82,0x67,0x98,0xae,0xc8,0x4d,0x90,0x82,0xb9,0x28,0xd4,0x55,0xea,0x30,0x41,0x11,0x42,0x49,0x36,0xf5,0x55,0xb2,0x92,0x48,0x47,0xec,0xc7,0x25,0xa,0x93,0xba,0xf4,0x3c,0xe1,0x56,0x9b,0x7f,0x8a,0x27,0xdb,0x45,0x4c,0x9e,0xfc,0xbd,0x49,0x63,0x97,0xaf,0xe,0x58,0x9f,0xc2,0x7d,0x26,0xaa,0x80,0xcd,0x80,0xc0,0x8b,0x8c,0x9d,0xeb,0x2e,0xda,0x8a,0x79,0x81,0xe8,0xf8,0xd5,0x37,0x3a,0xf4,0x39,0x67,0xad,0xdd,0xd1,0x7a,0x71,0xa9,0xb4,0xd3,0xbd,0xa4,0x75,0xd3,0x94,0x97,0x6c,0x3f,0xba,0x98,0x42,0x73,0x7f}; -static const unsigned char JH512_H0[128]={0x6f,0xd1,0x4b,0x96,0x3e,0x0,0xaa,0x17,0x63,0x6a,0x2e,0x5,0x7a,0x15,0xd5,0x43,0x8a,0x22,0x5e,0x8d,0xc,0x97,0xef,0xb,0xe9,0x34,0x12,0x59,0xf2,0xb3,0xc3,0x61,0x89,0x1d,0xa0,0xc1,0x53,0x6f,0x80,0x1e,0x2a,0xa9,0x5,0x6b,0xea,0x2b,0x6d,0x80,0x58,0x8e,0xcc,0xdb,0x20,0x75,0xba,0xa6,0xa9,0xf,0x3a,0x76,0xba,0xf8,0x3b,0xf7,0x1,0x69,0xe6,0x5,0x41,0xe3,0x4a,0x69,0x46,0xb5,0x8a,0x8e,0x2e,0x6f,0xe6,0x5a,0x10,0x47,0xa7,0xd0,0xc1,0x84,0x3c,0x24,0x3b,0x6e,0x71,0xb1,0x2d,0x5a,0xc1,0x99,0xcf,0x57,0xf6,0xec,0x9d,0xb1,0xf8,0x56,0xa7,0x6,0x88,0x7c,0x57,0x16,0xb1,0x56,0xe3,0xc2,0xfc,0xdf,0xe6,0x85,0x17,0xfb,0x54,0x5a,0x46,0x78,0xcc,0x8c,0xdd,0x4b}; - -/*42 round constants, each round constant is 32-byte (256-bit)*/ -static const unsigned char E8_bitslice_roundconstant[42][32]={ -{0x72,0xd5,0xde,0xa2,0xdf,0x15,0xf8,0x67,0x7b,0x84,0x15,0xa,0xb7,0x23,0x15,0x57,0x81,0xab,0xd6,0x90,0x4d,0x5a,0x87,0xf6,0x4e,0x9f,0x4f,0xc5,0xc3,0xd1,0x2b,0x40}, -{0xea,0x98,0x3a,0xe0,0x5c,0x45,0xfa,0x9c,0x3,0xc5,0xd2,0x99,0x66,0xb2,0x99,0x9a,0x66,0x2,0x96,0xb4,0xf2,0xbb,0x53,0x8a,0xb5,0x56,0x14,0x1a,0x88,0xdb,0xa2,0x31}, -{0x3,0xa3,0x5a,0x5c,0x9a,0x19,0xe,0xdb,0x40,0x3f,0xb2,0xa,0x87,0xc1,0x44,0x10,0x1c,0x5,0x19,0x80,0x84,0x9e,0x95,0x1d,0x6f,0x33,0xeb,0xad,0x5e,0xe7,0xcd,0xdc}, -{0x10,0xba,0x13,0x92,0x2,0xbf,0x6b,0x41,0xdc,0x78,0x65,0x15,0xf7,0xbb,0x27,0xd0,0xa,0x2c,0x81,0x39,0x37,0xaa,0x78,0x50,0x3f,0x1a,0xbf,0xd2,0x41,0x0,0x91,0xd3}, -{0x42,0x2d,0x5a,0xd,0xf6,0xcc,0x7e,0x90,0xdd,0x62,0x9f,0x9c,0x92,0xc0,0x97,0xce,0x18,0x5c,0xa7,0xb,0xc7,0x2b,0x44,0xac,0xd1,0xdf,0x65,0xd6,0x63,0xc6,0xfc,0x23}, -{0x97,0x6e,0x6c,0x3,0x9e,0xe0,0xb8,0x1a,0x21,0x5,0x45,0x7e,0x44,0x6c,0xec,0xa8,0xee,0xf1,0x3,0xbb,0x5d,0x8e,0x61,0xfa,0xfd,0x96,0x97,0xb2,0x94,0x83,0x81,0x97}, -{0x4a,0x8e,0x85,0x37,0xdb,0x3,0x30,0x2f,0x2a,0x67,0x8d,0x2d,0xfb,0x9f,0x6a,0x95,0x8a,0xfe,0x73,0x81,0xf8,0xb8,0x69,0x6c,0x8a,0xc7,0x72,0x46,0xc0,0x7f,0x42,0x14}, -{0xc5,0xf4,0x15,0x8f,0xbd,0xc7,0x5e,0xc4,0x75,0x44,0x6f,0xa7,0x8f,0x11,0xbb,0x80,0x52,0xde,0x75,0xb7,0xae,0xe4,0x88,0xbc,0x82,0xb8,0x0,0x1e,0x98,0xa6,0xa3,0xf4}, -{0x8e,0xf4,0x8f,0x33,0xa9,0xa3,0x63,0x15,0xaa,0x5f,0x56,0x24,0xd5,0xb7,0xf9,0x89,0xb6,0xf1,0xed,0x20,0x7c,0x5a,0xe0,0xfd,0x36,0xca,0xe9,0x5a,0x6,0x42,0x2c,0x36}, -{0xce,0x29,0x35,0x43,0x4e,0xfe,0x98,0x3d,0x53,0x3a,0xf9,0x74,0x73,0x9a,0x4b,0xa7,0xd0,0xf5,0x1f,0x59,0x6f,0x4e,0x81,0x86,0xe,0x9d,0xad,0x81,0xaf,0xd8,0x5a,0x9f}, -{0xa7,0x5,0x6,0x67,0xee,0x34,0x62,0x6a,0x8b,0xb,0x28,0xbe,0x6e,0xb9,0x17,0x27,0x47,0x74,0x7,0x26,0xc6,0x80,0x10,0x3f,0xe0,0xa0,0x7e,0x6f,0xc6,0x7e,0x48,0x7b}, -{0xd,0x55,0xa,0xa5,0x4a,0xf8,0xa4,0xc0,0x91,0xe3,0xe7,0x9f,0x97,0x8e,0xf1,0x9e,0x86,0x76,0x72,0x81,0x50,0x60,0x8d,0xd4,0x7e,0x9e,0x5a,0x41,0xf3,0xe5,0xb0,0x62}, -{0xfc,0x9f,0x1f,0xec,0x40,0x54,0x20,0x7a,0xe3,0xe4,0x1a,0x0,0xce,0xf4,0xc9,0x84,0x4f,0xd7,0x94,0xf5,0x9d,0xfa,0x95,0xd8,0x55,0x2e,0x7e,0x11,0x24,0xc3,0x54,0xa5}, -{0x5b,0xdf,0x72,0x28,0xbd,0xfe,0x6e,0x28,0x78,0xf5,0x7f,0xe2,0xf,0xa5,0xc4,0xb2,0x5,0x89,0x7c,0xef,0xee,0x49,0xd3,0x2e,0x44,0x7e,0x93,0x85,0xeb,0x28,0x59,0x7f}, -{0x70,0x5f,0x69,0x37,0xb3,0x24,0x31,0x4a,0x5e,0x86,0x28,0xf1,0x1d,0xd6,0xe4,0x65,0xc7,0x1b,0x77,0x4,0x51,0xb9,0x20,0xe7,0x74,0xfe,0x43,0xe8,0x23,0xd4,0x87,0x8a}, -{0x7d,0x29,0xe8,0xa3,0x92,0x76,0x94,0xf2,0xdd,0xcb,0x7a,0x9,0x9b,0x30,0xd9,0xc1,0x1d,0x1b,0x30,0xfb,0x5b,0xdc,0x1b,0xe0,0xda,0x24,0x49,0x4f,0xf2,0x9c,0x82,0xbf}, -{0xa4,0xe7,0xba,0x31,0xb4,0x70,0xbf,0xff,0xd,0x32,0x44,0x5,0xde,0xf8,0xbc,0x48,0x3b,0xae,0xfc,0x32,0x53,0xbb,0xd3,0x39,0x45,0x9f,0xc3,0xc1,0xe0,0x29,0x8b,0xa0}, -{0xe5,0xc9,0x5,0xfd,0xf7,0xae,0x9,0xf,0x94,0x70,0x34,0x12,0x42,0x90,0xf1,0x34,0xa2,0x71,0xb7,0x1,0xe3,0x44,0xed,0x95,0xe9,0x3b,0x8e,0x36,0x4f,0x2f,0x98,0x4a}, -{0x88,0x40,0x1d,0x63,0xa0,0x6c,0xf6,0x15,0x47,0xc1,0x44,0x4b,0x87,0x52,0xaf,0xff,0x7e,0xbb,0x4a,0xf1,0xe2,0xa,0xc6,0x30,0x46,0x70,0xb6,0xc5,0xcc,0x6e,0x8c,0xe6}, -{0xa4,0xd5,0xa4,0x56,0xbd,0x4f,0xca,0x0,0xda,0x9d,0x84,0x4b,0xc8,0x3e,0x18,0xae,0x73,0x57,0xce,0x45,0x30,0x64,0xd1,0xad,0xe8,0xa6,0xce,0x68,0x14,0x5c,0x25,0x67}, -{0xa3,0xda,0x8c,0xf2,0xcb,0xe,0xe1,0x16,0x33,0xe9,0x6,0x58,0x9a,0x94,0x99,0x9a,0x1f,0x60,0xb2,0x20,0xc2,0x6f,0x84,0x7b,0xd1,0xce,0xac,0x7f,0xa0,0xd1,0x85,0x18}, -{0x32,0x59,0x5b,0xa1,0x8d,0xdd,0x19,0xd3,0x50,0x9a,0x1c,0xc0,0xaa,0xa5,0xb4,0x46,0x9f,0x3d,0x63,0x67,0xe4,0x4,0x6b,0xba,0xf6,0xca,0x19,0xab,0xb,0x56,0xee,0x7e}, -{0x1f,0xb1,0x79,0xea,0xa9,0x28,0x21,0x74,0xe9,0xbd,0xf7,0x35,0x3b,0x36,0x51,0xee,0x1d,0x57,0xac,0x5a,0x75,0x50,0xd3,0x76,0x3a,0x46,0xc2,0xfe,0xa3,0x7d,0x70,0x1}, -{0xf7,0x35,0xc1,0xaf,0x98,0xa4,0xd8,0x42,0x78,0xed,0xec,0x20,0x9e,0x6b,0x67,0x79,0x41,0x83,0x63,0x15,0xea,0x3a,0xdb,0xa8,0xfa,0xc3,0x3b,0x4d,0x32,0x83,0x2c,0x83}, -{0xa7,0x40,0x3b,0x1f,0x1c,0x27,0x47,0xf3,0x59,0x40,0xf0,0x34,0xb7,0x2d,0x76,0x9a,0xe7,0x3e,0x4e,0x6c,0xd2,0x21,0x4f,0xfd,0xb8,0xfd,0x8d,0x39,0xdc,0x57,0x59,0xef}, -{0x8d,0x9b,0xc,0x49,0x2b,0x49,0xeb,0xda,0x5b,0xa2,0xd7,0x49,0x68,0xf3,0x70,0xd,0x7d,0x3b,0xae,0xd0,0x7a,0x8d,0x55,0x84,0xf5,0xa5,0xe9,0xf0,0xe4,0xf8,0x8e,0x65}, -{0xa0,0xb8,0xa2,0xf4,0x36,0x10,0x3b,0x53,0xc,0xa8,0x7,0x9e,0x75,0x3e,0xec,0x5a,0x91,0x68,0x94,0x92,0x56,0xe8,0x88,0x4f,0x5b,0xb0,0x5c,0x55,0xf8,0xba,0xbc,0x4c}, -{0xe3,0xbb,0x3b,0x99,0xf3,0x87,0x94,0x7b,0x75,0xda,0xf4,0xd6,0x72,0x6b,0x1c,0x5d,0x64,0xae,0xac,0x28,0xdc,0x34,0xb3,0x6d,0x6c,0x34,0xa5,0x50,0xb8,0x28,0xdb,0x71}, -{0xf8,0x61,0xe2,0xf2,0x10,0x8d,0x51,0x2a,0xe3,0xdb,0x64,0x33,0x59,0xdd,0x75,0xfc,0x1c,0xac,0xbc,0xf1,0x43,0xce,0x3f,0xa2,0x67,0xbb,0xd1,0x3c,0x2,0xe8,0x43,0xb0}, -{0x33,0xa,0x5b,0xca,0x88,0x29,0xa1,0x75,0x7f,0x34,0x19,0x4d,0xb4,0x16,0x53,0x5c,0x92,0x3b,0x94,0xc3,0xe,0x79,0x4d,0x1e,0x79,0x74,0x75,0xd7,0xb6,0xee,0xaf,0x3f}, -{0xea,0xa8,0xd4,0xf7,0xbe,0x1a,0x39,0x21,0x5c,0xf4,0x7e,0x9,0x4c,0x23,0x27,0x51,0x26,0xa3,0x24,0x53,0xba,0x32,0x3c,0xd2,0x44,0xa3,0x17,0x4a,0x6d,0xa6,0xd5,0xad}, -{0xb5,0x1d,0x3e,0xa6,0xaf,0xf2,0xc9,0x8,0x83,0x59,0x3d,0x98,0x91,0x6b,0x3c,0x56,0x4c,0xf8,0x7c,0xa1,0x72,0x86,0x60,0x4d,0x46,0xe2,0x3e,0xcc,0x8,0x6e,0xc7,0xf6}, -{0x2f,0x98,0x33,0xb3,0xb1,0xbc,0x76,0x5e,0x2b,0xd6,0x66,0xa5,0xef,0xc4,0xe6,0x2a,0x6,0xf4,0xb6,0xe8,0xbe,0xc1,0xd4,0x36,0x74,0xee,0x82,0x15,0xbc,0xef,0x21,0x63}, -{0xfd,0xc1,0x4e,0xd,0xf4,0x53,0xc9,0x69,0xa7,0x7d,0x5a,0xc4,0x6,0x58,0x58,0x26,0x7e,0xc1,0x14,0x16,0x6,0xe0,0xfa,0x16,0x7e,0x90,0xaf,0x3d,0x28,0x63,0x9d,0x3f}, -{0xd2,0xc9,0xf2,0xe3,0x0,0x9b,0xd2,0xc,0x5f,0xaa,0xce,0x30,0xb7,0xd4,0xc,0x30,0x74,0x2a,0x51,0x16,0xf2,0xe0,0x32,0x98,0xd,0xeb,0x30,0xd8,0xe3,0xce,0xf8,0x9a}, -{0x4b,0xc5,0x9e,0x7b,0xb5,0xf1,0x79,0x92,0xff,0x51,0xe6,0x6e,0x4,0x86,0x68,0xd3,0x9b,0x23,0x4d,0x57,0xe6,0x96,0x67,0x31,0xcc,0xe6,0xa6,0xf3,0x17,0xa,0x75,0x5}, -{0xb1,0x76,0x81,0xd9,0x13,0x32,0x6c,0xce,0x3c,0x17,0x52,0x84,0xf8,0x5,0xa2,0x62,0xf4,0x2b,0xcb,0xb3,0x78,0x47,0x15,0x47,0xff,0x46,0x54,0x82,0x23,0x93,0x6a,0x48}, -{0x38,0xdf,0x58,0x7,0x4e,0x5e,0x65,0x65,0xf2,0xfc,0x7c,0x89,0xfc,0x86,0x50,0x8e,0x31,0x70,0x2e,0x44,0xd0,0xb,0xca,0x86,0xf0,0x40,0x9,0xa2,0x30,0x78,0x47,0x4e}, -{0x65,0xa0,0xee,0x39,0xd1,0xf7,0x38,0x83,0xf7,0x5e,0xe9,0x37,0xe4,0x2c,0x3a,0xbd,0x21,0x97,0xb2,0x26,0x1,0x13,0xf8,0x6f,0xa3,0x44,0xed,0xd1,0xef,0x9f,0xde,0xe7}, -{0x8b,0xa0,0xdf,0x15,0x76,0x25,0x92,0xd9,0x3c,0x85,0xf7,0xf6,0x12,0xdc,0x42,0xbe,0xd8,0xa7,0xec,0x7c,0xab,0x27,0xb0,0x7e,0x53,0x8d,0x7d,0xda,0xaa,0x3e,0xa8,0xde}, -{0xaa,0x25,0xce,0x93,0xbd,0x2,0x69,0xd8,0x5a,0xf6,0x43,0xfd,0x1a,0x73,0x8,0xf9,0xc0,0x5f,0xef,0xda,0x17,0x4a,0x19,0xa5,0x97,0x4d,0x66,0x33,0x4c,0xfd,0x21,0x6a}, -{0x35,0xb4,0x98,0x31,0xdb,0x41,0x15,0x70,0xea,0x1e,0xf,0xbb,0xed,0xcd,0x54,0x9b,0x9a,0xd0,0x63,0xa1,0x51,0x97,0x40,0x72,0xf6,0x75,0x9d,0xbf,0x91,0x47,0x6f,0xe2}}; - - -static void E8(hashState *state); /*The bijective function E8, in bitslice form*/ -static void F8(hashState *state); /*The compression function F8 */ - -/*The API functions*/ -static HashReturn Init(hashState *state, int hashbitlen); -static HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen); -static HashReturn Final(hashState *state, BitSequence *hashval); -static HashReturn Hash(int hashbitlen, const BitSequence *data,DataLength databitlen, BitSequence *hashval); - -/*swapping bit 2i with bit 2i+1 of 64-bit x*/ -#define SWAP1(x) (x) = ((((x) & 0x5555555555555555ULL) << 1) | (((x) & 0xaaaaaaaaaaaaaaaaULL) >> 1)); -/*swapping bits 4i||4i+1 with bits 4i+2||4i+3 of 64-bit x*/ -#define SWAP2(x) (x) = ((((x) & 0x3333333333333333ULL) << 2) | (((x) & 0xccccccccccccccccULL) >> 2)); -/*swapping bits 8i||8i+1||8i+2||8i+3 with bits 8i+4||8i+5||8i+6||8i+7 of 64-bit x*/ -#define SWAP4(x) (x) = ((((x) & 0x0f0f0f0f0f0f0f0fULL) << 4) | (((x) & 0xf0f0f0f0f0f0f0f0ULL) >> 4)); -/*swapping bits 16i||16i+1||......||16i+7 with bits 16i+8||16i+9||......||16i+15 of 64-bit x*/ -#define SWAP8(x) (x) = ((((x) & 0x00ff00ff00ff00ffULL) << 8) | (((x) & 0xff00ff00ff00ff00ULL) >> 8)); -/*swapping bits 32i||32i+1||......||32i+15 with bits 32i+16||32i+17||......||32i+31 of 64-bit x*/ -#define SWAP16(x) (x) = ((((x) & 0x0000ffff0000ffffULL) << 16) | (((x) & 0xffff0000ffff0000ULL) >> 16)); -/*swapping bits 64i||64i+1||......||64i+31 with bits 64i+32||64i+33||......||64i+63 of 64-bit x*/ -#define SWAP32(x) (x) = (((x) << 32) | ((x) >> 32)); - -/*The MDS transform*/ -#define L(m0,m1,m2,m3,m4,m5,m6,m7) \ - (m4) ^= (m1); \ - (m5) ^= (m2); \ - (m6) ^= (m0) ^ (m3); \ - (m7) ^= (m0); \ - (m0) ^= (m5); \ - (m1) ^= (m6); \ - (m2) ^= (m4) ^ (m7); \ - (m3) ^= (m4); - -/*Two Sboxes are computed in parallel, each Sbox implements S0 and S1, selected by a constant bit*/ -/*The reason to compute two Sboxes in parallel is to try to fully utilize the parallel processing power*/ -#define SS(m0,m1,m2,m3,m4,m5,m6,m7,cc0,cc1) \ - m3 = ~(m3); \ - m7 = ~(m7); \ - m0 ^= ((~(m2)) & (cc0)); \ - m4 ^= ((~(m6)) & (cc1)); \ - temp0 = (cc0) ^ ((m0) & (m1));\ - temp1 = (cc1) ^ ((m4) & (m5));\ - m0 ^= ((m2) & (m3)); \ - m4 ^= ((m6) & (m7)); \ - m3 ^= ((~(m1)) & (m2)); \ - m7 ^= ((~(m5)) & (m6)); \ - m1 ^= ((m0) & (m2)); \ - m5 ^= ((m4) & (m6)); \ - m2 ^= ((m0) & (~(m3))); \ - m6 ^= ((m4) & (~(m7))); \ - m0 ^= ((m1) | (m3)); \ - m4 ^= ((m5) | (m7)); \ - m3 ^= ((m1) & (m2)); \ - m7 ^= ((m5) & (m6)); \ - m1 ^= (temp0 & (m0)); \ - m5 ^= (temp1 & (m4)); \ - m2 ^= temp0; \ - m6 ^= temp1; - -/*The bijective function E8, in bitslice form*/ -static void E8(hashState *state) -{ - uint64 i,roundnumber,temp0,temp1; - - for (roundnumber = 0; roundnumber < 42; roundnumber = roundnumber+7) { - /*round 7*roundnumber+0: Sbox, MDS and Swapping layers*/ - for (i = 0; i < 2; i++) { - SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+0])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+0])[i+2] ); - L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); - SWAP1(state->x[1][i]); SWAP1(state->x[3][i]); SWAP1(state->x[5][i]); SWAP1(state->x[7][i]); - } - - /*round 7*roundnumber+1: Sbox, MDS and Swapping layers*/ - for (i = 0; i < 2; i++) { - SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+1])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+1])[i+2] ); - L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); - SWAP2(state->x[1][i]); SWAP2(state->x[3][i]); SWAP2(state->x[5][i]); SWAP2(state->x[7][i]); - } - - /*round 7*roundnumber+2: Sbox, MDS and Swapping layers*/ - for (i = 0; i < 2; i++) { - SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+2])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+2])[i+2] ); - L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); - SWAP4(state->x[1][i]); SWAP4(state->x[3][i]); SWAP4(state->x[5][i]); SWAP4(state->x[7][i]); - } - - /*round 7*roundnumber+3: Sbox, MDS and Swapping layers*/ - for (i = 0; i < 2; i++) { - SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+3])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+3])[i+2] ); - L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); - SWAP8(state->x[1][i]); SWAP8(state->x[3][i]); SWAP8(state->x[5][i]); SWAP8(state->x[7][i]); - } - - /*round 7*roundnumber+4: Sbox, MDS and Swapping layers*/ - for (i = 0; i < 2; i++) { - SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+4])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+4])[i+2] ); - L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); - SWAP16(state->x[1][i]); SWAP16(state->x[3][i]); SWAP16(state->x[5][i]); SWAP16(state->x[7][i]); - } - - /*round 7*roundnumber+5: Sbox, MDS and Swapping layers*/ - for (i = 0; i < 2; i++) { - SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+5])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+5])[i+2] ); - L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); - SWAP32(state->x[1][i]); SWAP32(state->x[3][i]); SWAP32(state->x[5][i]); SWAP32(state->x[7][i]); - } - - /*round 7*roundnumber+6: Sbox and MDS layers*/ - for (i = 0; i < 2; i++) { - SS(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i],((uint64*)E8_bitslice_roundconstant[roundnumber+6])[i],((uint64*)E8_bitslice_roundconstant[roundnumber+6])[i+2] ); - L(state->x[0][i],state->x[2][i],state->x[4][i],state->x[6][i],state->x[1][i],state->x[3][i],state->x[5][i],state->x[7][i]); - } - /*round 7*roundnumber+6: swapping layer*/ - for (i = 1; i < 8; i = i+2) { - temp0 = state->x[i][0]; state->x[i][0] = state->x[i][1]; state->x[i][1] = temp0; - } - } - -} - -/*The compression function F8 */ -static void F8(hashState *state) -{ - uint64 i; - - /*xor the 512-bit message with the fist half of the 1024-bit hash state*/ - for (i = 0; i < 8; i++) state->x[i >> 1][i & 1] ^= ((uint64*)state->buffer)[i]; - - /*the bijective function E8 */ - E8(state); - - /*xor the 512-bit message with the second half of the 1024-bit hash state*/ - for (i = 0; i < 8; i++) state->x[(8+i) >> 1][(8+i) & 1] ^= ((uint64*)state->buffer)[i]; -} - -/*before hashing a message, initialize the hash state as H0 */ -static HashReturn Init(hashState *state, int hashbitlen) -{ - state->databitlen = 0; - state->datasize_in_buffer = 0; - - /*initialize the initial hash value of JH*/ - state->hashbitlen = hashbitlen; - - /*load the intital hash value into state*/ - switch (hashbitlen) - { - case 224: memcpy(state->x,JH224_H0,128); break; - case 256: memcpy(state->x,JH256_H0,128); break; - case 384: memcpy(state->x,JH384_H0,128); break; - case 512: memcpy(state->x,JH512_H0,128); break; - } - - return(SUCCESS); -} - - -/*hash each 512-bit message block, except the last partial block*/ -static HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen) -{ - DataLength index; /*the starting address of the data to be compressed*/ - - state->databitlen += databitlen; - index = 0; - - /*if there is remaining data in the buffer, fill it to a full message block first*/ - /*we assume that the size of the data in the buffer is the multiple of 8 bits if it is not at the end of a message*/ - - /*There is data in the buffer, but the incoming data is insufficient for a full block*/ - if ( (state->datasize_in_buffer > 0 ) && (( state->datasize_in_buffer + databitlen) < 512) ) { - if ( (databitlen & 7) == 0 ) { - memcpy(state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3)) ; - } - else memcpy(state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3)+1) ; - state->datasize_in_buffer += databitlen; - databitlen = 0; - } - - /*There is data in the buffer, and the incoming data is sufficient for a full block*/ - if ( (state->datasize_in_buffer > 0 ) && (( state->datasize_in_buffer + databitlen) >= 512) ) { - memcpy( state->buffer + (state->datasize_in_buffer >> 3), data, 64-(state->datasize_in_buffer >> 3) ) ; - index = 64-(state->datasize_in_buffer >> 3); - databitlen = databitlen - (512 - state->datasize_in_buffer); - F8(state); - state->datasize_in_buffer = 0; - } - - /*hash the remaining full message blocks*/ - for ( ; databitlen >= 512; index = index+64, databitlen = databitlen - 512) { - memcpy(state->buffer, data+index, 64); - F8(state); - } - - /*store the partial block into buffer, assume that -- if part of the last byte is not part of the message, then that part consists of 0 bits*/ - if ( databitlen > 0) { - if ((databitlen & 7) == 0) - memcpy(state->buffer, data+index, (databitlen & 0x1ff) >> 3); - else - memcpy(state->buffer, data+index, ((databitlen & 0x1ff) >> 3)+1); - state->datasize_in_buffer = databitlen; - } - - return(SUCCESS); -} - -/*pad the message, process the padded block(s), truncate the hash value H to obtain the message digest*/ -static HashReturn Final(hashState *state, BitSequence *hashval) -{ - unsigned int i; - - if ( (state->databitlen & 0x1ff) == 0 ) { - /*pad the message when databitlen is multiple of 512 bits, then process the padded block*/ - memset(state->buffer, 0, 64); - state->buffer[0] = 0x80; - state->buffer[63] = state->databitlen & 0xff; - state->buffer[62] = (state->databitlen >> 8) & 0xff; - state->buffer[61] = (state->databitlen >> 16) & 0xff; - state->buffer[60] = (state->databitlen >> 24) & 0xff; - state->buffer[59] = (state->databitlen >> 32) & 0xff; - state->buffer[58] = (state->databitlen >> 40) & 0xff; - state->buffer[57] = (state->databitlen >> 48) & 0xff; - state->buffer[56] = (state->databitlen >> 56) & 0xff; - F8(state); - } - else { - /*set the rest of the bytes in the buffer to 0*/ - if ( (state->datasize_in_buffer & 7) == 0) - for (i = (state->databitlen & 0x1ff) >> 3; i < 64; i++) state->buffer[i] = 0; - else - for (i = ((state->databitlen & 0x1ff) >> 3)+1; i < 64; i++) state->buffer[i] = 0; - - /*pad and process the partial block when databitlen is not multiple of 512 bits, then hash the padded blocks*/ - state->buffer[((state->databitlen & 0x1ff) >> 3)] |= 1 << (7- (state->databitlen & 7)); - - F8(state); - memset(state->buffer, 0, 64); - state->buffer[63] = state->databitlen & 0xff; - state->buffer[62] = (state->databitlen >> 8) & 0xff; - state->buffer[61] = (state->databitlen >> 16) & 0xff; - state->buffer[60] = (state->databitlen >> 24) & 0xff; - state->buffer[59] = (state->databitlen >> 32) & 0xff; - state->buffer[58] = (state->databitlen >> 40) & 0xff; - state->buffer[57] = (state->databitlen >> 48) & 0xff; - state->buffer[56] = (state->databitlen >> 56) & 0xff; - F8(state); - } - - /*truncating the final hash value to generate the message digest*/ - switch(state->hashbitlen) { - case 224: memcpy(hashval,(unsigned char*)state->x+64+36,28); break; - case 256: memcpy(hashval,(unsigned char*)state->x+64+32,32); break; - case 384: memcpy(hashval,(unsigned char*)state->x+64+16,48); break; - case 512: memcpy(hashval,(unsigned char*)state->x+64,64); break; - } - - return(SUCCESS); -} - -/* hash a message, - three inputs: message digest size in bits (hashbitlen); message (data); message length in bits (databitlen) - one output: message digest (hashval) -*/ -static HashReturn Hash(int hashbitlen, const BitSequence *data,DataLength databitlen, BitSequence *hashval) -{ - hashState state; - - if ( hashbitlen == 224 || hashbitlen == 256 || hashbitlen == 384 || hashbitlen == 512 ) { - Init(&state, hashbitlen); - Update(&state, data, databitlen); - Final(&state, hashval); - return SUCCESS; - } - else - return(BAD_HASHLEN); -} - -void jh(unsigned bit_len, const uint8_t input[], size_t input_bit_length, uint8_t output[]) -{ - HashReturn ret = Hash(bit_len, input, input_bit_length, output); - assert(ret == SUCCESS); -} diff --git a/src_native/jh_ansi_opt64.o b/src_native/jh_ansi_opt64.o deleted file mode 100644 index 8e703ce0..00000000 Binary files a/src_native/jh_ansi_opt64.o and /dev/null differ diff --git a/src_native/keccak.c b/src_native/keccak.c deleted file mode 100644 index de8e2a5b..00000000 --- a/src_native/keccak.c +++ /dev/null @@ -1,134 +0,0 @@ -// keccak.c -// 19-Nov-11 Markku-Juhani O. Saarinen -// A baseline Keccak (3rd round) implementation. - -#include -#include -#include -#include "hash-ops.h" -#include "keccak.h" - -static void local_abort(const char *msg) -{ - fprintf(stderr, "%s\n", msg); -#ifdef NDEBUG - _exit(1); -#else - abort(); -#endif -} - -const uint64_t keccakf_rndc[24] = -{ - 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, - 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, - 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, - 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, - 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, - 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, - 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, - 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 -}; - -const int keccakf_rotc[24] = -{ - 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, - 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 -}; - -const int keccakf_piln[24] = -{ - 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, - 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 -}; - -// update the state with given number of rounds - -void keccakf(uint64_t st[25], int rounds) -{ - int i, j, round; - uint64_t t, bc[5]; - - for (round = 0; round < rounds; round++) { - - // Theta - for (i = 0; i < 5; i++) - bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; - - for (i = 0; i < 5; i++) { - t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); - for (j = 0; j < 25; j += 5) - st[j + i] ^= t; - } - - // Rho Pi - t = st[1]; - for (i = 0; i < 24; i++) { - j = keccakf_piln[i]; - bc[0] = st[j]; - st[j] = ROTL64(t, keccakf_rotc[i]); - t = bc[0]; - } - - // Chi - for (j = 0; j < 25; j += 5) { - for (i = 0; i < 5; i++) - bc[i] = st[j + i]; - for (i = 0; i < 5; i++) - st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; - } - - // Iota - st[0] ^= keccakf_rndc[round]; - } -} - -// compute a keccak hash (md) of given byte length from "in" -typedef uint64_t state_t[25]; - -void keccak(const uint8_t *in, size_t inlen, uint8_t *md, int mdlen) -{ - state_t st; - uint8_t temp[144]; - size_t i, rsiz, rsizw; - - static_assert(HASH_DATA_AREA <= sizeof(temp), "Bad keccak preconditions"); - if (mdlen <= 0 || (mdlen > 100 && sizeof(st) != (size_t)mdlen)) - { - local_abort("Bad keccak use"); - } - - rsiz = sizeof(state_t) == mdlen ? HASH_DATA_AREA : 200 - 2 * mdlen; - rsizw = rsiz / 8; - - memset(st, 0, sizeof(st)); - - for ( ; inlen >= rsiz; inlen -= rsiz, in += rsiz) { - for (i = 0; i < rsizw; i++) - st[i] ^= ((uint64_t *) in)[i]; - keccakf(st, KECCAK_ROUNDS); - } - - // last block and padding - if (inlen + 1 >= sizeof(temp) || inlen > rsiz || rsiz - inlen + inlen + 1 >= sizeof(temp) || rsiz == 0 || rsiz - 1 >= sizeof(temp) || rsizw * 8 > sizeof(temp)) - { - local_abort("Bad keccak use"); - } - - memcpy(temp, in, inlen); - temp[inlen++] = 1; - memset(temp + inlen, 0, rsiz - inlen); - temp[rsiz - 1] |= 0x80; - - for (i = 0; i < rsizw; i++) - st[i] ^= ((uint64_t *) temp)[i]; - - keccakf(st, KECCAK_ROUNDS); - - memcpy(md, st, mdlen); -} - -void keccak1600(const uint8_t *in, size_t inlen, uint8_t *md) -{ - keccak(in, inlen, md, sizeof(state_t)); -} diff --git a/src_native/keccak.h b/src_native/keccak.h deleted file mode 100644 index fb9d8bd0..00000000 --- a/src_native/keccak.h +++ /dev/null @@ -1,26 +0,0 @@ -// keccak.h -// 19-Nov-11 Markku-Juhani O. Saarinen - -#ifndef KECCAK_H -#define KECCAK_H - -#include -#include - -#ifndef KECCAK_ROUNDS -#define KECCAK_ROUNDS 24 -#endif - -#ifndef ROTL64 -#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) -#endif - -// compute a keccak hash (md) of given byte length from "in" -void keccak(const uint8_t *in, size_t inlen, uint8_t *md, int mdlen); - -// update the state -void keccakf(uint64_t st[25], int norounds); - -void keccak1600(const uint8_t *in, size_t inlen, uint8_t *md); - -#endif diff --git a/src_native/keccak.o b/src_native/keccak.o deleted file mode 100644 index b2be880d..00000000 Binary files a/src_native/keccak.o and /dev/null differ diff --git a/src_native/license.txt b/src_native/license.txt deleted file mode 100644 index b0829699..00000000 --- a/src_native/license.txt +++ /dev/null @@ -1,39 +0,0 @@ -code is based on / largely copied from - -https://github.com/noahdesu/xmonarch - -which is based on the monero code. - - - -Copyright (c) 2014-2018, The Monero Project - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation -and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its contributors -may be used to endorse or promote products derived from this software without -specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Parts of the project are originally copyright (c) 2012-2013 The Cryptonote -developers diff --git a/src_native/main.c b/src_native/main.c deleted file mode 100644 index af9e4a03..00000000 --- a/src_native/main.c +++ /dev/null @@ -1,76 +0,0 @@ -#include -#include -#include -#include -#include -#include - -//#include "cryptonight.h" - -#include "crypto.h" -#include "crypto-ops.h" -#include "hash-ops.h" -//#include "hash.h" -#include "common/varint.h" - -extern "C" { - -bool generate_key_derivation(const unsigned char *key1, const unsigned char *key2, unsigned char *derivation) { - ge_p3 point; - ge_p2 point2; - ge_p1p1 point3; -// assert(sc_check(&key2) == 0); - if (ge_frombytes_vartime(&point, key1) != 0) { - return false; - } - - ge_scalarmult(&point2, key2, &point); - ge_mul8(&point3, &point2); - ge_p1p1_to_p2(&point2, &point3); - ge_tobytes(derivation, &point2); - return true; -} - -void hash_to_scalar(const void *data, size_t length, crypto::ec_scalar &res) { - cn_fast_hash(data, length, reinterpret_cast(&res)); - sc_reduce32(reinterpret_cast(&res)); -} - -void derivation_to_scalar(const crypto::key_derivation &derivation, size_t output_index, crypto::ec_scalar &res) { - struct { - crypto::key_derivation derivation; - char output_index[(sizeof(size_t) * 8 + 6) / 7]; - } buf; - char *end = buf.output_index; - buf.derivation = derivation; - tools::write_varint(end, output_index); - assert(end <= buf.output_index + sizeof buf.output_index); - hash_to_scalar(&buf, end - reinterpret_cast(&buf), res); -} - -bool derive_public_key(const crypto::key_derivation &derivation, size_t output_index, - const crypto::public_key &base, crypto::public_key &derived_key) { - crypto::ec_scalar scalar; - ge_p3 point1; - ge_p3 point2; - ge_cached point3; - ge_p1p1 point4; - ge_p2 point5; - if (ge_frombytes_vartime(&point1, reinterpret_cast(&base)) != 0) { - return false; - } - derivation_to_scalar(derivation, output_index, scalar); - ge_scalarmult_base(&point2, reinterpret_cast(&scalar)); - ge_p3_to_cached(&point3, &point2); - ge_add(&point4, &point1, &point3); - ge_p1p1_to_p2(&point5, &point4); - ge_tobytes(reinterpret_cast(&derived_key), &point5); - - return true; -} - -int main(void) { - return 0; -} - -} \ No newline at end of file diff --git a/src_native/main.o b/src_native/main.o deleted file mode 100644 index f07c9f9c..00000000 Binary files a/src_native/main.o and /dev/null differ diff --git a/tsconfig.json b/tsconfig.json index 8e023bc5..aaa35183 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,9 +3,9 @@ "module": "AMD", "target": "es5", "lib": ["ES5","DOM", "es2015"], - "sourceMap": true, + "sourceMap": false, "moduleResolution": "node", "strict":true, "experimentalDecorators": true } -} \ No newline at end of file +} diff --git a/tsconfig.prod.json b/tsconfig.prod.json deleted file mode 100644 index d301e73b..00000000 --- a/tsconfig.prod.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "module": "AMD", - "target": "es5", - "lib": ["ES5","DOM", "es2015"], - "sourceMap": false, - "moduleResolution": "node", - "strict":true, - "experimentalDecorators": true - } -} \ No newline at end of file