New start page and AmneziaFree support (#865)
New start page and AmneziaFree support
5
.github/workflows/deploy.yml
vendored
|
@ -15,6 +15,7 @@ jobs:
|
|||
env:
|
||||
QT_VERSION: 6.6.2
|
||||
QIF_VERSION: 4.7
|
||||
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
|
||||
|
||||
steps:
|
||||
- name: 'Install Qt'
|
||||
|
@ -80,6 +81,7 @@ jobs:
|
|||
QT_VERSION: 6.6.2
|
||||
QIF_VERSION: 4.7
|
||||
BUILD_ARCH: 64
|
||||
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
|
||||
|
||||
steps:
|
||||
- name: 'Get sources'
|
||||
|
@ -141,6 +143,7 @@ jobs:
|
|||
QT_VERSION: 6.6.2
|
||||
CC: cc
|
||||
CXX: c++
|
||||
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
|
||||
|
||||
steps:
|
||||
- name: 'Setup xcode'
|
||||
|
@ -231,6 +234,7 @@ jobs:
|
|||
# Keep compat with MacOS 10.15 aka Catalina by Qt 6.4
|
||||
QT_VERSION: 6.4.3
|
||||
QIF_VERSION: 4.6
|
||||
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
|
||||
|
||||
steps:
|
||||
- name: 'Setup xcode'
|
||||
|
@ -295,6 +299,7 @@ jobs:
|
|||
ANDROID_BUILD_PLATFORM: android-34
|
||||
QT_VERSION: 6.6.2
|
||||
QT_MODULES: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
|
||||
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
|
||||
|
||||
steps:
|
||||
- name: 'Install desktop Qt'
|
||||
|
|
1
.github/workflows/tag-deploy.yml
vendored
|
@ -15,6 +15,7 @@ jobs:
|
|||
env:
|
||||
QT_VERSION: 6.4.1
|
||||
QIF_VERSION: 4.5
|
||||
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
|
||||
|
||||
steps:
|
||||
- name: 'Install desktop Qt'
|
||||
|
|
3
.gitmodules
vendored
|
@ -13,3 +13,6 @@
|
|||
[submodule "client/3rd/amneziawg-apple"]
|
||||
path = client/3rd/amneziawg-apple
|
||||
url = https://github.com/amnezia-vpn/amneziawg-apple
|
||||
[submodule "client/3rd/QSimpleCrypto"]
|
||||
path = client/3rd/QSimpleCrypto
|
||||
url = https://github.com/amnezia-vpn/QSimpleCrypto.git
|
||||
|
|
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
|
|||
|
||||
set(PROJECT AmneziaVPN)
|
||||
|
||||
project(${PROJECT} VERSION 4.6.1.0
|
||||
project(${PROJECT} VERSION 4.7.0.0
|
||||
DESCRIPTION "AmneziaVPN"
|
||||
HOMEPAGE_URL "https://amnezia.org/"
|
||||
)
|
||||
|
@ -11,7 +11,7 @@ string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
|
|||
set(RELEASE_DATE "${CURRENT_DATE}")
|
||||
|
||||
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
||||
set(APP_ANDROID_VERSION_CODE 56)
|
||||
set(APP_ANDROID_VERSION_CODE 57)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
set(MZ_PLATFORM_NAME "linux")
|
||||
|
|
1
client/3rd/QSimpleCrypto
vendored
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit c99b33f0e08b7206116ddff85c22d3b97ce1e79d
|
|
@ -1,20 +0,0 @@
|
|||
include_directories(${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
set(HEADERS ${HEADERS}
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/QAead.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/QBlockCipher.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/QCryptoError.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/QRsa.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/QSimpleCrypto_global.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/QX509.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/include/QX509Store.h
|
||||
)
|
||||
|
||||
set(SOURCES ${SOURCES}
|
||||
${CMAKE_CURRENT_LIST_DIR}/sources/QAead.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/sources/QBlockCipher.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/sources/QCryptoError.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/sources/QRsa.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/sources/QX509.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/sources/QX509Store.cpp
|
||||
)
|
|
@ -1,18 +0,0 @@
|
|||
INCLUDEPATH += $$PWD
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/include/QAead.h \
|
||||
$$PWD/include/QBlockCipher.h \
|
||||
$$PWD/include/QCryptoError.h \
|
||||
$$PWD/include/QRsa.h \
|
||||
$$PWD/include/QSimpleCrypto_global.h \
|
||||
$$PWD/include/QX509.h \
|
||||
$$PWD/include/QX509Store.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/sources/QAead.cpp \
|
||||
$$PWD/sources/QBlockCipher.cpp \
|
||||
$$PWD/sources/QCryptoError.cpp \
|
||||
$$PWD/sources/QRsa.cpp \
|
||||
$$PWD/sources/QX509.cpp \
|
||||
$$PWD/sources/QX509Store.cpp
|
|
@ -1,87 +0,0 @@
|
|||
/**
|
||||
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution
|
||||
**/
|
||||
|
||||
#ifndef QAEAD_H
|
||||
#define QAEAD_H
|
||||
|
||||
#include "QSimpleCrypto_global.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "QCryptoError.h"
|
||||
|
||||
// clang-format off
|
||||
namespace QSimpleCrypto
|
||||
{
|
||||
class QSIMPLECRYPTO_EXPORT QAead {
|
||||
public:
|
||||
QAead();
|
||||
|
||||
///
|
||||
/// \brief encryptAesGcm - Function encrypts data with Gcm algorithm.
|
||||
/// \param data - Data that will be encrypted.
|
||||
/// \param key - AES key.
|
||||
/// \param iv - Initialization vector.
|
||||
/// \param tag - Authorization tag.
|
||||
/// \param aad - Additional authenticated data. Must be nullptr, if not used.
|
||||
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (gcm) - 128, 192, 256. Example: EVP_aes_256_gcm().
|
||||
/// \return Returns encrypted data or "", if error happened.
|
||||
///
|
||||
QByteArray encryptAesGcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad = "", const EVP_CIPHER* cipher = EVP_aes_256_gcm());
|
||||
|
||||
///
|
||||
/// \brief decryptAesGcm - Function decrypts data with Gcm algorithm.
|
||||
/// \param data - Data that will be decrypted
|
||||
/// \param key - AES key
|
||||
/// \param iv - Initialization vector
|
||||
/// \param tag - Authorization tag
|
||||
/// \param aad - Additional authenticated data. Must be nullptr, if not used
|
||||
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (gcm) - 128, 192, 256. Example: EVP_aes_256_gcm()
|
||||
/// \return Returns decrypted data or "", if error happened.
|
||||
///
|
||||
QByteArray decryptAesGcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad = "", const EVP_CIPHER* cipher = EVP_aes_256_gcm());
|
||||
|
||||
///
|
||||
/// \brief encryptAesCcm - Function encrypts data with Ccm algorithm.
|
||||
/// \param data - Data that will be encrypted.
|
||||
/// \param key - AES key.
|
||||
/// \param iv - Initialization vector.
|
||||
/// \param tag - Authorization tag.
|
||||
/// \param aad - Additional authenticated data. Must be nullptr, if not used.
|
||||
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (ccm) - 128, 192, 256. Example: EVP_aes_256_ccm().
|
||||
/// \return Returns encrypted data or "", if error happened.
|
||||
///
|
||||
QByteArray encryptAesCcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad = "", const EVP_CIPHER* cipher = EVP_aes_256_ccm());
|
||||
|
||||
///
|
||||
/// \brief decryptAesCcm - Function decrypts data with Ccm algorithm.
|
||||
/// \param data - Data that will be decrypted.
|
||||
/// \param key - AES key.
|
||||
/// \param iv - Initialization vector.
|
||||
/// \param tag - Authorization tag.
|
||||
/// \param aad - Additional authenticated data. Must be nullptr, if not used.
|
||||
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (ccm) - 128, 192, 256. Example: EVP_aes_256_ccm().
|
||||
/// \return Returns decrypted data or "", if error happened.
|
||||
///
|
||||
QByteArray decryptAesCcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad = "", const EVP_CIPHER* cipher = EVP_aes_256_ccm());
|
||||
|
||||
///
|
||||
/// \brief error - Error handler class.
|
||||
///
|
||||
QCryptoError error;
|
||||
};
|
||||
} // namespace QSimpleCrypto
|
||||
|
||||
#endif // QAEAD_H
|
|
@ -1,84 +0,0 @@
|
|||
/**
|
||||
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution
|
||||
**/
|
||||
|
||||
#ifndef QBLOCKCIPHER_H
|
||||
#define QBLOCKCIPHER_H
|
||||
|
||||
#include "QSimpleCrypto_global.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "QCryptoError.h"
|
||||
|
||||
// clang-format off
|
||||
namespace QSimpleCrypto
|
||||
{
|
||||
class QSIMPLECRYPTO_EXPORT QBlockCipher {
|
||||
|
||||
#define Aes128Rounds 10
|
||||
#define Aes192Rounds 12
|
||||
#define Aes256Rounds 14
|
||||
|
||||
public:
|
||||
QBlockCipher();
|
||||
|
||||
///
|
||||
/// \brief generateRandomBytes - Function generates random bytes by size.
|
||||
/// \param size - Size of generated bytes.
|
||||
/// \return Returns random bytes.
|
||||
///
|
||||
QByteArray generateRandomBytes(const int& size);
|
||||
QByteArray generateSecureRandomBytes(const int& size);
|
||||
|
||||
///
|
||||
/// \brief encryptAesBlockCipher - Function encrypts data with Aes Block Cipher algorithm.
|
||||
/// \param data - Data that will be encrypted.
|
||||
/// \param key - AES key.
|
||||
/// \param iv - Initialization vector.
|
||||
/// \param password - Encryption password.
|
||||
/// \param salt - Random delta.
|
||||
/// \param rounds - Transformation rounds.
|
||||
/// \param chiper - Can be used with OpenSSL EVP_CIPHER (ecb, cbc, cfb, ofb, ctr) - 128, 192, 256. Example: EVP_aes_256_cbc().
|
||||
/// \param md - Hash algroitm (OpenSSL EVP_MD). Example: EVP_sha512().
|
||||
/// \return Returns decrypted data or "", if error happened.
|
||||
///
|
||||
QByteArray encryptAesBlockCipher(QByteArray data, QByteArray key,
|
||||
QByteArray iv = "", const int& rounds = Aes256Rounds,
|
||||
const EVP_CIPHER* cipher = EVP_aes_256_cbc(), const EVP_MD* md = EVP_sha512());
|
||||
|
||||
///
|
||||
/// \brief decryptAesBlockCipher - Function decrypts data with Aes Block Cipher algorithm.
|
||||
/// \param data - Data that will be decrypted.
|
||||
/// \param key - AES key.
|
||||
/// \param iv - Initialization vector.
|
||||
/// \param password - Decryption password.
|
||||
/// \param salt - Random delta.
|
||||
/// \param rounds - Transformation rounds.
|
||||
/// \param chiper - Can be used with OpenSSL EVP_CIPHER (ecb, cbc, cfb, ofb, ctr) - 128, 192, 256. Example: EVP_aes_256_cbc().
|
||||
/// \param md - Hash algroitm (OpenSSL EVP_MD). Example: EVP_sha512().
|
||||
/// \return Returns decrypted data or "", if error happened.
|
||||
///
|
||||
QByteArray decryptAesBlockCipher(QByteArray data, QByteArray key,
|
||||
QByteArray iv = "", const int& rounds = Aes256Rounds,
|
||||
const EVP_CIPHER* cipher = EVP_aes_256_cbc(), const EVP_MD* md = EVP_sha512());
|
||||
|
||||
///
|
||||
/// \brief error - Error handler class.
|
||||
///
|
||||
QCryptoError error;
|
||||
};
|
||||
} // namespace QSimpleCrypto
|
||||
|
||||
#endif // QBLOCKCIPHER_H
|
|
@ -1,45 +0,0 @@
|
|||
#ifndef QCRYPTOERROR_H
|
||||
#define QCRYPTOERROR_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "QSimpleCrypto_global.h"
|
||||
|
||||
/// TODO: Add Special error code for each error.
|
||||
|
||||
// clang-format off
|
||||
namespace QSimpleCrypto
|
||||
{
|
||||
class QSIMPLECRYPTO_EXPORT QCryptoError : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QCryptoError(QObject* parent = nullptr);
|
||||
|
||||
///
|
||||
/// \brief setError - Sets error information
|
||||
/// \param errorCode - Error code.
|
||||
/// \param errorSummary - Error summary.
|
||||
///
|
||||
inline void setError(const quint8 errorCode, const QString& errorSummary)
|
||||
{
|
||||
m_currentErrorCode = errorCode;
|
||||
m_errorSummary = errorSummary;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief lastError - Returns last error.
|
||||
/// \return Returns eror ID and error Text.
|
||||
///
|
||||
inline QPair<quint8, QString> lastError() const
|
||||
{
|
||||
return QPair<quint8, QString>(m_currentErrorCode, m_errorSummary);
|
||||
}
|
||||
|
||||
private:
|
||||
quint8 m_currentErrorCode;
|
||||
QString m_errorSummary;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // QCRYPTOERROR_H
|
|
@ -1,104 +0,0 @@
|
|||
/**
|
||||
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution
|
||||
**/
|
||||
|
||||
#ifndef QRSA_H
|
||||
#define QRSA_H
|
||||
|
||||
#include "QSimpleCrypto_global.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QObject>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
#include "QCryptoError.h"
|
||||
|
||||
// clang-format off
|
||||
namespace QSimpleCrypto
|
||||
{
|
||||
class QSIMPLECRYPTO_EXPORT QRsa {
|
||||
|
||||
#define PublicEncrypt 0
|
||||
#define PrivateEncrypt 1
|
||||
#define PublicDecrypt 2
|
||||
#define PrivateDecrypt 3
|
||||
|
||||
public:
|
||||
QRsa();
|
||||
|
||||
///
|
||||
/// \brief generateRsaKeys - Function generate Rsa Keys and returns them in OpenSSL structure.
|
||||
/// \param bits - RSA key size.
|
||||
/// \param rsaBigNumber - The exponent is an odd number, typically 3, 17 or 65537.
|
||||
/// \return Returns 'OpenSSL RSA structure' or 'nullptr', if error happened. Returned value must be cleaned up with 'RSA_free()' to avoid memory leak.
|
||||
///
|
||||
RSA* generateRsaKeys(const int& bits, const int& rsaBigNumber);
|
||||
|
||||
///
|
||||
/// \brief savePublicKey - Saves to file RSA public key.
|
||||
/// \param rsa - OpenSSL RSA structure.
|
||||
/// \param publicKeyFileName - Public key file name.
|
||||
///
|
||||
void savePublicKey(RSA *rsa, const QByteArray& publicKeyFileName);
|
||||
|
||||
///
|
||||
/// \brief savePrivateKey - Saves to file RSA private key.
|
||||
/// \param rsa - OpenSSL RSA structure.
|
||||
/// \param privateKeyFileName - Private key file name.
|
||||
/// \param password - Private key password.
|
||||
/// \param cipher - Can be used with 'OpenSSL EVP_CIPHER' (ecb, cbc, cfb, ofb, ctr) - 128, 192, 256. Example: EVP_aes_256_cbc().
|
||||
///
|
||||
void savePrivateKey(RSA* rsa, const QByteArray& privateKeyFileName, QByteArray password = "", const EVP_CIPHER* cipher = nullptr);
|
||||
|
||||
///
|
||||
/// \brief getPublicKeyFromFile - Gets RSA public key from a file.
|
||||
/// \param filePath - File path to public key file.
|
||||
/// \return Returns 'OpenSSL EVP_PKEY structure' or 'nullptr', if error happened. Returned value must be cleaned up with 'EVP_PKEY_free()' to avoid memory leak.
|
||||
///
|
||||
EVP_PKEY* getPublicKeyFromFile(const QByteArray& filePath);
|
||||
|
||||
///
|
||||
/// \brief getPrivateKeyFromFile - Gets RSA private key from a file.
|
||||
/// \param filePath - File path to private key file.
|
||||
/// \param password - Private key password.
|
||||
/// \return - Returns 'OpenSSL EVP_PKEY structure' or 'nullptr', if error happened. Returned value must be cleaned up with 'EVP_PKEY_free()' to avoid memory leak.
|
||||
///
|
||||
EVP_PKEY* getPrivateKeyFromFile(const QByteArray& filePath, const QByteArray& password = "");
|
||||
|
||||
///
|
||||
/// \brief encrypt - Encrypt data with RSA algorithm.
|
||||
/// \param plaintext - Text that must be encrypted.
|
||||
/// \param rsa - OpenSSL RSA structure.
|
||||
/// \param encryptType - Public or private encrypt type. (PUBLIC_ENCRYPT, PRIVATE_ENCRYPT).
|
||||
/// \param padding - OpenSSL RSA padding can be used with: 'RSA_PKCS1_PADDING', 'RSA_NO_PADDING' and etc.
|
||||
/// \return Returns encrypted data or "", if error happened.
|
||||
///
|
||||
QByteArray encrypt(QByteArray plainText, RSA* rsa, const int& encryptType = PublicEncrypt, const int& padding = RSA_PKCS1_PADDING);
|
||||
|
||||
///
|
||||
/// \brief decrypt - Decrypt data with RSA algorithm.
|
||||
/// \param cipherText - Text that must be decrypted.
|
||||
/// \param rsa - OpenSSL RSA structure.
|
||||
/// \param decryptType - Public or private type. (PUBLIC_DECRYPT, PRIVATE_DECRYPT).
|
||||
/// \param padding - RSA padding can be used with: 'RSA_PKCS1_PADDING', 'RSA_NO_PADDING' and etc.
|
||||
/// \return - Returns decrypted data or "", if error happened.
|
||||
///
|
||||
QByteArray decrypt(QByteArray cipherText, RSA* rsa, const int& decryptType = PrivateDecrypt, const int& padding = RSA_PKCS1_PADDING);
|
||||
|
||||
///
|
||||
/// \brief error - Error handler class.
|
||||
///
|
||||
QCryptoError error;
|
||||
};
|
||||
} // namespace QSimpleCrypto
|
||||
|
||||
#endif // QRSA_H
|
|
@ -1,9 +0,0 @@
|
|||
#ifndef QSIMPLECRYPTO_GLOBAL_H
|
||||
#define QSIMPLECRYPTO_GLOBAL_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <stdexcept>
|
||||
|
||||
#define QSIMPLECRYPTO_EXPORT
|
||||
|
||||
#endif // QSIMPLECRYPTO_GLOBAL_H
|
|
@ -1,87 +0,0 @@
|
|||
/**
|
||||
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution
|
||||
**/
|
||||
|
||||
#ifndef QX509_H
|
||||
#define QX509_H
|
||||
|
||||
#include "QSimpleCrypto_global.h"
|
||||
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509_vfy.h>
|
||||
|
||||
#include "QCryptoError.h"
|
||||
|
||||
// clang-format off
|
||||
namespace QSimpleCrypto
|
||||
{
|
||||
class QSIMPLECRYPTO_EXPORT QX509 {
|
||||
|
||||
#define oneYear 31536000L
|
||||
#define x509LastVersion 2
|
||||
|
||||
public:
|
||||
QX509();
|
||||
|
||||
///
|
||||
/// \brief loadCertificateFromFile - Function load X509 from file and returns OpenSSL structure.
|
||||
/// \param fileName - File path to certificate.
|
||||
/// \return Returns OpenSSL X509 structure or nullptr, if error happened. Returned value must be cleaned up with 'X509_free' to avoid memory leak.
|
||||
///
|
||||
X509* loadCertificateFromFile(const QByteArray& fileName);
|
||||
|
||||
///
|
||||
/// \brief signCertificate - Function signs X509 certificate and returns signed X509 OpenSSL structure.
|
||||
/// \param endCertificate - Certificate that will be signed
|
||||
/// \param caCertificate - CA certificate that will sign end certificate
|
||||
/// \param caPrivateKey - CA certificate private key
|
||||
/// \param fileName - With that name certificate will be saved. Leave "", if don't need to save it
|
||||
/// \return Returns OpenSSL X509 structure or nullptr, if error happened.
|
||||
///
|
||||
X509* signCertificate(X509* endCertificate, X509* caCertificate, EVP_PKEY* caPrivateKey, const QByteArray& fileName = "");
|
||||
|
||||
///
|
||||
/// \brief verifyCertificate - Function verifies X509 certificate and returns verified X509 OpenSSL structure.
|
||||
/// \param x509 - OpenSSL X509. That certificate will be verified.
|
||||
/// \param store - Trusted certificate must be added to X509_Store with 'addCertificateToStore(X509_STORE* ctx, X509* x509)'.
|
||||
/// \return Returns OpenSSL X509 structure or nullptr, if error happened
|
||||
///
|
||||
X509* verifyCertificate(X509* x509, X509_STORE* store);
|
||||
|
||||
///
|
||||
/// \brief generateSelfSignedCertificate - Function generatesand returns self signed X509.
|
||||
/// \param rsa - OpenSSL RSA.
|
||||
/// \param additionalData - Certificate information.
|
||||
/// \param certificateFileName - With that name certificate will be saved. Leave "", if don't need to save it.
|
||||
/// \param md - OpenSSL EVP_MD structure. Example: EVP_sha512().
|
||||
/// \param serialNumber - X509 certificate serial number.
|
||||
/// \param version - X509 certificate version.
|
||||
/// \param notBefore - X509 start date.
|
||||
/// \param notAfter - X509 end date.
|
||||
/// \return Returns OpenSSL X509 structure or nullptr, if error happened. Returned value must be cleaned up with 'X509_free' to avoid memory leak.
|
||||
///
|
||||
X509* generateSelfSignedCertificate(RSA* rsa, const QMap<QByteArray, QByteArray>& additionalData,
|
||||
const QByteArray& certificateFileName = "", const EVP_MD* md = EVP_sha512(),
|
||||
const long& serialNumber = 1, const long& version = x509LastVersion,
|
||||
const long& notBefore = 0, const long& notAfter = oneYear);
|
||||
|
||||
///
|
||||
/// \brief error - Error handler class.
|
||||
///
|
||||
QCryptoError error;
|
||||
};
|
||||
} // namespace QSimpleCrypto
|
||||
|
||||
#endif // QX509_H
|
|
@ -1,120 +0,0 @@
|
|||
/**
|
||||
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution
|
||||
**/
|
||||
|
||||
#ifndef QX509STORE_H
|
||||
#define QX509STORE_H
|
||||
|
||||
#include "QSimpleCrypto_global.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/x509_vfy.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
#include "QCryptoError.h"
|
||||
|
||||
// clang-format off
|
||||
namespace QSimpleCrypto
|
||||
{
|
||||
class QSIMPLECRYPTO_EXPORT QX509Store {
|
||||
public:
|
||||
QX509Store();
|
||||
|
||||
///
|
||||
/// \brief addCertificateToStore
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \param x509 - OpenSSL X509.
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool addCertificateToStore(X509_STORE* store, X509* x509);
|
||||
|
||||
///
|
||||
/// \brief addLookup
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \param method - OpenSSL X509_LOOKUP_METHOD. Example: X509_LOOKUP_file.
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool addLookup(X509_STORE* store, X509_LOOKUP_METHOD* method);
|
||||
|
||||
///
|
||||
/// \brief setCertificateDepth
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \param depth - That is the maximum number of untrusted CA certificates that can appear in a chain. Example: 0.
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool setDepth(X509_STORE* store, const int& depth);
|
||||
|
||||
///
|
||||
/// \brief setFlag
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \param flag - The verification flags consists of zero or more of the following flags ored together. Example: X509_V_FLAG_CRL_CHECK.
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool setFlag(X509_STORE* store, const unsigned long& flag);
|
||||
|
||||
///
|
||||
/// \brief setFlag
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \param purpose - Verification purpose in param to purpose. Example: X509_PURPOSE_ANY.
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool setPurpose(X509_STORE* store, const int& purpose);
|
||||
|
||||
///
|
||||
/// \brief setTrust
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \param trust - Trust Level. Example: X509_TRUST_SSL_SERVER.
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool setTrust(X509_STORE* store, const int& trust);
|
||||
|
||||
///
|
||||
/// \brief setDefaultPaths
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool setDefaultPaths(X509_STORE* store);
|
||||
|
||||
///
|
||||
/// \brief loadLocations
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \param fileName - File name. Example: "caCertificate.pem".
|
||||
/// \param dirPath - Path to file. Example: "path/To/File".
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool loadLocations(X509_STORE* store, const QByteArray& fileName, const QByteArray& dirPath);
|
||||
|
||||
///
|
||||
/// \brief loadLocations
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \param file - Qt QFile that will be loaded.
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool loadLocations(X509_STORE* store, const QFile& file);
|
||||
|
||||
///
|
||||
/// \brief loadLocations
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \param fileInfo - Qt QFileInfo.
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool loadLocations(X509_STORE* store, const QFileInfo& fileInfo);
|
||||
|
||||
///
|
||||
/// \brief error - Error handler class.
|
||||
///
|
||||
QCryptoError error;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // QX509STORE_H
|
|
@ -1,364 +0,0 @@
|
|||
/**
|
||||
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution
|
||||
**/
|
||||
|
||||
#include "include/QAead.h"
|
||||
|
||||
QSimpleCrypto::QAead::QAead()
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QAEAD::encryptAesGcm - Function encrypts data with Gcm algorithm.
|
||||
/// \param data - Data that will be encrypted.
|
||||
/// \param key - AES key.
|
||||
/// \param iv - Initialization vector.
|
||||
/// \param tag - Authorization tag.
|
||||
/// \param aad - Additional authenticated data. Must be nullptr, if not used.
|
||||
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (gcm) - 128, 192, 256. Example: EVP_aes_256_gcm().
|
||||
/// \return Returns encrypted data or "", if error happened.
|
||||
///
|
||||
QByteArray QSimpleCrypto::QAead::encryptAesGcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad, const EVP_CIPHER* cipher)
|
||||
{
|
||||
try {
|
||||
/* Initialize EVP_CIPHER_CTX */
|
||||
std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX*)> encryptionCipher { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free };
|
||||
if (encryptionCipher == nullptr) {
|
||||
throw std::runtime_error("Couldn't initialize \'encryptionCipher\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Set data length */
|
||||
int plainTextLength = data.size();
|
||||
int cipherTextLength = 0;
|
||||
|
||||
/* Initialize cipherText. Here encrypted data will be stored */
|
||||
std::unique_ptr<unsigned char[]> cipherText { new unsigned char[plainTextLength]() };
|
||||
if (cipherText == nullptr) {
|
||||
throw std::runtime_error("Couldn't allocate memory for 'ciphertext'.");
|
||||
}
|
||||
|
||||
/* Initialize encryption operation. */
|
||||
if (!EVP_EncryptInit_ex(encryptionCipher.get(), cipher, nullptr, reinterpret_cast<unsigned char*>(key.data()), reinterpret_cast<unsigned char*>(iv.data()))) {
|
||||
throw std::runtime_error("Couldn't initialize encryption operation. EVP_EncryptInit_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Set IV length if default 12 bytes (96 bits) is not appropriate */
|
||||
if (!EVP_CIPHER_CTX_ctrl(encryptionCipher.get(), EVP_CTRL_GCM_SET_IVLEN, iv.length(), nullptr)) {
|
||||
throw std::runtime_error("Couldn't set IV length. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
// /* Check if aad need to be used */
|
||||
// if (aad.length() > 0) {
|
||||
// /* Provide any AAD data. This can be called zero or more times as required */
|
||||
// if (!EVP_EncryptUpdate(encryptionCipher.get(), nullptr, &cipherTextLength, reinterpret_cast<unsigned char*>(aad.data()), aad.length())) {
|
||||
// throw std::runtime_error("Couldn't provide aad data. EVP_EncryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
// }
|
||||
// }
|
||||
|
||||
/*
|
||||
* Provide the message to be encrypted, and obtain the encrypted output.
|
||||
* EVP_EncryptUpdate can be called multiple times if necessary
|
||||
*/
|
||||
if (!EVP_EncryptUpdate(encryptionCipher.get(), cipherText.get(), &cipherTextLength, reinterpret_cast<const unsigned char*>(data.data()), plainTextLength)) {
|
||||
throw std::runtime_error("Couldn't provide message to be encrypted. EVP_EncryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Finalize the encryption. Normally cipher text bytes may be written at
|
||||
* this stage, but this does not occur in GCM mode
|
||||
*/
|
||||
if (!EVP_EncryptFinal_ex(encryptionCipher.get(), cipherText.get(), &plainTextLength)) {
|
||||
throw std::runtime_error("Couldn't finalize encryption. EVP_EncryptFinal_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
// /* Get tag */
|
||||
// if (!EVP_CIPHER_CTX_ctrl(encryptionCipher.get(), EVP_CTRL_GCM_GET_TAG, tag->length(), reinterpret_cast<unsigned char*>(tag->data()))) {
|
||||
// throw std::runtime_error("Couldn't get tag. EVP_CIPHER_CTX_ctrl(. Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
// }
|
||||
|
||||
/* Finilize data to be readable with qt */
|
||||
QByteArray encryptedData = QByteArray(reinterpret_cast<char*>(cipherText.get()), cipherTextLength);
|
||||
|
||||
return encryptedData;
|
||||
|
||||
} catch (std::exception& exception) {
|
||||
QSimpleCrypto::QAead::error.setError(1, exception.what());
|
||||
return QByteArray();
|
||||
} catch (...) {
|
||||
QSimpleCrypto::QAead::error.setError(2, "Unknown error!");
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QAEAD::decryptAesGcm - Function decrypts data with Gcm algorithm.
|
||||
/// \param data - Data that will be decrypted
|
||||
/// \param key - AES key
|
||||
/// \param iv - Initialization vector
|
||||
/// \param tag - Authorization tag
|
||||
/// \param aad - Additional authenticated data. Must be nullptr, if not used
|
||||
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (gcm) - 128, 192, 256. Example: EVP_aes_256_gcm()
|
||||
/// \return Returns decrypted data or "", if error happened.
|
||||
///
|
||||
QByteArray QSimpleCrypto::QAead::decryptAesGcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad, const EVP_CIPHER* cipher)
|
||||
{
|
||||
try {
|
||||
/* Initialize EVP_CIPHER_CTX */
|
||||
std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX*)> decryptionCipher { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free };
|
||||
if (decryptionCipher.get() == nullptr) {
|
||||
throw std::runtime_error("Couldn't initialize \'decryptionCipher\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Set data length */
|
||||
int cipherTextLength = data.size();
|
||||
int plainTextLength = 0;
|
||||
|
||||
/* Initialize plainText. Here decrypted data will be stored */
|
||||
std::unique_ptr<unsigned char[]> plainText { new unsigned char[cipherTextLength]() };
|
||||
if (plainText == nullptr) {
|
||||
throw std::runtime_error("Couldn't allocate memory for 'plaintext'.");
|
||||
}
|
||||
|
||||
/* Initialize decryption operation. */
|
||||
if (!EVP_DecryptInit_ex(decryptionCipher.get(), cipher, nullptr, reinterpret_cast<unsigned char*>(key.data()), reinterpret_cast<unsigned char*>(iv.data()))) {
|
||||
throw std::runtime_error("Couldn't initialize decryption operation. EVP_DecryptInit_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Set IV length. Not necessary if this is 12 bytes (96 bits) */
|
||||
if (!EVP_CIPHER_CTX_ctrl(decryptionCipher.get(), EVP_CTRL_GCM_SET_IVLEN, iv.length(), nullptr)) {
|
||||
throw std::runtime_error("Couldn't set IV length. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
// /* Check if aad need to be used */
|
||||
// if (aad.length() > 0) {
|
||||
// /* Provide any AAD data. This can be called zero or more times as required */
|
||||
// if (!EVP_DecryptUpdate(decryptionCipher.get(), nullptr, &plainTextLength, reinterpret_cast<unsigned char*>(aad.data()), aad.length())) {
|
||||
// throw std::runtime_error("Couldn't provide aad data. EVP_DecryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
// }
|
||||
// }
|
||||
|
||||
/*
|
||||
* Provide the message to be decrypted, and obtain the plain text output.
|
||||
* EVP_DecryptUpdate can be called multiple times if necessary
|
||||
*/
|
||||
if (!EVP_DecryptUpdate(decryptionCipher.get(), plainText.get(), &plainTextLength, reinterpret_cast<const unsigned char*>(data.data()), cipherTextLength)) {
|
||||
throw std::runtime_error("Couldn't provide message to be decrypted. EVP_DecryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
// /* Set expected tag value. Works in OpenSSL 1.0.1d and later */
|
||||
// if (!EVP_CIPHER_CTX_ctrl(decryptionCipher.get(), EVP_CTRL_GCM_SET_TAG, tag->length(), reinterpret_cast<unsigned char*>(tag->data()))) {
|
||||
// throw std::runtime_error("Coldn't set tag. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
// }
|
||||
|
||||
/*
|
||||
* Finalize the decryption. A positive return value indicates success,
|
||||
* anything else is a failure - the plain text is not trustworthy.
|
||||
*/
|
||||
if (!EVP_DecryptFinal_ex(decryptionCipher.get(), plainText.get(), &cipherTextLength)) {
|
||||
throw std::runtime_error("Couldn't finalize decryption. EVP_DecryptFinal_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Finilize data to be readable with qt */
|
||||
QByteArray decryptedData = QByteArray(reinterpret_cast<char*>(plainText.get()), plainTextLength);
|
||||
|
||||
return decryptedData;
|
||||
|
||||
} catch (std::exception& exception) {
|
||||
QSimpleCrypto::QAead::error.setError(1, exception.what());
|
||||
return QByteArray();
|
||||
} catch (...) {
|
||||
QSimpleCrypto::QAead::error.setError(2, "Unknown error!");
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QAEAD::encryptAesCcm - Function encrypts data with Ccm algorithm.
|
||||
/// \param data - Data that will be encrypted.
|
||||
/// \param key - AES key.
|
||||
/// \param iv - Initialization vector.
|
||||
/// \param tag - Authorization tag.
|
||||
/// \param aad - Additional authenticated data. Must be nullptr, if not used.
|
||||
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (ccm) - 128, 192, 256. Example: EVP_aes_256_ccm().
|
||||
/// \return Returns encrypted data or "", if error happened.
|
||||
///
|
||||
QByteArray QSimpleCrypto::QAead::encryptAesCcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad, const EVP_CIPHER* cipher)
|
||||
{
|
||||
try {
|
||||
/* Initialize EVP_CIPHER_CTX */
|
||||
std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX*)> encryptionCipher { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free };
|
||||
if (encryptionCipher == nullptr) {
|
||||
throw std::runtime_error("Couldn't initialize \'encryptionCipher\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Set data length */
|
||||
int plainTextLength = data.size();
|
||||
int cipherTextLength = 0;
|
||||
|
||||
/* Initialize cipherText. Here encrypted data will be stored */
|
||||
std::unique_ptr<unsigned char[]> cipherText { new unsigned char[plainTextLength]() };
|
||||
if (cipherText.get() == nullptr) {
|
||||
throw std::runtime_error("Couldn't allocate memory for 'ciphertext'.");
|
||||
}
|
||||
|
||||
/* Initialize encryption operation. */
|
||||
if (!EVP_EncryptInit_ex(encryptionCipher.get(), cipher, nullptr, reinterpret_cast<unsigned char*>(key.data()), reinterpret_cast<unsigned char*>(iv.data()))) {
|
||||
throw std::runtime_error("Couldn't initialize encryption operation. EVP_EncryptInit_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Set IV length if default 12 bytes (96 bits) is not appropriate */
|
||||
if (!EVP_CIPHER_CTX_ctrl(encryptionCipher.get(), EVP_CTRL_CCM_SET_IVLEN, iv.length(), nullptr)) {
|
||||
throw std::runtime_error("Couldn't set IV length. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Set tag length */
|
||||
if (!EVP_CIPHER_CTX_ctrl(encryptionCipher.get(), EVP_CTRL_CCM_SET_TAG, tag->length(), nullptr)) {
|
||||
throw std::runtime_error("Coldn't set tag. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Check if aad need to be used */
|
||||
if (aad.length() > 0) {
|
||||
/* Provide the total plain text length */
|
||||
if (!EVP_EncryptUpdate(encryptionCipher.get(), nullptr, &cipherTextLength, nullptr, plainTextLength)) {
|
||||
throw std::runtime_error("Couldn't provide total plaintext length. EVP_EncryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Provide any AAD data. This can be called zero or more times as required */
|
||||
if (!EVP_EncryptUpdate(encryptionCipher.get(), nullptr, &cipherTextLength, reinterpret_cast<unsigned char*>(aad.data()), aad.length())) {
|
||||
throw std::runtime_error("Couldn't provide aad data. EVP_EncryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide the message to be encrypted, and obtain the encrypted output.
|
||||
* EVP_EncryptUpdate can be called multiple times if necessary
|
||||
*/
|
||||
if (!EVP_EncryptUpdate(encryptionCipher.get(), cipherText.get(), &cipherTextLength, reinterpret_cast<const unsigned char*>(data.data()), plainTextLength)) {
|
||||
throw std::runtime_error("Couldn't provide message to be encrypted. EVP_EncryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Finalize the encryption. Normally ciphertext bytes may be written at
|
||||
* this stage, but this does not occur in GCM mode
|
||||
*/
|
||||
if (!EVP_EncryptFinal_ex(encryptionCipher.get(), cipherText.get(), &plainTextLength)) {
|
||||
throw std::runtime_error("Couldn't finalize encryption. EVP_EncryptFinal_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Get tag */
|
||||
if (!EVP_CIPHER_CTX_ctrl(encryptionCipher.get(), EVP_CTRL_CCM_GET_TAG, tag->length(), reinterpret_cast<unsigned char*>(tag->data()))) {
|
||||
throw std::runtime_error("Couldn't get tag. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Finilize data to be readable with qt */
|
||||
QByteArray encryptedData = QByteArray(reinterpret_cast<char*>(cipherText.get()), cipherTextLength);
|
||||
|
||||
return encryptedData;
|
||||
|
||||
} catch (std::exception& exception) {
|
||||
QSimpleCrypto::QAead::error.setError(1, exception.what());
|
||||
return QByteArray();
|
||||
} catch (...) {
|
||||
QSimpleCrypto::QAead::error.setError(2, "Unknown error!");
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QAEAD::decryptAesCcm - Function decrypts data with Ccm algorithm.
|
||||
/// \param data - Data that will be decrypted.
|
||||
/// \param key - AES key.
|
||||
/// \param iv - Initialization vector.
|
||||
/// \param tag - Authorization tag.
|
||||
/// \param aad - Additional authenticated data. Must be nullptr, if not used.
|
||||
/// \param cipher - Can be used with OpenSSL EVP_CIPHER (ccm) - 128, 192, 256. Example: EVP_aes_256_ccm().
|
||||
/// \return Returns decrypted data or "", if error happened.
|
||||
///
|
||||
QByteArray QSimpleCrypto::QAead::decryptAesCcm(QByteArray data, QByteArray key, QByteArray iv, QByteArray* tag, QByteArray aad, const EVP_CIPHER* cipher)
|
||||
{
|
||||
try {
|
||||
/* Initialize EVP_CIPHER_CTX */
|
||||
std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX*)> decryptionCipher { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free };
|
||||
if (decryptionCipher.get() == nullptr) {
|
||||
throw std::runtime_error("Couldn't initialize \'decryptionCipher\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Set data length */
|
||||
int cipherTextLength = data.size();
|
||||
int plainTextLength = 0;
|
||||
|
||||
/* Initialize plainText. Here decrypted data will be stored */
|
||||
std::unique_ptr<unsigned char[]> plainText { new unsigned char[cipherTextLength]() };
|
||||
if (plainText == nullptr) {
|
||||
throw std::runtime_error("Couldn't allocate memory for 'plaintext'.");
|
||||
}
|
||||
|
||||
/* Initialize decryption operation. */
|
||||
if (!EVP_DecryptInit_ex(decryptionCipher.get(), cipher, nullptr, reinterpret_cast<unsigned char*>(key.data()), reinterpret_cast<unsigned char*>(iv.data()))) {
|
||||
throw std::runtime_error("Couldn't initialize decryption operation. EVP_DecryptInit_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Set IV length. Not necessary if this is 12 bytes (96 bits) */
|
||||
if (!EVP_CIPHER_CTX_ctrl(decryptionCipher.get(), EVP_CTRL_CCM_SET_IVLEN, iv.length(), nullptr)) {
|
||||
throw std::runtime_error("Couldn't set IV length. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Set expected tag value. Works in OpenSSL 1.0.1d and later */
|
||||
if (!EVP_CIPHER_CTX_ctrl(decryptionCipher.get(), EVP_CTRL_CCM_SET_TAG, tag->length(), reinterpret_cast<unsigned char*>(tag->data()))) {
|
||||
throw std::runtime_error("Coldn't set tag. EVP_CIPHER_CTX_ctrl(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Check if aad need to be used */
|
||||
if (aad.length() > 0) {
|
||||
/* Provide the total ciphertext length */
|
||||
if (!EVP_DecryptUpdate(decryptionCipher.get(), nullptr, &plainTextLength, nullptr, cipherTextLength)) {
|
||||
throw std::runtime_error("Couldn't provide total plaintext length. EVP_DecryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Provide any AAD data. This can be called zero or more times as required */
|
||||
if (!EVP_DecryptUpdate(decryptionCipher.get(), nullptr, &plainTextLength, reinterpret_cast<unsigned char*>(aad.data()), aad.length())) {
|
||||
throw std::runtime_error("Couldn't provide aad data. EVP_DecryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide the message to be decrypted, and obtain the plaintext output.
|
||||
* EVP_DecryptUpdate can be called multiple times if necessary
|
||||
*/
|
||||
if (!EVP_DecryptUpdate(decryptionCipher.get(), plainText.get(), &plainTextLength, reinterpret_cast<const unsigned char*>(data.data()), cipherTextLength)) {
|
||||
throw std::runtime_error("Couldn't provide message to be decrypted. EVP_DecryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Finalize the decryption. A positive return value indicates success,
|
||||
* anything else is a failure - the plaintext is not trustworthy.
|
||||
*/
|
||||
if (!EVP_DecryptFinal_ex(decryptionCipher.get(), plainText.get(), &cipherTextLength)) {
|
||||
throw std::runtime_error("Couldn't finalize decryption. EVP_DecryptFinal_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Finilize data to be readable with qt */
|
||||
QByteArray decryptedData = QByteArray(reinterpret_cast<char*>(plainText.get()), plainTextLength);
|
||||
|
||||
return decryptedData;
|
||||
|
||||
} catch (std::exception& exception) {
|
||||
QSimpleCrypto::QAead::error.setError(1, exception.what());
|
||||
return QByteArray();
|
||||
} catch (...) {
|
||||
QSimpleCrypto::QAead::error.setError(2, "Unknown error!");
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
return QByteArray();
|
||||
}
|
|
@ -1,193 +0,0 @@
|
|||
/**
|
||||
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution
|
||||
**/
|
||||
|
||||
#include "include/QBlockCipher.h"
|
||||
|
||||
QSimpleCrypto::QBlockCipher::QBlockCipher()
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QBlockCipher::generateRandomBytes - Function generates random bytes by size.
|
||||
/// \param size - Size of generated bytes.
|
||||
/// \return Returns random bytes.
|
||||
///
|
||||
QByteArray QSimpleCrypto::QBlockCipher::generateRandomBytes(const int& size)
|
||||
{
|
||||
unsigned char arr[sizeof(size)];
|
||||
RAND_bytes(arr, sizeof(size));
|
||||
|
||||
QByteArray buffer = QByteArray(reinterpret_cast<char*>(arr), size);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
QByteArray QSimpleCrypto::QBlockCipher::generateSecureRandomBytes(const int &size)
|
||||
{
|
||||
unsigned char arr[sizeof(size)];
|
||||
RAND_priv_bytes(arr, sizeof(size));
|
||||
|
||||
QByteArray buffer = QByteArray(reinterpret_cast<char*>(arr), size);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QBlockCipher::encryptAesBlockCipher - Function encrypts data with Aes Block Cipher algorithm.
|
||||
/// \param data - Data that will be encrypted.
|
||||
/// \param key - AES key.
|
||||
/// \param iv - Initialization vector.
|
||||
/// \param password - Encryption password.
|
||||
/// \param salt - Random delta.
|
||||
/// \param rounds - Transformation rounds.
|
||||
/// \param chiper - Can be used with OpenSSL EVP_CIPHER (ecb, cbc, cfb, ofb, ctr) - 128, 192, 256. Example: EVP_aes_256_cbc().
|
||||
/// \param md - Hash algroitm (OpenSSL EVP_MD). Example: EVP_sha512().
|
||||
/// \return Returns decrypted data or "", if error happened.
|
||||
///
|
||||
QByteArray QSimpleCrypto::QBlockCipher::encryptAesBlockCipher(QByteArray data, QByteArray key,
|
||||
QByteArray iv,
|
||||
const int& rounds, const EVP_CIPHER* cipher, const EVP_MD* md)
|
||||
{
|
||||
try {
|
||||
/* Initialize EVP_CIPHER_CTX */
|
||||
std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX*)> encryptionCipher { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free };
|
||||
if (encryptionCipher == nullptr) {
|
||||
throw std::runtime_error("Couldn't initialize \'encryptionCipher\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Reinterpret values for multi use */
|
||||
unsigned char* m_key = reinterpret_cast<unsigned char*>(key.data());
|
||||
unsigned char* m_iv = reinterpret_cast<unsigned char*>(iv.data());
|
||||
|
||||
/* Set data length */
|
||||
int cipherTextLength(data.size() + AES_BLOCK_SIZE);
|
||||
int finalLength = 0;
|
||||
|
||||
/* Initialize cipcherText. Here encrypted data will be stored */
|
||||
std::unique_ptr<unsigned char[]> cipherText { new unsigned char[cipherTextLength]() };
|
||||
if (cipherText == nullptr) {
|
||||
throw std::runtime_error("Couldn't allocate memory for 'cipherText'.");
|
||||
}
|
||||
|
||||
// Bug here
|
||||
// /* Start encryption with password based encryption routine */
|
||||
// if (!EVP_BytesToKey(cipher, md, reinterpret_cast<unsigned char*>(salt.data()), reinterpret_cast<unsigned char*>(password.data()), password.length(), rounds, m_key, m_iv)) {
|
||||
// throw std::runtime_error("Couldn't start encryption routine. EVP_BytesToKey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
// }
|
||||
|
||||
/* Initialize encryption operation. */
|
||||
if (!EVP_EncryptInit_ex(encryptionCipher.get(), cipher, nullptr, m_key, m_iv)) {
|
||||
throw std::runtime_error("Couldn't initialize encryption operation. EVP_EncryptInit_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide the message to be encrypted, and obtain the encrypted output.
|
||||
* EVP_EncryptUpdate can be called multiple times if necessary
|
||||
*/
|
||||
if (!EVP_EncryptUpdate(encryptionCipher.get(), cipherText.get(), &cipherTextLength, reinterpret_cast<const unsigned char*>(data.data()), data.size())) {
|
||||
throw std::runtime_error("Couldn't provide message to be encrypted. EVP_EncryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Finalize the encryption. Normally ciphertext bytes may be written at this stage */
|
||||
if (!EVP_EncryptFinal(encryptionCipher.get(), cipherText.get() + cipherTextLength, &finalLength)) {
|
||||
throw std::runtime_error("Couldn't finalize encryption. EVP_EncryptFinal(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Finilize data to be readable with qt */
|
||||
QByteArray encryptedData = QByteArray(reinterpret_cast<char*>(cipherText.get()), cipherTextLength + finalLength);
|
||||
|
||||
return encryptedData;
|
||||
|
||||
} catch (std::exception& exception) {
|
||||
QSimpleCrypto::QBlockCipher::error.setError(1, exception.what());
|
||||
return QByteArray();
|
||||
} catch (...) {
|
||||
QSimpleCrypto::QBlockCipher::error.setError(2, "Unknown error!");
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QBlockCipher::encryptAesBlockCipher - Function decrypts data with Aes Block Cipher algorithm.
|
||||
/// \param data - Data that will be decrypted.
|
||||
/// \param key - AES key.
|
||||
/// \param iv - Initialization vector.
|
||||
/// \param password - Decryption password.
|
||||
/// \param salt - Random delta.
|
||||
/// \param rounds - Transformation rounds.
|
||||
/// \param chiper - Can be used with OpenSSL EVP_CIPHER (ecb, cbc, cfb, ofb, ctr) - 128, 192, 256. Example: EVP_aes_256_cbc().
|
||||
/// \param md - Hash algroitm (OpenSSL EVP_MD). Example: EVP_sha512().
|
||||
/// \return Returns decrypted data or "", if error happened.
|
||||
///
|
||||
QByteArray QSimpleCrypto::QBlockCipher::decryptAesBlockCipher(QByteArray data, QByteArray key,
|
||||
QByteArray iv,
|
||||
const int& rounds, const EVP_CIPHER* cipher, const EVP_MD* md)
|
||||
{
|
||||
try {
|
||||
/* Initialize EVP_CIPHER_CTX */
|
||||
std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX*)> decryptionCipher { EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free };
|
||||
if (decryptionCipher == nullptr) {
|
||||
throw std::runtime_error("Couldn't initialize \'decryptionCipher\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Reinterpret values for multi use */
|
||||
unsigned char* m_key = reinterpret_cast<unsigned char*>(key.data());
|
||||
unsigned char* m_iv = reinterpret_cast<unsigned char*>(iv.data());
|
||||
|
||||
/* Set data length */
|
||||
int plainTextLength(data.size());
|
||||
int finalLength = 0;
|
||||
|
||||
/* Initialize plainText. Here decrypted data will be stored */
|
||||
std::unique_ptr<unsigned char[]> plainText { new unsigned char[plainTextLength + AES_BLOCK_SIZE]() };
|
||||
if (plainText == nullptr) {
|
||||
throw std::runtime_error("Couldn't allocate memory for \'plainText\'. EVP_CIPHER_CTX_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
// Bug here
|
||||
// /* Start encryption with password based encryption routine */
|
||||
// if (!EVP_BytesToKey(cipher, md, reinterpret_cast<const unsigned char*>(salt.data()), reinterpret_cast<const unsigned char*>(password.data()), password.length(), rounds, m_key, m_iv)) {
|
||||
// throw std::runtime_error("Couldn't start decryption routine. EVP_BytesToKey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
// }
|
||||
|
||||
/* Initialize decryption operation. */
|
||||
if (!EVP_DecryptInit_ex(decryptionCipher.get(), cipher, nullptr, m_key, m_iv)) {
|
||||
throw std::runtime_error("Couldn't initialize decryption operation. EVP_DecryptInit_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide the message to be decrypted, and obtain the plaintext output.
|
||||
* EVP_DecryptUpdate can be called multiple times if necessary
|
||||
*/
|
||||
if (!EVP_DecryptUpdate(decryptionCipher.get(), plainText.get(), &plainTextLength, reinterpret_cast<const unsigned char*>(data.data()), data.size())) {
|
||||
throw std::runtime_error("Couldn't provide message to be decrypted. EVP_DecryptUpdate(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/*
|
||||
* Finalize the decryption. A positive return value indicates success,
|
||||
* anything else is a failure - the plaintext is not trustworthy.
|
||||
*/
|
||||
if (!EVP_DecryptFinal(decryptionCipher.get(), plainText.get() + plainTextLength, &finalLength)) {
|
||||
throw std::runtime_error("Couldn't finalize decryption. EVP_DecryptFinal. Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Finilize data to be readable with qt */
|
||||
QByteArray decryptedData = QByteArray(reinterpret_cast<char*>(plainText.get()), plainTextLength + finalLength);
|
||||
|
||||
return decryptedData;
|
||||
|
||||
} catch (std::exception& exception) {
|
||||
QSimpleCrypto::QBlockCipher::error.setError(1, exception.what());
|
||||
return QByteArray(exception.what());
|
||||
} catch (...) {
|
||||
QSimpleCrypto::QBlockCipher::error.setError(2, "Unknown error!");
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
return QByteArray();
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
#include "include/QCryptoError.h"
|
||||
|
||||
QSimpleCrypto::QCryptoError::QCryptoError(QObject* parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
|
@ -1,274 +0,0 @@
|
|||
/**
|
||||
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution
|
||||
**/
|
||||
|
||||
#include "include/QRsa.h"
|
||||
|
||||
QSimpleCrypto::QRsa::QRsa()
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QRSA::generateRsaKeys - Function generate Rsa Keys and returns them in OpenSSL structure.
|
||||
/// \param bits - RSA key size.
|
||||
/// \param rsaBigNumber - The exponent is an odd number, typically 3, 17 or 65537.
|
||||
/// \return Returns 'OpenSSL RSA structure' or 'nullptr', if error happened. Returned value must be cleaned up with 'RSA_free()' to avoid memory leak.
|
||||
///
|
||||
RSA* QSimpleCrypto::QRsa::generateRsaKeys(const int& bits, const int& rsaBigNumber)
|
||||
{
|
||||
try {
|
||||
/* Initialize big number */
|
||||
std::unique_ptr<BIGNUM, void (*)(BIGNUM*)> bigNumber { BN_new(), BN_free };
|
||||
if (bigNumber == nullptr) {
|
||||
throw std::runtime_error("Couldn't initialize \'bigNumber\'. BN_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* Set big number */
|
||||
if (!BN_set_word(bigNumber.get(), rsaBigNumber)) {
|
||||
throw std::runtime_error("Couldn't set bigNumber. BN_set_word(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Initialize RSA */
|
||||
RSA* rsa = nullptr;
|
||||
if (!(rsa = RSA_new())) {
|
||||
throw std::runtime_error("Couldn't initialize x509. X509_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Generate key pair and store it in RSA */
|
||||
if (!RSA_generate_key_ex(rsa, bits, bigNumber.get(), nullptr)) {
|
||||
throw std::runtime_error("Couldn't generate RSA. RSA_generate_key_ex(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
return rsa;
|
||||
} catch (std::exception& exception) {
|
||||
QSimpleCrypto::QRsa::error.setError(1, exception.what());
|
||||
return nullptr;
|
||||
} catch (...) {
|
||||
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QRSA::savePublicKey - Saves to file RSA public key.
|
||||
/// \param rsa - OpenSSL RSA structure.
|
||||
/// \param publicKeyFileName - Public key file name.
|
||||
///
|
||||
void QSimpleCrypto::QRsa::savePublicKey(RSA* rsa, const QByteArray& publicKeyFileName)
|
||||
{
|
||||
try {
|
||||
/* Initialize BIO */
|
||||
std::unique_ptr<BIO, void (*)(BIO*)> bioPublicKey { BIO_new_file(publicKeyFileName.data(), "w+"), BIO_free_all };
|
||||
if (bioPublicKey == nullptr) {
|
||||
throw std::runtime_error("Couldn't initialize \'bioPublicKey\'. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Write public key on file */
|
||||
if (!PEM_write_bio_RSA_PUBKEY(bioPublicKey.get(), rsa)) {
|
||||
throw std::runtime_error("Couldn't save public key. PEM_write_bio_RSAPublicKey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
} catch (std::exception& exception) {
|
||||
QSimpleCrypto::QRsa::error.setError(1, exception.what());
|
||||
return;
|
||||
} catch (...) {
|
||||
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QRSA::savePrivateKey - Saves to file RSA private key.
|
||||
/// \param rsa - OpenSSL RSA structure.
|
||||
/// \param privateKeyFileName - Private key file name.
|
||||
/// \param password - Private key password.
|
||||
/// \param cipher - Can be used with 'OpenSSL EVP_CIPHER' (ecb, cbc, cfb, ofb, ctr) - 128, 192, 256. Example: EVP_aes_256_cbc().
|
||||
///
|
||||
void QSimpleCrypto::QRsa::savePrivateKey(RSA* rsa, const QByteArray& privateKeyFileName, QByteArray password, const EVP_CIPHER* cipher)
|
||||
{
|
||||
try {
|
||||
/* Initialize BIO */
|
||||
std::unique_ptr<BIO, void (*)(BIO*)> bioPrivateKey { BIO_new_file(privateKeyFileName.data(), "w+"), BIO_free_all };
|
||||
if (bioPrivateKey == nullptr) {
|
||||
throw std::runtime_error("Couldn't initialize bioPrivateKey. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Write private key to file */
|
||||
if (!PEM_write_bio_RSAPrivateKey(bioPrivateKey.get(), rsa, cipher, reinterpret_cast<unsigned char*>(password.data()), password.size(), nullptr, nullptr)) {
|
||||
throw std::runtime_error("Couldn't save private key. PEM_write_bio_RSAPrivateKey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
} catch (std::exception& exception) {
|
||||
QSimpleCrypto::QRsa::error.setError(1, exception.what());
|
||||
return;
|
||||
} catch (...) {
|
||||
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QRSA::getPublicKeyFromFile - Gets RSA public key from a file.
|
||||
/// \param filePath - File path to public key file.
|
||||
/// \return Returns 'OpenSSL EVP_PKEY structure' or 'nullptr', if error happened. Returned value must be cleaned up with 'EVP_PKEY_free()' to avoid memory leak.
|
||||
///
|
||||
EVP_PKEY* QSimpleCrypto::QRsa::getPublicKeyFromFile(const QByteArray& filePath)
|
||||
{
|
||||
try {
|
||||
/* Initialize BIO */
|
||||
std::unique_ptr<BIO, void (*)(BIO*)> bioPublicKey { BIO_new_file(filePath.data(), "r"), BIO_free_all };
|
||||
if (bioPublicKey == nullptr) {
|
||||
throw std::runtime_error("Couldn't initialize bioPublicKey. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Initialize EVP_PKEY */
|
||||
EVP_PKEY* keyStore = nullptr;
|
||||
if (!(keyStore = EVP_PKEY_new())) {
|
||||
throw std::runtime_error("Couldn't initialize keyStore. EVP_PKEY_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Write private key to file */
|
||||
if (!PEM_read_bio_PUBKEY(bioPublicKey.get(), &keyStore, nullptr, nullptr)) {
|
||||
throw std::runtime_error("Couldn't read private key. PEM_read_bio_PrivateKey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
return keyStore;
|
||||
|
||||
} catch (std::exception& exception) {
|
||||
QSimpleCrypto::QRsa::error.setError(1, exception.what());
|
||||
return nullptr;
|
||||
} catch (...) {
|
||||
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QRSA::getPrivateKeyFromFile - Gets RSA private key from a file.
|
||||
/// \param filePath - File path to private key file.
|
||||
/// \param password - Private key password.
|
||||
/// \return - Returns 'OpenSSL EVP_PKEY structure' or 'nullptr', if error happened. Returned value must be cleaned up with 'EVP_PKEY_free()' to avoid memory leak.
|
||||
///
|
||||
EVP_PKEY* QSimpleCrypto::QRsa::getPrivateKeyFromFile(const QByteArray& filePath, const QByteArray& password)
|
||||
{
|
||||
try {
|
||||
/* Initialize BIO */
|
||||
std::unique_ptr<BIO, void (*)(BIO*)> bioPrivateKey { BIO_new_file(filePath.data(), "r"), BIO_free_all };
|
||||
if (bioPrivateKey == nullptr) {
|
||||
throw std::runtime_error("Couldn't initialize bioPrivateKey. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Initialize EVP_PKEY */
|
||||
EVP_PKEY* keyStore = nullptr;
|
||||
if (!(keyStore = EVP_PKEY_new())) {
|
||||
throw std::runtime_error("Couldn't initialize keyStore. EVP_PKEY_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Write private key to file */
|
||||
if (!PEM_read_bio_PrivateKey(bioPrivateKey.get(), &keyStore, nullptr, (void*)password.data())) {
|
||||
throw std::runtime_error("Couldn't read private key. PEM_read_bio_PrivateKey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
return keyStore;
|
||||
|
||||
} catch (std::exception& exception) {
|
||||
QSimpleCrypto::QRsa::error.setError(1, exception.what());
|
||||
return nullptr;
|
||||
} catch (...) {
|
||||
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QRSA::encrypt - Encrypt data with RSA algorithm.
|
||||
/// \param plaintext - Text that must be encrypted.
|
||||
/// \param rsa - OpenSSL RSA structure.
|
||||
/// \param encryptType - Public or private encrypt type. (PUBLIC_ENCRYPT, PRIVATE_ENCRYPT).
|
||||
/// \param padding - OpenSSL RSA padding can be used with: 'RSA_PKCS1_PADDING', 'RSA_NO_PADDING' and etc.
|
||||
/// \return Returns encrypted data or "", if error happened.
|
||||
///
|
||||
QByteArray QSimpleCrypto::QRsa::encrypt(QByteArray plainText, RSA* rsa, const int& encryptType, const int& padding)
|
||||
{
|
||||
try {
|
||||
/* Initialize array. Here encrypted data will be saved */
|
||||
std::unique_ptr<unsigned char[]> cipherText { new unsigned char[RSA_size(rsa)]() };
|
||||
if (cipherText == nullptr) {
|
||||
throw std::runtime_error("Couldn't allocate memory for 'cipherText'.");
|
||||
}
|
||||
|
||||
/* Result of encryption operation */
|
||||
short int result = 0;
|
||||
|
||||
/* Execute encryption operation */
|
||||
if (encryptType == PublicDecrypt) {
|
||||
result = RSA_public_encrypt(plainText.size(), reinterpret_cast<unsigned char*>(plainText.data()), cipherText.get(), rsa, padding);
|
||||
} else if (encryptType == PrivateDecrypt) {
|
||||
result = RSA_private_encrypt(plainText.size(), reinterpret_cast<unsigned char*>(plainText.data()), cipherText.get(), rsa, padding);
|
||||
}
|
||||
|
||||
/* Check for result */
|
||||
if (result <= -1) {
|
||||
throw std::runtime_error("Couldn't encrypt data. Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Get encrypted data */
|
||||
const QByteArray& encryptedData = QByteArray(reinterpret_cast<char*>(cipherText.get()), RSA_size(rsa));
|
||||
|
||||
return encryptedData;
|
||||
} catch (std::exception& exception) {
|
||||
QSimpleCrypto::QRsa::error.setError(1, exception.what());
|
||||
return "";
|
||||
} catch (...) {
|
||||
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QRSA::decrypt - Decrypt data with RSA algorithm.
|
||||
/// \param cipherText - Text that must be decrypted.
|
||||
/// \param rsa - OpenSSL RSA structure.
|
||||
/// \param decryptType - Public or private type. (PUBLIC_DECRYPT, PRIVATE_DECRYPT).
|
||||
/// \param padding - RSA padding can be used with: 'RSA_PKCS1_PADDING', 'RSA_NO_PADDING' and etc.
|
||||
/// \return - Returns decrypted data or "", if error happened.
|
||||
///
|
||||
QByteArray QSimpleCrypto::QRsa::decrypt(QByteArray cipherText, RSA* rsa, const int& decryptType, const int& padding)
|
||||
{
|
||||
try {
|
||||
/* Initialize array. Here decrypted data will be saved */
|
||||
std::unique_ptr<unsigned char[]> plainText { new unsigned char[cipherText.size()]() };
|
||||
if (plainText == nullptr) {
|
||||
throw std::runtime_error("Couldn't allocate memory for 'plainText'.");
|
||||
}
|
||||
|
||||
/* Result of decryption operation */
|
||||
short int result = 0;
|
||||
|
||||
/* Execute decryption operation */
|
||||
if (decryptType == PublicDecrypt) {
|
||||
result = RSA_public_decrypt(RSA_size(rsa), reinterpret_cast<unsigned char*>(cipherText.data()), plainText.get(), rsa, padding);
|
||||
} else if (decryptType == PrivateDecrypt) {
|
||||
result = RSA_private_decrypt(RSA_size(rsa), reinterpret_cast<unsigned char*>(cipherText.data()), plainText.get(), rsa, padding);
|
||||
}
|
||||
|
||||
/* Check for result */
|
||||
if (result <= -1) {
|
||||
throw std::runtime_error("Couldn't decrypt data. Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Get decrypted data */
|
||||
const QByteArray& decryptedData = QByteArray(reinterpret_cast<char*>(plainText.get()));
|
||||
|
||||
return decryptedData;
|
||||
} catch (std::exception& exception) {
|
||||
QSimpleCrypto::QRsa::error.setError(1, exception.what());
|
||||
return "";
|
||||
} catch (...) {
|
||||
QSimpleCrypto::QRsa::error.setError(2, "Unknown error!");
|
||||
return "";
|
||||
}
|
||||
}
|
|
@ -1,234 +0,0 @@
|
|||
/**
|
||||
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution
|
||||
**/
|
||||
|
||||
#include "include/QX509.h"
|
||||
|
||||
QSimpleCrypto::QX509::QX509()
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QX509::loadCertificateFromFile - Function load X509 from file and returns OpenSSL structure.
|
||||
/// \param fileName - File path to certificate.
|
||||
/// \return Returns OpenSSL X509 structure or nullptr, if error happened. Returned value must be cleaned up with 'X509_free' to avoid memory leak.
|
||||
///
|
||||
X509* QSimpleCrypto::QX509::loadCertificateFromFile(const QByteArray& fileName)
|
||||
{
|
||||
try {
|
||||
/* Initialize X509 */
|
||||
X509* x509 = nullptr;
|
||||
if (!(x509 = X509_new())) {
|
||||
throw std::runtime_error("Couldn't initialize X509. X509_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Initialize BIO */
|
||||
std::unique_ptr<BIO, void (*)(BIO*)> certFile { BIO_new_file(fileName.data(), "r+"), BIO_free_all };
|
||||
if (certFile == nullptr) {
|
||||
throw std::runtime_error("Couldn't initialize certFile. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Read file */
|
||||
if (!PEM_read_bio_X509(certFile.get(), &x509, nullptr, nullptr)) {
|
||||
throw std::runtime_error("Couldn't read certificate file from disk. PEM_read_bio_X509(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
return x509;
|
||||
} catch (std::exception& exception) {
|
||||
QSimpleCrypto::QX509::error.setError(1, exception.what());
|
||||
return nullptr;
|
||||
} catch (...) {
|
||||
QSimpleCrypto::QX509::error.setError(2, "Unknown error!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QX509::signCertificate - Function signs X509 certificate and returns signed X509 OpenSSL structure.
|
||||
/// \param endCertificate - Certificate that will be signed
|
||||
/// \param caCertificate - CA certificate that will sign end certificate
|
||||
/// \param caPrivateKey - CA certificate private key
|
||||
/// \param fileName - With that name certificate will be saved. Leave "", if don't need to save it
|
||||
/// \return Returns OpenSSL X509 structure or nullptr, if error happened.
|
||||
///
|
||||
X509* QSimpleCrypto::QX509::signCertificate(X509* endCertificate, X509* caCertificate, EVP_PKEY* caPrivateKey, const QByteArray& fileName)
|
||||
{
|
||||
try {
|
||||
/* Set issuer to CA's subject. */
|
||||
if (!X509_set_issuer_name(endCertificate, X509_get_subject_name(caCertificate))) {
|
||||
throw std::runtime_error("Couldn't set issuer name for X509. X509_set_issuer_name(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Sign the certificate with key. */
|
||||
if (!X509_sign(endCertificate, caPrivateKey, EVP_sha256())) {
|
||||
throw std::runtime_error("Couldn't sign X509. X509_sign(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Write certificate file on disk. If needed */
|
||||
if (!fileName.isEmpty()) {
|
||||
/* Initialize BIO */
|
||||
std::unique_ptr<BIO, void (*)(BIO*)> certFile { BIO_new_file(fileName.data(), "w+"), BIO_free_all };
|
||||
if (certFile == nullptr) {
|
||||
throw std::runtime_error("Couldn't initialize certFile. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Write file on disk */
|
||||
if (!PEM_write_bio_X509(certFile.get(), endCertificate)) {
|
||||
throw std::runtime_error("Couldn't write certificate file on disk. PEM_write_bio_X509(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
}
|
||||
|
||||
return endCertificate;
|
||||
} catch (std::exception& exception) {
|
||||
QSimpleCrypto::QX509::error.setError(1, exception.what());
|
||||
return nullptr;
|
||||
} catch (...) {
|
||||
QSimpleCrypto::QX509::error.setError(2, "Unknown error!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QX509::verifyCertificate - Function verifies X509 certificate and returns verified X509 OpenSSL structure.
|
||||
/// \param x509 - OpenSSL X509. That certificate will be verified.
|
||||
/// \param store - Trusted certificate must be added to X509_Store with 'addCertificateToStore(X509_STORE* ctx, X509* x509)'.
|
||||
/// \return Returns OpenSSL X509 structure or nullptr, if error happened
|
||||
///
|
||||
X509* QSimpleCrypto::QX509::verifyCertificate(X509* x509, X509_STORE* store)
|
||||
{
|
||||
try {
|
||||
/* Initialize X509_STORE_CTX */
|
||||
std::unique_ptr<X509_STORE_CTX, void (*)(X509_STORE_CTX*)> ctx { X509_STORE_CTX_new(), X509_STORE_CTX_free };
|
||||
if (ctx == nullptr) {
|
||||
throw std::runtime_error("Couldn't initialize keyStore. EVP_PKEY_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Set up CTX for a subsequent verification operation */
|
||||
if (!X509_STORE_CTX_init(ctx.get(), store, x509, nullptr)) {
|
||||
throw std::runtime_error("Couldn't initialize X509_STORE_CTX. X509_STORE_CTX_init(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Verify X509 */
|
||||
if (!X509_verify_cert(ctx.get())) {
|
||||
throw std::runtime_error("Couldn't verify cert. X509_verify_cert(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
return x509;
|
||||
} catch (std::exception& exception) {
|
||||
QSimpleCrypto::QX509::error.setError(1, exception.what());
|
||||
return nullptr;
|
||||
} catch (...) {
|
||||
QSimpleCrypto::QX509::error.setError(2, "Unknown error!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QX509::generateSelfSignedCertificate - Function generatesand returns self signed X509.
|
||||
/// \param rsa - OpenSSL RSA.
|
||||
/// \param additionalData - Certificate information.
|
||||
/// \param certificateFileName - With that name certificate will be saved. Leave "", if don't need to save it.
|
||||
/// \param md - OpenSSL EVP_MD structure. Example: EVP_sha512().
|
||||
/// \param serialNumber - X509 certificate serial number.
|
||||
/// \param version - X509 certificate version.
|
||||
/// \param notBefore - X509 start date.
|
||||
/// \param notAfter - X509 end date.
|
||||
/// \return Returns OpenSSL X509 structure or nullptr, if error happened. Returned value must be cleaned up with 'X509_free' to avoid memory leak.
|
||||
///
|
||||
X509* QSimpleCrypto::QX509::generateSelfSignedCertificate(RSA* rsa, const QMap<QByteArray, QByteArray>& additionalData,
|
||||
const QByteArray& certificateFileName, const EVP_MD* md,
|
||||
const long& serialNumber, const long& version,
|
||||
const long& notBefore, const long& notAfter)
|
||||
{
|
||||
try {
|
||||
/* Initialize X509 */
|
||||
X509* x509 = nullptr;
|
||||
if (!(x509 = X509_new())) {
|
||||
throw std::runtime_error("Couldn't initialize X509. X509_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Initialize EVP_PKEY */
|
||||
std::unique_ptr<EVP_PKEY, void (*)(EVP_PKEY*)> keyStore { EVP_PKEY_new(), EVP_PKEY_free };
|
||||
if (keyStore == nullptr) {
|
||||
throw std::runtime_error("Couldn't initialize keyStore. EVP_PKEY_new(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Sign rsa key */
|
||||
if (!EVP_PKEY_assign_RSA(keyStore.get(), rsa)) {
|
||||
throw std::runtime_error("Couldn't assign rsa. EVP_PKEY_assign_RSA(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Set certificate serial number. */
|
||||
if (!ASN1_INTEGER_set(X509_get_serialNumber(x509), serialNumber)) {
|
||||
throw std::runtime_error("Couldn't set serial number. ASN1_INTEGER_set(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Set certificate version */
|
||||
if (!X509_set_version(x509, version)) {
|
||||
throw std::runtime_error("Couldn't set version. X509_set_version(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Set certificate creation and expiration date */
|
||||
X509_gmtime_adj(X509_get_notBefore(x509), notBefore);
|
||||
X509_gmtime_adj(X509_get_notAfter(x509), notAfter);
|
||||
|
||||
/* Set certificate public key */
|
||||
if (!X509_set_pubkey(x509, keyStore.get())) {
|
||||
throw std::runtime_error("Couldn't set public key. X509_set_pubkey(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Initialize X509_NAME */
|
||||
X509_NAME* x509Name = X509_get_subject_name(x509);
|
||||
if (x509Name == nullptr) {
|
||||
throw std::runtime_error("Couldn't initialize X509_NAME. X509_NAME(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Add additional data to certificate */
|
||||
QMapIterator<QByteArray, QByteArray> certificateInformationList(additionalData);
|
||||
while (certificateInformationList.hasNext()) {
|
||||
/* Read next item in list */
|
||||
certificateInformationList.next();
|
||||
|
||||
/* Set additional data */
|
||||
if (!X509_NAME_add_entry_by_txt(x509Name, certificateInformationList.key().data(), MBSTRING_UTF8, reinterpret_cast<const unsigned char*>(certificateInformationList.value().data()), -1, -1, 0)) {
|
||||
throw std::runtime_error("Couldn't set additional information. X509_NAME_add_entry_by_txt(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
}
|
||||
|
||||
/* Set certificate info */
|
||||
if (!X509_set_issuer_name(x509, x509Name)) {
|
||||
throw std::runtime_error("Couldn't set issuer name. X509_set_issuer_name(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Sign certificate */
|
||||
if (!X509_sign(x509, keyStore.get(), md)) {
|
||||
throw std::runtime_error("Couldn't sign X509. X509_sign(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Write certificate file on disk. If needed */
|
||||
if (!certificateFileName.isEmpty()) {
|
||||
/* Initialize BIO */
|
||||
std::unique_ptr<BIO, void (*)(BIO*)> certFile { BIO_new_file(certificateFileName.data(), "w+"), BIO_free_all };
|
||||
if (certFile == nullptr) {
|
||||
throw std::runtime_error("Couldn't initialize certFile. BIO_new_file(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
|
||||
/* Write file on disk */
|
||||
if (!PEM_write_bio_X509(certFile.get(), x509)) {
|
||||
throw std::runtime_error("Couldn't write certificate file on disk. PEM_write_bio_X509(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
}
|
||||
}
|
||||
|
||||
return x509;
|
||||
} catch (std::exception& exception) {
|
||||
QSimpleCrypto::QX509::error.setError(1, exception.what());
|
||||
return nullptr;
|
||||
} catch (...) {
|
||||
QSimpleCrypto::QX509::error.setError(2, "Unknown error!");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
|
@ -1,176 +0,0 @@
|
|||
/**
|
||||
* Copyright 2021 BrutalWizard (https://github.com/bru74lw1z4rd). All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License 2.0 (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution
|
||||
**/
|
||||
|
||||
#include "include/QX509Store.h"
|
||||
|
||||
QSimpleCrypto::QX509Store::QX509Store()
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QX509::addCertificateToStore
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \param x509 - OpenSSL X509.
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool QSimpleCrypto::QX509Store::addCertificateToStore(X509_STORE* store, X509* x509)
|
||||
{
|
||||
if (!X509_STORE_add_cert(store, x509)) {
|
||||
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't add certificate to X509_STORE. X509_STORE_add_cert(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QX509Store::addLookup
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \param method - OpenSSL X509_LOOKUP_METHOD. Example: X509_LOOKUP_file.
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool QSimpleCrypto::QX509Store::addLookup(X509_STORE* store, X509_LOOKUP_METHOD* method)
|
||||
{
|
||||
if (!X509_STORE_add_lookup(store, method)) {
|
||||
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't add lookup to X509_STORE. X509_STORE_add_lookup(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QX509Store::setCertificateDepth
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \param depth - That is the maximum number of untrusted CA certificates that can appear in a chain. Example: 0.
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool QSimpleCrypto::QX509Store::setDepth(X509_STORE* store, const int& depth)
|
||||
{
|
||||
if (!X509_STORE_set_depth(store, depth)) {
|
||||
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't set depth for X509_STORE. X509_STORE_set_depth(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QX509Store::setFlag
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \param flag - The verification flags consists of zero or more of the following flags ored together. Example: X509_V_FLAG_CRL_CHECK.
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool QSimpleCrypto::QX509Store::setFlag(X509_STORE* store, const unsigned long& flag)
|
||||
{
|
||||
if (!X509_STORE_set_flags(store, flag)) {
|
||||
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't set flag for X509_STORE. X509_STORE_set_flags(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QX509Store::setFlag
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \param purpose - Verification purpose in param to purpose. Example: X509_PURPOSE_ANY.
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool QSimpleCrypto::QX509Store::setPurpose(X509_STORE* store, const int& purpose)
|
||||
{
|
||||
if (!X509_STORE_set_purpose(store, purpose)) {
|
||||
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't set purpose for X509_STORE. X509_STORE_set_purpose(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QX509Store::setTrust
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \param trust - Trust Level. Example: X509_TRUST_SSL_SERVER.
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool QSimpleCrypto::QX509Store::setTrust(X509_STORE* store, const int& trust)
|
||||
{
|
||||
if (!X509_STORE_set_trust(store, trust)) {
|
||||
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't set trust for X509_STORE. X509_STORE_set_trust(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QX509Store::setDefaultPaths
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool QSimpleCrypto::QX509Store::setDefaultPaths(X509_STORE* store)
|
||||
{
|
||||
if (!X509_STORE_set_default_paths(store)) {
|
||||
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't set default paths for X509_STORE. X509_STORE_set_default_paths(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QX509Store::loadLocations
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \param fileName - File name. Example: "caCertificate.pem".
|
||||
/// \param dirPath - Path to file. Example: "path/To/File".
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool QSimpleCrypto::QX509Store::loadLocations(X509_STORE* store, const QByteArray& fileName, const QByteArray& dirPath)
|
||||
{
|
||||
if (!X509_STORE_load_locations(store, fileName, dirPath)) {
|
||||
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't load locations for X509_STORE. X509_STORE_load_locations(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QX509Store::loadLocations
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \param file - Qt QFile that will be loaded.
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool QSimpleCrypto::QX509Store::loadLocations(X509_STORE* store, const QFile& file)
|
||||
{
|
||||
/* Initialize QFileInfo to read information about file */
|
||||
QFileInfo info(file);
|
||||
|
||||
if (!X509_STORE_load_locations(store, info.fileName().toLocal8Bit(), info.absoluteDir().path().toLocal8Bit())) {
|
||||
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't load locations for X509_STORE. X509_STORE_load_locations(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
///
|
||||
/// \brief QSimpleCrypto::QX509Store::loadLocations
|
||||
/// \param store - OpenSSL X509_STORE.
|
||||
/// \param fileInfo - Qt QFileInfo.
|
||||
/// \return Returns 'true' on success and 'false', if error happened.
|
||||
///
|
||||
bool QSimpleCrypto::QX509Store::loadLocations(X509_STORE* store, const QFileInfo& fileInfo)
|
||||
{
|
||||
if (!X509_STORE_load_locations(store, fileInfo.fileName().toLocal8Bit(), fileInfo.absoluteDir().path().toLocal8Bit())) {
|
||||
QSimpleCrypto::QX509Store::error.setError(1, "Couldn't load locations for X509_STORE. X509_STORE_load_locations(). Error: " + QByteArray(ERR_error_string(ERR_get_error(), nullptr)));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -24,6 +24,9 @@ execute_process(
|
|||
|
||||
add_definitions(-DGIT_COMMIT_HASH="${GIT_COMMIT_HASH}")
|
||||
|
||||
add_definitions(-DPROD_AGW_PUBLIC_KEY="$ENV{PROD_AGW_PUBLIC_KEY}")
|
||||
add_definitions(-DPROD_PROXY_STORAGE_KEY="$ENV{PROD_PROXY_STORAGE_KEY}")
|
||||
|
||||
if(IOS)
|
||||
set(PACKAGES ${PACKAGES} Multimedia)
|
||||
endif()
|
||||
|
@ -136,6 +139,7 @@ set(HEADERS ${HEADERS}
|
|||
${CMAKE_CURRENT_LIST_DIR}/core/networkUtilities.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/serialization.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/serialization/transfer.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/core/enums/apiEnums.h
|
||||
)
|
||||
|
||||
# Mozilla headres
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
#include <QClipboard>
|
||||
#include <QFontDatabase>
|
||||
#include <QMimeData>
|
||||
#include <QQuickItem>
|
||||
#include <QQuickStyle>
|
||||
#include <QResource>
|
||||
#include <QStandardPaths>
|
||||
#include <QTextDocument>
|
||||
#include <QTimer>
|
||||
#include <QTranslator>
|
||||
#include <QQuickItem>
|
||||
|
||||
#include "logger.h"
|
||||
#include "ui/models/installedAppsModel.h"
|
||||
|
@ -116,7 +116,7 @@ void AmneziaApplication::init()
|
|||
}
|
||||
|
||||
connect(AndroidController::instance(), &AndroidController::importConfigFromOutside, [this](QString data) {
|
||||
m_pageController->replaceStartPage();
|
||||
m_pageController->goToPageHome();
|
||||
m_importController->extractConfigFromData(data);
|
||||
m_pageController->goToPageViewConfig();
|
||||
});
|
||||
|
@ -127,13 +127,13 @@ void AmneziaApplication::init()
|
|||
#ifdef Q_OS_IOS
|
||||
IosController::Instance()->initialize();
|
||||
connect(IosController::Instance(), &IosController::importConfigFromOutside, [this](QString data) {
|
||||
m_pageController->replaceStartPage();
|
||||
m_pageController->goToPageHome();
|
||||
m_importController->extractConfigFromData(data);
|
||||
m_pageController->goToPageViewConfig();
|
||||
});
|
||||
|
||||
connect(IosController::Instance(), &IosController::importBackupFromOutside, [this](QString filePath) {
|
||||
m_pageController->replaceStartPage();
|
||||
m_pageController->goToPageHome();
|
||||
m_pageController->goToPageSettingsBackup();
|
||||
m_settingsController->importBackupFromOutside(filePath);
|
||||
});
|
||||
|
@ -361,6 +361,18 @@ void AmneziaApplication::initModels()
|
|||
m_engine->rootContext()->setContextProperty("ClientManagementModel", m_clientManagementModel.get());
|
||||
connect(m_clientManagementModel.get(), &ClientManagementModel::adminConfigRevoked, m_serversModel.get(),
|
||||
&ServersModel::clearCachedProfile);
|
||||
|
||||
m_apiServicesModel.reset(new ApiServicesModel(this));
|
||||
m_engine->rootContext()->setContextProperty("ApiServicesModel", m_apiServicesModel.get());
|
||||
|
||||
m_apiCountryModel.reset(new ApiCountryModel(this));
|
||||
m_engine->rootContext()->setContextProperty("ApiCountryModel", m_apiCountryModel.get());
|
||||
connect(m_serversModel.get(), &ServersModel::updateApiLanguageModel, this, [this]() {
|
||||
m_apiCountryModel->updateModel(m_serversModel->getProcessedServerData("apiAvailableCountries").toJsonArray(),
|
||||
m_serversModel->getProcessedServerData("apiServerCountryCode").toString());
|
||||
});
|
||||
connect(m_serversModel.get(), &ServersModel::updateApiServicesModel, this,
|
||||
[this]() { m_apiServicesModel->updateModel(m_serversModel->getProcessedServerData("apiConfig").toJsonObject()); });
|
||||
}
|
||||
|
||||
void AmneziaApplication::initControllers()
|
||||
|
@ -369,25 +381,26 @@ void AmneziaApplication::initControllers()
|
|||
new ConnectionController(m_serversModel, m_containersModel, m_clientManagementModel, m_vpnConnection, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("ConnectionController", m_connectionController.get());
|
||||
|
||||
connect(m_connectionController.get(), qOverload<const QString &>(&ConnectionController::connectionErrorOccurred), this, [this](const QString &errorMessage) {
|
||||
emit m_pageController->showErrorMessage(errorMessage);
|
||||
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
||||
});
|
||||
connect(m_connectionController.get(), qOverload<const QString &>(&ConnectionController::connectionErrorOccurred), this,
|
||||
[this](const QString &errorMessage) {
|
||||
emit m_pageController->showErrorMessage(errorMessage);
|
||||
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
||||
});
|
||||
|
||||
connect(m_connectionController.get(), qOverload<ErrorCode>(&ConnectionController::connectionErrorOccurred), this, [this](ErrorCode errorCode) {
|
||||
emit m_pageController->showErrorMessage(errorCode);
|
||||
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
||||
});
|
||||
connect(m_connectionController.get(), qOverload<ErrorCode>(&ConnectionController::connectionErrorOccurred), this,
|
||||
[this](ErrorCode errorCode) {
|
||||
emit m_pageController->showErrorMessage(errorCode);
|
||||
emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected);
|
||||
});
|
||||
|
||||
connect(m_connectionController.get(), &ConnectionController::connectButtonClicked, m_connectionController.get(),
|
||||
&ConnectionController::toggleConnection, Qt::QueuedConnection);
|
||||
|
||||
connect(this, &AmneziaApplication::translationsUpdated, m_connectionController.get(), &ConnectionController::onTranslationsUpdated);
|
||||
|
||||
m_pageController.reset(new PageController(m_serversModel, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("PageController", m_pageController.get());
|
||||
|
||||
m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_protocolsModel, m_clientManagementModel, m_settings));
|
||||
m_installController.reset(new InstallController(m_serversModel, m_containersModel, m_protocolsModel, m_clientManagementModel,
|
||||
m_apiServicesModel, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("InstallController", m_installController.get());
|
||||
connect(m_installController.get(), &InstallController::passphraseRequestStarted, m_pageController.get(),
|
||||
&PageController::showPassphraseRequestDrawer);
|
||||
|
@ -396,6 +409,30 @@ void AmneziaApplication::initControllers()
|
|||
connect(m_installController.get(), &InstallController::currentContainerUpdated, m_connectionController.get(),
|
||||
&ConnectionController::onCurrentContainerUpdated);
|
||||
|
||||
connect(m_installController.get(), &InstallController::updateServerFromApiFinished, this, [this]() {
|
||||
disconnect(m_reloadConfigErrorOccurredConnection);
|
||||
emit m_connectionController->configFromApiUpdated();
|
||||
});
|
||||
|
||||
connect(m_connectionController.get(), &ConnectionController::updateApiConfigFromGateway, this, [this]() {
|
||||
m_reloadConfigErrorOccurredConnection = connect(
|
||||
m_installController.get(), qOverload<ErrorCode>(&InstallController::installationErrorOccurred), this,
|
||||
[this]() { emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected); },
|
||||
static_cast<Qt::ConnectionType>(Qt::AutoConnection || Qt::SingleShotConnection));
|
||||
m_installController->updateServiceFromApi(m_serversModel->getDefaultServerIndex(), "", "");
|
||||
});
|
||||
|
||||
connect(m_connectionController.get(), &ConnectionController::updateApiConfigFromTelegram, this, [this]() {
|
||||
m_reloadConfigErrorOccurredConnection = connect(
|
||||
m_installController.get(), qOverload<ErrorCode>(&InstallController::installationErrorOccurred), this,
|
||||
[this]() { emit m_vpnConnection->connectionStateChanged(Vpn::ConnectionState::Disconnected); },
|
||||
static_cast<Qt::ConnectionType>(Qt::AutoConnection || Qt::SingleShotConnection));
|
||||
m_serversModel->removeApiConfig(m_serversModel->getDefaultServerIndex());
|
||||
m_installController->updateServiceFromTelegram(m_serversModel->getDefaultServerIndex());
|
||||
});
|
||||
|
||||
connect(this, &AmneziaApplication::translationsUpdated, m_connectionController.get(), &ConnectionController::onTranslationsUpdated);
|
||||
|
||||
m_importController.reset(new ImportController(m_serversModel, m_containersModel, m_settings));
|
||||
m_engine->rootContext()->setContextProperty("ImportController", m_importController.get());
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#include "ui/models/sites_model.h"
|
||||
#include "ui/models/clientManagementModel.h"
|
||||
#include "ui/models/appSplitTunnelingModel.h"
|
||||
#include "ui/models/apiServicesModel.h"
|
||||
#include "ui/models/apiCountryModel.h"
|
||||
|
||||
#define amnApp (static_cast<AmneziaApplication *>(QCoreApplication::instance()))
|
||||
|
||||
|
@ -103,6 +105,8 @@ private:
|
|||
QSharedPointer<SitesModel> m_sitesModel;
|
||||
QSharedPointer<AppSplitTunnelingModel> m_appSplitTunnelingModel;
|
||||
QSharedPointer<ClientManagementModel> m_clientManagementModel;
|
||||
QSharedPointer<ApiServicesModel> m_apiServicesModel;
|
||||
QSharedPointer<ApiCountryModel> m_apiCountryModel;
|
||||
|
||||
QScopedPointer<OpenVpnConfigModel> m_openVpnConfigModel;
|
||||
QScopedPointer<ShadowSocksConfigModel> m_shadowSocksConfigModel;
|
||||
|
@ -134,6 +138,8 @@ private:
|
|||
QScopedPointer<AppSplitTunnelingController> m_appSplitTunnelingController;
|
||||
|
||||
QNetworkAccessManager *m_nam;
|
||||
|
||||
QMetaObject::Connection m_reloadConfigErrorOccurredConnection;
|
||||
};
|
||||
|
||||
#endif // AMNEZIA_APPLICATION_H
|
||||
|
|
|
@ -8,9 +8,9 @@ endif()
|
|||
|
||||
add_subdirectory(${CLIENT_ROOT_DIR}/3rd/SortFilterProxyModel)
|
||||
set(LIBS ${LIBS} SortFilterProxyModel)
|
||||
include(${CLIENT_ROOT_DIR}/cmake/QSimpleCrypto.cmake)
|
||||
|
||||
include(${CLIENT_ROOT_DIR}/3rd/qrcodegen/qrcodegen.cmake)
|
||||
include(${CLIENT_ROOT_DIR}/3rd/QSimpleCrypto/QSimpleCrypto.cmake)
|
||||
|
||||
set(LIBSSH_ROOT_DIR "${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/libssh/")
|
||||
set(OPENSSL_ROOT_DIR "${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/openssl/")
|
||||
|
@ -83,13 +83,12 @@ set(BUILD_WITH_QT6 ON)
|
|||
add_subdirectory(${CLIENT_ROOT_DIR}/3rd/qtkeychain)
|
||||
set(LIBS ${LIBS} qt6keychain)
|
||||
|
||||
|
||||
include_directories(
|
||||
${OPENSSL_INCLUDE_DIR}
|
||||
${LIBSSH_INCLUDE_DIR}/include
|
||||
${LIBSSH_ROOT_DIR}/include
|
||||
${CLIENT_ROOT_DIR}/3rd/libssh/include
|
||||
${CLIENT_ROOT_DIR}/3rd/QSimpleCrypto/include
|
||||
${CLIENT_ROOT_DIR}/3rd/QSimpleCrypto/src/include
|
||||
${CLIENT_ROOT_DIR}/3rd/qtkeychain/qtkeychain
|
||||
${CMAKE_CURRENT_BINARY_DIR}/3rd/qtkeychain
|
||||
${CMAKE_CURRENT_BINARY_DIR}/3rd/libssh/include
|
||||
|
|
21
client/cmake/QSimpleCrypto.cmake
Normal file
|
@ -0,0 +1,21 @@
|
|||
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/..)
|
||||
set(QSIMPLECRYPTO_DIR ${CLIENT_ROOT_DIR}/3rd/QSimpleCrypto/src)
|
||||
|
||||
include_directories(${QSIMPLECRYPTO_DIR})
|
||||
|
||||
set(HEADERS ${HEADERS}
|
||||
${QSIMPLECRYPTO_DIR}/include/QAead.h
|
||||
${QSIMPLECRYPTO_DIR}/include/QBlockCipher.h
|
||||
${QSIMPLECRYPTO_DIR}/include/QRsa.h
|
||||
${QSIMPLECRYPTO_DIR}/include/QSimpleCrypto_global.h
|
||||
${QSIMPLECRYPTO_DIR}/include/QX509.h
|
||||
${QSIMPLECRYPTO_DIR}/include/QX509Store.h
|
||||
)
|
||||
|
||||
set(SOURCES ${SOURCES}
|
||||
${QSIMPLECRYPTO_DIR}/sources/QAead.cpp
|
||||
${QSIMPLECRYPTO_DIR}/sources/QBlockCipher.cpp
|
||||
${QSIMPLECRYPTO_DIR}/sources/QRsa.cpp
|
||||
${QSIMPLECRYPTO_DIR}/sources/QX509.cpp
|
||||
${QSIMPLECRYPTO_DIR}/sources/QX509Store.cpp
|
||||
)
|
|
@ -5,7 +5,11 @@
|
|||
#include <QNetworkReply>
|
||||
#include <QtConcurrent>
|
||||
|
||||
#include "QBlockCipher.h"
|
||||
#include "QRsa.h"
|
||||
|
||||
#include "amnezia_application.h"
|
||||
#include "core/enums/apiEnums.h"
|
||||
#include "configurators/wireguard_configurator.h"
|
||||
#include "version.h"
|
||||
|
||||
|
@ -25,25 +29,74 @@ namespace
|
|||
constexpr char uuid[] = "installation_uuid";
|
||||
constexpr char osVersion[] = "os_version";
|
||||
constexpr char appVersion[] = "app_version";
|
||||
|
||||
constexpr char userCountryCode[] = "user_country_code";
|
||||
constexpr char serverCountryCode[] = "server_country_code";
|
||||
constexpr char serviceType[] = "service_type";
|
||||
|
||||
constexpr char aesKey[] = "aes_key";
|
||||
constexpr char aesIv[] = "aes_iv";
|
||||
constexpr char aesSalt[] = "aes_salt";
|
||||
|
||||
constexpr char apiPayload[] = "api_payload";
|
||||
constexpr char keyPayload[] = "key_payload";
|
||||
}
|
||||
|
||||
const QStringList proxyStorageUrl = {""};
|
||||
|
||||
ErrorCode checkErrors(const QList<QSslError> &sslErrors, QNetworkReply *reply)
|
||||
{
|
||||
if (!sslErrors.empty()) {
|
||||
qDebug().noquote() << sslErrors;
|
||||
return ErrorCode::ApiConfigSslError;
|
||||
} else if (reply->error() == QNetworkReply::NoError) {
|
||||
return ErrorCode::NoError;
|
||||
} else if (reply->error() == QNetworkReply::NetworkError::OperationCanceledError
|
||||
|| reply->error() == QNetworkReply::NetworkError::TimeoutError) {
|
||||
return ErrorCode::ApiConfigTimeoutError;
|
||||
} else {
|
||||
QString err = reply->errorString();
|
||||
qDebug() << QString::fromUtf8(reply->readAll());
|
||||
qDebug() << reply->error();
|
||||
qDebug() << err;
|
||||
qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
|
||||
return ErrorCode::ApiConfigDownloadError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ApiController::ApiController(QObject *parent) : QObject(parent)
|
||||
ApiController::ApiController(const QString &gatewayEndpoint, QObject *parent) : QObject(parent), m_gatewayEndpoint(gatewayEndpoint)
|
||||
{
|
||||
}
|
||||
|
||||
void ApiController::processApiConfig(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData, QString &config)
|
||||
void ApiController::fillServerConfig(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData,
|
||||
const QByteArray &apiResponseBody, QJsonObject &serverConfig)
|
||||
{
|
||||
if (protocol == configKey::cloak) {
|
||||
config.replace("<key>", "<key>\n");
|
||||
config.replace("$OPENVPN_PRIV_KEY", apiPayloadData.certRequest.privKey);
|
||||
QString data = QJsonDocument::fromJson(apiResponseBody).object().value(config_key::config).toString();
|
||||
|
||||
data.replace("vpn://", "");
|
||||
QByteArray ba = QByteArray::fromBase64(data.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||
|
||||
if (ba.isEmpty()) {
|
||||
emit errorOccurred(ErrorCode::ApiConfigEmptyError);
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray ba_uncompressed = qUncompress(ba);
|
||||
if (!ba_uncompressed.isEmpty()) {
|
||||
ba = ba_uncompressed;
|
||||
}
|
||||
|
||||
QString configStr = ba;
|
||||
if (protocol == configKey::cloak) {
|
||||
configStr.replace("<key>", "<key>\n");
|
||||
configStr.replace("$OPENVPN_PRIV_KEY", apiPayloadData.certRequest.privKey);
|
||||
} else if (protocol == configKey::awg) {
|
||||
config.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", apiPayloadData.wireGuardClientPrivKey);
|
||||
auto serverConfig = QJsonDocument::fromJson(config.toUtf8()).object();
|
||||
configStr.replace("$WIREGUARD_CLIENT_PRIVATE_KEY", apiPayloadData.wireGuardClientPrivKey);
|
||||
auto serverConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
|
||||
auto containers = serverConfig.value(config_key::containers).toArray();
|
||||
if (containers.isEmpty()) {
|
||||
return;
|
||||
return; // todo process error
|
||||
}
|
||||
auto container = containers.at(0).toObject();
|
||||
QString containerName = ContainerProps::containerTypeToString(DockerContainer::Awg);
|
||||
|
@ -61,11 +114,75 @@ void ApiController::processApiConfig(const QString &protocol, const ApiControlle
|
|||
container[containerName] = containerConfig;
|
||||
containers.replace(0, container);
|
||||
serverConfig[config_key::containers] = containers;
|
||||
config = QString(QJsonDocument(serverConfig).toJson());
|
||||
configStr = QString(QJsonDocument(serverConfig).toJson());
|
||||
}
|
||||
|
||||
QJsonObject apiConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
|
||||
serverConfig[config_key::dns1] = apiConfig.value(config_key::dns1);
|
||||
serverConfig[config_key::dns2] = apiConfig.value(config_key::dns2);
|
||||
serverConfig[config_key::containers] = apiConfig.value(config_key::containers);
|
||||
serverConfig[config_key::hostName] = apiConfig.value(config_key::hostName);
|
||||
|
||||
if (apiConfig.value(config_key::configVersion).toInt() == ApiConfigSources::AmneziaGateway) {
|
||||
serverConfig[config_key::configVersion] = apiConfig.value(config_key::configVersion);
|
||||
serverConfig[config_key::description] = apiConfig.value(config_key::description);
|
||||
serverConfig[config_key::name] = apiConfig.value(config_key::name);
|
||||
}
|
||||
|
||||
auto defaultContainer = apiConfig.value(config_key::defaultContainer).toString();
|
||||
serverConfig[config_key::defaultContainer] = defaultContainer;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
QStringList ApiController::getProxyUrls()
|
||||
{
|
||||
QNetworkRequest request;
|
||||
request.setTransferTimeout(7000);
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
|
||||
QEventLoop wait;
|
||||
QList<QSslError> sslErrors;
|
||||
QNetworkReply* reply;
|
||||
|
||||
for (const auto &proxyStorageUrl : proxyStorageUrl) {
|
||||
request.setUrl(proxyStorageUrl);
|
||||
reply = amnApp->manager()->get(request);
|
||||
|
||||
connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
|
||||
connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; });
|
||||
wait.exec();
|
||||
|
||||
if (reply->error() == QNetworkReply::NetworkError::NoError) {
|
||||
break;
|
||||
}
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
auto encryptedResponseBody = reply->readAll();
|
||||
reply->deleteLater();
|
||||
|
||||
EVP_PKEY *privateKey = nullptr;
|
||||
QByteArray responseBody;
|
||||
try {
|
||||
QByteArray key = PROD_PROXY_STORAGE_KEY;
|
||||
QSimpleCrypto::QRsa rsa;
|
||||
privateKey = rsa.getPrivateKeyFromByteArray(key, "");
|
||||
responseBody = rsa.decrypt(encryptedResponseBody, privateKey, RSA_PKCS1_PADDING);
|
||||
} catch (...) {
|
||||
qCritical() << "error loading private key from environment variables or decrypting payload";
|
||||
return {};
|
||||
}
|
||||
|
||||
auto endpointsArray = QJsonDocument::fromJson(responseBody).array();
|
||||
|
||||
QStringList endpoints;
|
||||
for (const auto &endpoint : endpointsArray) {
|
||||
endpoints.push_back(endpoint.toString());
|
||||
}
|
||||
return endpoints;
|
||||
}
|
||||
|
||||
ApiController::ApiPayloadData ApiController::generateApiPayloadData(const QString &protocol)
|
||||
{
|
||||
ApiController::ApiPayloadData apiPayload;
|
||||
|
@ -101,8 +218,6 @@ void ApiController::updateServerConfigFromApi(const QString &installationUuid, c
|
|||
QThread::msleep(10);
|
||||
#endif
|
||||
|
||||
auto containerConfig = serverConfig.value(config_key::containers).toArray();
|
||||
|
||||
if (serverConfig.value(config_key::configVersion).toInt()) {
|
||||
QNetworkRequest request;
|
||||
request.setTransferTimeout(7000);
|
||||
|
@ -120,39 +235,13 @@ void ApiController::updateServerConfigFromApi(const QString &installationUuid, c
|
|||
|
||||
QByteArray requestBody = QJsonDocument(apiPayload).toJson();
|
||||
|
||||
QNetworkReply *reply = amnApp->manager()->post(request, requestBody); // ??
|
||||
QNetworkReply *reply = amnApp->manager()->post(request, requestBody);
|
||||
|
||||
QObject::connect(reply, &QNetworkReply::finished, [this, reply, protocol, apiPayloadData, serverIndex, serverConfig]() mutable {
|
||||
if (reply->error() == QNetworkReply::NoError) {
|
||||
QString contents = QString::fromUtf8(reply->readAll());
|
||||
QString data = QJsonDocument::fromJson(contents.toUtf8()).object().value(config_key::config).toString();
|
||||
|
||||
data.replace("vpn://", "");
|
||||
QByteArray ba = QByteArray::fromBase64(data.toUtf8(), QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
|
||||
|
||||
if (ba.isEmpty()) {
|
||||
emit errorOccurred(ErrorCode::ApiConfigEmptyError);
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray ba_uncompressed = qUncompress(ba);
|
||||
if (!ba_uncompressed.isEmpty()) {
|
||||
ba = ba_uncompressed;
|
||||
}
|
||||
|
||||
QString configStr = ba;
|
||||
processApiConfig(protocol, apiPayloadData, configStr);
|
||||
|
||||
QJsonObject apiConfig = QJsonDocument::fromJson(configStr.toUtf8()).object();
|
||||
serverConfig[config_key::dns1] = apiConfig.value(config_key::dns1);
|
||||
serverConfig[config_key::dns2] = apiConfig.value(config_key::dns2);
|
||||
serverConfig[config_key::containers] = apiConfig.value(config_key::containers);
|
||||
serverConfig[config_key::hostName] = apiConfig.value(config_key::hostName);
|
||||
|
||||
auto defaultContainer = apiConfig.value(config_key::defaultContainer).toString();
|
||||
serverConfig[config_key::defaultContainer] = defaultContainer;
|
||||
|
||||
emit configUpdated(true, serverConfig, serverIndex);
|
||||
auto apiResponseBody = reply->readAll();
|
||||
fillServerConfig(protocol, apiPayloadData, apiResponseBody, serverConfig);
|
||||
emit finished(serverConfig, serverIndex);
|
||||
} else {
|
||||
if (reply->error() == QNetworkReply::NetworkError::OperationCanceledError
|
||||
|| reply->error() == QNetworkReply::NetworkError::TimeoutError) {
|
||||
|
@ -178,3 +267,154 @@ void ApiController::updateServerConfigFromApi(const QString &installationUuid, c
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
ErrorCode ApiController::getServicesList(QByteArray &responseBody)
|
||||
{
|
||||
#ifdef Q_OS_IOS
|
||||
IosController::Instance()->requestInetAccess();
|
||||
QThread::msleep(10);
|
||||
#endif
|
||||
|
||||
QNetworkRequest request;
|
||||
request.setTransferTimeout(7000);
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
|
||||
request.setUrl(QString("%1v1/services").arg(m_gatewayEndpoint));
|
||||
|
||||
QNetworkReply* reply;
|
||||
reply = amnApp->manager()->get(request);
|
||||
|
||||
QEventLoop wait;
|
||||
QObject::connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
|
||||
|
||||
QList<QSslError> sslErrors;
|
||||
connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; });
|
||||
wait.exec();
|
||||
|
||||
if (reply->error() == QNetworkReply::NetworkError::TimeoutError || reply->error() == QNetworkReply::NetworkError::OperationCanceledError) {
|
||||
m_proxyUrls = getProxyUrls();
|
||||
for (const QString &proxyUrl : m_proxyUrls) {
|
||||
request.setUrl(QString("%1v1/services").arg(proxyUrl));
|
||||
reply = amnApp->manager()->get(request);
|
||||
|
||||
QObject::connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
|
||||
connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; });
|
||||
wait.exec();
|
||||
if (reply->error() != QNetworkReply::NetworkError::TimeoutError && reply->error() != QNetworkReply::NetworkError::OperationCanceledError) {
|
||||
break;
|
||||
}
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
responseBody = reply->readAll();
|
||||
auto errorCode = checkErrors(sslErrors, reply);
|
||||
reply->deleteLater();
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
ErrorCode ApiController::getConfigForService(const QString &installationUuid, const QString &userCountryCode, const QString &serviceType,
|
||||
const QString &protocol, const QString &serverCountryCode, QJsonObject &serverConfig)
|
||||
{
|
||||
#ifdef Q_OS_IOS
|
||||
IosController::Instance()->requestInetAccess();
|
||||
QThread::msleep(10);
|
||||
#endif
|
||||
|
||||
QNetworkAccessManager manager;
|
||||
QNetworkRequest request;
|
||||
request.setTransferTimeout(7000);
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
|
||||
|
||||
request.setUrl(QString("%1v1/config").arg(m_gatewayEndpoint));
|
||||
|
||||
ApiPayloadData apiPayloadData = generateApiPayloadData(protocol);
|
||||
|
||||
QJsonObject apiPayload = fillApiPayload(protocol, apiPayloadData);
|
||||
apiPayload[configKey::userCountryCode] = userCountryCode;
|
||||
if (!serverCountryCode.isEmpty()) {
|
||||
apiPayload[configKey::serverCountryCode] = serverCountryCode;
|
||||
}
|
||||
apiPayload[configKey::serviceType] = serviceType;
|
||||
apiPayload[configKey::uuid] = installationUuid;
|
||||
|
||||
QSimpleCrypto::QBlockCipher blockCipher;
|
||||
QByteArray key = blockCipher.generatePrivateSalt(32);
|
||||
QByteArray iv = blockCipher.generatePrivateSalt(32);
|
||||
QByteArray salt = blockCipher.generatePrivateSalt(8);
|
||||
|
||||
QJsonObject keyPayload;
|
||||
keyPayload[configKey::aesKey] = QString(key.toBase64());
|
||||
keyPayload[configKey::aesIv] = QString(iv.toBase64());
|
||||
keyPayload[configKey::aesSalt] = QString(salt.toBase64());
|
||||
|
||||
QByteArray encryptedKeyPayload;
|
||||
QByteArray encryptedApiPayload;
|
||||
try {
|
||||
QSimpleCrypto::QRsa rsa;
|
||||
|
||||
EVP_PKEY *publicKey = nullptr;
|
||||
try {
|
||||
QByteArray key = PROD_AGW_PUBLIC_KEY;
|
||||
QSimpleCrypto::QRsa rsa;
|
||||
publicKey = rsa.getPublicKeyFromByteArray(key);
|
||||
} catch (...) {
|
||||
qCritical() << "error loading public key from environment variables";
|
||||
return ErrorCode::ApiMissingAgwPublicKey;
|
||||
}
|
||||
|
||||
encryptedKeyPayload = rsa.encrypt(QJsonDocument(keyPayload).toJson(), publicKey, RSA_PKCS1_PADDING);
|
||||
EVP_PKEY_free(publicKey);
|
||||
|
||||
encryptedApiPayload = blockCipher.encryptAesBlockCipher(QJsonDocument(apiPayload).toJson(), key, iv, "", salt);
|
||||
} catch (...) { // todo change error handling in QSimpleCrypto?
|
||||
qCritical() << "error when encrypting the request body";
|
||||
}
|
||||
|
||||
QJsonObject requestBody;
|
||||
requestBody[configKey::keyPayload] = QString(encryptedKeyPayload.toBase64());
|
||||
requestBody[configKey::apiPayload] = QString(encryptedApiPayload.toBase64());
|
||||
|
||||
QNetworkReply* reply = manager.post(request, QJsonDocument(requestBody).toJson());
|
||||
|
||||
QEventLoop wait;
|
||||
connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
|
||||
|
||||
QList<QSslError> sslErrors;
|
||||
connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; });
|
||||
wait.exec();
|
||||
|
||||
if (reply->error() == QNetworkReply::NetworkError::TimeoutError || reply->error() == QNetworkReply::NetworkError::OperationCanceledError) {
|
||||
if (m_proxyUrls.isEmpty()) {
|
||||
m_proxyUrls = getProxyUrls();
|
||||
}
|
||||
for (const QString &proxyUrl : m_proxyUrls) {
|
||||
request.setUrl(QString("%1v1/config").arg(proxyUrl));
|
||||
reply = manager.post(request, QJsonDocument(requestBody).toJson());
|
||||
|
||||
QObject::connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
|
||||
connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; });
|
||||
wait.exec();
|
||||
if (reply->error() != QNetworkReply::NetworkError::TimeoutError && reply->error() != QNetworkReply::NetworkError::OperationCanceledError) {
|
||||
break;
|
||||
}
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
auto errorCode = checkErrors(sslErrors, reply);
|
||||
if (errorCode) {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
auto encryptedResponseBody = reply->readAll();
|
||||
reply->deleteLater();
|
||||
try {
|
||||
auto responseBody = blockCipher.decryptAesBlockCipher(encryptedResponseBody, key, iv, "", salt);
|
||||
fillServerConfig(protocol, apiPayloadData, responseBody, serverConfig);
|
||||
} catch (...) { // todo change error handling in QSimpleCrypto?
|
||||
qCritical() << "error when decrypting the request body";
|
||||
}
|
||||
|
||||
return errorCode;
|
||||
}
|
||||
|
|
|
@ -14,14 +14,18 @@ class ApiController : public QObject
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ApiController(QObject *parent = nullptr);
|
||||
explicit ApiController(const QString &gatewayEndpoint, QObject *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
void updateServerConfigFromApi(const QString &installationUuid, const int serverIndex, QJsonObject serverConfig);
|
||||
|
||||
ErrorCode getServicesList(QByteArray &responseBody);
|
||||
ErrorCode getConfigForService(const QString &installationUuid, const QString &userCountryCode, const QString &serviceType,
|
||||
const QString &protocol, const QString &serverCountryCode, QJsonObject &serverConfig);
|
||||
|
||||
signals:
|
||||
void errorOccurred(ErrorCode errorCode);
|
||||
void configUpdated(const bool updateConfig, const QJsonObject &config, const int serverIndex);
|
||||
void finished(const QJsonObject &config, const int serverIndex);
|
||||
|
||||
private:
|
||||
struct ApiPayloadData
|
||||
|
@ -34,7 +38,12 @@ private:
|
|||
|
||||
ApiPayloadData generateApiPayloadData(const QString &protocol);
|
||||
QJsonObject fillApiPayload(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData);
|
||||
void processApiConfig(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData, QString &config);
|
||||
void fillServerConfig(const QString &protocol, const ApiController::ApiPayloadData &apiPayloadData, const QByteArray &apiResponseBody,
|
||||
QJsonObject &serverConfig);
|
||||
QStringList getProxyUrls();
|
||||
|
||||
QString m_gatewayEndpoint;
|
||||
QStringList m_proxyUrls;
|
||||
};
|
||||
|
||||
#endif // APICONTROLLER_H
|
||||
|
|
|
@ -106,6 +106,7 @@ namespace amnezia
|
|||
ApiConfigEmptyError = 1102,
|
||||
ApiConfigTimeoutError = 1103,
|
||||
ApiConfigSslError = 1104,
|
||||
ApiMissingAgwPublicKey = 1105,
|
||||
|
||||
// QFile errors
|
||||
OpenError = 1200,
|
||||
|
|
9
client/core/enums/apiEnums.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#ifndef APIENUMS_H
|
||||
#define APIENUMS_H
|
||||
|
||||
enum ApiConfigSources {
|
||||
Telegram = 1,
|
||||
AmneziaGateway
|
||||
};
|
||||
|
||||
#endif // APIENUMS_H
|
|
@ -60,6 +60,7 @@ QString errorString(ErrorCode code) {
|
|||
case (ErrorCode::ApiConfigEmptyError): errorMessage = QObject::tr("In the response from the server, an empty config was received"); break;
|
||||
case (ErrorCode::ApiConfigSslError): errorMessage = QObject::tr("SSL error occurred"); break;
|
||||
case (ErrorCode::ApiConfigTimeoutError): errorMessage = QObject::tr("Server response timeout on api request"); break;
|
||||
case (ErrorCode::ApiMissingAgwPublicKey): errorMessage = QObject::tr("Missing AGW public key"); break;
|
||||
|
||||
// QFile errors
|
||||
case(ErrorCode::OpenError): errorMessage = QObject::tr("QFile error: The file could not be opened"); break;
|
||||
|
|
Before Width: | Height: | Size: 236 KiB |
Before Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 282 B |
Before Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 189 KiB |
Before Width: | Height: | Size: 182 B |
Before Width: | Height: | Size: 344 B |
Before Width: | Height: | Size: 14 KiB |
|
@ -1,18 +0,0 @@
|
|||
<svg width="280" height="280" viewBox="0 0 280 280" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_f_1379_19114)">
|
||||
<circle cx="140" cy="140" r="107.5" stroke="#FBB36A"/>
|
||||
</g>
|
||||
<circle cx="140" cy="140" r="107" stroke="#FBB36A" stroke-width="2"/>
|
||||
<circle cx="140" cy="140" r="107" stroke="url(#paint0_linear_1379_19114)" stroke-width="2"/>
|
||||
<defs>
|
||||
<filter id="filter0_f_1379_19114" x="2" y="2" width="276" height="276" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||
<feGaussianBlur stdDeviation="15" result="effect1_foregroundBlur_1379_19114"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_1379_19114" x1="-2.43527" y1="89.3291" x2="192.652" y2="11.9798" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#E0AA84"/>
|
||||
<stop offset="1" stop-color="#DF7D37"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
Before Width: | Height: | Size: 969 B |
|
@ -1,17 +0,0 @@
|
|||
<svg width="280" height="280" viewBox="0 0 280 280" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g filter="url(#filter0_d_1379_19118)">
|
||||
<path d="M140 235C127.524 235 115.171 232.543 103.645 227.769C92.1191 222.994 81.6464 215.997 72.8248 207.175C64.0033 198.354 57.0056 187.881 52.2314 176.355C47.4572 164.829 45 152.476 45 140C45 127.524 47.4572 115.171 52.2314 103.645C57.0056 92.1191 64.0033 81.6464 72.8249 72.8248C81.6464 64.0033 92.1191 57.0056 103.645 52.2314C115.171 47.4572 127.524 45 140 45C152.476 45 164.829 47.4572 176.355 52.2314C187.881 57.0056 198.354 64.0033 207.175 72.8249C215.997 81.6464 222.994 92.1192 227.769 103.645C232.543 115.171 235 127.524 235 140C235 152.476 232.543 164.829 227.769 176.355C222.994 187.881 215.997 198.354 207.175 207.175C198.354 215.997 187.881 222.994 176.355 227.769C164.829 232.543 152.476 235 140 235L140 235Z" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d_1379_19118" x="38" y="38" width="204" height="204" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset/>
|
||||
<feGaussianBlur stdDeviation="3"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.2 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_1379_19118"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_1379_19118" result="shape"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.6 KiB |
|
@ -1,30 +0,0 @@
|
|||
<svg width="280" height="280" viewBox="0 0 280 280" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g opacity="0.1" filter="url(#filter0_d_1379_19115)">
|
||||
<path d="M235 140C235 152.476 232.543 164.829 227.769 176.355C222.994 187.881 215.997 198.354 207.175 207.175C198.354 215.997 187.881 222.994 176.355 227.769C164.829 232.543 152.476 235 140 235C127.524 235 115.171 232.543 103.645 227.769C92.1191 222.994 81.6464 215.997 72.8249 207.175C64.0033 198.354 57.0056 187.881 52.2314 176.355C47.4572 164.829 45 152.476 45 140C45 127.524 47.4572 115.171 52.2314 103.645C57.0056 92.1191 64.0033 81.6464 72.8249 72.8248C81.6464 64.0033 92.1192 57.0056 103.645 52.2314C115.171 47.4572 127.524 45 140 45C152.476 45 164.829 47.4573 176.355 52.2314C187.881 57.0056 198.354 64.0033 207.175 72.8249C215.997 81.6464 222.994 92.1192 227.769 103.645C232.543 115.171 235 127.524 235 140L235 140Z" stroke="#FBB36A"/>
|
||||
</g>
|
||||
<g filter="url(#filter1_d_1379_19115)">
|
||||
<path d="M140 235C126.016 235 112.204 231.913 99.551 225.959C86.8977 220.004 75.7151 211.33 66.8012 200.555C57.8874 189.78 51.4623 177.17 47.9846 163.626C44.5069 150.081 44.0623 135.935 46.6827 122.199C49.3031 108.462 54.9237 95.4738 63.1434 84.1604C71.363 72.847 81.979 63.4878 94.2334 56.7509C106.488 50.014 120.078 46.0655 134.035 45.1875C147.991 44.3094 161.97 46.5233 174.972 51.6712" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d_1379_19115" x="38.5" y="38.5" width="203" height="203" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset/>
|
||||
<feGaussianBlur stdDeviation="3"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.984314 0 0 0 0 0.717647 0 0 0 0 0.317647 0 0 0 1 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_1379_19115"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_1379_19115" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter1_d_1379_19115" x="38" y="38" width="143.973" height="204" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset/>
|
||||
<feGaussianBlur stdDeviation="3"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0.988235 0 0 0 0 0.301961 0 0 0 0 0.0705883 0 0 0 0.49 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_1379_19115"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_1379_19115" result="shape"/>
|
||||
</filter>
|
||||
</defs>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.8 KiB |
7
client/images/controls/archive-restore.svg
Normal file
|
@ -0,0 +1,7 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M20 4H4C2.89543 4 2 4.89543 2 6V7C2 8.10457 2.89543 9 4 9H20C21.1046 9 22 8.10457 22 7V6C22 4.89543 21.1046 4 20 4Z" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M12 13V20" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M9 16L12 13L15 16" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M4 9V18C4 18.5304 4.21071 19.0391 4.58579 19.4142C4.96086 19.7893 5.46957 20 6 20H8" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M20 9V18C20 18.5304 19.7893 19.0391 19.4142 19.4142C19.0391 19.7893 18.5304 20 18 20H16" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 884 B |
11
client/images/controls/bug.svg
Normal file
|
@ -0,0 +1,11 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M16 10C16 7.79086 14.2091 6 12 6C9.79086 6 8 7.79086 8 10V16C8 18.2091 9.79086 20 12 20C14.2091 20 16 18.2091 16 16V10Z" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M19 7L16 9" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M5 7L8 9" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M19 19L16 17" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M5 19L8 17" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M20 13H16" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M4 13H8" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M10 4L11 6" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M14 4L13 6" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
5
client/images/controls/folder-search-2.svg
Normal file
|
@ -0,0 +1,5 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4 20H20C20.5304 20 21.0391 19.7893 21.4142 19.4142C21.7893 19.0391 22 18.5304 22 18V8C22 7.46957 21.7893 6.96086 21.4142 6.58579C21.0391 6.21071 20.5304 6 20 6H12.07C11.7406 5.9983 11.4167 5.91525 11.1271 5.75824C10.8375 5.60123 10.5912 5.37512 10.41 5.1L9.59 3.9C9.40882 3.62488 9.1625 3.39877 8.8729 3.24176C8.58331 3.08475 8.25941 3.0017 7.93 3H4C3.46957 3 2.96086 3.21071 2.58579 3.58579C2.21071 3.96086 2 4.46957 2 5V18C2 19.1 2.9 20 4 20Z" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M11.5 15C12.8807 15 14 13.8807 14 12.5C14 11.1193 12.8807 10 11.5 10C10.1193 10 9 11.1193 9 12.5C9 13.8807 10.1193 15 11.5 15Z" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M13.27 14.27L15 16" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 974 B |
4
client/images/controls/gauge.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 15L15.5 11.5" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M20.3 18C20.7 17 21 15.8 21 14.6C21 9.8 17 6 12 6C7 6 3 9.8 3 14.6C3 15.8 3.3 17 3.7 18" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 394 B |
5
client/images/controls/help-circle.svg
Normal file
|
@ -0,0 +1,5 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M9.09009 9.00008C9.32519 8.33175 9.78924 7.76819 10.4 7.40921C11.0108 7.05024 11.729 6.91902 12.4273 7.03879C13.1255 7.15857 13.7589 7.52161 14.2152 8.06361C14.6714 8.60561 14.9211 9.2916 14.9201 10.0001C14.9201 12.0001 11.9201 13.0001 11.9201 13.0001" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M12 17H12.01" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 761 B |
5
client/images/controls/history.svg
Normal file
|
@ -0,0 +1,5 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3 3V8H8" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M3.05 13.0001C3.27151 15.0059 4.1607 16.8791 5.57478 18.3188C6.98886 19.7585 8.84577 20.6812 10.8473 20.9387C12.8488 21.1961 14.8788 20.7735 16.6112 19.7386C18.3436 18.7036 19.678 17.1165 20.3999 15.2321C21.1219 13.3476 21.1896 11.2752 20.5921 9.34766C19.9947 7.42012 18.7668 5.7493 17.1056 4.60353C15.4444 3.45776 13.4463 2.90354 11.4322 3.02987C9.41817 3.15619 7.50501 3.95574 6 5.30009L3 8.00009" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M12 7V12L16 14" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 805 B |
5
client/images/controls/info.svg
Normal file
|
@ -0,0 +1,5 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M12 16V12" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M12 8H12.01" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 518 B |
4
client/images/controls/map-pin.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M20 10C20 16 12 22 12 22C12 22 4 16 4 10C4 7.87827 4.84285 5.84344 6.34315 4.34315C7.84344 2.84285 9.87827 2 12 2C14.1217 2 16.1566 2.84285 17.6569 4.34315C19.1571 5.84344 20 7.87827 20 10V10Z" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M12 13C13.6569 13 15 11.6569 15 10C15 8.34315 13.6569 7 12 7C10.3431 7 9 8.34315 9 10C9 11.6569 10.3431 13 12 13Z" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 596 B |
6
client/images/controls/refresh-cw.svg
Normal file
|
@ -0,0 +1,6 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M21 2V8H15" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M3 12.0001C3.00158 10.2634 3.5056 8.56429 4.45125 7.10764C5.39691 5.651 6.74382 4.49907 8.32951 3.79079C9.9152 3.08252 11.6719 2.84815 13.3879 3.11596C15.1038 3.38377 16.7056 4.14232 18 5.30011L21 8.00011" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M3 22V16H9" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M21 12C20.9984 13.7367 20.4944 15.4358 19.5487 16.8925C18.6031 18.3491 17.2562 19.501 15.6705 20.2093C14.0848 20.9176 12.3281 21.152 10.6121 20.8841C8.89623 20.6163 7.29445 19.8578 6 18.7L3 16" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 895 B |
7
client/images/controls/scan-line.svg
Normal file
|
@ -0,0 +1,7 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3 7V5C3 4.46957 3.21071 3.96086 3.58579 3.58579C3.96086 3.21071 4.46957 3 5 3H7" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M17 3H19C19.5304 3 20.0391 3.21071 20.4142 3.58579C20.7893 3.96086 21 4.46957 21 5V7" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M21 17V19C21 19.5304 20.7893 20.0391 20.4142 20.4142C20.0391 20.7893 19.5304 21 19 21H17" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M7 21H5C4.46957 21 3.96086 20.7893 3.58579 20.4142C3.21071 20.0391 3 19.5304 3 19V17" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M7 12H17" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 917 B |
4
client/images/controls/tag.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M12 2H2V12L11.29 21.29C12.23 22.23 13.77 22.23 14.71 21.29L21.29 14.71C22.23 13.77 22.23 12.23 21.29 11.29L12 2Z" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M7 7H7.01" stroke="#D7D8DB" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
After Width: | Height: | Size: 412 B |
Before Width: | Height: | Size: 437 B |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 6 KiB |
Before Width: | Height: | Size: 636 B |
Before Width: | Height: | Size: 390 B |
Before Width: | Height: | Size: 643 B |
35
client/images/flagKit/AD.svg
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>AD</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#1537D1" offset="0%"></stop>
|
||||
<stop stop-color="#0522A5" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#EA3058" offset="0%"></stop>
|
||||
<stop stop-color="#CE173E" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-4">
|
||||
<stop stop-color="#FFCF3C" offset="0%"></stop>
|
||||
<stop stop-color="#FECB2F" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="AD">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask" fill="url(#linearGradient-3)" x="10" y="0" width="11" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-4)" x="7" y="0" width="7" height="15"></rect>
|
||||
<polygon id="Rectangle-139-Copy" fill="#FFEDB1" points="9.5 6.5 10.5 6.5 10.5 7 9.5 7"></polygon>
|
||||
<path d="M9.6650265,7.9595207 C9.68963036,8.25476702 9.9569379,8.5 10.2524408,8.5 L10.7475592,8.5 C11.042238,8.5 11.3105295,8.2528489 11.3349735,7.9595207 L11.4566002,6.5 L9.54339977,6.5 L9.6650265,7.9595207 Z M9.04128242,6.49538898 C9.01848277,6.2217932 9.2157526,6 9.49538898,6 L11.504611,6 C11.7782068,6 11.9820206,6.2157526 11.9587176,6.49538898 L11.8332464,8.00104344 C11.7872707,8.55275191 11.3030501,9 10.7475592,9 L10.2524408,9 C9.69880801,9 9.21311164,8.55733967 9.16675362,8.00104344 L9.04128242,6.49538898 Z" id="Rectangle-137" fill="#D32E28" fill-rule="nonzero"></path>
|
||||
<polygon id="Rectangle-139" fill="#D32E28" points="9.5 7 11.5 7 11.5 7.5 11 7.5 10 7.5 9.5 7.5"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
33
client/images/flagKit/AE.svg
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>AE</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#12833B" offset="0%"></stop>
|
||||
<stop stop-color="#0D7332" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#262626" offset="0%"></stop>
|
||||
<stop stop-color="#0D0D0D" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-4">
|
||||
<stop stop-color="#FF323E" offset="0%"></stop>
|
||||
<stop stop-color="#FD0D1B" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="AE">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="6" y="0" width="15" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-3)" x="6" y="10" width="15" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-1)" x="6" y="5" width="15" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-4)" x="0" y="0" width="6" height="15"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
34
client/images/flagKit/AF.svg
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>AF</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#1AB11F" offset="0%"></stop>
|
||||
<stop stop-color="#149818" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#262626" offset="0%"></stop>
|
||||
<stop stop-color="#0D0D0D" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-4">
|
||||
<stop stop-color="#DC0D18" offset="0%"></stop>
|
||||
<stop stop-color="#BE0711" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="AF">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask" fill="url(#linearGradient-2)" x="10" y="0" width="11" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-3)" x="0" y="0" width="7" height="15"></rect>
|
||||
<rect id="Rectangle-2-Copy" fill="url(#linearGradient-4)" x="7" y="0" width="7" height="15"></rect>
|
||||
<path d="M8,7 C8,7.90143048 8.48152018,8.71954992 9.24677273,9.16357911 C9.48561975,9.3021674 9.79159152,9.22089165 9.93017981,8.98204463 C10.0687681,8.74319762 9.98749235,8.43722585 9.74864534,8.29863755 C9.28867518,8.03174504 9,7.54127594 9,7 C9,6.72385763 8.77614237,6.5 8.5,6.5 C8.22385763,6.5 8,6.72385763 8,7 Z M11.8455353,9.10731545 C12.5588244,8.65111736 13,7.86294784 13,7 C13,6.72385763 12.7761424,6.5 12.5,6.5 C12.2238576,6.5 12,6.72385763 12,7 C12,7.5182519 11.7356132,7.99058439 11.3067388,8.26487951 C11.0741065,8.41366406 11.0061345,8.72286348 11.1549191,8.95549574 C11.3037036,9.188128 11.612903,9.2561 11.8455353,9.10731545 Z" id="Oval-5" fill="#FFFFFF" fill-rule="nonzero" opacity="0.75"></path>
|
||||
<ellipse id="Oval-5" fill-opacity="0.5" fill="#FFFFFF" cx="10.5" cy="6.5" rx="1" ry="1.5"></ellipse>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
44
client/images/flagKit/AG.svg
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>AG</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#E2243B" offset="0%"></stop>
|
||||
<stop stop-color="#CC162C" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#262626" offset="0%"></stop>
|
||||
<stop stop-color="#0D0D0D" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<polygon id="path-4" points="0 0 21 0 10.5 15"></polygon>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-6">
|
||||
<stop stop-color="#FFCF3C" offset="0%"></stop>
|
||||
<stop stop-color="#FECB2F" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-7">
|
||||
<stop stop-color="#1984D8" offset="0%"></stop>
|
||||
<stop stop-color="#1175C4" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="AG">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<path d="M8.5,7 C8.5,7.73933629 8.90117129,8.38497401 9.49770903,8.73110833 M11.576137,8.68609748 C12.1317007,8.33077576 12.5,7.70839833 12.5,7" id="Oval-5" opacity="0.75"></path>
|
||||
<ellipse id="Oval-5" fill-opacity="0.5" fill="#FFFFFF" cx="10.5" cy="6.5" rx="1" ry="1.5"></ellipse>
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<mask id="mask-5" fill="white">
|
||||
<use xlink:href="#path-4"></use>
|
||||
</mask>
|
||||
<use id="Mask" fill="url(#linearGradient-3)" xlink:href="#path-4"></use>
|
||||
<polygon id="Star-1" fill="url(#linearGradient-6)" mask="url(#mask-5)" points="10.5 8.25 8.77792455 10.1574579 8.90900974 7.59099026 6.3425421 7.72207545 8.25 6 5.99999999 3.99999993 8.90900963 4.49999993 8.49999999 1.49999999 10.5 3.99999993 12.5 1.49999999 12.0909905 4.49999993 15 4 12.75 6 14.6574579 7.72207545 12.0909903 7.59099026 12.2220754 10.1574579"></polygon>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-7)" mask="url(#mask-5)" x="0" y="6" width="21" height="4"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-1)" mask="url(#mask-5)" x="0" y="10" width="21" height="5"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3 KiB |
50
client/images/flagKit/AI.svg
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>AI</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#0A17A7" offset="0%"></stop>
|
||||
<stop stop-color="#030E88" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#DB1E36" offset="0%"></stop>
|
||||
<stop stop-color="#D51931" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<path d="M0,2.5 L0,0 L1,0.5 L2,0 L3,0.5 L4,0 L4,2.5 C4,4 2,5 2,5 C2,5 0,4 0,2.5 Z" id="path-4"></path>
|
||||
<filter x="-6.2%" y="-5.0%" width="112.5%" height="120.0%" filterUnits="objectBoundingBox" id="filter-6">
|
||||
<feOffset dx="0" dy="0.5" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-7">
|
||||
<stop stop-color="#FFA51B" offset="0%"></stop>
|
||||
<stop stop-color="#FF9A00" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="AI">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<path d="M3,3.22996746 L-1.3516287,-0.5 L0.660232527,-0.5 L4.16023253,2 L4.85660189,2 L9.5,-0.902123821 L9.5,0.25 C9.5,0.552509227 9.33308555,0.876533554 9.08215972,1.05576629 L6,3.25730895 L6,3.77003254 L9.13722049,6.45907867 C9.59934261,6.85518335 9.34102897,7.5 8.75,7.5 C8.50478614,7.5 8.2052751,7.40393402 8.00092153,7.25796718 L4.83976747,5 L4.14339811,5 L-0.5,7.90212382 L-0.5,6.24269105 L3,3.74269105 L3,3.22996746 Z" id="Rectangle-36" fill="url(#linearGradient-1)" fill-rule="nonzero"></path>
|
||||
<path d="M3.5,3 L-4.4408921e-16,7.10542736e-15 L0.5,7.10542736e-15 L4,2.5 L5,2.5 L9,7.10542736e-15 L9,0.25 C9,0.388071187 8.91348267,0.561798096 8.79154062,0.648899555 L5.5,3 L5.5,4 L8.8118248,6.83870697 C8.91575109,6.92778665 8.8840332,7 8.75,7 L8.75,7 C8.61192881,7 8.41348267,6.9382019 8.29154062,6.85110044 L5,4.5 L4,4.5 L-4.4408921e-16,7 L-4.4408921e-16,6.5 L3.5,4 L3.5,3 Z" id="Rectangle-36" fill="url(#linearGradient-3)"></path>
|
||||
<path d="M-4.4408921e-16,2.5 L-4.4408921e-16,4.5 L3.5,4.5 L3.5,7.00461102 C3.5,7.2782068 3.71403503,7.5 4.00468445,7.5 L4.99531555,7.5 C5.27404508,7.5 5.5,7.2842474 5.5,7.00461102 L5.5,4.5 L9.00952148,4.5 C9.28040529,4.5 9.5,4.28596497 9.5,3.99531555 L9.5,3.00468445 C9.5,2.72595492 9.28494263,2.5 9.00952148,2.5 L5.5,2.5 L5.5,7.10542736e-15 L3.5,7.10542736e-15 L3.5,2.5 L-4.4408921e-16,2.5 Z" id="Rectangle-2" fill="url(#linearGradient-1)"></path>
|
||||
<polygon id="Rectangle-36" fill="url(#linearGradient-3)" points="-4.4408921e-16 3 4 3 4 2.5 4 7.10542736e-15 5 7.10542736e-15 5 2.5 5 3 9 3 9 4 5 4 5 4.5 5 7 4 7 4 4.5 4 4 -4.4408921e-16 4"></polygon>
|
||||
<g id="Rectangle-1105" transform="translate(13.000000, 5.000000)">
|
||||
<mask id="mask-5" fill="white">
|
||||
<use xlink:href="#path-4"></use>
|
||||
</mask>
|
||||
<g id="Mask">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-6)" xlink:href="#path-4"></use>
|
||||
<use fill="url(#linearGradient-1)" fill-rule="evenodd" xlink:href="#path-4"></use>
|
||||
</g>
|
||||
<rect id="Rectangle-1106" fill="#9ACCFF" mask="url(#mask-5)" x="0" y="4" width="4" height="1"></rect>
|
||||
<path d="M2,2 C1.72385763,2 1.5,1.77614237 1.5,1.5 C1.5,1.22385763 1.72385763,1 2,1 C2.27614237,1 2.5,1.22385763 2.5,1.5 C2.5,1.77614237 2.27614237,2 2,2 Z M1,3 C0.723857625,3 0.5,2.77614237 0.5,2.5 C0.5,2.22385763 0.723857625,2 1,2 C1.27614237,2 1.5,2.22385763 1.5,2.5 C1.5,2.77614237 1.27614237,3 1,3 Z M3,3 C2.72385763,3 2.5,2.77614237 2.5,2.5 C2.5,2.22385763 2.72385763,2 3,2 C3.27614237,2 3.5,2.22385763 3.5,2.5 C3.5,2.77614237 3.27614237,3 3,3 Z" id="Oval-170" fill="url(#linearGradient-7)" mask="url(#mask-5)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.8 KiB |
27
client/images/flagKit/AL.svg
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>AL</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#EE343C" offset="0%"></stop>
|
||||
<stop stop-color="#E2222A" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#262626" offset="0%"></stop>
|
||||
<stop stop-color="#0D0D0D" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="AL">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<path d="M9.34790039,3.34790039 L10.1520996,4.15209961 C10.3394737,4.33947372 10.6557603,4.34423969 10.8479004,4.15209961 L11.6520996,3.34790039 C11.8394737,3.16052628 12.1835102,3.12234016 12.4098816,3.27325439 L13.5,4 L11.9520178,4.77399111 C11.7034302,4.89828491 11.5,5.22385763 11.5,5.5 C11.5,5.76806641 11.7238576,6 12,6 C12.2680664,6 12.6987251,5.90063747 12.9438648,5.77806759 L14.0561352,5.22193241 C14.3009205,5.09953976 14.6565891,5.15658907 14.8497515,5.34975147 L15.1502485,5.65024853 C15.34375,5.84375 15.3012749,6.09936253 15.0561352,6.22193241 L13.9438648,6.77806759 C13.6990795,6.90046024 13.6835102,7.12234016 13.9098816,7.27325439 L14.5901184,7.72674561 C14.8160706,7.87738037 14.78419,8.043162 14.5179749,8.09640503 L12.9820251,8.40359497 C12.7131486,8.45737028 12.6812037,8.63590279 12.9047298,8.80354738 L14.0952702,9.69645262 C14.3154297,9.86157227 14.2761424,10 14,10 C13.7319336,10 13.2832413,9.94581031 13.0158558,9.87896395 L11.9841442,9.62103605 C11.714035,9.55350876 11.6223402,9.68351024 11.7732544,9.90988159 L12.2267456,10.5901184 C12.3773804,10.8160706 12.2726361,11 11.9921684,11 L11.5078316,11 C11.2213302,11 10.92917,11.2124899 10.8417969,11.4746094 L10.6582031,12.0253906 C10.5695229,12.2914314 10.42917,12.2875101 10.3417969,12.0253906 L10.1582031,11.4746094 C10.0695229,11.2085686 9.77263606,11 9.49216843,11 L9.00783157,11 C8.72133017,11 8.62234016,10.8164898 8.77325439,10.5901184 L9.22674561,9.90988159 C9.37738037,9.68392944 9.28324125,9.55418969 9.01585579,9.62103605 L7.98414421,9.87896395 C7.71403503,9.94649124 7.27614237,10 7,10 C6.73193359,10 6.68120372,9.86409721 6.90472984,9.69645262 L8.09527016,8.80354738 C8.31542969,8.63842773 8.28418999,8.456838 8.01797485,8.40359497 L6.48202515,8.09640503 C6.21314859,8.04262972 6.18351024,7.87765984 6.40988159,7.72674561 L7.09011841,7.27325439 C7.31607056,7.12261963 7.30127495,6.90063747 7.05613518,6.77806759 L5.94386482,6.22193241 C5.69907951,6.09953976 5.65658907,5.84341093 5.84975147,5.65024853 L6.15024853,5.34975147 C6.34375,5.15625 6.69872505,5.09936253 6.94386482,5.22193241 L8.05613518,5.77806759 C8.30092049,5.90046024 8.72385763,6 9,6 C9.26806641,6 9.5,5.77614237 9.5,5.5 C9.5,5.23193359 9.30127495,4.90063747 9.05613518,4.77806759 L7.94386482,4.22193241 C7.69907951,4.09953976 7.68351024,3.87765984 7.90988159,3.72674561 L8.59011841,3.27325439 C8.81607056,3.12261963 9.15576031,3.15576031 9.34790039,3.34790039 Z" id="Combined-Shape" fill="url(#linearGradient-3)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.8 KiB |
32
client/images/flagKit/AM.svg
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>AM</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#1047B9" offset="0%"></stop>
|
||||
<stop stop-color="#06379D" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#F01C31" offset="0%"></stop>
|
||||
<stop stop-color="#D70A1F" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-4">
|
||||
<stop stop-color="#F5B23E" offset="0%"></stop>
|
||||
<stop stop-color="#F0A728" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="AM">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="0" y="5" width="21" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-3)" x="0" y="0" width="21" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-4)" x="0" y="10" width="21" height="5"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
37
client/images/flagKit/AO.svg
Normal file
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>AO</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#FF323E" offset="0%"></stop>
|
||||
<stop stop-color="#FD0D1B" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#262626" offset="0%"></stop>
|
||||
<stop stop-color="#0D0D0D" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-4">
|
||||
<stop stop-color="#DD2137" offset="0%"></stop>
|
||||
<stop stop-color="#CC162C" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-5">
|
||||
<stop stop-color="#F8D84B" offset="0%"></stop>
|
||||
<stop stop-color="#F9D536" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="AO">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-3)" x="0" y="8" width="21" height="7"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-4)" x="0" y="0" width="21" height="8"></rect>
|
||||
<path d="M10.6306023,8.85466006 L9.2226499,7.91602515 C8.99288556,7.76284892 8.93079862,7.45241425 9.08397485,7.2226499 C9.23715108,6.99288556 9.54758575,6.93079862 9.7773501,7.08397485 L11.3130296,8.10776118 C11.3806662,7.9788916 11.4351961,7.84059073 11.4744444,7.69411428 C11.760328,6.62718208 11.127163,5.53050816 10.0602308,5.24462454 C9.79349776,5.17315364 9.63520651,4.89898516 9.70667742,4.63225211 C9.77814832,4.36551905 10.0523168,4.20722781 10.3190499,4.27869871 C11.9194482,4.70752415 12.8691956,6.35253502 12.4403702,7.95293333 C12.3721274,8.20761904 12.2730844,8.44582688 12.1483226,8.66462317 L12.7773501,9.08397485 C13.0071144,9.23715108 13.0692014,9.54758575 12.9160251,9.7773501 C12.7628489,10.0071144 12.4524142,10.0692014 12.2226499,9.91602515 L11.5104877,9.44125038 C10.7832553,10.0719943 9.76598896,10.3421636 8.76613558,10.0742537 C8.49940253,10.0027828 8.34111129,9.72861429 8.41258219,9.46188124 C8.4840531,9.19514819 8.75822158,9.03685694 9.02495463,9.10832785 C9.59426997,9.26087543 10.1720537,9.15174297 10.6306023,8.85466006 Z M9.5,6.5 C9.22385763,6.5 9,6.27614237 9,6 C9,5.72385763 9.22385763,5.5 9.5,5.5 C9.77614237,5.5 10,5.72385763 10,6 C10,6.27614237 9.77614237,6.5 9.5,6.5 Z" id="Shape" fill="url(#linearGradient-5)" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.3 KiB |
26
client/images/flagKit/AR.svg
Normal file
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>AR</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#88BBE8" offset="0%"></stop>
|
||||
<stop stop-color="#76ADDD" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="AR">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="0" y="10" width="21" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-1)" x="0" y="5" width="21" height="5"></rect>
|
||||
<path d="M10.5,9.5 C9.3954305,9.5 8.5,8.6045695 8.5,7.5 C8.5,6.3954305 9.3954305,5.5 10.5,5.5 C11.6045695,5.5 12.5,6.3954305 12.5,7.5 C12.5,8.6045695 11.6045695,9.5 10.5,9.5 Z" id="Oval-1" fill="#DB7A2C" fill-rule="nonzero"></path>
|
||||
<circle id="Oval-1" fill="#F4B32E" cx="10.5" cy="7.5" r="1.5"></circle>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
36
client/images/flagKit/AS.svg
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>AS</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#071585" offset="0%"></stop>
|
||||
<stop stop-color="#000B64" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#D32636" offset="0%"></stop>
|
||||
<stop stop-color="#BA1827" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="35.4001096%" y2="89.1313033%" id="linearGradient-4">
|
||||
<stop stop-color="#AB5423" offset="0%"></stop>
|
||||
<stop stop-color="#5A3719" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="AS">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<polygon id="Rectangle-1134" fill="url(#linearGradient-3)" fill-rule="nonzero" points="22 15.5 0 7.5 22 -0.5"></polygon>
|
||||
<polygon id="Rectangle-1134" fill="url(#linearGradient-1)" fill-rule="nonzero" points="21 0.927699992 2.92617498 7.5 21 14.0723"></polygon>
|
||||
<path d="M16,7.038486 C15.8815511,6.92003711 15.1942139,7.19421386 15.1942139,7.19421386 L14,6 C14,6 13.9383569,5.33698587 14.5,5 C14.9247187,4.74516878 15.7204931,4.83977815 16.4990013,4.5 C17.7459982,3.95575102 19,3 19,3 L18.1979642,5.20559849 C18.1979642,5.20559849 19.1166408,5.67923724 18.9999998,6 C18.9661979,6.0929551 18.0694389,6.38457486 17.9999998,6.5 C17.8680615,6.71931452 18.5239661,6.78580715 18.3197925,7.03848593 C17.7327784,7.76495606 17,8.5 17,8.5 L16,8 C16,8 16.1501465,7.18863249 16,7.038486 Z" id="Rectangle-1475" fill="url(#linearGradient-4)"></path>
|
||||
<circle id="Oval-322" fill="#FFC322" cx="13.5" cy="7.5" r="1"></circle>
|
||||
<path d="M12.5,9 L17.5,9 C17.7761424,9 18,8.77614237 18,8.5 C18,8.22385763 17.7761424,8 17.5,8 L12.5,8 C12.2238576,8 12,8.22385763 12,8.5 C12,8.77614237 12.2238576,9 12.5,9 Z" id="Line" fill="#FFC322" fill-rule="nonzero"></path>
|
||||
<path d="M14.1969596,10.4595725 L17.6969596,8.95957252 C17.9507745,8.8507947 18.0683503,8.55685524 17.9595725,8.30304035 C17.8507947,8.04922546 17.5568552,7.93164967 17.3030404,8.04042748 L13.8030404,9.54042748 C13.5492255,9.6492053 13.4316497,9.94314476 13.5404275,10.1969596 C13.6492053,10.4507745 13.9431448,10.5683503 14.1969596,10.4595725 Z" id="Line-Copy" fill="#FFC322" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.2 KiB |
24
client/images/flagKit/AT.svg
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>AT</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#F64253" offset="0%"></stop>
|
||||
<stop stop-color="#EA2D3F" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="AT">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="0" y="10" width="21" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-1)" x="0" y="5" width="21" height="5"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
36
client/images/flagKit/AU.svg
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>AU</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#0A17A7" offset="0%"></stop>
|
||||
<stop stop-color="#030E88" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#DB1E36" offset="0%"></stop>
|
||||
<stop stop-color="#D51931" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="AU">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<path d="M3,3.22996746 L-1.3516287,-0.5 L0.660232527,-0.5 L4.16023253,2 L4.85660189,2 L9.5,-0.902123821 L9.5,0.25 C9.5,0.552509227 9.33308555,0.876533554 9.08215972,1.05576629 L6,3.25730895 L6,3.77003254 L9.13722049,6.45907867 C9.59934261,6.85518335 9.34102897,7.5 8.75,7.5 C8.50478614,7.5 8.2052751,7.40393402 8.00092153,7.25796718 L4.83976747,5 L4.14339811,5 L-0.5,7.90212382 L-0.5,6.24269105 L3,3.74269105 L3,3.22996746 Z" id="Rectangle-36" fill="url(#linearGradient-1)" fill-rule="nonzero"></path>
|
||||
<path d="M3.5,3 L-4.4408921e-16,-2.13162821e-14 L0.5,-2.13162821e-14 L4,2.5 L5,2.5 L9,-2.13162821e-14 L9,0.25 C9,0.388071187 8.91348267,0.561798096 8.79154062,0.648899555 L5.5,3 L5.5,4 L8.8118248,6.83870697 C8.91575109,6.92778665 8.8840332,7 8.75,7 L8.75,7 C8.61192881,7 8.41348267,6.9382019 8.29154062,6.85110044 L5,4.5 L4,4.5 L-4.4408921e-16,7 L-4.4408921e-16,6.5 L3.5,4 L3.5,3 Z" id="Rectangle-36" fill="url(#linearGradient-3)"></path>
|
||||
<path d="M-4.4408921e-16,2.5 L-4.4408921e-16,4.5 L3.5,4.5 L3.5,7.00461102 C3.5,7.2782068 3.71403503,7.5 4.00468445,7.5 L4.99531555,7.5 C5.27404508,7.5 5.5,7.2842474 5.5,7.00461102 L5.5,4.5 L9.00952148,4.5 C9.28040529,4.5 9.5,4.28596497 9.5,3.99531555 L9.5,3.00468445 C9.5,2.72595492 9.28494263,2.5 9.00952148,2.5 L5.5,2.5 L5.5,-2.13162821e-14 L3.5,-2.13162821e-14 L3.5,2.5 L-4.4408921e-16,2.5 Z" id="Rectangle-2" fill="url(#linearGradient-1)"></path>
|
||||
<polygon id="Rectangle-36" fill="url(#linearGradient-3)" points="-4.4408921e-16 3 4 3 4 2.5 4 -2.13162821e-14 5 -2.13162821e-14 5 2.5 5 3 9 3 9 4 5 4 5 4.5 5 7 4 7 4 4.5 4 4 -4.4408921e-16 4"></polygon>
|
||||
<polygon id="Star-2" fill="#FFFFFF" points="4.5 12.25 3.61832212 12.7135255 3.78670761 11.7317627 3.07341523 11.0364745 4.05916106 10.8932373 4.5 10 4.94083894 10.8932373 5.92658477 11.0364745 5.21329239 11.7317627 5.38167788 12.7135255"></polygon>
|
||||
<polygon id="Star-2" fill="#FFFFFF" points="15 13 14.2928932 13.2071068 14.5 12.5 14.2928932 11.7928932 15 12 15.7071068 11.7928932 15.5 12.5 15.7071068 13.2071068"></polygon>
|
||||
<polygon id="Star-2" fill="#FFFFFF" points="15 3.5 14.2928932 3.70710678 14.5 3 14.2928932 2.29289322 15 2.5 15.7071068 2.29289322 15.5 3 15.7071068 3.70710678"></polygon>
|
||||
<polygon id="Star-2" fill="#FFFFFF" points="18 6.5 17.2928932 6.70710678 17.5 6 17.2928932 5.29289322 18 5.5 18.7071068 5.29289322 18.5 6 18.7071068 6.70710678"></polygon>
|
||||
<polygon id="Star-2" fill="#FFFFFF" points="12 7.5 11.2928932 7.70710678 11.5 7 11.2928932 6.29289322 12 6.5 12.7071068 6.29289322 12.5 7 12.7071068 7.70710678"></polygon>
|
||||
<polygon id="Star-2" fill="#FFFFFF" points="16.5 8.75 16.1464466 8.85355339 16.25 8.5 16.1464466 8.14644661 16.5 8.25 16.8535534 8.14644661 16.75 8.5 16.8535534 8.85355339"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.1 KiB |
30
client/images/flagKit/AW.svg
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>AW</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#5098EA" offset="0%"></stop>
|
||||
<stop stop-color="#458BDB" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#E82045" offset="0%"></stop>
|
||||
<stop stop-color="#D01739" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="AW">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<path d="M1.80304035,4.95957252 C1.39898655,4.7864066 1.39898655,4.2135934 1.80304035,4.04042748 L3.36921134,3.36921134 L4.04042748,1.80304035 C4.2135934,1.39898655 4.7864066,1.39898655 4.95957252,1.80304035 L5.63078866,3.36921134 L7.19695965,4.04042748 C7.60101345,4.2135934 7.60101345,4.7864066 7.19695965,4.95957252 L5.63078866,5.63078866 L4.95957252,7.19695965 C4.7864066,7.60101345 4.2135934,7.60101345 4.04042748,7.19695965 L3.36921134,5.63078866 L1.80304035,4.95957252 Z" id="Star" fill="url(#linearGradient-1)" fill-rule="nonzero"></path>
|
||||
<polygon id="Star" fill="url(#linearGradient-3)" points="3.75 5.25 2 4.5 3.75 3.75 4.5 2 5.25 3.75 7 4.5 5.25 5.25 4.5 7"></polygon>
|
||||
<rect id="Rectangle-1337" fill="#F9D536" x="0" y="11" width="21" height="1"></rect>
|
||||
<rect id="Rectangle-1337-Copy" fill="#F9D536" x="0" y="9" width="21" height="1"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
32
client/images/flagKit/AX.svg
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>AX</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#157CBB" offset="0%"></stop>
|
||||
<stop stop-color="#0E6CA5" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#FFD34D" offset="0%"></stop>
|
||||
<stop stop-color="#FECB2F" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-4">
|
||||
<stop stop-color="#EB363A" offset="0%"></stop>
|
||||
<stop stop-color="#D52B2F" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="AX">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<polygon id="Rectangle-2" fill="url(#linearGradient-3)" points="0 9 6 9 6 15 9 15 9 9 21 9 21 6 9 6 9 0 6 0 6 6 0 6"></polygon>
|
||||
<polygon id="Rectangle-2" fill="url(#linearGradient-4)" points="0 8 7 8 7 15 8 15 8 8 21 8 21 7 8 7 8 0 7 0 7 7 0 7"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
33
client/images/flagKit/AZ.svg
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>AZ</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#24AAD5" offset="0%"></stop>
|
||||
<stop stop-color="#1899C2" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#ED1845" offset="0%"></stop>
|
||||
<stop stop-color="#DE0C39" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-4">
|
||||
<stop stop-color="#21BF75" offset="0%"></stop>
|
||||
<stop stop-color="#19AD68" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="AZ">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-3)" x="0" y="5" width="21" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-4)" x="0" y="10" width="21" height="5"></rect>
|
||||
<path d="M11.3335689,6.25274924 C11.3059482,6.25092604 11.2780822,6.25 11.25,6.25 C10.5596441,6.25 10,6.80964406 10,7.5 C10,8.19035594 10.5596441,8.75 11.25,8.75 C11.2780822,8.75 11.3059482,8.74907396 11.3335689,8.74725076 C11.0951725,8.9068934 10.8084594,9 10.5,9 C9.67157288,9 9,8.32842712 9,7.5 C9,6.67157288 9.67157288,6 10.5,6 C10.8084594,6 11.0951725,6.0931066 11.3335689,6.25274924 Z M11.5,8 C11.2238576,8 11,7.77614237 11,7.5 C11,7.22385763 11.2238576,7 11.5,7 C11.7761424,7 12,7.22385763 12,7.5 C12,7.77614237 11.7761424,8 11.5,8 Z" id="Oval-68" fill="url(#linearGradient-1)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
32
client/images/flagKit/BA.svg
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BA</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#0B36B2" offset="0%"></stop>
|
||||
<stop stop-color="#042993" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#FFD045" offset="0%"></stop>
|
||||
<stop stop-color="#FECA2F" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BA">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<polygon id="Rectangle-2" fill="url(#linearGradient-3)" points="17 15 17 0 6.5 0"></polygon>
|
||||
<polygon id="Star-2" fill="url(#linearGradient-1)" points="13 14 12.2928932 14.2071068 12.5 13.5 12.2928932 12.7928932 13 13 13.7071068 12.7928932 13.5 13.5 13.7071068 14.2071068"></polygon>
|
||||
<polygon id="Star-2" fill="url(#linearGradient-1)" points="11 11 10.2928932 11.2071068 10.5 10.5 10.2928932 9.79289322 11 10 11.7071068 9.79289322 11.5 10.5 11.7071068 11.2071068"></polygon>
|
||||
<polygon id="Star-2" fill="url(#linearGradient-1)" points="9 8 8.29289322 8.20710678 8.5 7.5 8.29289322 6.79289322 9 7 9.70710678 6.79289322 9.5 7.5 9.70710678 8.20710678"></polygon>
|
||||
<polygon id="Star-2" fill="url(#linearGradient-1)" points="7 5 6.29289322 5.20710678 6.5 4.5 6.29289322 3.79289322 7 4 7.70710678 3.79289322 7.5 4.5 7.70710678 5.20710678"></polygon>
|
||||
<polygon id="Star-2" fill="url(#linearGradient-1)" points="5 2 4.29289322 2.20710678 4.5 1.5 4.29289322 0.792893219 5 1 5.70710678 0.792893219 5.5 1.5 5.70710678 2.20710678"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
38
client/images/flagKit/BB.svg
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BB</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#1132C7" offset="0%"></stop>
|
||||
<stop stop-color="#0522A5" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#08379D" offset="0%"></stop>
|
||||
<stop stop-color="#042A7D" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-4">
|
||||
<stop stop-color="#FFCC50" offset="0%"></stop>
|
||||
<stop stop-color="#FFC63C" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-5">
|
||||
<stop stop-color="#262626" offset="0%"></stop>
|
||||
<stop stop-color="#0D0D0D" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BB">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask" fill="url(#linearGradient-3)" x="10" y="0" width="11" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-3)" x="0" y="0" width="7" height="15"></rect>
|
||||
<rect id="Rectangle-2-Copy" fill="url(#linearGradient-4)" x="7" y="0" width="7" height="15"></rect>
|
||||
<path d="M10.378269,4.70856857 C10.4566062,4.59337933 10.5844043,4.59841919 10.6563604,4.70856857 L11.3637506,5.79143143 C11.4389991,5.90662067 11.3828125,6.00000001 11.2460842,6.00000001 L11.0039158,6.00000003 C10.863682,6.00000004 10.7607422,6.10742192 10.7748849,6.24884943 L10.9751151,8.25115061 C10.9888586,8.38858633 11.1159668,8.5 11.25,8.5 C11.3880712,8.5 11.578125,8.42271423 11.6805115,8.32142761 L11.8194885,8.18394348 C11.9191823,8.08532067 12,7.89777878 12,7.75167352 L12,7.25369758 C12,7.11358427 11.921875,6.921875 11.8194885,6.81948853 L11.6805115,6.68051147 C11.5808177,6.58081774 11.5984192,6.46719361 11.734375,6.42187501 L12.765625,6.07812504 C12.8950667,6.03497779 12.9802439,6.10742192 12.9542338,6.24884943 L12.5859883,8.25115061 C12.5607124,8.38858633 12.4585977,8.57846832 12.3590293,8.67418671 L11.6811929,9.32581329 C11.5811228,9.42201396 11.3840332,9.5 11.25,9.5 C11.1119288,9.5 11,9.60701752 11,9.75234222 L11,10.2476578 C11,10.3870225 10.8929825,10.5 10.7476578,10.5 L10.2523422,10.5 C10.1129775,10.5 10,10.3929825 10,10.2476578 L10,9.75234222 C10,9.61297746 9.8840332,9.5 9.75,9.5 C9.61192881,9.5 9.42153168,9.42153168 9.32581329,9.32581329 L8.67418671,8.67418671 C8.57798604,8.57798604 8.47851563,8.39257813 8.45023012,8.25115061 L8.04976988,6.24884943 C8.02228273,6.11141371 8.09841919,6.03280644 8.234375,6.07812504 L9.265625,6.42187501 C9.39506674,6.46502225 9.421875,6.578125 9.31948853,6.68051147 L9.18051147,6.81948853 C9.08081774,6.91918226 9,7.10759232 9,7.25369758 L9,7.75167352 C9,7.89178682 9.078125,8.08265686 9.18051147,8.18394348 L9.31948853,8.32142761 C9.41918226,8.42005042 9.6159668,8.5 9.75,8.5 C9.88807119,8.5 10.0107422,8.39257812 10.0248849,8.25115061 L10.2251151,6.24884939 C10.2388586,6.11141367 10.1328125,6 9.99608421,6 L9.75391579,6 C9.61368197,6 9.56693234,5.90158081 9.64184208,5.79143143 L10.378269,4.70856857 Z" id="Combined-Shape" fill="url(#linearGradient-5)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4 KiB |
27
client/images/flagKit/BD.svg
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BD</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#128363" offset="0%"></stop>
|
||||
<stop stop-color="#0C6A4F" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#F23C53" offset="0%"></stop>
|
||||
<stop stop-color="#F22E46" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BD">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<circle id="Oval-9" fill="url(#linearGradient-3)" cx="9.5" cy="7.5" r="4.5"></circle>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
32
client/images/flagKit/BE.svg
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BE</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#FF4453" offset="0%"></stop>
|
||||
<stop stop-color="#EE2A39" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#262626" offset="0%"></stop>
|
||||
<stop stop-color="#0D0D0D" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-4">
|
||||
<stop stop-color="#FFCF3C" offset="0%"></stop>
|
||||
<stop stop-color="#FECB2F" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BE">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask" fill="url(#linearGradient-2)" x="10" y="0" width="11" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-3)" x="0" y="0" width="7" height="15"></rect>
|
||||
<rect id="Rectangle-2-Copy" fill="url(#linearGradient-4)" x="7" y="0" width="7" height="15"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
28
client/images/flagKit/BF.svg
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BF</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#00B051" offset="0%"></stop>
|
||||
<stop stop-color="#009F49" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#FA494B" offset="0%"></stop>
|
||||
<stop stop-color="#F02B2D" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BF">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="0" y="8" width="21" height="7"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-3)" x="0" y="0" width="21" height="8"></rect>
|
||||
<polygon id="Star-8" fill="#FDD216" points="10.5 9.17000005 8.73664424 10.427051 9.38726383 8.3615499 7.64683045 7.07294902 9.81229123 7.05345008 10.5 5 11.1877088 7.05345008 13.3531695 7.07294902 11.6127362 8.3615499 12.2633558 10.427051"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
28
client/images/flagKit/BG.svg
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BG</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#06A77C" offset="0%"></stop>
|
||||
<stop stop-color="#00966E" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#E32E19" offset="0%"></stop>
|
||||
<stop stop-color="#D62612" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BG">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="0" y="5" width="21" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-3)" x="0" y="10" width="21" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="5"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
23
client/images/flagKit/BH.svg
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BH</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#E7243B" offset="0%"></stop>
|
||||
<stop stop-color="#CC162C" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BH">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<polygon id="Rectangle-2-Copy" fill="url(#linearGradient-1)" points="0 15 7.5 15 6 14 7.5 13 6 12 7.5 11 6 10 7.5 9 6 8 7.5 7 6 6 7.5 5 6 4 7.5 3 6 2 7.5 1 6 0 0 0"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
36
client/images/flagKit/BI.svg
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BI</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#E4233B" offset="0%"></stop>
|
||||
<stop stop-color="#CC162C" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#34CD4E" offset="0%"></stop>
|
||||
<stop stop-color="#2AB441" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-4">
|
||||
<stop stop-color="#DF2239" offset="0%"></stop>
|
||||
<stop stop-color="#CC162C" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BI">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<g id="Group-2" transform="translate(-2.080000, -1.440000)">
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="2.08023771" y="1.43733467" width="21" height="15"></rect>
|
||||
<polygon id="Rectangle-253" fill="url(#linearGradient-3)" points="2 1.43733467 11 8.93733467 2 16.4373347"></polygon>
|
||||
<polygon id="Rectangle-253" fill="url(#linearGradient-3)" transform="translate(18.580000, 8.937335) scale(-1, 1) translate(-18.580000, -8.937335) " points="14.0799999 1.43733467 23.0799999 8.93733467 14.0799999 16.4373347"></polygon>
|
||||
<path d="M10.3586667,6.23264816 L1.11838581,-1.77635684e-15 L1.11022302e-15,1.65807515 L9.23955861,7.89023612 C9.13603457,8.22085713 9.08023771,8.57257987 9.08023771,8.93733467 C9.08023771,9.30208947 9.13603457,9.65381222 9.23955861,9.98443323 L1.77635684e-15,16.2165942 L1.11838581,17.8746693 L10.3586667,11.6420212 C10.9629797,12.1389684 11.7367651,12.4373347 12.5802377,12.4373347 C13.4237103,12.4373347 14.1974957,12.1389684 14.8018087,11.6420212 L24.0420896,17.8746693 L25.1604754,16.2165942 L15.9209168,9.98443323 C16.0244408,9.65381222 16.0802377,9.30208947 16.0802377,8.93733467 C16.0802377,8.57257987 16.0244408,8.22085713 15.9209168,7.89023612 L25.1604754,1.65807515 L24.0420896,-3.55271368e-15 L14.8018087,6.23264816 C14.1974957,5.73570091 13.4237103,5.43733467 12.5802377,5.43733467 C11.7367651,5.43733467 10.9629797,5.73570091 10.3586667,6.23264816 Z" id="Rectangle-2" fill="url(#linearGradient-1)"></path>
|
||||
<path d="M12.5802377,7.93733467 L11.8731309,8.14444145 L12.0802377,7.43733467 L11.8731309,6.73022789 L12.5802377,6.93733467 L13.2873445,6.73022789 L13.0802377,7.43733467 L13.2873445,8.14444145 L12.5802377,7.93733467 Z M11.0802377,10.4373347 L10.3731309,10.6444415 L10.5802377,9.93733467 L10.3731309,9.23022789 L11.0802377,9.43733467 L11.7873445,9.23022789 L11.5802377,9.93733467 L11.7873445,10.6444415 L11.0802377,10.4373347 Z M14.0802377,10.4373347 L13.3731309,10.6444415 L13.5802377,9.93733467 L13.3731309,9.23022789 L14.0802377,9.43733467 L14.7873445,9.23022789 L14.5802377,9.93733467 L14.7873445,10.6444415 L14.0802377,10.4373347 Z" id="Star-2" fill="url(#linearGradient-4)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.7 KiB |
32
client/images/flagKit/BJ.svg
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BJ</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#F12641" offset="0%"></stop>
|
||||
<stop stop-color="#E71834" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#FFD648" offset="0%"></stop>
|
||||
<stop stop-color="#FCD036" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-4">
|
||||
<stop stop-color="#17A668" offset="0%"></stop>
|
||||
<stop stop-color="#118653" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BJ">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="0" y="7" width="21" height="8"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-3)" x="0" y="0" width="21" height="7"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-4)" x="0" y="0" width="8" height="15"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
42
client/images/flagKit/BL.svg
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BL</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#216CD3" offset="0%"></stop>
|
||||
<stop stop-color="#1557B2" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<path d="M0.5,0 L7.49999992,0 L7.49999998,4.49121523 C7.49999999,5.04835167 7.16440529,5.78765261 6.74055213,6.15095532 L5.1460309,7.5176878 C4.51309551,8.06020385 3.48356295,8.05733967 2.8539691,7.5176878 L1.25944787,6.15095532 C0.840016394,5.79144262 0.5,5.04991192 0.5,4.49121523 L0.5,0 Z" id="path-3"></path>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-5">
|
||||
<stop stop-color="#F7E14B" offset="0%"></stop>
|
||||
<stop stop-color="#F7DF3E" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-6">
|
||||
<stop stop-color="#E12539" offset="0%"></stop>
|
||||
<stop stop-color="#CA192C" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BL">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<g id="Rectangle-1693" transform="translate(6.500000, 5.000000)">
|
||||
<mask id="mask-4" fill="white">
|
||||
<use xlink:href="#path-3"></use>
|
||||
</mask>
|
||||
<use id="Combined-Shape" fill="url(#linearGradient-2)" xlink:href="#path-3"></use>
|
||||
<path d="M2,2 C1.72385763,2 1.5,1.77614237 1.5,1.5 C1.5,1.22385763 1.72385763,1 2,1 C2.27614237,1 2.5,1.22385763 2.5,1.5 C2.5,1.77614237 2.27614237,2 2,2 Z M4,2 C3.72385763,2 3.5,1.77614237 3.5,1.5 C3.5,1.22385763 3.72385763,1 4,1 C4.27614237,1 4.5,1.22385763 4.5,1.5 C4.5,1.77614237 4.27614237,2 4,2 Z M6,2 C5.72385763,2 5.5,1.77614237 5.5,1.5 C5.5,1.22385763 5.72385763,1 6,1 C6.27614237,1 6.5,1.22385763 6.5,1.5 C6.5,1.77614237 6.27614237,2 6,2 Z" id="Combined-Shape" fill="url(#linearGradient-5)" mask="url(#mask-4)"></path>
|
||||
<path d="M2.5,6.5 C2.22385763,6.5 2,6.27614237 2,6 C2,5.72385763 2.22385763,5.5 2.5,5.5 C2.77614237,5.5 3,5.72385763 3,6 C3,6.27614237 2.77614237,6.5 2.5,6.5 Z M4,7 C3.72385763,7 3.5,6.77614237 3.5,6.5 C3.5,6.22385763 3.72385763,6 4,6 C4.27614237,6 4.5,6.22385763 4.5,6.5 C4.5,6.77614237 4.27614237,7 4,7 Z M5.5,6.5 C5.22385763,6.5 5,6.27614237 5,6 C5,5.72385763 5.22385763,5.5 5.5,5.5 C5.77614237,5.5 6,5.72385763 6,6 C6,6.27614237 5.77614237,6.5 5.5,6.5 Z" id="Combined-Shape-Copy" fill="url(#linearGradient-5)" mask="url(#mask-4)"></path>
|
||||
<rect id="Rectangle-1425-Copy" fill="url(#linearGradient-6)" mask="url(#mask-4)" x="0.5" y="3" width="7" height="2"></rect>
|
||||
<circle id="Oval-292" fill="#FFFFFF" mask="url(#mask-4)" cx="4" cy="4" r="1"></circle>
|
||||
</g>
|
||||
<path d="M6.5,3.5 C6.5,3.5 8.5,3 10.5,3 C12.5,3 14.5,3.5 14.5,3.5 L14,5.5 C14,5.5 12.25,5 10.5,5 C8.75,5 7,5.5 7,5.5 L6.5,3.5 Z" id="Rectangle-1426" fill="url(#linearGradient-5)"></path>
|
||||
<path d="M10.5,4.5 C10.2238576,4.5 10,4.27614237 10,4 C10,3.72385763 10.2238576,3.5 10.5,3.5 C10.7761424,3.5 11,3.72385763 11,4 C11,4.27614237 10.7761424,4.5 10.5,4.5 Z M12.5,4.5 C12.2238576,4.5 12,4.27614237 12,4 C12,3.72385763 12.2238576,3.5 12.5,3.5 C12.7761424,3.5 13,3.72385763 13,4 C13,4.27614237 12.7761424,4.5 12.5,4.5 Z M8.5,4.5 C8.22385763,4.5 8,4.27614237 8,4 C8,3.72385763 8.22385763,3.5 8.5,3.5 C8.77614237,3.5 9,3.72385763 9,4 C9,4.27614237 8.77614237,4.5 8.5,4.5 Z" id="Combined-Shape" fill="#5E5216"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.1 KiB |
49
client/images/flagKit/BM.svg
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BM</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#DC1F37" offset="0%"></stop>
|
||||
<stop stop-color="#CF142C" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#042C90" offset="0%"></stop>
|
||||
<stop stop-color="#00247E" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-4">
|
||||
<stop stop-color="#DB1E36" offset="0%"></stop>
|
||||
<stop stop-color="#D51931" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<path d="M0,2.5 L0,0 L2,0 L4,0 L4,2.5 C4,4 2,5 2,5 C2,5 0,4 0,2.5 Z" id="path-5"></path>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-7">
|
||||
<stop stop-color="#E20B0C" offset="0%"></stop>
|
||||
<stop stop-color="#D40001" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BM">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Rectangle-1115" fill="url(#linearGradient-3)" x="0" y="0" width="9" height="7"></rect>
|
||||
<path d="M3,3.22996746 L-1.3516287,-0.5 L0.660232527,-0.5 L4.16023253,2 L4.85660189,2 L9.5,-0.902123821 L9.5,0.25 C9.5,0.552509227 9.33308555,0.876533554 9.08215972,1.05576629 L6,3.25730895 L6,3.77003254 L9.13722049,6.45907867 C9.59934261,6.85518335 9.34102897,7.5 8.75,7.5 C8.50478614,7.5 8.2052751,7.40393402 8.00092153,7.25796718 L4.83976747,5 L4.14339811,5 L-0.5,7.90212382 L-0.5,6.24269105 L3,3.74269105 L3,3.22996746 Z" id="Rectangle-36" fill="url(#linearGradient-1)" fill-rule="nonzero"></path>
|
||||
<path d="M3.5,3 L-4.4408921e-16,7.10542736e-15 L0.5,7.10542736e-15 L4,2.5 L5,2.5 L9,7.10542736e-15 L9,0.25 C9,0.388071187 8.91348267,0.561798096 8.79154062,0.648899555 L5.5,3 L5.5,4 L8.8118248,6.83870697 C8.91575109,6.92778665 8.8840332,7 8.75,7 L8.75,7 C8.61192881,7 8.41348267,6.9382019 8.29154062,6.85110044 L5,4.5 L4,4.5 L-4.4408921e-16,7 L-4.4408921e-16,6.5 L3.5,4 L3.5,3 Z" id="Rectangle-36" fill="url(#linearGradient-4)"></path>
|
||||
<path d="M-4.4408921e-16,2.5 L-4.4408921e-16,4.5 L3.5,4.5 L3.5,7.00461102 C3.5,7.2782068 3.71403503,7.5 4.00468445,7.5 L4.99531555,7.5 C5.27404508,7.5 5.5,7.2842474 5.5,7.00461102 L5.5,4.5 L9.00952148,4.5 C9.28040529,4.5 9.5,4.28596497 9.5,3.99531555 L9.5,3.00468445 C9.5,2.72595492 9.28494263,2.5 9.00952148,2.5 L5.5,2.5 L5.5,7.10542736e-15 L3.5,7.10542736e-15 L3.5,2.5 L-4.4408921e-16,2.5 Z" id="Rectangle-2" fill="url(#linearGradient-1)"></path>
|
||||
<polygon id="Rectangle-36" fill="url(#linearGradient-4)" points="-4.4408921e-16 3 4 3 4 2.5 4 7.10542736e-15 5 7.10542736e-15 5 2.5 5 3 9 3 9 4 5 4 5 4.5 5 7 4 7 4 4.5 4 4 -4.4408921e-16 4"></polygon>
|
||||
<g id="Rectangle-1105" transform="translate(13.000000, 5.000000)">
|
||||
<mask id="mask-6" fill="white">
|
||||
<use xlink:href="#path-5"></use>
|
||||
</mask>
|
||||
<use id="Mask" fill="url(#linearGradient-1)" xlink:href="#path-5"></use>
|
||||
<circle id="Oval-173" fill="#65B5D2" mask="url(#mask-6)" cx="2" cy="3" r="1"></circle>
|
||||
<path d="M2,2 C1.72385763,2 1.5,1.77614237 1.5,1.5 C1.5,1.22385763 1.72385763,1 2,1 C2.27614237,1 2.5,1.22385763 2.5,1.5 C2.5,1.77614237 2.27614237,2 2,2 Z M1,3 C0.723857625,3 0.5,2.77614237 0.5,2.5 C0.5,2.22385763 0.723857625,2 1,2 C1.27614237,2 1.5,2.22385763 1.5,2.5 C1.5,2.77614237 1.27614237,3 1,3 Z M3,3 C2.72385763,3 2.5,2.77614237 2.5,2.5 C2.5,2.22385763 2.72385763,2 3,2 C3.27614237,2 3.5,2.22385763 3.5,2.5 C3.5,2.77614237 3.27614237,3 3,3 Z" id="Oval-174" fill="url(#linearGradient-7)" mask="url(#mask-6)"></path>
|
||||
<rect id="Rectangle-1106" fill="#2F8F22" mask="url(#mask-6)" x="0" y="4" width="4" height="1"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.7 KiB |
28
client/images/flagKit/BN.svg
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BN</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#F7E250" offset="0%"></stop>
|
||||
<stop stop-color="#F7DF38" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#262626" offset="0%"></stop>
|
||||
<stop stop-color="#0D0D0D" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BN">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Rectangle-2-Copy-4" fill="url(#linearGradient-1)" transform="translate(11.013030, 6.090461) rotate(20.000000) translate(-11.013030, -6.090461) " x="-3.48696979" y="4.59046107" width="29" height="3"></rect>
|
||||
<rect id="Rectangle-2-Copy-4" fill="url(#linearGradient-3)" transform="translate(9.986970, 8.909539) rotate(20.000000) translate(-9.986970, -8.909539) " x="-4.51303021" y="7.40953893" width="29" height="3"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
32
client/images/flagKit/BO.svg
Normal file
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BO</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#058C3F" offset="0%"></stop>
|
||||
<stop stop-color="#007A34" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#E63426" offset="0%"></stop>
|
||||
<stop stop-color="#D52B1E" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-4">
|
||||
<stop stop-color="#FFEB1F" offset="0%"></stop>
|
||||
<stop stop-color="#FAE400" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BO">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="0" y="10" width="21" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-3)" x="0" y="0" width="21" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-4)" x="0" y="5" width="21" height="5"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
35
client/images/flagKit/BR.svg
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BR</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#05AB41" offset="0%"></stop>
|
||||
<stop stop-color="#019C39" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#053087" offset="0%"></stop>
|
||||
<stop stop-color="#012877" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<circle id="path-4" cx="3.5" cy="3.5" r="3.5"></circle>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BR">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<path d="M2.42151632,7.77274586 C2.18871929,7.62211248 2.19350487,7.37479097 2.42151632,7.22725414 L10.0784837,2.27274586 C10.3112807,2.12211248 10.6935049,2.12520903 10.9215163,2.27274586 L18.5784837,7.22725414 C18.8112807,7.37788752 18.8064951,7.62520903 18.5784837,7.77274586 L10.9215163,12.7272541 C10.6887193,12.8778875 10.3064951,12.874791 10.0784837,12.7272541 L2.42151632,7.77274586 Z" id="Combined-Shape" fill="#FDD216"></path>
|
||||
<g id="Oval-2" transform="translate(7.000000, 4.000000)">
|
||||
<mask id="mask-5" fill="white">
|
||||
<use xlink:href="#path-4"></use>
|
||||
</mask>
|
||||
<use id="Mask" fill="url(#linearGradient-3)" xlink:href="#path-4"></use>
|
||||
<path d="M-0.100381226,2.97376324 C0.164901149,2.75894182 1.36252192,2.933788 3.43417519,3.48641101 C4.90835176,3.87965437 6.60707006,4.747859 6.9957681,5.22786103 L7.31042832,5.61643399 L8.08757424,4.98711354 L7.77291401,4.59854058 C7.22285434,3.91927356 5.35175728,2.96296719 3.69191715,2.52019722 C1.10596471,1.83038255 -0.0661252244,1.65926374 -0.7297016,2.19661727 L-1.11827459,2.51127745 L-0.488954213,3.28842343 L-0.100381226,2.97376324 Z" id="Line" fill="#FFFFFF" fill-rule="nonzero" mask="url(#mask-5)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
33
client/images/flagKit/BS.svg
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BS</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#22B7D5" offset="0%"></stop>
|
||||
<stop stop-color="#1CACC8" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#FCE569" offset="0%"></stop>
|
||||
<stop stop-color="#FADF52" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-4">
|
||||
<stop stop-color="#262626" offset="0%"></stop>
|
||||
<stop stop-color="#0D0D0D" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BS">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="0" y="10" width="21" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-3)" x="0" y="5" width="21" height="5"></rect>
|
||||
<polygon id="Rectangle-83" fill="url(#linearGradient-4)" points="0 0 10 7.5 0 15"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
27
client/images/flagKit/BT.svg
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BT</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#FF5F38" offset="0%"></stop>
|
||||
<stop stop-color="#FD5026" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#FFD951" offset="0%"></stop>
|
||||
<stop stop-color="#FFD43B" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BT">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<polygon id="Rectangle-2" fill="url(#linearGradient-3)" points="0 15 21 0 0 0"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
28
client/images/flagKit/BV.svg
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BV</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#F14247" offset="0%"></stop>
|
||||
<stop stop-color="#ED2F35" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#0A3A85" offset="0%"></stop>
|
||||
<stop stop-color="#032A67" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BV">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<polygon id="Rectangle-2" fill="url(#linearGradient-1)" points="0 9 6 9 6 15 9 15 9 9 21 9 21 6 9 6 9 0 6 0 6 6 0 6"></polygon>
|
||||
<polygon id="Rectangle-2" fill="url(#linearGradient-3)" points="0 8 7 8 7 15 8 15 8 8 21 8 21 7 8 7 8 0 7 0 7 7 0 7"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
29
client/images/flagKit/BW.svg
Normal file
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BW</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#8BBDEA" offset="0%"></stop>
|
||||
<stop stop-color="#78ABDA" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#262626" offset="0%"></stop>
|
||||
<stop stop-color="#0D0D0D" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BW">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="0" y="10" width="21" height="5"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-1)" x="0" y="5" width="21" height="5"></rect>
|
||||
<rect id="Rectangle-2-Copy-4" fill="url(#linearGradient-3)" x="0" y="6" width="21" height="3"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
30
client/images/flagKit/BY.svg
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BY</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#E54252" offset="0%"></stop>
|
||||
<stop stop-color="#C63442" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#5CBE6B" offset="0%"></stop>
|
||||
<stop stop-color="#4EA55B" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BY">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="10"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-3)" x="0" y="10" width="21" height="5"></rect>
|
||||
<path d="M3,12.75 L3,15 L2.22044605e-16,15 L2.22044605e-16,0 L3,0 L3,2.25 L2.5,3 L3,3.75 L3,5.25 L2.5,6 L3,6.75 L3,8.25 L2.5,9 L3,9.75 L3,11.25 L2.5,12 L3,12.75 Z" id="Rectangle-1512" fill="url(#linearGradient-1)"></path>
|
||||
<path d="M-1.5,3 L-0.5,1.5 L0.5,3 L-0.5,4.5 L-1.5,3 Z M-1.5,6 L-0.5,4.5 L0.5,6 L-0.5,7.5 L-1.5,6 Z M-1.5,9 L-0.5,7.5 L0.5,9 L-0.5,10.5 L-1.5,9 Z M-1.5,12 L-0.5,10.5 L0.5,12 L-0.5,13.5 L-1.5,12 Z" id="Rectangle-1513" fill="url(#linearGradient-2)"></path>
|
||||
<path d="M0.5,1.5 L1.5,0 L2.5,1.5 L1.5,3 L0.5,1.5 Z M0.5,4.5 L1.5,3 L2.5,4.5 L1.5,6 L0.5,4.5 Z M0.5,7.5 L1.5,6 L2.5,7.5 L1.5,9 L0.5,7.5 Z M0.5,10.5 L1.5,9 L2.5,10.5 L1.5,12 L0.5,10.5 Z M0.5,13.5 L1.5,12 L2.5,13.5 L1.5,15 L0.5,13.5 Z" id="Rectangle-1513" fill="url(#linearGradient-2)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
30
client/images/flagKit/BZ.svg
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>BZ</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#094995" offset="0%"></stop>
|
||||
<stop stop-color="#074185" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#D5182F" offset="0%"></stop>
|
||||
<stop stop-color="#CC162C" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="BZ">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Rectangle-2-Copy-4" fill="url(#linearGradient-2)" x="0" y="2" width="21" height="11"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-3)" x="0" y="0" width="21" height="2"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-3)" x="0" y="13" width="21" height="2"></rect>
|
||||
<circle id="Oval-12" fill="url(#linearGradient-1)" cx="10.5" cy="7.5" r="4.5"></circle>
|
||||
<path d="M10.5,11 C10.2238576,11 10,10.7761424 10,10.5 C10,10.2238576 10.2238576,10 10.5,10 C10.783679,10 11.0602516,9.9529391 11.3219255,9.86189033 C11.5827313,9.77114362 11.8677209,9.90900372 11.9584676,10.1698095 C12.0492143,10.4306153 11.9113542,10.7156048 11.6505484,10.8063515 C11.2835669,10.9340418 10.8959367,11 10.5,11 Z M13.1511931,9.78506629 C13.406745,9.48879706 13.6113949,9.15160754 13.755598,8.78712579 C13.8571885,8.53034969 13.7313858,8.2398361 13.4746097,8.13824553 C13.2178336,8.03665496 12.92732,8.16245769 12.8257294,8.41923379 C12.7228617,8.67923811 12.576689,8.92007816 12.3939694,9.13191064 C12.2136055,9.34101219 12.2369019,9.65673635 12.4460034,9.83710031 C12.655105,10.0174643 12.9708291,9.99416783 13.1511931,9.78506629 Z M13.9681136,7.02598701 C13.9151393,6.63525776 13.7969147,6.25940768 13.6195772,5.91169522 C13.4941162,5.66569899 13.1929906,5.56798589 12.9469943,5.69344691 C12.7009981,5.81890792 12.603285,6.12003351 12.728746,6.36602974 C12.8551834,6.6139404 12.9393986,6.88167049 12.9771796,7.16033603 C13.014279,7.43397492 13.2661822,7.62572801 13.5398211,7.58862856 C13.81346,7.5515291 14.0052131,7.2996259 13.9681136,7.02598701 Z M12.3566317,4.53255799 C12.0253409,4.32490498 11.6610887,4.1738376 11.2774715,4.08677105 C11.0081779,4.02565162 10.7403252,4.19441011 10.6792058,4.46370368 C10.6180864,4.73299725 10.7868449,5.00084991 11.0561384,5.06196933 C11.3295087,5.12401401 11.5891154,5.23168146 11.8255367,5.37987023 C12.0595155,5.52652808 12.3680825,5.45574046 12.5147403,5.22176164 C12.6613982,4.98778282 12.5906105,4.67921584 12.3566317,4.53255799 Z M9.5575528,4.12848171 C9.17912609,4.23407333 8.82257836,4.40271264 8.5015931,4.62628761 C8.27499938,4.7841163 8.21925431,5.09575224 8.37708301,5.32234596 C8.5349117,5.54893969 8.84654764,5.60468475 9.07314136,5.44685606 C9.30235338,5.28720365 9.55662191,5.16694018 9.82631439,5.09168844 C10.0922966,5.01747198 10.2477534,4.74168648 10.173537,4.47570428 C10.0993205,4.20972209 9.823535,4.05426525 9.5575528,4.12848171 Z M7.34980403,5.9732204 C7.1794218,6.32421179 7.06864103,6.70226234 7.02331764,7.09421416 C6.99159725,7.36852863 7.18825862,7.6166189 7.46257309,7.64833928 C7.73688756,7.68005966 7.98497782,7.4833983 8.01669821,7.20908383 C8.04903512,6.9294377 8.12794951,6.6601344 8.24941219,6.40991841 C8.37000302,6.16149848 8.26637705,5.86235615 8.01795712,5.74176532 C7.76953719,5.6211745 7.47039486,5.72480046 7.34980403,5.9732204 Z M7.29030361,8.89755956 C7.44684558,9.25665095 7.66282722,9.58666982 7.92825784,9.874078 C8.11560955,10.0769424 8.43194217,10.0895179 8.63480653,9.90216614 C8.83767089,9.71481443 8.85024638,9.39848181 8.66289467,9.19561745 C8.47304982,8.99005351 8.31870545,8.75421609 8.20698559,8.49794206 C8.09663426,8.24480732 7.80197059,8.12905849 7.54883585,8.23940982 C7.29570111,8.34976114 7.17995228,8.64442482 7.29030361,8.89755956 Z M9.43580227,10.8351354 C9.17271015,10.7512477 9.02743627,10.469965 9.11132398,10.2068729 C9.19521168,9.94378077 9.47649441,9.79850688 9.73958653,9.88239459 C9.96870828,9.95545074 10.2085454,9.99517772 10.454027,9.99958744 C10.7301248,10.0045471 10.9499257,10.2323893 10.944966,10.5084871 C10.9400063,10.7845849 10.7121642,11.0043858 10.4360664,10.9994261 C10.0932451,10.9932679 9.75713989,10.9375949 9.43580227,10.8351354 Z" id="Oval-73" fill="#118014" fill-rule="nonzero"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.9 KiB |
25
client/images/flagKit/CA.svg
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>CA</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#FF3131" offset="0%"></stop>
|
||||
<stop stop-color="#FF0000" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="CA">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask" fill="url(#linearGradient-2)" x="10" y="0" width="11" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="0" y="0" width="7" height="15"></rect>
|
||||
<rect id="Rectangle-2-Copy" fill="url(#linearGradient-1)" x="6" y="0" width="9" height="15"></rect>
|
||||
<path d="M11.6741867,7.32581329 L12.3258133,6.67418671 C12.4215317,6.57846832 12.5808177,6.58081774 12.6805115,6.68051147 L13,7 L14,6.5 L13.5,7.5 L13.8194885,7.81948853 C13.921875,7.921875 13.9229621,8.07703795 13.8279309,8.17206907 L12.5,9.5 L11,9.5 L10.75,11 L10.25,11 L10,9.5 L8.5,9.5 L7.17206907,8.17206907 C7.08064651,8.08064651 7.08081774,7.91918226 7.18051147,7.81948853 L7.5,7.5 L7,6.5 L8,7 L8.31948853,6.68051147 C8.421875,6.578125 8.57798604,6.57798604 8.67418671,6.67418671 L9.32581329,7.32581329 C9.42153168,7.42153168 9.47771727,7.38858633 9.45023012,7.25115061 L9,5 L10,5.5 L10.5,4 L11,5.5 L12,5 L11.5497699,7.25115061 C11.5214844,7.39257812 11.577986,7.42201396 11.6741867,7.32581329 Z" id="Combined-Shape" fill="url(#linearGradient-2)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
33
client/images/flagKit/CC.svg
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>CC</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#229716" offset="0%"></stop>
|
||||
<stop stop-color="#1C7E12" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#FFE244" offset="0%"></stop>
|
||||
<stop stop-color="#FFDF32" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="CC">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<path d="M4,6 C2.8954305,6 2,5.1045695 2,4 C2,2.8954305 2.8954305,2 4,2 C5.1045695,2 6,2.8954305 6,4 C6,5.1045695 5.1045695,6 4,6 Z M4,4 C4.2082035,4 3.83990355,5.05443624 4,5 C4.26457858,4.91003759 5,3.67204063 5,3.5 C5,3.22385763 4.55228475,3 4,3 C3.44771525,3 3,3.22385763 3,3.5 C3,3.77614237 3.44771525,4 4,4 Z" id="Combined-Shape" fill="url(#linearGradient-3)"></path>
|
||||
<polygon id="Star-2" fill="url(#linearGradient-3)" points="16 13 15.2928932 13.2071068 15.5 12.5 15.2928932 11.7928932 16 12 16.7071068 11.7928932 16.5 12.5 16.7071068 13.2071068"></polygon>
|
||||
<polygon id="Star-2" fill="url(#linearGradient-3)" points="16 3.5 15.2928932 3.70710678 15.5 3 15.2928932 2.29289322 16 2.5 16.7071068 2.29289322 16.5 3 16.7071068 3.70710678"></polygon>
|
||||
<polygon id="Star-2" fill="url(#linearGradient-3)" points="19 6.5 18.2928932 6.70710678 18.5 6 18.2928932 5.29289322 19 5.5 19.7071068 5.29289322 19.5 6 19.7071068 6.70710678"></polygon>
|
||||
<polygon id="Star-2" fill="url(#linearGradient-3)" points="14 7.5 13.2928932 7.70710678 13.5 7 13.2928932 6.29289322 14 6.5 14.7071068 6.29289322 14.5 7 14.7071068 7.70710678"></polygon>
|
||||
<polygon id="Star-2" fill="url(#linearGradient-3)" points="17.5 8.75 17.1464466 8.85355339 17.25 8.5 17.1464466 8.14644661 17.5 8.25 17.8535534 8.14644661 17.75 8.5 17.8535534 8.85355339"></polygon>
|
||||
<path d="M12.0613625,5.54741025 C11.6335382,5.2048611 11.090693,5 10.5,5 C9.11928813,5 8,6.11928813 8,7.5 C8,8.88071187 9.11928813,10 10.5,10 C11.090693,10 11.6335382,9.7951389 12.0613625,9.45258975 C11.834734,9.53712452 11.58943,9.58333333 11.3333333,9.58333333 C10.1827401,9.58333333 9.25,8.65059323 9.25,7.5 C9.25,6.34940677 10.1827401,5.41666667 11.3333333,5.41666667 C11.58943,5.41666667 11.834734,5.46287548 12.0613625,5.54741025 L12.0613625,5.54741025 Z" id="Oval-12" fill="url(#linearGradient-3)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.2 KiB |
31
client/images/flagKit/CD.svg
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>CD</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#158AFF" offset="0%"></stop>
|
||||
<stop stop-color="#007FFF" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#CE1120" offset="0%"></stop>
|
||||
<stop stop-color="#E11B2B" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="CD">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<g id="Group-2" transform="translate(-4.290000, -1.440000)">
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="4.29377901" y="1.44262682" width="21" height="15"></rect>
|
||||
<polygon id="Rectangle-69-Copy" fill="#FDD216" transform="translate(14.281566, 9.255882) rotate(153.000000) translate(-14.281566, -9.255882) " points="-0.2184339 6.25588182 28.7815661 6.25588182 28.7815661 12.2558818 -0.2184339 12.2558818"></polygon>
|
||||
<rect id="Rectangle-69" fill="url(#linearGradient-3)" transform="translate(14.557467, 9.073824) rotate(153.000000) translate(-14.557467, -9.073824) " x="0.0574665988" y="7.07382404" width="29" height="4"></rect>
|
||||
<polygon id="Star-8" fill="#FDD216" points="7.79377901 5.91762686 6.32431588 6.9651693 6.86649887 5.2439184 5.41613772 4.17008433 7.22068837 4.15383522 7.79377901 2.44262682 8.36686965 4.15383522 10.1714203 4.17008433 8.72105915 5.2439184 9.26324214 6.9651693"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.2 KiB |
43
client/images/flagKit/CF.svg
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>CF</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#083D96" offset="0%"></stop>
|
||||
<stop stop-color="#053380" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#37AE39" offset="0%"></stop>
|
||||
<stop stop-color="#2E9630" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-4">
|
||||
<stop stop-color="#FFD13F" offset="0%"></stop>
|
||||
<stop stop-color="#FFCD2F" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-5">
|
||||
<stop stop-color="#E42346" offset="0%"></stop>
|
||||
<stop stop-color="#D01739" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-6">
|
||||
<stop stop-color="#FFD03B" offset="0%"></stop>
|
||||
<stop stop-color="#FFCD2F" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="CF">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="4"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-3)" x="0" y="7" width="21" height="4"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-4)" x="0" y="11" width="21" height="4"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-1)" x="0" y="4" width="21" height="3"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-5)" x="8" y="0" width="5" height="15"></rect>
|
||||
<polygon id="Star-8" fill="url(#linearGradient-6)" points="3.5 2.58500002 2.61832212 3.21352549 2.94363192 2.18077495 2.07341523 1.53647451 3.15614561 1.52672504 3.5 0.5 3.84385439 1.52672504 4.92658477 1.53647451 4.05636808 2.18077495 4.38167788 3.21352549"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.7 KiB |
34
client/images/flagKit/CG.svg
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>CG</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#F33630" offset="0%"></stop>
|
||||
<stop stop-color="#DC241E" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#009643" offset="0%"></stop>
|
||||
<stop stop-color="#09C15B" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-4">
|
||||
<stop stop-color="#FCDF4A" offset="0%"></stop>
|
||||
<stop stop-color="#FCE154" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="CG">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<g id="Group-2" transform="translate(-1.060000, -5.020000)">
|
||||
<polygon id="Rectangle-74" fill="url(#linearGradient-2)" points="6.06152385 19.017348 21.0615238 5.01734803 22.0615238 5.01734803 22.0615238 20.017348 6.06152385 20.017348"></polygon>
|
||||
<polygon id="Rectangle-74-Copy" fill="url(#linearGradient-3)" transform="translate(9.061524, 12.517348) scale(-1, -1) translate(-9.061524, -12.517348) " points="1.06152385 19.017348 16.0615238 5.01734803 17.0615238 5.01734803 17.0615238 20.017348 1.06152385 20.017348"></polygon>
|
||||
<polygon id="Rectangle-69-Copy" fill="url(#linearGradient-4)" transform="translate(11.870896, 12.167073) rotate(134.000000) translate(-11.870896, -12.167073) " points="-2.62910413 9.66707303 26.3708959 9.66707303 26.3708959 14.667073 -2.62910413 14.667073"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.3 KiB |
23
client/images/flagKit/CH.svg
Normal file
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>CH</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="100%" x2="50%" y2="3.061617e-15%" id="linearGradient-2">
|
||||
<stop stop-color="#FF0000" offset="0%"></stop>
|
||||
<stop stop-color="#FF3131" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="CH">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask-Copy" fill="url(#linearGradient-2)" x="0" y="0" width="21" height="15"></rect>
|
||||
<path d="M9,9 L6.25577831,9 C6.11451585,9 6,8.88605976 6,8.74422169 L6,6.25577831 C6,6.11451585 6.11394024,6 6.25577831,6 L9,6 L9,3.25577831 C9,3.11451585 9.11394024,3 9.25577831,3 L11.7442217,3 C11.8854841,3 12,3.11394024 12,3.25577831 L12,6 L14.7442217,6 C14.8854841,6 15,6.11394024 15,6.25577831 L15,8.74422169 C15,8.88548415 14.8860598,9 14.7442217,9 L12,9 L12,11.7442217 C12,11.8854841 11.8860598,12 11.7442217,12 L9.25577831,12 C9.11451585,12 9,11.8860598 9,11.7442217 L9,9 Z" id="Combined-Shape" fill="url(#linearGradient-1)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
28
client/images/flagKit/CI.svg
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="21px" height="15px" viewBox="0 0 21 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: sketchtool 46 (44423) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>CI</title>
|
||||
<desc>Created with sketchtool.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#FFFFFF" offset="0%"></stop>
|
||||
<stop stop-color="#F0F0F0" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
|
||||
<stop stop-color="#1DC87D" offset="0%"></stop>
|
||||
<stop stop-color="#169E62" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-3">
|
||||
<stop stop-color="#F89242" offset="0%"></stop>
|
||||
<stop stop-color="#F67F22" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="CI">
|
||||
<rect id="FlagBackground" fill="url(#linearGradient-1)" x="0" y="0" width="21" height="15"></rect>
|
||||
<rect id="Mask" fill="url(#linearGradient-2)" x="10" y="0" width="11" height="15"></rect>
|
||||
<rect id="Rectangle-2" fill="url(#linearGradient-3)" x="0" y="0" width="7" height="15"></rect>
|
||||
<rect id="Rectangle-2-Copy" fill="url(#linearGradient-1)" x="7" y="0" width="7" height="15"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |