Compare commits

..

13 Commits

Author SHA1 Message Date
albexk
9ebefe79ca refactor: modify response json 2024-11-08 11:12:56 +03:00
albexk
d7581f29ba Merge branch 'dev' into feature/android-gpb
# Conflicts:
#	CMakeLists.txt
#	client/android/src/org/amnezia/vpn/AmneziaActivity.kt
2024-10-30 17:39:13 +03:00
albexk
2c6ae4214d Add methods to verify and purchase subscriptions 2024-10-30 17:35:33 +03:00
albexk
12eee2cd40 Merge branch 'dev' into feature/android-gpb
# Conflicts:
#	CMakeLists.txt
2024-10-03 19:52:38 +03:00
albexk
bad9327ffa Add method to get the list of offers 2024-10-03 19:47:39 +03:00
albexk
3bd6f704e9 Merge branch 'dev' into feature/android-gpb
# Conflicts:
#	CMakeLists.txt
2024-09-24 17:55:01 +03:00
albexk
58d1178416 Build script refactor to support AAB build for Google Play 2024-09-17 21:27:59 +03:00
albexk
e2dd5109f9 Add a method to detect Google Play build 2024-09-17 20:53:36 +03:00
albexk
582bd92d31 Add billing module, provide a separate build for Google Play 2024-09-17 20:51:02 +03:00
albexk
fe18472d07 Disable Qt debugger sleep 2024-09-17 20:44:39 +03:00
albexk
cb90881f24 Merge branch 'dev' into feature/android-gpb
# Conflicts:
#	CMakeLists.txt
2024-09-17 18:08:30 +03:00
albexk
8e95e6a2fd Bump Android version code to 59 2024-09-17 18:07:29 +03:00
albexk
73990bb07d Add Google Play Billing Library 2024-09-11 19:51:32 +03:00
72 changed files with 1620 additions and 2167 deletions

View File

@@ -306,70 +306,6 @@ jobs:
path: deploy/build/client/AmneziaVPN.app
retention-days: 7
# ------------------------------------------------------
Build-MacOS-NE:
runs-on: macos-latest
env:
QT_VERSION: 6.4.3
QIF_VERSION: 4.6
QT_MIRROR: https://mirrors.ocf.berkeley.edu/qt/
PROD_AGW_PUBLIC_KEY: ${{ secrets.PROD_AGW_PUBLIC_KEY }}
DEV_AGW_PUBLIC_KEY: ${{ secrets.DEV_AGW_PUBLIC_KEY }}
steps:
- name: 'Setup Xcode'
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '14.3.1'
- name: 'Install desktop Qt'
uses: jurplel/install-qt-action@v3
with:
version: ${{ env.QT_VERSION }}
host: 'mac'
target: 'desktop'
modules: 'qtremoteobjects qt5compat qtshadertools qtmultimedia'
arch: 'clang_64'
dir: ${{ runner.temp }}
set-env: 'true'
extra: '--base ${{ env.QT_MIRROR }}'
- name: 'Install Qt Installer Framework ${{ env.QIF_VERSION }}'
run: |
mkdir -pv ${{ runner.temp }}/Qt/Tools/QtInstallerFramework
wget https://qt.amzsvc.com/tools/ifw/${{ env.QIF_VERSION }}.zip
unzip ${{ env.QIF_VERSION }}.zip -d ${{ runner.temp }}/Qt/Tools/QtInstallerFramework/
- name: 'Install Go'
uses: actions/setup-go@v5
with:
go-version: '1.22.1'
cache: false
- name: 'Get sources'
uses: actions/checkout@v4
with:
submodules: 'true'
fetch-depth: 10
- name: 'Install dependencies'
run: pip install jsonschema jinja2
- name: 'Set execute permissions for deploy script'
run: chmod +x deploy/build_macos_ne.sh
# - name: 'Build and deploy macOS NE'
# run: |
# export QT_BIN_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos/bin"
# export QIF_BIN_DIR="${{ runner.temp }}/Qt/Tools/QtInstallerFramework/${{ env.QIF_VERSION }}/bin"
# export QT_MACOS_ROOT_DIR="${{ runner.temp }}/Qt/${{ env.QT_VERSION }}/macos"
# bash deploy/build_macos_ne.sh
# env:
# APPSTORE_CONNECT_KEY_ID: ${{ secrets.APPSTORE_CONNECT_KEY_ID }}
# APPSTORE_CONNECT_ISSUER_ID: ${{ secrets.APPSTORE_CONNECT_ISSUER_ID }}
# APPSTORE_CONNECT_PRIVATE_KEY: ${{ secrets.APPSTORE_CONNECT_PRIVATE_KEY }}
# MAC_TRUST_CERT_BASE64: ${{ secrets.IOS_TRUST_CERT_BASE64 }}
# MAC_SIGNING_CERT_BASE64: ${{ secrets.IOS_SIGNING_CERT_BASE64 }}
# MAC_SIGNING_CERT_PASSWORD: ${{ secrets.IOS_SIGNING_CERT_PASSWORD }}
# ------------------------------------------------------
Build-Android:
@@ -482,13 +418,13 @@ jobs:
ANDROID_KEYSTORE_KEY_ALIAS: ${{ secrets.ANDROID_RELEASE_KEYSTORE_KEY_ALIAS }}
ANDROID_KEYSTORE_KEY_PASS: ${{ secrets.ANDROID_RELEASE_KEYSTORE_KEY_PASS }}
shell: bash
run: ./deploy/build_android.sh --aab --apk all --build-platform ${{ env.ANDROID_BUILD_PLATFORM }}
run: ./deploy/build_android.sh --aab --play --apk all --build-platform ${{ env.ANDROID_BUILD_PLATFORM }}
- name: 'Upload x86_64 apk'
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN-android-x86_64
path: deploy/build/AmneziaVPN-x86_64-release.apk
path: deploy/build/AmneziaVPN-oss-x86_64-release.apk
compression-level: 0
retention-days: 7
@@ -496,7 +432,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN-android-x86
path: deploy/build/AmneziaVPN-x86-release.apk
path: deploy/build/AmneziaVPN-oss-x86-release.apk
compression-level: 0
retention-days: 7
@@ -504,7 +440,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN-android-arm64-v8a
path: deploy/build/AmneziaVPN-arm64-v8a-release.apk
path: deploy/build/AmneziaVPN-oss-arm64-v8a-release.apk
compression-level: 0
retention-days: 7
@@ -512,7 +448,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN-android-armeabi-v7a
path: deploy/build/AmneziaVPN-armeabi-v7a-release.apk
path: deploy/build/AmneziaVPN-oss-armeabi-v7a-release.apk
compression-level: 0
retention-days: 7
@@ -520,7 +456,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: AmneziaVPN-android
path: deploy/build/AmneziaVPN-release.aab
path: deploy/build/AmneziaVPN-play-release.aab
compression-level: 0
retention-days: 7
@@ -540,4 +476,4 @@ jobs:
if: ${{ fromJSON(steps.pull_request.outputs.data)[0].number != '' }}
run: |
echo "Pull request:" >> $GITHUB_STEP_SUMMARY
echo "[[#${{ fromJSON(steps.pull_request.outputs.data)[0].number }}] ${{ fromJSON(steps.pull_request.outputs.data)[0].title }}](${{ fromJSON(steps.pull_request.outputs.data)[0].html_url }})" >> $GITHUB_STEP_SUMMARY
echo "[[#${{ fromJSON(steps.pull_request.outputs.data)[0].number }}] ${{ fromJSON(steps.pull_request.outputs.data)[0].title }}](${{ fromJSON(steps.pull_request.outputs.data)[0].html_url }})" >> $GITHUB_STEP_SUMMARY

2
.gitmodules vendored
View File

@@ -1,7 +1,6 @@
[submodule "client/3rd/OpenVPNAdapter"]
path = client/3rd/OpenVPNAdapter
url = https://github.com/amnezia-vpn/OpenVPNAdapter.git
branch = macos-dirty-build
[submodule "client/3rd/qtkeychain"]
path = client/3rd/qtkeychain
url = https://github.com/frankosterfeld/qtkeychain.git
@@ -11,7 +10,6 @@
[submodule "client/3rd-prebuilt"]
path = client/3rd-prebuilt
url = https://github.com/amnezia-vpn/3rd-prebuilt
branch = fixbug/mac-network-extension
[submodule "client/3rd/amneziawg-apple"]
path = client/3rd/amneziawg-apple
url = https://github.com/amnezia-vpn/amneziawg-apple

View File

@@ -31,13 +31,13 @@ set(QT_BUILD_TOOLS_WHEN_CROSS_COMPILING ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if((APPLE AND NOT IOS) OR (DEFINED MACOS_NE AND MACOS_NE AND NOT IOS))
if(APPLE AND NOT IOS)
set(CMAKE_OSX_ARCHITECTURES "x86_64")
endif()
add_subdirectory(client)
if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
if(NOT IOS AND NOT ANDROID)
add_subdirectory(service)
include(${CMAKE_SOURCE_DIR}/deploy/installer/config.cmake)

View File

@@ -31,12 +31,11 @@ add_definitions(-DDEV_AGW_PUBLIC_KEY="$ENV{DEV_AGW_PUBLIC_KEY}")
add_definitions(-DDEV_AGW_ENDPOINT="$ENV{DEV_AGW_ENDPOINT}")
add_definitions(-DDEV_S3_ENDPOINT="$ENV{DEV_S3_ENDPOINT}")
if(IOS OR MACOS_NE)
if(IOS)
set(PACKAGES ${PACKAGES} Multimedia)
endif()
#Macos Network Extension doesn't need Widgets
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
set(PACKAGES ${PACKAGES} Widgets)
endif()
@@ -49,23 +48,18 @@ set(LIBS ${LIBS}
Qt6::Core5Compat Qt6::Concurrent
)
if(IOS OR MACOS_NE)
if(IOS)
set(LIBS ${LIBS} Qt6::Multimedia)
endif()
# message("Client desktop build ", ${MACOS_NE})
#Macos Network Extension doesn't need Widgets
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
message("Run this block when MACOS_NE is not defined or set to FALSE")
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
set(LIBS ${LIBS} Qt6::Widgets)
endif()
qt_standard_project_setup()
qt_add_executable(${PROJECT} MANUAL_FINALIZATION)
# TODO error in there
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
message("Run this block when MACOS_NE is not defined or set to FALSE")
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_interface.rep)
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_process_interface.rep)
qt_add_repc_replicas(${PROJECT} ${CMAKE_CURRENT_LIST_DIR}/../ipc/ipc_process_tun2socks.rep)
@@ -103,18 +97,10 @@ qt6_add_resources(QRC ${I18NQRC} ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc)
# -- i18n end
if(IOS)
message("Building for iOS")
execute_process(COMMAND bash ${CMAKE_CURRENT_LIST_DIR}/ios/scripts/openvpn.sh args
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
endif()
# Build openvpn adapter for MacOS Network Extension
if(MACOS_NE)
message("Building for MacOS Network Extension")
execute_process(COMMAND bash ${CMAKE_CURRENT_LIST_DIR}/macos/scripts/openvpn.sh args
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR})
endif()
set(IS_CI ${CI})
if(IS_CI)
message("Detected CI env")
@@ -175,24 +161,12 @@ include_directories(mozilla)
include_directories(mozilla/shared)
include_directories(mozilla/models)
if(MACOS_NE)
message("MACOS_NE is ON")
add_definitions(-DQ_OS_IOS)
add_definitions(-DMACOS_NE)
message("Add macros for MacOS Network Extension")
else()
message("MACOS_NE is OFF")
endif()
if(NOT IOS AND NOT MACOS_NE)
message(" Add header for non-IOS and non-MACOS_NE")
if(NOT IOS)
set(HEADERS ${HEADERS}
${CMAKE_CURRENT_LIST_DIR}/platforms/ios/QRCodeReaderBase.h
)
endif()
if(NOT ANDROID)
set(HEADERS ${HEADERS}
${CMAKE_CURRENT_LIST_DIR}/ui/notificationhandler.h
@@ -237,7 +211,7 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_compile_definitions(${PROJECT} PRIVATE "MZ_DEBUG")
endif()
if(NOT IOS AND NOT MACOS_NE)
if(NOT IOS)
set(SOURCES ${SOURCES}
${CMAKE_CURRENT_LIST_DIR}/platforms/ios/QRCodeReaderBase.cpp
)
@@ -338,7 +312,6 @@ if(APPLE)
set(CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM ${BUILD_VPN_DEVELOPMENT_TEAM})
set(CMAKE_XCODE_ATTRIBUTE_GROUP_ID_IOS ${BUILD_IOS_GROUP_IDENTIFIER})
set(MACOSX_DEPLOYMENT_TARGET "12.0")
endif()
if(LINUX AND NOT ANDROID)
@@ -346,9 +319,10 @@ if(LINUX AND NOT ANDROID)
link_directories(${CMAKE_CURRENT_LIST_DIR}/platforms/linux)
endif()
# Macos Network Extension doesn't need
if(WIN32 OR (APPLE AND NOT IOS AND NOT MACOS_NE) OR (LINUX AND NOT ANDROID))
if(WIN32 OR (APPLE AND NOT IOS) OR (LINUX AND NOT ANDROID))
message("Client desktop build")
add_compile_definitions(AMNEZIA_DESKTOP)
set(HEADERS ${HEADERS}
${CMAKE_CURRENT_LIST_DIR}/core/ipcclient.h
${CMAKE_CURRENT_LIST_DIR}/core/privileged_process.h
@@ -381,12 +355,9 @@ endif()
if(IOS)
include(cmake/ios.cmake)
include(cmake/ios-arch-fixup.cmake)
elseif(APPLE AND NOT IOS AND NOT DEFINED MACOS_NE)
# include(cmake/osxtools.cmake)
include(cmake/macos.cmake)
elseif(APPLE AND NOT IOS AND MACOS_NE)
elseif(APPLE AND NOT IOS)
include(cmake/osxtools.cmake)
include(cmake/macos_ne.cmake)
include(cmake/macos.cmake)
endif()
target_link_libraries(${PROJECT} PRIVATE ${LIBS})
@@ -405,7 +376,7 @@ elseif(APPLE AND NOT IOS)
set(DEPLOY_PLATFORM_PATH "macos")
endif()
if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
if(NOT IOS AND NOT ANDROID)
add_custom_command(
TARGET ${PROJECT} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E $<IF:$<CONFIG:Debug>,copy_directory,true>
@@ -424,36 +395,4 @@ if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
endif()
target_sources(${PROJECT} PRIVATE ${SOURCES} ${HEADERS} ${RESOURCES} ${QRC} ${I18NQRC})
if(MACOS_NE)
message("Copy MacOS Network Extension files")
add_custom_command(TARGET ${PROJECT} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory
$<TARGET_BUNDLE_DIR:AmneziaVPN>/Contents/Frameworks
COMMAND ${CMAKE_COMMAND} -E echo "Copying OpenVPNAdapter.framework..."
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_SOURCE_DIR}/client/3rd/OpenVPNAdapter/build/Release-macos/OpenVPNAdapter.framework/Versions/A
$<TARGET_BUNDLE_DIR:AmneziaVPN>/Contents/Frameworks/OpenVPNAdapter.framework/Versions/A
COMMAND ${CMAKE_COMMAND} -E echo "OpenVPNAdapter.framework copied successfully."
)
# MacOS specific application deployment
add_custom_command(TARGET ${PROJECT} POST_BUILD
COMMAND ${QT_BIN_DIR_DETECTED}/macdeployqt $<TARGET_BUNDLE_DIR:AmneziaVPN> -appstore-compliant -qmldir=${CMAKE_CURRENT_SOURCE_DIR}
)
# MacOS specific code signing for Release
if(CMAKE_BUILD_TYPE STREQUAL "Release")
SET(SIGN_CMD codesign --deep --force --sign 'Apple Distribution: Privacy Technologies OU \(X7UJ388FXK\)' --timestamp --options runtime $<TARGET_BUNDLE_DIR:AmneziaVPN>)
message("Manual signing bundle...")
message(${SIGN_CMD})
add_custom_command(TARGET ${PROJECT} POST_BUILD
COMMAND ${SIGN_CMD}
)
endif()
endif()
qt_finalize_target(${PROJECT})

View File

@@ -0,0 +1,19 @@
plugins {
id(libs.plugins.android.library.get().pluginId)
id(libs.plugins.kotlin.android.get().pluginId)
}
kotlin {
jvmToolchain(17)
}
android {
namespace = "org.amnezia.vpn.billing"
}
dependencies {
compileOnly(project(":utils"))
implementation(libs.androidx.core)
implementation(libs.kotlinx.coroutines)
implementation(libs.android.billing)
}

View File

@@ -0,0 +1,65 @@
import com.android.billingclient.api.BillingClient.BillingResponseCode.BILLING_UNAVAILABLE
import com.android.billingclient.api.BillingClient.BillingResponseCode.DEVELOPER_ERROR
import com.android.billingclient.api.BillingClient.BillingResponseCode.ERROR
import com.android.billingclient.api.BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED
import com.android.billingclient.api.BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED
import com.android.billingclient.api.BillingClient.BillingResponseCode.ITEM_NOT_OWNED
import com.android.billingclient.api.BillingClient.BillingResponseCode.ITEM_UNAVAILABLE
import com.android.billingclient.api.BillingClient.BillingResponseCode.NETWORK_ERROR
import com.android.billingclient.api.BillingClient.BillingResponseCode.SERVICE_DISCONNECTED
import com.android.billingclient.api.BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE
import com.android.billingclient.api.BillingClient.BillingResponseCode.USER_CANCELED
import com.android.billingclient.api.BillingResult
import org.amnezia.vpn.util.ErrorCode
internal class BillingException(
billingResult: BillingResult,
retryable: Boolean = false
) : Exception(billingResult.toString()) {
constructor(msg: String) : this(BillingResult.newBuilder()
.setResponseCode(DEVELOPER_ERROR)
.setDebugMessage(msg)
.build())
val errorCode: Int
val isCanceled = billingResult.responseCode == USER_CANCELED
val isRetryable = retryable || billingResult.responseCode in setOf(
NETWORK_ERROR,
SERVICE_DISCONNECTED,
SERVICE_UNAVAILABLE,
ERROR
)
init {
when (billingResult.responseCode) {
ERROR -> {
errorCode = ErrorCode.BillingGooglePlayError
}
BILLING_UNAVAILABLE, SERVICE_DISCONNECTED, SERVICE_UNAVAILABLE -> {
errorCode = ErrorCode.BillingUnavailable
}
DEVELOPER_ERROR, FEATURE_NOT_SUPPORTED, ITEM_NOT_OWNED -> {
errorCode = ErrorCode.BillingError
}
ITEM_ALREADY_OWNED -> {
errorCode = ErrorCode.SubscriptionAlreadyOwned
}
ITEM_UNAVAILABLE -> {
errorCode = ErrorCode.SubscriptionUnavailable
}
NETWORK_ERROR -> {
errorCode = ErrorCode.BillingNetworkError
}
else -> {
errorCode = ErrorCode.BillingError
}
}
}
}

View File

@@ -0,0 +1,320 @@
import android.app.Activity
import android.content.Context
import com.android.billingclient.api.AcknowledgePurchaseParams
import com.android.billingclient.api.BillingClient
import com.android.billingclient.api.BillingClient.BillingResponseCode
import com.android.billingclient.api.BillingClient.ProductType
import com.android.billingclient.api.BillingClientStateListener
import com.android.billingclient.api.BillingFlowParams
import com.android.billingclient.api.BillingFlowParams.SubscriptionUpdateParams.ReplacementMode
import com.android.billingclient.api.BillingResult
import com.android.billingclient.api.GetBillingConfigParams
import com.android.billingclient.api.PendingPurchasesParams
import com.android.billingclient.api.ProductDetails
import com.android.billingclient.api.Purchase
import com.android.billingclient.api.PurchasesUpdatedListener
import com.android.billingclient.api.QueryProductDetailsParams
import com.android.billingclient.api.QueryProductDetailsParams.Product
import com.android.billingclient.api.QueryPurchasesParams
import com.android.billingclient.api.acknowledgePurchase
import com.android.billingclient.api.queryProductDetails
import com.android.billingclient.api.queryPurchasesAsync
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.withContext
import org.amnezia.vpn.util.ErrorCode
import org.amnezia.vpn.util.Log
import org.json.JSONArray
import org.json.JSONObject
private const val TAG = "BillingProvider"
private const val PRODUCT_ID = "premium"
class BillingProvider(context: Context) : AutoCloseable {
private var billingClient: BillingClient
private var subscriptionPurchases = MutableStateFlow<Pair<BillingResult, List<Purchase>?>?>(null)
private val purchasesUpdatedListeners = PurchasesUpdatedListener { billingResult, purchases ->
Log.v(TAG, "Purchases updated: $billingResult")
subscriptionPurchases.value = billingResult to purchases
}
init {
billingClient = BillingClient.newBuilder(context)
.setListener(purchasesUpdatedListeners)
.enablePendingPurchases(PendingPurchasesParams.newBuilder().enableOneTimeProducts().build())
.build()
}
private suspend fun connect() {
if (billingClient.isReady) return
Log.v(TAG, "Billing client connection")
val connection = CompletableDeferred<Unit>()
withContext(Dispatchers.IO) {
billingClient.startConnection(object : BillingClientStateListener {
override fun onBillingSetupFinished(billingResult: BillingResult) {
Log.v(TAG, "Billing setup finished: $billingResult")
if (billingResult.isOk) {
connection.complete(Unit)
} else {
Log.e(TAG, "Billing setup failed: $billingResult")
connection.completeExceptionally(BillingException(billingResult))
}
}
override fun onBillingServiceDisconnected() {
Log.w(TAG, "Billing service disconnected")
}
})
}
connection.await()
}
private suspend fun handleBillingApiCall(block: suspend () -> JSONObject): JSONObject {
val numberAttempts = 3
var attemptCount = 0
while (true) {
try {
return block()
} catch (e: BillingException) {
if (e.isCanceled) {
Log.w(TAG, "Billing canceled")
return JSONObject().put("responseCode", ErrorCode.BillingCanceled)
} else if (e.isRetryable && attemptCount < numberAttempts) {
Log.d(TAG, "Retryable error: $e")
++attemptCount
delay(1000)
} else {
Log.e(TAG, "Billing error: $e")
return JSONObject().put("responseCode", e.errorCode)
}
} catch (_: CancellationException) {
Log.w(TAG, "Billing coroutine canceled")
return JSONObject().put("responseCode", ErrorCode.BillingCanceled)
}
}
}
suspend fun getSubscriptionPlans(): JSONObject {
Log.v(TAG, "Get subscription plans")
val productDetailsList = getProductDetails()
val resultJson = JSONObject().put("responseCode", ErrorCode.NoError)
val productArray = JSONArray().also { resultJson.put("products", it) }
productDetailsList?.forEach { productDetails ->
val product = JSONObject().also { productArray.put(it) }
.put("productId", productDetails.productId)
.put("name", productDetails.name)
val offers = JSONArray().also { product.put("offers", it) }
productDetails.subscriptionOfferDetails?.forEach { offerDetails ->
val offer = JSONObject().also { offers.put(it) }
.put("basePlanId", offerDetails.basePlanId)
.put("offerId", offerDetails.offerId)
.put("offerToken", offerDetails.offerToken)
val pricingPhases = JSONArray().also { offer.put("pricingPhases", it) }
offerDetails.pricingPhases.pricingPhaseList.forEach { phase ->
JSONObject().also { pricingPhases.put(it) }
.put("billingCycleCount", phase.billingCycleCount)
.put("billingPeriod", phase.billingPeriod)
.put("formatedPrice", phase.formattedPrice)
.put("recurrenceMode", phase.recurrenceMode)
}
}
}
return resultJson
}
private suspend fun getProductDetails(): List<ProductDetails>? {
Log.v(TAG, "Get product details")
val productDetailsParams = Product.newBuilder()
.setProductId(PRODUCT_ID)
.setProductType(ProductType.SUBS)
.build()
val queryProductDetailsParams = QueryProductDetailsParams.newBuilder()
.setProductList(listOf(productDetailsParams))
.build()
val result = withContext(Dispatchers.IO) {
billingClient.queryProductDetails(queryProductDetailsParams)
}
Log.v(TAG, "Query product details result: ${result.billingResult}")
if (!result.billingResult.isOk) {
Log.e(TAG, "Failed to get product details: ${result.billingResult}")
throw BillingException(result.billingResult)
}
return result.productDetailsList
}
suspend fun getCustomerCountryCode(): JSONObject {
Log.v(TAG, "Get customer country code")
val deferred = CompletableDeferred<String>()
withContext(Dispatchers.IO) {
billingClient.getBillingConfigAsync(GetBillingConfigParams.newBuilder().build(),
{ billingResult, billingConfig ->
Log.v(TAG, "Billing config: $billingResult, ${billingConfig?.countryCode}")
if (billingResult.isOk) {
deferred.complete(billingConfig?.countryCode ?: "")
} else {
deferred.completeExceptionally(BillingException(billingResult))
}
})
}
val countryCode = deferred.await()
return JSONObject()
.put("responseCode", ErrorCode.NoError)
.put("countryCode", countryCode)
}
suspend fun purchaseSubscription(
activity: Activity,
offerToken: String,
oldPurchaseToken: String? = null
): JSONObject {
Log.v(TAG, "Purchase subscription")
Log.v(TAG, "Offer token: $offerToken")
oldPurchaseToken?.let { Log.v(TAG, "Old purchase token: $it") }
if (offerToken.isBlank()) throw BillingException("offerToken can not be empty")
val productDetails = getProductDetails()?.let {
it.filter { it.productId == PRODUCT_ID }
}?.firstOrNull() ?: throw BillingException("Product details not found")
Log.v(TAG, "Filtered product details:\n$productDetails")
val productDetail = BillingFlowParams.ProductDetailsParams.newBuilder()
.setProductDetails(productDetails)
.setOfferToken(offerToken)
.build()
val subscriptionUpdateParams = oldPurchaseToken?.let {
BillingFlowParams.SubscriptionUpdateParams.newBuilder()
.setOldPurchaseToken(oldPurchaseToken)
.setSubscriptionReplacementMode(ReplacementMode.WITHOUT_PRORATION)
.build()
}
val billingResult = billingClient.launchBillingFlow(activity, BillingFlowParams.newBuilder()
.setProductDetailsParamsList(listOf(productDetail))
.apply { subscriptionUpdateParams?.let { setSubscriptionUpdateParams(it) } }
.build())
Log.v(TAG, "Start billing flow result: $billingResult")
if (billingResult.responseCode == BillingResponseCode.ITEM_ALREADY_OWNED) {
Log.w(TAG, "Attempting to purchase already owned product")
val purchases = queryPurchases()
if (purchases.any { PRODUCT_ID in it.products }) throw BillingException(billingResult)
else throw BillingException(billingResult, retryable = true)
} else if (billingResult.responseCode == BillingResponseCode.ITEM_NOT_OWNED) {
Log.w(TAG, "Attempting to replace not owned product")
val purchases = queryPurchases()
if (purchases.all { PRODUCT_ID !in it.products }) throw BillingException(billingResult)
else throw BillingException(billingResult, retryable = true)
} else if (!billingResult.isOk) throw BillingException(billingResult)
subscriptionPurchases.firstOrNull { it != null }?.let { (billingResult, purchases) ->
if (!billingResult.isOk) throw BillingException(billingResult)
return JSONObject()
.put("responseCode", ErrorCode.NoError)
.put("purchases", processPurchases(purchases))
} ?: throw BillingException("Purchase failed")
}
private fun processPurchases(purchases: List<Purchase>?): JSONArray {
val purchaseArray = JSONArray()
purchases?.forEach { purchase ->
/* val purchaseJson = */ JSONObject().also { purchaseArray.put(it) }
.put("purchaseToken", purchase.purchaseToken)
.put("purchaseTime", purchase.purchaseTime)
.put("purchaseState", purchase.purchaseState)
.put("isAcknowledged", purchase.isAcknowledged)
.put("isAutoRenewing", purchase.isAutoRenewing)
.put("orderId", purchase.orderId)
// .put("productIds", JSONArray(purchase.products))
/* purchase.pendingPurchaseUpdate?.let { purchaseUpdate ->
JSONObject()
.put("purchaseToken", purchaseUpdate.purchaseToken)
// .put("productIds", JSONArray(purchaseUpdate.products))
}.also { purchaseJson.put("pendingPurchaseUpdate", it) } */
}
return purchaseArray
}
suspend fun acknowledge(purchaseToken: String): JSONObject {
Log.v(TAG, "Acknowledge purchase: $purchaseToken")
val result = withContext(Dispatchers.IO) {
billingClient.acknowledgePurchase(
AcknowledgePurchaseParams.newBuilder()
.setPurchaseToken(purchaseToken)
.build()
)
}
Log.v(TAG, "Acknowledge purchase result: $result")
if (result.responseCode == BillingResponseCode.ITEM_NOT_OWNED) {
Log.w(TAG, "Attempting to acknowledge not owned product")
val purchases = queryPurchases()
if (purchases.all { PRODUCT_ID !in it.products }) throw BillingException(result)
else throw BillingException(result, retryable = true)
} else if (!result.isOk && result.responseCode != BillingResponseCode.ITEM_ALREADY_OWNED) {
throw BillingException(result)
}
return JSONObject().put("responseCode", ErrorCode.NoError)
}
suspend fun getPurchases(): JSONObject {
Log.v(TAG, "Get purchases")
val purchases = queryPurchases()
return JSONObject()
.put("responseCode", ErrorCode.NoError)
.put("purchases", processPurchases(purchases))
}
private suspend fun queryPurchases(): List<Purchase> {
Log.v(TAG, "Query purchases")
val result = withContext(Dispatchers.IO) {
billingClient.queryPurchasesAsync(
QueryPurchasesParams.newBuilder().setProductType(ProductType.SUBS).build()
)
}
Log.v(TAG, "Query purchases result: ${result.billingResult}")
if (!result.billingResult.isOk) throw BillingException(result.billingResult)
return result.purchasesList
}
override fun close() {
Log.v(TAG, "Close billing client connection")
billingClient.endConnection()
}
companion object {
suspend fun withBillingProvider(context: Context, block: suspend BillingProvider.() -> JSONObject): String =
BillingProvider(context).use { bp ->
bp.handleBillingApiCall {
bp.connect()
bp.block()
}.toString()
}
}
}
internal val BillingResult.isOk: Boolean
get() = responseCode == BillingResponseCode.OK

View File

@@ -20,6 +20,7 @@ android {
namespace = "org.amnezia.vpn"
buildFeatures {
buildConfig = true
viewBinding = true
}
@@ -41,17 +42,6 @@ android {
resourceConfigurations += listOf("en", "ru", "b+zh+Hans")
}
sourceSets {
getByName("main") {
manifest.srcFile("AndroidManifest.xml")
java.setSrcDirs(listOf("src"))
res.setSrcDirs(listOf("res"))
// androyddeployqt creates the folders below
assets.setSrcDirs(listOf("assets"))
jniLibs.setSrcDirs(listOf("libs"))
}
}
signingConfigs {
register("release") {
storeFile = providers.environmentVariable("ANDROID_KEYSTORE_PATH").orNull?.let { file(it) }
@@ -77,6 +67,36 @@ android {
}
}
flavorDimensions += "billing"
productFlavors {
create("oss") {
dimension = "billing"
}
create("play") {
dimension = "billing"
}
}
sourceSets {
getByName("main") {
manifest.srcFile("AndroidManifest.xml")
java.setSrcDirs(listOf("src"))
res.setSrcDirs(listOf("res"))
// androyddeployqt creates the folders below
assets.setSrcDirs(listOf("assets"))
jniLibs.setSrcDirs(listOf("libs"))
}
getByName("oss") {
java.setSrcDirs(listOf("oss"))
}
getByName("play") {
java.setSrcDirs(listOf("play"))
}
}
splits {
abi {
isEnable = true
@@ -122,4 +142,9 @@ dependencies {
implementation(libs.google.mlkit)
implementation(libs.androidx.datastore)
implementation(libs.androidx.biometric)
playImplementation(project(":billing"))
}
fun DependencyHandler.playImplementation(dependency: Any): Dependency? =
add("playImplementation", dependency)

View File

@@ -1,6 +1,7 @@
[versions]
agp = "8.5.2"
kotlin = "1.9.24"
android-billing = "7.0.0"
androidx-core = "1.13.1"
androidx-activity = "1.9.1"
androidx-annotation = "1.8.2"
@@ -14,6 +15,7 @@ kotlinx-serialization = "1.6.3"
google-mlkit = "17.3.0"
[libraries]
android-billing = { module = "com.android.billingclient:billing-ktx", version.ref = "android-billing" }
androidx-core = { module = "androidx.core:core-ktx", version.ref = "androidx-core" }
androidx-activity = { module = "androidx.activity:activity-ktx", version.ref = "androidx-activity" }
androidx-annotation = { module = "androidx.annotation:annotation", version.ref = "androidx-annotation" }

View File

@@ -0,0 +1,13 @@
package org.amnezia.vpn
import android.app.Activity
import android.content.Context
class BillingPaymentRepository(@Suppress("UNUSED_PARAMETER") context: Context) : BillingRepository {
override suspend fun getCountryCode(): String = ""
override suspend fun getSubscriptionPlans(): String = ""
override suspend fun purchaseSubscription(activity: Activity, offerToken: String): String = ""
override suspend fun upgradeSubscription(activity: Activity, offerToken: String, oldPurchaseToken: String): String = ""
override suspend fun acknowledge(purchaseToken: String): String = ""
override suspend fun queryPurchases(): String = ""
}

View File

@@ -0,0 +1,34 @@
package org.amnezia.vpn
import android.app.Activity
import android.content.Context
import BillingProvider.Companion.withBillingProvider
class BillingPaymentRepository(private val context: Context) : BillingRepository {
override suspend fun getCountryCode(): String = withBillingProvider(context) {
getCustomerCountryCode()
}
override suspend fun getSubscriptionPlans(): String = withBillingProvider(context) {
getSubscriptionPlans()
}
override suspend fun purchaseSubscription(activity: Activity, offerToken: String): String =
withBillingProvider(context) {
purchaseSubscription(activity, offerToken)
}
override suspend fun upgradeSubscription(activity: Activity, offerToken: String, oldPurchaseToken: String): String =
withBillingProvider(context) {
purchaseSubscription(activity, offerToken, oldPurchaseToken)
}
override suspend fun acknowledge(purchaseToken: String): String = withBillingProvider(context) {
acknowledge(purchaseToken)
}
override suspend fun queryPurchases(): String = withBillingProvider(context) {
getPurchases()
}
}

View File

@@ -31,6 +31,7 @@ rootProject.buildFileName = "build.gradle.kts"
include(":qt")
include(":utils")
include(":billing")
include(":protocolApi")
include(":wireguard")
include(":awg")

View File

@@ -30,6 +30,7 @@ import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import java.io.IOException
import kotlin.LazyThreadSafetyMode.NONE
import kotlin.coroutines.CoroutineContext
import kotlin.text.RegexOption.IGNORE_CASE
import AppListProvider
import kotlinx.coroutines.CompletableDeferred
@@ -40,7 +41,6 @@ import kotlinx.coroutines.async
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.amnezia.vpn.protocol.getStatistics
import org.amnezia.vpn.protocol.getStatus
import org.amnezia.vpn.qt.QtAndroidController
@@ -71,6 +71,7 @@ class AmneziaActivity : QtActivity() {
private var isInBoundState = false
private var notificationStateReceiver: BroadcastReceiver? = null
private lateinit var vpnServiceMessenger: IpcMessenger
private lateinit var billingRepository: BillingRepository
private val actionResultHandlers = mutableMapOf<Int, ActivityResultHandler>()
private val permissionRequestHandlers = mutableMapOf<Int, PermissionRequestHandler>()
@@ -180,6 +181,7 @@ class AmneziaActivity : QtActivity() {
registerBroadcastReceivers()
intent?.let(::processIntent)
runBlocking { vpnProto = proto.await() }
billingRepository = BillingPaymentRepository(applicationContext)
}
private fun loadLibs() {
@@ -647,15 +649,9 @@ class AmneziaActivity : QtActivity() {
@Suppress("unused")
fun getAppList(): String {
Log.v(TAG, "Get app list")
var appList = ""
runBlocking {
mainScope.launch {
withContext(Dispatchers.IO) {
appList = AppListProvider.getAppList(packageManager, packageName)
}
}.join()
return blockingCall(Dispatchers.IO) {
AppListProvider.getAppList(packageManager, packageName)
}
return appList
}
@Suppress("unused")
@@ -721,6 +717,47 @@ class AmneziaActivity : QtActivity() {
}
}
@Suppress("unused")
fun isPlay(): Boolean = BuildConfig.FLAVOR == "play"
@Suppress("unused")
fun getCountryCode(): String {
Log.v(TAG, "Get country code")
return blockingCall { billingRepository.getCountryCode() }
}
@Suppress("unused")
fun getSubscriptionPlans(): String {
Log.v(TAG, "Get subscription plans")
return blockingCall { billingRepository.getSubscriptionPlans() }
}
@Suppress("unused")
fun purchaseSubscription(offerToken: String): String {
Log.v(TAG, "Purchase subscription")
return blockingCall { billingRepository.purchaseSubscription(this@AmneziaActivity, offerToken) }
}
@Suppress("unused")
fun upgradeSubscription(offerToken: String, oldPurchaseToken: String): String {
Log.v(TAG, "Upgrade subscription")
return blockingCall {
billingRepository.upgradeSubscription(this@AmneziaActivity, offerToken, oldPurchaseToken)
}
}
@Suppress("unused")
fun acknowledgePurchase(purchaseToken: String): String {
Log.v(TAG, "Acknowledge purchase")
return blockingCall { billingRepository.acknowledge(purchaseToken) }
}
@Suppress("unused")
fun queryPurchases(): String {
Log.v(TAG, "Query purchases")
return blockingCall { billingRepository.queryPurchases() }
}
// workaround for a bug in Qt that causes the mouse click event not to be handled
// also disable right-click, as it causes the application to crash
private var lastButtonState = 0
@@ -784,6 +821,13 @@ class AmneziaActivity : QtActivity() {
/**
* Utils methods
*/
private fun <T> blockingCall(
context: CoroutineContext = Dispatchers.Default,
block: suspend () -> T
) = runBlocking {
mainScope.async(context) { block() }.await()
}
companion object {
private fun actionCodeToString(actionCode: Int): String =
when (actionCode) {

View File

@@ -1,5 +1,6 @@
package org.amnezia.vpn
import android.system.Os
import androidx.camera.camera2.Camera2Config
import androidx.camera.core.CameraSelector
import androidx.camera.core.CameraXConfig
@@ -12,6 +13,9 @@ private const val TAG = "AmneziaApplication"
class AmneziaApplication : QtApplication(), CameraXConfig.Provider {
override fun onCreate() {
if (BuildConfig.DEBUG) {
Os.setenv("QT_ANDROID_DEBUGGER_MAIN_THREAD_SLEEP_MS", "0", true)
}
super.onCreate()
Prefs.init(this)
Log.init(this)

View File

@@ -0,0 +1,12 @@
package org.amnezia.vpn
import android.app.Activity
interface BillingRepository {
suspend fun getCountryCode(): String
suspend fun getSubscriptionPlans(): String
suspend fun purchaseSubscription(activity: Activity, offerToken: String): String
suspend fun upgradeSubscription(activity: Activity, offerToken: String, oldPurchaseToken: String): String
suspend fun acknowledge(purchaseToken: String): String
suspend fun queryPurchases(): String
}

View File

@@ -0,0 +1,14 @@
package org.amnezia.vpn.util
// keep synchronized with client/core/defs.h error_code_ns::ErrorCode
object ErrorCode {
const val NoError = 0
const val BillingCanceled = 1300
const val BillingError = 1301
const val BillingGooglePlayError = 1302
const val BillingUnavailable = 1303
const val SubscriptionAlreadyOwned = 1304
const val SubscriptionUnavailable = 1305
const val BillingNetworkError = 1306
}

View File

@@ -1,140 +0,0 @@
message("Client ==> MacOS NE build")
set_target_properties(${PROJECT} PROPERTIES MACOSX_BUNDLE TRUE)
set(CMAKE_OSX_ARCHITECTURES "x86_64")
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.15)
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf-with-dsym")
set(APPLE_PROJECT_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
enable_language(OBJC)
enable_language(Swift)
find_package(Qt6 REQUIRED COMPONENTS ShaderTools)
set(LIBS ${LIBS} Qt6::ShaderTools)
find_library(FW_AUTHENTICATIONSERVICES AuthenticationServices)
find_library(FW_AVFOUNDATION AVFoundation)
find_library(FW_FOUNDATION Foundation)
find_library(FW_STOREKIT StoreKit)
find_library(FW_USERNOTIFICATIONS UserNotifications)
find_library(FW_NETWORKEXTENSION NetworkExtension)
set(LIBS ${LIBS}
${FW_AUTHENTICATIONSERVICES}
${FW_AVFOUNDATION}
${FW_FOUNDATION}
${FW_STOREKIT}
${FW_USERNOTIFICATIONS}
${FW_NETWORKEXTENSION}
)
set(HEADERS ${HEADERS}
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/ios_controller.h
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/ios_controller_wrapper.h
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/iosnotificationhandler.h
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/QtAppDelegate.h
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/QtAppDelegate-C-Interface.h
)
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/ios_controller.h PROPERTIES OBJECTIVE_CPP_HEADER TRUE)
set(SOURCES ${SOURCES}
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/ios_controller.mm
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/ios_controller_wrapper.mm
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/iosnotificationhandler.mm
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/iosglue.mm
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/QRCodeReaderBase.mm
${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios/QtAppDelegate.mm
)
target_include_directories(${PROJECT} PRIVATE ${Qt6Gui_PRIVATE_INCLUDE_DIRS})
set_target_properties(${PROJECT} PROPERTIES
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Info.plist.in
MACOSX_BUNDLE_ICON_FILE "AppIcon"
MACOSX_BUNDLE_INFO_STRING "AmneziaVPN"
MACOSX_BUNDLE_BUNDLE_NAME "AmneziaVPN"
MACOSX_BUNDLE_BUNDLE_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
MACOSX_BUNDLE_LONG_VERSION_STRING "${APPLE_PROJECT_VERSION}-${CMAKE_PROJECT_VERSION_TWEAK}"
MACOSX_BUNDLE_SHORT_VERSION_STRING "${APPLE_PROJECT_VERSION}"
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${BUILD_IOS_APP_IDENTIFIER}"
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/ios/app/main.entitlements"
XCODE_ATTRIBUTE_MARKETING_VERSION "${APPLE_PROJECT_VERSION}"
XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION "${CMAKE_PROJECT_VERSION_TWEAK}"
XCODE_ATTRIBUTE_PRODUCT_NAME "AmneziaVPN"
XCODE_ATTRIBUTE_BUNDLE_INFO_STRING "AmneziaVPN"
XCODE_GENERATE_SCHEME TRUE
XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME "AppIcon"
XCODE_ATTRIBUTE_TARGETED_DEVICE_FAMILY "1,2"
XCODE_EMBED_FRAMEWORKS_CODE_SIGN_ON_COPY "NO"
XCODE_EMBED_FRAMEWORKS_REMOVE_HEADERS_ON_COPY "YES"
XCODE_LINK_BUILD_PHASE_MODE KNOWN_LOCATION
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../Frameworks"
XCODE_EMBED_APP_EXTENSIONS networkextension
# XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution: Privacy Technologies OU (X7UJ388FXK)"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development"
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "Mac AppStore AmneziaVPN"
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "org.amnezia.AmneziaVPNManual"
)
set_target_properties(${PROJECT} PROPERTIES
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES "YES"
XCODE_ATTRIBUTE_SWIFT_PRECOMPILE_BRIDGING_HEADER "NO"
XCODE_ATTRIBUTE_SWIFT_OBJC_INTERFACE_HEADER_NAME "AmneziaVPN-Swift.h"
XCODE_ATTRIBUTE_SWIFT_OBJC_INTEROP_MODE "objcxx"
)
set_target_properties(${PROJECT} PROPERTIES
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "X7UJ388FXK"
)
target_include_directories(${PROJECT} PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_compile_options(${PROJECT} PRIVATE
-DGROUP_ID=\"${BUILD_IOS_GROUP_IDENTIFIER}\"
-DVPN_NE_BUNDLEID=\"${BUILD_IOS_APP_IDENTIFIER}.network-extension\"
)
set(WG_APPLE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/3rd/amneziawg-apple/Sources)
target_sources(${PROJECT} PRIVATE
${WG_APPLE_SOURCE_DIR}/WireGuardKitC/x25519.c
${CLIENT_ROOT_DIR}/platforms/ios/LogController.swift
${CLIENT_ROOT_DIR}/platforms/ios/Log.swift
${CLIENT_ROOT_DIR}/platforms/ios/LogRecord.swift
${CLIENT_ROOT_DIR}/platforms/ios/ScreenProtection.swift
${CLIENT_ROOT_DIR}/platforms/ios/VPNCController.swift
)
target_sources(${PROJECT} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Images.xcassets
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
)
set_property(TARGET ${PROJECT} APPEND PROPERTY RESOURCE
${CMAKE_CURRENT_SOURCE_DIR}/macos/app/Images.xcassets
${CMAKE_CURRENT_SOURCE_DIR}/ios/app/PrivacyInfo.xcprivacy
)
add_subdirectory(macos/networkextension)
add_dependencies(${PROJECT} networkextension)
get_target_property(QtCore_location Qt6::Core LOCATION)
message("QtCore_location")
message(${QtCore_location})
get_filename_component(QT_BIN_DIR_DETECTED "${QtCore_location}/../../../../../bin" ABSOLUTE)
set_property(TARGET ${PROJECT} PROPERTY XCODE_EMBED_FRAMEWORKS
"${CMAKE_CURRENT_SOURCE_DIR}/3rd/OpenVPNAdapter/build/Release-macos/OpenVPNAdapter.framework"
)
set(CMAKE_XCODE_ATTRIBUTE_FRAMEWORK_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/3rd/OpenVPNAdapter/build/Release-macos)
target_link_libraries("networkextension" PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/3rd/OpenVPNAdapter/build/Release-macos/OpenVPNAdapter.framework")

View File

@@ -76,7 +76,7 @@ function(osx_bundle_assetcatalog TARGET)
)
## Patch the asset catalog into the target bundle.
if(NOT IOS AND NOT MACOS_NE)
if(NOT IOS)
set(XCASSETS_RESOURCE_DIR "Resources")
endif()
add_custom_command(TARGET ${TARGET} POST_BUILD
@@ -141,7 +141,6 @@ function(osx_codesign_target TARGET)
endif()
foreach(FILE ${CODESIGN_FILES})
message(STATUS "Signing ${TARGET}: ${FILE}")
add_custom_command(TARGET ${TARGET} POST_BUILD VERBATIM
COMMAND ${COMMENT_ECHO_COMMAND} "Signing ${TARGET}: ${FILE}"
COMMAND ${CODESIGN_BIN} ${CODESIGN_ARGS} ${FILE}

View File

@@ -102,9 +102,7 @@ QProcessEnvironment SshConfigurator::prepareEnv()
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\cygwin;");
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "\\openvpn;");
#elif defined(Q_OS_MACX)
#if !defined(MACOS_NE)
pathEnvVar.prepend(QDir::toNativeSeparators(QApplication::applicationDirPath()) + "/Contents/MacOS");
#endif
#endif
env.insert("PATH", pathEnvVar);

View File

@@ -116,7 +116,16 @@ namespace amnezia
PermissionsError = 1202,
UnspecifiedError = 1203,
FatalError = 1204,
AbortError = 1205
AbortError = 1205,
// Billing errors
BillingCanceled = 1300,
BillingError = 1301,
BillingGooglePlayError = 1302,
BillingUnavailable = 1303,
SubscriptionAlreadyOwned = 1304,
SubscriptionUnavailable = 1305,
BillingNetworkError = 1306,
};
Q_ENUM_NS(ErrorCode)
}

View File

@@ -72,6 +72,15 @@ QString errorString(ErrorCode code) {
case(ErrorCode::FatalError): errorMessage = QObject::tr("QFile error: A fatal error occurred"); break;
case(ErrorCode::AbortError): errorMessage = QObject::tr("QFile error: The operation was aborted"); break;
// Billing errors
case(ErrorCode::BillingCanceled): errorMessage = QObject::tr("Transaction was canceled by the user"); break;
case(ErrorCode::BillingError): errorMessage = QObject::tr("Billing error"); break;
case(ErrorCode::BillingGooglePlayError): errorMessage = QObject::tr("Internal Google Play error, please try again later"); break;
case(ErrorCode::BillingUnavailable): errorMessage = QObject::tr("Billing is unavailable, please try again later"); break;
case(ErrorCode::SubscriptionAlreadyOwned): errorMessage = QObject::tr("You already own this subscription"); break;
case(ErrorCode::SubscriptionUnavailable): errorMessage = QObject::tr("The requested subscription is not available for purchase"); break;
case(ErrorCode::BillingNetworkError): errorMessage = QObject::tr("A network error occurred during the operation, please check the Internet connection"); break;
case(ErrorCode::InternalError):
default:
errorMessage = QObject::tr("Internal error"); break;

View File

@@ -16,7 +16,5 @@
<array>
<string>$(AppIdentifierPrefix)group.org.amnezia.AmneziaVPN</string>
</array>
<key>com.apple.security.app-sandbox</key>
<true/>
</dict>
</plist>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 421 B

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 946 B

After

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 946 B

After

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -1,68 +1,68 @@
{
"images": [
"images" : [
{
"idiom": "mac",
"size": "16x16",
"scale": "1x",
"filename": "16.png"
"filename" : "16.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"idiom": "mac",
"size": "16x16",
"scale": "2x",
"filename": "16@2x.png"
"filename" : "16@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"idiom": "mac",
"size": "32x32",
"scale": "1x",
"filename": "32.png"
"filename" : "32.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"idiom": "mac",
"size": "32x32",
"scale": "2x",
"filename": "32@2x.png"
"filename" : "32@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"idiom": "mac",
"size": "128x128",
"scale": "1x",
"filename": "128.png"
"filename" : "128.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"idiom": "mac",
"size": "128x128",
"scale": "2x",
"filename": "128@2x.png"
"filename" : "128@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"idiom": "mac",
"size": "256x256",
"scale": "1x",
"filename": "256.png"
"filename" : "256.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"idiom": "mac",
"size": "256x256",
"scale": "2x",
"filename": "256@2x.png"
"filename" : "256@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"idiom": "mac",
"size": "512x512",
"scale": "1x",
"filename": "512.png"
"filename" : "512.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"idiom": "mac",
"size": "512x512",
"scale": "2x",
"filename": "512@2x.png"
"filename" : "512@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
}
],
"info": {
"version": 1,
"author": "xcode"
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -1,68 +1,6 @@
{
"images": [
{
"idiom": "mac",
"size": "16x16",
"scale": "1x",
"filename": "16.png"
},
{
"idiom": "mac",
"size": "16x16",
"scale": "2x",
"filename": "16@2x.png"
},
{
"idiom": "mac",
"size": "32x32",
"scale": "1x",
"filename": "32.png"
},
{
"idiom": "mac",
"size": "32x32",
"scale": "2x",
"filename": "32@2x.png"
},
{
"idiom": "mac",
"size": "128x128",
"scale": "1x",
"filename": "128.png"
},
{
"idiom": "mac",
"size": "128x128",
"scale": "2x",
"filename": "128@2x.png"
},
{
"idiom": "mac",
"size": "256x256",
"scale": "1x",
"filename": "256.png"
},
{
"idiom": "mac",
"size": "256x256",
"scale": "2x",
"filename": "256@2x.png"
},
{
"idiom": "mac",
"size": "512x512",
"scale": "1x",
"filename": "512.png"
},
{
"idiom": "mac",
"size": "512x512",
"scale": "2x",
"filename": "512@2x.png"
}
],
"info": {
"version": 1,
"author": "xcode"
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -1,184 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleAllowMixedLocalizations</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>${QT_INTERNAL_DOLLAR_VAR}{PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${MACOSX_BUNDLE_EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${MACOSX_BUNDLE_GUI_IDENTIFIER}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
<key>CFBundleVersion</key>
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
<key>NSHumanReadableCopyright</key>
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>AmneziaVPNLaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
<array/>
<key>UIRequiresFullScreen</key>
<true/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array/>
<key>UIUserInterfaceStyle</key>
<string>Light</string>
<key>com.wireguard.ios.app_group_id</key>
<string>group.org.amnezia.AmneziaVPN</string>
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
<key>NSCameraUsageDescription</key>
<string>Amnezia VPN needs access to the camera for reading QR-codes.</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false/>
<key>NSAllowsLocalNetworking</key>
<true/>
</dict>
<key>CFBundleIcons</key>
<dict/>
<key>CFBundleIcons~ipad</key>
<dict/>
<key>UTImportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>Amnezia VPN config</string>
<key>UTTypeIconFiles</key>
<array/>
<key>UTTypeIdentifier</key>
<string>org.amnezia.AmneziaVPN.amnezia-config</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>vpn</string>
</array>
<key>public.mime-type</key>
<array>
<string>text/plain</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>WireGuard config</string>
<key>UTTypeIconFiles</key>
<array/>
<key>UTTypeIdentifier</key>
<string>org.amnezia.AmneziaVPN.wireguard-config</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>conf</string>
<string>cfg</string>
</array>
<key>public.mime-type</key>
<array>
<string>text/plain</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>OpenVPN config</string>
<key>UTTypeIconFiles</key>
<array/>
<key>UTTypeIdentifier</key>
<string>org.amnezia.AmneziaVPN.openvpn-config</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>ovpn</string>
</array>
<key>public.mime-type</key>
<array>
<string>text/plain</string>
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
</array>
<key>UTTypeDescription</key>
<string>AmneziaVPN backup file</string>
<key>UTTypeIconFiles</key>
<array/>
<key>UTTypeIdentifier</key>
<string>org.amnezia.AmneziaVPN.backup-config</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>backup</string>
</array>
<key>public.mime-type</key>
<array>
<string>text/plain</string>
</array>
</dict>
</dict>
</array>
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeName</key>
<string>Amnezia VPN config</string>
<key>LSHandlerRank</key>
<string>Alternate</string>
<key>LSItemContentTypes</key>
<array>
<string>org.amnezia.AmneziaVPN.amnezia-config</string>
<string>org.amnezia.AmneziaVPN.wireguard-config</string>
<string>org.amnezia.AmneziaVPN.openvpn-config</string>
<string>org.amnezia.AmneziaVPN.backup-config</string>
</array>
</dict>
</array>
</dict>
</plist>

View File

@@ -3,52 +3,40 @@
<plist version="1.0">
<dict>
<key>com.apple.application-identifier</key>
<string>X7UJ388FXK.org.amnezia.AmneziaVPN.network-extension</string>
<string>$(DEVELOPMENT_TEAM).$(NETEXT_ID_MACOS)</string>
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>packet-tunnel-provider</string>
</array>
<key>com.apple.developer.team-identifier</key>
<string>X7UJ388FXK</string>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>group.org.amnezia.AmneziaVPN</string>
</array>
<key>com.apple.security.assets.movies.read-write</key>
<true/>
<key>com.apple.security.assets.music.read-write</key>
<true/>
<key>com.apple.security.assets.pictures.read-write</key>
<true/>
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.device.bluetooth</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.device.usb</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.personal-information.addressbook</key>
<true/>
<key>com.apple.security.personal-information.calendars</key>
<true/>
<key>com.apple.security.personal-information.location</key>
<true/>
<key>com.apple.security.print</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)org.amnezia.AmneziaVPN.network-extension</string>
<string>$(DEVELOPMENT_TEAM).*</string>
</array>
<key>com.apple.developer.team-identifier</key>
<string>$(DEVELOPMENT_TEAM)</string>
<key>com.apple.developer.system-extension.install</key>
<true/>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>$(DEVELOPMENT_TEAM).$(GROUP_ID_MACOS)</string>
</array>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.private.network.socket-delegate</key>
<true/>
</dict>
</plist>

View File

@@ -1,139 +0,0 @@
enable_language(Swift)
message("Client message >> macos build >> networkextension")
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
add_executable(networkextension)
if(MACOS_NE)
message("MACOS_NE is ON")
add_definitions(-DQ_OS_IOS)
add_definitions(-DMACOS_NE)
else()
message("MACOS_NE is OFF")
endif()
message("executable_path is: @executable_path/../../Frameworks")
set_target_properties(networkextension PROPERTIES
XCODE_PRODUCT_TYPE com.apple.product-type.app-extension
BUNDLE_EXTENSION appex
MACOSX_BUNDLE_SHORT_VERSION_STRING "${APPLE_PROJECT_VERSION}"
MACOSX_BUNDLE_INFO_STRING "AmneziaVPNNetworkExtension"
MACOSX_BUNDLE_BUNDLE_NAME "AmneziaVPNNetworkExtension"
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${BUILD_IOS_APP_IDENTIFIER}.network-extension"
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_NAME "${BUILD_IOS_APP_IDENTIFIER}.network-extension"
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS ${CMAKE_CURRENT_SOURCE_DIR}/AmneziaVPNNetworkExtension.entitlements
XCODE_ATTRIBUTE_MARKETING_VERSION "${APP_MAJOR_VERSION}"
XCODE_ATTRIBUTE_CURRENT_PROJECT_VERSION "${BUILD_ID}"
XCODE_ATTRIBUTE_PRODUCT_NAME "AmneziaVPNNetworkExtension"
XCODE_ATTRIBUTE_APPLICATION_EXTENSION_API_ONLY "YES"
XCODE_ATTRIBUTE_ENABLE_BITCODE "NO"
# XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Manual
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER "Mac AppStore AmneziaVPN.network-extension"
XCODE_ATTRIBUTE_PROVISIONING_PROFILE_SPECIFIER[variant=Debug] "amnezia.AmneziaVPN.network-extensionManual"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Distribution: Privacy Technologies OU (X7UJ388FXK)"
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY[variant=Debug] "Apple Development"
XCODE_ATTRIBUTE_INFOPLIST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in
XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../../../../Frameworks @loader_path/../../../../Frameworks"
)
set_target_properties(networkextension PROPERTIES
XCODE_ATTRIBUTE_SWIFT_VERSION "5.0"
XCODE_ATTRIBUTE_CLANG_ENABLE_MODULES "YES"
XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/WireGuardNetworkExtension-Bridging-Header.h"
XCODE_ATTRIBUTE_SWIFT_OPTIMIZATION_LEVEL "-Onone"
XCODE_ATTRIBUTE_SWIFT_PRECOMPILE_BRIDGING_HEADER "NO"
)
set_target_properties("networkextension" PROPERTIES
XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "X7UJ388FXK"
)
find_library(FW_ASSETS_LIBRARY AssetsLibrary)
find_library(FW_MOBILE_CORE MobileCoreServices)
find_library(FW_UI_KIT UIKit)
find_library(FW_LIBRESOLV libresolv.9.tbd)
# Set the root directory
set(CLIENT_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
set(CMAKE_FRAMEWORK_PATH ${CLIENT_ROOT_DIR}/3rd/OpenVPNAdapter/build/Release-macos)
target_link_libraries(networkextension PRIVATE ${FW_LIBRESOLV})
target_compile_options(networkextension PRIVATE -DGROUP_ID=\"${BUILD_IOS_GROUP_IDENTIFIER}\")
target_compile_options(networkextension PRIVATE -DNETWORK_EXTENSION=1)
set(WG_APPLE_SOURCE_DIR ${CLIENT_ROOT_DIR}/3rd/amneziawg-apple/Sources)
message("WG_APPLE_SOURCE_DIR is: ${WG_APPLE_SOURCE_DIR}")
message("CLIENT_ROOT_DIR is: ${CLIENT_ROOT_DIR}")
target_sources(networkextension PRIVATE
${WG_APPLE_SOURCE_DIR}/WireGuardKit/WireGuardAdapter.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PacketTunnelSettingsGenerator.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKit/DNSResolver.swift
${WG_APPLE_SOURCE_DIR}/WireGuardNetworkExtension/ErrorNotifier.swift
${WG_APPLE_SOURCE_DIR}/Shared/Keychain.swift
${WG_APPLE_SOURCE_DIR}/Shared/Model/TunnelConfiguration+WgQuickConfig.swift
${WG_APPLE_SOURCE_DIR}/Shared/Model/NETunnelProviderProtocol+Extension.swift
${WG_APPLE_SOURCE_DIR}/Shared/Model/String+ArrayConversion.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKit/TunnelConfiguration.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKit/IPAddressRange.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKit/Endpoint.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKit/DNSServer.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKit/InterfaceConfiguration.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PeerConfiguration.swift
${WG_APPLE_SOURCE_DIR}/Shared/FileManager+Extension.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKitC/x25519.c
${WG_APPLE_SOURCE_DIR}/WireGuardKit/Array+ConcurrentMap.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKit/IPAddress+AddrInfo.swift
${WG_APPLE_SOURCE_DIR}/WireGuardKit/PrivateKey.swift
${CLIENT_ROOT_DIR}/platforms/ios/HevSocksTunnel.swift
${CLIENT_ROOT_DIR}/platforms/ios/NELogController.swift
${CLIENT_ROOT_DIR}/platforms/ios/Log.swift
${CLIENT_ROOT_DIR}/platforms/ios/LogRecord.swift
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider.swift
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+WireGuard.swift
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+OpenVPN.swift
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+Xray.swift
${CLIENT_ROOT_DIR}/platforms/ios/WGConfig.swift
${CLIENT_ROOT_DIR}/platforms/ios/iosglue.mm
${CLIENT_ROOT_DIR}/platforms/ios/XrayConfig.swift
)
target_sources(networkextension PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
)
set_property(TARGET networkextension APPEND PROPERTY RESOURCE
${CMAKE_CURRENT_SOURCE_DIR}/PrivacyInfo.xcprivacy
)
## Build wireguard-go-version.h
execute_process(
COMMAND go list -m golang.zx2c4.com/wireguard
WORKING_DIRECTORY ${CLIENT_ROOT_DIR}/3rd/wireguard-apple/Sources/WireGuardKitGo
OUTPUT_VARIABLE WG_VERSION_FULL
)
string(REGEX REPLACE ".*v\([0-9.]*\).*" "\\1" WG_VERSION_STRING 1.1.1)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/wireguard-go-version.h.in
${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h)
target_sources(networkextension PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/wireguard-go-version.h)
target_include_directories(networkextension PRIVATE ${CLIENT_ROOT_DIR})
target_include_directories(networkextension PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/wireguard/macos/x86_64/libwg-go.a)
message(${CLIENT_ROOT_DIR})
message(${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/libhev-socks5-tunnel.a)
target_link_libraries(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/libhev-socks5-tunnel.a)
target_include_directories(networkextension PRIVATE ${CLIENT_ROOT_DIR}/3rd-prebuilt/3rd-prebuilt/xray/HevSocks5Tunnel.xcframework/macos-arm64_x86_64/Headers)

View File

@@ -3,32 +3,27 @@
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>AmneziaVPNNetworkExtension</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>org.amnezia.AmneziaVPN.network-extension</string>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>AmneziaVPNNetworkExtension</string>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>${APPLE_PROJECT_VERSION}</string>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>${CMAKE_PROJECT_VERSION_TWEAK}</string>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSMinimumSystemVersion</key>
<string>${CMAKE_OSX_DEPLOYMENT_TARGET}</string>
<key>CFBundleDisplayName</key>
<string>AmneziaVPNNetworkExtension</string>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>NSExtension</key>
<dict>
<key>NSExtensionPointIdentifier</key>
@@ -36,11 +31,5 @@
<key>NSExtensionPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).PacketTunnelProvider</string>
</dict>
<key>com.wireguard.ios.app_group_id</key>
<string>group.org.amnezia.AmneziaVPN</string>
<key>com.wireguard.macos.app_group_id</key>
<string>${BUILD_VPN_DEVELOPMENT_TEAM}.group.org.amnezia.AmneziaVPN</string>
</dict>
</plist>

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>1C8F.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
</array>
</dict>
</plist>

View File

@@ -1,10 +1,10 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "macos/gobridge/wireguard.h"
#include "wireguard-go-version.h"
#include "3rd/amneziawg-apple/Sources/WireGuardKitGo/wireguard.h"
#include "3rd/amneziawg-apple/Sources/WireGuardKitC/WireGuardKitC.h"
#include "3rd/awg-apple/Sources/WireGuardKitC/WireGuardKitC.h"
#include <stdbool.h>
#include <stdint.h>
@@ -23,8 +23,3 @@ bool key_from_hex(uint8_t key[WG_KEY_LEN], const char* hex);
bool key_eq(const uint8_t key1[WG_KEY_LEN], const uint8_t key2[WG_KEY_LEN]);
void write_msg_to_log(const char* tag, const char* msg);
// init function definition in C
void hev_socks5_tunnel_quit(void);
// Updated function definition in C
int hev_socks5_tunnel_main(const char* configFile, int fd);

View File

@@ -1,3 +0,0 @@
#ifndef WIREGUARD_GO_VERSION
#define WIREGUARD_GO_VERSION "@WG_VERSION_STRING@"
#endif // WIREGUARD_GO_VERSION

View File

@@ -1,36 +0,0 @@
#!/bin/bash
XCODEBUILD="/usr/bin/xcodebuild"
WORKINGDIR=`pwd`
PATCH="/usr/bin/patch"
echo "Building OpenVPNAdapter for macOS Network Extension (MacNE)..."
# Copy the Project-MacNE.xcconfig settings to amnezia.xcconfig
cat $WORKINGDIR/3rd/OpenVPNAdapter/Configuration/Project-MacNE.xcconfig > $WORKINGDIR/3rd/OpenVPNAdapter/Configuration/amnezia.xcconfig
# Append macOS-specific build directory configurations to amnezia.xcconfig
cat << EOF >> $WORKINGDIR/3rd/OpenVPNAdapter/Configuration/amnezia.xcconfig
PROJECT_TEMP_DIR = $WORKINGDIR/3rd/OpenVPNAdapter/build/OpenVPNAdapter.build
CONFIGURATION_BUILD_DIR = $WORKINGDIR/3rd/OpenVPNAdapter/build/Release-macos
BUILT_PRODUCTS_DIR = $WORKINGDIR/3rd/OpenVPNAdapter/build/Release-macos
EOF
# Fetch the current macOS SDK version dynamically
MACOSX_SDK=$(xcrun --sdk macosx --show-sdk-path | sed -E 's/.*MacOSX([0-9]+\.[0-9]+)\.sdk/\1/')
echo "Using macOS SDK version: $MACOSX_SDK"
cd 3rd/OpenVPNAdapter
# Build for macOS using the correct SDK and destination
if $XCODEBUILD -scheme OpenVPNAdapter -configuration Release -xcconfig Configuration/amnezia.xcconfig -sdk macosx$MACOSX_SDK -destination 'generic/platform=macOS' -project OpenVPNAdapter.xcodeproj ; then
echo "OpenVPNAdapter built successfully for macOS Network Extension (MacNE)"
else
echo "OpenVPNAdapter macOS Network Extension (MacNE) build failed..."
fi
# Remove CodeSignature if needed for macOS
rm -rf ./build/Release-macos/OpenVPNAdapter.framework/Versions/A/_CodeSignature
cd ../../

View File

@@ -287,6 +287,51 @@ bool AndroidController::requestAuthentication()
return result;
}
bool AndroidController::isPlay()
{
return callActivityMethod<jboolean>("isPlay", "()Z");
}
QJsonObject AndroidController::getSubscriptionPlans()
{
QJniObject subscriptionPlans = callActivityMethod<jstring>("getSubscriptionPlans", "()Ljava/lang/String;");
QJsonObject json = QJsonDocument::fromJson(subscriptionPlans.toString().toUtf8()).object();
return json;
}
QJsonObject AndroidController::purchaseSubscription(const QString &offerToken)
{
QJniObject result = callActivityMethod<jstring, jstring>("purchaseSubscription", "(Ljava/lang/String;)Ljava/lang/String;",
QJniObject::fromString(offerToken).object<jstring>());
QJsonObject json = QJsonDocument::fromJson(result.toString().toUtf8()).object();
return json;
}
QJsonObject AndroidController::upgradeSubscription(const QString &offerToken, const QString &oldPurchaseToken)
{
QJniObject result = callActivityMethod<jstring, jstring, jstring>("upgradeSubscription",
"(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
QJniObject::fromString(offerToken).object<jstring>(),
QJniObject::fromString(oldPurchaseToken).object<jstring>());
QJsonObject json = QJsonDocument::fromJson(result.toString().toUtf8()).object();
return json;
}
QJsonObject AndroidController::acknowledgePurchase(const QString &purchaseToken)
{
QJniObject result = callActivityMethod<jstring, jstring>("acknowledgePurchase", "(Ljava/lang/String;)Ljava/lang/String;",
QJniObject::fromString(purchaseToken).object<jstring>());
QJsonObject json = QJsonDocument::fromJson(result.toString().toUtf8()).object();
return json;
}
QJsonObject AndroidController::queryPurchases()
{
QJniObject result = callActivityMethod<jstring>("queryPurchases", "()Ljava/lang/String;");
QJsonObject json = QJsonDocument::fromJson(result.toString().toUtf8()).object();
return json;
}
// Moving log processing to the Android side
jclass AndroidController::log;
jmethodID AndroidController::logDebug;

View File

@@ -48,6 +48,12 @@ public:
bool isNotificationPermissionGranted();
void requestNotificationPermission();
bool requestAuthentication();
bool isPlay();
QJsonObject getSubscriptionPlans();
QJsonObject purchaseSubscription(const QString &offerToken);
QJsonObject upgradeSubscription(const QString &offerToken, const QString &oldPurchaseToken);
QJsonObject acknowledgePurchase(const QString &purchaseToken);
QJsonObject queryPurchases();
static bool initLogging();
static void messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &message);

View File

@@ -47,7 +47,7 @@ extension PacketTunnelProvider {
let configuration = OpenVPNConfiguration()
configuration.fileContent = ovpnConfiguration
if str.contains("cloak") {
configuration.setPTCloak()
configuration.setPTCloak()
}
let evaluation: OpenVPNConfigurationEvaluation?

View File

@@ -1,4 +1,3 @@
#if !MACOS_NE
#include "QRCodeReaderBase.h"
#import <UIKit/UIKit.h>
@@ -109,19 +108,3 @@ void QRCodeReader::startReading() {
void QRCodeReader::stopReading() {
[m_qrCodeReader stopReading];
}
#else
#include "QRCodeReaderBase.h"
QRCodeReader::QRCodeReader()
{
}
QRect QRCodeReader::cameraSize() {
return QRect();
}
void QRCodeReader::startReading() {}
void QRCodeReader::stopReading() {}
void QRCodeReader::setCameraSize(QRect) {}
#endif

View File

@@ -1,6 +1,5 @@
#if !MACOS_NE
#import <UIKit/UIKit.h>
#endif
@interface QIOSApplicationDelegate
@end

View File

@@ -5,7 +5,7 @@
@implementation QIOSApplicationDelegate (AmneziaVPNDelegate)
#if !MACOS_NE
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[application setMinimumBackgroundFetchInterval: UIApplicationBackgroundFetchIntervalMinimum];
@@ -57,5 +57,5 @@
}
return NO;
}
#endif
@end

View File

@@ -1,13 +1,3 @@
#if MACOS_NE
public func toggleScreenshots(_ isEnabled: Bool) {
}
class ScreenProtection {
}
#else
import UIKit
public func toggleScreenshots(_ isEnabled: Bool) {
@@ -95,4 +85,3 @@ struct ProtectionPair {
textField.removeFromSuperview()
}
}
#endif

View File

@@ -27,7 +27,6 @@ const char* MessageKey::isOnDemand = "is-on-demand";
const char* MessageKey::SplitTunnelType = "SplitTunnelType";
const char* MessageKey::SplitTunnelSites = "SplitTunnelSites";
#if !MACOS_NE
static UIViewController* getViewController() {
NSArray *windows = [[UIApplication sharedApplication]windows];
for (UIWindow *window in windows) {
@@ -37,7 +36,6 @@ static UIViewController* getViewController() {
}
return nil;
}
#endif
Vpn::ConnectionState iosStatusToState(NEVPNStatus status) {
switch (status) {
@@ -791,14 +789,14 @@ bool IosController::shareText(const QStringList& filesToSend) {
NSURL *logFileUrl = [[NSURL alloc] initFileURLWithPath:filesToSend[i].toNSString()];
[sharingItems addObject:logFileUrl];
}
#if !MACOS_NE
UIViewController *qtController = getViewController();
if (!qtController) return;
UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:sharingItems applicationActivities:nil];
#endif
__block bool isAccepted = false;
#if !MACOS_NE
[activityController setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) {
isAccepted = completed;
emit finished();
@@ -810,7 +808,7 @@ bool IosController::shareText(const QStringList& filesToSend) {
popController.sourceView = qtController.view;
popController.sourceRect = CGRectMake(100, 100, 100, 100);
}
#endif
QEventLoop wait;
QObject::connect(this, &IosController::finished, &wait, &QEventLoop::quit);
wait.exec();
@@ -819,7 +817,6 @@ bool IosController::shareText(const QStringList& filesToSend) {
}
QString IosController::openFile() {
#if !MACOS_NE
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[@"public.item"] inMode:UIDocumentPickerModeOpen];
DocumentPickerDelegate *documentPickerDelegate = [[DocumentPickerDelegate alloc] init];
@@ -829,9 +826,9 @@ QString IosController::openFile() {
if (!qtController) return;
[qtController presentViewController:documentPicker animated:YES completion:nil];
#endif
__block QString filePath;
#if !MACOS_NE
documentPickerDelegate.documentPickerClosedCallback = ^(NSString *path) {
if (path) {
filePath = QString::fromUtf8(path.UTF8String);
@@ -840,7 +837,7 @@ QString IosController::openFile() {
}
emit finished();
};
#endif
QEventLoop wait;
QObject::connect(this, &IosController::finished, &wait, &QEventLoop::quit);
wait.exec();
@@ -866,4 +863,3 @@ void IosController::requestInetAccess() {
}];
[task resume];
}

View File

@@ -1,11 +1,7 @@
#import <NetworkExtension/NetworkExtension.h>
#import <NetworkExtension/NETunnelProviderSession.h>
#import <Foundation/Foundation.h>
#if !MACOS_NE
#include <UIKit/UIKit.h>
#endif
#include <Security/Security.h>
class IosController;
@@ -21,10 +17,9 @@ class IosController;
@end
typedef void (^DocumentPickerClosedCallback)(NSString *path);
#if !MACOS_NE
@interface DocumentPickerDelegate : NSObject <UIDocumentPickerDelegate>
@property (nonatomic, copy) DocumentPickerClosedCallback documentPickerClosedCallback;
@end
#endif

View File

@@ -26,8 +26,7 @@
@end
#if !MACOS_NE
@implementation DocumentPickerDelegate
@implementation DocumentPickerDelegate
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray<NSURL *> *)urls {
for (NSURL *url in urls) {
@@ -43,5 +42,4 @@
}
}
@end
#endif
@end

View File

@@ -6,8 +6,6 @@
#import <UserNotifications/UserNotifications.h>
#import <Foundation/Foundation.h>
#if !MACOS_NE
#import <UIKit/UIKit.h>
@interface IOSNotificationDelegate
@@ -89,86 +87,3 @@ void IOSNotificationHandler::notify(NotificationHandler::Message type, const QSt
}
}];
}
#else
// Removed the UIResponder and UIApplicationDelegate references as these are not available in macOS
@interface IOSNotificationDelegate
: NSObject <UNUserNotificationCenterDelegate> {
IOSNotificationHandler* m_iosNotificationHandler;
}
@end
@implementation IOSNotificationDelegate
- (id)initWithObject:(IOSNotificationHandler*)notification {
self = [super init]; // Removed `super init` as it refers to UIResponder, which is iOS specific
if (self) {
m_iosNotificationHandler = notification;
}
return self;
}
- (void)userNotificationCenter:(UNUserNotificationCenter*)center
willPresentNotification:(UNNotification*)notification
withCompletionHandler:
(void (^)(UNNotificationPresentationOptions options))completionHandler {
Q_UNUSED(center)
completionHandler(UNNotificationPresentationOptionList | UNNotificationPresentationOptionBanner);
}
- (void)userNotificationCenter:(UNUserNotificationCenter*)center
didReceiveNotificationResponse:(UNNotificationResponse*)response
withCompletionHandler:(void (^)())completionHandler {
Q_UNUSED(center)
Q_UNUSED(response)
completionHandler();
}
@end
IOSNotificationHandler::IOSNotificationHandler(QObject* parent) : NotificationHandler(parent) {
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert |
UNAuthorizationOptionBadge)
completionHandler:^(BOOL granted, NSError* _Nullable error) {
Q_UNUSED(granted);
if (!error) {
m_delegate = [[IOSNotificationDelegate alloc] initWithObject:this];
}
}];
}
IOSNotificationHandler::~IOSNotificationHandler() { }
void IOSNotificationHandler::notify(NotificationHandler::Message type, const QString& title,
const QString& message, int timerMsec) {
Q_UNUSED(type);
if (!m_delegate) {
return;
}
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
content.title = title.toNSString();
content.body = message.toNSString();
content.sound = [UNNotificationSound defaultSound];
int timerSec = timerMsec / 1000;
UNTimeIntervalNotificationTrigger* trigger =
[UNTimeIntervalNotificationTrigger triggerWithTimeInterval:timerSec repeats:NO];
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:@"amneziavpn"
content:content
trigger:trigger];
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = (id<UNUserNotificationCenterDelegate>)m_delegate;
[center addNotificationRequest:request
withCompletionHandler:^(NSError* _Nullable error) {
if (error) {
NSLog(@"Local Notification failed");
}
}];
}
#endif

View File

@@ -4,7 +4,7 @@
#include "core/errorstrings.h"
#include "vpnprotocol.h"
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) and !defined MACOS_NE || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
#include "openvpnovercloakprotocol.h"
#include "openvpnprotocol.h"
#include "shadowsocksvpnprotocol.h"
@@ -109,7 +109,7 @@ VpnProtocol *VpnProtocol::factory(DockerContainer container, const QJsonObject &
#if defined(Q_OS_WINDOWS)
case DockerContainer::Ipsec: return new Ikev2Protocol(configuration);
#endif
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) and !defined MACOS_NE || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
#if defined(Q_OS_WINDOWS) || defined(Q_OS_MACX) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
case DockerContainer::OpenVpn: return new OpenVpnProtocol(configuration);
case DockerContainer::Cloak: return new OpenVpnOverCloakProtocol(configuration);
case DockerContainer::ShadowSocks: return new ShadowSocksVpnProtocol(configuration);

View File

@@ -89,60 +89,60 @@
<name>ConnectionController</name>
<message>
<location filename="../ui/controllers/connectionController.h" line="80"/>
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
<source>Connect</source>
<translation>اتصل</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
<source>VPN Protocols is not installed.
Please install VPN container at first</source>
<translation>لم يتم تثبيت بروتوكولات VPN, من فضلك قم بتنزيل حاوية VPN اولاً</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
<source>Connecting...</source>
<translation>اتصال...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
<source>Connected</source>
<translation>تم الاتصال</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
<source>Reconnecting...</source>
<translation>إعادة الاتصال...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
<source>Disconnecting...</source>
<translation>إنهاء الاتصال...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
<source>Preparing...</source>
<translation>جاري التحضير...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
<source>Settings updated successfully, reconnnection...</source>
<translation>تم تحديث الاعدادات بنجاح, جاري إعادة الاتصال...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
<source>Settings updated successfully</source>
<translation>تم تحديث الاعدادات بنجاح</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="212"/>
<location filename="../ui/controllers/connectionController.cpp" line="209"/>
<source>The selected protocol is not supported on the current platform</source>
<translation>البروتوكول المحدد غير مدعوم علي المنصة الحالية</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
<source>unable to create configuration</source>
<translation>غير قادر علي إنشاء تكوين</translation>
</message>
@@ -253,20 +253,23 @@ Can&apos;t be disabled for current server</source>
<context>
<name>ImportController</name>
<message>
<location filename="../ui/controllers/importController.cpp" line="87"/>
<source>Unable to open file</source>
<translation type="vanished">غير قادر علي فتح الملف</translation>
<translation>غير قادر علي فتح الملف</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="187"/>
<location filename="../ui/controllers/importController.cpp" line="192"/>
<source>Invalid configuration file</source>
<translation type="vanished">ملف تكوين غير صحيح</translation>
<translation>ملف تكوين غير صحيح</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="623"/>
<location filename="../ui/controllers/importController.cpp" line="617"/>
<source>Scanned %1 of %2.</source>
<translation>تم فحص%1 من %2.</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="658"/>
<location filename="../ui/controllers/importController.cpp" line="652"/>
<source>In the imported configuration, potentially dangerous lines were found:</source>
<translation>في التكوين المستورد، تم العثور على سطور يحتمل أن تكون خطرة:</translation>
</message>
@@ -274,24 +277,24 @@ Can&apos;t be disabled for current server</source>
<context>
<name>InstallController</name>
<message>
<location filename="../ui/controllers/installController.cpp" line="157"/>
<location filename="../ui/controllers/installController.cpp" line="181"/>
<source>%1 installed successfully. </source>
<translation>%1 تم التثبيت بنجاح. </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="159"/>
<location filename="../ui/controllers/installController.cpp" line="183"/>
<source>%1 is already installed on the server. </source>
<translation>%1 بالفعل مٌثبت علي الخادم. </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="179"/>
<location filename="../ui/controllers/installController.cpp" line="203"/>
<source>
Added containers that were already installed on the server</source>
<translation>
تمت إضافة الحاويات التي كانت مٌثبتة بالفعل علي الخادم</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="259"/>
<location filename="../ui/controllers/installController.cpp" line="283"/>
<source>
Already installed containers were found on the server. All installed containers have been added to the application</source>
<translation>
@@ -299,62 +302,62 @@ Already installed containers were found on the server. All installed containers
تمت إضافة جميع الحاويات المٌثبتة إلي التطبيق</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="517"/>
<location filename="../ui/controllers/installController.cpp" line="541"/>
<source>Settings updated successfully</source>
<translation>تم تحديث الاعدادات بنجاح</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="534"/>
<location filename="../ui/controllers/installController.cpp" line="558"/>
<source>Server &apos;%1&apos; was rebooted</source>
<translation>تمت إعادة تشغيل الخادم%1</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="546"/>
<location filename="../ui/controllers/installController.cpp" line="570"/>
<source>Server &apos;%1&apos; was removed</source>
<translation>تمت إزالة الخادم &apos;%1&apos;</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="557"/>
<location filename="../ui/controllers/installController.cpp" line="581"/>
<source>All containers from server &apos;%1&apos; have been removed</source>
<translation>قد تم حذفها &apos;%1&apos; جميع الحاويات من الخادم</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="575"/>
<location filename="../ui/controllers/installController.cpp" line="599"/>
<source>%1 has been removed from the server &apos;%2&apos;</source>
<translation>%1 تم حدف &apos;%2&apos; اسم الخادم</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="584"/>
<location filename="../ui/controllers/installController.cpp" line="608"/>
<source>Api config removed</source>
<translation>تم حذف تكوين Api</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="606"/>
<location filename="../ui/controllers/installController.cpp" line="630"/>
<source>%1 cached profile cleared</source>
<translation>تم مسح ملف تعريف %1 المخزن مؤقتًا</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="745"/>
<location filename="../ui/controllers/installController.cpp" line="769"/>
<source>Please login as the user</source>
<translation>من فضلك قم بتسجيل الدخول كمستخدم</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="773"/>
<location filename="../ui/controllers/installController.cpp" line="797"/>
<source>Server added successfully</source>
<translation>تمت إضافة الخادم بنجاح</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="821"/>
<location filename="../ui/controllers/installController.cpp" line="845"/>
<source>%1 installed successfully.</source>
<translation>تم تحميل %1 بنجاح</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="855"/>
<location filename="../ui/controllers/installController.cpp" line="877"/>
<source>API config reloaded</source>
<translation>تمت إعادة تحميل تكوين API</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="859"/>
<location filename="../ui/controllers/installController.cpp" line="881"/>
<source>Successfully changed the country of connection to %1</source>
<translation>تم تغيير بلد الاتصال بنجاح إلى %1</translation>
</message>
@@ -398,28 +401,28 @@ Already installed containers were found on the server. All installed containers
<context>
<name>NotificationHandler</name>
<message>
<location filename="../ui/notificationhandler.cpp" line="64"/>
<location filename="../ui/notificationhandler.cpp" line="71"/>
<location filename="../ui/notificationhandler.cpp" line="63"/>
<location filename="../ui/notificationhandler.cpp" line="70"/>
<source>AmneziaVPN</source>
<translation>AmneziaVPN</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="65"/>
<location filename="../ui/notificationhandler.cpp" line="64"/>
<source>VPN Connected</source>
<translation>تم الاتصال</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="72"/>
<location filename="../ui/notificationhandler.cpp" line="71"/>
<source>VPN Disconnected</source>
<translation>تم إنهاء الاتصال</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="95"/>
<location filename="../ui/notificationhandler.cpp" line="94"/>
<source>AmneziaVPN notification</source>
<translation>إشعار من AmneziaVPN</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="96"/>
<location filename="../ui/notificationhandler.cpp" line="95"/>
<source>Unsecured network detected: </source>
<translation>تم العثور علي شبكة غير مؤمنة: </translation>
</message>
@@ -2315,107 +2318,97 @@ Already installed containers were found on the server. All installed containers
<context>
<name>PageSetupWizardConfigSource</name>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
<source>Connection</source>
<translation>الاتصال</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
<source>Settings</source>
<translation type="unfinished">إعدادات</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
<source>Enable logs</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
<source>Support tag</source>
<translation type="unfinished">علامة الدعم</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Copied</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
<source>Insert the key, add a configuration file or scan the QR-code</source>
<translation>أدخل المفتاح، أضف ملف تكوين أو امسح رمز الاستجابة السريعة</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
<source>Insert key</source>
<translation>أدخل مفتاح</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Insert</source>
<translation>أدخل</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
<source>Continue</source>
<translation>واصل</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/>
<source>Other connection options</source>
<translation>اختيارات اتصال اخري</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/>
<source>VPN by Amnezia</source>
<translation>VPN بواسطة Amnezia</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/>
<source>Connect to classic paid and free VPN services from Amnezia</source>
<translation>اتصل بخدمات VPN الكلاسيكية المدفوعة والمجانية من Amnezia</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/>
<source>Self-hosted VPN</source>
<translation>VPN ذاتية الاستضافة</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/>
<source>Configure Amnezia VPN on your own server</source>
<translation>قم بتكوين Amnezia VPN على الخادم الخاص بك</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/>
<source>Restore from backup</source>
<translation>استرجاع من ملف يحتوي علي نسخة احتياطية</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/>
<source>Open backup file</source>
<translation>افتح ملف نسخ احتياطي</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<source>Backup files (*.backup)</source>
<translation>ملفات نٌسخ احتياطية (*.backup)</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/>
<source>File with connection settings</source>
<translation>ملف إعدادات اتصال</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/>
<source>Open config file</source>
<translation>افتح ملف تكوين</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
<source>QR code</source>
<translation>رمز QR</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/>
<source>I have nothing</source>
<translation>ليس لدي اي شئ</translation>
</message>
@@ -2433,12 +2426,12 @@ Already installed containers were found on the server. All installed containers
<translation>عنوان خادم IP [:منفذ]</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
<source>Continue</source>
<translation>واصل</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>ستظل جميع البيانات التي تدخلها سرية للغاية ولن تتم مشاركتها أو الكشف عنها ل Amnezia أو أي طرف ثالث</translation>
</message>
@@ -2448,42 +2441,42 @@ Already installed containers were found on the server. All installed containers
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
<source>SSH Username</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
<source>Password or SSH private key</source>
<translation>كلمة مرور او مفتاح SSH خاص</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
<source>How to run your VPN server</source>
<translation>كيف تقوم بتشغيل خادم ال VPN الخاص بك</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
<translation>اين تحصل علي بيانات الاتصال, تعليمات خطوة ب خطوة لشراء VPS</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
<source>Ip address cannot be empty</source>
<translation>لا يمكن لعنوان IP ان يكون فارغ</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
<source>Enter the address in the format 255.255.255.255:88</source>
<translation>ادخل العنوان في شكل 255.255.255.255:88</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
<source>Login cannot be empty</source>
<translation>تسجيل دخول لا يمكن ان يكون فارغ</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
<source>Password/private key cannot be empty</source>
<translation>كلمة مرور/مفتاح خاص لأ يمكن ان يكونو فارغين</translation>
</message>
@@ -2778,67 +2771,62 @@ Already installed containers were found on the server. All installed containers
<translation>ابحث</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/>
<source>Creation date: %1</source>
<translation>تاريخ الإنشاء: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/>
<source>Latest handshake: %1</source>
<translation>اخر تصافح: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/>
<source>Data received: %1</source>
<translation>البيانات المستلمة: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/>
<source>Data sent: %1</source>
<translation>البيانات المٌرسلة: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
<source>Allowed IPs: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
<source>Rename</source>
<translation>إعادة التسمية</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
<source>Client name</source>
<translation>اسم العميل</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
<source>Save</source>
<translation>احفظ</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
<source>Revoke</source>
<translation>سحب وإبطال</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
<source>Revoke the config for a user - %1?</source>
<translation>سحب وإبطال للمستخدم - %1?</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<source>The user will no longer be able to connect to your server.</source>
<translation>المستخدم لن يكون قادر علي الاتصال بعد الان.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
<source>Continue</source>
<translation>واصل</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
<source>Cancel</source>
<translation>إلغاء</translation>
</message>
@@ -2951,17 +2939,17 @@ Already installed containers were found on the server. All installed containers
<context>
<name>PageStart</name>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/>
<source>Logging was disabled after 14 days, log files were deleted</source>
<translation>تم تعطيل التسجيل بعد 14 يومًا، وتم حذف ملفات السجل</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<source>Settings restored from backup file</source>
<translation>تم تحميل الإعدادات من ملف نسخة احتياطية</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/>
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
<translation type="unfinished"></translation>
</message>
@@ -3300,22 +3288,22 @@ Already installed containers were found on the server. All installed containers
<translation>انتهت مدة الاتصال بالخادم</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="56"/>
<location filename="../core/errorstrings.cpp" line="55"/>
<source>VPN connection error</source>
<translation></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="59"/>
<location filename="../core/errorstrings.cpp" line="58"/>
<source>Error when retrieving configuration from API</source>
<translation>خطأ عند استرداد التكوين من API</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="60"/>
<location filename="../core/errorstrings.cpp" line="59"/>
<source>This config has already been added to the application</source>
<translation>هذا التكوين بالفعل تمت إضافتة للبرنامج</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="80"/>
<location filename="../core/errorstrings.cpp" line="78"/>
<source>ErrorCode: %1. </source>
<translation></translation>
</message>
@@ -3390,67 +3378,57 @@ Already installed containers were found on the server. All installed containers
<translation>التكوين لا يحتوي علي اي حاويات و اعتماد للأتصال بالخادم</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="53"/>
<source>Unable to open config file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="61"/>
<location filename="../core/errorstrings.cpp" line="60"/>
<source>In the response from the server, an empty config was received</source>
<translation>في الاستجابة من الخادم، تم تلقي تكوين فارغ</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="62"/>
<location filename="../core/errorstrings.cpp" line="61"/>
<source>SSL error occurred</source>
<translation>حدث خطأ SSL</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="63"/>
<location filename="../core/errorstrings.cpp" line="62"/>
<source>Server response timeout on api request</source>
<translation>انتهت مهلة استجابة الخادم عند طلب واجهة برمجة التطبيقات</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="64"/>
<location filename="../core/errorstrings.cpp" line="63"/>
<source>Missing AGW public key</source>
<translation>مفتاح AGW عام مفقود</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="65"/>
<source>Failed to decrypt response payload</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="68"/>
<location filename="../core/errorstrings.cpp" line="66"/>
<source>QFile error: The file could not be opened</source>
<translation>خطأ QFile: لا يمكن فتح الملف</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="69"/>
<location filename="../core/errorstrings.cpp" line="67"/>
<source>QFile error: An error occurred when reading from the file</source>
<translation>خطأ QFile: ظهر خطأ اثناء القراءه من الملف</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="70"/>
<location filename="../core/errorstrings.cpp" line="68"/>
<source>QFile error: The file could not be accessed</source>
<translation>خطأ QFile: لا يمكن الوصول للملف</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="71"/>
<location filename="../core/errorstrings.cpp" line="69"/>
<source>QFile error: An unspecified error occurred</source>
<translation>خطأ QFile: ظهر خطأ غير محدد</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="72"/>
<location filename="../core/errorstrings.cpp" line="70"/>
<source>QFile error: A fatal error occurred</source>
<translation>خطأ QFile: حدث خطأ فادح</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="73"/>
<location filename="../core/errorstrings.cpp" line="71"/>
<source>QFile error: The operation was aborted</source>
<translation>خطأ QFile: تم إحباط العملية</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="77"/>
<location filename="../core/errorstrings.cpp" line="75"/>
<source>Internal error</source>
<translation>خطأ داخلي</translation>
</message>
@@ -4048,7 +4026,7 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<context>
<name>VpnConnection</name>
<message>
<location filename="../vpnconnection.cpp" line="409"/>
<location filename="../vpnconnection.cpp" line="408"/>
<source>Mbps</source>
<translation></translation>
</message>
@@ -4122,12 +4100,12 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<context>
<name>main2</name>
<message>
<location filename="../ui/qml/main2.qml" line="163"/>
<location filename="../ui/qml/main2.qml" line="162"/>
<source>Private key passphrase</source>
<translation>عبارة المرور الخاصة بالمفتاح</translation>
</message>
<message>
<location filename="../ui/qml/main2.qml" line="186"/>
<location filename="../ui/qml/main2.qml" line="185"/>
<source>Save</source>
<translation>احفظ</translation>
</message>

View File

@@ -88,63 +88,63 @@
<context>
<name>ConnectionController</name>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
<source>VPN Protocols is not installed.
Please install VPN container at first</source>
<translation>پروتکل ویپیان نصب نشده است
لطفا کانتینر ویپیان را نصب کنید</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
<source>Connecting...</source>
<translation>در حال ارتباط...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
<source>Connected</source>
<translation>متصل</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
<source>Preparing...</source>
<translation>در حال آمادهسازی...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
<source>Settings updated successfully, reconnnection...</source>
<translation>تنظیمات به روز رسانی شد
در حال اتصال دوباره...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
<source>Settings updated successfully</source>
<translation>تنظیمات با موفقیت بهروزرسانی شدند</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="212"/>
<location filename="../ui/controllers/connectionController.cpp" line="209"/>
<source>The selected protocol is not supported on the current platform</source>
<translation>پروتکل انتخابشده در پلتفرم فعلی پشتیبانی نمیشود.</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
<source>unable to create configuration</source>
<translation>نمیتوان پیکربندی را ایجاد کرد.</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
<source>Reconnecting...</source>
<translation>اتصال دوباره...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.h" line="80"/>
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
<source>Connect</source>
<translation>اتصال</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
<source>Disconnecting...</source>
<translation>قطع ارتباط...</translation>
</message>
@@ -258,20 +258,23 @@ Can&apos;t be disabled for current server</source>
<context>
<name>ImportController</name>
<message>
<location filename="../ui/controllers/importController.cpp" line="87"/>
<source>Unable to open file</source>
<translation type="vanished">نمیتوان فایل را باز کرد.</translation>
<translation>نمیتوان فایل را باز کرد.</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="187"/>
<location filename="../ui/controllers/importController.cpp" line="192"/>
<source>Invalid configuration file</source>
<translation type="vanished">فایل پیکربندی نامعتبر است.</translation>
<translation>فایل پیکربندی نامعتبر است.</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="623"/>
<location filename="../ui/controllers/importController.cpp" line="617"/>
<source>Scanned %1 of %2.</source>
<translation>ارزیابی %1 از %2.</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="658"/>
<location filename="../ui/controllers/importController.cpp" line="652"/>
<source>In the imported configuration, potentially dangerous lines were found:</source>
<translation>در پیکربندی وارد شده، خطوطی که ممکن است خطرناک باشند، یافت شدند:</translation>
</message>
@@ -279,86 +282,86 @@ Can&apos;t be disabled for current server</source>
<context>
<name>InstallController</name>
<message>
<location filename="../ui/controllers/installController.cpp" line="157"/>
<location filename="../ui/controllers/installController.cpp" line="181"/>
<source>%1 installed successfully. </source>
<translation>%1 با موفقیت نصب شد. </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="159"/>
<location filename="../ui/controllers/installController.cpp" line="183"/>
<source>%1 is already installed on the server. </source>
<translation>%1 در حال حاضر بر روی سرور نصب شده است. </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="179"/>
<location filename="../ui/controllers/installController.cpp" line="203"/>
<source>
Added containers that were already installed on the server</source>
<translation>
کانتینرهایی که بر روی سرور موجود بودند اضافه شدند</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="259"/>
<location filename="../ui/controllers/installController.cpp" line="283"/>
<source>
Already installed containers were found on the server. All installed containers have been added to the application</source>
<translation>
کانتینرهای نصب شده بر روی سرور شناسایی شدند. تمام کانتینترهای نصب شده به نرم افزار اضافه شدند</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="517"/>
<location filename="../ui/controllers/installController.cpp" line="541"/>
<source>Settings updated successfully</source>
<translation>تنظیمات با موفقیت بهروزرسانی شدند</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="534"/>
<location filename="../ui/controllers/installController.cpp" line="558"/>
<source>Server &apos;%1&apos; was rebooted</source>
<translation>سرور %1 راه اندازی مجدد شد</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="546"/>
<location filename="../ui/controllers/installController.cpp" line="570"/>
<source>Server &apos;%1&apos; was removed</source>
<translation>سرور %1 حذف شد</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="557"/>
<location filename="../ui/controllers/installController.cpp" line="581"/>
<source>All containers from server &apos;%1&apos; have been removed</source>
<translation>تمام کانتینترها از سرور %1 حذف شدند</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="575"/>
<location filename="../ui/controllers/installController.cpp" line="599"/>
<source>%1 has been removed from the server &apos;%2&apos;</source>
<translation>%1 از سرور %2 حذف شد</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="584"/>
<location filename="../ui/controllers/installController.cpp" line="608"/>
<source>Api config removed</source>
<translation>پیکربندی API حذف شد.</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="606"/>
<location filename="../ui/controllers/installController.cpp" line="630"/>
<source>%1 cached profile cleared</source>
<translation>%1 پروفایل ذخیره شده پاک شد.</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="745"/>
<location filename="../ui/controllers/installController.cpp" line="769"/>
<source>Please login as the user</source>
<translation>لطفا به عنوان کاربر وارد شوید</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="773"/>
<location filename="../ui/controllers/installController.cpp" line="797"/>
<source>Server added successfully</source>
<translation>سرور با موفقیت اضافه شد</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="821"/>
<location filename="../ui/controllers/installController.cpp" line="845"/>
<source>%1 installed successfully.</source>
<translation>%1 با موفقیت نصب شد.</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="855"/>
<location filename="../ui/controllers/installController.cpp" line="877"/>
<source>API config reloaded</source>
<translation>پیکربندی API دوباره بارگذاری شد.</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="859"/>
<location filename="../ui/controllers/installController.cpp" line="881"/>
<source>Successfully changed the country of connection to %1</source>
<translation>کشور اتصال با موفقیت به %1 تغییر یافت.</translation>
</message>
@@ -402,28 +405,28 @@ Already installed containers were found on the server. All installed containers
<context>
<name>NotificationHandler</name>
<message>
<location filename="../ui/notificationhandler.cpp" line="64"/>
<location filename="../ui/notificationhandler.cpp" line="71"/>
<location filename="../ui/notificationhandler.cpp" line="63"/>
<location filename="../ui/notificationhandler.cpp" line="70"/>
<source>AmneziaVPN</source>
<translation>AmneziaVPN</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="65"/>
<location filename="../ui/notificationhandler.cpp" line="64"/>
<source>VPN Connected</source>
<translation>ویپیان وصل شد</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="72"/>
<location filename="../ui/notificationhandler.cpp" line="71"/>
<source>VPN Disconnected</source>
<translation>ویپیان قطع شد</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="95"/>
<location filename="../ui/notificationhandler.cpp" line="94"/>
<source>AmneziaVPN notification</source>
<translation>اخطار AmneziaVPN</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="96"/>
<location filename="../ui/notificationhandler.cpp" line="95"/>
<source>Unsecured network detected: </source>
<translation>شبکه ناامن شناسایی شد: </translation>
</message>
@@ -2430,7 +2433,7 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="vanished">چی داری؟</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/>
<source>File with connection settings</source>
<translation>فایل شامل تنظیمات اتصال</translation>
</message>
@@ -2439,102 +2442,92 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="vanished">فایل شامل تنظیمات اتصال یا بکآپ</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
<source>Connection</source>
<translation>ارتباط</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
<source>Settings</source>
<translation type="unfinished">تنظیمات</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
<source>Enable logs</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
<source>Support tag</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Copied</source>
<translation type="unfinished">کپی شد</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
<source>Insert the key, add a configuration file or scan the QR-code</source>
<translation>کلید را وارد کنید، فایل پیکربندی را اضافه کنید یا کد QR را اسکن کنید</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
<source>Insert key</source>
<translation>کلید را وارد کنید</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Insert</source>
<translation>وارد کردن</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
<source>Continue</source>
<translation>ادامه دهید</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/>
<source>Other connection options</source>
<translation>گزینههای اتصال دیگر</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/>
<source>VPN by Amnezia</source>
<translation>VPN توسط Amnezia</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/>
<source>Connect to classic paid and free VPN services from Amnezia</source>
<translation>اتصال به سرویسهای VPN کلاسیک پولی و رایگان از Amnezia</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/>
<source>Self-hosted VPN</source>
<translation>Self-hosted VPN</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/>
<source>Configure Amnezia VPN on your own server</source>
<translation>پیکربندی VPN Amnezia بر روی سرور خودتان</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/>
<source>Restore from backup</source>
<translation>بازیابی از پشتیبان</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/>
<source>Open backup file</source>
<translation>باز کردن فایل پشتیبان</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<source>Backup files (*.backup)</source>
<translation>Backup files (*.backup)</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/>
<source>Open config file</source>
<translation>باز کردن فایل تنظیمات</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
<source>QR code</source>
<translation>QR-Code</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/>
<source>I have nothing</source>
<translation>من هیچی ندارم</translation>
</message>
@@ -2551,12 +2544,12 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation>آدرس آیپی سرور (:پورت)</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
<source>Continue</source>
<translation>ادامه</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
<source>Enter the address in the format 255.255.255.255:88</source>
<translation>آدرس را با فرمت 255.255.255.255:88 وارد کنید</translation>
</message>
@@ -2571,42 +2564,42 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
<source>SSH Username</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
<source>Password or SSH private key</source>
<translation>رمز عبور یا کلید خصوصی SSH</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>تمام دادههایی که شما وارد میکنید به شدت محرمانه است و با Amnezia یا هر شخص ثالث دیگری به اشتراک گذاشته نمیشود</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
<source>How to run your VPN server</source>
<translation>چگونه سرور VPN خود را اجرا کنید</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
<translation>دادههای اتصال را از کجا دریافت کنید و دستورالعملهای مرحله به مرحله برای خرید یک VPS</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
<source>Ip address cannot be empty</source>
<translation>آدرس آیپی نمیتواند خالی باشد</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
<source>Login cannot be empty</source>
<translation>نامکاربری نمیتواند خالی باشد</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
<source>Password/private key cannot be empty</source>
<translation>پسورد یا کلید خصوصی نمیتواند خالی باشد</translation>
</message>
@@ -2946,71 +2939,66 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation>جستجو</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/>
<source>Creation date: %1</source>
<translation>تاریخ ایجاد: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/>
<source>Latest handshake: %1</source>
<translation>آخرین ارتباط: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/>
<source>Data received: %1</source>
<translation>دادههای دریافت شده: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/>
<source>Data sent: %1</source>
<translation>دادههای ارسال شده: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
<source>Allowed IPs: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Creation date: </source>
<translation type="vanished">تاریخ ایجاد: </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
<source>Rename</source>
<translation>تغییر نام</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
<source>Client name</source>
<translation>نام کلاینت</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
<source>Save</source>
<translation>ذخیره</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
<source>Revoke</source>
<translation>ابطال</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
<source>Revoke the config for a user - %1?</source>
<translation>لغو پیکربندی برای یک کاربر - %1?</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<source>The user will no longer be able to connect to your server.</source>
<translation>کاربر دیگر نمیتواند به سرور وصل شود.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
<source>Continue</source>
<translation>ادامه</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
<source>Cancel</source>
<translation>کنسل</translation>
</message>
@@ -3097,17 +3085,17 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<context>
<name>PageStart</name>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/>
<source>Logging was disabled after 14 days, log files were deleted</source>
<translation>ثبت وقایع پس از ۱۴ روز غیرفعال شد و فایلهای ثبت وقایع حذف شدند</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<source>Settings restored from backup file</source>
<translation>تنظیمات از فایل پشتیبان بازیابی شد</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/>
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
<translation type="unfinished"></translation>
</message>
@@ -3491,22 +3479,22 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation>تنظیمات شامل هیچ کانتینر یا اعتبارنامهای برای اتصال به سرور نیست</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="56"/>
<location filename="../core/errorstrings.cpp" line="55"/>
<source>VPN connection error</source>
<translation>خطای اتصال VPN</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="59"/>
<location filename="../core/errorstrings.cpp" line="58"/>
<source>Error when retrieving configuration from API</source>
<translation>خطا هنگام بازیابی پیکربندی از API</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="60"/>
<location filename="../core/errorstrings.cpp" line="59"/>
<source>This config has already been added to the application</source>
<translation>این پیکربندی قبلاً به برنامه اضافه شده است</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="80"/>
<location filename="../core/errorstrings.cpp" line="78"/>
<source>ErrorCode: %1. </source>
<translation>کد خطا: %1. </translation>
</message>
@@ -3576,67 +3564,57 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation>VPN pool error: no available addresses</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="53"/>
<source>Unable to open config file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="61"/>
<location filename="../core/errorstrings.cpp" line="60"/>
<source>In the response from the server, an empty config was received</source>
<translation>در پاسخ از سرور، پیکربندی خالی دریافت شد</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="62"/>
<location filename="../core/errorstrings.cpp" line="61"/>
<source>SSL error occurred</source>
<translation type="unfinished">SSL error occurred</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="63"/>
<location filename="../core/errorstrings.cpp" line="62"/>
<source>Server response timeout on api request</source>
<translation>Server response timeout on api request</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="64"/>
<location filename="../core/errorstrings.cpp" line="63"/>
<source>Missing AGW public key</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="65"/>
<source>Failed to decrypt response payload</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="68"/>
<location filename="../core/errorstrings.cpp" line="66"/>
<source>QFile error: The file could not be opened</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="69"/>
<location filename="../core/errorstrings.cpp" line="67"/>
<source>QFile error: An error occurred when reading from the file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="70"/>
<location filename="../core/errorstrings.cpp" line="68"/>
<source>QFile error: The file could not be accessed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="71"/>
<location filename="../core/errorstrings.cpp" line="69"/>
<source>QFile error: An unspecified error occurred</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="72"/>
<location filename="../core/errorstrings.cpp" line="70"/>
<source>QFile error: A fatal error occurred</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="73"/>
<location filename="../core/errorstrings.cpp" line="71"/>
<source>QFile error: The operation was aborted</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="77"/>
<location filename="../core/errorstrings.cpp" line="75"/>
<source>Internal error</source>
<translation>Internal error</translation>
</message>
@@ -4256,7 +4234,7 @@ For more detailed information, you can
<context>
<name>VpnConnection</name>
<message>
<location filename="../vpnconnection.cpp" line="409"/>
<location filename="../vpnconnection.cpp" line="408"/>
<source>Mbps</source>
<translation>Mbps</translation>
</message>
@@ -4338,12 +4316,12 @@ For more detailed information, you can
<context>
<name>main2</name>
<message>
<location filename="../ui/qml/main2.qml" line="163"/>
<location filename="../ui/qml/main2.qml" line="162"/>
<source>Private key passphrase</source>
<translation>عبارت کلید خصوصی</translation>
</message>
<message>
<location filename="../ui/qml/main2.qml" line="186"/>
<location filename="../ui/qml/main2.qml" line="185"/>
<source>Save</source>
<translation>ذخیره</translation>
</message>

View File

@@ -89,61 +89,61 @@
<name>ConnectionController</name>
<message>
<location filename="../ui/controllers/connectionController.h" line="80"/>
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
<source>Connect</source>
<translation></translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
<source>VPN Protocols is not installed.
Please install VPN container at first</source>
<translation> ि .
ि </translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
<source>Connected</source>
<translation> </translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="212"/>
<location filename="../ui/controllers/connectionController.cpp" line="209"/>
<source>The selected protocol is not supported on the current platform</source>
<translation>ि ि </translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
<source>unable to create configuration</source>
<translation>ि </translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
<source>Connecting...</source>
<translation>...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
<source>Reconnecting...</source>
<translation> ...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
<source>Disconnecting...</source>
<translation>ि ...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
<source>Preparing...</source>
<translation> ...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
<source>Settings updated successfully, reconnnection...</source>
<translation>ि ...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
<source>Settings updated successfully</source>
<translation>ि </translation>
</message>
@@ -254,20 +254,23 @@ Can&apos;t be disabled for current server</source>
<context>
<name>ImportController</name>
<message>
<location filename="../ui/controllers/importController.cpp" line="87"/>
<source>Unable to open file</source>
<translation type="vanished"> </translation>
<translation> </translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="187"/>
<location filename="../ui/controllers/importController.cpp" line="192"/>
<source>Invalid configuration file</source>
<translation type="vanished"> ि </translation>
<translation> ि </translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="623"/>
<location filename="../ui/controllers/importController.cpp" line="617"/>
<source>Scanned %1 of %2.</source>
<translation>%2 %1 ि .</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="658"/>
<location filename="../ui/controllers/importController.cpp" line="652"/>
<source>In the imported configuration, potentially dangerous lines were found:</source>
<translation type="unfinished"></translation>
</message>
@@ -275,86 +278,86 @@ Can&apos;t be disabled for current server</source>
<context>
<name>InstallController</name>
<message>
<location filename="../ui/controllers/installController.cpp" line="157"/>
<location filename="../ui/controllers/installController.cpp" line="181"/>
<source>%1 installed successfully. </source>
<translation>%1 ि . </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="159"/>
<location filename="../ui/controllers/installController.cpp" line="183"/>
<source>%1 is already installed on the server. </source>
<translation>%1 ि . </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="179"/>
<location filename="../ui/controllers/installController.cpp" line="203"/>
<source>
Added containers that were already installed on the server</source>
<translation>
ि </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="259"/>
<location filename="../ui/controllers/installController.cpp" line="283"/>
<source>
Already installed containers were found on the server. All installed containers have been added to the application</source>
<translation>
ि ि ि ि </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="517"/>
<location filename="../ui/controllers/installController.cpp" line="541"/>
<source>Settings updated successfully</source>
<translation>ि </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="534"/>
<location filename="../ui/controllers/installController.cpp" line="558"/>
<source>Server &apos;%1&apos; was rebooted</source>
<translation> &apos;%1&apos; ि </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="546"/>
<location filename="../ui/controllers/installController.cpp" line="570"/>
<source>Server &apos;%1&apos; was removed</source>
<translation> &apos;%1&apos; ि </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="557"/>
<location filename="../ui/controllers/installController.cpp" line="581"/>
<source>All containers from server &apos;%1&apos; have been removed</source>
<translation> &apos;%1&apos; ि </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="575"/>
<location filename="../ui/controllers/installController.cpp" line="599"/>
<source>%1 has been removed from the server &apos;%2&apos;</source>
<translation>%1 &apos;%2&apos; ि </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="584"/>
<location filename="../ui/controllers/installController.cpp" line="608"/>
<source>Api config removed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="606"/>
<location filename="../ui/controllers/installController.cpp" line="630"/>
<source>%1 cached profile cleared</source>
<translation>%1 </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="745"/>
<location filename="../ui/controllers/installController.cpp" line="769"/>
<source>Please login as the user</source>
<translation> ि </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="773"/>
<location filename="../ui/controllers/installController.cpp" line="797"/>
<source>Server added successfully</source>
<translation> </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="821"/>
<location filename="../ui/controllers/installController.cpp" line="845"/>
<source>%1 installed successfully.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="855"/>
<location filename="../ui/controllers/installController.cpp" line="877"/>
<source>API config reloaded</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="859"/>
<location filename="../ui/controllers/installController.cpp" line="881"/>
<source>Successfully changed the country of connection to %1</source>
<translation type="unfinished"></translation>
</message>
@@ -398,28 +401,28 @@ Already installed containers were found on the server. All installed containers
<context>
<name>NotificationHandler</name>
<message>
<location filename="../ui/notificationhandler.cpp" line="64"/>
<location filename="../ui/notificationhandler.cpp" line="71"/>
<location filename="../ui/notificationhandler.cpp" line="63"/>
<location filename="../ui/notificationhandler.cpp" line="70"/>
<source>AmneziaVPN</source>
<translation>AmneziaVPN</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="65"/>
<location filename="../ui/notificationhandler.cpp" line="64"/>
<source>VPN Connected</source>
<translation></translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="72"/>
<location filename="../ui/notificationhandler.cpp" line="71"/>
<source>VPN Disconnected</source>
<translation></translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="95"/>
<location filename="../ui/notificationhandler.cpp" line="94"/>
<source>AmneziaVPN notification</source>
<translation>AmneziaVPN ि</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="96"/>
<location filename="../ui/notificationhandler.cpp" line="95"/>
<source>Unsecured network detected: </source>
<translation>ि : </translation>
</message>
@@ -2379,107 +2382,97 @@ Already installed containers were found on the server. All installed containers
<translation type="vanished"> ि </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
<source>Connection</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
<source>Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
<source>Enable logs</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
<source>Support tag</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Copied</source>
<translation type="unfinished"> ि </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
<source>Insert the key, add a configuration file or scan the QR-code</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
<source>Insert key</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Insert</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
<source>Continue</source>
<translation type="unfinished"> </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/>
<source>Other connection options</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/>
<source>VPN by Amnezia</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/>
<source>Connect to classic paid and free VPN services from Amnezia</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/>
<source>Self-hosted VPN</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/>
<source>Configure Amnezia VPN on your own server</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/>
<source>Restore from backup</source>
<translation type="unfinished"> </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/>
<source>Open backup file</source>
<translation type="unfinished"> </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<source>Backup files (*.backup)</source>
<translation type="unfinished"> (*.backup)</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/>
<source>File with connection settings</source>
<translation> ि </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/>
<source>Open config file</source>
<translation>ि </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
<source>QR code</source>
<translation> ि</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/>
<source>I have nothing</source>
<translation type="unfinished"> </translation>
</message>
@@ -2501,12 +2494,12 @@ Already installed containers were found on the server. All installed containers
<translation> [:]</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
<source>Continue</source>
<translation> </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation> ि ि ि ि </translation>
</message>
@@ -2516,42 +2509,42 @@ Already installed containers were found on the server. All installed containers
<translation>255.255.255.255:22</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
<source>SSH Username</source>
<translation>SSH </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
<source>Password or SSH private key</source>
<translation> SSH ि </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
<source>How to run your VPN server</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
<source>Ip address cannot be empty</source>
<translation> </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
<source>Enter the address in the format 255.255.255.255:88</source>
<translation> 255.255.255.255:88 </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
<source>Login cannot be empty</source>
<translation>ि </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
<source>Password/private key cannot be empty</source>
<translation>/ि </translation>
</message>
@@ -2864,71 +2857,66 @@ Already installed containers were found on the server. All installed containers
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/>
<source>Creation date: %1</source>
<translation>ि ि: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/>
<source>Latest handshake: %1</source>
<translation> ि: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/>
<source>Data received: %1</source>
<translation> : %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/>
<source>Data sent: %1</source>
<translation> : %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
<source>Allowed IPs: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Creation date: </source>
<translation type="vanished">ि िि: </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
<source>Rename</source>
<translation> </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
<source>Client name</source>
<translation> </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
<source>Save</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
<source>Revoke</source>
<translation>ि </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
<source>Revoke the config for a user - %1?</source>
<translation>ि ि ि ि - %1?</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<source>The user will no longer be able to connect to your server.</source>
<translation> .</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
<source>Continue</source>
<translation> </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
<source>Cancel</source>
<translation> </translation>
</message>
@@ -3046,17 +3034,17 @@ Already installed containers were found on the server. All installed containers
<context>
<name>PageStart</name>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/>
<source>Logging was disabled after 14 days, log files were deleted</source>
<translation>14 ि ि , </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<source>Settings restored from backup file</source>
<translation type="unfinished"> ि ि </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/>
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
<translation type="unfinished"></translation>
</message>
@@ -3405,52 +3393,42 @@ Already installed containers were found on the server. All installed containers
<translation> </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="53"/>
<source>Unable to open config file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="56"/>
<location filename="../core/errorstrings.cpp" line="55"/>
<source>VPN connection error</source>
<translation>VPN ि</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="59"/>
<location filename="../core/errorstrings.cpp" line="58"/>
<source>Error when retrieving configuration from API</source>
<translation> ि ि</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="60"/>
<location filename="../core/errorstrings.cpp" line="59"/>
<source>This config has already been added to the application</source>
<translation> ि ि </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="61"/>
<location filename="../core/errorstrings.cpp" line="60"/>
<source>In the response from the server, an empty config was received</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="62"/>
<location filename="../core/errorstrings.cpp" line="61"/>
<source>SSL error occurred</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="63"/>
<location filename="../core/errorstrings.cpp" line="62"/>
<source>Server response timeout on api request</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="64"/>
<location filename="../core/errorstrings.cpp" line="63"/>
<source>Missing AGW public key</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="65"/>
<source>Failed to decrypt response payload</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="80"/>
<location filename="../core/errorstrings.cpp" line="78"/>
<source>ErrorCode: %1. </source>
<translation>ErrorCode: %1. </translation>
</message>
@@ -3515,37 +3493,37 @@ Already installed containers were found on the server. All installed containers
<translation>ि ि ि </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="68"/>
<location filename="../core/errorstrings.cpp" line="66"/>
<source>QFile error: The file could not be opened</source>
<translation>Qफ़ ि: </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="69"/>
<location filename="../core/errorstrings.cpp" line="67"/>
<source>QFile error: An error occurred when reading from the file</source>
<translation>Qफ़ ि: ि </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="70"/>
<location filename="../core/errorstrings.cpp" line="68"/>
<source>QFile error: The file could not be accessed</source>
<translation>Qफ़ ि: </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="71"/>
<location filename="../core/errorstrings.cpp" line="69"/>
<source>QFile error: An unspecified error occurred</source>
<translation>Qफ़ ि: िि ि </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="72"/>
<location filename="../core/errorstrings.cpp" line="70"/>
<source>QFile error: A fatal error occurred</source>
<translation>Qफ़ ि: ि </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="73"/>
<location filename="../core/errorstrings.cpp" line="71"/>
<source>QFile error: The operation was aborted</source>
<translation>Qफ़ ि: ि ि </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="77"/>
<location filename="../core/errorstrings.cpp" line="75"/>
<source>Internal error</source>
<translation>ि ि</translation>
</message>
@@ -4144,7 +4122,7 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<context>
<name>VpnConnection</name>
<message>
<location filename="../vpnconnection.cpp" line="409"/>
<location filename="../vpnconnection.cpp" line="408"/>
<source>Mbps</source>
<translation></translation>
</message>
@@ -4230,12 +4208,12 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<context>
<name>main2</name>
<message>
<location filename="../ui/qml/main2.qml" line="163"/>
<location filename="../ui/qml/main2.qml" line="162"/>
<source>Private key passphrase</source>
<translation>ि </translation>
</message>
<message>
<location filename="../ui/qml/main2.qml" line="186"/>
<location filename="../ui/qml/main2.qml" line="185"/>
<source>Save</source>
<translation></translation>
</message>

View File

@@ -88,62 +88,62 @@
<context>
<name>ConnectionController</name>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
<source>VPN Protocols is not installed.
Please install VPN container at first</source>
<translation>VPN ကက
က VPN ကက </translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
<source>Connecting...</source>
<translation>က...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
<source>Connected</source>
<translation>က</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
<source>Preparing...</source>
<translation>...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
<source>Settings updated successfully, reconnnection...</source>
<translation>ကက က...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
<source>Settings updated successfully</source>
<translation>ကက </translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="212"/>
<location filename="../ui/controllers/connectionController.cpp" line="209"/>
<source>The selected protocol is not supported on the current platform</source>
<translation> ကက ကက က</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
<source>unable to create configuration</source>
<translation>configuration </translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
<source>Reconnecting...</source>
<translation>က...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.h" line="80"/>
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
<source>Connect</source>
<translation>က</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
<source>Disconnecting...</source>
<translation>က...</translation>
</message>
@@ -254,20 +254,23 @@ Can&apos;t be disabled for current server</source>
<context>
<name>ImportController</name>
<message>
<location filename="../ui/controllers/importController.cpp" line="87"/>
<source>Unable to open file</source>
<translation type="vanished">က</translation>
<translation>က</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="187"/>
<location filename="../ui/controllers/importController.cpp" line="192"/>
<source>Invalid configuration file</source>
<translation type="vanished">Configuration က</translation>
<translation>Configuration က</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="623"/>
<location filename="../ui/controllers/importController.cpp" line="617"/>
<source>Scanned %1 of %2.</source>
<translation>%2 %1 က က.</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="658"/>
<location filename="../ui/controllers/importController.cpp" line="652"/>
<source>In the imported configuration, potentially dangerous lines were found:</source>
<translation> configuration က :</translation>
</message>
@@ -275,86 +278,86 @@ Can&apos;t be disabled for current server</source>
<context>
<name>InstallController</name>
<message>
<location filename="../ui/controllers/installController.cpp" line="157"/>
<location filename="../ui/controllers/installController.cpp" line="181"/>
<source>%1 installed successfully. </source>
<translation>%1 က . </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="159"/>
<location filename="../ui/controllers/installController.cpp" line="183"/>
<source>%1 is already installed on the server. </source>
<translation>%1 က . </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="179"/>
<location filename="../ui/controllers/installController.cpp" line="203"/>
<source>
Added containers that were already installed on the server</source>
<translation>
ကက </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="259"/>
<location filename="../ui/controllers/installController.cpp" line="283"/>
<source>
Already installed containers were found on the server. All installed containers have been added to the application</source>
<translation>
ကက ကက က </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="517"/>
<location filename="../ui/controllers/installController.cpp" line="541"/>
<source>Settings updated successfully</source>
<translation>ကက </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="534"/>
<location filename="../ui/controllers/installController.cpp" line="558"/>
<source>Server &apos;%1&apos; was rebooted</source>
<translation> &apos;%1&apos; က </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="546"/>
<location filename="../ui/controllers/installController.cpp" line="570"/>
<source>Server &apos;%1&apos; was removed</source>
<translation> &apos;%1&apos; က </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="557"/>
<location filename="../ui/controllers/installController.cpp" line="581"/>
<source>All containers from server &apos;%1&apos; have been removed</source>
<translation> &apos;%1&apos; ကက က</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="575"/>
<location filename="../ui/controllers/installController.cpp" line="599"/>
<source>%1 has been removed from the server &apos;%2&apos;</source>
<translation>%1 က &apos;%2&apos; က</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="584"/>
<location filename="../ui/controllers/installController.cpp" line="608"/>
<source>Api config removed</source>
<translation>Api config ကက</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="606"/>
<location filename="../ui/controllers/installController.cpp" line="630"/>
<source>%1 cached profile cleared</source>
<translation>ကက %1 က </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="745"/>
<location filename="../ui/controllers/installController.cpp" line="769"/>
<source>Please login as the user</source>
<translation> log in က</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="773"/>
<location filename="../ui/controllers/installController.cpp" line="797"/>
<source>Server added successfully</source>
<translation>က </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="821"/>
<location filename="../ui/controllers/installController.cpp" line="845"/>
<source>%1 installed successfully.</source>
<translation>%1 က .</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="855"/>
<location filename="../ui/controllers/installController.cpp" line="877"/>
<source>API config reloaded</source>
<translation>API config က က</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="859"/>
<location filename="../ui/controllers/installController.cpp" line="881"/>
<source>Successfully changed the country of connection to %1</source>
<translation>ကက %1 က</translation>
</message>
@@ -398,28 +401,28 @@ Already installed containers were found on the server. All installed containers
<context>
<name>NotificationHandler</name>
<message>
<location filename="../ui/notificationhandler.cpp" line="64"/>
<location filename="../ui/notificationhandler.cpp" line="71"/>
<location filename="../ui/notificationhandler.cpp" line="63"/>
<location filename="../ui/notificationhandler.cpp" line="70"/>
<source>AmneziaVPN</source>
<translation>AmneziaVPN</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="65"/>
<location filename="../ui/notificationhandler.cpp" line="64"/>
<source>VPN Connected</source>
<translation>VPN က</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="72"/>
<location filename="../ui/notificationhandler.cpp" line="71"/>
<source>VPN Disconnected</source>
<translation>VPN က</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="95"/>
<location filename="../ui/notificationhandler.cpp" line="94"/>
<source>AmneziaVPN notification</source>
<translation>AmneziaVPN </translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="96"/>
<location filename="../ui/notificationhandler.cpp" line="95"/>
<source>Unsecured network detected: </source>
<translation>ကက က: </translation>
</message>
@@ -2324,107 +2327,97 @@ Already installed containers were found on the server. All installed containers
<context>
<name>PageSetupWizardConfigSource</name>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/>
<source>File with connection settings</source>
<translation>ကက</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
<source>Connection</source>
<translation>က</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
<source>Settings</source>
<translation type="unfinished">က</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
<source>Enable logs</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
<source>Support tag</source>
<translation type="unfinished">က tag</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Copied</source>
<translation type="unfinished">က</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
<source>Insert the key, add a configuration file or scan the QR-code</source>
<translation>Key က က QR-ကက က</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
<source>Insert key</source>
<translation>Key က</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Insert</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
<source>Continue</source>
<translation>ကက</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/>
<source>Other connection options</source>
<translation>က</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/>
<source>VPN by Amnezia</source>
<translation>Amnezia VPN</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/>
<source>Connect to classic paid and free VPN services from Amnezia</source>
<translation>Amnezia VPN က</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/>
<source>Self-hosted VPN</source>
<translation>က host VPN</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/>
<source>Configure Amnezia VPN on your own server</source>
<translation>Amnezia VPN က က </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/>
<source>Restore from backup</source>
<translation> </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/>
<source>Open backup file</source>
<translation>က </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<source>Backup files (*.backup)</source>
<translation> (*.backup)</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/>
<source>Open config file</source>
<translation>config က</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
<source>QR code</source>
<translation>QR-က</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/>
<source>I have nothing</source>
<translation>က</translation>
</message>
@@ -2437,12 +2430,12 @@ Already installed containers were found on the server. All installed containers
<translation> IP [:port]</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
<source>Continue</source>
<translation>ကက</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
<source>Enter the address in the format 255.255.255.255:88</source>
<translation>က 255.255.255.255:88 </translation>
</message>
@@ -2457,42 +2450,42 @@ Already installed containers were found on the server. All installed containers
<translation>255.255.255.255:22</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
<source>SSH Username</source>
<translation>SSH </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
<source>Password or SSH private key</source>
<translation>ကက SSH private key</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>က ကက Amnezia က </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
<source>How to run your VPN server</source>
<translation>က </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
<translation>ကက VPS က ကက</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
<source>Ip address cannot be empty</source>
<translation>IP </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
<source>Login cannot be empty</source>
<translation>ကက </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
<source>Password/private key cannot be empty</source>
<translation>ကက/private key </translation>
</message>
@@ -2812,67 +2805,62 @@ Already installed containers were found on the server. All installed containers
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/>
<source>Creation date: %1</source>
<translation>က: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/>
<source>Latest handshake: %1</source>
<translation>က handshake : %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/>
<source>Data received: %1</source>
<translation>က: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/>
<source>Data sent: %1</source>
<translation>က: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
<source>Allowed IPs: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
<source>Rename</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
<source>Client name</source>
<translation>က</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
<source>Save</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
<source>Revoke</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
<source>Revoke the config for a user - %1?</source>
<translation> %1 က config က ?</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<source>The user will no longer be able to connect to your server.</source>
<translation> က.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
<source>Continue</source>
<translation>ကက</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
<source>Cancel</source>
<translation>က</translation>
</message>
@@ -2959,17 +2947,17 @@ Already installed containers were found on the server. All installed containers
<context>
<name>PageStart</name>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/>
<source>Logging was disabled after 14 days, log files were deleted</source>
<translation> ကက Logging က က ကက</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<source>Settings restored from backup file</source>
<translation>ကက </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/>
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
<translation type="unfinished"></translation>
</message>
@@ -3301,17 +3289,17 @@ Already installed containers were found on the server. All installed containers
<translation>Config ကက က က </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="59"/>
<location filename="../core/errorstrings.cpp" line="58"/>
<source>Error when retrieving configuration from API</source>
<translation>API က </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="60"/>
<location filename="../core/errorstrings.cpp" line="59"/>
<source>This config has already been added to the application</source>
<translation> config က က </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="80"/>
<location filename="../core/errorstrings.cpp" line="78"/>
<source>ErrorCode: %1. </source>
<translation>က: %1. </translation>
</message>
@@ -3381,72 +3369,62 @@ Already installed containers were found on the server. All installed containers
<translation>VPN pool မှု: ရရှိနိုင်သ</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="53"/>
<source>Unable to open config file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="56"/>
<location filename="../core/errorstrings.cpp" line="55"/>
<source>VPN connection error</source>
<translation>VPN က</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="61"/>
<location filename="../core/errorstrings.cpp" line="60"/>
<source>In the response from the server, an empty config was received</source>
<translation> config က က</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="62"/>
<location filename="../core/errorstrings.cpp" line="61"/>
<source>SSL error occurred</source>
<translation>SSL </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="63"/>
<location filename="../core/errorstrings.cpp" line="62"/>
<source>Server response timeout on api request</source>
<translation>Api က</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="64"/>
<location filename="../core/errorstrings.cpp" line="63"/>
<source>Missing AGW public key</source>
<translation>AGW public key က</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="65"/>
<source>Failed to decrypt response payload</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="68"/>
<location filename="../core/errorstrings.cpp" line="66"/>
<source>QFile error: The file could not be opened</source>
<translation>QFile မှု: ဖိုင်ကို </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="69"/>
<location filename="../core/errorstrings.cpp" line="67"/>
<source>QFile error: An error occurred when reading from the file</source>
<translation>QFile မှု: ဖိုင်ကိုဖတ်န </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="70"/>
<location filename="../core/errorstrings.cpp" line="68"/>
<source>QFile error: The file could not be accessed</source>
<translation>QFile မှု: ဖိုင်ကို </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="71"/>
<location filename="../core/errorstrings.cpp" line="69"/>
<source>QFile error: An unspecified error occurred</source>
<translation>QFile မှု: သတ်မှတ်မထ </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="72"/>
<location filename="../core/errorstrings.cpp" line="70"/>
<source>QFile error: A fatal error occurred</source>
<translation>QFile မှု: က </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="73"/>
<location filename="../core/errorstrings.cpp" line="71"/>
<source>QFile error: The operation was aborted</source>
<translation>QFile မှု: လုပ်ငန်က ကက</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="77"/>
<location filename="../core/errorstrings.cpp" line="75"/>
<source>Internal error</source>
<translation>က </translation>
</message>
@@ -4053,7 +4031,7 @@ For more detailed information, you can
<context>
<name>VpnConnection</name>
<message>
<location filename="../vpnconnection.cpp" line="409"/>
<location filename="../vpnconnection.cpp" line="408"/>
<source>Mbps</source>
<translation>Mbps</translation>
</message>
@@ -4127,12 +4105,12 @@ For more detailed information, you can
<context>
<name>main2</name>
<message>
<location filename="../ui/qml/main2.qml" line="163"/>
<location filename="../ui/qml/main2.qml" line="162"/>
<source>Private key passphrase</source>
<translation>က key ကက</translation>
</message>
<message>
<location filename="../ui/qml/main2.qml" line="186"/>
<location filename="../ui/qml/main2.qml" line="185"/>
<source>Save</source>
<translation></translation>
</message>

View File

@@ -88,62 +88,62 @@
<context>
<name>ConnectionController</name>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
<source>VPN Protocols is not installed.
Please install VPN container at first</source>
<translation>VPN-протоколы не установлены.
Пожалуйста, установите протокол</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
<source>Connecting...</source>
<translation>Подключение...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
<source>Connected</source>
<translation>Подключено</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
<source>Preparing...</source>
<translation>Подготовка...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
<source>Settings updated successfully, reconnnection...</source>
<translation>Настройки успешно обновлены, переподключение...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
<source>Settings updated successfully</source>
<translation>Настройки успешно обновлены</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="212"/>
<location filename="../ui/controllers/connectionController.cpp" line="209"/>
<source>The selected protocol is not supported on the current platform</source>
<translation>Выбранный протокол не поддерживается на данном устройстве</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
<source>unable to create configuration</source>
<translation>не удалось создать конфигурацию</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
<source>Reconnecting...</source>
<translation>Переподключение...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.h" line="80"/>
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
<source>Connect</source>
<translation>Подключиться</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
<source>Disconnecting...</source>
<translation>Отключение...</translation>
</message>
@@ -258,20 +258,23 @@ Can&apos;t be disabled for current server</source>
<context>
<name>ImportController</name>
<message>
<location filename="../ui/controllers/importController.cpp" line="87"/>
<source>Unable to open file</source>
<translation type="vanished">Невозможно открыть файл</translation>
<translation>Невозможно открыть файл</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="187"/>
<location filename="../ui/controllers/importController.cpp" line="192"/>
<source>Invalid configuration file</source>
<translation type="vanished">Неверный файл конфигурации</translation>
<translation>Неверный файл конфигурации</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="623"/>
<location filename="../ui/controllers/importController.cpp" line="617"/>
<source>Scanned %1 of %2.</source>
<translation>Отсканировано %1 из %2.</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="658"/>
<location filename="../ui/controllers/importController.cpp" line="652"/>
<source>In the imported configuration, potentially dangerous lines were found:</source>
<translation>В импортированной конфигурации были обнаружены потенциально опасные строки:</translation>
</message>
@@ -279,86 +282,86 @@ Can&apos;t be disabled for current server</source>
<context>
<name>InstallController</name>
<message>
<location filename="../ui/controllers/installController.cpp" line="157"/>
<location filename="../ui/controllers/installController.cpp" line="181"/>
<source>%1 installed successfully. </source>
<translation>%1 успешно установлен. </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="159"/>
<location filename="../ui/controllers/installController.cpp" line="183"/>
<source>%1 is already installed on the server. </source>
<translation>%1 уже установлен на сервер. </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="179"/>
<location filename="../ui/controllers/installController.cpp" line="203"/>
<source>
Added containers that were already installed on the server</source>
<translation>
Добавлены сервисы и протоколы, которые были ранее установлены на сервер</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="259"/>
<location filename="../ui/controllers/installController.cpp" line="283"/>
<source>
Already installed containers were found on the server. All installed containers have been added to the application</source>
<translation>
На сервере обнаружены установленные протоколы и сервисы. Все они были добавлены в приложение</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="517"/>
<location filename="../ui/controllers/installController.cpp" line="541"/>
<source>Settings updated successfully</source>
<translation>Настройки успешно обновлены</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="534"/>
<location filename="../ui/controllers/installController.cpp" line="558"/>
<source>Server &apos;%1&apos; was rebooted</source>
<translation>Сервер &apos;%1&apos; был перезагружен</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="546"/>
<location filename="../ui/controllers/installController.cpp" line="570"/>
<source>Server &apos;%1&apos; was removed</source>
<translation>Сервер &apos;%1&apos; был удален</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="557"/>
<location filename="../ui/controllers/installController.cpp" line="581"/>
<source>All containers from server &apos;%1&apos; have been removed</source>
<translation>Все протоколы и сервисы были удалены с сервера &apos;%1&apos;</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="575"/>
<location filename="../ui/controllers/installController.cpp" line="599"/>
<source>%1 has been removed from the server &apos;%2&apos;</source>
<translation>%1 был удален с сервера &apos;%2&apos;</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="584"/>
<location filename="../ui/controllers/installController.cpp" line="608"/>
<source>Api config removed</source>
<translation>Конфигурация API удалена</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="606"/>
<location filename="../ui/controllers/installController.cpp" line="630"/>
<source>%1 cached profile cleared</source>
<translation>%1 закэшированный профиль очищен</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="745"/>
<location filename="../ui/controllers/installController.cpp" line="769"/>
<source>Please login as the user</source>
<translation>Пожалуйста, войдите в систему от имени пользователя</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="773"/>
<location filename="../ui/controllers/installController.cpp" line="797"/>
<source>Server added successfully</source>
<translation>Сервер успешно добавлен</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="821"/>
<location filename="../ui/controllers/installController.cpp" line="845"/>
<source>%1 installed successfully.</source>
<translation>%1 успешно установлен.</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="855"/>
<location filename="../ui/controllers/installController.cpp" line="877"/>
<source>API config reloaded</source>
<translation>Конфигурация API перезагружена</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="859"/>
<location filename="../ui/controllers/installController.cpp" line="881"/>
<source>Successfully changed the country of connection to %1</source>
<translation>Изменение страны подключения на %1</translation>
</message>
@@ -402,28 +405,28 @@ Already installed containers were found on the server. All installed containers
<context>
<name>NotificationHandler</name>
<message>
<location filename="../ui/notificationhandler.cpp" line="64"/>
<location filename="../ui/notificationhandler.cpp" line="71"/>
<location filename="../ui/notificationhandler.cpp" line="63"/>
<location filename="../ui/notificationhandler.cpp" line="70"/>
<source>AmneziaVPN</source>
<translation>AmneziaVPN</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="65"/>
<location filename="../ui/notificationhandler.cpp" line="64"/>
<source>VPN Connected</source>
<translation>VPN подключен</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="72"/>
<location filename="../ui/notificationhandler.cpp" line="71"/>
<source>VPN Disconnected</source>
<translation>VPN выключен</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="95"/>
<location filename="../ui/notificationhandler.cpp" line="94"/>
<source>AmneziaVPN notification</source>
<translation>Уведомление AmneziaVPN</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="96"/>
<location filename="../ui/notificationhandler.cpp" line="95"/>
<source>Unsecured network detected: </source>
<translation>Обнаружена незащищенная сеть: </translation>
</message>
@@ -2502,7 +2505,7 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="vanished">Что у вас есть?</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/>
<source>File with connection settings</source>
<translation>Файл с настройками подключения</translation>
</message>
@@ -2511,102 +2514,92 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="vanished">Файл с настройками подключения или резервной копией</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
<source>Connection</source>
<translation>Соединение</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
<source>Settings</source>
<translation type="unfinished">Настройки</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
<source>Enable logs</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
<source>Support tag</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Copied</source>
<translation type="unfinished">Скопировано</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
<source>Insert the key, add a configuration file or scan the QR-code</source>
<translation>Вставьте ключ, добавьте файл конфигурации или отсканируйте QR-код</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
<source>Insert key</source>
<translation>Вставьте ключ</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Insert</source>
<translation>Вставить</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
<source>Continue</source>
<translation>Продолжить</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/>
<source>Other connection options</source>
<translation>Другие варианты подключения</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/>
<source>VPN by Amnezia</source>
<translation>VPN от Amnezia</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/>
<source>Connect to classic paid and free VPN services from Amnezia</source>
<translation>Подключайтесь к классическим платным и бесплатным VPN-сервисам от Amnezia</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/>
<source>Self-hosted VPN</source>
<translation>Self-hosted VPN</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/>
<source>Configure Amnezia VPN on your own server</source>
<translation>Настроить VPN на собственном сервере</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/>
<source>Restore from backup</source>
<translation>Восстановить из резервной копии</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/>
<source>Open backup file</source>
<translation>Открыть резервную копию</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<source>Backup files (*.backup)</source>
<translation>Файлы резервных копий (*.backup)</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/>
<source>Open config file</source>
<translation>Открыть файл с конфигурацией</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
<source>QR code</source>
<translation>QR-код</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/>
<source>I have nothing</source>
<translation>У меня ничего нет</translation>
</message>
@@ -2635,7 +2628,7 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="vanished">Password / SSH private key</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
<source>Continue</source>
<translation>Продолжить</translation>
</message>
@@ -2645,7 +2638,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation type="vanished">Все данные, которые вы вводите, останутся строго конфиденциальными и не будут переданы или раскрыты Amnezia или каким-либо третьим лицам</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
<source>Enter the address in the format 255.255.255.255:88</source>
<translation>Введите адрес в формате 255.255.255.255:88</translation>
</message>
@@ -2664,42 +2657,42 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>255.255.255.255:22</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
<source>SSH Username</source>
<translation>Имя пользователя SSH</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
<source>Password or SSH private key</source>
<translation>Пароль или закрытый ключ SSH</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>Все данные, которые вы вводите, останутся строго конфиденциальными и не будут переданы или раскрыты Amnezia или каким-либо третьим лицам</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
<source>How to run your VPN server</source>
<translation>Как создать VPN на собственном сервере</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
<translation>Где взять данные для подключения, пошаговые инстуркции по покупке VPS</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
<source>Ip address cannot be empty</source>
<translation>Поле с IP-адресом не может быть пустым</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
<source>Login cannot be empty</source>
<translation>Поле с логином не может быть пустым</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
<source>Password/private key cannot be empty</source>
<translation>Поле с паролем/закрытым ключом не может быть пустым</translation>
</message>
@@ -3075,71 +3068,66 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>Поиск</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/>
<source>Creation date: %1</source>
<translation>Дата создания: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/>
<source>Latest handshake: %1</source>
<translation>Последнее рукопожатие: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/>
<source>Data received: %1</source>
<translation>Получено данных: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/>
<source>Data sent: %1</source>
<translation>Отправлено данных: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
<source>Allowed IPs: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Creation date: </source>
<translation type="vanished">Дата создания: </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
<source>Rename</source>
<translation>Переименовать</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
<source>Client name</source>
<translation>Имя клиента</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
<source>Save</source>
<translation>Сохранить</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
<source>Revoke</source>
<translation>Отозвать</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
<source>Revoke the config for a user - %1?</source>
<translation>Отозвать конфигурацию для пользователя - %1?</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<source>The user will no longer be able to connect to your server.</source>
<translation>Пользователь больше не сможет подключаться к вашему серверу.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
<source>Continue</source>
<translation>Продолжить</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
<source>Cancel</source>
<translation>Отменить</translation>
</message>
@@ -3230,17 +3218,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<context>
<name>PageStart</name>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/>
<source>Logging was disabled after 14 days, log files were deleted</source>
<translation>Логирование было отключено по прошествии 14 дней, файлы логов были удалены.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<source>Settings restored from backup file</source>
<translation>Настройки восстановлены из бэкап файла</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/>
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
<translation type="unfinished"></translation>
</message>
@@ -3637,17 +3625,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>Конфигурация не содержит каких-либо контейнеров и учетных данных для подключения к серверу</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="59"/>
<location filename="../core/errorstrings.cpp" line="58"/>
<source>Error when retrieving configuration from API</source>
<translation>Ошибка при получении конфигурации из API</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="60"/>
<location filename="../core/errorstrings.cpp" line="59"/>
<source>This config has already been added to the application</source>
<translation>Данная конфигурация уже была добавлена в приложение</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="80"/>
<location filename="../core/errorstrings.cpp" line="78"/>
<source>ErrorCode: %1. </source>
<translation>Код ошибки: %1. </translation>
</message>
@@ -3706,72 +3694,62 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>Ошибка пула VPN: нет доступных адресов</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="53"/>
<source>Unable to open config file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="56"/>
<location filename="../core/errorstrings.cpp" line="55"/>
<source>VPN connection error</source>
<translation>Ошибка VPN-соединения</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="61"/>
<location filename="../core/errorstrings.cpp" line="60"/>
<source>In the response from the server, an empty config was received</source>
<translation>В ответе от сервера была получена пустая конфигурация</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="62"/>
<location filename="../core/errorstrings.cpp" line="61"/>
<source>SSL error occurred</source>
<translation>Произошла ошибка SSL</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="63"/>
<location filename="../core/errorstrings.cpp" line="62"/>
<source>Server response timeout on api request</source>
<translation>Тайм-аут ответа сервера на запрос API</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="64"/>
<location filename="../core/errorstrings.cpp" line="63"/>
<source>Missing AGW public key</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="65"/>
<source>Failed to decrypt response payload</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="68"/>
<location filename="../core/errorstrings.cpp" line="66"/>
<source>QFile error: The file could not be opened</source>
<translation>Ошибка QFile: не удалось открыть файл</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="69"/>
<location filename="../core/errorstrings.cpp" line="67"/>
<source>QFile error: An error occurred when reading from the file</source>
<translation>Ошибка QFile: произошла ошибка при чтении из файла</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="70"/>
<location filename="../core/errorstrings.cpp" line="68"/>
<source>QFile error: The file could not be accessed</source>
<translation>Ошибка QFile: не удалось получить доступ к файлу</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="71"/>
<location filename="../core/errorstrings.cpp" line="69"/>
<source>QFile error: An unspecified error occurred</source>
<translation>Ошибка QFile: произошла неизвестная ошибка</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="72"/>
<location filename="../core/errorstrings.cpp" line="70"/>
<source>QFile error: A fatal error occurred</source>
<translation>Ошибка QFile: произошла фатальная ошибка</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="73"/>
<location filename="../core/errorstrings.cpp" line="71"/>
<source>QFile error: The operation was aborted</source>
<translation>Ошибка QFile: операция была прервана</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="77"/>
<location filename="../core/errorstrings.cpp" line="75"/>
<source>Internal error</source>
<translation>Внутренняя ошибка</translation>
</message>
@@ -4471,7 +4449,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin
<context>
<name>VpnConnection</name>
<message>
<location filename="../vpnconnection.cpp" line="409"/>
<location filename="../vpnconnection.cpp" line="408"/>
<source>Mbps</source>
<translation>Мбит/с</translation>
</message>
@@ -4569,12 +4547,12 @@ This means that AmneziaWG keeps the fast performance of the original while addin
<context>
<name>main2</name>
<message>
<location filename="../ui/qml/main2.qml" line="163"/>
<location filename="../ui/qml/main2.qml" line="162"/>
<source>Private key passphrase</source>
<translation>Парольная фраза для закрытого ключа</translation>
</message>
<message>
<location filename="../ui/qml/main2.qml" line="186"/>
<location filename="../ui/qml/main2.qml" line="185"/>
<source>Save</source>
<translation>Сохранить</translation>
</message>

View File

@@ -111,62 +111,62 @@
<context>
<name>ConnectionController</name>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
<source>VPN Protocols is not installed.
Please install VPN container at first</source>
<translation>VPN протоколи не встановлено.
Будь-ласка, встановіть VPN контейнер</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
<source>unable to create configuration</source>
<translation>Неможливо створити конфігурацію</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
<source>Connecting...</source>
<translation>Підключення...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
<source>Connected</source>
<translation>Підключено</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
<source>Preparing...</source>
<translation>Підготовка...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
<source>Settings updated successfully, reconnnection...</source>
<translation>Налаштування оновлено, підключення...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
<source>Settings updated successfully</source>
<translation>Налаштування оновлено</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="212"/>
<location filename="../ui/controllers/connectionController.cpp" line="209"/>
<source>The selected protocol is not supported on the current platform</source>
<translation>Вибраний протокол не підтримується на цьому пристрої</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
<source>Reconnecting...</source>
<translation>Перепідключення...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.h" line="80"/>
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
<source>Connect</source>
<translation>Підключитись</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
<source>Disconnecting...</source>
<translation>Відключаємось...</translation>
</message>
@@ -285,20 +285,23 @@ Can&apos;t be disabled for current server</source>
<context>
<name>ImportController</name>
<message>
<location filename="../ui/controllers/importController.cpp" line="87"/>
<source>Unable to open file</source>
<translation type="vanished">Неможливо відкрити файл</translation>
<translation>Неможливо відкрити файл</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="187"/>
<location filename="../ui/controllers/importController.cpp" line="192"/>
<source>Invalid configuration file</source>
<translation type="vanished">Недійсний файл конфігурації</translation>
<translation>Недійсний файл конфігурації</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="623"/>
<location filename="../ui/controllers/importController.cpp" line="617"/>
<source>Scanned %1 of %2.</source>
<translation>Відскановано %1 з %2.</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="658"/>
<location filename="../ui/controllers/importController.cpp" line="652"/>
<source>In the imported configuration, potentially dangerous lines were found:</source>
<translation>У імпортованій конфігурації знайдено потенційно небезпечні рядки:</translation>
</message>
@@ -306,85 +309,85 @@ Can&apos;t be disabled for current server</source>
<context>
<name>InstallController</name>
<message>
<location filename="../ui/controllers/installController.cpp" line="157"/>
<location filename="../ui/controllers/installController.cpp" line="181"/>
<source>%1 installed successfully. </source>
<translation>%1 встановлено. </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="159"/>
<location filename="../ui/controllers/installController.cpp" line="183"/>
<source>%1 is already installed on the server. </source>
<translation>%1 вже встановлено на сервері. </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="179"/>
<location filename="../ui/controllers/installController.cpp" line="203"/>
<source>
Added containers that were already installed on the server</source>
<translation>Додані сервіси і протоколи, які були раніше встановлені на сервері</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="259"/>
<location filename="../ui/controllers/installController.cpp" line="283"/>
<source>
Already installed containers were found on the server. All installed containers have been added to the application</source>
<translation>
На сервері знайдені сервіси та протоколи, всі вони додані в застосунок</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="517"/>
<location filename="../ui/controllers/installController.cpp" line="541"/>
<source>Settings updated successfully</source>
<translation>Налаштування оновлено</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="534"/>
<location filename="../ui/controllers/installController.cpp" line="558"/>
<source>Server &apos;%1&apos; was rebooted</source>
<translation>Сервер &apos;%1&apos; перезавантажено</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="546"/>
<location filename="../ui/controllers/installController.cpp" line="570"/>
<source>Server &apos;%1&apos; was removed</source>
<translation>Сервер &apos;%1&apos; був видалений</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="557"/>
<location filename="../ui/controllers/installController.cpp" line="581"/>
<source>All containers from server &apos;%1&apos; have been removed</source>
<translation>Всі сервіси та протоколи були видалені з сервера &apos;%1&apos;</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="575"/>
<location filename="../ui/controllers/installController.cpp" line="599"/>
<source>%1 has been removed from the server &apos;%2&apos;</source>
<translation>%1 був видалений з сервера &apos;%2&apos;</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="584"/>
<location filename="../ui/controllers/installController.cpp" line="608"/>
<source>Api config removed</source>
<translation>Конфігурацію API видалено</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="606"/>
<location filename="../ui/controllers/installController.cpp" line="630"/>
<source>%1 cached profile cleared</source>
<translation>Кешований профіль %1 очищено</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="745"/>
<location filename="../ui/controllers/installController.cpp" line="769"/>
<source>Please login as the user</source>
<translation>Буль-ласка, увійдіть в систему від імені користувача</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="773"/>
<location filename="../ui/controllers/installController.cpp" line="797"/>
<source>Server added successfully</source>
<translation>Сервер додано</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="821"/>
<location filename="../ui/controllers/installController.cpp" line="845"/>
<source>%1 installed successfully.</source>
<translation>%1 встановлено успішно.</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="855"/>
<location filename="../ui/controllers/installController.cpp" line="877"/>
<source>API config reloaded</source>
<translation>Конфігурацію API перезавантажено</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="859"/>
<location filename="../ui/controllers/installController.cpp" line="881"/>
<source>Successfully changed the country of connection to %1</source>
<translation>Успішно змінено країну підключення на %1</translation>
</message>
@@ -428,28 +431,28 @@ Already installed containers were found on the server. All installed containers
<context>
<name>NotificationHandler</name>
<message>
<location filename="../ui/notificationhandler.cpp" line="64"/>
<location filename="../ui/notificationhandler.cpp" line="71"/>
<location filename="../ui/notificationhandler.cpp" line="63"/>
<location filename="../ui/notificationhandler.cpp" line="70"/>
<source>AmneziaVPN</source>
<translation>AmneziaVPN</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="65"/>
<location filename="../ui/notificationhandler.cpp" line="64"/>
<source>VPN Connected</source>
<translation>VPN Підключено</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="72"/>
<location filename="../ui/notificationhandler.cpp" line="71"/>
<source>VPN Disconnected</source>
<translation>VPN Вимкнено</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="95"/>
<location filename="../ui/notificationhandler.cpp" line="94"/>
<source>AmneziaVPN notification</source>
<translation>Сповіщення AmneziaVPN</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="96"/>
<location filename="../ui/notificationhandler.cpp" line="95"/>
<source>Unsecured network detected: </source>
<translation>Знайдена не захищена мережа: </translation>
</message>
@@ -2588,7 +2591,7 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="vanished">Виберіть що у вас є</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/>
<source>File with connection settings</source>
<translation>Файл з налаштуваннями підключення</translation>
</message>
@@ -2597,102 +2600,92 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="vanished">Файл з налаштуваннями підключення або бекап</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
<source>Connection</source>
<translation>Підключення</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
<source>Settings</source>
<translation type="unfinished">Налаштування</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
<source>Enable logs</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
<source>Support tag</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Copied</source>
<translation type="unfinished">Скопійовано</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
<source>Insert the key, add a configuration file or scan the QR-code</source>
<translation>Вставте ключ, додайте файл конфігурації або відскануйте QR-код</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
<source>Insert key</source>
<translation>Вставити ключ</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Insert</source>
<translation>Вставити</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
<source>Continue</source>
<translation>Продовжити</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/>
<source>Other connection options</source>
<translation>Інші параметри підключення</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/>
<source>VPN by Amnezia</source>
<translation>VPN від Amnezia</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/>
<source>Connect to classic paid and free VPN services from Amnezia</source>
<translation>Підключайтеся до звичайних платних та безкоштовних VPN-сервісів від Amnezia</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/>
<source>Self-hosted VPN</source>
<translation>Self-hosted VPN</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/>
<source>Configure Amnezia VPN on your own server</source>
<translation>Налаштуйте Amnezia VPN на власному сервері</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/>
<source>Restore from backup</source>
<translation>Відновити із бекапа</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/>
<source>Open backup file</source>
<translation>Відкрити бекап файл</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<source>Backup files (*.backup)</source>
<translation>Файли резервної копії (*.backup)</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/>
<source>Open config file</source>
<translation>Відкрити файл з конфігурацією</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
<source>QR code</source>
<translation>QR-код</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/>
<source>I have nothing</source>
<translation>У мене нічого нема</translation>
</message>
@@ -2721,7 +2714,7 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="vanished">Password / SSH private key</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
<source>Continue</source>
<translation>Продовжити</translation>
</message>
@@ -2732,7 +2725,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
і не будуть передані чи розголошені Amnezia або будь-яким третім особам</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
<source>Enter the address in the format 255.255.255.255:88</source>
<translation>Введіть адресу в форматі 255.255.255.255:88</translation>
</message>
@@ -2751,42 +2744,42 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>255.255.255.255:22</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
<source>SSH Username</source>
<translation>SSH Username</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
<source>Password or SSH private key</source>
<translation>Пароль або SSH ключ</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>Усі дані, які ви вводите, залишатимуться суворо конфіденційними та не будуть передані чи розголошені Amnezia або будь-яким третім особам</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
<source>How to run your VPN server</source>
<translation>Як запустити ваш VPN-сервер</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
<translation>Де отримати дані для підключення: покрокові інструкції з придбання VPS</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
<source>Ip address cannot be empty</source>
<translation>Поле IP address не може бути пустим</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
<source>Login cannot be empty</source>
<translation>Поле Login не може бути пустим</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
<source>Password/private key cannot be empty</source>
<translation>Поле Password/Private key не може бути пустим</translation>
</message>
@@ -3170,71 +3163,66 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>Пошук</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/>
<source>Creation date: %1</source>
<translation>Дата створення: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/>
<source>Latest handshake: %1</source>
<translation>Останнє з&apos;єднання: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/>
<source>Data received: %1</source>
<translation>Отримано даних: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/>
<source>Data sent: %1</source>
<translation>Відправлено даних: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
<source>Allowed IPs: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Creation date: </source>
<translation type="obsolete">Дата створення:</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
<source>Rename</source>
<translation>Перейменувати</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
<source>Client name</source>
<translation>Назва клієнта</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
<source>Save</source>
<translation>Зберегти</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
<source>Revoke</source>
<translation>Відкликати</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
<source>Revoke the config for a user - %1?</source>
<translation>Відкликати доступ для користувача - %1?</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<source>The user will no longer be able to connect to your server.</source>
<translation>Користувач більше не зможе підключатись до вашого сервера </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
<source>Continue</source>
<translation>Продовжити</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
<source>Cancel</source>
<translation>Відмінити</translation>
</message>
@@ -3324,17 +3312,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<context>
<name>PageStart</name>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/>
<source>Logging was disabled after 14 days, log files were deleted</source>
<translation>Логування було вимкнене через 14 днів, файли журналів були видалені</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<source>Settings restored from backup file</source>
<translation>Відновлення налаштувань із бекап файлу</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/>
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
<translation type="unfinished"></translation>
</message>
@@ -3733,17 +3721,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation type="unfinished">Конфігурація не містить контейнерів і облікових даних для підключення до серверу</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="59"/>
<location filename="../core/errorstrings.cpp" line="58"/>
<source>Error when retrieving configuration from API</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="60"/>
<location filename="../core/errorstrings.cpp" line="59"/>
<source>This config has already been added to the application</source>
<translation>Ця конфігурація вже була додана в застосунок</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="80"/>
<location filename="../core/errorstrings.cpp" line="78"/>
<source>ErrorCode: %1. </source>
<translation type="unfinished"></translation>
</message>
@@ -3802,72 +3790,62 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>VPN pool error: no available addresses</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="53"/>
<source>Unable to open config file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="56"/>
<location filename="../core/errorstrings.cpp" line="55"/>
<source>VPN connection error</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="61"/>
<location filename="../core/errorstrings.cpp" line="60"/>
<source>In the response from the server, an empty config was received</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="62"/>
<location filename="../core/errorstrings.cpp" line="61"/>
<source>SSL error occurred</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="63"/>
<location filename="../core/errorstrings.cpp" line="62"/>
<source>Server response timeout on api request</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="64"/>
<location filename="../core/errorstrings.cpp" line="63"/>
<source>Missing AGW public key</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="65"/>
<source>Failed to decrypt response payload</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="68"/>
<location filename="../core/errorstrings.cpp" line="66"/>
<source>QFile error: The file could not be opened</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="69"/>
<location filename="../core/errorstrings.cpp" line="67"/>
<source>QFile error: An error occurred when reading from the file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="70"/>
<location filename="../core/errorstrings.cpp" line="68"/>
<source>QFile error: The file could not be accessed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="71"/>
<location filename="../core/errorstrings.cpp" line="69"/>
<source>QFile error: An unspecified error occurred</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="72"/>
<location filename="../core/errorstrings.cpp" line="70"/>
<source>QFile error: A fatal error occurred</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="73"/>
<location filename="../core/errorstrings.cpp" line="71"/>
<source>QFile error: The operation was aborted</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="77"/>
<location filename="../core/errorstrings.cpp" line="75"/>
<source>Internal error</source>
<translation>Internal error</translation>
</message>
@@ -4548,7 +4526,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin
<context>
<name>VpnConnection</name>
<message>
<location filename="../vpnconnection.cpp" line="409"/>
<location filename="../vpnconnection.cpp" line="408"/>
<source>Mbps</source>
<translation>Mbps</translation>
</message>
@@ -4646,12 +4624,12 @@ This means that AmneziaWG keeps the fast performance of the original while addin
<context>
<name>main2</name>
<message>
<location filename="../ui/qml/main2.qml" line="163"/>
<location filename="../ui/qml/main2.qml" line="162"/>
<source>Private key passphrase</source>
<translation>Пароль для особистого ключа</translation>
</message>
<message>
<location filename="../ui/qml/main2.qml" line="186"/>
<location filename="../ui/qml/main2.qml" line="185"/>
<source>Save</source>
<translation>Зберегти</translation>
</message>

View File

@@ -89,60 +89,60 @@
<name>ConnectionController</name>
<message>
<location filename="../ui/controllers/connectionController.h" line="80"/>
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
<source>Connect</source>
<translation>جوڑنا</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="212"/>
<location filename="../ui/controllers/connectionController.cpp" line="209"/>
<source>The selected protocol is not supported on the current platform</source>
<translation>منتخب کردہ پروٹوکول موجودہ پلیٹ فارم پر تعاون یافتہ نہیں ہے</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
<source>VPN Protocols is not installed.
Please install VPN container at first</source>
<translation>وی پی این پروٹوکول انسٹال نہیں ہے,براہ کرم پہلےوی پی این کنٹینر انسٹال کریں</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
<source>unable to create configuration</source>
<translation>تشکیل تیار کرنے میں ناکام</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
<source>Connecting...</source>
<translation>جوڑاجارھاھے....</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
<source>Connected</source>
<translation>جوڑاجارھاھے</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
<source>Reconnecting...</source>
<translation>دوبارہ جوڑنےکی کوشش...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
<source>Disconnecting...</source>
<translation>منقطع کرنا...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
<source>Preparing...</source>
<translation>تیاری کیا جا رہا ہے...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
<source>Settings updated successfully, reconnnection...</source>
<translation>ترتیب ک ھوگی،دوبارہ جوڑنےکی کوشش...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
<source>Settings updated successfully</source>
<translation>دوبارہ ترتیب تاذہ کامیاب</translation>
</message>
@@ -252,20 +252,23 @@ Can&apos;t be disabled for current server</source>
<context>
<name>ImportController</name>
<message>
<location filename="../ui/controllers/importController.cpp" line="87"/>
<source>Unable to open file</source>
<translation type="vanished">فائل کو کھولنے سے قاصر ہے</translation>
<translation>فائل کو کھولنے سے قاصر ہے</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="187"/>
<location filename="../ui/controllers/importController.cpp" line="192"/>
<source>Invalid configuration file</source>
<translation type="vanished">غلط کنفیگریشن فائل</translation>
<translation>غلط کنفیگریشن فائل</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="623"/>
<location filename="../ui/controllers/importController.cpp" line="617"/>
<source>Scanned %1 of %2.</source>
<translation>سکین%1 کی%2.</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="658"/>
<location filename="../ui/controllers/importController.cpp" line="652"/>
<source>In the imported configuration, potentially dangerous lines were found:</source>
<translation type="unfinished"></translation>
</message>
@@ -273,86 +276,86 @@ Can&apos;t be disabled for current server</source>
<context>
<name>InstallController</name>
<message>
<location filename="../ui/controllers/installController.cpp" line="157"/>
<location filename="../ui/controllers/installController.cpp" line="181"/>
<source>%1 installed successfully. </source>
<translation>%1 کامیابی سےنصب. </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="159"/>
<location filename="../ui/controllers/installController.cpp" line="183"/>
<source>%1 is already installed on the server. </source>
<translation>%1 پہلے ہی سرور پر انسٹال ہے. </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="179"/>
<location filename="../ui/controllers/installController.cpp" line="203"/>
<source>
Added containers that were already installed on the server</source>
<translation>
وہ کنٹینرز شامل کیے گئے جو پہلے سے سرور پر نصب تھے</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="259"/>
<location filename="../ui/controllers/installController.cpp" line="283"/>
<source>
Already installed containers were found on the server. All installed containers have been added to the application</source>
<translation>
سرور پر پہلے سے نصب کنٹینرز پائے گئے۔ تمام نصب کنٹینرز کو ایپلی کیشن میں شامل کر دیا گیا ہے</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="517"/>
<location filename="../ui/controllers/installController.cpp" line="541"/>
<source>Settings updated successfully</source>
<translation>ترتیب کامیابی کے ساتھ اپ ڈیٹ ہو گئی</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="534"/>
<location filename="../ui/controllers/installController.cpp" line="558"/>
<source>Server &apos;%1&apos; was rebooted</source>
<translation>سرور %1 دوبارہ چالو کیا گیا تھا</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="546"/>
<location filename="../ui/controllers/installController.cpp" line="570"/>
<source>Server &apos;%1&apos; was removed</source>
<translation>سرور %1 ہٹا دیا گیا تھا</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="557"/>
<location filename="../ui/controllers/installController.cpp" line="581"/>
<source>All containers from server &apos;%1&apos; have been removed</source>
<translation>سرور &apos;%1&apos; سے تمام کنٹینرز ہٹا دیے گئے ہیں</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="575"/>
<location filename="../ui/controllers/installController.cpp" line="599"/>
<source>%1 has been removed from the server &apos;%2&apos;</source>
<translation>سرور &apos;%2&apos; سے %1 ہٹا دیا گیا ہے</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="584"/>
<location filename="../ui/controllers/installController.cpp" line="608"/>
<source>Api config removed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="606"/>
<location filename="../ui/controllers/installController.cpp" line="630"/>
<source>%1 cached profile cleared</source>
<translation>%1 کیش کردہ پروفائل ختم کر دی گئی</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="745"/>
<location filename="../ui/controllers/installController.cpp" line="769"/>
<source>Please login as the user</source>
<translation>براہ کرم صارف کے طور پر لاگ ان کریں</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="773"/>
<location filename="../ui/controllers/installController.cpp" line="797"/>
<source>Server added successfully</source>
<translation>سرور کامیابی سے شامل کیا گیا</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="821"/>
<location filename="../ui/controllers/installController.cpp" line="845"/>
<source>%1 installed successfully.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="855"/>
<location filename="../ui/controllers/installController.cpp" line="877"/>
<source>API config reloaded</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="859"/>
<location filename="../ui/controllers/installController.cpp" line="881"/>
<source>Successfully changed the country of connection to %1</source>
<translation type="unfinished"></translation>
</message>
@@ -396,30 +399,30 @@ Already installed containers were found on the server. All installed containers
<context>
<name>NotificationHandler</name>
<message>
<location filename="../ui/notificationhandler.cpp" line="64"/>
<location filename="../ui/notificationhandler.cpp" line="71"/>
<location filename="../ui/notificationhandler.cpp" line="63"/>
<location filename="../ui/notificationhandler.cpp" line="70"/>
<source>AmneziaVPN</source>
<translation>The translation of &quot;AmneziaVPN&quot; in Urdu would be:
امنیزیا وی پی ای</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="65"/>
<location filename="../ui/notificationhandler.cpp" line="64"/>
<source>VPN Connected</source>
<translation>وی پی این متصل ہوگیا</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="72"/>
<location filename="../ui/notificationhandler.cpp" line="71"/>
<source>VPN Disconnected</source>
<translation>وی پی این منقطع ہوگیا</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="95"/>
<location filename="../ui/notificationhandler.cpp" line="94"/>
<source>AmneziaVPN notification</source>
<translation>امنیزیا وی پی این کی اطلاعات</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="96"/>
<location filename="../ui/notificationhandler.cpp" line="95"/>
<source>Unsecured network detected: </source>
<translation>غیر محفوظ نیٹ ورک کا پتہ لگایا گیا ہے: </translation>
</message>
@@ -2383,107 +2386,97 @@ Already installed containers were found on the server. All installed containers
<translation type="vanished">کنکشن کی ترتیبات یا بیک اپ والی فائل</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
<source>Connection</source>
<translation type="unfinished">کنکشن</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
<source>Settings</source>
<translation type="unfinished">ترتیبات</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
<source>Enable logs</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
<source>Support tag</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Copied</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
<source>Insert the key, add a configuration file or scan the QR-code</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
<source>Insert key</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Insert</source>
<translation type="unfinished">داخل کریں</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
<source>Continue</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/>
<source>Other connection options</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/>
<source>VPN by Amnezia</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/>
<source>Connect to classic paid and free VPN services from Amnezia</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/>
<source>Self-hosted VPN</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/>
<source>Configure Amnezia VPN on your own server</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/>
<source>Restore from backup</source>
<translation type="unfinished">بیک اپ سے بحال کریں</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/>
<source>Open backup file</source>
<translation type="unfinished">بیک اپ فائل کو کھولیں</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<source>Backup files (*.backup)</source>
<translation type="unfinished">بیک اپ فائلیں (*.backup)</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/>
<source>File with connection settings</source>
<translation>کنکشن کی ترتیبات والی فائل</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/>
<source>Open config file</source>
<translation>کنفیگ فائل کو کھولیں</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
<source>QR code</source>
<translation>QR کوڈ</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/>
<source>I have nothing</source>
<translation type="unfinished">میرے پاس کچھ نہیں ہے</translation>
</message>
@@ -2505,12 +2498,12 @@ Already installed containers were found on the server. All installed containers
<translation>سرور آئی پی پتہ [:پورٹ]</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
<source>Continue</source>
<translation>براہ کرم جاری رکھیں</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>آپ جو ڈیٹا داخل کریں گے وہ بالکل خفیہ رہے گا اور نہ تو امنیزیا یا کسی تیسری شخصیت کے ساتھ اشتراک کیا جائے گا</translation>
</message>
@@ -2520,42 +2513,42 @@ Already installed containers were found on the server. All installed containers
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
<source>SSH Username</source>
<translation>ایس ایس ایچ صارف نام</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
<source>Password or SSH private key</source>
<translation>پاس ورڈ یا SSH نجی کلید</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
<source>How to run your VPN server</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
<source>Ip address cannot be empty</source>
<translation>آئی پی پتہ خالی نہیں ہو سکتا</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
<source>Enter the address in the format 255.255.255.255:88</source>
<translation>ایڈریس درج کریں فارمیٹ 255.255.255.255:88</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
<source>Login cannot be empty</source>
<translation>لاگ ان نام خالی نہیں ہو سکتا</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
<source>Password/private key cannot be empty</source>
<translation>پاس ورڈ یا نجی کلید خالی نہیں ہو سکتی</translation>
</message>
@@ -2868,71 +2861,66 @@ Already installed containers were found on the server. All installed containers
<translation>تلاش</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/>
<source>Creation date: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/>
<source>Latest handshake: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/>
<source>Data received: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/>
<source>Data sent: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
<source>Allowed IPs: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Creation date: </source>
<translation type="vanished">تخلیق کی تاریخ: </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
<source>Rename</source>
<translation>نام تبدیل</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
<source>Client name</source>
<translation>کلائنٹ کا نام</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
<source>Save</source>
<translation>محفوظ</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
<source>Revoke</source>
<translation>واپس لین</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
<source>Revoke the config for a user - %1?</source>
<translation>کیا آپ مستعمل کے لئے کنفیگ کو واپس لینا چاہتے ہیں - %1؟</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<source>The user will no longer be able to connect to your server.</source>
<translation>صارف آپ کے سرور سے متصل ہونے کا اختیار نہیں رہے گا.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
<source>Continue</source>
<translation>جاری رکھیں</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
<source>Cancel</source>
<translation>منسوخ</translation>
</message>
@@ -3050,17 +3038,17 @@ Already installed containers were found on the server. All installed containers
<context>
<name>PageStart</name>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/>
<source>Logging was disabled after 14 days, log files were deleted</source>
<translation>لاگنگ کو 14 دنوں کے بعد غیر فعال کر دیا گیا، لاگ فائلوں کو حذف کر دیا گیا</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<source>Settings restored from backup file</source>
<translation type="unfinished">ترتیبات بیک اپ فائل سے بحال کردی گئی ہیں</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/>
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
<translation type="unfinished"></translation>
</message>
@@ -3399,22 +3387,22 @@ Already installed containers were found on the server. All installed containers
<translation>سرور سے منسلک ہونے کا ٹائم آؤٹ</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="56"/>
<location filename="../core/errorstrings.cpp" line="55"/>
<source>VPN connection error</source>
<translation>VPN کنکشن کی خرابی</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="59"/>
<location filename="../core/errorstrings.cpp" line="58"/>
<source>Error when retrieving configuration from API</source>
<translation>آپی سے کنفیگریشن بازیافت کرتے وقت خرابی</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="60"/>
<location filename="../core/errorstrings.cpp" line="59"/>
<source>This config has already been added to the application</source>
<translation>یہ تشکیل پہلے ہی ایپلی کیشن میں شامل کی جا چکی ہے</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="80"/>
<location filename="../core/errorstrings.cpp" line="78"/>
<source>ErrorCode: %1. </source>
<translation>ایرر کوڈ: %1. </translation>
</message>
@@ -3489,67 +3477,57 @@ Already installed containers were found on the server. All installed containers
<translation>ترتیب میں سرور سے منسلک ہونے کے لیے کوئی کنٹینرز اور اسناد نہیں ہیں</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="53"/>
<source>Unable to open config file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="61"/>
<location filename="../core/errorstrings.cpp" line="60"/>
<source>In the response from the server, an empty config was received</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="62"/>
<location filename="../core/errorstrings.cpp" line="61"/>
<source>SSL error occurred</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="63"/>
<location filename="../core/errorstrings.cpp" line="62"/>
<source>Server response timeout on api request</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="64"/>
<location filename="../core/errorstrings.cpp" line="63"/>
<source>Missing AGW public key</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="65"/>
<source>Failed to decrypt response payload</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="68"/>
<location filename="../core/errorstrings.cpp" line="66"/>
<source>QFile error: The file could not be opened</source>
<translation>QFile کی خرابی: فائل کو نہیں کھولا جا سکا</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="69"/>
<location filename="../core/errorstrings.cpp" line="67"/>
<source>QFile error: An error occurred when reading from the file</source>
<translation>کیو فائل کی خرابی: فائل سے پڑھتے وقت ایک خرابی پیش آگئی</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="70"/>
<location filename="../core/errorstrings.cpp" line="68"/>
<source>QFile error: The file could not be accessed</source>
<translation>QFile کی خرابی: فائل تک رسائی نہیں ہو سکی</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="71"/>
<location filename="../core/errorstrings.cpp" line="69"/>
<source>QFile error: An unspecified error occurred</source>
<translation>کیو فائل میں خرابی: ایک غیر متعینہ خرابی پیش آگئی</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="72"/>
<location filename="../core/errorstrings.cpp" line="70"/>
<source>QFile error: A fatal error occurred</source>
<translation>کیو فائل میں خرابی: ایک مہلک خرابی پیش آگئی</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="73"/>
<location filename="../core/errorstrings.cpp" line="71"/>
<source>QFile error: The operation was aborted</source>
<translation>کیو فائل کی خرابی: آپریشن روک دیا گیا تھا</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="77"/>
<location filename="../core/errorstrings.cpp" line="75"/>
<source>Internal error</source>
<translation>داخلی خامی</translation>
</message>
@@ -4090,7 +4068,7 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<context>
<name>VpnConnection</name>
<message>
<location filename="../vpnconnection.cpp" line="409"/>
<location filename="../vpnconnection.cpp" line="408"/>
<source>Mbps</source>
<translation>ایم بی پی ایس</translation>
</message>
@@ -4176,12 +4154,12 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<context>
<name>main2</name>
<message>
<location filename="../ui/qml/main2.qml" line="163"/>
<location filename="../ui/qml/main2.qml" line="162"/>
<source>Private key passphrase</source>
<translation>نجی کلید پاس فریز</translation>
</message>
<message>
<location filename="../ui/qml/main2.qml" line="186"/>
<location filename="../ui/qml/main2.qml" line="185"/>
<source>Save</source>
<translation>محفوظ کریں</translation>
</message>

View File

@@ -89,60 +89,60 @@
<name>ConnectionController</name>
<message>
<location filename="../ui/controllers/connectionController.h" line="80"/>
<location filename="../ui/controllers/connectionController.cpp" line="103"/>
<location filename="../ui/controllers/connectionController.cpp" line="118"/>
<location filename="../ui/controllers/connectionController.cpp" line="124"/>
<location filename="../ui/controllers/connectionController.cpp" line="100"/>
<location filename="../ui/controllers/connectionController.cpp" line="115"/>
<location filename="../ui/controllers/connectionController.cpp" line="121"/>
<source>Connect</source>
<translation></translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="217"/>
<location filename="../ui/controllers/connectionController.cpp" line="214"/>
<source>VPN Protocols is not installed.
Please install VPN container at first</source>
<translation>VPN协议</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="84"/>
<location filename="../ui/controllers/connectionController.cpp" line="81"/>
<source>Connecting...</source>
<translation></translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="89"/>
<location filename="../ui/controllers/connectionController.cpp" line="86"/>
<source>Connected</source>
<translation></translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="98"/>
<location filename="../ui/controllers/connectionController.cpp" line="95"/>
<source>Reconnecting...</source>
<translation></translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="108"/>
<location filename="../ui/controllers/connectionController.cpp" line="105"/>
<source>Disconnecting...</source>
<translation></translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="113"/>
<location filename="../ui/controllers/connectionController.cpp" line="110"/>
<source>Preparing...</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
<location filename="../ui/controllers/connectionController.cpp" line="132"/>
<source>Settings updated successfully, reconnnection...</source>
<translation>, ...</translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="138"/>
<location filename="../ui/controllers/connectionController.cpp" line="135"/>
<source>Settings updated successfully</source>
<translation></translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="212"/>
<location filename="../ui/controllers/connectionController.cpp" line="209"/>
<source>The selected protocol is not supported on the current platform</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/controllers/connectionController.cpp" line="236"/>
<location filename="../ui/controllers/connectionController.cpp" line="233"/>
<source>unable to create configuration</source>
<translation type="unfinished"></translation>
</message>
@@ -257,12 +257,23 @@ Can&apos;t be disabled for current server</source>
<context>
<name>ImportController</name>
<message>
<location filename="../ui/controllers/importController.cpp" line="623"/>
<location filename="../ui/controllers/importController.cpp" line="87"/>
<source>Unable to open file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="187"/>
<location filename="../ui/controllers/importController.cpp" line="192"/>
<source>Invalid configuration file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="617"/>
<source>Scanned %1 of %2.</source>
<translation> %1 of %2.</translation>
</message>
<message>
<location filename="../ui/controllers/importController.cpp" line="658"/>
<location filename="../ui/controllers/importController.cpp" line="652"/>
<source>In the imported configuration, potentially dangerous lines were found:</source>
<translation type="unfinished"></translation>
</message>
@@ -278,75 +289,75 @@ Can&apos;t be disabled for current server</source>
<translation type="obsolete"> </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="157"/>
<location filename="../ui/controllers/installController.cpp" line="181"/>
<source>%1 installed successfully. </source>
<translation>%1 </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="159"/>
<location filename="../ui/controllers/installController.cpp" line="183"/>
<source>%1 is already installed on the server. </source>
<translation> %1</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="179"/>
<location filename="../ui/controllers/installController.cpp" line="203"/>
<source>
Added containers that were already installed on the server</source>
<translation></translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="259"/>
<location filename="../ui/controllers/installController.cpp" line="283"/>
<source>
Already installed containers were found on the server. All installed containers have been added to the application</source>
<translation>
</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="517"/>
<location filename="../ui/controllers/installController.cpp" line="541"/>
<source>Settings updated successfully</source>
<translation></translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="534"/>
<location filename="../ui/controllers/installController.cpp" line="558"/>
<source>Server &apos;%1&apos; was rebooted</source>
<translation> &apos;%1&apos; </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="546"/>
<location filename="../ui/controllers/installController.cpp" line="570"/>
<source>Server &apos;%1&apos; was removed</source>
<translation> &apos;%1&apos;</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="557"/>
<location filename="../ui/controllers/installController.cpp" line="581"/>
<source>All containers from server &apos;%1&apos; have been removed</source>
<translation> &apos;%1&apos; </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="575"/>
<location filename="../ui/controllers/installController.cpp" line="599"/>
<source>%1 has been removed from the server &apos;%2&apos;</source>
<translation>%1 &apos;%2&apos; </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="584"/>
<location filename="../ui/controllers/installController.cpp" line="608"/>
<source>Api config removed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="606"/>
<location filename="../ui/controllers/installController.cpp" line="630"/>
<source>%1 cached profile cleared</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="821"/>
<location filename="../ui/controllers/installController.cpp" line="845"/>
<source>%1 installed successfully.</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="855"/>
<location filename="../ui/controllers/installController.cpp" line="877"/>
<source>API config reloaded</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="859"/>
<location filename="../ui/controllers/installController.cpp" line="881"/>
<source>Successfully changed the country of connection to %1</source>
<translation type="unfinished"></translation>
</message>
@@ -367,12 +378,12 @@ Already installed containers were found on the server. All installed containers
<translation type="obsolete"> </translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="745"/>
<location filename="../ui/controllers/installController.cpp" line="769"/>
<source>Please login as the user</source>
<translation></translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="773"/>
<location filename="../ui/controllers/installController.cpp" line="797"/>
<source>Server added successfully</source>
<translation></translation>
</message>
@@ -416,28 +427,28 @@ Already installed containers were found on the server. All installed containers
<context>
<name>NotificationHandler</name>
<message>
<location filename="../ui/notificationhandler.cpp" line="64"/>
<location filename="../ui/notificationhandler.cpp" line="71"/>
<location filename="../ui/notificationhandler.cpp" line="63"/>
<location filename="../ui/notificationhandler.cpp" line="70"/>
<source>AmneziaVPN</source>
<translation></translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="65"/>
<location filename="../ui/notificationhandler.cpp" line="64"/>
<source>VPN Connected</source>
<translation>VPN</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="72"/>
<location filename="../ui/notificationhandler.cpp" line="71"/>
<source>VPN Disconnected</source>
<translation>VPN断开</translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="95"/>
<location filename="../ui/notificationhandler.cpp" line="94"/>
<source>AmneziaVPN notification</source>
<translation>AmneziaVPN </translation>
</message>
<message>
<location filename="../ui/notificationhandler.cpp" line="96"/>
<location filename="../ui/notificationhandler.cpp" line="95"/>
<source>Unsecured network detected: </source>
<translation></translation>
</message>
@@ -2538,107 +2549,97 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="59"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="57"/>
<source>Connection</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="86"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="83"/>
<source>Settings</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="96"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="91"/>
<source>Enable logs</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="112"/>
<source>Support tag</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Copied</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="140"/>
<source>Insert the key, add a configuration file or scan the QR-code</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="150"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="122"/>
<source>Insert key</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="151"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="123"/>
<source>Insert</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="171"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="143"/>
<source>Continue</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="189"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="161"/>
<source>Other connection options</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="200"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="172"/>
<source>VPN by Amnezia</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="201"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="173"/>
<source>Connect to classic paid and free VPN services from Amnezia</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="196"/>
<source>Self-hosted VPN</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="225"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="197"/>
<source>Configure Amnezia VPN on your own server</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="245"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="217"/>
<source>Restore from backup</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="251"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="223"/>
<source>Open backup file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="252"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="224"/>
<source>Backup files (*.backup)</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="269"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="241"/>
<source>File with connection settings</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="277"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="249"/>
<source>Open config file</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="296"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="268"/>
<source>QR code</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="319"/>
<location filename="../ui/qml/Pages2/PageSetupWizardConfigSource.qml" line="291"/>
<source>I have nothing</source>
<translation type="unfinished"></translation>
</message>
@@ -2672,12 +2673,12 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="vanished"> </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="113"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="116"/>
<source>Continue</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="141"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="144"/>
<source>All data you enter will remain strictly confidential and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation> Amnezia </translation>
</message>
@@ -2693,42 +2694,42 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="75"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="78"/>
<source>SSH Username</source>
<translation>SSH </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="91"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="94"/>
<source>Password or SSH private key</source>
<translation> SSH </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="150"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="153"/>
<source>How to run your VPN server</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="151"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="154"/>
<source>Where to get connection data, step-by-step instructions for buying a VPS</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="167"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
<source>Ip address cannot be empty</source>
<translation>IP不能为空</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="170"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="173"/>
<source>Enter the address in the format 255.255.255.255:88</source>
<translation> 255.255.255.255:88</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="174"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="177"/>
<source>Login cannot be empty</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="178"/>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="181"/>
<source>Password/private key cannot be empty</source>
<translation></translation>
</message>
@@ -3066,71 +3067,66 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="814"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="817"/>
<source>Creation date: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="822"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="825"/>
<source>Latest handshake: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="830"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="833"/>
<source>Data received: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="838"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="841"/>
<source>Data sent: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="846"/>
<source>Allowed IPs: %1</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Creation date: </source>
<translation type="vanished">: </translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="866"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="862"/>
<source>Rename</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="912"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="908"/>
<source>Client name</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="925"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="921"/>
<source>Save</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="955"/>
<source>Revoke</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="964"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="959"/>
<source>Revoke the config for a user - %1?</source>
<translation>- %1?</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="965"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="960"/>
<source>The user will no longer be able to connect to your server.</source>
<translation>.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="966"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="961"/>
<source>Continue</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="967"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="962"/>
<source>Cancel</source>
<translation></translation>
</message>
@@ -3287,17 +3283,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<context>
<name>PageStart</name>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="198"/>
<source>Logging was disabled after 14 days, log files were deleted</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="206"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="202"/>
<source>Settings restored from backup file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageStart.qml" line="212"/>
<location filename="../ui/qml/Pages2/PageStart.qml" line="208"/>
<source>Logging is enabled. Note that logs will be automaticallydisabled after 14 days, and all log files will be deleted.</source>
<translation type="unfinished"></translation>
</message>
@@ -3650,11 +3646,6 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<source>SCP error: Generic failure</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="53"/>
<source>Unable to open config file</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Sftp error: End-of-file encountered</source>
<translation type="vanished">Sftp错误: End-of-file encountered</translation>
@@ -3708,77 +3699,72 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation type="vanished">Sftp 错误: 远程驱动器中没有媒介</translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="56"/>
<location filename="../core/errorstrings.cpp" line="55"/>
<source>VPN connection error</source>
<translation>VPN </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="59"/>
<location filename="../core/errorstrings.cpp" line="58"/>
<source>Error when retrieving configuration from API</source>
<translation> API </translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="60"/>
<location filename="../core/errorstrings.cpp" line="59"/>
<source>This config has already been added to the application</source>
<translation></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="61"/>
<location filename="../core/errorstrings.cpp" line="60"/>
<source>In the response from the server, an empty config was received</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="62"/>
<location filename="../core/errorstrings.cpp" line="61"/>
<source>SSL error occurred</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="63"/>
<location filename="../core/errorstrings.cpp" line="62"/>
<source>Server response timeout on api request</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="64"/>
<location filename="../core/errorstrings.cpp" line="63"/>
<source>Missing AGW public key</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="65"/>
<source>Failed to decrypt response payload</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="68"/>
<location filename="../core/errorstrings.cpp" line="66"/>
<source>QFile error: The file could not be opened</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="69"/>
<location filename="../core/errorstrings.cpp" line="67"/>
<source>QFile error: An error occurred when reading from the file</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="70"/>
<location filename="../core/errorstrings.cpp" line="68"/>
<source>QFile error: The file could not be accessed</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="71"/>
<location filename="../core/errorstrings.cpp" line="69"/>
<source>QFile error: An unspecified error occurred</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="72"/>
<location filename="../core/errorstrings.cpp" line="70"/>
<source>QFile error: A fatal error occurred</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="73"/>
<location filename="../core/errorstrings.cpp" line="71"/>
<source>QFile error: The operation was aborted</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="80"/>
<location filename="../core/errorstrings.cpp" line="78"/>
<source>ErrorCode: %1. </source>
<translation>: %1. </translation>
</message>
@@ -3846,7 +3832,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../core/errorstrings.cpp" line="77"/>
<location filename="../core/errorstrings.cpp" line="75"/>
<source>Internal error</source>
<translation></translation>
</message>
@@ -4526,7 +4512,7 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<context>
<name>VpnConnection</name>
<message>
<location filename="../vpnconnection.cpp" line="409"/>
<location filename="../vpnconnection.cpp" line="408"/>
<source>Mbps</source>
<translation></translation>
</message>
@@ -4624,12 +4610,12 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<context>
<name>main2</name>
<message>
<location filename="../ui/qml/main2.qml" line="163"/>
<location filename="../ui/qml/main2.qml" line="162"/>
<source>Private key passphrase</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/main2.qml" line="186"/>
<location filename="../ui/qml/main2.qml" line="185"/>
<source>Save</source>
<translation></translation>
</message>

View File

@@ -24,7 +24,7 @@ PageController::PageController(const QSharedPointer<ServersModel> &serversModel,
AndroidController::instance()->setNavigationBarColor(initialPageNavigationBarColor);
#endif
#if defined Q_OS_MACX and !defined MACOS_NE
#if defined Q_OS_MACX
connect(this, &PageController::raiseMainWindow, []() { setDockIconVisible(true); });
connect(this, &PageController::hideMainWindow, []() { setDockIconVisible(false); });
#endif
@@ -114,7 +114,7 @@ void PageController::showOnStartup()
} else {
#if defined(Q_OS_WIN) || (defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID))
emit hideMainWindow();
#elif defined Q_OS_MACX and !defined MACOS_NE
#elif defined Q_OS_MACX
setDockIconVisible(false);
#endif
}

View File

@@ -5,13 +5,12 @@
#include <QDebug>
#include "notificationhandler.h"
#if defined(Q_OS_IOS) || defined(MACOS_NE)
#if defined(Q_OS_IOS)
# include "platforms/ios/iosnotificationhandler.h"
#else
# include "systemtray_notificationhandler.h"
#endif
// static
NotificationHandler* NotificationHandler::create(QObject* parent) {
#if defined(Q_OS_IOS)

View File

@@ -23,6 +23,7 @@ Options:
By default, the latest available platform is used
-m, --move Move the build result to the root of the build directory
-f, --fdroid Build for F-Droid
-p, --play Build AAB for Google Play
-h, --help Display this help
EOT
@@ -30,7 +31,7 @@ EOT
BUILD_TYPE="release"
opts=$(getopt -l debug,aab,apk:,build-platform:,move,fdroid,help -o "dua:b:mfh" -- "$@")
opts=$(getopt -l debug,aab,apk:,build-platform:,move,fdroid,play,help -o "dua:b:mfph" -- "$@")
eval set -- "$opts"
while true; do
case "$1" in
@@ -40,6 +41,7 @@ while true; do
-b | --build-platform) ANDROID_BUILD_PLATFORM=$2; shift 2;;
-m | --move) MOVE_RESULT=1; shift;;
-f | --fdroid) FDROID=1; shift;;
-p | --play) PLAY=1; shift;;
-h | --help) usage; exit 0;;
--) shift; break;;
esac
@@ -149,11 +151,17 @@ if [ -v FDROID ]; then
BUILD_TYPE="fdroid"
fi
if [ -v PLAY ]; then
AAB_FLAVOR="play"
else
AAB_FLAVOR="oss"
fi
if [ -v AAB ]; then
gradle_opts+=(bundle"${BUILD_TYPE^}")
gradle_opts+=(bundle"${AAB_FLAVOR^}${BUILD_TYPE^}")
fi
if [ -v ABIS ]; then
gradle_opts+=(assemble"${BUILD_TYPE^}")
gradle_opts+=(assembleOss"${BUILD_TYPE^}")
fi
$OUT_APP_DIR/android-build/gradlew \
@@ -164,7 +172,7 @@ $OUT_APP_DIR/android-build/gradlew \
if [[ -v CI || -v MOVE_RESULT ]]; then
echo "Moving APK/AAB..."
if [ -v AAB ]; then
mv -u $OUT_APP_DIR/android-build/build/outputs/bundle/$BUILD_TYPE/AmneziaVPN-$BUILD_TYPE.aab \
mv -u $OUT_APP_DIR/android-build/build/outputs/bundle/$AAB_FLAVOR"${BUILD_TYPE^}"/AmneziaVPN-$AAB_FLAVOR-$BUILD_TYPE.aab \
$PROJECT_DIR/deploy/build/
fi
@@ -181,7 +189,7 @@ if [[ -v CI || -v MOVE_RESULT ]]; then
IFS=';' read -r -a abi_array <<< "$ABIS"
for ABI in "${abi_array[@]}"
do
mv -u $OUT_APP_DIR/android-build/build/outputs/apk/$BUILD_TYPE/AmneziaVPN-$ABI-$suffix.apk \
mv -u $OUT_APP_DIR/android-build/build/outputs/apk/oss/$BUILD_TYPE/AmneziaVPN-oss-$ABI-$suffix.apk \
$PROJECT_DIR/deploy/build/
done
fi

View File

@@ -1,134 +0,0 @@
#!/bin/bash
echo "Build script for macOS Network Extension started ..."
set -o errexit -o nounset
while getopts n flag
do
case "${flag}" in
n) NOTARIZE_APP=1;;
esac
done
# Hold on to current directory
PROJECT_DIR=$(pwd)
DEPLOY_DIR=$PROJECT_DIR/deploy
mkdir -p $DEPLOY_DIR/build
BUILD_DIR=$DEPLOY_DIR/build
echo "Project dir: ${PROJECT_DIR}"
echo "Build dir: ${BUILD_DIR}"
APP_NAME=AmneziaVPN
APP_FILENAME=$APP_NAME.app
APP_DOMAIN=org.amneziavpn.package
PLIST_NAME=$APP_NAME.plist
OUT_APP_DIR=$BUILD_DIR/client
BUNDLE_DIR=$OUT_APP_DIR/$APP_FILENAME
PREBUILT_DEPLOY_DATA_DIR=$PROJECT_DIR/deploy/data/deploy-prebuilt/macos
DEPLOY_DATA_DIR=$PROJECT_DIR/deploy/data/macos
INSTALLER_DATA_DIR=$BUILD_DIR/installer/packages/$APP_DOMAIN/data
INSTALLER_BUNDLE_DIR=$BUILD_DIR/installer/$APP_FILENAME
DMG_FILENAME=$PROJECT_DIR/${APP_NAME}.dmg
# Setup provisioning profiles for main app and NE
echo "Setting up provisioning profiles..."
# Tạo thư mục Provisioning Profiles nếu chưa tồn tại
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
# Setup provisioning profile cho main app
echo "Setting up provisioning profile for main app (AmneziaVPN)"
cp $PROJECT_DIR/deploy/AnhTVMacOSMain.provisionprofile ~/Library/MobileDevice/Provisioning\ Profiles/
macos_main_uuid=$(grep UUID -A1 -a ~/Library/MobileDevice/Provisioning\ Profiles/AnhTVMacOSMain.provisionprofile | grep -io "[-A-F0-9]\{36\}")
mv ~/Library/MobileDevice/Provisioning\ Profiles/AnhTVMacOSMain.provisionprofile ~/Library/MobileDevice/Provisioning\ Profiles/$macos_main_uuid.mobileprovision
# Setup provisioning profile cho Network Extension (NE)
echo "Setting up provisioning profile for Network Extension"
cp $PROJECT_DIR/deploy/AnhTVMacOSNE.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/macos_ne.mobileprovision
macos_ne_uuid=$(grep UUID -A1 -a ~/Library/MobileDevice/Provisioning\ Profiles/macos_ne.mobileprovision | grep -io "[-A-F0-9]\{36\}")
mv ~/Library/MobileDevice/Provisioning\ Profiles/macos_ne.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/$macos_ne_uuid.mobileprovision
# Decode and install signing certificates
echo "Installing signing certificates..."
echo $MAC_TRUST_CERT_BASE64 | base64 --decode > mac_trust_cert.pem
echo $MAC_SIGNING_CERT_BASE64 | base64 --decode > mac_signing_cert.p12
# Install certificates into keychain
security create-keychain -p password build.keychain
security default-keychain -s build.keychain
security unlock-keychain -p password build.keychain
security import mac_trust_cert.pem -k build.keychain -A
security import mac_signing_cert.p12 -k build.keychain -P $MAC_SIGNING_CERT_PASSWORD -A
# Establish the keychain settings for the signing process
security set-key-partition-list -S apple-tool:,apple: -s -k password build.keychain
# Check if QIF_VERSION is properly set, otherwise set a default
if [ -z "${QIF_VERSION+x}" ]; then
echo "QIF_VERSION is not set, using default 4.6"
QIF_VERSION=4.6
fi
QIF_BIN_DIR="$QT_BIN_DIR/../../../Tools/QtInstallerFramework/$QIF_VERSION/bin"
# Checking environment
$QT_BIN_DIR/qt-cmake --version || { echo "Error: qt-cmake not found in $QT_BIN_DIR"; exit 1; }
cmake --version || { echo "Error: cmake not found"; exit 1; }
clang -v || { echo "Error: clang not found"; exit 1; }
# Build the Network Extension app
echo "Building Network Extension App..."
mkdir -p build-macos-ne
cd build-macos-ne
$QT_BIN_DIR/qt-cmake .. -GXcode -DQT_HOST_PATH=$QT_MACOS_ROOT_DIR -DMACOS_NE=TRUE
cmake --build . --config release --target AmneziaVPN -- -allowProvisioningUpdates # Thay đổi target phù hợp cho Network Extension
# Build and run tests here
echo "____________________________________"
echo "............Deploy.................."
echo "____________________________________"
# Package Network Extension
echo "Packaging Network Extension ..."
# Copy necessary data
cp -Rv $PREBUILT_DEPLOY_DATA_DIR/* $BUNDLE_DIR/Contents/macOS
$QT_BIN_DIR/macdeployqt $OUT_APP_DIR/$APP_FILENAME -always-overwrite -qmldir=$PROJECT_DIR
cp -av $BUILD_DIR/service/server/$APP_NAME-service $BUNDLE_DIR/Contents/macOS
cp -Rv $PROJECT_DIR/deploy/data/macos/* $BUNDLE_DIR/Contents/macOS
# Signing and notarizing the Network Extension
if [ "${MAC_CERT_PW+x}" ]; then
CERTIFICATE_P12=$DEPLOY_DIR/PrivacyTechAppleCertDeveloperId.p12
WWDRCA=$DEPLOY_DIR/WWDRCA.cer
KEYCHAIN=amnezia.build.macos.keychain
TEMP_PASS=tmp_pass
security create-keychain -p $TEMP_PASS $KEYCHAIN || true
security default-keychain -s $KEYCHAIN
security unlock-keychain -p $TEMP_PASS $KEYCHAIN
security import $WWDRCA -k $KEYCHAIN -T /usr/bin/codesign || true
security import $CERTIFICATE_P12 -k $KEYCHAIN -P $MAC_CERT_PW -T /usr/bin/codesign || true
echo "Signing Network Extension..."
/usr/bin/codesign --deep --force --verbose --timestamp -o runtime --sign "$MAC_SIGNER_ID" $BUNDLE_DIR
spctl -a -vvvv $BUNDLE_DIR || true
if [ "${NOTARIZE_APP+x}" ]; then
echo "Notarizing Network Extension bundle..."
/usr/bin/ditto -c -k --keepParent $BUNDLE_DIR $PROJECT_DIR/NE_Bundle_to_notarize.zip
xcrun notarytool submit $PROJECT_DIR/NE_Bundle_to_notarize.zip --apple-id $APPLE_DEV_EMAIL --team-id $MAC_TEAM_ID --password $APPLE_DEV_PASSWORD
rm $PROJECT_DIR/NE_Bundle_to_notarize.zip
sleep 300
xcrun stapler staple $BUNDLE_DIR
spctl -a -vvvv $BUNDLE_DIR || true
fi
fi

View File

@@ -4,7 +4,7 @@ if(WIN32)
${CMAKE_CURRENT_LIST_DIR}/config/windows.xml.in
${CMAKE_BINARY_DIR}/installer/config/windows.xml
)
elseif(APPLE AND NOT IOS AND NOT MACOS_NE)
elseif(APPLE AND NOT IOS)
configure_file(
${CMAKE_CURRENT_LIST_DIR}/config/macos.xml.in
${CMAKE_BINARY_DIR}/installer/config/macos.xml

View File

@@ -6,6 +6,6 @@ project(${PROJECT})
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(NOT IOS AND NOT ANDROID AND NOT MACOS_NE)
if(NOT IOS AND NOT ANDROID)
add_subdirectory(server)
endif()