1
0
Fork 0
forked from lthn/blockchain

Merge branch 'develop' into pos_impr

This commit is contained in:
cryptozoidberg 2019-08-14 10:23:56 +02:00
commit 3cf4b87a07
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
108 changed files with 3743 additions and 809 deletions

View file

@ -289,6 +289,40 @@ namespace file_io_utils
}
}
template<class t_string>
bool load_file_to_string(const t_string& path_to_file, std::string& target_str)
{
try
{
std::ifstream fstream;
//fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::in | std::ios::ate);
if (!fstream.good())
return false;
std::ifstream::pos_type file_size = fstream.tellg();
if (file_size > 1000000000)
return false;//don't get crazy
size_t file_size_t = static_cast<size_t>(file_size);
target_str.resize(file_size_t);
fstream.seekg(0, std::ios::beg);
fstream.read((char*)target_str.data(), target_str.size());
if (!fstream.good())
return false;
fstream.close();
return true;
}
catch (...)
{
return false;
}
}
/*
inline
bool load_form_handle(HANDLE hfile, std::string& str)
@ -338,38 +372,7 @@ namespace file_io_utils
}
inline
bool load_file_to_string(const std::string& path_to_file, std::string& target_str)
{
try
{
std::ifstream fstream;
//fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::in | std::ios::ate);
if (!fstream.good())
return false;
std::ifstream::pos_type file_size = fstream.tellg();
if(file_size > 1000000000)
return false;//don't go crazy
size_t file_size_t = static_cast<size_t>(file_size);
target_str.resize(file_size_t);
fstream.seekg (0, std::ios::beg);
fstream.read((char*)target_str.data(), target_str.size());
if (!fstream.good())
return false;
fstream.close();
return true;
}
catch(...)
{
return false;
}
}
#ifdef WIN32
typedef HANDLE native_filesystem_handle;

View file

@ -42,9 +42,8 @@ namespace zlib_helper
int ret = deflateInit(&zstream, Z_DEFAULT_COMPRESSION);
if(target.size())
{
result_packed_buff.resize(target.size()*2, 'X');
size_t estimated_output_size_max = deflateBound(&zstream, target.size());
result_packed_buff.resize(estimated_output_size_max, 'X');
zstream.next_in = (Bytef*)target.data();
zstream.avail_in = (uInt)target.size();
@ -52,12 +51,10 @@ namespace zlib_helper
zstream.avail_out = (uInt)result_packed_buff.size();
ret = deflate(&zstream, Z_FINISH);
CHECK_AND_ASSERT_MES(ret>=0, false, "Failed to deflate. err = " << ret);
// as we allocated enough room for a signel pass avail_out should not be zero
CHECK_AND_ASSERT_MES(ret == Z_STREAM_END && zstream.avail_out != 0, false, "Failed to deflate. err = " << ret);
if(result_packed_buff.size() != zstream.avail_out)
result_packed_buff.resize(result_packed_buff.size()-zstream.avail_out);
result_packed_buff.resize(result_packed_buff.size() - zstream.avail_out);
result_packed_buff.erase(0, 2);
}

View file

@ -1158,6 +1158,32 @@ QString MainWindow::store_to_file(const QString& path, const QString& buff)
CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR);
}
QString MainWindow::load_from_file(const QString& path)
{
TRY_ENTRY();
try {
std::string buff;
bool r = epee::file_io_utils::load_file_to_string(path.toStdWString(), buff);
if (r)
return QString::fromStdString(buff);
else
return QString();
}
catch (const std::exception& ex)
{
LOG_ERROR("FILED TO LOAD FROM FILE: " << path.toStdString() << " ERROR:" << ex.what());
return QString(API_RETURN_CODE_ACCESS_DENIED) + ": " + ex.what();
}
catch (...)
{
return API_RETURN_CODE_ACCESS_DENIED;
}
CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR);
}
QString MainWindow::get_app_data()
{
TRY_ENTRY();

View file

@ -132,6 +132,7 @@ public:
QString restore_wallet(const QString& param);
QString is_pos_allowed();
QString store_to_file(const QString& path, const QString& buff);
QString load_from_file(const QString& path);
QString is_file_exist(const QString& path);
QString get_mining_estimate(const QString& obj);
QString backup_wallet_keys(const QString& obj);

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -38,6 +38,7 @@
"MESSAGES": "New offers/Messages",
"SYNCING": "Syncing wallet"
},
"CONTACTS": "Contacts",
"SETTINGS": "Settings",
"LOG_OUT": "Log out",
"SYNCHRONIZATION": {
@ -192,18 +193,17 @@
},
"ASSIGN_ALIAS": {
"NAME": {
"LABEL": "Unique name",
"LABEL": "Alias",
"PLACEHOLDER": "@ Enter alias",
"TOOLTIP": "An alias is a shortened form or your account. An alias can only include Latin letters, numbers and characters “.” and “-”. It must start with “@”."
},
"COMMENT": {
"LABEL": "Comment",
"PLACEHOLDER": "Enter comment",
"PLACEHOLDER": "",
"TOOLTIP": "The comment will be visible to anyone who wants to make a payment to your alias. You can provide details about your business, contacts, or include any text. Comments can be edited later."
},
"COST": "Cost to create alias {{value}} {{currency}}",
"COST": "Alias fee {{value}} {{currency}}",
"BUTTON_ASSIGN": "Assign",
"BUTTON_CANCEL": "Cancel",
"FORM_ERRORS": {
"NAME_REQUIRED": "Name is required",
"NAME_WRONG": "Alias has wrong name",
@ -217,40 +217,39 @@
},
"EDIT_ALIAS": {
"NAME": {
"LABEL": "Unique name",
"LABEL": "Alias",
"PLACEHOLDER": "@ Enter alias"
},
"COMMENT": {
"LABEL": "Comment",
"PLACEHOLDER": "Enter comment"
"PLACEHOLDER": ""
},
"FORM_ERRORS": {
"NO_MONEY": "You do not have enough funds to change the comment to this alias",
"MAX_LENGTH": "Maximum comment length reached"
},
"COST": "Cost to edit alias {{value}} {{currency}}",
"BUTTON_EDIT": "Edit",
"BUTTON_CANCEL": "Cancel"
"COST": "Fee {{value}} {{currency}}",
"BUTTON_EDIT": "Edit"
},
"TRANSFER_ALIAS": {
"NAME": {
"LABEL": "Unique name",
"LABEL": "Alias",
"PLACEHOLDER": "@ Enter alias"
},
"COMMENT": {
"LABEL": "Comment",
"PLACEHOLDER": "Enter comment"
"PLACEHOLDER": ""
},
"ADDRESS": {
"LABEL": "The account to which the alias will be transferred",
"PLACEHOLDER": "Enter wallet address"
"LABEL": "Transfer to",
"PLACEHOLDER": ""
},
"FORM_ERRORS": {
"WRONG_ADDRESS": "No wallet with this account exists",
"ALIAS_EXISTS": "This account already has an alias",
"NO_MONEY": "You do not have enough funds to transfer this alias"
},
"COST": "Cost to transfer alias {{value}} {{currency}}",
"COST": "Transfer fee {{value}} {{currency}}",
"BUTTON_TRANSFER": "Transfer",
"BUTTON_CANCEL": "Cancel",
"REQUEST_SEND_REG": "The alias will be transferred within 10 minutes"
@ -453,6 +452,17 @@
"INFO": "Information",
"OK": "OK"
},
"CONFIRM": {
"BUTTON_CONFIRM": "Send",
"BUTTON_CANCEL": "Cancel",
"TITLE": "Confirm transaction",
"MESSAGE": {
"SEND": "Send",
"FROM": "From",
"TO": "To",
"COMMENT": "Comment"
}
},
"STAKING": {
"TITLE": "Staking",
"TITLE_PENDING": "Pending",
@ -478,6 +488,55 @@
"OFF": "OFF"
}
},
"CONTACTS": {
"TITLE": "Contact list",
"IMPORT_EXPORT": "Import or export contacts",
"IMPORT": "Import",
"EXPORT": "Export",
"ADD": "Add/edit contact",
"SEND": "Send",
"SEND_FROM": "Send from",
"SEND_TO": "To",
"OPEN_ADD_WALLET": "Open/Add wallet",
"COPY": "- Copy"
, "TABLE": {
"NAME": "Name",
"ALIAS": "Alias",
"ADDRESS": "Address",
"NOTES": "Notes",
"EMPTY": "Contact list is empty"
},
"FORM": {
"NAME": "Name",
"ADDRESS": "Address",
"NOTES": "Notes"
},
"FORM_ERRORS": {
"NAME_REQUIRED": "Name is required",
"NAME_DUBLICATED": "Name is dublicated",
"ADDRESS_REQUIRED": "Address is required",
"ADDRESS_NOT_VALID": "Address not valid",
"SET_MASTER_PASSWORD": "Set master password",
"ADDRESS_DUBLICATED": "Address is dublicated",
"MAX_LENGTH": "Maximum notes length reached",
"NAME_WRONG": "Contact has wrong name",
"NAME_LENGTH": "The name must be 4-25 characters long"
},
"BUTTON": {
"SEND": "Send",
"EDIT": "Edit",
"DELETE": "Delete",
"ADD": "Add contact",
"ADD_EDIT": "Add/Save",
"GO_TO_WALLET": "Go to wallet",
"IMPORT_EXPORT": "Import/export"
},
"SUCCESS_SENT": "Contact added",
"SUCCESS_SAVE": "Contact is edited",
"SUCCESS_IMPORT": "Contacts is imported",
"ERROR_IMPORT": "Error is occured while reading file!",
"ERROR_TYPE_FILE": "Please import valid .csv file."
},
"ERRORS": {
"NO_MONEY": "Not enough money",
"NOT_ENOUGH_MONEY": "Insufficient funds in account",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -5,6 +5,7 @@
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<title>icons_5</title>
<g id="f31d9964-f67b-451c-9eb6-78b833647305">
<path class="st0" d="M299.9,197.6c9.3-16.7,14.2-35.5,14.1-54.6c0-70-43.4-105-97-105s-97,35-97,105c-0.1,19.1,4.8,38,14.2,54.6
C89.2,218.8,68.5,274.1,50,346l334-0.1C365.5,274,344.8,218.8,299.9,197.6z M178.1,94c11.6-11.6,27.6-14,38.9-14s27.3,2.4,38.9,14
c13.3,13.2,16.1,34,16.1,49c0,34.7-24.7,63-55,63s-55-28.3-55-63C162,115.7,170.7,101.3,178.1,94z M128.8,256.5
c10.1-14.3,21.1-22.1,36.1-25c31.4,22,73.1,22,104.5-0.1c14.9,2.9,25.9,10.8,35.9,25c8.9,12.6,16.3,29.3,22.7,47.5L106.1,304
C112.5,285.8,119.9,269.1,128.8,256.5z"/>
<path class="st0" d="M32.5,261H0v42h18.2C23,287,27.6,273.3,32.5,261z"/>
<path class="st0" d="M83,182c-0.9-3.6-1.7-7.3-2.4-11H0v42h56.8C64.2,201.6,73,191.2,83,182z"/>
<path class="st0" d="M88.8,81H0v42h79C80.4,108.6,83.7,94.5,88.8,81z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<path class="st0" d="M371,76H269V14H115v62H13v42h35v266h288V118h35V76z M157,56h70v20h-70V56z M294,342H90V118h204V342z"/>
<rect x="136" y="166" class="st0" width="42" height="128"/>
<rect x="206" y="166" class="st0" width="42" height="128"/>
</svg>

After

Width:  |  Height:  |  Size: 651 B

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<path id="details_1_" class="st0" d="M384,112.9L271.1,0L25,246.1v83.8L0.3,354l29.3,30l25.6-25h82.6L384,112.9z M324.6,112.9
l-36.4,36.4l-53.5-53.5l36.4-36.4L324.6,112.9z M70.3,317l-3.3-3.5v-50l138-138l53.5,53.5l-138,138H70.3z"/>
</svg>

After

Width:  |  Height:  |  Size: 637 B

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<polygon class="st0" points="296.5,366 384,288 296.5,210.5 296.5,267 0,267 0,309 296.5,309 "/>
<polygon class="st0" points="87.5,18 0,96 87.5,173.5 87.5,117 384,117 384,75 87.5,75 "/>
</svg>

After

Width:  |  Height:  |  Size: 592 B

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 32 32" style="enable-background:new 0 0 32 32;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<path class="st0" d="M22,15h-3.4H9.9v-5c0-3.3,2.7-6,6-6H16c3,0,5.4,2.2,5.9,5h4c-0.5-5-4.8-9-9.9-9h-0.1c-5.5,0-10,4.5-10,10v5H3
v17h12.9H16h13V15h-3H22z M18,27h-4v-7h4V27z"/>
</svg>

After

Width:  |  Height:  |  Size: 581 B

View file

@ -997,3 +997,29 @@ app-open-wallet-modal {
}
}
}
app-send-modal {
.modal {
@include themify($themes) {
background: themed(modalBackground);
color: themed(mainTextColor);
}
.title {
@include themify($themes) {
border-bottom: 0.2rem solid themed(transparentButtonBorderColor);
}
}
.action-button {
@include themify($themes) {
background-color: themed(blueTextColor);
color: themed(alternativeTextColor);
}
}
}
}

View file

@ -0,0 +1,88 @@
app-contacts, app-add-contacts,
app-contact-send, app-export-import {
flex: 1 1 auto;
padding: 3rem;
min-width: 85rem;
.content {
position: relative;
padding: 3rem;
min-height: 100%;
@include themify($themes) {
background-color: themed(contentBackgroundColor);
color: themed(mainTextColor);
}
.head {
position: absolute;
top: 0;
left: 0;
}
}
}
app-contacts {
table {
.alias {
@include themify($themes) {
color: themed(blueTextColor);
}
}
button {
.icon {
@include themify($themes) {
background-color: themed(blueTextColor);
}
}
span {
@include themify($themes) {
color: themed(mainTextColor)
}
}
}
}
.footer {
@include themify($themes) {
color: themed(blueTextColor);
}
.import-btn {
@include themify($themes) {
color: themed(blueTextColor);
}
.icon {
@include themify($themes) {
background-color: themed(blueTextColor);
}
}
}
}
}
app-contact-send {
.wallets-selection {
button {
@include themify($themes) {
color: themed(blueTextColor);
}
}
}
}

View file

@ -199,6 +199,13 @@ app-history {
}
}
.unlock-transaction {
@include themify($themes) {
background-color: themed(blueTextColor);
}
}
.status.send {
.status-transaction {

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<title>icons_5</title>
<g id="f31d9964-f67b-451c-9eb6-78b833647305">
<path class="st0" d="M299.9,197.6c9.3-16.7,14.2-35.5,14.1-54.6c0-70-43.4-105-97-105s-97,35-97,105c-0.1,19.1,4.8,38,14.2,54.6
C89.2,218.8,68.5,274.1,50,346l334-0.1C365.5,274,344.8,218.8,299.9,197.6z M178.1,94c11.6-11.6,27.6-14,38.9-14s27.3,2.4,38.9,14
c13.3,13.2,16.1,34,16.1,49c0,34.7-24.7,63-55,63s-55-28.3-55-63C162,115.7,170.7,101.3,178.1,94z M128.8,256.5
c10.1-14.3,21.1-22.1,36.1-25c31.4,22,73.1,22,104.5-0.1c14.9,2.9,25.9,10.8,35.9,25c8.9,12.6,16.3,29.3,22.7,47.5L106.1,304
C112.5,285.8,119.9,269.1,128.8,256.5z"/>
<path class="st0" d="M32.5,261H0v42h18.2C23,287,27.6,273.3,32.5,261z"/>
<path class="st0" d="M83,182c-0.9-3.6-1.7-7.3-2.4-11H0v42h56.8C64.2,201.6,73,191.2,83,182z"/>
<path class="st0" d="M88.8,81H0v42h79C80.4,108.6,83.7,94.5,88.8,81z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<path class="st0" d="M371,76H269V14H115v62H13v42h35v266h288V118h35V76z M157,56h70v20h-70V56z M294,342H90V118h204V342z"/>
<rect x="136" y="166" class="st0" width="42" height="128"/>
<rect x="206" y="166" class="st0" width="42" height="128"/>
</svg>

After

Width:  |  Height:  |  Size: 651 B

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<path id="details_1_" class="st0" d="M384,112.9L271.1,0L25,246.1v83.8L0.3,354l29.3,30l25.6-25h82.6L384,112.9z M324.6,112.9
l-36.4,36.4l-53.5-53.5l36.4-36.4L324.6,112.9z M70.3,317l-3.3-3.5v-50l138-138l53.5,53.5l-138,138H70.3z"/>
</svg>

After

Width:  |  Height:  |  Size: 637 B

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<polygon class="st0" points="296.5,366 384,288 296.5,210.5 296.5,267 0,267 0,309 296.5,309 "/>
<polygon class="st0" points="87.5,18 0,96 87.5,173.5 87.5,117 384,117 384,75 87.5,75 "/>
</svg>

After

Width:  |  Height:  |  Size: 592 B

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -5800,8 +5800,8 @@ __webpack_require__.r(__webpack_exports__);
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
__webpack_require__(/*! E:\Zano\check\zano\src\gui\qt-daemon\html_source\src\polyfills.ts */"./src/polyfills.ts");
module.exports = __webpack_require__(/*! E:\Zano\check\zano\src\gui\qt-daemon\html_source\node_modules\@angular-devkit\build-angular\src\angular-cli-files\models\jit-polyfills.js */"./node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/jit-polyfills.js");
__webpack_require__(/*! d:\Projects_now\ZANO\zano\src\gui\qt-daemon\html_source\src\polyfills.ts */"./src/polyfills.ts");
module.exports = __webpack_require__(/*! d:\Projects_now\ZANO\zano\src\gui\qt-daemon\html_source\node_modules\@angular-devkit\build-angular\src\angular-cli-files\models\jit-polyfills.js */"./node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/jit-polyfills.js");
/***/ })

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 32 32" style="enable-background:new 0 0 32 32;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<path class="st0" d="M22,15h-3.4H9.9v-5c0-3.3,2.7-6,6-6H16c3,0,5.4,2.2,5.9,5h4c-0.5-5-4.8-9-9.9-9h-0.1c-5.5,0-10,4.5-10,10v5H3
v17h12.9H16h13V15h-3H22z M18,27h-4v-7h4V27z"/>
</svg>

After

Width:  |  Height:  |  Size: 581 B

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -33,6 +33,7 @@
"idlejs": "^2.0.1",
"json-bignumber": "^1.0.1",
"ngx-contextmenu": "^5.1.1",
"ngx-papaparse": "^3.0.3",
"qrcode": "^1.3.0",
"rxjs": "~6.3.3",
"zone.js": "~0.8.26"

View file

@ -0,0 +1,6 @@
export class Contact {
name: string;
address: string;
alias?;
notes: string;
}

View file

@ -313,11 +313,17 @@ export class BackendService {
this.runCommand('check_master_password', pass, callback);
}
storeSecureAppData(callback?) {
let data;
const wallets = [];
const contacts = [];
this.variablesService.wallets.forEach((wallet) => {
wallets.push({name: wallet.name, pass: wallet.pass, path: wallet.path, staking: wallet.staking});
});
this.backendObject['store_secure_app_data'](JSON.stringify(wallets), this.variablesService.appPass, (dataStore) => {
this.variablesService.contacts.forEach((contact) => {
contacts.push({name: contact.name, address: contact.address, notes: contact.notes});
});
data = {wallets: wallets, contacts: contacts};
this.backendObject['store_secure_app_data'](JSON.stringify(data), this.variablesService.appPass, (dataStore) => {
this.backendCallback(dataStore, {}, callback, 'store_secure_app_data');
});
}
@ -352,6 +358,14 @@ export class BackendService {
this.runCommand('show_openfile_dialog', params, callback);
}
storeFile(path, buff) {
this.backendObject['store_to_file'](path, (typeof buff === 'string' ? buff : JSON.stringify(buff)));
}
loadFile(path, callback) {
this.runCommand('load_from_file', path, callback);
}
generateWallet(path, pass, callback) {
const params = {
path: path,
@ -601,6 +615,22 @@ export class BackendService {
return {};
}
getContactAlias() {
if (this.variablesService.contacts.length && this.variablesService.daemon_state === 2) {
this.variablesService.contacts.map(contact => {
this.getAliasByAddress(contact.address, (status, data) => {
if (status) {
if (data.alias) {
contact.alias = '@' + data.alias;
}
} else {
contact.alias = null;
}
});
});
}
}
getPoolInfo(callback) {
this.runCommand('get_tx_pool_info', {}, callback);
}

View file

@ -1,5 +1,6 @@
import {Injectable, NgZone} from '@angular/core';
import {Wallet} from '../models/wallet.model';
import {Contact} from '../models/contact.model';
import {BehaviorSubject} from 'rxjs';
import {Idle} from 'idlejs/dist';
import {Router} from '@angular/router';
@ -45,12 +46,16 @@ export class VariablesService {
public wallets: Array<Wallet> = [];
public currentWallet: Wallet;
public selectWallet: number;
public aliases: any = [];
public aliasesChecked: any = {};
public enableAliasSearch = false;
public maxWalletNameLength = 25;
public maxCommentLength = 255;
public dataIsLoaded = false;
public dataIsLoaded = false;
public contacts: Array<Contact> = [];
public newContact: Contact = {name: null, address: null, notes: null};
getExpMedTsEvent = new BehaviorSubject(null);
getHeightAppEvent = new BehaviorSubject(null);

View file

@ -0,0 +1,69 @@
<div class="content scrolled-content">
<div class="head">
<div class="breadcrumbs">
<span [routerLink]="['/contacts']">{{ 'CONTACTS.TITLE' | translate }}</span>
<span>{{ 'CONTACTS.ADD' | translate }}</span>
</div>
<button type="button" class="back-btn" (click)="back()">
<i class="icon back"></i>
<span>{{ 'COMMON.BACK' | translate }}</span>
</button>
</div>
<form class="form-add" [formGroup]="addContactForm" (ngSubmit)="add()">
<div class="input-block input-block-name">
<label for="add-name">{{ 'CONTACTS.FORM.NAME' | translate }}</label>
<input type="text" id="add-name" formControlName="name" (contextmenu)="variablesService.onContextMenu($event)">
<div class="error-block" *ngIf="addContactForm.controls['name'].invalid && (addContactForm.controls['name'].dirty || addContactForm.controls['name'].touched)">
<div *ngIf="addContactForm.controls['name'].errors['pattern']">
{{ 'CONTACTS.FORM_ERRORS.NAME_WRONG' | translate }}
</div>
<div *ngIf="addContactForm.get('name').value.length < 4 || addContactForm.get('name').value.length > 25">
{{ 'CONTACTS.FORM_ERRORS.NAME_LENGTH' | translate }}
</div>
<div *ngIf="addContactForm.controls['name'].errors['required']">
{{ 'CONTACTS.FORM_ERRORS.NAME_REQUIRED' | translate }}
</div>
<div *ngIf="addContactForm.controls['name'].errors['dublicated']">
{{ 'CONTACTS.FORM_ERRORS.NAME_DUBLICATED' | translate }}
</div>
</div>
</div>
<div class="input-block input-block-alias">
<label for="address">{{ 'CONTACTS.FORM.ADDRESS' | translate }}</label>
<input type="text" id="address" formControlName="address" (contextmenu)="variablesService.onContextMenu($event)">
<div class="error-block" *ngIf="addContactForm.controls['address'].invalid && (addContactForm.controls['address'].dirty || addContactForm.controls['address'].touched)">
<div *ngIf="addContactForm.controls['address'].errors['required']">
{{ 'CONTACTS.FORM_ERRORS.ADDRESS_REQUIRED' | translate }}
</div>
<div *ngIf="addContactForm.controls['address'].errors['address_not_valid']">
{{ 'CONTACTS.FORM_ERRORS.ADDRESS_NOT_VALID' | translate }}
</div>
<div *ngIf="addContactForm.controls['address'].errors['dublicated']">
{{ 'CONTACTS.FORM_ERRORS.ADDRESS_DUBLICATED' | translate }}
</div>
</div>
</div>
<div class="input-block input-block-notes">
<label for="notes">{{ 'CONTACTS.FORM.NOTES' | translate }}</label>
<input type="text" id="notes" formControlName="notes" (contextmenu)="variablesService.onContextMenu($event)">
<div class="error-block" *ngIf="addContactForm.controls['notes'].invalid">
<div *ngIf="addContactForm.controls['notes'].errors['maxLength']">
{{ 'CONTACTS.FORM_ERRORS.MAX_LENGTH' | translate }}
</div>
</div>
</div>
<button type="submit" class="blue-button" [disabled]="!addContactForm.valid">{{ 'CONTACTS.BUTTON.ADD_EDIT' | translate }}</button>
<app-send-modal *ngIf="isModalDialogVisible" [form]="addContactForm" (confirmed)="confirmed($event)"></app-send-modal>
</form>
</div>

View file

@ -0,0 +1,13 @@
.form-add {
margin-top: 3rem;
.input-block-name {
width: 50%;
}
button {
margin-top: 3rem;
width: 100%;
max-width: 18rem;
}
}

View file

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { AddContactsComponent } from './add-contacts.component';
describe('AddContactsComponent', () => {
let component: AddContactsComponent;
let fixture: ComponentFixture<AddContactsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ AddContactsComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AddContactsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,189 @@
import { Component, OnInit, NgZone, OnDestroy } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { BackendService } from '../_helpers/services/backend.service';
import { VariablesService } from '../_helpers/services/variables.service';
import { ModalService } from '../_helpers/services/modal.service';
import { Location } from '@angular/common';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-add-contacts',
templateUrl: './add-contacts.component.html',
styleUrls: ['./add-contacts.component.scss']
})
export class AddContactsComponent implements OnInit, OnDestroy {
id: number;
queryRouting;
addContactForm = new FormGroup({
address: new FormControl('', [
Validators.required,
(g: FormControl) => {
if (g.value) {
this.backend.validateAddress(g.value, valid_status => {
this.ngZone.run(() => {
if (valid_status === false) {
g.setErrors(
Object.assign({ address_not_valid: true }, g.errors)
);
} else {
if (g.hasError('address_not_valid')) {
delete g.errors['address_not_valid'];
if (Object.keys(g.errors).length === 0) {
g.setErrors(null);
}
}
}
});
});
return g.hasError('address_not_valid')
? { address_not_valid: true }
: null;
}
return null;
},
(g: FormControl) => {
const isDublicated = this.variablesService.contacts.findIndex(
contact => contact.address === g.value
);
if (isDublicated !== -1 && !(this.id === isDublicated)) {
return { dublicated: true };
}
return null;
}
]),
notes: new FormControl('', [
(g: FormControl) => {
if (g.value) {
if (g.value.length > this.variablesService.maxCommentLength) {
return { maxLength: true };
} else {
return null;
}
} else {
return null;
}
}
]),
name: new FormControl('', [
Validators.required,
Validators.pattern(/^[\w\s-_.]{4,25}$/),
(g: FormControl) => {
if (g.value) {
const isDublicated = this.variablesService.contacts.findIndex(
contact => contact.name === g.value.trim()
);
if (isDublicated !== -1 && !(this.id === isDublicated)) {
return { dublicated: true };
}
return null;
}
}
])
});
constructor(
private route: ActivatedRoute,
private backend: BackendService,
public variablesService: VariablesService,
private modalService: ModalService,
private ngZone: NgZone,
private location: Location
) {}
ngOnInit() {
this.queryRouting = this.route.queryParams.subscribe(params => {
if (params.id) {
this.id = parseInt(params.id, 10);
this.addContactForm.reset({
name: this.variablesService.contacts[params.id]['name'],
address: this.variablesService.contacts[params.id]['address'],
notes: this.variablesService.contacts[params.id]['notes']
});
} else {
this.addContactForm.reset({
name: this.variablesService.newContact['name'],
address: this.variablesService.newContact['address'],
notes: this.variablesService.newContact['notes']
});
}
});
}
add() {
if (!this.variablesService.appPass) {
this.modalService.prepareModal(
'error',
'CONTACTS.FORM_ERRORS.SET_MASTER_PASSWORD'
);
} else {
if (this.addContactForm.valid) {
this.backend.validateAddress(
this.addContactForm.get('address').value,
valid_status => {
if (valid_status === false) {
this.ngZone.run(() => {
this.addContactForm
.get('address')
.setErrors({ address_not_valid: true });
});
} else {
if (this.id || this.id === 0) {
this.variablesService.contacts.forEach((contact, index) => {
if (index === this.id) {
contact.name = this.addContactForm.get('name').value.trim();
contact.address = this.addContactForm.get('address').value;
contact.notes =
this.addContactForm.get('notes').value || '';
}
});
this.backend.storeSecureAppData();
this.backend.getContactAlias();
this.modalService.prepareModal(
'success',
'CONTACTS.SUCCESS_SAVE'
);
} else {
this.variablesService.contacts.push({
name: this.addContactForm.get('name').value.trim(),
address: this.addContactForm.get('address').value,
notes: this.addContactForm.get('notes').value || ''
});
this.backend.storeSecureAppData();
this.backend.getContactAlias();
this.modalService.prepareModal(
'success',
'CONTACTS.SUCCESS_SENT'
);
this.variablesService.newContact = {
name: null,
address: null,
notes: null
};
this.addContactForm.reset({
name: null,
address: null,
notes: null
});
}
}
}
);
}
}
}
back() {
this.location.back();
}
ngOnDestroy() {
if (!(this.id || this.id === 0)) {
this.variablesService.newContact = {
name: this.addContactForm.get('name').value,
address: this.addContactForm.get('address').value,
notes: this.addContactForm.get('notes').value
};
}
this.queryRouting.unsubscribe();
}
}

View file

@ -20,8 +20,12 @@ import { RestoreWalletComponent } from './restore-wallet/restore-wallet.componen
import { SeedPhraseComponent } from './seed-phrase/seed-phrase.component';
import { WalletDetailsComponent } from './wallet-details/wallet-details.component';
import { AssignAliasComponent } from './assign-alias/assign-alias.component';
import { EditAliasComponent } from "./edit-alias/edit-alias.component";
import { TransferAliasComponent } from "./transfer-alias/transfer-alias.component";
import { EditAliasComponent } from './edit-alias/edit-alias.component';
import { TransferAliasComponent } from './transfer-alias/transfer-alias.component';
import { ContactsComponent } from './contacts/contacts.component';
import { AddContactsComponent } from './add-contacts/add-contacts.component';
import { ContactSendComponent } from './contact-send/contact-send.component';
import { ExportImportComponent } from './export-import/export-import.component';
const routes: Routes = [
{
@ -119,6 +123,26 @@ const routes: Routes = [
path: 'settings',
component: SettingsComponent
},
{
path: 'contacts',
component: ContactsComponent
},
{
path: 'add-contacts',
component: AddContactsComponent
},
{
path: 'edit-contacts/:id',
component: AddContactsComponent
},
{
path: 'contact-send/:id',
component: ContactSendComponent
},
{
path: 'import',
component: ExportImportComponent
},
{
path: '',
redirectTo: '/',

View file

@ -193,6 +193,7 @@ export class AppComponent implements OnInit, OnDestroy {
});
if (!this.firstOnlineState && data['daemon_network_state'] === 2) {
this.getAliases();
this.backend.getContactAlias();
this.backend.getDefaultFee((status_fee, data_fee) => {
this.variablesService.default_fee_big = new BigNumber(data_fee);
this.variablesService.default_fee = this.intToMoneyPipe.transform(data_fee);

View file

@ -51,12 +51,17 @@ import * as highcharts from 'highcharts';
import exporting from 'highcharts/modules/exporting.src';
import { ProgressContainerComponent } from './_helpers/directives/progress-container/progress-container.component';
import { InputDisableSelectionDirective } from './_helpers/directives/input-disable-selection/input-disable-selection.directive';
import { SendModalComponent } from './send-modal/send-modal.component';
import { ContactsComponent } from './contacts/contacts.component';
import { AddContactsComponent } from './add-contacts/add-contacts.component';
import { ContactSendComponent } from './contact-send/contact-send.component';
import { ExportImportComponent } from './export-import/export-import.component';
export function HttpLoaderFactory(httpClient: HttpClient) {
return new TranslateHttpLoader(httpClient, './assets/i18n/', '.json');
}
import { PapaParseModule } from 'ngx-papaparse';
// import * as more from 'highcharts/highcharts-more.src';
// import * as exporting from 'highcharts/modules/exporting.src';
// import * as highstock from 'highcharts/modules/stock.src';
@ -108,7 +113,12 @@ export function highchartsFactory() {
ModalContainerComponent,
TransactionDetailsComponent,
ProgressContainerComponent,
InputDisableSelectionDirective
InputDisableSelectionDirective,
SendModalComponent,
ContactsComponent,
AddContactsComponent,
ContactSendComponent,
ExportImportComponent
],
imports: [
BrowserModule,
@ -125,6 +135,7 @@ export function highchartsFactory() {
ReactiveFormsModule,
NgSelectModule,
ChartModule,
PapaParseModule,
ContextMenuModule.forRoot()
],
providers: [
@ -136,7 +147,8 @@ export function highchartsFactory() {
// {provide: HIGHCHARTS_MODULES, useFactory: () => [ highstock, more, exporting ] }
],
entryComponents: [
ModalContainerComponent
ModalContainerComponent,
SendModalComponent
],
bootstrap: [AppComponent]
})

View file

@ -61,7 +61,6 @@
<div class="wrap-buttons">
<button type="button" class="blue-button" (click)="assignAlias()" [disabled]="!assignForm.valid || !canRegister || notEnoughMoney">{{ 'ASSIGN_ALIAS.BUTTON_ASSIGN' | translate }}</button>
<button type="button" class="blue-button" (click)="back()">{{ 'ASSIGN_ALIAS.BUTTON_CANCEL' | translate }}</button>
</div>
</form>

View file

@ -0,0 +1,44 @@
<div class="content scrolled-content">
<div class="head">
<div class="breadcrumbs">
<span [routerLink]="['/contacts']">{{
'CONTACTS.TITLE' | translate
}}</span>
<span>{{ 'CONTACTS.SEND' | translate }}</span>
</div>
<button type="button" class="back-btn" (click)="back()">
<i class="icon back"></i>
<span>{{ 'COMMON.BACK' | translate }}</span>
</button>
</div>
<div>
<div class="wallets-selection">
<div class="input-block">
<label>
{{ 'CONTACTS.SEND_FROM' | translate }}
</label>
<ng-select
class="custom-select"
[items]="this.variablesService.wallets"
[(ngModel)]="this.variablesService.selectWallet"
bindValue="wallet_id"
bindLabel="name"
[clearable]="false"
[searchable]="false"
>
</ng-select>
</div>
<button [routerLink]="['/main']">
{{ 'CONTACTS.OPEN_ADD_WALLET' | translate }}
</button>
</div>
<div class="input-block">
<label for="address">{{ 'CONTACTS.SEND_TO' | translate }}</label>
<input type="text" id="address" [ngModel]="address" [readonly]="true"/>
</div>
</div>
<button class="blue-button" [routerLink]="['/wallet/' + this.variablesService.selectWallet + '/send']" [queryParams]="{send: true}" (click)="goToWallet(this.variablesService.selectWallet)"
[disabled]="!(this.variablesService.selectWallet === 0 || this.variablesService.selectWallet)">{{ 'CONTACTS.BUTTON.GO_TO_WALLET' | translate }}</button>
</div>

View file

@ -0,0 +1,33 @@
.wallets-selection {
display: flex;
align-items: center;
margin-top: 2rem;
.input-block {
width: 18rem;
}
button {
padding: 2rem;
background: transparent;
border: none;
outline: none;
}
}
.input-block {
width: 44rem;
input {
overflow: hidden;
text-overflow: ellipsis;
}
}
.blue-button {
margin-top: 2.5rem;
width: 100%;
max-width: 18rem;
}

View file

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ContactSendComponent } from './contact-send.component';
describe('ContactSendComponent', () => {
let component: ContactSendComponent;
let fixture: ComponentFixture<ContactSendComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ContactSendComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ContactSendComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,44 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Location } from '@angular/common';
import { VariablesService } from '../_helpers/services/variables.service';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-contact-send',
templateUrl: './contact-send.component.html',
styleUrls: ['./contact-send.component.scss']
})
export class ContactSendComponent implements OnInit, OnDestroy {
queryRouting;
address;
constructor(
private location: Location,
private variablesService: VariablesService,
private route: ActivatedRoute
) { }
ngOnInit() {
this.queryRouting = this.route.queryParams.subscribe(params => {
if (params.address) {
this.address = params.address;
}
});
}
goToWallet(id) {
this.variablesService.setCurrentWallet(id);
this.variablesService.currentWallet.send_data['address'] = this.address;
}
back() {
this.location.back();
}
ngOnDestroy() {
this.queryRouting.unsubscribe();
}
}

View file

@ -0,0 +1,98 @@
<div class="content scrolled-content">
<div>
<div class="head">
<button type="button" class="back-btn" (click)="back()">
<i class="icon back"></i>
<span>{{ 'COMMON.BACK' | translate }}</span>
</button>
</div>
<h3 class="contacts-title">{{ 'CONTACTS.TITLE' | translate }}</h3>
<div class="wrap-table">
<ng-container>
<table
*ngIf="this.variablesService.contacts.length !== 0; else emptyList"
>
<thead>
<tr #head (window:resize)="calculateWidth()">
<th>{{ 'CONTACTS.TABLE.NAME' | translate }}</th>
<th>{{ 'CONTACTS.TABLE.ALIAS' | translate }}</th>
<th>{{ 'CONTACTS.TABLE.ADDRESS' | translate }}</th>
<th>{{ 'CONTACTS.TABLE.NOTES' | translate }}</th>
<th></th>
</tr>
</thead>
<tbody>
<ng-container
*ngFor="
let contact of this.variablesService.contacts;
let i = index
"
>
<tr>
<td>
{{ contact.name }}
</td>
<td>
<ng-container *ngIf="contact.alias">
<span
class="alias"
(click)="openInBrowser(contact.alias)"
>{{ contact.alias }}</span
>
</ng-container>
</td>
<td class="remote-address">
{{ contact.address }}
</td>
<td class="remote-notes">
{{ contact.notes }}
</td>
<td>
<div class="button-wrapper">
<button
[routerLink]="['/contact-send/' + i]"
[queryParams]="{ address: contact.address }"
>
<i class="icon transfer"></i>
<span>{{ 'CONTACTS.BUTTON.SEND' | translate }}</span>
</button>
<button
[routerLink]="['/edit-contacts/' + i]"
[queryParams]="{ id: i }"
>
<i class="icon edit"></i>
<span>{{ 'CONTACTS.BUTTON.EDIT' | translate }}</span>
</button>
<button (click)="delete(i)">
<i class="icon delete"></i>
<span>{{ 'CONTACTS.BUTTON.DELETE' | translate }}</span>
</button>
</div>
</td>
</tr>
</ng-container>
</tbody>
</table>
</ng-container>
<ng-template #emptyList>
<div class="empty-list">
{{ 'CONTACTS.TABLE.EMPTY' | translate }}
</div>
</ng-template>
</div>
<button [routerLink]="['/add-contacts']" class="blue-button">
{{ 'CONTACTS.BUTTON.ADD' | translate }}
</button>
<div class="footer">
<button type="button" class="import-btn" [routerLink]="['/import']">
<i class="icon import"></i>
<span>{{ 'CONTACTS.BUTTON.IMPORT_EXPORT' | translate }}</span>
</button>
</div>
</div>
</div>

View file

@ -0,0 +1,117 @@
:host {
min-width: 95rem;
width: 100%;
height: 100%;
}
.head {
justify-content: flex-end;
}
.contacts-title {
font-size: 1.7rem;
}
.wrap-table {
margin: 1rem -3rem;
table {
tbody{
tr {
td {
padding: 0 3rem 0 1rem;
overflow: hidden;
text-overflow: ellipsis;
&:first-child {
max-width: 10rem;
padding: 0 3rem 0 3rem;
}
&:nth-child(2) {
max-width: 10rem;
}
.alias {
cursor: pointer;
}
.button-wrapper {
display: flex;
button {
display: flex;
align-items: center;
background: transparent;
border: none;
font-size: 1.3rem;
font-weight: 400;
line-height: 3rem;
outline: none;
padding: 0;
height: auto;
margin-right: 1.8rem;
.icon {
cursor: pointer;
margin-right: 0.8rem;
width: 1.7rem;
height: 1.7rem;
&.edit {
mask: url(../../assets/icons/edit.svg) no-repeat center;
}
&.transfer {
mask: url(../../assets/icons/send.svg) no-repeat center;
}
&.delete {
mask: url(../../assets/icons/delete.svg) no-repeat center;
}
}
}
}
}
}
}
}
.empty-list {
margin: 2.5rem 3rem;
}
}
.blue-button {
width: 100%;
max-width: 18rem;
margin-top: 3rem;
}
.footer {
position: absolute;
bottom: 3rem;
font-size: 1.3rem;
.import-btn {
display: flex;
align-items: center;
background-color: transparent;
font-size: inherit;
font-weight: 400;
line-height: 1.3rem;
padding: 0;
height: auto;
.icon {
margin-right: 0.7rem;
mask: url(../../assets/icons/import-export.svg) no-repeat center;
width: 0.9rem;
height: 0.9rem;
}
}
}

View file

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ContactsComponent } from './contacts.component';
describe('ContactsComponent', () => {
let component: ContactsComponent;
let fixture: ComponentFixture<ContactsComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ContactsComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ContactsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,60 @@
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { Location } from '@angular/common';
import { VariablesService } from '../_helpers/services/variables.service';
import { BackendService } from '../_helpers/services/backend.service';
@Component({
selector: 'app-contacts',
templateUrl: './contacts.component.html',
styleUrls: ['./contacts.component.scss']
})
export class ContactsComponent implements OnInit {
calculatedWidth = [];
@ViewChild('head') head: ElementRef;
constructor(
private location: Location,
private variablesService: VariablesService,
private backend: BackendService
) {}
ngOnInit() {
this.backend.getContactAlias();
}
delete(index: number) {
if (this.variablesService.appPass) {
this.variablesService.contacts.splice(index, 1);
this.backend.storeSecureAppData();
}
}
calculateWidth() {
this.calculatedWidth = [];
this.calculatedWidth.push(
this.head.nativeElement.childNodes[0].clientWidth
);
this.calculatedWidth.push(
this.head.nativeElement.childNodes[1].clientWidth +
this.head.nativeElement.childNodes[2].clientWidth
);
this.calculatedWidth.push(
this.head.nativeElement.childNodes[3].clientWidth
);
this.calculatedWidth.push(
this.head.nativeElement.childNodes[4].clientWidth
);
}
openInBrowser(alias: string) {
if (alias !== null) {
this.backend.openUrlInBrowser(
`explorer.zano.org/aliases/${alias.slice(1)}`
);
}
}
back() {
this.location.back();
}
}

View file

@ -44,7 +44,6 @@
<div class="wrap-buttons">
<button type="button" class="blue-button" (click)="updateAlias()" [disabled]="notEnoughMoney || (oldAliasComment === alias.comment) || alias.comment.length > variablesService.maxCommentLength">{{ 'EDIT_ALIAS.BUTTON_EDIT' | translate }}</button>
<button type="button" class="blue-button" (click)="back()">{{ 'EDIT_ALIAS.BUTTON_CANCEL' | translate }}</button>
</div>
</form>

View file

@ -0,0 +1,21 @@
<div class="content scrolled-content">
<div>
<div class="head">
<button type="button" class="back-btn" (click)="back()">
<i class="icon back"></i>
<span>{{ 'COMMON.BACK' | translate }}</span>
</button>
</div>
<h3 class="contacts-title">{{ 'CONTACTS.IMPORT_EXPORT' | translate }}</h3>
<div class="btn-wrapper">
<button class="blue-button" type="button" (click)="import()">
{{ 'CONTACTS.IMPORT' | translate }}
</button>
<button class="blue-button" type="button" (click)="export()">
{{ 'CONTACTS.EXPORT' | translate }}
</button>
</div>
</div>
</div>

View file

@ -0,0 +1,25 @@
:host {
width: 100%;
}
.head {
justify-content: flex-end;
}
.contacts-title {
font-size: 1.7rem;
margin-bottom: 1rem;
}
.btn-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
margin: 0 -0.5rem;
padding: 1.5rem 0;
button {
flex: 1 0 auto;
margin: 0 0.5rem;
}
}

View file

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ExportImportComponent } from './export-import.component';
describe('ExportImportComponent', () => {
let component: ExportImportComponent;
let fixture: ComponentFixture<ExportImportComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ExportImportComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ExportImportComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,124 @@
import { Component, OnInit } from '@angular/core';
import { Location } from '@angular/common';
import { BackendService } from '../_helpers/services/backend.service';
import { VariablesService } from '../_helpers/services/variables.service';
import { Contact } from '../_helpers/models/contact.model';
import { ModalService } from '../_helpers/services/modal.service';
import { Papa } from 'ngx-papaparse';
import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'app-export-import',
templateUrl: './export-import.component.html',
styleUrls: ['./export-import.component.scss']
})
export class ExportImportComponent implements OnInit {
csvContent;
constructor(
private location: Location,
private variablesService: VariablesService,
private backend: BackendService,
private modalService: ModalService,
private papa: Papa,
private translate: TranslateService
) {}
ngOnInit() {}
import() {
this.backend.openFileDialog(
'',
'*',
this.variablesService.settings.default_path,
(file_status, file_data) => {
if (file_status) {
this.variablesService.settings.default_path = file_data.path.substr(
0,
file_data.path.lastIndexOf('/')
);
if (this.isValid(file_data.path)) {
this.backend.loadFile(file_data.path, (status, data) => {
if (status) {
const options = {
header: true
};
const elements = this.papa.parse(data, options);
if (elements.data && !elements.errors.length) {
if (!this.variablesService.contacts.length) {
elements.data.forEach(element => {
this.variablesService.contacts.push(element);
});
} else {
elements.data.forEach(element => {
const indexName = this.variablesService.contacts.findIndex(
contact => contact.name === element.name
);
const indexAddress = this.variablesService.contacts.findIndex(
contact => contact.address === element.address
);
if (indexAddress === -1 && indexName === -1) {
this.variablesService.contacts.push(element);
}
if (indexName !== -1 && indexAddress === -1) {
this.variablesService.contacts.push({
name: `${element.name} ${this.translate.instant(
'CONTACTS.COPY'
)}`,
address: element.address,
notes: element.notes
});
}
});
}
this.backend.getContactAlias();
this.modalService.prepareModal(
'success',
'CONTACTS.SUCCESS_IMPORT'
);
}
if (elements.errors.length) {
this.modalService.prepareModal(
'error',
'CONTACTS.ERROR_IMPORT'
);
console.log(elements.errors);
}
}
});
} else {
this.modalService.prepareModal('error', 'CONTACTS.ERROR_TYPE_FILE');
}
}
}
);
}
export() {
const contacts: Array<Contact> = [];
this.variablesService.contacts.forEach(contact => {
delete contact.alias;
contacts.push(contact);
});
this.backend.saveFileDialog(
'',
'*',
this.variablesService.settings.default_path,
(file_status, file_data) => {
if (file_status) {
this.backend.storeFile(file_data.path, this.papa.unparse(contacts));
}
}
);
}
isValid(file) {
return file.endsWith('.csv');
}
back() {
this.location.back();
}
}

View file

@ -13,16 +13,33 @@
<tbody>
<ng-container *ngFor="let item of variablesService.currentWallet.history">
<tr (click)="openDetails(item.tx_hash)" [class.locked-transaction]="!item.is_mining && item.unlock_time > 0">
<td>
<td>
<div class="status" [class.send]="!item.is_income" [class.received]="item.is_income">
<ng-container *ngIf="variablesService.height_app - item.height < 10 || item.height === 0 && item.timestamp > 0">
<div class="confirmation" tooltip="{{ 'HISTORY.STATUS_TOOLTIP' | translate : {'current': getHeight(item)/10, 'total': 10} }}" placement="bottom-left" tooltipClass="table-tooltip" [delay]="500">
<div class="fill" [style.height]="getHeight(item) + '%'"></div>
</div>
</ng-container>
<ng-container *ngIf="!item.is_mining && item.unlock_time > 0">
<i class="icon lock-transaction" tooltip="{{ 'HISTORY.LOCK_TOOLTIP' | translate : {'date': item.unlock_time * 1000 | date : 'MM.dd.yy'} }}" placement="bottom-left" tooltipClass="table-tooltip" [delay]="500"></i>
<ng-container *ngIf="item.unlock_time !== 0 && item.tx_type !== 6">
<ng-container *ngIf="isLocked(item); else unlock">
<ng-container *ngIf="item.unlock_time < 500000000">
<i class="icon lock-transaction" tooltip="{{ 'HISTORY.LOCK_TOOLTIP' | translate : {'date': time(item) | date : 'MM.dd.yy'} }}" placement="bottom-left" tooltipClass="table-tooltip" [delay]="500"
[class.position]="variablesService.height_app - item.height < 10 || item.height === 0 && item.timestamp > 0"></i>
</ng-container>
<ng-container *ngIf="item.unlock_time > 500000000">
<i class="icon lock-transaction" tooltip="{{ 'HISTORY.LOCK_TOOLTIP' | translate : {'date': item.unlock_time * 1000 | date : 'MM.dd.yy'} }}" placement="bottom-left" tooltipClass="table-tooltip" [delay]="500"
[class.position]="variablesService.height_app - item.height < 10 || item.height === 0 && item.timestamp > 0"></i>
</ng-container>
</ng-container>
<ng-template #unlock>
<i class="icon unlock-transaction" placement="bottom-left" [class.position]="variablesService.height_app - item.height < 10 || item.height === 0 && item.timestamp > 0"></i>
</ng-template>
</ng-container>
<!-- <ng-container *ngIf="!item.is_mining && item.unlock_time > 0">
<i class="icon lock-transaction" tooltip="{{ 'HISTORY.LOCK_TOOLTIP' | translate : {'date': item.unlock_time * 1000 | date : 'MM.dd.yy'} }}" placement="bottom-left" tooltipClass="table-tooltip" [delay]="500"></i>
</ng-container> -->
<i class="icon status-transaction"></i>
<span>{{ (item.is_income ? 'HISTORY.RECEIVED' : 'HISTORY.SEND') | translate }}</span>
</div>

View file

@ -37,12 +37,24 @@
.lock-transaction {
position: absolute;
top: 50%;
left: -2rem;
transform: translateY(-50%);
mask: url(../../assets/icons/lock-transaction.svg) no-repeat center;
width: 1.2rem;
height: 1.2rem;
margin-right: 1.1rem;
}
.unlock-transaction {
position: absolute;
left: -2rem;
mask: url(../../assets/icons/unlock-transaction.svg) no-repeat center;
width: 1.2rem;
height: 1.2rem;
margin-right: 1.1rem;
}
.position {
position: static;
}
.status-transaction {

View file

@ -1,6 +1,7 @@
import {Component, OnInit, OnDestroy, AfterViewChecked, ViewChild, ElementRef} from '@angular/core';
import {VariablesService} from '../_helpers/services/variables.service';
import {ActivatedRoute} from '@angular/router';
import { Transaction } from '../_helpers/models/transaction.model';
@Component({
selector: 'app-history',
@ -56,6 +57,23 @@ export class HistoryComponent implements OnInit, OnDestroy, AfterViewChecked {
this.calculatedWidth.push(this.head.nativeElement.childNodes[4].clientWidth);
}
time(item: Transaction) {
const now = new Date().getTime();
const unlockTime = now + ((item.unlock_time - this.variablesService.height_app) * 60 * 1000);
return unlockTime;
}
isLocked(item: Transaction) {
if ((item.unlock_time > 500000000) && (item.unlock_time > new Date().getTime() / 1000)) {
console.log(new Date().getTime());
return true;
}
if ((item.unlock_time < 500000000) && (item.unlock_time > this.variablesService.height_app)) {
return true;
}
return false;
}
ngOnDestroy() {
this.parentRouting.unsubscribe();
}

View file

@ -26,7 +26,7 @@ export class LoginComponent implements OnInit, OnDestroy {
password: new FormControl('')
});
type = 'reg';
type = 'reg';
constructor(
private route: ActivatedRoute,
@ -61,8 +61,7 @@ export class LoginComponent implements OnInit, OnDestroy {
} else {
console.log(data['error_code']);
}
})
});
}
}
@ -74,10 +73,12 @@ export class LoginComponent implements OnInit, OnDestroy {
});
}
dropSecureAppData(): void{
dropSecureAppData(): void {
this.backend.dropSecureAppData(() => {
this.onSkipCreatePass();
});
this.onSkipCreatePass();
});
this.variablesService.wallets = [];
this.variablesService.contacts = [];
}
onSubmitAuthPass(): void {
@ -93,9 +94,9 @@ export class LoginComponent implements OnInit, OnDestroy {
this.router.navigate(['/']);
});
}
})
});
} else {
this.getWalletData(this.variablesService.appPass)
this.getWalletData(this.variablesService.appPass);
}
}
}
@ -107,16 +108,21 @@ export class LoginComponent implements OnInit, OnDestroy {
this.variablesService.dataIsLoaded = true;
this.variablesService.startCountdown();
this.variablesService.appPass = appPass;
if (Object.keys(data['contacts']).length !== 0) {
data['contacts'].map(contact => {
this.variablesService.contacts.push(contact);
});
}
if (this.variablesService.wallets.length) {
this.ngZone.run(() => {
this.router.navigate(['/wallet/' + this.variablesService.wallets[0].wallet_id]);
});
return;
}
if (Object.keys(data).length !== 0) {
if (Object.keys(data['wallets']).length !== 0) {
let openWallets = 0;
let runWallets = 0;
data.forEach((wallet, wallet_index) => {
data['wallets'].forEach((wallet, wallet_index) => {
this.backend.openWallet(wallet.path, wallet.pass, true, (open_status, open_data, open_error) => {
if (open_status || open_error === 'FILE_RESTORED') {
openWallets++;

View file

@ -21,8 +21,7 @@
<div class="wrap-buttons">
<button type="button" class="blue-button seed-phrase-button" (click)="runWallet()">{{ 'SEED_PHRASE.BUTTON_CREATE_ACCOUNT' | translate }}</button>
<button type="button" class="blue-button copy-button" *ngIf="!seedPhraseCopied" (click)="copySeedPhrase()">{{ 'SEED_PHRASE.BUTTON_COPY' | translate }}</button>
<button type="button" class="transparent-button copy-button" *ngIf="seedPhraseCopied" disabled><i class="icon"></i>{{ 'SEED_PHRASE.BUTTON_COPY' | translate }}</button>
<button type="button" class="blue-button copy-button" (click)="copySeedPhrase()">{{ 'SEED_PHRASE.BUTTON_COPY' | translate }}</button>
</div>
</div>

View file

@ -0,0 +1,31 @@
<div class="modal">
<div class="title">
<span>{{ 'CONFIRM.TITLE' | translate }}</span>
</div>
<div class="content">
<div class="message-container">
<div class="message-block">
<div class="message-label">{{ 'CONFIRM.MESSAGE.SEND' | translate }}</div>
<div class="message-text">{{ form.get('amount').value }} {{variablesService.defaultCurrency}}</div>
</div>
<div class="message-block">
<div class="message-label">{{ 'CONFIRM.MESSAGE.FROM' | translate }}</div>
<div class="message-text">{{ variablesService.currentWallet.address }}</div>
</div>
<div class="message-block">
<div class="message-label">{{ 'CONFIRM.MESSAGE.TO' | translate }}</div>
<div class="message-text">{{ form.get('address').value }}</div>
</div>
<ng-container *ngIf="form.get('comment').value != ''">
<div class="message-block" *ngIf="form.get('comment').value != null">
<div class="message-label">{{ 'CONFIRM.MESSAGE.COMMENT' | translate }}</div>
<div class="message-text">{{ form.get('comment').value }}</div>
</div>
</ng-container>
</div>
</div>
<div class="wrapper-buttons">
<button type="button" class="blue-button" (click)="confirm()">{{ 'CONFIRM.BUTTON_CONFIRM' | translate }}</button>
<button type="button" class="blue-button" (click)="onClose()">{{ 'CONFIRM.BUTTON_CANCEL' | translate }}</button>
</div>
</div>

View file

@ -0,0 +1,84 @@
:host {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.25);
}
.modal {
position: relative;
display: flex;
flex-direction: column;
background-position: center;
background-size: 200%;
padding: 0.3rem 3rem 3rem 3rem;
width: 64rem;
.title {
padding: 1.4rem 0;
font-size: 1.8rem;
line-height: 3rem;
}
.content {
display: flex;
font-size: 1.4rem;
.message-container {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
margin: 1.4rem 3rem 6.2rem 0;
.message-block {
display: flex;
margin-bottom: 1rem;
&:first-child {
.message-label {
line-height: 4rem;
}
.message-text {
line-height: 4rem;
}
}
&:last-child {
margin-bottom: 0;
}
.message-label {
min-width: 6.7rem;
line-height: 2rem;
}
.message-text {
overflow-wrap: break-word;
margin-left: 4.8rem;
width: 43.4rem;
line-height: 2rem;
}
}
}
}
.wrapper-buttons {
display: flex;
align-items: center;
justify-content: space-between;
button {
width: 100%;
max-width: 15rem;
}
}
}

View file

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { SendModalComponent } from './send-modal.component';
describe('SendModalComponent', () => {
let component: SendModalComponent;
let fixture: ComponentFixture<SendModalComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ SendModalComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SendModalComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,32 @@
import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
import { FormGroup } from '@angular/forms';
import { VariablesService } from '../_helpers/services/variables.service';
@Component({
selector: 'app-send-modal',
templateUrl: './send-modal.component.html',
styleUrls: ['./send-modal.component.scss']
})
export class SendModalComponent implements OnInit {
@Input() form: FormGroup;
@Output() confirmed: EventEmitter<boolean> = new EventEmitter<boolean>();
constructor(
public variablesService: VariablesService
) {
}
ngOnInit() {
}
confirm() {
this.confirmed.emit(true);
}
onClose() {
this.confirmed.emit(false);
}
}

View file

@ -1,4 +1,4 @@
<form class="form-send" [formGroup]="sendForm" (ngSubmit)="onSend()">
<form class="form-send" [formGroup]="sendForm" (ngSubmit)="showDialog()">
<div class="input-block input-block-alias">
<label for="send-address">{{ 'SEND.ADDRESS' | translate }}</label>
@ -85,4 +85,6 @@
<button type="submit" class="blue-button" [disabled]="!sendForm.valid || !variablesService.currentWallet.loaded">{{ 'SEND.BUTTON' | translate }}</button>
<app-send-modal *ngIf="isModalDialogVisible" [form]="sendForm" (confirmed)="confirmed($event)"></app-send-modal>
</form>

View file

@ -1,4 +1,4 @@
import {Component, OnInit, OnDestroy, NgZone, HostListener} from '@angular/core';
import {Component, OnInit, OnDestroy, NgZone, HostListener, Input} from '@angular/core';
import {FormGroup, FormControl, Validators} from '@angular/forms';
import {ActivatedRoute} from '@angular/router';
import {BackendService} from '../_helpers/services/backend.service';
@ -15,6 +15,7 @@ export class SendComponent implements OnInit, OnDestroy {
isOpen = false;
localAliases = [];
isModalDialogVisible = false;
currentWalletId = null;
parentRouting;
@ -73,13 +74,7 @@ export class SendComponent implements OnInit, OnDestroy {
}
return null;
}]),
comment: new FormControl('', [(g: FormControl) => {
if (g.value > this.variablesService.maxCommentLength) {
return {'maxLength': true};
} else {
return null;
}
}]),
comment: new FormControl(''),
mixin: new FormControl(0, Validators.required),
fee: new FormControl(this.variablesService.default_fee, [Validators.required, (g: FormControl) => {
if ((new BigNumber(g.value)).isLessThan(this.variablesService.default_fee)) {
@ -132,6 +127,17 @@ export class SendComponent implements OnInit, OnDestroy {
});
}
showDialog() {
this.isModalDialogVisible = true;
}
confirmed(confirmed: boolean) {
if (confirmed) {
this.onSend();
}
this.isModalDialogVisible = false;
}
onSend() {
if (this.sendForm.valid) {
if (this.sendForm.get('address').value.indexOf('@') !== 0) {

View file

@ -38,6 +38,12 @@
</div>
</div>
<div class="sidebar-settings">
<div class="wrap-button" routerLinkActive="active">
<button (click)="contactsRoute()" [class.disabled]="variablesService.daemon_state !== 2" [disabled]="variablesService.daemon_state !== 2">
<i class="icon contacts"></i>
<span>{{ 'SIDEBAR.CONTACTS' | translate }}</span>
</button>
</div>
<div class="wrap-button" routerLinkActive="active">
<button [routerLink]="['/settings']">
<i class="icon settings"></i>

View file

@ -198,11 +198,19 @@
padding: 0 3rem;
width: 100%;
&.disabled {
cursor: url(../../assets/icons/not-allowed.svg), not-allowed;
}
.icon {
margin-right: 1.2rem;
width: 1.7rem;
height: 1.7rem;
&.contacts {
mask: url(../../assets/icons/contacts.svg) no-repeat center;
}
&.settings {
mask: url(../../assets/icons/settings.svg) no-repeat center;
}

View file

@ -2,6 +2,7 @@ import {Component, NgZone, OnInit, OnDestroy} from '@angular/core';
import {ActivatedRoute, NavigationStart, Router} from '@angular/router';
import {VariablesService} from '../_helpers/services/variables.service';
import {BackendService} from '../_helpers/services/backend.service';
import { ModalService } from '../_helpers/services/modal.service';
@Component({
selector: 'app-sidebar',
@ -18,6 +19,7 @@ export class SidebarComponent implements OnInit, OnDestroy {
private router: Router,
public variablesService: VariablesService,
private backend: BackendService,
private modal: ModalService,
private ngZone: NgZone
) {}
@ -49,6 +51,17 @@ export class SidebarComponent implements OnInit, OnDestroy {
});
}
contactsRoute() {
if (this.variablesService.appPass) {
this.router.navigate(['/contacts']);
} else {
this.modal.prepareModal(
'error',
'CONTACTS.FORM_ERRORS.SET_MASTER_PASSWORD'
);
}
}
getUpdate() {
this.backend.openUrlInBrowser('zano.org/downloads.html');
}

View file

@ -15,14 +15,14 @@
<div class="input-block alias-name">
<label for="alias-name">
{{ 'EDIT_ALIAS.NAME.LABEL' | translate }}
{{ 'TRANSFER_ALIAS.NAME.LABEL' | translate }}
</label>
<input type="text" id="alias-name" [value]="alias.name" placeholder="{{ 'EDIT_ALIAS.NAME.PLACEHOLDER' | translate }}" readonly>
</div>
<div class="input-block textarea">
<label for="alias-comment">
{{ 'EDIT_ALIAS.COMMENT.LABEL' | translate }}
{{ 'TRANSFER_ALIAS.COMMENT.LABEL' | translate }}
</label>
<textarea id="alias-comment" [value]="alias.comment" placeholder="{{ 'EDIT_ALIAS.COMMENT.PLACEHOLDER' | translate }}" readonly></textarea>
</div>
@ -49,7 +49,6 @@
<div class="wrap-buttons">
<button type="button" class="blue-button" (click)="transferAlias()" [disabled]="transferAddressAlias || !transferAddressValid || notEnoughMoney">{{ 'TRANSFER_ALIAS.BUTTON_TRANSFER' | translate }}</button>
<button type="button" class="blue-button" (click)="back()">{{ 'TRANSFER_ALIAS.BUTTON_CANCEL' | translate }}</button>
</div>
</form>

View file

@ -14,6 +14,7 @@ import {Subscription} from 'rxjs';
export class WalletComponent implements OnInit, OnDestroy {
subRouting1;
subRouting2;
queryRouting;
walletID;
copyAnimation = false;
copyAnimationTimeout;
@ -94,6 +95,15 @@ export class WalletComponent implements OnInit, OnDestroy {
}
}
});
this.queryRouting = this.route.queryParams.subscribe(params => {
if (params.send) {
this.tabs.forEach((tab, index) => {
if (tab.link === '/send') {
this.changeTab(index);
}
});
}
});
if (this.variablesService.currentWallet.alias.hasOwnProperty('name')) {
this.variablesService.currentWallet.wakeAlias = false;
}
@ -178,6 +188,7 @@ export class WalletComponent implements OnInit, OnDestroy {
ngOnDestroy() {
this.subRouting1.unsubscribe();
this.subRouting2.unsubscribe();
this.queryRouting.unsubscribe();
this.aliasSubscription.unsubscribe();
clearTimeout(this.copyAnimationTimeout);
}

View file

@ -1,87 +1,87 @@
{
"LOGIN": {
"SETUP_MASTER_PASS": "Setup master password",
"SETUP_CONFIRM_PASS": "Confirm the password",
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"SETUP_MASTER_PASS": "Nastavit hlavní heslo",
"SETUP_CONFIRM_PASS": "Potvrdit heslo",
"MASTER_PASS": "Hlavní heslo",
"BUTTON_NEXT": "Další",
"BUTTON_SKIP": "Přeskočit",
"BUTTON_RESET": "Resetovat",
"INCORRECT_PASSWORD": "Neplatné heslo",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",
"CONFIRM_REQUIRED": "Confirmation is required",
"MISMATCH": "Mismatch"
"PASS_REQUIRED": "Je vyžadováno heslo",
"CONFIRM_REQUIRED": "Je požadováno potvrzení",
"MISMATCH": "Neodpovídající"
}
},
"COMMON": {
"BACK": "Go back"
"BACK": "Jít zpět"
},
"BREADCRUMBS": {
"ADD_WALLET": "Add wallet",
"CREATE_WALLET": "Create new wallet",
"SAVE_PHRASE": "Save your seed phrase",
"OPEN_WALLET": "Open existing wallet",
"RESTORE_WALLET": "Restore from backup",
"WALLET_DETAILS": "Wallet details",
"ASSIGN_ALIAS": "Assign alias",
"EDIT_ALIAS": "Edit alias",
"TRANSFER_ALIAS": "Transfer alias",
"CONTRACTS": "Contracts",
"NEW_PURCHASE": "New purchase",
"OLD_PURCHASE": "Purchase"
"ADD_WALLET": "Přidat peněženku",
"CREATE_WALLET": "Vytvořit novou peněženku",
"SAVE_PHRASE": "Uložit svoji seed frázi",
"OPEN_WALLET": "Otevřít existující peněženku",
"RESTORE_WALLET": "Obnovení z zálohy",
"WALLET_DETAILS": "Podrobnosti o peněžence",
"ASSIGN_ALIAS": "Přidělit přezdívku",
"EDIT_ALIAS": "Upravit přezdívku",
"TRANSFER_ALIAS": "Převést přezdívku",
"CONTRACTS": "Kontrakty",
"NEW_PURCHASE": "Nový nákup",
"OLD_PURCHASE": "Nákup"
},
"SIDEBAR": {
"TITLE": "Wallets",
"ADD_NEW": "+ Add",
"TITLE": "Peněženky",
"ADD_NEW": "+ Přidat",
"ACCOUNT": {
"STAKING": "Staking",
"MESSAGES": "New offers/Messages",
"SYNCING": "Syncing wallet"
"MESSAGES": "Nové nabídky/zprávy",
"SYNCING": "Synchronizace pěněženky"
},
"SETTINGS": "Settings",
"LOG_OUT": "Log out",
"SETTINGS": "Nastavení",
"LOG_OUT": "Odhlásit se",
"SYNCHRONIZATION": {
"OFFLINE": "Offline",
"ONLINE": "Online",
"ERROR": "System error",
"COMPLETE": "Completion",
"SYNCING": "Syncing blockchain",
"LOADING": "Loading blockchain data"
"ERROR": "Chyba systému",
"COMPLETE": "Dokončení",
"SYNCING": "Sychronizace blockchainu",
"LOADING": "Nahrávání blockchainových dat"
},
"UPDATE": {
"STANDARD": "Update available",
"STANDARD_TOOLTIP": "<span class=\"standard-update\">Get new update.</span><br><span>Update is recommended!</span>",
"IMPORTANT": "Update available",
"IMPORTANT_HINT": "Important update!",
"IMPORTANT_TOOLTIP": "<span class=\"important-update\">Get new update.</span><br><span>Important update!</span>",
"CRITICAL": "Update available",
"CRITICAL_HINT": "Critical update!",
"CRITICAL_TOOLTIP": "<span class=\"critical-update\">Critical update available.</span><i class=\"icon\"></i><span>Update strongly recommended!</span>",
"TIME": "System time differs from network",
"TIME_TOOLTIP": "<span class=\"wrong-time\">Wrong system time!</span><br><span>Check and repair your system time.</span>"
"STANDARD": "Aktualizace k dispozici",
"STANDARD_TOOLTIP": "<span class=\"standard-update\">Získejte novou aktualizaci.</span><br><span>Doporučená aktualizace!</span>",
"IMPORTANT": "Aktualizace k dispozici",
"IMPORTANT_HINT": "Důležitá aktualizace!",
"IMPORTANT_TOOLTIP": "<span class=\"important-update\">Získejte novou aktualizaci.</span><br><span>Důležitá aktualizace!</span>",
"CRITICAL": "Aktualizace k dispozici",
"CRITICAL_HINT": "Kritická aktualizace!",
"CRITICAL_TOOLTIP": "<span class=\"critical-update\">Kritická aktualizace k dispozici.</span><i class=\"icon\"></i><span>Aktualizaci důrazně doporučujeme!</span>",
"TIME": "Systémový čas se liší od sítového",
"TIME_TOOLTIP": "<span class=\"wrong-time\">Špatný systémový čas!</span><br><span>Zkontrolujte a nastavte systémový čas.</span>"
}
},
"MAIN": {
"TITLE": "Create or open the wallet to start using Zano",
"BUTTON_NEW_WALLET": "Create new wallet",
"BUTTON_OPEN_WALLET": "Open existing wallet",
"BUTTON_RESTORE_BACKUP": "Restore from backup",
"HELP": "How to create wallet?",
"CHOOSE_PATH": "Please choose a path"
"TITLE": "Chcete-li začít používat Zano, vytvořte nebo otevřete peněženku",
"BUTTON_NEW_WALLET": "Vytvořit novou peněženku",
"BUTTON_OPEN_WALLET": "Otevřít existující peněženku",
"BUTTON_RESTORE_BACKUP": "Obnovení ze zálohy",
"HELP": "Jak vytvořit peněženku?",
"CHOOSE_PATH": "Zvolte prosím cestu"
},
"CREATE_WALLET": {
"NAME": "Wallet name",
"PASS": "Set wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",
"BUTTON_CREATE": "Create wallet",
"TITLE_SAVE": "Save the wallet file.",
"ERROR_CANNOT_SAVE_TOP": "Existing wallet files cannot be replaced or overwritten",
"ERROR_CANNOT_SAVE_SYSTEM": "Wallet files cannot be saved to the OS partition",
"NAME": "Název peněženky",
"PASS": "Nastavit heslo peněženky",
"CONFIRM": "Potvrdit heslo k peněžence",
"BUTTON_SELECT": "Vyberte cestu k pěněžence",
"BUTTON_CREATE": "Vytvořit peněženku",
"TITLE_SAVE": "Uložte soubor peněženky.",
"ERROR_CANNOT_SAVE_TOP": "Stávající soubory peněženky nelze nahradit nebo přepsat",
"ERROR_CANNOT_SAVE_SYSTEM": "Soubory peněženky nelze uložit na diskový oddíl s operačním systémem",
"FORM_ERRORS": {
"NAME_REQUIRED": "Name is required",
"NAME_DUPLICATE": "Name is duplicate",
"MAX_LENGTH": "Maximum name length reached",
"NAME_REQUIRED": "Název je povinný",
"NAME_DUPLICATE": "Název je duplicitní",
"MAX_LENGTH": "Dosáhli jste maximální délky názvu",
"CONFIRM_NOT_MATCH": "Confirm password not match"
}
},

View file

@ -1,12 +1,12 @@
{
"LOGIN": {
"SETUP_MASTER_PASS": "Setup master password",
"SETUP_CONFIRM_PASS": "Confirm the password",
"SETUP_CONFIRM_PASS": "Passwort bestätigen",
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_SKIP": "Überspringen",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"INCORRECT_PASSWORD": "Ungültiges Passwort",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",
"CONFIRM_REQUIRED": "Confirmation is required",
@ -32,13 +32,13 @@
},
"SIDEBAR": {
"TITLE": "Wallets",
"ADD_NEW": "+ Add",
"ADD_NEW": "+ Hinzufügen",
"ACCOUNT": {
"STAKING": "Staking",
"MESSAGES": "New offers/Messages",
"SYNCING": "Syncing wallet"
},
"SETTINGS": "Settings",
"SETTINGS": "Einstellungen",
"LOG_OUT": "Log out",
"SYNCHRONIZATION": {
"OFFLINE": "Offline",
@ -51,11 +51,11 @@
"UPDATE": {
"STANDARD": "Update available",
"STANDARD_TOOLTIP": "<span class=\"standard-update\">Get new update.</span><br><span>Update is recommended!</span>",
"IMPORTANT": "Update available",
"IMPORTANT": "Update verfügbar",
"IMPORTANT_HINT": "Important update!",
"IMPORTANT_TOOLTIP": "<span class=\"important-update\">Get new update.</span><br><span>Important update!</span>",
"CRITICAL": "Update available",
"CRITICAL_HINT": "Critical update!",
"CRITICAL": "Update verfügbar",
"CRITICAL_HINT": "Kritisches Update!",
"CRITICAL_TOOLTIP": "<span class=\"critical-update\">Critical update available.</span><i class=\"icon\"></i><span>Update strongly recommended!</span>",
"TIME": "System time differs from network",
"TIME_TOOLTIP": "<span class=\"wrong-time\">Wrong system time!</span><br><span>Check and repair your system time.</span>"
@ -80,7 +80,7 @@
"ERROR_CANNOT_SAVE_SYSTEM": "Wallet files cannot be saved to the OS partition",
"FORM_ERRORS": {
"NAME_REQUIRED": "Name is required",
"NAME_DUPLICATE": "Name is duplicate",
"NAME_DUPLICATE": "Name existiert bereits",
"MAX_LENGTH": "Maximum name length reached",
"CONFIRM_NOT_MATCH": "Confirm password not match"
}
@ -88,20 +88,20 @@
"OPEN_WALLET": {
"NAME": "Wallet name",
"PASS": "Wallet password",
"BUTTON": "Open wallet",
"BUTTON": "Wallet öffnen",
"WITH_ADDRESS_ALREADY_OPEN": "A wallet with this address is already open",
"FILE_NOT_FOUND1": "Wallet file not found",
"FILE_NOT_FOUND2": "<br/><br/> It might have been renamed or moved. <br/> To open it, use the \"Open wallet\" button.",
"FORM_ERRORS": {
"NAME_REQUIRED": "Name is required",
"NAME_DUPLICATE": "Name is duplicate",
"NAME_DUPLICATE": "Name existiert bereits",
"MAX_LENGTH": "Maximum name length reached"
},
"MODAL": {
"TITLE": "Type wallet password",
"LABEL": "Password to this wallet",
"OPEN": "Open wallet",
"SKIP": "Skip",
"SKIP": "Überspringen",
"NOT_FOUND": "Not found"
}
},
@ -116,7 +116,7 @@
"CHOOSE_PATH": "Please choose a path",
"FORM_ERRORS": {
"NAME_REQUIRED": "Name is required",
"NAME_DUPLICATE": "Name is duplicate",
"NAME_DUPLICATE": "Name existiert bereits",
"MAX_LENGTH": "Maximum name length reached",
"CONFIRM_NOT_MATCH": "Confirm password not match",
"KEY_REQUIRED": "Key is required",
@ -149,7 +149,7 @@
"MASTER_PASSWORD": {
"TITLE": "Update master password",
"OLD": "Old password",
"NEW": "New password",
"NEW": "Neues Passwort",
"CONFIRM": "New password confirmation",
"BUTTON": "Save"
},
@ -169,7 +169,7 @@
"LOCKED_BALANCE": "Locked <b>{{locked}} {{currency}}<b/>",
"LOCKED_BALANCE_LINK": "What does that mean?",
"TABS": {
"SEND": "Send",
"SEND": "Senden",
"RECEIVE": "Receive",
"HISTORY": "History",
"CONTRACTS": "Contracts",
@ -266,7 +266,7 @@
"BUTTON": "Send",
"SUCCESS_SENT": "Transaction sent",
"FORM_ERRORS": {
"ADDRESS_REQUIRED": "Address is required",
"ADDRESS_REQUIRED": "Adresse benötigt",
"ADDRESS_NOT_VALID": "Address not valid",
"ALIAS_NOT_VALID": "Alias not valid",
"AMOUNT_REQUIRED": "Amount is required",

View file

@ -38,6 +38,7 @@
"MESSAGES": "New offers/Messages",
"SYNCING": "Syncing wallet"
},
"CONTACTS": "Contacts",
"SETTINGS": "Settings",
"LOG_OUT": "Log out",
"SYNCHRONIZATION": {
@ -192,18 +193,17 @@
},
"ASSIGN_ALIAS": {
"NAME": {
"LABEL": "Unique name",
"LABEL": "Alias",
"PLACEHOLDER": "@ Enter alias",
"TOOLTIP": "An alias is a shortened form or your account. An alias can only include Latin letters, numbers and characters “.” and “-”. It must start with “@”."
},
"COMMENT": {
"LABEL": "Comment",
"PLACEHOLDER": "Enter comment",
"PLACEHOLDER": "",
"TOOLTIP": "The comment will be visible to anyone who wants to make a payment to your alias. You can provide details about your business, contacts, or include any text. Comments can be edited later."
},
"COST": "Cost to create alias {{value}} {{currency}}",
"COST": "Alias fee {{value}} {{currency}}",
"BUTTON_ASSIGN": "Assign",
"BUTTON_CANCEL": "Cancel",
"FORM_ERRORS": {
"NAME_REQUIRED": "Name is required",
"NAME_WRONG": "Alias has wrong name",
@ -217,40 +217,39 @@
},
"EDIT_ALIAS": {
"NAME": {
"LABEL": "Unique name",
"LABEL": "Alias",
"PLACEHOLDER": "@ Enter alias"
},
"COMMENT": {
"LABEL": "Comment",
"PLACEHOLDER": "Enter comment"
"PLACEHOLDER": ""
},
"FORM_ERRORS": {
"NO_MONEY": "You do not have enough funds to change the comment to this alias",
"MAX_LENGTH": "Maximum comment length reached"
},
"COST": "Cost to edit alias {{value}} {{currency}}",
"BUTTON_EDIT": "Edit",
"BUTTON_CANCEL": "Cancel"
"COST": "Fee {{value}} {{currency}}",
"BUTTON_EDIT": "Edit"
},
"TRANSFER_ALIAS": {
"NAME": {
"LABEL": "Unique name",
"LABEL": "Alias",
"PLACEHOLDER": "@ Enter alias"
},
"COMMENT": {
"LABEL": "Comment",
"PLACEHOLDER": "Enter comment"
"PLACEHOLDER": ""
},
"ADDRESS": {
"LABEL": "The account to which the alias will be transferred",
"PLACEHOLDER": "Enter wallet address"
"LABEL": "Transfer to",
"PLACEHOLDER": ""
},
"FORM_ERRORS": {
"WRONG_ADDRESS": "No wallet with this account exists",
"ALIAS_EXISTS": "This account already has an alias",
"NO_MONEY": "You do not have enough funds to transfer this alias"
},
"COST": "Cost to transfer alias {{value}} {{currency}}",
"COST": "Transfer fee {{value}} {{currency}}",
"BUTTON_TRANSFER": "Transfer",
"BUTTON_CANCEL": "Cancel",
"REQUEST_SEND_REG": "The alias will be transferred within 10 minutes"
@ -453,6 +452,17 @@
"INFO": "Information",
"OK": "OK"
},
"CONFIRM": {
"BUTTON_CONFIRM": "Send",
"BUTTON_CANCEL": "Cancel",
"TITLE": "Confirm transaction",
"MESSAGE": {
"SEND": "Send",
"FROM": "From",
"TO": "To",
"COMMENT": "Comment"
}
},
"STAKING": {
"TITLE": "Staking",
"TITLE_PENDING": "Pending",
@ -478,6 +488,55 @@
"OFF": "OFF"
}
},
"CONTACTS": {
"TITLE": "Contact list",
"IMPORT_EXPORT": "Import or export contacts",
"IMPORT": "Import",
"EXPORT": "Export",
"ADD": "Add/edit contact",
"SEND": "Send",
"SEND_FROM": "Send from",
"SEND_TO": "To",
"OPEN_ADD_WALLET": "Open/Add wallet",
"COPY": "- Copy"
, "TABLE": {
"NAME": "Name",
"ALIAS": "Alias",
"ADDRESS": "Address",
"NOTES": "Notes",
"EMPTY": "Contact list is empty"
},
"FORM": {
"NAME": "Name",
"ADDRESS": "Address",
"NOTES": "Notes"
},
"FORM_ERRORS": {
"NAME_REQUIRED": "Name is required",
"NAME_DUBLICATED": "Name is dublicated",
"ADDRESS_REQUIRED": "Address is required",
"ADDRESS_NOT_VALID": "Address not valid",
"SET_MASTER_PASSWORD": "Set master password",
"ADDRESS_DUBLICATED": "Address is dublicated",
"MAX_LENGTH": "Maximum notes length reached",
"NAME_WRONG": "Contact has wrong name",
"NAME_LENGTH": "The name must be 4-25 characters long"
},
"BUTTON": {
"SEND": "Send",
"EDIT": "Edit",
"DELETE": "Delete",
"ADD": "Add contact",
"ADD_EDIT": "Add/Save",
"GO_TO_WALLET": "Go to wallet",
"IMPORT_EXPORT": "Import/export"
},
"SUCCESS_SENT": "Contact added",
"SUCCESS_SAVE": "Contact is edited",
"SUCCESS_IMPORT": "Contacts is imported",
"ERROR_IMPORT": "Error is occured while reading file!",
"ERROR_TYPE_FILE": "Please import valid .csv file."
},
"ERRORS": {
"NO_MONEY": "Not enough money",
"NOT_ENOUGH_MONEY": "Insufficient funds in account",

View file

@ -1,477 +1,477 @@
{
"LOGIN": {
"SETUP_MASTER_PASS": "Setup master password",
"SETUP_CONFIRM_PASS": "Confirm the password",
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"SETUP_MASTER_PASS": "Configurer le mot de passe principal",
"SETUP_CONFIRM_PASS": "Confirmer le mot de passe",
"MASTER_PASS": "Mot de passe principal",
"BUTTON_NEXT": "Suivant",
"BUTTON_SKIP": "Sauter",
"BUTTON_RESET": "Réinitialiser",
"INCORRECT_PASSWORD": "Mot de passe invalide",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",
"CONFIRM_REQUIRED": "Confirmation is required",
"MISMATCH": "Mismatch"
"PASS_REQUIRED": "Mot de passe requis",
"CONFIRM_REQUIRED": "Confirmation requise",
"MISMATCH": "Non-concordant"
}
},
"COMMON": {
"BACK": "Go back"
"BACK": "Retour"
},
"BREADCRUMBS": {
"ADD_WALLET": "Add wallet",
"CREATE_WALLET": "Create new wallet",
"SAVE_PHRASE": "Save your seed phrase",
"OPEN_WALLET": "Open existing wallet",
"RESTORE_WALLET": "Restore from backup",
"WALLET_DETAILS": "Wallet details",
"ASSIGN_ALIAS": "Assign alias",
"EDIT_ALIAS": "Edit alias",
"TRANSFER_ALIAS": "Transfer alias",
"CONTRACTS": "Contracts",
"NEW_PURCHASE": "New purchase",
"OLD_PURCHASE": "Purchase"
"ADD_WALLET": "Ajouter un portefeuille",
"CREATE_WALLET": "Créer un nouveau portefeuille",
"SAVE_PHRASE": "Enregistrer votre phrase de sécurité",
"OPEN_WALLET": "Ouvrir un portefeuille existant",
"RESTORE_WALLET": "Restaurer depuis une sauvegarde",
"WALLET_DETAILS": "Détails du portefeuille",
"ASSIGN_ALIAS": "Assigner un alias",
"EDIT_ALIAS": "Modifier l'alias",
"TRANSFER_ALIAS": "Transférer l'alias",
"CONTRACTS": "Contrats",
"NEW_PURCHASE": "Nouvel achat",
"OLD_PURCHASE": "Achat"
},
"SIDEBAR": {
"TITLE": "Wallets",
"ADD_NEW": "+ Add",
"TITLE": "Portefeuilles",
"ADD_NEW": "+ Ajouter",
"ACCOUNT": {
"STAKING": "Staking",
"MESSAGES": "New offers/Messages",
"SYNCING": "Syncing wallet"
"STAKING": "Mise",
"MESSAGES": "Nouvelles offres/Messages",
"SYNCING": "Synchronisation du portefeuille"
},
"SETTINGS": "Settings",
"LOG_OUT": "Log out",
"SETTINGS": "Paramètres",
"LOG_OUT": "Déconnexion",
"SYNCHRONIZATION": {
"OFFLINE": "Offline",
"ONLINE": "Online",
"ERROR": "System error",
"COMPLETE": "Completion",
"SYNCING": "Syncing blockchain",
"LOADING": "Loading blockchain data"
"OFFLINE": "Hors ligne",
"ONLINE": "En ligne",
"ERROR": "Erreur de système",
"COMPLETE": "Fermeture",
"SYNCING": "Synchronisation de la blockchain",
"LOADING": "Chargement des données de la blockchain"
},
"UPDATE": {
"STANDARD": "Update available",
"STANDARD_TOOLTIP": "<span class=\"standard-update\">Get new update.</span><br><span>Update is recommended!</span>",
"IMPORTANT": "Update available",
"IMPORTANT_HINT": "Important update!",
"IMPORTANT_TOOLTIP": "<span class=\"important-update\">Get new update.</span><br><span>Important update!</span>",
"CRITICAL": "Update available",
"CRITICAL_HINT": "Critical update!",
"CRITICAL_TOOLTIP": "<span class=\"critical-update\">Critical update available.</span><i class=\"icon\"></i><span>Update strongly recommended!</span>",
"TIME": "System time differs from network",
"TIME_TOOLTIP": "<span class=\"wrong-time\">Wrong system time!</span><br><span>Check and repair your system time.</span>"
"STANDARD": "Mise à jour disponible",
"STANDARD_TOOLTIP": "<span class=\"standard-update\">Mise à jour.</span><br><span>La mise à jour est recommandée.</span>",
"IMPORTANT": "Mise à jour disponible",
"IMPORTANT_HINT": "Mise à jour importante !",
"IMPORTANT_TOOLTIP": "<span class=\"important-update\">Mise à jour.</span><br><span>La mise à jour est recommandée.</span>",
"CRITICAL": "Mise à jour disponible",
"CRITICAL_HINT": "Mise à jour critique !",
"CRITICAL_TOOLTIP": "<span class=\"critical-update\">Mise à jour critique disponible.</span><i class=\"icon\"></i><span>Mise à jour fortement recommandée.</span>",
"TIME": "Le temps du système diffère de celui du réseau",
"TIME_TOOLTIP": "<span class=\"wrong-time\">Mauvais temps de système</span><br><span>Vérifier et corriger votre temps de système.</span>"
}
},
"MAIN": {
"TITLE": "Create or open the wallet to start using Zano",
"BUTTON_NEW_WALLET": "Create new wallet",
"BUTTON_OPEN_WALLET": "Open existing wallet",
"BUTTON_RESTORE_BACKUP": "Restore from backup",
"HELP": "How to create wallet?",
"CHOOSE_PATH": "Please choose a path"
"TITLE": "Créer ou ouvrir le portefeuille pour commencer à utiliser Zano",
"BUTTON_NEW_WALLET": "Créer un nouveau portefeuille",
"BUTTON_OPEN_WALLET": "Ouvrir un portefeuille existant",
"BUTTON_RESTORE_BACKUP": "Restaurer depuis une sauvegarde",
"HELP": "Comment créer un portefeuille ?",
"CHOOSE_PATH": "Veuillez choisir un chemin"
},
"CREATE_WALLET": {
"NAME": "Wallet name",
"PASS": "Set wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",
"BUTTON_CREATE": "Create wallet",
"TITLE_SAVE": "Save the wallet file.",
"ERROR_CANNOT_SAVE_TOP": "Existing wallet files cannot be replaced or overwritten",
"ERROR_CANNOT_SAVE_SYSTEM": "Wallet files cannot be saved to the OS partition",
"NAME": "Nom du portefeuille",
"PASS": "Définir le mot de passe du portefeuille",
"CONFIRM": "Confirmer le mot de passe du portefeuille",
"BUTTON_SELECT": "Sélectionner l'emplacement du portefeuille",
"BUTTON_CREATE": "Créer un portefeuille",
"TITLE_SAVE": "Enregistrer le fichier du portefeuille.",
"ERROR_CANNOT_SAVE_TOP": "Les fichiers de portefeuille existants ne peuvent pas être remplacés ou écrasés",
"ERROR_CANNOT_SAVE_SYSTEM": "Les fichiers de portefeuille ne peuvent pas être sauvegardés sur la partition du OS",
"FORM_ERRORS": {
"NAME_REQUIRED": "Name is required",
"NAME_DUPLICATE": "Name is duplicate",
"MAX_LENGTH": "Maximum name length reached",
"CONFIRM_NOT_MATCH": "Confirm password not match"
"NAME_REQUIRED": "Le nom est requis",
"NAME_DUPLICATE": "Nom déjà utilisé",
"MAX_LENGTH": "Longueur maximale du nom atteinte",
"CONFIRM_NOT_MATCH": "La confirmation du mot de passe ne correspond pas"
}
},
"OPEN_WALLET": {
"NAME": "Wallet name",
"PASS": "Wallet password",
"BUTTON": "Open wallet",
"WITH_ADDRESS_ALREADY_OPEN": "A wallet with this address is already open",
"FILE_NOT_FOUND1": "Wallet file not found",
"FILE_NOT_FOUND2": "<br/><br/> It might have been renamed or moved. <br/> To open it, use the \"Open wallet\" button.",
"NAME": "Nom du portefeuille",
"PASS": "Mot de passe du portefeuille",
"BUTTON": "Ouvrir un portefeuille",
"WITH_ADDRESS_ALREADY_OPEN": "Un portefeuille avec cette adresse est déjà ouvert",
"FILE_NOT_FOUND1": "Fichier de portefeuille introuvable",
"FILE_NOT_FOUND2": "<br/><br/> Il aurait peut-être été renommé ou déplacé. <br/> Pour l'ouvrir, utilisez le bouton \"Ouvrir le portefeuille\".",
"FORM_ERRORS": {
"NAME_REQUIRED": "Name is required",
"NAME_DUPLICATE": "Name is duplicate",
"MAX_LENGTH": "Maximum name length reached"
"NAME_REQUIRED": "Le nom est requis",
"NAME_DUPLICATE": "Nom déjà utilisé",
"MAX_LENGTH": "Longueur maximale du nom atteinte"
},
"MODAL": {
"TITLE": "Type wallet password",
"LABEL": "Password to this wallet",
"OPEN": "Open wallet",
"SKIP": "Skip",
"NOT_FOUND": "Not found"
"TITLE": "Entrer le mot de passe du portefeuille",
"LABEL": "Mot de passe de ce portefeuille",
"OPEN": "Ouvrir un portefeuille",
"SKIP": "Sauter",
"NOT_FOUND": "Introuvable"
}
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",
"BUTTON_CREATE": "Create wallet",
"NOT_CORRECT_FILE_OR_PASSWORD": "Invalid wallet file or password does not match",
"CHOOSE_PATH": "Please choose a path",
"LABEL_NAME": "Nom du portefeuille",
"LABEL_PHRASE_KEY": "Phrase de sécurité / clé privée",
"PASS": "Mot de passe du portefeuille",
"CONFIRM": "Confirmer le mot de passe du portefeuille",
"BUTTON_SELECT": "Sélectionner l'emplacement du portefeuille",
"BUTTON_CREATE": "Créer un portefeuille",
"NOT_CORRECT_FILE_OR_PASSWORD": "Le fichier est invalide ou mot de passe du portefeuille ne correspond pas",
"CHOOSE_PATH": "Veuillez choisir un chemin",
"FORM_ERRORS": {
"NAME_REQUIRED": "Name is required",
"NAME_DUPLICATE": "Name is duplicate",
"MAX_LENGTH": "Maximum name length reached",
"CONFIRM_NOT_MATCH": "Confirm password not match",
"KEY_REQUIRED": "Key is required",
"KEY_NOT_VALID": "Key not valid"
"NAME_REQUIRED": "Le nom est requis",
"NAME_DUPLICATE": "Nom déjà utilisé",
"MAX_LENGTH": "Longueur maximale atteinte",
"CONFIRM_NOT_MATCH": "La confirmation du mot de passe ne correspond pas",
"KEY_REQUIRED": "Clé requise",
"KEY_NOT_VALID": "Clé invalide"
}
},
"SEED_PHRASE": {
"TITLE": "Make sure to keep your seed phrase in a safe place. If you forget your seed phrase you will not be able to recover your wallet.",
"BUTTON_CREATE_ACCOUNT": "Create wallet",
"BUTTON_COPY": "Copy"
"TITLE": "Assurez-vous de garder votre phrase de sécurité dans un endroit sûr. Si vous oubliez votre phrase de sécurité, vous ne pourrez pas récupérer votre portefeuille.",
"BUTTON_CREATE_ACCOUNT": "Créer un portefeuille",
"BUTTON_COPY": "Copier"
},
"PROGRESS": {
"ADD_WALLET": "Add wallet",
"SELECT_LOCATION": "Select wallet location",
"CREATE_WALLET": "Create new wallet",
"RESTORE_WALLET": "Restore from backup"
"ADD_WALLET": "Ajouter un portefeuille",
"SELECT_LOCATION": "Sélectionner l'emplacement du portefeuille",
"CREATE_WALLET": "Créer un nouveau portefeuille",
"RESTORE_WALLET": "Restaurer depuis une sauvegarde"
},
"SETTINGS": {
"TITLE": "Settings",
"DARK_THEME": "Dark theme",
"WHITE_THEME": "White theme",
"GRAY_THEME": "Grey theme",
"TITLE": "Paramètres",
"DARK_THEME": "Thème sombre",
"WHITE_THEME": "Thème blanc",
"GRAY_THEME": "Thème gris",
"APP_LOCK": {
"TITLE": "Lock app after:",
"TITLE": "Verrouiller l'application après :",
"TIME1": "5 min",
"TIME2": "15 min",
"TIME3": "1 hour",
"TIME4": "Never"
"TIME3": "1 heure",
"TIME4": "Jamais"
},
"MASTER_PASSWORD": {
"TITLE": "Update master password",
"OLD": "Old password",
"NEW": "New password",
"CONFIRM": "New password confirmation",
"BUTTON": "Save"
"TITLE": "Mettre à jour le mot de passe principal",
"OLD": "Ancien mot de passe",
"NEW": "Nouveau mot de passe",
"CONFIRM": "Confirmer le mot de passe",
"BUTTON": "Enregistrer"
},
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",
"PASS_NOT_MATCH": "Old password not match",
"CONFIRM_NOT_MATCH": "Confirm password not match"
"PASS_REQUIRED": "Mot de passe requis",
"PASS_NOT_MATCH": "Ancien mot de passe non correspondant",
"CONFIRM_NOT_MATCH": "La confirmation du mot de passe ne correspond pas"
},
"LAST_BUILD": "Current build: {{value}}",
"APP_LOG_TITLE": "Log level:"
"LAST_BUILD": "Version actuelle : {{value}}",
"APP_LOG_TITLE": "Niveau de log :"
},
"WALLET": {
"REGISTER_ALIAS": "Register an alias",
"DETAILS": "Details",
"LOCK": "Lock",
"AVAILABLE_BALANCE": "Available <b>{{available}} {{currency}}<b/>",
"LOCKED_BALANCE": "Locked <b>{{locked}} {{currency}}<b/>",
"LOCKED_BALANCE_LINK": "What does that mean?",
"REGISTER_ALIAS": "Enregistrer un alias",
"DETAILS": "Détails",
"LOCK": "Verrouillage",
"AVAILABLE_BALANCE": "Disponible <b>{{available}} {{currency}}<b/>",
"LOCKED_BALANCE": "Vérouillé<b>{{locked}}{{currency}}<b/>",
"LOCKED_BALANCE_LINK": "Que signifie cela?",
"TABS": {
"SEND": "Send",
"RECEIVE": "Receive",
"HISTORY": "History",
"CONTRACTS": "Contracts",
"SEND": "Envoyer",
"RECEIVE": "Recevoir",
"HISTORY": "Historique",
"CONTRACTS": "Contrats",
"MESSAGES": "Messages",
"STAKING": "Staking"
"STAKING": "Mise"
}
},
"WALLET_DETAILS": {
"LABEL_NAME": "Wallet name",
"LABEL_FILE_LOCATION": "Wallet file location",
"LABEL_SEED_PHRASE": "Seed phrase",
"SEED_PHRASE_HINT": "Click to reveal the seed phrase",
"BUTTON_SAVE": "Save",
"BUTTON_REMOVE": "Close wallet",
"LABEL_NAME": "Nom du portefeuille",
"LABEL_FILE_LOCATION": "Emplacement du fichier de portefeuille",
"LABEL_SEED_PHRASE": "Phrase de sécurité",
"SEED_PHRASE_HINT": "Cliquez pour révéler la phrase de sécurité",
"BUTTON_SAVE": "Enregistrer",
"BUTTON_REMOVE": "Fermer le portefeuille",
"FORM_ERRORS": {
"NAME_REQUIRED": "Name is required",
"NAME_DUPLICATE": "Name is duplicate",
"MAX_LENGTH": "Maximum name length reached"
"NAME_REQUIRED": "Le nom est requis",
"NAME_DUPLICATE": "Nom déjà utilisé",
"MAX_LENGTH": "Longueur maximale atteinte"
}
},
"ASSIGN_ALIAS": {
"NAME": {
"LABEL": "Unique name",
"PLACEHOLDER": "@ Enter alias",
"TOOLTIP": "An alias is a shortened form or your account. An alias can only include Latin letters, numbers and characters “.” and “-”. It must start with “@”."
"LABEL": "Nom unique",
"PLACEHOLDER": "@ Entrer l'alias",
"TOOLTIP": "Un alias est une forme abréviée pour votre compte. Un alias ne peut inclure que des lettres, des chiffres et des caractères latins « » et « - ». Il doit commencer par « @ »."
},
"COMMENT": {
"LABEL": "Comment",
"PLACEHOLDER": "Enter comment",
"TOOLTIP": "The comment will be visible to anyone who wants to make a payment to your alias. You can provide details about your business, contacts, or include any text. Comments can be edited later."
"LABEL": "Commentaire",
"PLACEHOLDER": "Entrez un commentaire",
"TOOLTIP": "Le commentaire sera visible à quiconque souhaite effectuer un paiement à votre alias. Vous pouvez fournir des détails sur votre entreprise, vos informations de contact ou inclure tout texte. Les commentaires peuvent être modifiés plus tard."
},
"COST": "Cost to create alias {{value}} {{currency}}",
"BUTTON_ASSIGN": "Assign",
"BUTTON_CANCEL": "Cancel",
"COST": "Coût pour créer l'alias {{value}} {{currency}}",
"BUTTON_ASSIGN": "Assigner",
"BUTTON_CANCEL": "Annuler",
"FORM_ERRORS": {
"NAME_REQUIRED": "Name is required",
"NAME_WRONG": "Alias has wrong name",
"NAME_LENGTH": "The alias must be 6-25 characters long",
"NAME_EXISTS": "Alias name already exists",
"NO_MONEY": "You do not have enough funds to assign this alias",
"MAX_LENGTH": "Maximum comment length reached"
"NAME_REQUIRED": "Le nom est requis",
"NAME_WRONG": "L'alias a un nom incorrect",
"NAME_LENGTH": "L'alias doit contenir 6-25 caractères",
"NAME_EXISTS": "Alias déjà existant",
"NO_MONEY": "Vous n'avez pas assez de fonds pour assigner cet alias",
"MAX_LENGTH": "Longueur maximale du commentaire atteinte"
},
"ONE_ALIAS": "You can create only one alias per wallet",
"REQUEST_ADD_REG": "The alias will be assigned within 10 minutes"
"ONE_ALIAS": "Vous pouvez créer un seul alias par portefeuille",
"REQUEST_ADD_REG": "L'alias sera assigné dans les 10 prochaines minutes"
},
"EDIT_ALIAS": {
"NAME": {
"LABEL": "Unique name",
"PLACEHOLDER": "@ Enter alias"
"LABEL": "Nom unique",
"PLACEHOLDER": "@ Entrer l'alias"
},
"COMMENT": {
"LABEL": "Comment",
"PLACEHOLDER": "Enter comment"
"LABEL": "Commentaire",
"PLACEHOLDER": "Entrez un commentaire"
},
"FORM_ERRORS": {
"NO_MONEY": "You do not have enough funds to change the comment to this alias",
"MAX_LENGTH": "Maximum comment length reached"
"NO_MONEY": "Vous n'avez pas assez de fonds pour changer le commentaire de cet alias",
"MAX_LENGTH": "Longueur maximale du commentaire atteinte"
},
"COST": "Cost to edit alias {{value}} {{currency}}",
"BUTTON_EDIT": "Edit",
"BUTTON_CANCEL": "Cancel"
"COST": "Coût pour modifier l'alias {{value}} {{currency}}",
"BUTTON_EDIT": "Modifier",
"BUTTON_CANCEL": "Annuler"
},
"TRANSFER_ALIAS": {
"NAME": {
"LABEL": "Unique name",
"PLACEHOLDER": "@ Enter alias"
"LABEL": "Nom unique",
"PLACEHOLDER": "@ Entrer l'alias"
},
"COMMENT": {
"LABEL": "Comment",
"PLACEHOLDER": "Enter comment"
"LABEL": "Commentaire",
"PLACEHOLDER": "Entrez un commentaire"
},
"ADDRESS": {
"LABEL": "The account to which the alias will be transferred",
"PLACEHOLDER": "Enter wallet address"
"LABEL": "Le compte auquel l'alias sera transféré",
"PLACEHOLDER": "Entrez l'adresse du portefeuille"
},
"FORM_ERRORS": {
"WRONG_ADDRESS": "No wallet with this account exists",
"ALIAS_EXISTS": "This account already has an alias",
"NO_MONEY": "You do not have enough funds to transfer this alias"
"WRONG_ADDRESS": "Aucun portefeuille avec ce compte n'existe",
"ALIAS_EXISTS": "Ce compte a déjà un alias",
"NO_MONEY": "Vous n'avez pas assez de fonds pour transférer cet alias"
},
"COST": "Cost to transfer alias {{value}} {{currency}}",
"BUTTON_TRANSFER": "Transfer",
"BUTTON_CANCEL": "Cancel",
"REQUEST_SEND_REG": "The alias will be transferred within 10 minutes"
"COST": "Coût pour transférer l'alias {{value}} {{currency}}",
"BUTTON_TRANSFER": "Transférer",
"BUTTON_CANCEL": "Annuler",
"REQUEST_SEND_REG": "L'alias sera transféré dans les 10 prochaines minutes"
},
"SEND": {
"ADDRESS": "Address",
"AMOUNT": "Amount",
"COMMENT": "Comment",
"DETAILS": "Additional details",
"MIXIN": "Mixin",
"FEE": "Fee",
"HIDE": "Hide your wallet address from recipient",
"BUTTON": "Send",
"SUCCESS_SENT": "Transaction sent",
"ADDRESS": "Adresse",
"AMOUNT": "Montant",
"COMMENT": "Commentaire",
"DETAILS": "Détails supplémentaires",
"MIXIN": "Mélange",
"FEE": "Frais",
"HIDE": "Masquer votre adresse de portefeuille au destinataire",
"BUTTON": "Envoyer",
"SUCCESS_SENT": "Transaction envoyée",
"FORM_ERRORS": {
"ADDRESS_REQUIRED": "Address is required",
"ADDRESS_NOT_VALID": "Address not valid",
"ALIAS_NOT_VALID": "Alias not valid",
"AMOUNT_REQUIRED": "Amount is required",
"AMOUNT_ZERO": "Amount is zero",
"FEE_REQUIRED": "Fee is required",
"FEE_MINIMUM": "Minimum fee: {{fee}}",
"MAX_LENGTH": "Maximum comment length reached"
"ADDRESS_REQUIRED": "Adresse requise",
"ADDRESS_NOT_VALID": "Addresse invalide",
"ALIAS_NOT_VALID": "Alias non valide",
"AMOUNT_REQUIRED": "Le Montant est requis",
"AMOUNT_ZERO": "Le montant est zéro",
"FEE_REQUIRED": "Les frais sont requis",
"FEE_MINIMUM": "Frais minimum : {{fee}}",
"MAX_LENGTH": "Longueur maximale du commentaire atteinte"
}
},
"HISTORY": {
"STATUS": "Status",
"STATUS": "Statut",
"STATUS_TOOLTIP": "Confirmations {{current}}/{{total}}",
"LOCK_TOOLTIP": "Locked till {{date}}",
"SEND": "Sent",
"RECEIVED": "Received",
"LOCK_TOOLTIP": "Verrouillé jusqu'à {{date}}",
"SEND": "Envoyé",
"RECEIVED": "Reçu",
"DATE": "Date",
"AMOUNT": "Amount",
"FEE": "Fee",
"ADDRESS": "Address",
"AMOUNT": "Montant",
"FEE": "Frais",
"ADDRESS": "Adresse",
"DETAILS": {
"PAYMENT_ID": "Payment ID",
"ID": "Transaction ID",
"SIZE": "Transaction size",
"SIZE_VALUE": "{{value}} bytes",
"HEIGHT": "Height",
"PAYMENT_ID": "ID de paiement",
"ID": "ID de transaction",
"SIZE": "Taille de la transaction",
"SIZE_VALUE": "{{value}} octets",
"HEIGHT": "Hauteur",
"CONFIRMATION": "Confirmation",
"INPUTS": "Inputs",
"OUTPUTS": "Outputs",
"COMMENT": "Comment"
"INPUTS": "Entrées",
"OUTPUTS": "Sorties",
"COMMENT": "Commentaire"
},
"TYPE_MESSAGES": {
"HIDDEN": "hidden",
"UNDEFINED": "Undefined",
"COMPLETE_BUYER": "Contract completed",
"COMPLETE_SELLER": "Contract completed",
"CREATE_ALIAS": "Fee for assigning alias",
"UPDATE_ALIAS": "Fee for editing alias",
"POW_REWARD": "POW reward",
"POS_REWARD": "POS reward",
"CREATE_CONTRACT": "Contract proposal",
"PLEDGE_CONTRACT": "Contract deposit",
"NULLIFY_CONTRACT": "Burn deposits",
"PROPOSAL_CANCEL_CONTRACT": "Cancellation request",
"CANCEL_CONTRACT": "Cancel and return deposits"
"HIDDEN": "caché",
"UNDEFINED": "Non défini",
"COMPLETE_BUYER": "Contrat complété",
"COMPLETE_SELLER": "Contrat complété",
"CREATE_ALIAS": "Frais pour assigner l'alias",
"UPDATE_ALIAS": "Frais pour modifier l'alias",
"POW_REWARD": "Récompense POW",
"POS_REWARD": "Récompense POS",
"CREATE_CONTRACT": "Proposition de contrat",
"PLEDGE_CONTRACT": "Dépôt de contrat",
"NULLIFY_CONTRACT": "Brûler les dépôts",
"PROPOSAL_CANCEL_CONTRACT": "Demande d'annulation",
"CANCEL_CONTRACT": "Annuler et retourner les dépôts"
}
},
"CONTRACTS": {
"EMPTY": "No active contracts",
"CONTRACTS": "Contracts",
"PURCHASE": "Purchase",
"SELL": "Sell",
"EMPTY": "Aucun contrat actif",
"CONTRACTS": "Contrats",
"PURCHASE": "Achat",
"SELL": "Vendre",
"DATE": "Date",
"AMOUNT": "Amount",
"STATUS": "Status",
"COMMENTS": "Comments",
"PURCHASE_BUTTON": "New Purchase",
"LISTING_BUTTON": "Create listing",
"AMOUNT": "Montant",
"STATUS": "Statut",
"COMMENTS": "Commentaires",
"PURCHASE_BUTTON": "Nouvel achat",
"LISTING_BUTTON": "Créer une offre",
"TIME_LEFT": {
"REMAINING_LESS_ONE": "Less than an hour to respond",
"REMAINING_ONE": "{{time}} hour remains",
"REMAINING_MANY": "{{time}} hours remain",
"REMAINING_MANY_ALT": "{{time}} hours remain",
"REMAINING_ONE_RESPONSE": "{{time}} hour remains",
"REMAINING_MANY_RESPONSE": "{{time}} hours remain",
"REMAINING_MANY_ALT_RESPONSE": "{{time}} hours remain",
"REMAINING_ONE_WAITING": "Waiting for {{time}} hour",
"REMAINING_MANY_WAITING": "Waiting for {{time}} hours",
"REMAINING_MANY_ALT_WAITING": "Waiting for {{time}} hours"
"REMAINING_LESS_ONE": "Moins d'une heure pour répondre",
"REMAINING_ONE": "{{time}} heure restante",
"REMAINING_MANY": "{{time}} heures restantes",
"REMAINING_MANY_ALT": "{{time}} heures restantes",
"REMAINING_ONE_RESPONSE": "{{time}} heure restante",
"REMAINING_MANY_RESPONSE": "{{time}} heures restantes",
"REMAINING_MANY_ALT_RESPONSE": "{{time}} heures restantes",
"REMAINING_ONE_WAITING": "En attente de {{time}}  heure",
"REMAINING_MANY_WAITING": "En attente de {{time}} heures",
"REMAINING_MANY_ALT_WAITING": "En attente de {{time}} heures"
},
"STATUS_MESSAGES": {
"SELLER": {
"NEW_CONTRACT": "New contract proposal",
"IGNORED": "You ignored contract proposal",
"ACCEPTED": "Contract started",
"WAIT": "Waiting for contract confirmation",
"WAITING_BUYER": "Waiting for delivery",
"COMPLETED": "Contract completed",
"NOT_RECEIVED": "Delivery failed",
"NULLIFIED": "All deposits burned",
"PROPOSAL_CANCEL": "New proposal to cancel contract and return deposits",
"BEING_CANCELLED": "Cancellation in progress",
"CANCELLED": "Contract canceled",
"IGNORED_CANCEL": "You ignored cancellation proposal",
"EXPIRED": "Contract proposal has expired"
"NEW_CONTRACT": "Nouvelle proposition de contrat",
"IGNORED": "Vous avez ignoré la proposition de contrat",
"ACCEPTED": "Contrat démarré",
"WAIT": "En attente de confirmation du contrat",
"WAITING_BUYER": "En attente de livraison",
"COMPLETED": "Contrat terminé",
"NOT_RECEIVED": "Échec de la livraison",
"NULLIFIED": "Tous les dépôts ont été brûlés",
"PROPOSAL_CANCEL": "Nouvelle proposition d'annulation de contrat et retour des dépôts",
"BEING_CANCELLED": "Annulation en cours",
"CANCELLED": "Contrat annulé",
"IGNORED_CANCEL": "Vous avez ignoré la proposition d'annulation",
"EXPIRED": "La proposition de contrat a expiré"
},
"BUYER": {
"WAITING": "Waiting for response",
"IGNORED": "Seller ignored your contract proposal",
"ACCEPTED": "Seller accepted your contract proposal",
"WAIT": "Waiting for deposits confirmation",
"WAITING_SELLER": "Waiting for delivery",
"COMPLETED": "Contract completed",
"NOT_RECEIVED": "Delivery failed",
"NULLIFIED": "All deposits burned",
"WAITING_CANCEL": "Waiting for contract cancellation",
"BEING_CANCELLED": "Cancellation in progress",
"CANCELLED": "Contract canceled",
"IGNORED_CANCEL": "The seller ignored your proposal to cancel the contract",
"EXPIRED": "The contract proposal has expired"
"WAITING": "En attente d'une réponse",
"IGNORED": "Le vendeur a ignoré votre proposition de contrat",
"ACCEPTED": "Le vendeur a accepté votre proposition de contrat",
"WAIT": "En attente de confirmation des dépôts",
"WAITING_SELLER": "En attente de livraison",
"COMPLETED": "Contrat complété",
"NOT_RECEIVED": "Échec de la livraison",
"NULLIFIED": "Tous les dépôts ont été brûlés",
"WAITING_CANCEL": "En attente d'annulation du contrat",
"BEING_CANCELLED": "Annulation en cours",
"CANCELLED": "Contrat annulé",
"IGNORED_CANCEL": "Le vendeur a ignoré votre proposition d'annuler le contrat",
"EXPIRED": "La proposition de contrat a expiré"
}
}
},
"PURCHASE": {
"DESCRIPTION": "Description",
"SELLER": "Seller",
"AMOUNT": "Amount",
"YOUR_DEPOSIT": "Your deposit",
"SELLER_DEPOSIT": "Seller deposit",
"BUYER_DEPOSIT": "Buyer deposit",
"SAME_AMOUNT": "Same amount",
"COMMENT": "Comment",
"DETAILS": "Additional details",
"SEND_BUTTON": "Send",
"SELLER": "Vendeur",
"AMOUNT": "Montant",
"YOUR_DEPOSIT": "Votre dépôt",
"SELLER_DEPOSIT": "Dépôt du vendeur",
"BUYER_DEPOSIT": "Dépôt d'acheteur",
"SAME_AMOUNT": "Montant identique",
"COMMENT": "Commentaire",
"DETAILS": "Détails supplémentaires",
"SEND_BUTTON": "Envoyer",
"FORM_ERRORS": {
"DESC_REQUIRED": "Description required",
"DESC_MAXIMUM": "Maximum field length reached",
"SELLER_REQUIRED": "Address required",
"SELLER_NOT_VALID": "Invalid address",
"ALIAS_NOT_VALID": "Invalid alias",
"AMOUNT_REQUIRED": "Amount required",
"AMOUNT_ZERO": "Amount cannot be zero",
"YOUR_DEPOSIT_REQUIRED": "Deposit required",
"SELLER_DEPOSIT_REQUIRED": "Seller deposit required",
"SELLER_SAME": "Use separate account",
"COMMENT_MAXIMUM": "Maximum field length reached"
"DESC_REQUIRED": "Description requise",
"DESC_MAXIMUM": "Longueur maximale du champ atteinte",
"SELLER_REQUIRED": "Adresse requise",
"SELLER_NOT_VALID": "Adresse invalide",
"ALIAS_NOT_VALID": "Alias invalide",
"AMOUNT_REQUIRED": "Montant requis",
"AMOUNT_ZERO": "Le montant ne peut pas être nul",
"YOUR_DEPOSIT_REQUIRED": "Dépôt requis",
"SELLER_DEPOSIT_REQUIRED": "Dépôt de vendeur requis",
"SELLER_SAME": "Utiliser un compte séparé",
"COMMENT_MAXIMUM": "Longueur maximale du champ atteinte"
},
"PROGRESS_NEW": "New purchase",
"PROGRESS_WAIT": "Awaiting reply",
"PROGRESS_RECEIVE": "Reply received",
"PROGRESS_COMPLETE": "Completed",
"FEE": "Fee",
"PAYMENT": "Payment ID",
"PROGRESS_NEW": "Nouvel achat",
"PROGRESS_WAIT": "En attente d'une réponse",
"PROGRESS_RECEIVE": "Réponse reçue",
"PROGRESS_COMPLETE": "Complété",
"FEE": "Frais",
"PAYMENT": "ID de paiement",
"STATUS_MESSAGES": {
"NEW_PURCHASE": "New purchase",
"WAITING_SELLER": "Waiting for response",
"WAITING_BUYER": "Contract proposal received",
"WAITING_CONFIRMATION": "Waiting for deposits confirmation",
"WAITING_DELIVERY": "Waiting for delivery",
"COMPLETED": "Contract completed",
"IGNORED_BUYER": "Contract proposal ignored",
"IGNORED_SELLER": "The seller ignored your contract proposal",
"PROPOSAL_CANCEL_SELLER": "Cancellation request sent",
"PROPOSAL_CANCEL_BUYER": "Cancellation request received",
"BEING_CANCELLED": "Cancellation in progress",
"IGNORED_CANCEL_SELLER": "The seller ignored your proposal to cancel the contract",
"IGNORED_CANCEL_BUYER": "Contract cancellation proposal ignored",
"CANCELLED": "Contract canceled",
"EXPIRED": "Contract proposal expired",
"NOT_RECEIVED": "Delivery failed",
"NULLIFIED": "All deposits burned"
"NEW_PURCHASE": "Nouvel achat",
"WAITING_SELLER": "En attente d'une réponse",
"WAITING_BUYER": "Proposition de contrat reçue",
"WAITING_CONFIRMATION": "En attente de confirmation des dépôts",
"WAITING_DELIVERY": "En attente de livraison",
"COMPLETED": "Contrat complété",
"IGNORED_BUYER": "Proposition de contrat ignorée",
"IGNORED_SELLER": "Le vendeur a ignoré votre proposition de contrat",
"PROPOSAL_CANCEL_SELLER": "Demande d'annulation envoyée",
"PROPOSAL_CANCEL_BUYER": "Demande d'annulation reçue",
"BEING_CANCELLED": "Annulation en cours",
"IGNORED_CANCEL_SELLER": "Le vendeur a ignoré votre proposition d'annuler le contrat",
"IGNORED_CANCEL_BUYER": "Proposition d'annulation du contrat ignorée",
"CANCELLED": "Contrat annulé",
"EXPIRED": "Proposition de contrat expirée",
"NOT_RECEIVED": "Échec de la livraison",
"NULLIFIED": "Tous les dépôts ont été brûlés"
},
"ACCEPT_STATE_WAIT_BIG": "Contract started",
"IGNORED_ACCEPT": "Contract proposal ignored",
"BURN_PROPOSAL": "Deposits burned",
"SUCCESS_FINISH_PROPOSAL": "Contract completed",
"SEND_CANCEL_PROPOSAL": "Cancellation request sent",
"IGNORED_CANCEL": "Contract cancellation proposal ignored",
"DEALS_CANCELED_WAIT": "Cancellation in progress",
"WAITING_TIME": "Response time",
"NEED_MONEY": "Insufficient funds",
"BUTTON_MAKE_PLEDGE": "Accept and make deposit",
"BUTTON_IGNORE": "Ignore and hide offer",
"BUTTON_NULLIFY": "Terminate and burn deposits",
"BUTTON_RECEIVED": "Complete and release deposits",
"BUTTON_CANCEL_BUYER": "Cancel and return deposits",
"BUTTON_NOT_CANCEL": "Ignore request",
"BUTTON_CANCEL_SELLER": "Confirm and return deposits",
"HOUR": "hour",
"HOURS": "hours",
"CANCEL": "Cancel",
"NULLIFY_QUESTION": "Are you sure you want to burn both deposits?",
"BUTTON_NULLIFY_SHORT": "Burn",
"WAITING_TIME_QUESTION": "Are you sure you want to cancel the contract?"
"ACCEPT_STATE_WAIT_BIG": "Contrat débuté",
"IGNORED_ACCEPT": "Proposition de contrat ignorée",
"BURN_PROPOSAL": "Dépositions brûlées",
"SUCCESS_FINISH_PROPOSAL": "Contrat complété",
"SEND_CANCEL_PROPOSAL": "Demande d'annulation envoyée",
"IGNORED_CANCEL": "Proposition d'annulation du contrat ignorée",
"DEALS_CANCELED_WAIT": "Annulation en cours",
"WAITING_TIME": "Heure de réponse",
"NEED_MONEY": "Fonds insuffisants",
"BUTTON_MAKE_PLEDGE": "Accepter et effectuer un dépôt",
"BUTTON_IGNORE": "Ignorer et cacher l'offre",
"BUTTON_NULLIFY": "Terminer et brûler les dépôts",
"BUTTON_RECEIVED": "Compléter et libérer les dépôts",
"BUTTON_CANCEL_BUYER": "Annuler et retourner les dépôts",
"BUTTON_NOT_CANCEL": "Ignorer la requête",
"BUTTON_CANCEL_SELLER": "Confirmer et retourner les dépôts",
"HOUR": "heure",
"HOURS": "heures",
"CANCEL": "Annuler",
"NULLIFY_QUESTION": "Êtes-vous sûr de vouloir brûler les deux dépôts ?",
"BUTTON_NULLIFY_SHORT": "Brûler",
"WAITING_TIME_QUESTION": "Êtes-vous sûr de vouloir annuler le contrat ?"
},
"MESSAGES": {
"ADDRESS": "Address",
"ADDRESS": "Adresse",
"MESSAGE": "Message",
"SEND_PLACEHOLDER": "Type a message...",
"SEND_BUTTON": "Send"
"SEND_PLACEHOLDER": "Tapez un message...",
"SEND_BUTTON": "Envoyer"
},
"MODALS": {
"ERROR": "Error",
"SUCCESS": "Success",
"ERROR": "Erreur",
"SUCCESS": "Succès",
"INFO": "Information",
"OK": "OK"
},
"STAKING": {
"TITLE": "Staking",
"TITLE_PENDING": "Pending",
"TITLE": "Mise",
"TITLE_PENDING": "En attente",
"TITLE_TOTAL": "Total",
"TITLE_PERIOD": "Time period:",
"TITLE_PERIOD": "Période de temps:",
"PERIOD": {
"WEEK1": "1 week",
"WEEK2": "2 week",
"MONTH1": "1 month",
"MONTH3": "3 month",
"MONTH6": "6 month",
"YEAR": "1 year",
"ALL": "All"
"WEEK1": "1 semaine",
"WEEK2": "2 semaines",
"MONTH1": "1 mois",
"MONTH3": "3 mois",
"MONTH6": "6 mois",
"YEAR": "1 an",
"ALL": "Tout"
},
"TITLE_GROUP": "Group:",
"TITLE_GROUP": "Groupe :",
"GROUP": {
"DAY": "day",
"WEEK": "week",
"MONTH": "month"
"DAY": "jour",
"WEEK": "semaine",
"MONTH": "mois"
},
"SWITCH": {
"ON": "ON",
@ -479,47 +479,47 @@
}
},
"ERRORS": {
"NO_MONEY": "Not enough money",
"NOT_ENOUGH_MONEY": "Insufficient funds in account",
"CORE_BUSY": "Internal error: core is busy",
"DAEMON_BUSY": "Internal error: daemon is busy",
"NO_MONEY_REMOVE_OFFER": "There is no fee for deleting an offer, but in order to protect the network against flood transactions you need to have at least {{fee}} {{currency}} in your wallet",
"NOT_ENOUGH_OUTPUTS_TO_MIX": "Mix-in number is too big for current blockchain state. There are not enough unspent outputs to mix with",
"TRANSACTION_IS_TO_BIG": "Transaction exceeds network limit, send required amount with multiple transactions",
"TRANSFER_ATTEMPT": "There is no connection to Zano network",
"ACCESS_DENIED": "Access denied",
"TRANSACTION_ERROR": "Error. Transaction not completed.",
"BAD_ARG": "Invalid argument",
"WALLET_WRONG_ID": "Invalid wallet ID",
"WRONG_PASSWORD": "Invalid password",
"FILE_RESTORED": "The wallet file was corrupted. We have recovered the keys and the wallet from the blockchain",
"FILE_NOT_FOUND": "File not found",
"FILE_EXIST": "A file with that name already exists. Enter another name to save the file under",
"FILE_NOT_SAVED": "You cannot save a wallet file in this folder. Please choose another folder.",
"TX_TYPE_NORMAL": "Error. The payment from the wallet",
"TX_TYPE_NORMAL_TO": "to",
"TX_TYPE_NORMAL_END": "was not completed.",
"TX_TYPE_NEW_ALIAS": "Error. Failed to register alias to safe",
"TX_TYPE_NEW_ALIAS_END": "Please try again.",
"TX_TYPE_UPDATE_ALIAS": "Error. Failed to change comment to alias in safe",
"TX_TYPE_COIN_BASE": "Error. The payment was not completed."
"NO_MONEY": "Pas assez de fonds",
"NOT_ENOUGH_MONEY": "Fonds insuffisants dans le compte",
"CORE_BUSY": "Erreur interne : le noyau est occupé",
"DAEMON_BUSY": "Erreur interne : le daemon est occupé",
"NO_MONEY_REMOVE_OFFER": "Il n'y a pas de frais pour supprimer une offre, mais pour protéger le réseau contre les transactions de spam, vous devez avoir au moins {{fee}} {{currency}} dans votre portefeuille",
"NOT_ENOUGH_OUTPUTS_TO_MIX": "Le nombre de mixage est trop grand pour l'état actuel de la blockchain. Il n'y a pas assez de sorties non utilisées pour mélanger avec",
"TRANSACTION_IS_TO_BIG": "La transaction dépasse la limite réseau, envoyez le montant requis avec plusieurs transactions",
"TRANSFER_ATTEMPT": "Il n'y a pas de connexion au réseau Zano",
"ACCESS_DENIED": "Accès refusé",
"TRANSACTION_ERROR": "Erreur. Transaction non complétée.",
"BAD_ARG": "Argument invalide",
"WALLET_WRONG_ID": "ID de portefeuille invalide",
"WRONG_PASSWORD": "Mot de passe invalide",
"FILE_RESTORED": "Le fichier de portefeuille a été corrompu. Nous avons récupéré les clés et le portefeuille de la blockchain",
"FILE_NOT_FOUND": "Fichier introuvable",
"FILE_EXIST": "Un fichier avec ce nom existe déjà. Entrez un autre nom pour enregistrer le fichier sous",
"FILE_NOT_SAVED": "Vous ne pouvez pas enregistrer un fichier de portefeuille dans ce dossier. Veuillez choisir un autre dossier.",
"TX_TYPE_NORMAL": "Erreur. paiement du portefeuille",
"TX_TYPE_NORMAL_TO": "à",
"TX_TYPE_NORMAL_END": "n'a pas été complété.",
"TX_TYPE_NEW_ALIAS": "Erreur. Impossible d'enregistrer l'alias dans la blockchain",
"TX_TYPE_NEW_ALIAS_END": "Veuillez réessayer.",
"TX_TYPE_UPDATE_ALIAS": "Erreur. Impossible de changer le commentaire de l'alias actuel",
"TX_TYPE_COIN_BASE": "Erreur. Le paiement n'a pas été complété."
},
"CONTEXT_MENU": {
"COPY": "copy",
"PASTE": "paste",
"SELECT": "select all"
"COPY": "copier",
"PASTE": "coller",
"SELECT": "tout sélectionner"
},
"BACKEND_LOCALIZATION": {
"QUIT": "Quit",
"QUIT": "Quitter",
"IS_RECEIVED": "",
"IS_CONFIRMED": "",
"INCOME_TRANSFER_UNCONFIRMED": "Incoming payment (not confirmed)",
"INCOME_TRANSFER_CONFIRMED": "Payment received",
"MINED": "Mined",
"LOCKED": "Blocked",
"IS_MINIMIZE": "Zano application is minimized to the system tray",
"RESTORE": "You can recover it by clicking or using the context menu",
"TRAY_MENU_SHOW": "Resize",
"TRAY_MENU_MINIMIZE": "Minimize"
"INCOME_TRANSFER_UNCONFIRMED": "Paiement entrant (non confirmé)",
"INCOME_TRANSFER_CONFIRMED": "Paiement reçu",
"MINED": "Miné",
"LOCKED": "Bloqué",
"IS_MINIMIZE": "L'application Zano est minimisée dans la barre d'état",
"RESTORE": "Vous pouvez le récupérer en cliquant ou en utilisant le menu contextuel",
"TRAY_MENU_SHOW": "Redimensionner",
"TRAY_MENU_MINIMIZE": "Réduire"
}
}

View file

@ -1,287 +1,287 @@
{
"LOGIN": {
"SETUP_MASTER_PASS": "Setup master password",
"SETUP_CONFIRM_PASS": "Confirm the password",
"MASTER_PASS": "Master password",
"BUTTON_NEXT": "Next",
"BUTTON_SKIP": "Skip",
"BUTTON_RESET": "Reset",
"INCORRECT_PASSWORD": "Invalid password",
"SETUP_MASTER_PASS": "Imposta la password generale",
"SETUP_CONFIRM_PASS": "Conferma la password",
"MASTER_PASS": "Password generale",
"BUTTON_NEXT": "Prossimo",
"BUTTON_SKIP": "Salta",
"BUTTON_RESET": "Azzera",
"INCORRECT_PASSWORD": "Password non valida",
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",
"CONFIRM_REQUIRED": "Confirmation is required",
"MISMATCH": "Mismatch"
"PASS_REQUIRED": "La password è necessaria",
"CONFIRM_REQUIRED": "La conferma è richiesta",
"MISMATCH": "Non corrisponde"
}
},
"COMMON": {
"BACK": "Go back"
"BACK": "Torna indietro"
},
"BREADCRUMBS": {
"ADD_WALLET": "Add wallet",
"CREATE_WALLET": "Create new wallet",
"ADD_WALLET": "Aggiungi portafoglio",
"CREATE_WALLET": "Crea un nuovo portafoglio",
"SAVE_PHRASE": "Save your seed phrase",
"OPEN_WALLET": "Open existing wallet",
"RESTORE_WALLET": "Restore from backup",
"WALLET_DETAILS": "Wallet details",
"ASSIGN_ALIAS": "Assign alias",
"EDIT_ALIAS": "Edit alias",
"TRANSFER_ALIAS": "Transfer alias",
"CONTRACTS": "Contracts",
"NEW_PURCHASE": "New purchase",
"OLD_PURCHASE": "Purchase"
"OPEN_WALLET": "Apri portafoglio esistente",
"RESTORE_WALLET": "Ripristina da backup",
"WALLET_DETAILS": "Dettagli portafoglio",
"ASSIGN_ALIAS": "Assegna alias",
"EDIT_ALIAS": "Modifica alias",
"TRANSFER_ALIAS": "Trasferisci alias",
"CONTRACTS": "Contratti",
"NEW_PURCHASE": "Nuovo acquisto",
"OLD_PURCHASE": "Acquisto"
},
"SIDEBAR": {
"TITLE": "Wallets",
"ADD_NEW": "+ Add",
"TITLE": "Portafogli",
"ADD_NEW": "+ Aggiungi",
"ACCOUNT": {
"STAKING": "Staking",
"MESSAGES": "New offers/Messages",
"SYNCING": "Syncing wallet"
"MESSAGES": "Nuove offerte/messaggi",
"SYNCING": "Sincronizzazione portafoglio"
},
"SETTINGS": "Settings",
"LOG_OUT": "Log out",
"SETTINGS": "Impostazioni",
"LOG_OUT": "Esci",
"SYNCHRONIZATION": {
"OFFLINE": "Offline",
"ONLINE": "Online",
"ERROR": "System error",
"ERROR": "Errore di sistema",
"COMPLETE": "Completion",
"SYNCING": "Syncing blockchain",
"SYNCING": "Sincronizzazione blockchain",
"LOADING": "Loading blockchain data"
},
"UPDATE": {
"STANDARD": "Update available",
"STANDARD": "Aggiornamento disponibile",
"STANDARD_TOOLTIP": "<span class=\"standard-update\">Get new update.</span><br><span>Update is recommended!</span>",
"IMPORTANT": "Update available",
"IMPORTANT_HINT": "Important update!",
"IMPORTANT": "Aggiornamento disponibile",
"IMPORTANT_HINT": "Aggiornamento importante!",
"IMPORTANT_TOOLTIP": "<span class=\"important-update\">Get new update.</span><br><span>Important update!</span>",
"CRITICAL": "Update available",
"CRITICAL_HINT": "Critical update!",
"CRITICAL": "Aggiornamento disponibile",
"CRITICAL_HINT": "Aggiornamento critico!",
"CRITICAL_TOOLTIP": "<span class=\"critical-update\">Critical update available.</span><i class=\"icon\"></i><span>Update strongly recommended!</span>",
"TIME": "System time differs from network",
"TIME": "L'orario di sistema differisce dalla rete",
"TIME_TOOLTIP": "<span class=\"wrong-time\">Wrong system time!</span><br><span>Check and repair your system time.</span>"
}
},
"MAIN": {
"TITLE": "Create or open the wallet to start using Zano",
"BUTTON_NEW_WALLET": "Create new wallet",
"BUTTON_OPEN_WALLET": "Open existing wallet",
"BUTTON_RESTORE_BACKUP": "Restore from backup",
"HELP": "How to create wallet?",
"CHOOSE_PATH": "Please choose a path"
"TITLE": "Crea o apri il portafoglio per iniziare a usare Zano",
"BUTTON_NEW_WALLET": "Crea un nuovo portafoglio",
"BUTTON_OPEN_WALLET": "Apri portafoglio esistente",
"BUTTON_RESTORE_BACKUP": "Ripristina da backup",
"HELP": "Come creare il portafoglio?",
"CHOOSE_PATH": "Scegli un percorso"
},
"CREATE_WALLET": {
"NAME": "Wallet name",
"PASS": "Set wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",
"BUTTON_CREATE": "Create wallet",
"TITLE_SAVE": "Save the wallet file.",
"ERROR_CANNOT_SAVE_TOP": "Existing wallet files cannot be replaced or overwritten",
"ERROR_CANNOT_SAVE_SYSTEM": "Wallet files cannot be saved to the OS partition",
"NAME": "Nome del portafoglio",
"PASS": "Imposta password portafoglio",
"CONFIRM": "Conferma password portafoglio",
"BUTTON_SELECT": "Seleziona posizione portafoglio",
"BUTTON_CREATE": "Crea portafoglio",
"TITLE_SAVE": "Salva il file del portafoglio.",
"ERROR_CANNOT_SAVE_TOP": "I file del portafoglio esistenti non possono essere sostituiti o sovrascritti",
"ERROR_CANNOT_SAVE_SYSTEM": "I file del portafoglio non possono essere salvati nella partizione di sistema",
"FORM_ERRORS": {
"NAME_REQUIRED": "Name is required",
"NAME_DUPLICATE": "Name is duplicate",
"MAX_LENGTH": "Maximum name length reached",
"CONFIRM_NOT_MATCH": "Confirm password not match"
"NAME_REQUIRED": "Il nome è richiesto",
"NAME_DUPLICATE": "Il nome è duplicato",
"MAX_LENGTH": "Lunghezza massima del nome raggiunta",
"CONFIRM_NOT_MATCH": "La password di conferma non corrisponde"
}
},
"OPEN_WALLET": {
"NAME": "Wallet name",
"PASS": "Wallet password",
"BUTTON": "Open wallet",
"WITH_ADDRESS_ALREADY_OPEN": "A wallet with this address is already open",
"FILE_NOT_FOUND1": "Wallet file not found",
"FILE_NOT_FOUND2": "<br/><br/> It might have been renamed or moved. <br/> To open it, use the \"Open wallet\" button.",
"NAME": "Nome del portafoglio",
"PASS": "Password portafoglio",
"BUTTON": "Apri portafoglio",
"WITH_ADDRESS_ALREADY_OPEN": "Un portafoglio con questo indirizzo è già aperto",
"FILE_NOT_FOUND1": "File del portafoglio non trovato",
"FILE_NOT_FOUND2": "<br/><br/> Potrebbe essere stato rinominato o spostato. <br/> Per aprirlo, usa il pulsante \"Apri portafoglio\".",
"FORM_ERRORS": {
"NAME_REQUIRED": "Name is required",
"NAME_DUPLICATE": "Name is duplicate",
"MAX_LENGTH": "Maximum name length reached"
"NAME_REQUIRED": "Il nome è richiesto",
"NAME_DUPLICATE": "Il nome è un duplicato",
"MAX_LENGTH": "Lunghezza massima del nome raggiunta"
},
"MODAL": {
"TITLE": "Type wallet password",
"LABEL": "Password to this wallet",
"OPEN": "Open wallet",
"SKIP": "Skip",
"NOT_FOUND": "Not found"
"TITLE": "Imposta password portafoglio",
"LABEL": "Password per questo portafoglio",
"OPEN": "Apri portafoglio",
"SKIP": "Salta",
"NOT_FOUND": "Non trovato"
}
},
"RESTORE_WALLET": {
"LABEL_NAME": "Wallet name",
"LABEL_PHRASE_KEY": "Seed phrase / private key",
"PASS": "Wallet password",
"CONFIRM": "Confirm wallet password",
"BUTTON_SELECT": "Select wallet location",
"BUTTON_CREATE": "Create wallet",
"NOT_CORRECT_FILE_OR_PASSWORD": "Invalid wallet file or password does not match",
"CHOOSE_PATH": "Please choose a path",
"LABEL_NAME": "Nome del portafoglio",
"LABEL_PHRASE_KEY": "Frase segreta / chiave privata",
"PASS": "Password portafoglio",
"CONFIRM": "Conferma password portafoglio",
"BUTTON_SELECT": "Seleziona posizione portafoglio",
"BUTTON_CREATE": "Crea portafoglio",
"NOT_CORRECT_FILE_OR_PASSWORD": "File del portafoglio non valido o password non corrispondente",
"CHOOSE_PATH": "Scegli un percorso",
"FORM_ERRORS": {
"NAME_REQUIRED": "Name is required",
"NAME_DUPLICATE": "Name is duplicate",
"MAX_LENGTH": "Maximum name length reached",
"CONFIRM_NOT_MATCH": "Confirm password not match",
"KEY_REQUIRED": "Key is required",
"KEY_NOT_VALID": "Key not valid"
"NAME_REQUIRED": "Il nome è richiesto",
"NAME_DUPLICATE": "Il nome è un duplicato",
"MAX_LENGTH": "Lunghezza massima del nome raggiunta",
"CONFIRM_NOT_MATCH": "La password di conferma non corrisponde",
"KEY_REQUIRED": "Chiave richiesta",
"KEY_NOT_VALID": "Chiave non valida"
}
},
"SEED_PHRASE": {
"TITLE": "Make sure to keep your seed phrase in a safe place. If you forget your seed phrase you will not be able to recover your wallet.",
"BUTTON_CREATE_ACCOUNT": "Create wallet",
"BUTTON_COPY": "Copy"
"TITLE": "Assicurati di mantenere la tua frase segreta in un posto sicuro. Se dimentichi la tua frase segreta non sarai in grado di recuperare il tuo portafoglio.",
"BUTTON_CREATE_ACCOUNT": "Crea portafoglio",
"BUTTON_COPY": "Copia"
},
"PROGRESS": {
"ADD_WALLET": "Add wallet",
"SELECT_LOCATION": "Select wallet location",
"CREATE_WALLET": "Create new wallet",
"RESTORE_WALLET": "Restore from backup"
"ADD_WALLET": "Aggiungi portafoglio",
"SELECT_LOCATION": "Seleziona posizione portafoglio",
"CREATE_WALLET": "Crea un nuovo portafoglio",
"RESTORE_WALLET": "Ripristina da backup"
},
"SETTINGS": {
"TITLE": "Settings",
"DARK_THEME": "Dark theme",
"WHITE_THEME": "White theme",
"GRAY_THEME": "Grey theme",
"TITLE": "Impostazioni",
"DARK_THEME": "Tema scuro",
"WHITE_THEME": "Tema bianco",
"GRAY_THEME": "Tema grigio",
"APP_LOCK": {
"TITLE": "Lock app after:",
"TIME1": "5 min",
"TIME2": "15 min",
"TIME3": "1 hour",
"TIME4": "Never"
"TITLE": "Blocca app dopo:",
"TIME1": "5 minuti",
"TIME2": "15 minuti",
"TIME3": "1 ora",
"TIME4": "Mai"
},
"MASTER_PASSWORD": {
"TITLE": "Update master password",
"OLD": "Old password",
"NEW": "New password",
"CONFIRM": "New password confirmation",
"BUTTON": "Save"
"TITLE": "Aggiorna password generale",
"OLD": "Vecchia password",
"NEW": "Nuova password",
"CONFIRM": "Conferma nuova password",
"BUTTON": "Salva"
},
"FORM_ERRORS": {
"PASS_REQUIRED": "Password is required",
"PASS_NOT_MATCH": "Old password not match",
"CONFIRM_NOT_MATCH": "Confirm password not match"
"PASS_REQUIRED": "La password è necessaria",
"PASS_NOT_MATCH": "La vecchia password non corrisponde",
"CONFIRM_NOT_MATCH": "La password di conferma non corrisponde"
},
"LAST_BUILD": "Current build: {{value}}",
"APP_LOG_TITLE": "Log level:"
"LAST_BUILD": "Build attuale: {{value}}",
"APP_LOG_TITLE": "Livello di log:"
},
"WALLET": {
"REGISTER_ALIAS": "Register an alias",
"DETAILS": "Details",
"LOCK": "Lock",
"AVAILABLE_BALANCE": "Available <b>{{available}} {{currency}}<b/>",
"LOCKED_BALANCE": "Locked <b>{{locked}} {{currency}}<b/>",
"LOCKED_BALANCE_LINK": "What does that mean?",
"REGISTER_ALIAS": "Registra un alias",
"DETAILS": "Dettagli",
"LOCK": "Blocca",
"AVAILABLE_BALANCE": "Disponibile <b>{{available}} {{currency}}<b/>",
"LOCKED_BALANCE": "Bloccato <b>{{locked}} {{currency}}<b/>",
"LOCKED_BALANCE_LINK": "Che cosa significa?",
"TABS": {
"SEND": "Send",
"RECEIVE": "Receive",
"HISTORY": "History",
"CONTRACTS": "Contracts",
"MESSAGES": "Messages",
"SEND": "Invia",
"RECEIVE": "Ricevi",
"HISTORY": "Storico",
"CONTRACTS": "Contratti",
"MESSAGES": "Messaggi",
"STAKING": "Staking"
}
},
"WALLET_DETAILS": {
"LABEL_NAME": "Wallet name",
"LABEL_FILE_LOCATION": "Wallet file location",
"LABEL_SEED_PHRASE": "Seed phrase",
"SEED_PHRASE_HINT": "Click to reveal the seed phrase",
"BUTTON_SAVE": "Save",
"BUTTON_REMOVE": "Close wallet",
"LABEL_NAME": "Nome portafoglio",
"LABEL_FILE_LOCATION": "Posizione file portafoglio",
"LABEL_SEED_PHRASE": "Frase segreta",
"SEED_PHRASE_HINT": "Clicca per rivelare la frase segreta",
"BUTTON_SAVE": "Salva",
"BUTTON_REMOVE": "Chiudi portafoglio",
"FORM_ERRORS": {
"NAME_REQUIRED": "Name is required",
"NAME_DUPLICATE": "Name is duplicate",
"MAX_LENGTH": "Maximum name length reached"
"NAME_REQUIRED": "Il nome è richiesto",
"NAME_DUPLICATE": "Il nome è un duplicato",
"MAX_LENGTH": "Lunghezza massima del nome raggiunta"
}
},
"ASSIGN_ALIAS": {
"NAME": {
"LABEL": "Unique name",
"PLACEHOLDER": "@ Enter alias",
"TOOLTIP": "An alias is a shortened form or your account. An alias can only include Latin letters, numbers and characters “.” and “-”. It must start with “@”."
"LABEL": "Nome univoco",
"PLACEHOLDER": "@ Inserisci alias",
"TOOLTIP": "Un alias è un modulo abbreviato o il tuo account. Un alias può solo includere lettere latine, numeri e caratteri “.” e “-”. Deve iniziare con “@”."
},
"COMMENT": {
"LABEL": "Comment",
"PLACEHOLDER": "Enter comment",
"TOOLTIP": "The comment will be visible to anyone who wants to make a payment to your alias. You can provide details about your business, contacts, or include any text. Comments can be edited later."
"LABEL": "Commento",
"PLACEHOLDER": "Inserisci commento",
"TOOLTIP": "Il commento sarà visibile a chiunque desideri effettuare un pagamento al tuo alias. Puoi fornire dettagli sul tuo business, contatti o includere qualsiasi testo. I commenti possono essere modificati più tardi."
},
"COST": "Cost to create alias {{value}} {{currency}}",
"BUTTON_ASSIGN": "Assign",
"BUTTON_CANCEL": "Cancel",
"COST": "Costo per creare alias {{value}} {{currency}}",
"BUTTON_ASSIGN": "Assegna",
"BUTTON_CANCEL": "Cancella",
"FORM_ERRORS": {
"NAME_REQUIRED": "Name is required",
"NAME_WRONG": "Alias has wrong name",
"NAME_LENGTH": "The alias must be 6-25 characters long",
"NAME_EXISTS": "Alias name already exists",
"NO_MONEY": "You do not have enough funds to assign this alias",
"MAX_LENGTH": "Maximum comment length reached"
"NAME_REQUIRED": "Il nome è richiesto",
"NAME_WRONG": "L'Alias ha un nome errato",
"NAME_LENGTH": "L'alias deve essere lungo 6-25 caratteri",
"NAME_EXISTS": "Il nome dell'alias esiste già",
"NO_MONEY": "Non hai fondi sufficienti per assegnare questo alias",
"MAX_LENGTH": "Lunghezza massima del nome raggiunta"
},
"ONE_ALIAS": "You can create only one alias per wallet",
"REQUEST_ADD_REG": "The alias will be assigned within 10 minutes"
"ONE_ALIAS": "Puoi creare solo un alias per portafoglio",
"REQUEST_ADD_REG": "L'alias sarà assegnato entro 10 minuti"
},
"EDIT_ALIAS": {
"NAME": {
"LABEL": "Unique name",
"PLACEHOLDER": "@ Enter alias"
"LABEL": "Nome univoco",
"PLACEHOLDER": "@ Inserisci alias"
},
"COMMENT": {
"LABEL": "Comment",
"PLACEHOLDER": "Enter comment"
"LABEL": "Commento",
"PLACEHOLDER": "Inserisci commento"
},
"FORM_ERRORS": {
"NO_MONEY": "You do not have enough funds to change the comment to this alias",
"MAX_LENGTH": "Maximum comment length reached"
"NO_MONEY": "Non hai fondi sufficienti per modificare il commento a questo alias",
"MAX_LENGTH": "Lunghezza massima del commento raggiunta"
},
"COST": "Cost to edit alias {{value}} {{currency}}",
"BUTTON_EDIT": "Edit",
"BUTTON_CANCEL": "Cancel"
"COST": "Costo per modificare alias {{value}} {{currency}}",
"BUTTON_EDIT": "Modifica",
"BUTTON_CANCEL": "Cancella"
},
"TRANSFER_ALIAS": {
"NAME": {
"LABEL": "Unique name",
"PLACEHOLDER": "@ Enter alias"
"LABEL": "Nome univoco",
"PLACEHOLDER": "@ Inserisci alias"
},
"COMMENT": {
"LABEL": "Comment",
"PLACEHOLDER": "Enter comment"
"LABEL": "Commento",
"PLACEHOLDER": "Inserisci commento"
},
"ADDRESS": {
"LABEL": "The account to which the alias will be transferred",
"PLACEHOLDER": "Enter wallet address"
"LABEL": "L'account al quale l'alias verrà trasferito",
"PLACEHOLDER": "Inserisci indirizzo portafoglio"
},
"FORM_ERRORS": {
"WRONG_ADDRESS": "No wallet with this account exists",
"ALIAS_EXISTS": "This account already has an alias",
"NO_MONEY": "You do not have enough funds to transfer this alias"
"WRONG_ADDRESS": "Non esiste alcun portafoglio con questo account",
"ALIAS_EXISTS": "Questo account ha già un alias",
"NO_MONEY": "Non hai fondi sufficienti per trasferire questo alias"
},
"COST": "Cost to transfer alias {{value}} {{currency}}",
"BUTTON_TRANSFER": "Transfer",
"BUTTON_CANCEL": "Cancel",
"REQUEST_SEND_REG": "The alias will be transferred within 10 minutes"
"COST": "Costo per trasferire alias {{value}} {{currency}}",
"BUTTON_TRANSFER": "Trasferisci",
"BUTTON_CANCEL": "Cancella",
"REQUEST_SEND_REG": "L'alias verrà trasferito entro 10 minuti"
},
"SEND": {
"ADDRESS": "Address",
"AMOUNT": "Amount",
"COMMENT": "Comment",
"DETAILS": "Additional details",
"ADDRESS": "Indirizzo",
"AMOUNT": "Importo",
"COMMENT": "Commento",
"DETAILS": "Dettagli aggiuntivi",
"MIXIN": "Mixin",
"FEE": "Fee",
"HIDE": "Hide your wallet address from recipient",
"BUTTON": "Send",
"SUCCESS_SENT": "Transaction sent",
"FEE": "Commissione",
"HIDE": "Nascondi l'indirizzo del tuo portafoglio dal destinatario",
"BUTTON": "Invia",
"SUCCESS_SENT": "Transazione inviata",
"FORM_ERRORS": {
"ADDRESS_REQUIRED": "Address is required",
"ADDRESS_NOT_VALID": "Address not valid",
"ALIAS_NOT_VALID": "Alias not valid",
"AMOUNT_REQUIRED": "Amount is required",
"AMOUNT_ZERO": "Amount is zero",
"FEE_REQUIRED": "Fee is required",
"ADDRESS_REQUIRED": "Indirizzo richiesto",
"ADDRESS_NOT_VALID": "Indirizzo non valido",
"ALIAS_NOT_VALID": "Alias non valido",
"AMOUNT_REQUIRED": "Importo richiesto",
"AMOUNT_ZERO": "Importo è zero",
"FEE_REQUIRED": "La commissione è richiesta",
"FEE_MINIMUM": "Minimum fee: {{fee}}",
"MAX_LENGTH": "Maximum comment length reached"
"MAX_LENGTH": "Lunghezza massima del commento raggiunta"
}
},
"HISTORY": {
"STATUS": "Status",
"STATUS_TOOLTIP": "Confirmations {{current}}/{{total}}",
"LOCK_TOOLTIP": "Locked till {{date}}",
"SEND": "Sent",
"RECEIVED": "Received",
"STATUS_TOOLTIP": "Conferme {{current}}/{{total}}",
"LOCK_TOOLTIP": "Bloccato fino a {{date}}",
"SEND": "Inviato",
"RECEIVED": "Ricevuto",
"DATE": "Date",
"AMOUNT": "Amount",
"FEE": "Fee",
@ -500,7 +500,7 @@
"TX_TYPE_NORMAL_TO": "to",
"TX_TYPE_NORMAL_END": "was not completed.",
"TX_TYPE_NEW_ALIAS": "Error. Failed to register alias to safe",
"TX_TYPE_NEW_ALIAS_END": "Please try again.",
"TX_TYPE_NEW_ALIAS_END": "Per favore riprova.",
"TX_TYPE_UPDATE_ALIAS": "Error. Failed to change comment to alias in safe",
"TX_TYPE_COIN_BASE": "Error. The payment was not completed."
},

View file

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<title>icons_5</title>
<g id="f31d9964-f67b-451c-9eb6-78b833647305">
<path class="st0" d="M299.9,197.6c9.3-16.7,14.2-35.5,14.1-54.6c0-70-43.4-105-97-105s-97,35-97,105c-0.1,19.1,4.8,38,14.2,54.6
C89.2,218.8,68.5,274.1,50,346l334-0.1C365.5,274,344.8,218.8,299.9,197.6z M178.1,94c11.6-11.6,27.6-14,38.9-14s27.3,2.4,38.9,14
c13.3,13.2,16.1,34,16.1,49c0,34.7-24.7,63-55,63s-55-28.3-55-63C162,115.7,170.7,101.3,178.1,94z M128.8,256.5
c10.1-14.3,21.1-22.1,36.1-25c31.4,22,73.1,22,104.5-0.1c14.9,2.9,25.9,10.8,35.9,25c8.9,12.6,16.3,29.3,22.7,47.5L106.1,304
C112.5,285.8,119.9,269.1,128.8,256.5z"/>
<path class="st0" d="M32.5,261H0v42h18.2C23,287,27.6,273.3,32.5,261z"/>
<path class="st0" d="M83,182c-0.9-3.6-1.7-7.3-2.4-11H0v42h56.8C64.2,201.6,73,191.2,83,182z"/>
<path class="st0" d="M88.8,81H0v42h79C80.4,108.6,83.7,94.5,88.8,81z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<path class="st0" d="M371,76H269V14H115v62H13v42h35v266h288V118h35V76z M157,56h70v20h-70V56z M294,342H90V118h204V342z"/>
<rect x="136" y="166" class="st0" width="42" height="128"/>
<rect x="206" y="166" class="st0" width="42" height="128"/>
</svg>

After

Width:  |  Height:  |  Size: 651 B

Some files were not shown because too many files have changed in this diff Show more