diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..50823d93
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "Submodules/API"]
+ path = Submodules/API
+ url = https://github.com/passepartoutvpn/api
+[submodule "Submodules/Core"]
+ path = Submodules/Core
+ url = https://github.com/passepartoutvpn/passepartout-core-apple
diff --git a/Libraries/API b/Libraries/API
new file mode 120000
index 00000000..b4015434
--- /dev/null
+++ b/Libraries/API
@@ -0,0 +1 @@
+../Submodules/API/
\ No newline at end of file
diff --git a/Libraries/Core b/Libraries/Core
new file mode 120000
index 00000000..01be531a
--- /dev/null
+++ b/Libraries/Core
@@ -0,0 +1 @@
+../Submodules/Core/
\ No newline at end of file
diff --git a/Passepartout-CoreTests/ConnectionService.json b/Passepartout-CoreTests/ConnectionService.json
deleted file mode 100644
index 142883f8..00000000
--- a/Passepartout-CoreTests/ConnectionService.json
+++ /dev/null
@@ -1 +0,0 @@
-{"appGroup":"group.com.algoritmico.Passepartout","activeProfileId":"host.edu","tunnelConfiguration":{"endpointProtocols":["UDP:1194"],"compressionFraming":0,"digest":"SHA1","ca":"","lastErrorKey":"LastVPNError","debugLogFormat":"$DHH:mm:ss$d - $M","usesPIAPatches":false,"cipher":"AES-128-CBC","prefersResolvedAddresses":false,"shouldDebug":true,"mtu":1250,"debugLogKey":"LastVPNLog"},"preferences":{"trustPolicy":"ignore","trustsMobileNetwork":false,"disconnectsOnSleep":false,"trustedWifis":{},"resolvesHostname":true},"profiles":[{"provider":{"username":"p0000000","id":"provider.PIA","poolId":"ca-vancouver","name":"PIA","presetId":"recommended"}},{"host":{"username":"","title":"edu","hostname":"1.2.4.5","parameters":{"endpointProtocols":["UDP:1194","TCP:1194","TCP:443"],"compressionFraming":1,"digest":"SHA256","ca":"bogus+ca","clientCertificate":"bogus+client","usesPIAPatches":false,"tlsWrap":{"key":{"dir":1,"data":"bogus+static+key"},"strategy":"auth"},"cipher":"AES-256-CBC","prefersResolvedAddresses":false,"clientKey":"bogus+key","mtu":1500,"shouldDebug":false}}},{"host":{"username":"","title":"vps-udp-tc","hostname":"8.8.4.4","parameters":{"shouldDebug":false,"endpointProtocols":["UDP:1198"],"compressionFraming":1,"digest":"SHA512","ca":"bogus+ca","renegotiatesAfterSeconds":0,"usesPIAPatches":false,"tlsWrap":{"key":{"dir":1,"data":"bogus+static+key"},"strategy":"crypt"},"cipher":"AES-192-CBC","prefersResolvedAddresses":false,"clientKey":"bogus+key","mtu":1500,"keepAliveSeconds":25}}}]}
diff --git a/Passepartout-CoreTests/ConnectionServiceTests.swift b/Passepartout-CoreTests/ConnectionServiceTests.swift
deleted file mode 100644
index 0be1019a..00000000
--- a/Passepartout-CoreTests/ConnectionServiceTests.swift
+++ /dev/null
@@ -1,64 +0,0 @@
-//
-// ConnectionServiceTests.swift
-// Passepartout-CoreTests
-//
-// Created by Davide De Rosa on 10/25/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import XCTest
-import TunnelKit
-@testable import Passepartout_Core
-
-class ConnectionServiceTests: XCTestCase {
- let url = Bundle(for: ConnectionServiceTests.self).url(forResource: "ConnectionService", withExtension: "json")!
-
- override func setUp() {
- // Put setup code here. This method is called before the invocation of each test method in the class.
- }
-
- override func tearDown() {
- // Put teardown code here. This method is called after the invocation of each test method in the class.
- }
-
- func testParse() {
- let jsonData = try! Data(contentsOf: url)
- XCTAssertNoThrow(try JSONSerialization.jsonObject(with: jsonData, options: []))
- }
-
- func testPathExtension() {
- XCTAssertTrue(privateTestPathExtension("file:///foo/bar/johndoe.json"))
- XCTAssertFalse(privateTestPathExtension("file:///foo/bar/break.json.johndoe.json"))
- }
-
- private func privateTestPathExtension(_ string: String) -> Bool {
- let url = URL(string: string)!
- let filename = url.lastPathComponent
- guard let extRange = filename.range(of: ".json") else {
- return false
- }
- guard url.pathExtension == "json" else {
- return false
- }
- let name1 = String(filename[filename.startIndex...
-//
-
-import XCTest
-@testable import Passepartout_Core
-import TunnelKit
-
-class InfrastructureTests: XCTestCase {
- private let infra = InfrastructureFactory.shared.get(.pia)
-
- override func setUp() {
- }
-
- override func tearDown() {
- // Put teardown code here. This method is called after the invocation of each test method in the class.
- }
-
- func testParsing() {
- print(infra.categories)
- XCTAssertEqual(infra.categories.count, 1)
- }
-
- func testIdentifier() {
- let id = "us-east"
- guard let pool = infra.pool(for: id) else {
- XCTAssert(false)
- return
- }
- print(pool)
- XCTAssertEqual(pool.id, id)
- }
-
- func testStableSort() {
- let original: [EndpointProtocol] = [
- EndpointProtocol(.udp, 1194),
- EndpointProtocol(.udp, 8080),
- EndpointProtocol(.udp, 9201),
- EndpointProtocol(.udp, 53),
- EndpointProtocol(.udp, 1197),
- EndpointProtocol(.udp, 198),
- EndpointProtocol(.tcp, 443),
- EndpointProtocol(.tcp, 110),
- EndpointProtocol(.tcp, 80),
- EndpointProtocol(.tcp, 500),
- EndpointProtocol(.tcp, 501),
- EndpointProtocol(.tcp, 502)
- ]
- var preferredType: SocketType
-
- preferredType = .udp
- let sorted1 = original.stableSorted {
- return ($0.socketType == preferredType) && ($1.socketType != preferredType)
- }
- XCTAssertEqual(sorted1, original)
-
- preferredType = .tcp
- let sorted2 = original.stableSorted {
- return ($0.socketType == preferredType) && ($1.socketType != preferredType)
- }
- XCTAssertNotEqual(sorted2, original)
- }
-}
diff --git a/Passepartout-CoreTests/UtilsTests.swift b/Passepartout-CoreTests/UtilsTests.swift
deleted file mode 100644
index 80ccc6a9..00000000
--- a/Passepartout-CoreTests/UtilsTests.swift
+++ /dev/null
@@ -1,69 +0,0 @@
-//
-// UtilsTests.swift
-// Passepartout-CoreTests
-//
-// Created by Davide De Rosa on 3/30/19.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import XCTest
-@testable import Passepartout_Core
-
-class UtilsTests: XCTestCase {
- override func setUp() {
- }
-
- override func tearDown() {
- // Put teardown code here. This method is called after the invocation of each test method in the class.
- }
-
- func testDataUnitDescription() {
- XCTAssertEqual(0.dataUnitDescription, "0B")
- XCTAssertEqual(1.dataUnitDescription, "1B")
- XCTAssertEqual(1024.dataUnitDescription, "1kB")
- XCTAssertEqual(1025.dataUnitDescription, "1kB")
- XCTAssertEqual(548575.dataUnitDescription, "0.52MB")
- XCTAssertEqual(1048575.dataUnitDescription, "1.00MB")
- XCTAssertEqual(1048576.dataUnitDescription, "1.00MB")
- XCTAssertEqual(1048577.dataUnitDescription, "1.00MB")
- XCTAssertEqual(600000000.dataUnitDescription, "0.56GB")
- XCTAssertEqual(1073741823.dataUnitDescription, "1.00GB")
- XCTAssertEqual(1073741824.dataUnitDescription, "1.00GB")
- XCTAssertEqual(1073741825.dataUnitDescription, "1.00GB")
- }
-
- func testLanguageLocalization() {
- let languages = ["en", "it", "de", "pt-BR", "ru"]
- let english = Locale(identifier: "en")
- let italian = Locale(identifier: "it")
-
- let languagesEN = privateSortedLanguages(languages, with: english)
- let languagesIT = privateSortedLanguages(languages, with: italian)
-
- XCTAssertEqual(languagesEN, ["en", "de", "it", "pt-BR", "ru"])
- XCTAssertEqual(languagesIT, ["en", "it", "pt-BR", "ru", "de"])
- }
-
- private func privateSortedLanguages(_ languages: [String], with locale: Locale) -> [String] {
- return languages.sorted {
- return locale.localizedString(forLanguageCode: $0)! < locale.localizedString(forLanguageCode: $1)!
- }
- }
-}
diff --git a/Passepartout-iOS-Tunnel/Info.plist b/Passepartout-iOS-Tunnel/Info.plist
index fabb8a2a..bc929fb2 100644
--- a/Passepartout-iOS-Tunnel/Info.plist
+++ b/Passepartout-iOS-Tunnel/Info.plist
@@ -17,7 +17,7 @@
CFBundlePackageType
XPC!
CFBundleShortVersionString
- 1.6.1
+ 1.7.0
CFBundleVersion
1
NSExtension
diff --git a/Passepartout-iOS/AppDelegate.swift b/Passepartout-iOS/AppDelegate.swift
index 466cf031..9db6c80f 100644
--- a/Passepartout-iOS/AppDelegate.swift
+++ b/Passepartout-iOS/AppDelegate.swift
@@ -25,7 +25,7 @@
import UIKit
import TunnelKit
-import Passepartout_Core
+import PassepartoutCore
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UISplitViewControllerDelegate {
diff --git a/Passepartout-iOS/Global/ConfigurationParserResult+Alerts.swift b/Passepartout-iOS/Global/ConfigurationParserResult+Alerts.swift
index 20746548..8077bbe5 100644
--- a/Passepartout-iOS/Global/ConfigurationParserResult+Alerts.swift
+++ b/Passepartout-iOS/Global/ConfigurationParserResult+Alerts.swift
@@ -27,7 +27,7 @@ import Foundation
import UIKit
import TunnelKit
import SwiftyBeaver
-import Passepartout_Core
+import PassepartoutCore
private let log = SwiftyBeaver.self
diff --git a/Passepartout-iOS/Global/Downloader.swift b/Passepartout-iOS/Global/Downloader.swift
index dd879794..3074838b 100644
--- a/Passepartout-iOS/Global/Downloader.swift
+++ b/Passepartout-iOS/Global/Downloader.swift
@@ -26,7 +26,7 @@
import Foundation
import MBProgressHUD
import SwiftyBeaver
-import Passepartout_Core
+import PassepartoutCore
private let log = SwiftyBeaver.self
diff --git a/Passepartout-iOS/Global/IssueReporter.swift b/Passepartout-iOS/Global/IssueReporter.swift
index 0d7ad96d..c638ba6a 100644
--- a/Passepartout-iOS/Global/IssueReporter.swift
+++ b/Passepartout-iOS/Global/IssueReporter.swift
@@ -26,7 +26,7 @@
import Foundation
import TunnelKit
import MessageUI
-import Passepartout_Core
+import PassepartoutCore
class IssueReporter: NSObject {
struct Attachments {
diff --git a/Passepartout-iOS/Global/Theme+Cells.swift b/Passepartout-iOS/Global/Theme+Cells.swift
index 2e2bc097..ef0e3d0f 100644
--- a/Passepartout-iOS/Global/Theme+Cells.swift
+++ b/Passepartout-iOS/Global/Theme+Cells.swift
@@ -25,7 +25,7 @@
import UIKit
import TunnelKit
-import Passepartout_Core
+import PassepartoutCore
extension UITableViewCell {
func applyChecked(_ checked: Bool, _ theme: Theme) {
diff --git a/Passepartout-iOS/Global/Theme.swift b/Passepartout-iOS/Global/Theme.swift
index f2c06b83..c6fa2826 100644
--- a/Passepartout-iOS/Global/Theme.swift
+++ b/Passepartout-iOS/Global/Theme.swift
@@ -26,7 +26,7 @@
import UIKit
import MessageUI
import StoreKit
-import Passepartout_Core
+import PassepartoutCore
extension UIColor {
convenience init(rgb: UInt32, alpha: CGFloat) {
diff --git a/Passepartout-iOS/Info.plist b/Passepartout-iOS/Info.plist
index a930e4a9..5233eba8 100644
--- a/Passepartout-iOS/Info.plist
+++ b/Passepartout-iOS/Info.plist
@@ -34,7 +34,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 1.6.1
+ 1.7.0
CFBundleVersion
1
ITSAppUsesNonExemptEncryption
diff --git a/Passepartout-iOS/Scenes/About/AboutViewController.swift b/Passepartout-iOS/Scenes/About/AboutViewController.swift
index a1ca82cc..48951ffb 100644
--- a/Passepartout-iOS/Scenes/About/AboutViewController.swift
+++ b/Passepartout-iOS/Scenes/About/AboutViewController.swift
@@ -24,7 +24,7 @@
//
import UIKit
-import Passepartout_Core
+import PassepartoutCore
class AboutViewController: UITableViewController, TableModelHost {
@@ -195,10 +195,10 @@ extension AboutViewController {
openCredits()
case .readme:
- visit(AppConstants.URLs.readme)
+ visit(AppConstants.URLs.iOS.readme)
case .changelog:
- visit(AppConstants.URLs.changelog)
+ visit(AppConstants.URLs.iOS.changelog)
case .website:
visit(AppConstants.URLs.website)
diff --git a/Passepartout-iOS/Scenes/About/CreditsViewController.swift b/Passepartout-iOS/Scenes/About/CreditsViewController.swift
index 60ff1929..cd76ece6 100644
--- a/Passepartout-iOS/Scenes/About/CreditsViewController.swift
+++ b/Passepartout-iOS/Scenes/About/CreditsViewController.swift
@@ -24,7 +24,7 @@
//
import UIKit
-import Passepartout_Core
+import PassepartoutCore
class CreditsViewController: UITableViewController, TableModelHost {
private let licenses = AppConstants.License.all
diff --git a/Passepartout-iOS/Scenes/About/LabelViewController.swift b/Passepartout-iOS/Scenes/About/LabelViewController.swift
index 8ab7930a..22d62a0a 100644
--- a/Passepartout-iOS/Scenes/About/LabelViewController.swift
+++ b/Passepartout-iOS/Scenes/About/LabelViewController.swift
@@ -24,7 +24,7 @@
//
import UIKit
-import Passepartout_Core
+import PassepartoutCore
class LabelViewController: UIViewController {
@IBOutlet private weak var scrollView: UIScrollView?
diff --git a/Passepartout-iOS/Scenes/About/VersionViewController.swift b/Passepartout-iOS/Scenes/About/VersionViewController.swift
index 44383def..f6d35cf9 100644
--- a/Passepartout-iOS/Scenes/About/VersionViewController.swift
+++ b/Passepartout-iOS/Scenes/About/VersionViewController.swift
@@ -24,7 +24,7 @@
//
import UIKit
-import Passepartout_Core
+import PassepartoutCore
class VersionViewController: UIViewController {
@IBOutlet private weak var scrollView: UIScrollView?
diff --git a/Passepartout-iOS/Scenes/AccountViewController.swift b/Passepartout-iOS/Scenes/AccountViewController.swift
index a4a44aff..d3fffded 100644
--- a/Passepartout-iOS/Scenes/AccountViewController.swift
+++ b/Passepartout-iOS/Scenes/AccountViewController.swift
@@ -24,7 +24,7 @@
//
import UIKit
-import Passepartout_Core
+import PassepartoutCore
protocol AccountViewControllerDelegate: class {
func accountController(_: AccountViewController, didEnterCredentials credentials: Credentials)
diff --git a/Passepartout-iOS/Scenes/ConfigurationViewController.swift b/Passepartout-iOS/Scenes/ConfigurationViewController.swift
index 5b30553d..aa793f2a 100644
--- a/Passepartout-iOS/Scenes/ConfigurationViewController.swift
+++ b/Passepartout-iOS/Scenes/ConfigurationViewController.swift
@@ -26,7 +26,7 @@
import UIKit
import TunnelKit
import SwiftyBeaver
-import Passepartout_Core
+import PassepartoutCore
private let log = SwiftyBeaver.self
diff --git a/Passepartout-iOS/Scenes/DebugLogViewController.swift b/Passepartout-iOS/Scenes/DebugLogViewController.swift
index f9705529..40441cf6 100644
--- a/Passepartout-iOS/Scenes/DebugLogViewController.swift
+++ b/Passepartout-iOS/Scenes/DebugLogViewController.swift
@@ -25,7 +25,7 @@
import UIKit
import SwiftyBeaver
-import Passepartout_Core
+import PassepartoutCore
private let log = SwiftyBeaver.self
diff --git a/Passepartout-iOS/Scenes/EndpointViewController.swift b/Passepartout-iOS/Scenes/EndpointViewController.swift
index e7cbb5de..9ada92b9 100644
--- a/Passepartout-iOS/Scenes/EndpointViewController.swift
+++ b/Passepartout-iOS/Scenes/EndpointViewController.swift
@@ -25,7 +25,7 @@
import UIKit
import TunnelKit
-import Passepartout_Core
+import PassepartoutCore
protocol EndpointViewControllerDelegate: class {
func endpointController(_: EndpointViewController, didUpdateWithNewAddress newAddress: String?, newProtocol: EndpointProtocol?)
diff --git a/Passepartout-iOS/Scenes/NetworkSettingsViewController.swift b/Passepartout-iOS/Scenes/NetworkSettingsViewController.swift
index c46d25b9..27a0542e 100644
--- a/Passepartout-iOS/Scenes/NetworkSettingsViewController.swift
+++ b/Passepartout-iOS/Scenes/NetworkSettingsViewController.swift
@@ -24,7 +24,7 @@
//
import UIKit
-import Passepartout_Core
+import PassepartoutCore
import TunnelKit
import SwiftyBeaver
diff --git a/Passepartout-iOS/Scenes/Organizer/DonationViewController.swift b/Passepartout-iOS/Scenes/Organizer/DonationViewController.swift
index 1e45a440..35cca335 100644
--- a/Passepartout-iOS/Scenes/Organizer/DonationViewController.swift
+++ b/Passepartout-iOS/Scenes/Organizer/DonationViewController.swift
@@ -25,7 +25,7 @@
import UIKit
import StoreKit
-import Passepartout_Core
+import PassepartoutCore
class DonationViewController: UITableViewController, TableModelHost {
private var donationList: [InApp.Donation] = []
diff --git a/Passepartout-iOS/Scenes/Organizer/ImportedHostsViewController.swift b/Passepartout-iOS/Scenes/Organizer/ImportedHostsViewController.swift
index b262f1b3..ed913d2d 100644
--- a/Passepartout-iOS/Scenes/Organizer/ImportedHostsViewController.swift
+++ b/Passepartout-iOS/Scenes/Organizer/ImportedHostsViewController.swift
@@ -26,7 +26,7 @@
import UIKit
import TunnelKit
import SwiftyBeaver
-import Passepartout_Core
+import PassepartoutCore
private let log = SwiftyBeaver.self
diff --git a/Passepartout-iOS/Scenes/Organizer/OrganizerViewController.swift b/Passepartout-iOS/Scenes/Organizer/OrganizerViewController.swift
index e3371a90..3f332e98 100644
--- a/Passepartout-iOS/Scenes/Organizer/OrganizerViewController.swift
+++ b/Passepartout-iOS/Scenes/Organizer/OrganizerViewController.swift
@@ -26,7 +26,7 @@
import UIKit
import StoreKit
import MessageUI
-import Passepartout_Core
+import PassepartoutCore
// XXX: convoluted due to the separation of provider/host profiles
diff --git a/Passepartout-iOS/Scenes/Organizer/WizardHostViewController.swift b/Passepartout-iOS/Scenes/Organizer/WizardHostViewController.swift
index 9a769cfe..19dfb0e8 100644
--- a/Passepartout-iOS/Scenes/Organizer/WizardHostViewController.swift
+++ b/Passepartout-iOS/Scenes/Organizer/WizardHostViewController.swift
@@ -26,7 +26,7 @@
import UIKit
import TunnelKit
import SwiftyBeaver
-import Passepartout_Core
+import PassepartoutCore
private let log = SwiftyBeaver.self
diff --git a/Passepartout-iOS/Scenes/Organizer/WizardProviderViewController.swift b/Passepartout-iOS/Scenes/Organizer/WizardProviderViewController.swift
index 097e24f7..1591e925 100644
--- a/Passepartout-iOS/Scenes/Organizer/WizardProviderViewController.swift
+++ b/Passepartout-iOS/Scenes/Organizer/WizardProviderViewController.swift
@@ -24,7 +24,7 @@
//
import UIKit
-import Passepartout_Core
+import PassepartoutCore
class WizardProviderViewController: UITableViewController {
var availableNames: [Infrastructure.Name] = []
diff --git a/Passepartout-iOS/Scenes/ProviderPoolViewController.swift b/Passepartout-iOS/Scenes/ProviderPoolViewController.swift
index 48add460..7d8d9f4e 100644
--- a/Passepartout-iOS/Scenes/ProviderPoolViewController.swift
+++ b/Passepartout-iOS/Scenes/ProviderPoolViewController.swift
@@ -24,7 +24,7 @@
//
import UIKit
-import Passepartout_Core
+import PassepartoutCore
protocol ProviderPoolViewControllerDelegate: class {
func providerPoolController(_: ProviderPoolViewController, didSelectPool pool: Pool)
diff --git a/Passepartout-iOS/Scenes/ProviderPresetViewController.swift b/Passepartout-iOS/Scenes/ProviderPresetViewController.swift
index ce0d7c6a..d8901562 100644
--- a/Passepartout-iOS/Scenes/ProviderPresetViewController.swift
+++ b/Passepartout-iOS/Scenes/ProviderPresetViewController.swift
@@ -24,7 +24,7 @@
//
import UIKit
-import Passepartout_Core
+import PassepartoutCore
protocol ProviderPresetViewControllerDelegate: class {
func providerPresetController(_: ProviderPresetViewController, didSelectPreset preset: InfrastructurePreset)
diff --git a/Passepartout-iOS/Scenes/ServiceViewController.swift b/Passepartout-iOS/Scenes/ServiceViewController.swift
index f11a30bd..9495b4e5 100644
--- a/Passepartout-iOS/Scenes/ServiceViewController.swift
+++ b/Passepartout-iOS/Scenes/ServiceViewController.swift
@@ -28,7 +28,7 @@ import NetworkExtension
import CoreTelephony
import MBProgressHUD
import TunnelKit
-import Passepartout_Core
+import PassepartoutCore
class ServiceViewController: UIViewController, TableModelHost {
@IBOutlet private weak var tableView: UITableView!
diff --git a/Passepartout-iOS/Scenes/Shortcuts/ShortcutsAddViewController.swift b/Passepartout-iOS/Scenes/Shortcuts/ShortcutsAddViewController.swift
index e147741c..ee6fc2c4 100644
--- a/Passepartout-iOS/Scenes/Shortcuts/ShortcutsAddViewController.swift
+++ b/Passepartout-iOS/Scenes/Shortcuts/ShortcutsAddViewController.swift
@@ -25,7 +25,7 @@
import UIKit
import Intents
-import Passepartout_Core
+import PassepartoutCore
@available(iOS 12, *)
class ShortcutsAddViewController: UITableViewController, TableModelHost {
diff --git a/Passepartout-iOS/Scenes/Shortcuts/ShortcutsConnectToViewController.swift b/Passepartout-iOS/Scenes/Shortcuts/ShortcutsConnectToViewController.swift
index 16e44a47..02f7759f 100644
--- a/Passepartout-iOS/Scenes/Shortcuts/ShortcutsConnectToViewController.swift
+++ b/Passepartout-iOS/Scenes/Shortcuts/ShortcutsConnectToViewController.swift
@@ -26,7 +26,7 @@
import UIKit
import Intents
import IntentsUI
-import Passepartout_Core
+import PassepartoutCore
@available(iOS 12, *)
class ShortcutsConnectToViewController: UITableViewController, ProviderPoolViewControllerDelegate, TableModelHost {
diff --git a/Passepartout-iOS/Scenes/Shortcuts/ShortcutsViewController.swift b/Passepartout-iOS/Scenes/Shortcuts/ShortcutsViewController.swift
index dccfb9e1..e655187d 100644
--- a/Passepartout-iOS/Scenes/Shortcuts/ShortcutsViewController.swift
+++ b/Passepartout-iOS/Scenes/Shortcuts/ShortcutsViewController.swift
@@ -26,7 +26,7 @@
import UIKit
import Intents
import IntentsUI
-import Passepartout_Core
+import PassepartoutCore
@available(iOS 12, *)
protocol ShortcutsIntentDelegate: class {
diff --git a/Passepartout.xcodeproj/project.pbxproj b/Passepartout.xcodeproj/project.pbxproj
index 49e8006b..cf9f3d65 100644
--- a/Passepartout.xcodeproj/project.pbxproj
+++ b/Passepartout.xcodeproj/project.pbxproj
@@ -20,10 +20,10 @@
0E242740225951B00064A1A3 /* InApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E24273F225951B00064A1A3 /* InApp.swift */; };
0E242742225956AC0064A1A3 /* DonationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E242741225956AC0064A1A3 /* DonationViewController.swift */; };
0E2B494020FCFF990094784C /* Theme+Titles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E2B493F20FCFF990094784C /* Theme+Titles.swift */; };
- 0E3152A4223F9EF500F61841 /* Passepartout_Core.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E31529B223F9EF400F61841 /* Passepartout_Core.framework */; };
- 0E3152AD223F9EF500F61841 /* Passepartout_Core.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E31529D223F9EF500F61841 /* Passepartout_Core.h */; settings = {ATTRIBUTES = (Public, ); }; };
- 0E3152B0223F9EF500F61841 /* Passepartout_Core.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E31529B223F9EF400F61841 /* Passepartout_Core.framework */; };
- 0E3152B1223F9EF500F61841 /* Passepartout_Core.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 0E31529B223F9EF400F61841 /* Passepartout_Core.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 0E3152A4223F9EF500F61841 /* PassepartoutCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E31529B223F9EF400F61841 /* PassepartoutCore.framework */; };
+ 0E3152AD223F9EF500F61841 /* PassepartoutCore.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E31529D223F9EF500F61841 /* PassepartoutCore.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ 0E3152B0223F9EF500F61841 /* PassepartoutCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0E31529B223F9EF400F61841 /* PassepartoutCore.framework */; };
+ 0E3152B1223F9EF500F61841 /* PassepartoutCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 0E31529B223F9EF400F61841 /* PassepartoutCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
0E3152B9223F9F3B00F61841 /* ConnectionServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EBBE8F021822B4D00106008 /* ConnectionServiceTests.swift */; };
0E3152BA223F9F3D00F61841 /* InfrastructureTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED31C2620CF257C0027975F /* InfrastructureTests.swift */; };
0E3152BB223FA03D00F61841 /* AppConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E39BCF2214DA9310035E9DE /* AppConstants.swift */; };
@@ -60,13 +60,15 @@
0E3152DA223FA05800F61841 /* PlaceholderConnectionProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E79D13E21919EC900BB5FB2 /* PlaceholderConnectionProfile.swift */; };
0E3152DB223FA05800F61841 /* ProfileKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E79D14021919F5600BB5FB2 /* ProfileKey.swift */; };
0E3152DC223FA05800F61841 /* ProviderConnectionProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EBE3AA4213DC1B000BFA2F5 /* ProviderConnectionProfile.swift */; };
- 0E3152DD223FA06100F61841 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0E05C5DF20D198B9006EE732 /* Localizable.strings */; };
- 0E3152DE223FA06400F61841 /* Web in Resources */ = {isa = PBXBuildFile; fileRef = 0E0EABC721DF853C0069DAE7 /* Web */; };
0E3152DF223FA1DD00F61841 /* ConnectionService.json in Resources */ = {isa = PBXBuildFile; fileRef = 0EBBE8F121822B4D00106008 /* ConnectionService.json */; };
0E3586FE225BD34800509A4D /* ActivityTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3586FD225BD34800509A4D /* ActivityTableViewCell.swift */; };
0E36D24D2240234B006AF062 /* ShortcutsAddViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E36D24C2240234B006AF062 /* ShortcutsAddViewController.swift */; };
0E36D25822403469006AF062 /* Shortcuts.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E36D25A22403469006AF062 /* Shortcuts.storyboard */; };
0E36D25C224034AD006AF062 /* ShortcutsConnectToViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E36D25B224034AD006AF062 /* ShortcutsConnectToViewController.swift */; };
+ 0E3CAFB7229AAE770008E5C8 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0E3CAF98229AAE760008E5C8 /* Localizable.strings */; };
+ 0E3CAFB8229AAE770008E5C8 /* Intents.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0E3CAF9A229AAE760008E5C8 /* Intents.strings */; };
+ 0E3CAFC0229AAE770008E5C8 /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 0E3CAFAD229AAE760008E5C8 /* Intents.intentdefinition */; };
+ 0E3CAFC4229AAF8E0008E5C8 /* API in Resources */ = {isa = PBXBuildFile; fileRef = 0E3CAFC3229AAF8E0008E5C8 /* API */; };
0E3DA371215CB5BF00B40FC9 /* VersionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3DA370215CB5BF00B40FC9 /* VersionViewController.swift */; };
0E4C9CBB20DCF0D600A0C59C /* DestructiveTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E4C9CBA20DCF0D600A0C59C /* DestructiveTableViewCell.swift */; };
0E4FD7F120D58618002221FF /* Macros.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E4FD7F020D58618002221FF /* Macros.swift */; };
@@ -76,8 +78,6 @@
0E57F64120C83FC5008323CF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E57F63F20C83FC5008323CF /* Main.storyboard */; };
0E57F64320C83FC7008323CF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0E57F64220C83FC7008323CF /* Assets.xcassets */; };
0E57F64620C83FC7008323CF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0E57F64420C83FC7008323CF /* LaunchScreen.storyboard */; };
- 0E58BD9322404EF1006FB157 /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BD9122404EF1006FB157 /* Intents.intentdefinition */; };
- 0E58BF65224152F9006FB157 /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 0E58BD9122404EF1006FB157 /* Intents.intentdefinition */; settings = {ATTRIBUTES = (no_codegen, ); }; };
0E66A270225FE25800F9C779 /* PoolCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E66A26F225FE25800F9C779 /* PoolCategory.swift */; };
0E6BE13F20CFBAB300A6DD36 /* DebugLogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E6BE13E20CFBAB300A6DD36 /* DebugLogViewController.swift */; };
0E773BF8224BF37600CDDC8E /* ShortcutsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E773BF7224BF37600CDDC8E /* ShortcutsViewController.swift */; };
@@ -115,10 +115,10 @@
0EFBFAC121AC464800887A8C /* CreditsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFBFAC021AC464800887A8C /* CreditsViewController.swift */; };
0EFD943E215BE10800529B64 /* IssueReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFD943D215BE10800529B64 /* IssueReporter.swift */; };
0EFD9440215BED8E00529B64 /* LabelViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EFD943F215BED8E00529B64 /* LabelViewController.swift */; };
- 2774FA39ED110D958C822250 /* Pods_Passepartout_iOS_Tunnel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A3A4ADF4EAADB11C595D7937 /* Pods_Passepartout_iOS_Tunnel.framework */; };
- 64BC3972D5FD0698BA15D741 /* Pods_Passepartout_CoreTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 330CE87BE42AD629984E05C3 /* Pods_Passepartout_CoreTests.framework */; };
- 65923F9A7B1F49732A1B386B /* Pods_Passepartout_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1EAE1FBCD7178916560C394 /* Pods_Passepartout_iOS.framework */; };
- 974F713030E083F69F5E1049 /* Pods_Passepartout_Core.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ABC62156F813CA8AE19A046B /* Pods_Passepartout_Core.framework */; };
+ 360C6E03D6FEF3C040079A77 /* Pods_PassepartoutCoreTests_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 992C366F272FAA643335F68C /* Pods_PassepartoutCoreTests_iOS.framework */; };
+ 577B90392A4798F63461B0B5 /* Pods_Passepartout_iOS_Tunnel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA4CE55A94366C45DDB1E624 /* Pods_Passepartout_iOS_Tunnel.framework */; };
+ 87121F7216E808EE79925040 /* Pods_Passepartout_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6D32B24AA7767AB2E7FB6E0F /* Pods_Passepartout_iOS.framework */; };
+ 91AF81613E19B47C06EBD447 /* Pods_PassepartoutCore_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 276375A4CF0313B033CD8B5A /* Pods_PassepartoutCore_iOS.framework */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -152,7 +152,7 @@
dstPath = "";
dstSubfolderSpec = 10;
files = (
- 0E3152B1223F9EF500F61841 /* Passepartout_Core.framework in Embed Frameworks */,
+ 0E3152B1223F9EF500F61841 /* PassepartoutCore.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
@@ -171,43 +171,52 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
- 0006BCD0B73ABD3B2B701604 /* Pods-Passepartout-Core.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Passepartout-Core.release.xcconfig"; path = "Target Support Files/Pods-Passepartout-Core/Pods-Passepartout-Core.release.xcconfig"; sourceTree = ""; };
+ 09CB728874F1553EF27BAAB9 /* Pods-Passepartout-iOS-Tunnel.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Passepartout-iOS-Tunnel.debug.xcconfig"; path = "Target Support Files/Pods-Passepartout-iOS-Tunnel/Pods-Passepartout-iOS-Tunnel.debug.xcconfig"; sourceTree = ""; };
0E05C5CE20D139AF006EE732 /* FieldTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FieldTableViewCell.swift; sourceTree = ""; };
- 0E05C5DE20D198B9006EE732 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; };
0E05C5E320D1993C006EE732 /* SwiftGen+Strings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SwiftGen+Strings.swift"; sourceTree = ""; };
0E05C61C20D27C82006EE732 /* Theme.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Theme.swift; sourceTree = ""; };
- 0E0B6CE3226F3CDF00C1B244 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; };
- 0E0B6CE4226F45B000C1B244 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Intents.strings; sourceTree = ""; };
- 0E0B6CE5226F45B100C1B244 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; };
- 0E0EABC721DF853C0069DAE7 /* Web */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Web; sourceTree = ""; };
0E1066C820E0F84A004F98B7 /* Cells.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cells.swift; sourceTree = ""; };
- 0E108485226F3CC100BA41E9 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Intents.strings; sourceTree = ""; };
0E158AD920E11B0B00C85A82 /* EndpointViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EndpointViewController.swift; sourceTree = ""; };
0E1D72B1213BFFCF00BA1586 /* ProviderPresetViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProviderPresetViewController.swift; sourceTree = ""; };
0E1D72B3213C118500BA1586 /* ConfigurationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurationViewController.swift; sourceTree = ""; };
0E23B4A12298559800304C30 /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = ""; };
- 0E242735225944060064A1A3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Intents.strings; sourceTree = ""; };
0E24273B225950450064A1A3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/About.storyboard; sourceTree = ""; };
0E24273F225951B00064A1A3 /* InApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InApp.swift; sourceTree = ""; };
0E242741225956AC0064A1A3 /* DonationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DonationViewController.swift; sourceTree = ""; };
0E2B493F20FCFF990094784C /* Theme+Titles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Theme+Titles.swift"; sourceTree = ""; };
0E2B494120FD16540094784C /* TransientStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransientStore.swift; sourceTree = ""; };
0E2D11B9217DBEDE0096822C /* ConnectionService+Configurations.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ConnectionService+Configurations.swift"; sourceTree = ""; };
- 0E31529B223F9EF400F61841 /* Passepartout_Core.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Passepartout_Core.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- 0E31529D223F9EF500F61841 /* Passepartout_Core.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Passepartout_Core.h; sourceTree = ""; };
+ 0E31529B223F9EF400F61841 /* PassepartoutCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PassepartoutCore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 0E31529D223F9EF500F61841 /* PassepartoutCore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PassepartoutCore.h; sourceTree = ""; };
0E31529E223F9EF500F61841 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
- 0E3152A3223F9EF500F61841 /* Passepartout-CoreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Passepartout-CoreTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 0E3152A3223F9EF500F61841 /* PassepartoutCoreTests-iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "PassepartoutCoreTests-iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
0E3152AC223F9EF500F61841 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
0E3586FD225BD34800509A4D /* ActivityTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityTableViewCell.swift; sourceTree = ""; };
0E36D24C2240234B006AF062 /* ShortcutsAddViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutsAddViewController.swift; sourceTree = ""; };
0E36D25B224034AD006AF062 /* ShortcutsConnectToViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShortcutsConnectToViewController.swift; sourceTree = ""; };
0E39BCEF214B9EF10035E9DE /* WebServices.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebServices.swift; sourceTree = ""; };
0E39BCF2214DA9310035E9DE /* AppConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppConstants.swift; sourceTree = ""; };
- 0E3CAFC5229B033E0008E5C8 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Intents.strings; sourceTree = ""; };
- 0E3CAFC7229B28310008E5C8 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; };
+ 0E3CAF99229AAE760008E5C8 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; };
+ 0E3CAF9B229AAE760008E5C8 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Intents.strings; sourceTree = ""; };
+ 0E3CAF9C229AAE760008E5C8 /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/Localizable.strings; sourceTree = ""; };
+ 0E3CAF9D229AAE760008E5C8 /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/Intents.strings; sourceTree = ""; };
+ 0E3CAF9E229AAE760008E5C8 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; };
+ 0E3CAF9F229AAE760008E5C8 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Intents.strings; sourceTree = ""; };
+ 0E3CAFA0229AAE760008E5C8 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; };
+ 0E3CAFA1229AAE760008E5C8 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Intents.strings; sourceTree = ""; };
+ 0E3CAFAB229AAE760008E5C8 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Localizable.strings; sourceTree = ""; };
+ 0E3CAFAC229AAE760008E5C8 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Intents.strings; sourceTree = ""; };
+ 0E3CAFAE229AAE760008E5C8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; name = Base; path = Base.lproj/Intents.intentdefinition; sourceTree = ""; };
+ 0E3CAFAF229AAE760008E5C8 /* pt-br */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-br"; path = "pt-br.lproj/Localizable.strings"; sourceTree = ""; };
+ 0E3CAFB0229AAE760008E5C8 /* pt-br */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-br"; path = "pt-br.lproj/Intents.strings"; sourceTree = ""; };
+ 0E3CAFB1229AAE760008E5C8 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; };
+ 0E3CAFB2229AAE760008E5C8 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Intents.strings; sourceTree = ""; };
+ 0E3CAFB3229AAE760008E5C8 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; };
+ 0E3CAFB4229AAE760008E5C8 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Intents.strings; sourceTree = ""; };
+ 0E3CAFB5229AAE760008E5C8 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; };
+ 0E3CAFB6229AAE760008E5C8 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Intents.strings; sourceTree = ""; };
+ 0E3CAFC3229AAF8E0008E5C8 /* API */ = {isa = PBXFileReference; lastKnownFileType = folder; path = API; sourceTree = ""; };
0E3DA370215CB5BF00B40FC9 /* VersionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionViewController.swift; sourceTree = ""; };
- 0E411BA32272183700E0852C /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Intents.strings"; sourceTree = ""; };
- 0E411BA42272184A00E0852C /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Localizable.strings"; sourceTree = ""; };
0E4C9CB820DB9BC600A0C59C /* TrustedNetworks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrustedNetworks.swift; sourceTree = ""; };
0E4C9CBA20DCF0D600A0C59C /* DestructiveTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DestructiveTableViewCell.swift; sourceTree = ""; };
0E4FD7DD20D3E49A002221FF /* StandardVPNProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandardVPNProvider.swift; sourceTree = ""; };
@@ -215,9 +224,6 @@
0E4FD7ED20D539A0002221FF /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; };
0E4FD7F020D58618002221FF /* Macros.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Macros.swift; sourceTree = ""; };
0E4FD80420D683A2002221FF /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/NetworkExtension.framework; sourceTree = DEVELOPER_DIR; };
- 0E533B0C2257BAB900EF94FC /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; name = Base; path = Base.lproj/Intents.intentdefinition; sourceTree = ""; };
- 0E533B102257C0F200EF94FC /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Intents.strings; sourceTree = ""; };
- 0E533B142257C1DC00EF94FC /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; };
0E533B152258E03B00EF94FC /* PoolGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PoolGroup.swift; sourceTree = ""; };
0E57F63820C83FC5008323CF /* Passepartout.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Passepartout.app; sourceTree = BUILT_PRODUCTS_DIR; };
0E57F63B20C83FC5008323CF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
@@ -240,8 +246,6 @@
0E8D97E121388B52006FB4A0 /* InfrastructurePreset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfrastructurePreset.swift; sourceTree = ""; };
0E9CD7862257462800D033B4 /* Providers.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Providers.xcassets; sourceTree = ""; };
0E9CD788225746B300D033B4 /* Flags.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Flags.xcassets; sourceTree = ""; };
- 0E9DE06B22992DE000DEC291 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Intents.strings; sourceTree = ""; };
- 0E9DE06C22992DE600DEC291 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Localizable.strings; sourceTree = ""; };
0EA068F3218475F800C320AD /* ConfigurationParserResult+Alerts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ConfigurationParserResult+Alerts.swift"; sourceTree = ""; };
0EB60FD92111136E00AD27F3 /* UITextView+Search.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextView+Search.swift"; sourceTree = ""; };
0EB67D6A2184581E00BA6200 /* ImportedHostsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportedHostsViewController.swift; sourceTree = ""; };
@@ -280,7 +284,7 @@
0ED38AF1214177920004D387 /* VPNProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNProvider.swift; sourceTree = ""; };
0ED824C920D12B8700F2FE9E /* ToggleTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleTableViewCell.swift; sourceTree = ""; };
0ED824CD20D12DBE00F2FE9E /* SettingTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingTableViewCell.swift; sourceTree = ""; };
- 0ED993B0223FF8C700B0F9C9 /* IntentDispatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = IntentDispatcher.swift; path = Passepartout/Sources/Intents/IntentDispatcher.swift; sourceTree = SOURCE_ROOT; };
+ 0ED993B0223FF8C700B0F9C9 /* IntentDispatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = IntentDispatcher.swift; path = Submodules/Core/Passepartout/Sources/Intents/IntentDispatcher.swift; sourceTree = SOURCE_ROOT; };
0EDE8DBF20C86910004C739C /* Passepartout-Tunnel.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "Passepartout-Tunnel.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
0EDE8DC320C86910004C739C /* PacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelProvider.swift; sourceTree = ""; };
0EDE8DC520C86910004C739C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
@@ -289,14 +293,8 @@
0EDE8DE320C89028004C739C /* SwiftGen+Scenes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SwiftGen+Scenes.swift"; sourceTree = ""; };
0EDE8DE620C93945004C739C /* Credentials.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Credentials.swift; sourceTree = ""; };
0EDE8DED20C93E4C004C739C /* GroupConstants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupConstants.swift; sourceTree = ""; };
- 0EE2FA662291E4AA00F56F49 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Intents.strings; sourceTree = ""; };
- 0EE2FA672291E50300F56F49 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; };
0EE3BBB1215ED3A900F30952 /* AboutViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutViewController.swift; sourceTree = ""; };
- 0EE4EB29229A6AF8000E4BA1 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Intents.strings; sourceTree = ""; };
- 0EE4EB2A229A6AF8000E4BA1 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; };
0EEB53B1225D525B00746300 /* Downloader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Downloader.swift; sourceTree = ""; };
- 0EF4EF7F229431CB0030E6EB /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/Intents.strings; sourceTree = ""; };
- 0EF4EF80229431D20030E6EB /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/Localizable.strings; sourceTree = ""; };
0EF56BBA2185AC8500B0C8AB /* SwiftGen+Segues.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SwiftGen+Segues.swift"; sourceTree = ""; };
0EF5CF242141CE58004FF1BD /* HUD.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HUD.swift; sourceTree = ""; };
0EFB901722764689006405E4 /* ProfileNetworkSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileNetworkSettings.swift; sourceTree = ""; };
@@ -304,17 +302,17 @@
0EFBFAC021AC464800887A8C /* CreditsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreditsViewController.swift; sourceTree = ""; };
0EFD943D215BE10800529B64 /* IssueReporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IssueReporter.swift; sourceTree = ""; };
0EFD943F215BED8E00529B64 /* LabelViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelViewController.swift; sourceTree = ""; };
- 1AA0A7801E34D3A4286280AB /* Pods-Passepartout-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Passepartout-iOS.release.xcconfig"; path = "Target Support Files/Pods-Passepartout-iOS/Pods-Passepartout-iOS.release.xcconfig"; sourceTree = ""; };
- 306E9009D8A771C5756ACC83 /* Pods-Passepartout-CoreTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Passepartout-CoreTests.release.xcconfig"; path = "Target Support Files/Pods-Passepartout-CoreTests/Pods-Passepartout-CoreTests.release.xcconfig"; sourceTree = ""; };
- 330CE87BE42AD629984E05C3 /* Pods_Passepartout_CoreTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Passepartout_CoreTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- 84E4F391724F65947460C4C6 /* Pods-Passepartout-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Passepartout-iOS.debug.xcconfig"; path = "Target Support Files/Pods-Passepartout-iOS/Pods-Passepartout-iOS.debug.xcconfig"; sourceTree = ""; };
- A1EAE1FBCD7178916560C394 /* Pods_Passepartout_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Passepartout_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- A3A4ADF4EAADB11C595D7937 /* Pods_Passepartout_iOS_Tunnel.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Passepartout_iOS_Tunnel.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- ABC62156F813CA8AE19A046B /* Pods_Passepartout_Core.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Passepartout_Core.framework; sourceTree = BUILT_PRODUCTS_DIR; };
- C8A8897C87D8BCB817593651 /* Pods-Passepartout-iOS-Tunnel.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Passepartout-iOS-Tunnel.release.xcconfig"; path = "Target Support Files/Pods-Passepartout-iOS-Tunnel/Pods-Passepartout-iOS-Tunnel.release.xcconfig"; sourceTree = ""; };
- CA8AA77D192D2ABAABC8A4DA /* Pods-Passepartout-iOS-Tunnel.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Passepartout-iOS-Tunnel.debug.xcconfig"; path = "Target Support Files/Pods-Passepartout-iOS-Tunnel/Pods-Passepartout-iOS-Tunnel.debug.xcconfig"; sourceTree = ""; };
- D35137256E20958EA0A025A0 /* Pods-Passepartout-CoreTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Passepartout-CoreTests.debug.xcconfig"; path = "Target Support Files/Pods-Passepartout-CoreTests/Pods-Passepartout-CoreTests.debug.xcconfig"; sourceTree = ""; };
- D7CC6F055B1ECE468E956C00 /* Pods-Passepartout-Core.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Passepartout-Core.debug.xcconfig"; path = "Target Support Files/Pods-Passepartout-Core/Pods-Passepartout-Core.debug.xcconfig"; sourceTree = ""; };
+ 0FD7B360EE444EF1CDBFDF1C /* Pods-PassepartoutCoreTests-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PassepartoutCoreTests-iOS.debug.xcconfig"; path = "Target Support Files/Pods-PassepartoutCoreTests-iOS/Pods-PassepartoutCoreTests-iOS.debug.xcconfig"; sourceTree = ""; };
+ 234D3C887F46AD64480495BB /* Pods-PassepartoutCoreTests-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PassepartoutCoreTests-iOS.release.xcconfig"; path = "Target Support Files/Pods-PassepartoutCoreTests-iOS/Pods-PassepartoutCoreTests-iOS.release.xcconfig"; sourceTree = ""; };
+ 276375A4CF0313B033CD8B5A /* Pods_PassepartoutCore_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PassepartoutCore_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4BD12523ABCBF7ED941FC270 /* Pods-Passepartout-iOS-Tunnel.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Passepartout-iOS-Tunnel.release.xcconfig"; path = "Target Support Files/Pods-Passepartout-iOS-Tunnel/Pods-Passepartout-iOS-Tunnel.release.xcconfig"; sourceTree = ""; };
+ 53B773C4BAE7EDB38C7AFCD1 /* Pods-Passepartout-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Passepartout-iOS.release.xcconfig"; path = "Target Support Files/Pods-Passepartout-iOS/Pods-Passepartout-iOS.release.xcconfig"; sourceTree = ""; };
+ 6D32B24AA7767AB2E7FB6E0F /* Pods_Passepartout_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Passepartout_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 992C366F272FAA643335F68C /* Pods_PassepartoutCoreTests_iOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PassepartoutCoreTests_iOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ A1C4E67627603307808F2FFC /* Pods-PassepartoutCore-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PassepartoutCore-iOS.debug.xcconfig"; path = "Target Support Files/Pods-PassepartoutCore-iOS/Pods-PassepartoutCore-iOS.debug.xcconfig"; sourceTree = ""; };
+ F1BECEC1D93FEBDB17B714D8 /* Pods-PassepartoutCore-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PassepartoutCore-iOS.release.xcconfig"; path = "Target Support Files/Pods-PassepartoutCore-iOS/Pods-PassepartoutCore-iOS.release.xcconfig"; sourceTree = ""; };
+ F4959B5F3CB1BBC2C46EA639 /* Pods-Passepartout-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Passepartout-iOS.debug.xcconfig"; path = "Target Support Files/Pods-Passepartout-iOS/Pods-Passepartout-iOS.debug.xcconfig"; sourceTree = ""; };
+ FA4CE55A94366C45DDB1E624 /* Pods_Passepartout_iOS_Tunnel.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Passepartout_iOS_Tunnel.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -322,7 +320,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 974F713030E083F69F5E1049 /* Pods_Passepartout_Core.framework in Frameworks */,
+ 91AF81613E19B47C06EBD447 /* Pods_PassepartoutCore_iOS.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -330,8 +328,8 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 0E3152A4223F9EF500F61841 /* Passepartout_Core.framework in Frameworks */,
- 64BC3972D5FD0698BA15D741 /* Pods_Passepartout_CoreTests.framework in Frameworks */,
+ 0E3152A4223F9EF500F61841 /* PassepartoutCore.framework in Frameworks */,
+ 360C6E03D6FEF3C040079A77 /* Pods_PassepartoutCoreTests_iOS.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -339,9 +337,9 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 0E3152B0223F9EF500F61841 /* Passepartout_Core.framework in Frameworks */,
+ 0E3152B0223F9EF500F61841 /* PassepartoutCore.framework in Frameworks */,
0ED31C3D20CF396E0027975F /* NetworkExtension.framework in Frameworks */,
- 65923F9A7B1F49732A1B386B /* Pods_Passepartout_iOS.framework in Frameworks */,
+ 87121F7216E808EE79925040 /* Pods_Passepartout_iOS.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -350,7 +348,7 @@
buildActionMask = 2147483647;
files = (
0ED31C3A20CF39510027975F /* NetworkExtension.framework in Frameworks */,
- 2774FA39ED110D958C822250 /* Pods_Passepartout_iOS_Tunnel.framework in Frameworks */,
+ 577B90392A4798F63461B0B5 /* Pods_Passepartout_iOS_Tunnel.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -391,25 +389,34 @@
path = Shortcuts;
sourceTree = "";
};
- 0E31529C223F9EF500F61841 /* Passepartout-Core */ = {
+ 0E31529C223F9EF500F61841 /* PassepartoutCore-iOS */ = {
isa = PBXGroup;
children = (
- 0E31529D223F9EF500F61841 /* Passepartout_Core.h */,
+ 0E31529D223F9EF500F61841 /* PassepartoutCore.h */,
0E31529E223F9EF500F61841 /* Info.plist */,
);
- path = "Passepartout-Core";
+ path = "PassepartoutCore-iOS";
sourceTree = "";
};
- 0E3152A9223F9EF500F61841 /* Passepartout-CoreTests */ = {
+ 0E3152A9223F9EF500F61841 /* PassepartoutTests */ = {
isa = PBXGroup;
children = (
0EBBE8F121822B4D00106008 /* ConnectionService.json */,
0EBBE8F021822B4D00106008 /* ConnectionServiceTests.swift */,
0ED31C2620CF257C0027975F /* InfrastructureTests.swift */,
0ECEB10B224FEF9B00E9E551 /* UtilsTests.swift */,
- 0E3152AC223F9EF500F61841 /* Info.plist */,
);
- path = "Passepartout-CoreTests";
+ path = PassepartoutTests;
+ sourceTree = "";
+ };
+ 0E3CAF97229AAE760008E5C8 /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 0E3CAF9A229AAE760008E5C8 /* Intents.strings */,
+ 0E3CAFAD229AAE760008E5C8 /* Intents.intentdefinition */,
+ 0E3CAF98229AAE760008E5C8 /* Localizable.strings */,
+ );
+ path = Resources;
sourceTree = "";
};
0E4FD7D920D3E43F002221FF /* VPN */ = {
@@ -437,11 +444,11 @@
0E57F62F20C83FC5008323CF = {
isa = PBXGroup;
children = (
- 0EDE8DEF20C93EBB004C739C /* Passepartout */,
- 0E31529C223F9EF500F61841 /* Passepartout-Core */,
- 0E3152A9223F9EF500F61841 /* Passepartout-CoreTests */,
+ 0E31529C223F9EF500F61841 /* PassepartoutCore-iOS */,
+ 0EE4EB2B229A6FED000E4BA1 /* PassepartoutCoreTests-iOS */,
0E57F63A20C83FC5008323CF /* Passepartout-iOS */,
0EDE8DC020C86910004C739C /* Passepartout-iOS-Tunnel */,
+ 0EE4EB2C229A71BB000E4BA1 /* Libraries */,
0E57F63920C83FC5008323CF /* Products */,
374B9F085E1148C37CF9117A /* Frameworks */,
ECB6C4CA315B2CB2AFE7ACBB /* Pods */,
@@ -453,8 +460,8 @@
children = (
0E57F63820C83FC5008323CF /* Passepartout.app */,
0EDE8DBF20C86910004C739C /* Passepartout-Tunnel.appex */,
- 0E31529B223F9EF400F61841 /* Passepartout_Core.framework */,
- 0E3152A3223F9EF500F61841 /* Passepartout-CoreTests.xctest */,
+ 0E31529B223F9EF400F61841 /* PassepartoutCore.framework */,
+ 0E3152A3223F9EF500F61841 /* PassepartoutCoreTests-iOS.xctest */,
);
name = Products;
sourceTree = "";
@@ -549,16 +556,6 @@
path = Services;
sourceTree = "";
};
- 0ED31C1C20CF17CC0027975F /* Resources */ = {
- isa = PBXGroup;
- children = (
- 0E0EABC721DF853C0069DAE7 /* Web */,
- 0E58BD9122404EF1006FB157 /* Intents.intentdefinition */,
- 0E05C5DF20D198B9006EE732 /* Localizable.strings */,
- );
- path = Resources;
- sourceTree = "";
- };
0EDE8DC020C86910004C739C /* Passepartout-iOS-Tunnel */ = {
isa = PBXGroup;
children = (
@@ -593,7 +590,7 @@
0EDE8DEF20C93EBB004C739C /* Passepartout */ = {
isa = PBXGroup;
children = (
- 0ED31C1C20CF17CC0027975F /* Resources */,
+ 0E3CAF97229AAE760008E5C8 /* Resources */,
0EDE8DF020C93EBB004C739C /* Sources */,
);
path = Passepartout;
@@ -635,16 +632,42 @@
path = Scenes;
sourceTree = "";
};
+ 0EE4EB2B229A6FED000E4BA1 /* PassepartoutCoreTests-iOS */ = {
+ isa = PBXGroup;
+ children = (
+ 0E3152AC223F9EF500F61841 /* Info.plist */,
+ );
+ path = "PassepartoutCoreTests-iOS";
+ sourceTree = "";
+ };
+ 0EE4EB2C229A71BB000E4BA1 /* Libraries */ = {
+ isa = PBXGroup;
+ children = (
+ 0E3CAFC3229AAF8E0008E5C8 /* API */,
+ 0EE4EB2E229A71DA000E4BA1 /* Core */,
+ );
+ path = Libraries;
+ sourceTree = "";
+ };
+ 0EE4EB2E229A71DA000E4BA1 /* Core */ = {
+ isa = PBXGroup;
+ children = (
+ 0EDE8DEF20C93EBB004C739C /* Passepartout */,
+ 0E3152A9223F9EF500F61841 /* PassepartoutTests */,
+ );
+ path = Core;
+ sourceTree = "";
+ };
374B9F085E1148C37CF9117A /* Frameworks */ = {
isa = PBXGroup;
children = (
0E4FD80420D683A2002221FF /* NetworkExtension.framework */,
0ED31C3920CF39510027975F /* NetworkExtension.framework */,
0EDE8DD220C86978004C739C /* NotificationCenter.framework */,
- ABC62156F813CA8AE19A046B /* Pods_Passepartout_Core.framework */,
- 330CE87BE42AD629984E05C3 /* Pods_Passepartout_CoreTests.framework */,
- A1EAE1FBCD7178916560C394 /* Pods_Passepartout_iOS.framework */,
- A3A4ADF4EAADB11C595D7937 /* Pods_Passepartout_iOS_Tunnel.framework */,
+ 6D32B24AA7767AB2E7FB6E0F /* Pods_Passepartout_iOS.framework */,
+ FA4CE55A94366C45DDB1E624 /* Pods_Passepartout_iOS_Tunnel.framework */,
+ 276375A4CF0313B033CD8B5A /* Pods_PassepartoutCore_iOS.framework */,
+ 992C366F272FAA643335F68C /* Pods_PassepartoutCoreTests_iOS.framework */,
);
name = Frameworks;
sourceTree = "";
@@ -652,14 +675,14 @@
ECB6C4CA315B2CB2AFE7ACBB /* Pods */ = {
isa = PBXGroup;
children = (
- D7CC6F055B1ECE468E956C00 /* Pods-Passepartout-Core.debug.xcconfig */,
- 0006BCD0B73ABD3B2B701604 /* Pods-Passepartout-Core.release.xcconfig */,
- D35137256E20958EA0A025A0 /* Pods-Passepartout-CoreTests.debug.xcconfig */,
- 306E9009D8A771C5756ACC83 /* Pods-Passepartout-CoreTests.release.xcconfig */,
- 84E4F391724F65947460C4C6 /* Pods-Passepartout-iOS.debug.xcconfig */,
- 1AA0A7801E34D3A4286280AB /* Pods-Passepartout-iOS.release.xcconfig */,
- CA8AA77D192D2ABAABC8A4DA /* Pods-Passepartout-iOS-Tunnel.debug.xcconfig */,
- C8A8897C87D8BCB817593651 /* Pods-Passepartout-iOS-Tunnel.release.xcconfig */,
+ F4959B5F3CB1BBC2C46EA639 /* Pods-Passepartout-iOS.debug.xcconfig */,
+ 53B773C4BAE7EDB38C7AFCD1 /* Pods-Passepartout-iOS.release.xcconfig */,
+ 09CB728874F1553EF27BAAB9 /* Pods-Passepartout-iOS-Tunnel.debug.xcconfig */,
+ 4BD12523ABCBF7ED941FC270 /* Pods-Passepartout-iOS-Tunnel.release.xcconfig */,
+ A1C4E67627603307808F2FFC /* Pods-PassepartoutCore-iOS.debug.xcconfig */,
+ F1BECEC1D93FEBDB17B714D8 /* Pods-PassepartoutCore-iOS.release.xcconfig */,
+ 0FD7B360EE444EF1CDBFDF1C /* Pods-PassepartoutCoreTests-iOS.debug.xcconfig */,
+ 234D3C887F46AD64480495BB /* Pods-PassepartoutCoreTests-iOS.release.xcconfig */,
);
path = Pods;
sourceTree = "";
@@ -671,18 +694,18 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
- 0E3152AD223F9EF500F61841 /* Passepartout_Core.h in Headers */,
+ 0E3152AD223F9EF500F61841 /* PassepartoutCore.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
- 0E31529A223F9EF400F61841 /* Passepartout-Core */ = {
+ 0E31529A223F9EF400F61841 /* PassepartoutCore-iOS */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 0E3152B6223F9EF500F61841 /* Build configuration list for PBXNativeTarget "Passepartout-Core" */;
+ buildConfigurationList = 0E3152B6223F9EF500F61841 /* Build configuration list for PBXNativeTarget "PassepartoutCore-iOS" */;
buildPhases = (
- 62FB13BEA00ABC00B4A29BCD /* [CP] Check Pods Manifest.lock */,
+ 0A0A35FE311454E07CF67743 /* [CP] Check Pods Manifest.lock */,
0E315296223F9EF400F61841 /* Headers */,
0E315297223F9EF400F61841 /* Sources */,
0E315298223F9EF400F61841 /* Frameworks */,
@@ -692,42 +715,42 @@
);
dependencies = (
);
- name = "Passepartout-Core";
+ name = "PassepartoutCore-iOS";
productName = "Passepartout-Core";
- productReference = 0E31529B223F9EF400F61841 /* Passepartout_Core.framework */;
+ productReference = 0E31529B223F9EF400F61841 /* PassepartoutCore.framework */;
productType = "com.apple.product-type.framework";
};
- 0E3152A2223F9EF500F61841 /* Passepartout-CoreTests */ = {
+ 0E3152A2223F9EF500F61841 /* PassepartoutCoreTests-iOS */ = {
isa = PBXNativeTarget;
- buildConfigurationList = 0E3152B8223F9EF500F61841 /* Build configuration list for PBXNativeTarget "Passepartout-CoreTests" */;
+ buildConfigurationList = 0E3152B8223F9EF500F61841 /* Build configuration list for PBXNativeTarget "PassepartoutCoreTests-iOS" */;
buildPhases = (
- 659C2986645B0E1133FB185B /* [CP] Check Pods Manifest.lock */,
+ C049DFE2FEC5C79568EE5396 /* [CP] Check Pods Manifest.lock */,
0E31529F223F9EF500F61841 /* Sources */,
0E3152A0223F9EF500F61841 /* Frameworks */,
0E3152A1223F9EF500F61841 /* Resources */,
- C3A988ABD9CCD3E4C5E86591 /* [CP] Embed Pods Frameworks */,
+ 2825A35DA56F68B80DAF7499 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
0E3152A6223F9EF500F61841 /* PBXTargetDependency */,
);
- name = "Passepartout-CoreTests";
+ name = "PassepartoutCoreTests-iOS";
productName = "Passepartout-CoreTests";
- productReference = 0E3152A3223F9EF500F61841 /* Passepartout-CoreTests.xctest */;
+ productReference = 0E3152A3223F9EF500F61841 /* PassepartoutCoreTests-iOS.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
0E57F63720C83FC5008323CF /* Passepartout-iOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 0E57F65520C83FC7008323CF /* Build configuration list for PBXNativeTarget "Passepartout-iOS" */;
buildPhases = (
- D6AF52B99BBE4A3C74D968EC /* [CP] Check Pods Manifest.lock */,
+ 8598326924C7B7B17B82A427 /* [CP] Check Pods Manifest.lock */,
0E57F63420C83FC5008323CF /* Sources */,
0E57F63520C83FC5008323CF /* Frameworks */,
0E57F63620C83FC5008323CF /* Resources */,
0EDE8DCC20C86910004C739C /* Embed App Extensions */,
0E3152B7223F9EF500F61841 /* Embed Frameworks */,
- 414F21AD820CC70E9B15ACA9 /* [CP] Embed Pods Frameworks */,
+ 71085646689FD70B4B7AD683 /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@@ -744,7 +767,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 0EDE8DC920C86910004C739C /* Build configuration list for PBXNativeTarget "Passepartout-iOS-Tunnel" */;
buildPhases = (
- 7E3CCE2D5D070D79917AEC2C /* [CP] Check Pods Manifest.lock */,
+ 4316D2F30EA7143E6BB85EDE /* [CP] Check Pods Manifest.lock */,
0EDE8DBB20C86910004C739C /* Sources */,
0EDE8DBC20C86910004C739C /* Frameworks */,
0EDE8DBD20C86910004C739C /* Resources */,
@@ -824,14 +847,15 @@
sv,
fr,
es,
+ "pt-br",
);
mainGroup = 0E57F62F20C83FC5008323CF;
productRefGroup = 0E57F63920C83FC5008323CF /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
- 0E31529A223F9EF400F61841 /* Passepartout-Core */,
- 0E3152A2223F9EF500F61841 /* Passepartout-CoreTests */,
+ 0E31529A223F9EF400F61841 /* PassepartoutCore-iOS */,
+ 0E3152A2223F9EF500F61841 /* PassepartoutCoreTests-iOS */,
0E57F63720C83FC5008323CF /* Passepartout-iOS */,
0EDE8DBE20C86910004C739C /* Passepartout-iOS-Tunnel */,
);
@@ -843,8 +867,9 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 0E3152DD223FA06100F61841 /* Localizable.strings in Resources */,
- 0E3152DE223FA06400F61841 /* Web in Resources */,
+ 0E3CAFC4229AAF8E0008E5C8 /* API in Resources */,
+ 0E3CAFB8229AAE770008E5C8 /* Intents.strings in Resources */,
+ 0E3CAFB7229AAE770008E5C8 /* Localizable.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -881,7 +906,79 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
- 414F21AD820CC70E9B15ACA9 /* [CP] Embed Pods Frameworks */ = {
+ 0A0A35FE311454E07CF67743 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-PassepartoutCore-iOS-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 2825A35DA56F68B80DAF7499 /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-PassepartoutCoreTests-iOS/Pods-PassepartoutCoreTests-iOS-frameworks.sh",
+ "${PODS_ROOT}/OpenSSL-Apple/frameworks/iPhone/openssl.framework",
+ "${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework",
+ "${BUILT_PRODUCTS_DIR}/SwiftyBeaver/SwiftyBeaver.framework",
+ "${BUILT_PRODUCTS_DIR}/TunnelKit/TunnelKit.framework",
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SSZipArchive.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyBeaver.framework",
+ "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TunnelKit.framework",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PassepartoutCoreTests-iOS/Pods-PassepartoutCoreTests-iOS-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 4316D2F30EA7143E6BB85EDE /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-Passepartout-iOS-Tunnel-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 71085646689FD70B4B7AD683 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -911,101 +1008,7 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Passepartout-iOS/Pods-Passepartout-iOS-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
- 62FB13BEA00ABC00B4A29BCD /* [CP] Check Pods Manifest.lock */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputFileListPaths = (
- );
- inputPaths = (
- "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
- "${PODS_ROOT}/Manifest.lock",
- );
- name = "[CP] Check Pods Manifest.lock";
- outputFileListPaths = (
- );
- outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-Passepartout-Core-checkManifestLockResult.txt",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
- showEnvVarsInLog = 0;
- };
- 659C2986645B0E1133FB185B /* [CP] Check Pods Manifest.lock */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputFileListPaths = (
- );
- inputPaths = (
- "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
- "${PODS_ROOT}/Manifest.lock",
- );
- name = "[CP] Check Pods Manifest.lock";
- outputFileListPaths = (
- );
- outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-Passepartout-CoreTests-checkManifestLockResult.txt",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
- showEnvVarsInLog = 0;
- };
- 7E3CCE2D5D070D79917AEC2C /* [CP] Check Pods Manifest.lock */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputFileListPaths = (
- );
- inputPaths = (
- "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
- "${PODS_ROOT}/Manifest.lock",
- );
- name = "[CP] Check Pods Manifest.lock";
- outputFileListPaths = (
- );
- outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-Passepartout-iOS-Tunnel-checkManifestLockResult.txt",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
- showEnvVarsInLog = 0;
- };
- C3A988ABD9CCD3E4C5E86591 /* [CP] Embed Pods Frameworks */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputFileListPaths = (
- );
- inputPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-Passepartout-CoreTests/Pods-Passepartout-CoreTests-frameworks.sh",
- "${PODS_ROOT}/OpenSSL-Apple/frameworks/iPhone/openssl.framework",
- "${BUILT_PRODUCTS_DIR}/SSZipArchive/SSZipArchive.framework",
- "${BUILT_PRODUCTS_DIR}/SwiftyBeaver/SwiftyBeaver.framework",
- "${BUILT_PRODUCTS_DIR}/TunnelKit/TunnelKit.framework",
- );
- name = "[CP] Embed Pods Frameworks";
- outputFileListPaths = (
- );
- outputPaths = (
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SSZipArchive.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyBeaver.framework",
- "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/TunnelKit.framework",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Passepartout-CoreTests/Pods-Passepartout-CoreTests-frameworks.sh\"\n";
- showEnvVarsInLog = 0;
- };
- D6AF52B99BBE4A3C74D968EC /* [CP] Check Pods Manifest.lock */ = {
+ 8598326924C7B7B17B82A427 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@@ -1027,6 +1030,28 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
+ C049DFE2FEC5C79568EE5396 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-PassepartoutCoreTests-iOS-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -1067,12 +1092,12 @@
0E3152CD223FA05400F61841 /* ConnectionProfile.swift in Sources */,
0E3152BC223FA03D00F61841 /* ApplicationError.swift in Sources */,
0E3152C9223FA04D00F61841 /* InfrastructureFactory.swift in Sources */,
- 0E58BD9322404EF1006FB157 /* Intents.intentdefinition in Sources */,
0E3152D3223FA05400F61841 /* EndpointDataSource.swift in Sources */,
0E3152D4223FA05400F61841 /* Preferences.swift in Sources */,
0EFB901822764689006405E4 /* ProfileNetworkSettings.swift in Sources */,
0E3152C0223FA03D00F61841 /* Utils.swift in Sources */,
0E3152CB223FA04D00F61841 /* Pool.swift in Sources */,
+ 0E3CAFC0229AAE770008E5C8 /* Intents.intentdefinition in Sources */,
0E3152C7223FA04800F61841 /* VPNStatus.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1092,7 +1117,6 @@
buildActionMask = 2147483647;
files = (
0ECEE44E20E1122200A6BB43 /* TableModel.swift in Sources */,
- 0E58BF65224152F9006FB157 /* Intents.intentdefinition in Sources */,
0ED38AD9213F33150004D387 /* WizardHostViewController.swift in Sources */,
0EE3BBB2215ED3A900F30952 /* AboutViewController.swift in Sources */,
0EBE3A79213C4E5500BFA2F5 /* OrganizerViewController.swift in Sources */,
@@ -1153,12 +1177,12 @@
/* Begin PBXTargetDependency section */
0E3152A6223F9EF500F61841 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
- target = 0E31529A223F9EF400F61841 /* Passepartout-Core */;
+ target = 0E31529A223F9EF400F61841 /* PassepartoutCore-iOS */;
targetProxy = 0E3152A5223F9EF500F61841 /* PBXContainerItemProxy */;
};
0E3152AF223F9EF500F61841 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
- target = 0E31529A223F9EF400F61841 /* Passepartout-Core */;
+ target = 0E31529A223F9EF400F61841 /* PassepartoutCore-iOS */;
targetProxy = 0E3152AE223F9EF500F61841 /* PBXContainerItemProxy */;
};
0EDE8DC720C86910004C739C /* PBXTargetDependency */ = {
@@ -1169,23 +1193,6 @@
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
- 0E05C5DF20D198B9006EE732 /* Localizable.strings */ = {
- isa = PBXVariantGroup;
- children = (
- 0E05C5DE20D198B9006EE732 /* en */,
- 0E533B142257C1DC00EF94FC /* it */,
- 0E0B6CE3226F3CDF00C1B244 /* de */,
- 0E0B6CE5226F45B100C1B244 /* ru */,
- 0E411BA42272184A00E0852C /* pt-BR */,
- 0EE2FA672291E50300F56F49 /* nl */,
- 0EF4EF80229431D20030E6EB /* el */,
- 0E9DE06C22992DE600DEC291 /* sv */,
- 0EE4EB2A229A6AF8000E4BA1 /* fr */,
- 0E3CAFC7229B28310008E5C8 /* es */,
- );
- name = Localizable.strings;
- sourceTree = "";
- };
0E24273C225950450064A1A3 /* About.storyboard */ = {
isa = PBXVariantGroup;
children = (
@@ -1202,6 +1209,46 @@
name = Shortcuts.storyboard;
sourceTree = "";
};
+ 0E3CAF98229AAE760008E5C8 /* Localizable.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 0E3CAF99229AAE760008E5C8 /* de */,
+ 0E3CAF9C229AAE760008E5C8 /* el */,
+ 0E3CAF9E229AAE760008E5C8 /* en */,
+ 0E3CAFA0229AAE760008E5C8 /* it */,
+ 0E3CAFAB229AAE760008E5C8 /* sv */,
+ 0E3CAFAF229AAE760008E5C8 /* pt-br */,
+ 0E3CAFB1229AAE760008E5C8 /* ru */,
+ 0E3CAFB3229AAE760008E5C8 /* fr */,
+ 0E3CAFB5229AAE760008E5C8 /* nl */,
+ );
+ name = Localizable.strings;
+ sourceTree = "";
+ };
+ 0E3CAF9A229AAE760008E5C8 /* Intents.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 0E3CAF9B229AAE760008E5C8 /* de */,
+ 0E3CAF9D229AAE760008E5C8 /* el */,
+ 0E3CAF9F229AAE760008E5C8 /* en */,
+ 0E3CAFA1229AAE760008E5C8 /* it */,
+ 0E3CAFAC229AAE760008E5C8 /* sv */,
+ 0E3CAFB0229AAE760008E5C8 /* pt-br */,
+ 0E3CAFB2229AAE760008E5C8 /* ru */,
+ 0E3CAFB4229AAE760008E5C8 /* fr */,
+ 0E3CAFB6229AAE760008E5C8 /* nl */,
+ );
+ name = Intents.strings;
+ sourceTree = "";
+ };
+ 0E3CAFAD229AAE760008E5C8 /* Intents.intentdefinition */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 0E3CAFAE229AAE760008E5C8 /* Base */,
+ );
+ name = Intents.intentdefinition;
+ sourceTree = "";
+ };
0E57F63F20C83FC5008323CF /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
@@ -1218,24 +1265,6 @@
name = LaunchScreen.storyboard;
sourceTree = "";
};
- 0E58BD9122404EF1006FB157 /* Intents.intentdefinition */ = {
- isa = PBXVariantGroup;
- children = (
- 0E533B0C2257BAB900EF94FC /* Base */,
- 0E533B102257C0F200EF94FC /* it */,
- 0E242735225944060064A1A3 /* en */,
- 0E108485226F3CC100BA41E9 /* de */,
- 0E0B6CE4226F45B000C1B244 /* ru */,
- 0E411BA32272183700E0852C /* pt-BR */,
- 0EE2FA662291E4AA00F56F49 /* nl */,
- 0EF4EF7F229431CB0030E6EB /* el */,
- 0E9DE06B22992DE000DEC291 /* sv */,
- 0EE4EB29229A6AF8000E4BA1 /* fr */,
- 0E3CAFC5229B033E0008E5C8 /* es */,
- );
- name = Intents.intentdefinition;
- sourceTree = "";
- };
0ED38ADC213F44D00004D387 /* Organizer.storyboard */ = {
isa = PBXVariantGroup;
children = (
@@ -1249,7 +1278,7 @@
/* Begin XCBuildConfiguration section */
0E3152B2223F9EF500F61841 /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = D7CC6F055B1ECE468E956C00 /* Pods-Passepartout-Core.debug.xcconfig */;
+ baseConfigurationReference = A1C4E67627603307808F2FFC /* Pods-PassepartoutCore-iOS.debug.xcconfig */;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
CODE_SIGN_IDENTITY = "iPhone Developer";
@@ -1260,7 +1289,7 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
- INFOPLIST_FILE = "Passepartout-Core/Info.plist";
+ INFOPLIST_FILE = "PassepartoutCore-iOS/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
@@ -1269,8 +1298,8 @@
);
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
- PRODUCT_BUNDLE_IDENTIFIER = "com.algoritmico.ios.Passepartout-Core";
- PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+ PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.PassepartoutCore;
+ PRODUCT_NAME = PassepartoutCore;
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -1281,7 +1310,7 @@
};
0E3152B3223F9EF500F61841 /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 0006BCD0B73ABD3B2B701604 /* Pods-Passepartout-Core.release.xcconfig */;
+ baseConfigurationReference = F1BECEC1D93FEBDB17B714D8 /* Pods-PassepartoutCore-iOS.release.xcconfig */;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
CODE_SIGN_IDENTITY = "iPhone Developer";
@@ -1292,7 +1321,7 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
- INFOPLIST_FILE = "Passepartout-Core/Info.plist";
+ INFOPLIST_FILE = "PassepartoutCore-iOS/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
@@ -1300,8 +1329,8 @@
"@loader_path/Frameworks",
);
MTL_FAST_MATH = YES;
- PRODUCT_BUNDLE_IDENTIFIER = "com.algoritmico.ios.Passepartout-Core";
- PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
+ PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.PassepartoutCore;
+ PRODUCT_NAME = PassepartoutCore;
SKIP_INSTALL = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -1312,10 +1341,10 @@
};
0E3152B4223F9EF500F61841 /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = D35137256E20958EA0A025A0 /* Pods-Passepartout-CoreTests.debug.xcconfig */;
+ baseConfigurationReference = 0FD7B360EE444EF1CDBFDF1C /* Pods-PassepartoutCoreTests-iOS.debug.xcconfig */;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
- INFOPLIST_FILE = "Passepartout-CoreTests/Info.plist";
+ INFOPLIST_FILE = "PassepartoutCoreTests-iOS/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
@@ -1324,7 +1353,7 @@
);
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
- PRODUCT_BUNDLE_IDENTIFIER = "com.algoritmico.ios.Passepartout-CoreTests";
+ PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.PassepartoutCoreTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -1333,10 +1362,10 @@
};
0E3152B5223F9EF500F61841 /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 306E9009D8A771C5756ACC83 /* Pods-Passepartout-CoreTests.release.xcconfig */;
+ baseConfigurationReference = 234D3C887F46AD64480495BB /* Pods-PassepartoutCoreTests-iOS.release.xcconfig */;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
- INFOPLIST_FILE = "Passepartout-CoreTests/Info.plist";
+ INFOPLIST_FILE = "PassepartoutCoreTests-iOS/Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 12.1;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
@@ -1344,7 +1373,7 @@
"@loader_path/Frameworks",
);
MTL_FAST_MATH = YES;
- PRODUCT_BUNDLE_IDENTIFIER = "com.algoritmico.ios.Passepartout-CoreTests";
+ PRODUCT_BUNDLE_IDENTIFIER = com.algoritmico.ios.PassepartoutCoreTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -1481,7 +1510,7 @@
};
0E57F65620C83FC7008323CF /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 84E4F391724F65947460C4C6 /* Pods-Passepartout-iOS.debug.xcconfig */;
+ baseConfigurationReference = F4959B5F3CB1BBC2C46EA639 /* Pods-Passepartout-iOS.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
@@ -1505,7 +1534,7 @@
};
0E57F65720C83FC7008323CF /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 1AA0A7801E34D3A4286280AB /* Pods-Passepartout-iOS.release.xcconfig */;
+ baseConfigurationReference = 53B773C4BAE7EDB38C7AFCD1 /* Pods-Passepartout-iOS.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
@@ -1528,7 +1557,7 @@
};
0EDE8DCA20C86910004C739C /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = CA8AA77D192D2ABAABC8A4DA /* Pods-Passepartout-iOS-Tunnel.debug.xcconfig */;
+ baseConfigurationReference = 09CB728874F1553EF27BAAB9 /* Pods-Passepartout-iOS-Tunnel.debug.xcconfig */;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = "Passepartout-iOS-Tunnel/Tunnel.entitlements";
CODE_SIGN_IDENTITY = "iPhone Developer";
@@ -1552,7 +1581,7 @@
};
0EDE8DCB20C86910004C739C /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = C8A8897C87D8BCB817593651 /* Pods-Passepartout-iOS-Tunnel.release.xcconfig */;
+ baseConfigurationReference = 4BD12523ABCBF7ED941FC270 /* Pods-Passepartout-iOS-Tunnel.release.xcconfig */;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = "Passepartout-iOS-Tunnel/Tunnel.entitlements";
CODE_SIGN_IDENTITY = "iPhone Developer";
@@ -1576,7 +1605,7 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
- 0E3152B6223F9EF500F61841 /* Build configuration list for PBXNativeTarget "Passepartout-Core" */ = {
+ 0E3152B6223F9EF500F61841 /* Build configuration list for PBXNativeTarget "PassepartoutCore-iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0E3152B2223F9EF500F61841 /* Debug */,
@@ -1585,7 +1614,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- 0E3152B8223F9EF500F61841 /* Build configuration list for PBXNativeTarget "Passepartout-CoreTests" */ = {
+ 0E3152B8223F9EF500F61841 /* Build configuration list for PBXNativeTarget "PassepartoutCoreTests-iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0E3152B4223F9EF500F61841 /* Debug */,
diff --git a/Passepartout.xcodeproj/xcshareddata/xcschemes/Passepartout-Core.xcscheme b/Passepartout.xcodeproj/xcshareddata/xcschemes/Passepartout-Core.xcscheme
index 5af84744..d896fdc6 100644
--- a/Passepartout.xcodeproj/xcshareddata/xcschemes/Passepartout-Core.xcscheme
+++ b/Passepartout.xcodeproj/xcshareddata/xcschemes/Passepartout-Core.xcscheme
@@ -15,8 +15,8 @@
@@ -33,8 +33,8 @@
@@ -43,8 +43,8 @@
@@ -65,8 +65,8 @@
@@ -83,8 +83,8 @@
diff --git a/Passepartout.xcodeproj/xcshareddata/xcschemes/Passepartout-iOS.xcscheme b/Passepartout.xcodeproj/xcshareddata/xcschemes/Passepartout-iOS.xcscheme
index ed4df1f9..b4fde8fd 100644
--- a/Passepartout.xcodeproj/xcshareddata/xcschemes/Passepartout-iOS.xcscheme
+++ b/Passepartout.xcodeproj/xcshareddata/xcschemes/Passepartout-iOS.xcscheme
@@ -57,8 +57,8 @@
diff --git a/Passepartout/Resources/Base.lproj/Intents.intentdefinition b/Passepartout/Resources/Base.lproj/Intents.intentdefinition
deleted file mode 100644
index bee0e46c..00000000
--- a/Passepartout/Resources/Base.lproj/Intents.intentdefinition
+++ /dev/null
@@ -1,673 +0,0 @@
-
-
-
-
- INEnums
-
- INIntentDefinitionModelVersion
- 1.0
- INIntentDefinitionSystemVersion
- 18D42
- INIntentDefinitionToolsBuildVersion
- 10E125
- INIntentDefinitionToolsVersion
- 10.2
- INIntents
-
-
- INIntentCategory
- generic
- INIntentDescription
- Connects to a host profile
- INIntentDescriptionID
- eXXb2z
- INIntentLastParameterTag
- 5
- INIntentName
- ConnectVPN
- INIntentParameterCombinations
-
- context,profileId
-
- INIntentParameterCombinationIsPrimary
-
- INIntentParameterCombinationSubtitle
-
- INIntentParameterCombinationSubtitleID
- uMFvJW
- INIntentParameterCombinationSupportsBackgroundExecution
-
- INIntentParameterCombinationTitle
- Connect to ${profileId}
- INIntentParameterCombinationTitleID
- U6o81V
-
-
- INIntentParameters
-
-
- INIntentParameterDisplayPriority
- 1
- INIntentParameterName
- context
- INIntentParameterSupportsMultipleValues
-
- INIntentParameterTag
- 5
- INIntentParameterType
- String
-
-
- INIntentParameterDisplayPriority
- 2
- INIntentParameterName
- profileId
- INIntentParameterSupportsMultipleValues
-
- INIntentParameterTag
- 4
- INIntentParameterType
- String
-
-
- INIntentResponse
-
- INIntentResponseCodes
-
-
- INIntentResponseCodeFormatString
-
- INIntentResponseCodeFormatStringID
- uKU9RD
- INIntentResponseCodeName
- failure
- INIntentResponseCodeSuccess
-
-
-
- INIntentResponseCodeFormatString
-
- INIntentResponseCodeFormatStringID
- WNbRl5
- INIntentResponseCodeName
- success
- INIntentResponseCodeSuccess
-
-
-
- INIntentResponseLastParameterTag
- 0
- INIntentResponseParameters
-
-
- INIntentRestrictions
- 0
- INIntentTitle
- Connect to VPN
- INIntentTitleID
- LA99yM
- INIntentType
- Custom
- INIntentUserConfirmationRequired
-
- INIntentVerb
- Do
-
-
- INIntentCategory
- generic
- INIntentDescription
- Adds current Wi-Fi to trusted networks
- INIntentDescriptionID
- BKxs8X
- INIntentLastParameterTag
- 0
- INIntentName
- TrustCurrentNetwork
- INIntentParameterCombinations
-
-
-
- INIntentParameterCombinationIsPrimary
-
- INIntentParameterCombinationSubtitle
-
- INIntentParameterCombinationSubtitleID
- AxbXUn
- INIntentParameterCombinationSupportsBackgroundExecution
-
- INIntentParameterCombinationTitle
-
- INIntentParameterCombinationTitleID
- POyDPM
-
-
- INIntentParameters
-
- INIntentResponse
-
- INIntentResponseCodes
-
-
- INIntentResponseCodeFormatString
-
- INIntentResponseCodeFormatStringID
- x3pVKZ
- INIntentResponseCodeName
- failure
- INIntentResponseCodeSuccess
-
-
-
- INIntentResponseCodeFormatString
-
- INIntentResponseCodeFormatStringID
- qEDn4J
- INIntentResponseCodeName
- success
- INIntentResponseCodeSuccess
-
-
-
- INIntentResponseLastParameterTag
- 0
- INIntentResponseParameters
-
-
- INIntentRestrictions
- 0
- INIntentTitle
- Trust current Wi-Fi
- INIntentTitleID
- m2E7SI
- INIntentType
- Custom
- INIntentUserConfirmationRequired
-
- INIntentVerb
- Do
-
-
- INIntentCategory
- generic
- INIntentDescription
- Disables the VPN service
- INIntentDescriptionID
- eQ1yzr
- INIntentLastParameterTag
- 0
- INIntentName
- DisableVPN
- INIntentParameterCombinations
-
-
-
- INIntentParameterCombinationIsPrimary
-
- INIntentParameterCombinationSubtitle
-
- INIntentParameterCombinationSubtitleID
- 85kxu8
- INIntentParameterCombinationSupportsBackgroundExecution
-
- INIntentParameterCombinationTitle
-
- INIntentParameterCombinationTitleID
- IeGsEq
-
-
- INIntentParameters
-
- INIntentResponse
-
- INIntentResponseCodes
-
-
- INIntentResponseCodeFormatString
-
- INIntentResponseCodeFormatStringID
- fnSNbT
- INIntentResponseCodeName
- failure
- INIntentResponseCodeSuccess
-
-
-
- INIntentResponseCodeFormatString
-
- INIntentResponseCodeFormatStringID
- oKHXZ3
- INIntentResponseCodeName
- success
- INIntentResponseCodeSuccess
-
-
-
- INIntentResponseLastParameterTag
- 0
- INIntentResponseParameters
-
-
- INIntentRestrictions
- 0
- INIntentTitle
- Disable VPN
- INIntentTitleID
- 1ZRTCZ
- INIntentType
- Custom
- INIntentUserConfirmationRequired
-
- INIntentVerb
- Do
-
-
- INIntentCategory
- generic
- INIntentDescription
- Removes current Wi-Fi from trusted networks
- INIntentDescriptionID
- 7eoAss
- INIntentLastParameterTag
- 0
- INIntentName
- UntrustCurrentNetwork
- INIntentParameterCombinations
-
-
-
- INIntentParameterCombinationIsPrimary
-
- INIntentParameterCombinationSubtitle
-
- INIntentParameterCombinationSubtitleID
- pb3MGt
- INIntentParameterCombinationSupportsBackgroundExecution
-
- INIntentParameterCombinationTitle
-
- INIntentParameterCombinationTitleID
- 0Wu9nb
-
-
- INIntentParameters
-
- INIntentResponse
-
- INIntentResponseCodes
-
-
- INIntentResponseCodeFormatString
-
- INIntentResponseCodeFormatStringID
- r0ZjO4
- INIntentResponseCodeName
- failure
- INIntentResponseCodeSuccess
-
-
-
- INIntentResponseCodeFormatString
-
- INIntentResponseCodeFormatStringID
- rtaAzk
- INIntentResponseCodeName
- success
- INIntentResponseCodeSuccess
-
-
-
- INIntentResponseLastParameterTag
- 0
- INIntentResponseParameters
-
-
- INIntentRestrictions
- 0
- INIntentTitle
- Untrust current Wi-Fi
- INIntentTitleID
- rd1T8p
- INIntentType
- Custom
- INIntentUserConfirmationRequired
-
- INIntentVerb
- Do
-
-
- INIntentCategory
- generic
- INIntentDescription
- Adds cellular to trusted networks
- INIntentDescriptionID
- 9GpJt5
- INIntentLastParameterTag
- 0
- INIntentName
- TrustCellularNetwork
- INIntentParameterCombinations
-
-
-
- INIntentParameterCombinationIsPrimary
-
- INIntentParameterCombinationSubtitle
-
- INIntentParameterCombinationSubtitleID
- vIPVA5
- INIntentParameterCombinationSupportsBackgroundExecution
-
- INIntentParameterCombinationTitle
-
- INIntentParameterCombinationTitleID
- NWWgCl
-
-
- INIntentParameters
-
- INIntentResponse
-
- INIntentResponseCodes
-
-
- INIntentResponseCodeFormatString
-
- INIntentResponseCodeFormatStringID
- nMRaxS
- INIntentResponseCodeName
- failure
- INIntentResponseCodeSuccess
-
-
-
- INIntentResponseCodeFormatString
-
- INIntentResponseCodeFormatStringID
- gSqy7Y
- INIntentResponseCodeName
- success
- INIntentResponseCodeSuccess
-
-
-
- INIntentResponseLastParameterTag
- 0
- INIntentResponseParameters
-
-
- INIntentRestrictions
- 0
- INIntentTitle
- Trust cellular network
- INIntentTitleID
- H4taev
- INIntentType
- Custom
- INIntentUserConfirmationRequired
-
- INIntentVerb
- Do
-
-
- INIntentCategory
- generic
- INIntentDescription
- Removes cellular from trusted networks
- INIntentDescriptionID
- 0jRWn5
- INIntentLastParameterTag
- 0
- INIntentName
- UntrustCellularNetwork
- INIntentParameterCombinations
-
-
-
- INIntentParameterCombinationIsPrimary
-
- INIntentParameterCombinationSubtitle
-
- INIntentParameterCombinationSubtitleID
- qRkLSU
- INIntentParameterCombinationSupportsBackgroundExecution
-
- INIntentParameterCombinationTitle
-
- INIntentParameterCombinationTitleID
- ggzKA2
-
-
- INIntentParameters
-
- INIntentResponse
-
- INIntentResponseCodes
-
-
- INIntentResponseCodeFormatString
-
- INIntentResponseCodeFormatStringID
- YncGoj
- INIntentResponseCodeName
- failure
- INIntentResponseCodeSuccess
-
-
-
- INIntentResponseCodeFormatString
-
- INIntentResponseCodeFormatStringID
- BW8KLX
- INIntentResponseCodeName
- success
- INIntentResponseCodeSuccess
-
-
-
- INIntentResponseLastParameterTag
- 0
- INIntentResponseParameters
-
-
- INIntentRestrictions
- 0
- INIntentTitle
- Untrust cellular network
- INIntentTitleID
- wB1iYX
- INIntentType
- Custom
- INIntentUserConfirmationRequired
-
- INIntentVerb
- Do
-
-
- INIntentCategory
- generic
- INIntentDescription
- Connects to a specific location of a provider profile
- INIntentDescriptionID
- KjkCfU
- INIntentLastParameterTag
- 3
- INIntentName
- MoveToLocation
- INIntentParameterCombinations
-
- providerId,poolName,poolId
-
- INIntentParameterCombinationIsPrimary
-
- INIntentParameterCombinationSubtitle
- With ${providerId} provider
- INIntentParameterCombinationSubtitleID
- 66bZBE
- INIntentParameterCombinationSupportsBackgroundExecution
-
- INIntentParameterCombinationTitle
- Connect to ${poolName}
- INIntentParameterCombinationTitleID
- WnTPFg
-
-
- INIntentParameters
-
-
- INIntentParameterDisplayPriority
- 1
- INIntentParameterName
- providerId
- INIntentParameterSupportsMultipleValues
-
- INIntentParameterTag
- 2
- INIntentParameterType
- String
-
-
- INIntentParameterDisplayPriority
- 2
- INIntentParameterName
- poolId
- INIntentParameterSupportsMultipleValues
-
- INIntentParameterTag
- 3
- INIntentParameterType
- String
-
-
- INIntentParameterDisplayPriority
- 3
- INIntentParameterName
- poolName
- INIntentParameterSupportsMultipleValues
-
- INIntentParameterTag
- 1
- INIntentParameterType
- String
-
-
- INIntentResponse
-
- INIntentResponseCodes
-
-
- INIntentResponseCodeFormatString
-
- INIntentResponseCodeFormatStringID
- PmWNkC
- INIntentResponseCodeName
- failure
- INIntentResponseCodeSuccess
-
-
-
- INIntentResponseCodeFormatString
-
- INIntentResponseCodeFormatStringID
- O6nCLQ
- INIntentResponseCodeName
- success
- INIntentResponseCodeSuccess
-
-
-
- INIntentResponseLastParameterTag
- 0
- INIntentResponseParameters
-
-
- INIntentRestrictions
- 0
- INIntentTitle
- Connect to provider location
- INIntentTitleID
- qo3Szz
- INIntentType
- Custom
- INIntentUserConfirmationRequired
-
- INIntentVerb
- Go
-
-
- INIntentCategory
- generic
- INIntentDescription
- Enables the VPN service with the profile currently in use
- INIntentDescriptionID
- xY97Vu
- INIntentLastParameterTag
- 0
- INIntentName
- EnableVPN
- INIntentParameterCombinations
-
-
-
- INIntentParameterCombinationIsPrimary
-
- INIntentParameterCombinationSubtitle
- With profile in use
- INIntentParameterCombinationSubtitleID
- NCoK9B
- INIntentParameterCombinationSupportsBackgroundExecution
-
- INIntentParameterCombinationTitle
-
- INIntentParameterCombinationTitleID
- yesvFP
-
-
- INIntentParameters
-
- INIntentResponse
-
- INIntentResponseCodes
-
-
- INIntentResponseCodeFormatString
-
- INIntentResponseCodeFormatStringID
- FJp18d
- INIntentResponseCodeName
- failure
- INIntentResponseCodeSuccess
-
-
-
- INIntentResponseCodeFormatString
-
- INIntentResponseCodeFormatStringID
- lV5LVw
- INIntentResponseCodeName
- success
- INIntentResponseCodeSuccess
-
-
-
- INIntentResponseLastParameterTag
- 0
- INIntentResponseParameters
-
-
- INIntentRestrictions
- 0
- INIntentTitle
- Enable VPN
- INIntentTitleID
- lQ6ziK
- INIntentType
- Custom
- INIntentUserConfirmationRequired
-
- INIntentVerb
- Do
-
-
-
-
diff --git a/Passepartout/Resources/Web/net/mullvad.json b/Passepartout/Resources/Web/net/mullvad.json
deleted file mode 100644
index 16c06e82..00000000
--- a/Passepartout/Resources/Web/net/mullvad.json
+++ /dev/null
@@ -1 +0,0 @@
-{"presets":[{"id":"default","name":"Default","comment":"256-bit encryption","cfg":{"ca":"-----BEGIN CERTIFICATE-----\nMIIGIzCCBAugAwIBAgIJAK6BqXN9GHI0MA0GCSqGSIb3DQEBCwUAMIGfMQswCQYD\nVQQGEwJTRTERMA8GA1UECAwIR290YWxhbmQxEzARBgNVBAcMCkdvdGhlbmJ1cmcx\nFDASBgNVBAoMC0FtYWdpY29tIEFCMRAwDgYDVQQLDAdNdWxsdmFkMRswGQYDVQQD\nDBJNdWxsdmFkIFJvb3QgQ0EgdjIxIzAhBgkqhkiG9w0BCQEWFHNlY3VyaXR5QG11\nbGx2YWQubmV0MB4XDTE4MTEwMjExMTYxMVoXDTI4MTAzMDExMTYxMVowgZ8xCzAJ\nBgNVBAYTAlNFMREwDwYDVQQIDAhHb3RhbGFuZDETMBEGA1UEBwwKR290aGVuYnVy\nZzEUMBIGA1UECgwLQW1hZ2ljb20gQUIxEDAOBgNVBAsMB011bGx2YWQxGzAZBgNV\nBAMMEk11bGx2YWQgUm9vdCBDQSB2MjEjMCEGCSqGSIb3DQEJARYUc2VjdXJpdHlA\nbXVsbHZhZC5uZXQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCifDn7\n5E/Zdx1qsy31rMEzuvbTXqZVZp4bjWbmcyyXqvnayRUHHoovG+lzc+HDL3HJV+kj\nxKpCMkEVWwjY159lJbQbm8kkYntBBREdzRRjjJpTb6haf/NXeOtQJ9aVlCc4dM66\nbEmyAoXkzXVZTQJ8h2FE55KVxHi5Sdy4XC5zm0wPa4DPDokNp1qm3A9Xicq3Hsfl\nLbMZRCAGuI+Jek6caHqiKjTHtujn6Gfxv2WsZ7SjerUAk+mvBo2sfKmB7octxG7y\nAOFFg7YsWL0AxddBWqgq5R/1WDJ9d1Cwun9WGRRQ1TLvzF1yABUerjjKrk89RCzY\nISwsKcgJPscaDqZgO6RIruY/xjuTtrnZSv+FXs+Woxf87P+QgQd76LC0MstTnys+\nAfTMuMPOLy9fMfEzs3LP0Nz6v5yjhX8ff7+3UUI3IcMxCvyxdTPClY5IvFdW7CCm\nmLNzakmx5GCItBWg/EIg1K1SG0jU9F8vlNZUqLKz42hWy/xB5C4QYQQ9ILdu4ara\nPnrXnmd1D1QKVwKQ1DpWhNbpBDfE776/4xXD/tGM5O0TImp1NXul8wYsDi8g+e0p\nxNgY3Pahnj1yfG75Yw82spZanUH0QSNoMVMWnmV2hXGsWqypRq0pH8mPeLzeKa82\ngzsAZsouRD1k8wFlYA4z9HQFxqfcntTqXuwQcQIDAQABo2AwXjAdBgNVHQ4EFgQU\nfaEyaBpGNzsqttiSMETq+X/GJ0YwHwYDVR0jBBgwFoAUfaEyaBpGNzsqttiSMETq\n+X/GJ0YwCwYDVR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL\nBQADggIBADH5izxu4V8Javal8EA4DxZxIHUsWCg5cuopB28PsyJYpyKipsBoI8+R\nXqbtrLLue4WQfNPZHLXlKi+A3GTrLdlnenYzXVipPd+n3vRZyofaB3Jtb03nirVW\nGa8FG21Xy/f4rPqwcW54lxrnnh0SA0hwuZ+b2yAWESBXPxrzVQdTWCqoFI6/aRnN\n8RyZn0LqRYoW7WDtKpLmfyvshBmmu4PCYSh/SYiFHgR9fsWzVcxdySDsmX8wXowu\nFfp8V9sFhD4TsebAaplaICOuLUgj+Yin5QzgB0F9Ci3Zh6oWwl64SL/OxxQLpzMW\nzr0lrWsQrS3PgC4+6JC4IpTXX5eUqfSvHPtbRKK0yLnd9hYgvZUBvvZvUFR/3/fW\n+mpBHbZJBu9+/1uux46M4rJ2FeaJUf9PhYCPuUj63yu0Grn0DreVKK1SkD5V6qXN\n0TmoxYyguhfsIPCpI1VsdaSWuNjJ+a/HIlKIU8vKp5iN/+6ZTPAg9Q7s3Ji+vfx/\nAhFtQyTpIYNszVzNZyobvkiMUlK+eUKGlHVQp73y6MmGIlbBbyzpEoedNU4uFu57\nmw4fYGHqYZmYqFaiNQv4tVrGkg6p+Ypyu1zOfIHF7eqlAOu/SyRTvZkt9VtSVEOV\nH7nDIGdrCC9U/g1Lqk8Td00Oj8xesyKzsG214Xd8m7/7GmJ7nXe5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIGHDCCBASgAwIBAgIEEAAAADANBgkqhkiG9w0BAQsFADCBnzELMAkGA1UEBhMC\nU0UxETAPBgNVBAgMCEdvdGFsYW5kMRMwEQYDVQQHDApHb3RoZW5idXJnMRQwEgYD\nVQQKDAtBbWFnaWNvbSBBQjEQMA4GA1UECwwHTXVsbHZhZDEbMBkGA1UEAwwSTXVs\nbHZhZCBSb290IENBIHYyMSMwIQYJKoZIhvcNAQkBFhRzZWN1cml0eUBtdWxsdmFk\nLm5ldDAeFw0xODExMDIxMTI2MDNaFw0xOTExMDIxMTI2MDNaMIGdMQswCQYDVQQG\nEwJTRTERMA8GA1UECAwIR290YWxhbmQxFDASBgNVBAoMC0FtYWdpY29tIEFCMRAw\nDgYDVQQLDAdNdWxsdmFkMS4wLAYDVQQDDCVNdWxsdmFkIFRyYW5zaXRpb24tSW50\nZXJtZWRpYXRlIENBIHYxMSMwIQYJKoZIhvcNAQkBFhRzZWN1cml0eUBtdWxsdmFk\nLm5ldDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOAvizkx9wPHo9qH\nTKdSe1ckgoe20PsN++pAnIZ1ZrrUAW/Y/7HjeZvPH1nJHWtQaoY72mQKbl3WVafZ\nTHm+t0qtnAGcI+1dZjAERmPBZyVtbsOegITqWiAyw5QGfq/+pmC752a8NxHy73Pt\ncvt81vML87dx0vzOm2IPCr2mdsdxMsoETuBCED/gY6N4BEnK/NS5JjNnpynq4bZb\nobzKuLKTmFabU5CVttg7eBcI4O6KhOYbP4T6Xpo+ALRN7+fyAjir2YKIifccftf5\neiB23Ov1kt9k4nIc3lt6tDHaz6INPHjigHJ2AuJDb7V3GH0czdu2Elr5tZC+5sDX\nNcMSOPNA9L4o9svA553c21tg/1cwKUD3GJoCzIN9k9+ba9VWnpOiebNakdTUlegy\n5LlzO+aVpZbMoAHoP/1PHqPe9Nz62vrt2wtTfuP5cTCHkTIFy6X6LWitWmox3lLo\naaruQ2x6WF64bGuFHKLDlMNRWd63GE/ZE3AXTmmYIE+CgZ6aPyFuUluAA9C6r7bU\n052ddBIuQLBZ2Pj4yZ0UK2aymjS4OBYddzLkPM4B5Mttcj3nbk8FKHDHTXLlyIvE\n9BQAejH2p+sOboWudHyw7B7kDqWt9aHHYrQbSimnaY6QoJ8VisyFZVrrIQMQxwLw\nAvBScVkmBDTP1iG0B4tGzCRTIilPAgMBAAGjYDBeMB0GA1UdDgQWBBQVxpaQ55d1\nyngyg7YEXMuTDc9hPzAfBgNVHSMEGDAWgBR9oTJoGkY3Oyq22JIwROr5f8YnRjAL\nBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEA\nSTee9JP7tegxul90VTRyG53l37fuZGjrp70tYQfl8676lTyFyZVBF7tAFrJwc1K9\n2d1JnMbyHzyR7LzZr/7tB3w7eIR8Q7TiBAe9eHleMlmK975ivcAhrY0fJ+BO8xgw\n6KE7dOI1jeeff5wF/2KmXybeq2M1phA3KGy+sxc8KrLCVHfXfOnv+b9HRKDqE4/c\n3ALMVHXir9sXDyY5bH7jcOGyVQTPI5ZLxvjndunCkXG595pJqDqUWXS8BYcFExIf\nIQuJ5omt+tyM9U17yOPvwTyadbRW2m7LIcTwPEwC3IUHCUQzqLZkmF2pCQa8hV2b\nq3eK/hV1mHvFbfZcQ+TPl8vl4cRT92vLQGGy51D9t8bVs4bBET0DSPivVcnMqkSO\nvAz7xdXqya36iri27iI3aUdBI/XihT1LkxAJhas9YBt+T2xz7xN+WU/ImB+Cq+sH\nnJNIcB+wE50/rBb+gTaOpEx80Onq277N3TUByVLjCztl1J6cWIy1XObhRVgXLUcT\nB6/Z/zRblHt7f/f5TTUmAwMc+VwvnjpweSV98DpP0MLV6ZEpmh/ij0Dwpc6IoD8u\nLwvyq9jhkSAki5LHO2t1mw0jIjtncxEq/9RmrVP1e3/weYvyhy1T4Mq4NCcPGFR0\n+TUxbjSUGVUuHIPxiR+XptxDWguRhwSYEKSy3EwfOMc=\n-----END CERTIFICATE-----\n","ep":["UDP:1194","UDP:1195","UDP:1196","UDP:1197","UDP:1301","UDP:1302","UDP:53","TCP:443","TCP:80"],"cipher":"AES-256-CBC","auth":"SHA1","frame":0,"ping":10,"reneg":3600,"eku":true},"external":{"hostname":"${id}.mullvad.net"}}],"defaults":{"username":"1234567890","pool":"us","preset":"default"},"categories":[{"name":"","groups":[{"country":"AT","pools":[{"id":"at","country":"AT","addrs":[3644882890,3644882826,628661242]}]},{"country":"AU","area":"bne","pools":[{"id":"au-bne","country":"AU","addrs":[737517730],"area":"bne"}]},{"country":"AU","area":"mel","pools":[{"id":"au-mel","country":"AU","addrs":[1959716042,1959716082,1959716450],"area":"mel"}]},{"country":"AU","pools":[{"id":"au","country":"AU","addrs":[1959716450,1959716042,737518210,1733159747,737517730,3715732930,1733159058,1959716082]}]},{"country":"AU","area":"per","pools":[{"id":"au-per","country":"AU","addrs":[1733159746],"area":"per"}]},{"country":"AU","area":"syd","pools":[{"id":"au-syd","country":"AU","addrs":[1733159058,3715732930,737518210],"area":"syd"}]},{"country":"BE","pools":[{"id":"be","country":"BE","addrs":[3110648522,1540307250,628658058]}]},{"country":"BG","pools":[{"id":"bg","country":"BG","addrs":[3109994562,3109994538]}]},{"country":"BR","pools":[{"id":"br","country":"BR","addrs":[2973978810]}]},{"country":"CA","area":"bc","pools":[{"id":"ca-bc","country":"CA","addrs":[1192491248,1192491345,2891130914,2891130918],"area":"bc"}]},{"country":"CA","area":"on","pools":[{"id":"ca-on","country":"CA","addrs":[3091977858,3343014608,2732306682,3343014512],"area":"on"}]},{"country":"CA","pools":[{"id":"ca","country":"CA","addrs":[1466260626,2333923954,3343014512,2960214706,1466260618,3091977858,2732306682,3343014608,2960214714]}]},{"country":"CA","area":"qc","pools":[{"id":"ca-qc","country":"CA","addrs":[1466260618,2960214706,2333923954,1466260626,2960214714],"area":"qc"}]},{"country":"CH","pools":[{"id":"ch","country":"CH","addrs":[3117722162,1360073762,1382422658,1382422714,3005972650,3104379490,3115804754,3117722274]}]},{"country":"CZ","pools":[{"id":"cz","country":"CZ","addrs":[3114053266,3114053290]}]},{"country":"DE","area":"fra","pools":[{"id":"de-fra","country":"DE","addrs":[3117783940,3117783947,3117783944,1382420570,3107900583,3117783945,3117783942,3110647986,3117783948,1307817930,3117783939,3107900816,3117783941,3117783943,3110647994,3117783946],"area":"fra"}]},{"country":"DE","pools":[{"id":"de","country":"DE","addrs":[1401943338,3117783940,3117783946,3110647986,3117783944,3117783947,1401943330,3117783942,3110647994,3117783943,1307817930,3107900583,3117783941,3107900816,1382420570,3117783945,3117783948,3117783939]}]},{"country":"DK","pools":[{"id":"dk","country":"DK","addrs":[3117342834,3117342839,1382517973,2254083466]}]},{"country":"ES","pools":[{"id":"es","country":"ES","addrs":[1508815394,3285085074,1508815434]}]},{"country":"FI","pools":[{"id":"fi","country":"FI","addrs":[3117154736,3117154731,3117154732,3117154733,3117154734,3117154735]}]},{"country":"FR","area":"mrs","pools":[{"id":"fr-mrs","country":"FR","addrs":[3115462770,3115462771],"area":"mrs"}]},{"country":"FR","pools":[{"id":"fr","country":"FR","addrs":[3115462771,3114053082,3116200274,3112180130,3115462770]}]},{"country":"GB","area":"lon","pools":[{"id":"gb-lon","country":"GB","addrs":[1489680228,3104855444,2372074628,3116922473,3104855450,2372074627,2372074631,3104855350,2372074632,2372074633,3104855447,3104855466,2372074630,3117721844],"area":"lon"}]},{"country":"GB","area":"mnc","pools":[{"id":"gb-mnc","country":"GB","addrs":[3650576964,1508816884,628662180,1508816700],"area":"mnc"}]},{"country":"GB","pools":[{"id":"gb","country":"GB","addrs":[3117721844,3650576964,1508816884,628662180,3104855447,3116922473,3104855350,2372074628,2372074627,2372074632,2372074630,2372074631,2372074633,3104855444,3104855466,3104855450,2372074629,1508816700]}]},{"country":"GR","pools":[{"id":"gr","country":"GR","addrs":[3118613416]}]},{"country":"HK","pools":[{"id":"hk","country":"HK","addrs":[1168229234,3510286482]}]},{"country":"HU","pools":[{"id":"hu","country":"HU","addrs":[3109994122,3116200458]}]},{"country":"IN","pools":[{"id":"in","country":"IN","addrs":[759195743]}]},{"country":"IT","pools":[{"id":"it","country":"IT","addrs":[3644879287,3644879284]}]},{"country":"JP","pools":[{"id":"jp","country":"JP","addrs":[3247706330,3119645746]}]},{"country":"LU","pools":[{"id":"lu","country":"LU","addrs":[3564485744]}]},{"country":"LV","pools":[{"id":"lv","country":"LV","addrs":[531240450]}]},{"country":"MD","pools":[{"id":"md","country":"MD","addrs":[2997849794]}]},{"country":"NL","pools":[{"id":"nl","country":"NL","addrs":[3108079236,3108079237,3108079251,3108079239,3108079242,3108079245,3108079252,3108079238,3108079248,3108079241,3108079246,3108079243,3108079247,3108079249,3108079244,3108079250,3108079240]}]},{"country":"NO","pools":[{"id":"no","country":"NO","addrs":[1532636171,1532636173,1532636172,1532636175,1532636176,1532636177,1532636174]}]},{"country":"NZ","pools":[{"id":"nz","country":"NZ","addrs":[1743215474]}]},{"country":"PL","pools":[{"id":"pl","country":"PL","addrs":[3119830743,3119830738,3003066586]}]},{"country":"PT","pools":[{"id":"pt","country":"PT","addrs":[97445846]}]},{"country":"RO","pools":[{"id":"ro","country":"RO","addrs":[3106737418,3115672778]}]},{"country":"RS","pools":[{"id":"rs","country":"RS","addrs":[2959633270]}]},{"country":"SE","area":"got","pools":[{"id":"se-got","country":"SE","addrs":[3117783688,3117783689,3117783683,3117783686,3117783687,3117783685],"area":"got"}]},{"country":"SE","area":"hel","pools":[{"id":"se-hel","country":"SE","addrs":[3117783172,3117783178,3117783174,3117783177,3117783171,3117783179,3117783183,3117783173],"area":"hel"}]},{"country":"SE","area":"mma","pools":[{"id":"se-mma","country":"SE","addrs":[3247102597,3247102601,3247102596,3247102600,3247102595,3247102602,3247102599,3247102604,3247102603,3247102598],"area":"mma"}]},{"country":"SE","pools":[{"id":"se","country":"SE","addrs":[3247102596,3247102598,3117783689,3108079510,3247102600,3108079512,3117783684,3247102595,3108079509,3247102599,3108079503,3247102603,3117783686,3108079508,3247102597,3247102601,3247102604,3108079511,3108079507,3247102602]}]},{"country":"SE","area":"sto","pools":[{"id":"se-sto","country":"SE","addrs":[3108079514,3108079515,3108079491,3108079513,3108079512,3108079499,3108079500,3108079509,3108079495,3108079507,3108079498,3108079505,3108079496,3108079492,3108079494,3108079501,3108079506,3108079504,3108079503,3108079508,3108079493,3108079510,3108079497,3108079502,3108079511],"area":"sto"}]},{"country":"SG","pools":[{"id":"sg","country":"SG","addrs":[1744738642,1731807262,3112179762]}]},{"country":"UA","pools":[{"id":"ua","country":"UA","addrs":[1540307987]}]},{"country":"US","area":"az","pools":[{"id":"us-az","country":"US","addrs":[1805149014,3234338899,3234338898],"area":"az"}]},{"country":"US","area":"ca","pools":[{"id":"us-ca","country":"US","addrs":[3634506322,3119302722,3634506323,3119302898,1760464698,2915520642,3119302754,3520196131,3119302727,1807067266,3119302746,3520196130,1757976642],"area":"ca"}]},{"country":"US","area":"co","pools":[{"id":"us-co","country":"US","addrs":[3325305859,3325305858],"area":"co"}]},{"country":"US","area":"dc","pools":[{"id":"us-dc","country":"US","addrs":[3485276595,3485276594],"area":"dc"}]},{"country":"US","area":"fl","pools":[{"id":"us-fl","country":"US","addrs":[2905351482,2892123250,3240492170,646215682,3240492186],"area":"fl"}]},{"country":"US","area":"ga","pools":[{"id":"us-ga","country":"US","addrs":[1805151294,1753290994,3495205262],"area":"ga"}]},{"country":"US","area":"hi","pools":[{"id":"us-hi","country":"US","addrs":[],"area":"hi"}]},{"country":"US","area":"il","pools":[{"id":"us-il","country":"US","addrs":[3494713011,3494713019,1156260619,1156260795,1156264043,1753292570,3494712947,1156260779],"area":"il"}]},{"country":"US","area":"ma","pools":[{"id":"us-ma","country":"US","addrs":[1807044387,1807044386],"area":"ma"}]},{"country":"US","area":"ms","pools":[{"id":"us-ms","country":"US","addrs":[2812312338],"area":"ms"}]},{"country":"US","area":"nc","pools":[{"id":"us-nc","country":"US","addrs":[3232439699,3232439698],"area":"nc"}]},{"country":"US","area":"nj","pools":[{"id":"us-nj","country":"US","addrs":[646216762,1815957130,1815949427,400720794,400720770,1110938427],"area":"nj"}]},{"country":"US","area":"ny","pools":[{"id":"us-ny","country":"US","addrs":[1466261346,3118024058,1466261362,1466261370,3563532346,3247706860,2960214242,3118995010,3118994954,1466261354,3118995042,1807147726,3247706842,3247706850,1807147738,3247706874,3247706818,3563532514],"area":"ny"}]},{"country":"US","area":"oh","pools":[{"id":"us-oh","country":"US","addrs":[3485277539,3485277538],"area":"oh"}]},{"country":"US","area":"ok","pools":[{"id":"us-ok","country":"US","addrs":[3225426546,3225426547],"area":"ok"}]},{"country":"US","pools":[{"id":"us","country":"US","addrs":[1753292570,1760464698,3118995042,3119302722,3240492186,646215682,1382424263,3240492170,1156260795,1382424354,1382424274,1382424370,1613533458,1110938427,1382424258,1613534082,1382424359,1815949427,3119302754,2915520642,3119302727,1156264043,3118024058,2905351482,3118994954,3119302746,3118995010,3119302898,3225426018,3494713019]}]},{"country":"US","area":"pa","pools":[{"id":"us-pa","country":"US","addrs":[3225426786,3225426787],"area":"pa"}]},{"country":"US","area":"tx","pools":[{"id":"us-tx","country":"US","addrs":[1613533458,1613534082,1757974066,1805149802],"area":"tx"}]},{"country":"US","area":"ut","pools":[{"id":"us-ut","country":"US","addrs":[3512678571,1807150821],"area":"ut"}]},{"country":"US","area":"va","pools":[{"id":"us-va","country":"US","addrs":[3225426035,3225426034],"area":"va"}]},{"country":"US","area":"wa","pools":[{"id":"us-wa","country":"US","addrs":[1757970838,1757970798,1757970730,1757970890],"area":"wa"}]},{"country":"ZA","pools":[{"id":"za","country":"ZA","addrs":[3236310418]}]}]}],"build":1779,"name":"Mullvad"}
\ No newline at end of file
diff --git a/Passepartout/Resources/Web/net/nordvpn.json b/Passepartout/Resources/Web/net/nordvpn.json
deleted file mode 100644
index 4442330e..00000000
--- a/Passepartout/Resources/Web/net/nordvpn.json
+++ /dev/null
@@ -1 +0,0 @@
-{"presets":[{"id":"default","name":"Default","comment":"256-bit encryption","cfg":{"ca":"-----BEGIN CERTIFICATE-----\nMIIFCjCCAvKgAwIBAgIBATANBgkqhkiG9w0BAQ0FADA5MQswCQYDVQQGEwJQQTEQ\nMA4GA1UEChMHTm9yZFZQTjEYMBYGA1UEAxMPTm9yZFZQTiBSb290IENBMB4XDTE2\nMDEwMTAwMDAwMFoXDTM1MTIzMTIzNTk1OVowOTELMAkGA1UEBhMCUEExEDAOBgNV\nBAoTB05vcmRWUE4xGDAWBgNVBAMTD05vcmRWUE4gUm9vdCBDQTCCAiIwDQYJKoZI\nhvcNAQEBBQADggIPADCCAgoCggIBAMkr/BYhyo0F2upsIMXwC6QvkZps3NN2/eQF\nkfQIS1gql0aejsKsEnmY0Kaon8uZCTXPsRH1gQNgg5D2gixdd1mJUvV3dE3y9FJr\nXMoDkXdCGBodvKJyU6lcfEVF6/UxHcbBguZK9UtRHS9eJYm3rpL/5huQMCppX7kU\neQ8dpCwd3iKITqwd1ZudDqsWaU0vqzC2H55IyaZ/5/TnCk31Q1UP6BksbbuRcwOV\nskEDsm6YoWDnn/IIzGOYnFJRzQH5jTz3j1QBvRIuQuBuvUkfhx1FEwhwZigrcxXu\nMP+QgM54kezgziJUaZcOM2zF3lvrwMvXDMfNeIoJABv9ljw969xQ8czQCU5lMVmA\n37ltv5Ec9U5hZuwk/9QO1Z+d/r6Jx0mlurS8gnCAKJgwa3kyZw6e4FZ8mYL4vpRR\nhPdvRTWCMJkeB4yBHyhxUmTRgJHm6YR3D6hcFAc9cQcTEl/I60tMdz33G6m0O42s\nQt/+AR3YCY/RusWVBJB/qNS94EtNtj8iaebCQW1jHAhvGmFILVR9lzD0EzWKHkvy\nWEjmUVRgCDd6Ne3eFRNS73gdv/C3l5boYySeu4exkEYVxVRn8DhCxs0MnkMHWFK6\nMyzXCCn+JnWFDYPfDKHvpff/kLDobtPBf+Lbch5wQy9quY27xaj0XwLyjOltpiST\nLWae/Q4vAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqG\nSIb3DQEBDQUAA4ICAQC9fUL2sZPxIN2mD32VeNySTgZlCEdVmlq471o/bDMP4B8g\nnQesFRtXY2ZCjs50Jm73B2LViL9qlREmI6vE5IC8IsRBJSV4ce1WYxyXro5rmVg/\nk6a10rlsbK/eg//GHoJxDdXDOokLUSnxt7gk3QKpX6eCdh67p0PuWm/7WUJQxH2S\nDxsT9vB/iZriTIEe/ILoOQF0Aqp7AgNCcLcLAmbxXQkXYCCSB35Vp06u+eTWjG0/\npyS5V14stGtw+fA0DJp5ZJV4eqJ5LqxMlYvEZ/qKTEdoCeaXv2QEmN6dVqjDoTAo\nk0t5u4YRXzEVCfXAC3ocplNdtCA72wjFJcSbfif4BSC8bDACTXtnPC7nD0VndZLp\n+RiNLeiENhk0oTC+UVdSc+n2nJOzkCK0vYu0Ads4JGIB7g8IB3z2t9ICmsWrgnhd\nNdcOe15BincrGA8avQ1cWXsfIKEjbrnEuEk9b5jel6NfHtPKoHc9mDpRdNPISeVa\nwDBM1mJChneHt59Nh8Gah74+TM1jBsw4fhJPvoc7Atcg740JErb904mZfkIEmojC\nVPhBHVQ9LHBAdM8qFI2kRK0IynOmAZhexlP/aT/kpEsEPyaZQlnBn3An1CRz8h0S\nPApL8PytggYKeQmRhl499+6jLxcZ2IegLfqq41dzIjwHwTMplg+1pKIOVojpWA==\n-----END CERTIFICATE-----\n","wrap":{"strategy":"auth","key":{"dir":1,"data":"5oW9r2WaJaIA4rnjnlH/Aw/HLPHOByMr2LK+XmxnAUP1HpN+Zw7uCdTy6lpuTmmWXbhSwnU1G4b8TKiS14rgAtb3DQKb15xNHCbPFOlYgDPPY5+KdICfKfcrnVj5uPX+/Hk46t5A6f7Wy5IYSrsswQ6xopbfJDslHfBkPVNyTNtakqHWy4F4BMSpMZtX1TvlgIFbz8st9VAYzIP8Q7x/+C1R+biDZHdu6dEvyFzH6luXQcT1mMSFMW2wZtUttFQOIS4VGKm9SCghniSyDYj1mKGWyd6WASCQ4zNRmuGNNQmUJ+ezctNI01LcTIXhjNS5P4pW3bLmTrZ638mzNxV/9A=="}},"cipher":"AES-256-CBC","auth":"SHA512","frame":1,"ping":15,"reneg":0,"eku":true,"random":true,"ep":["UDP:1194","TCP:443"]},"external":{"hostname":"${id}.nordvpn.com"}},{"id":"double","name":"Double VPN","comment":"256-bit encryption","cfg":{"ca":"-----BEGIN CERTIFICATE-----\nMIIFCjCCAvKgAwIBAgIBATANBgkqhkiG9w0BAQ0FADA5MQswCQYDVQQGEwJQQTEQ\nMA4GA1UEChMHTm9yZFZQTjEYMBYGA1UEAxMPTm9yZFZQTiBSb290IENBMB4XDTE2\nMDEwMTAwMDAwMFoXDTM1MTIzMTIzNTk1OVowOTELMAkGA1UEBhMCUEExEDAOBgNV\nBAoTB05vcmRWUE4xGDAWBgNVBAMTD05vcmRWUE4gUm9vdCBDQTCCAiIwDQYJKoZI\nhvcNAQEBBQADggIPADCCAgoCggIBAMkr/BYhyo0F2upsIMXwC6QvkZps3NN2/eQF\nkfQIS1gql0aejsKsEnmY0Kaon8uZCTXPsRH1gQNgg5D2gixdd1mJUvV3dE3y9FJr\nXMoDkXdCGBodvKJyU6lcfEVF6/UxHcbBguZK9UtRHS9eJYm3rpL/5huQMCppX7kU\neQ8dpCwd3iKITqwd1ZudDqsWaU0vqzC2H55IyaZ/5/TnCk31Q1UP6BksbbuRcwOV\nskEDsm6YoWDnn/IIzGOYnFJRzQH5jTz3j1QBvRIuQuBuvUkfhx1FEwhwZigrcxXu\nMP+QgM54kezgziJUaZcOM2zF3lvrwMvXDMfNeIoJABv9ljw969xQ8czQCU5lMVmA\n37ltv5Ec9U5hZuwk/9QO1Z+d/r6Jx0mlurS8gnCAKJgwa3kyZw6e4FZ8mYL4vpRR\nhPdvRTWCMJkeB4yBHyhxUmTRgJHm6YR3D6hcFAc9cQcTEl/I60tMdz33G6m0O42s\nQt/+AR3YCY/RusWVBJB/qNS94EtNtj8iaebCQW1jHAhvGmFILVR9lzD0EzWKHkvy\nWEjmUVRgCDd6Ne3eFRNS73gdv/C3l5boYySeu4exkEYVxVRn8DhCxs0MnkMHWFK6\nMyzXCCn+JnWFDYPfDKHvpff/kLDobtPBf+Lbch5wQy9quY27xaj0XwLyjOltpiST\nLWae/Q4vAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqG\nSIb3DQEBDQUAA4ICAQC9fUL2sZPxIN2mD32VeNySTgZlCEdVmlq471o/bDMP4B8g\nnQesFRtXY2ZCjs50Jm73B2LViL9qlREmI6vE5IC8IsRBJSV4ce1WYxyXro5rmVg/\nk6a10rlsbK/eg//GHoJxDdXDOokLUSnxt7gk3QKpX6eCdh67p0PuWm/7WUJQxH2S\nDxsT9vB/iZriTIEe/ILoOQF0Aqp7AgNCcLcLAmbxXQkXYCCSB35Vp06u+eTWjG0/\npyS5V14stGtw+fA0DJp5ZJV4eqJ5LqxMlYvEZ/qKTEdoCeaXv2QEmN6dVqjDoTAo\nk0t5u4YRXzEVCfXAC3ocplNdtCA72wjFJcSbfif4BSC8bDACTXtnPC7nD0VndZLp\n+RiNLeiENhk0oTC+UVdSc+n2nJOzkCK0vYu0Ads4JGIB7g8IB3z2t9ICmsWrgnhd\nNdcOe15BincrGA8avQ1cWXsfIKEjbrnEuEk9b5jel6NfHtPKoHc9mDpRdNPISeVa\nwDBM1mJChneHt59Nh8Gah74+TM1jBsw4fhJPvoc7Atcg740JErb904mZfkIEmojC\nVPhBHVQ9LHBAdM8qFI2kRK0IynOmAZhexlP/aT/kpEsEPyaZQlnBn3An1CRz8h0S\nPApL8PytggYKeQmRhl499+6jLxcZ2IegLfqq41dzIjwHwTMplg+1pKIOVojpWA==\n-----END CERTIFICATE-----\n","wrap":{"strategy":"auth","key":{"dir":1,"data":"5oW9r2WaJaIA4rnjnlH/Aw/HLPHOByMr2LK+XmxnAUP1HpN+Zw7uCdTy6lpuTmmWXbhSwnU1G4b8TKiS14rgAtb3DQKb15xNHCbPFOlYgDPPY5+KdICfKfcrnVj5uPX+/Hk46t5A6f7Wy5IYSrsswQ6xopbfJDslHfBkPVNyTNtakqHWy4F4BMSpMZtX1TvlgIFbz8st9VAYzIP8Q7x/+C1R+biDZHdu6dEvyFzH6luXQcT1mMSFMW2wZtUttFQOIS4VGKm9SCghniSyDYj1mKGWyd6WASCQ4zNRmuGNNQmUJ+ezctNI01LcTIXhjNS5P4pW3bLmTrZ638mzNxV/9A=="}},"cipher":"AES-256-CBC","auth":"SHA512","frame":1,"ping":15,"reneg":0,"eku":true,"random":true,"ep":["TCP:443"]},"external":{"hostname":"${id}.nordvpn.com"}}],"defaults":{"username":"user@mail.com","pool":"us","preset":"default"},"categories":[{"name":"","groups":[{"country":"AL","pools":[{"id":"al10","country":"AL","num":10},{"id":"al11","country":"AL","num":11},{"id":"al12","country":"AL","num":12},{"id":"al13","country":"AL","num":13},{"id":"al8","country":"AL","num":8},{"id":"al9","country":"AL","num":9}]},{"country":"AR","pools":[{"id":"ar10","country":"AR","num":10},{"id":"ar11","country":"AR","num":11},{"id":"ar12","country":"AR","num":12},{"id":"ar13","country":"AR","num":13},{"id":"ar14","country":"AR","num":14},{"id":"ar15","country":"AR","num":15},{"id":"ar16","country":"AR","num":16},{"id":"ar17","country":"AR","num":17},{"id":"ar18","country":"AR","num":18},{"id":"ar19","country":"AR","num":19},{"id":"ar20","country":"AR","num":20},{"id":"ar21","country":"AR","num":21},{"id":"ar22","country":"AR","num":22},{"id":"ar23","country":"AR","num":23},{"id":"ar24","country":"AR","num":24},{"id":"ar25","country":"AR","num":25},{"id":"ar4","country":"AR","num":4},{"id":"ar8","country":"AR","num":8},{"id":"ar9","country":"AR","num":9}]},{"country":"AT","pools":[{"id":"at31","country":"AT","num":31},{"id":"at32","country":"AT","num":32},{"id":"at33","country":"AT","num":33},{"id":"at34","country":"AT","num":34},{"id":"at35","country":"AT","num":35},{"id":"at36","country":"AT","num":36},{"id":"at37","country":"AT","num":37},{"id":"at38","country":"AT","num":38},{"id":"at39","country":"AT","num":39},{"id":"at40","country":"AT","num":40},{"id":"at41","country":"AT","num":41},{"id":"at42","country":"AT","num":42},{"id":"at43","country":"AT","num":43},{"id":"at44","country":"AT","num":44},{"id":"at45","country":"AT","num":45},{"id":"at46","country":"AT","num":46},{"id":"at47","country":"AT","num":47},{"id":"at48","country":"AT","num":48},{"id":"at49","country":"AT","num":49},{"id":"at50","country":"AT","num":50},{"id":"at51","country":"AT","num":51},{"id":"at52","country":"AT","num":52},{"id":"at53","country":"AT","num":53},{"id":"at54","country":"AT","num":54},{"id":"at55","country":"AT","num":55},{"id":"at56","country":"AT","num":56},{"id":"at57","country":"AT","num":57},{"id":"at58","country":"AT","num":58},{"id":"at59","country":"AT","num":59},{"id":"at60","country":"AT","num":60},{"id":"at61","country":"AT","num":61},{"id":"at62","country":"AT","num":62},{"id":"at63","country":"AT","num":63}]},{"country":"AU","pools":[{"id":"au180","country":"AU","num":180},{"id":"au181","country":"AU","num":181},{"id":"au182","country":"AU","num":182},{"id":"au183","country":"AU","num":183},{"id":"au184","country":"AU","num":184},{"id":"au185","country":"AU","num":185},{"id":"au186","country":"AU","num":186},{"id":"au187","country":"AU","num":187},{"id":"au192","country":"AU","num":192},{"id":"au193","country":"AU","num":193},{"id":"au194","country":"AU","num":194},{"id":"au195","country":"AU","num":195},{"id":"au196","country":"AU","num":196},{"id":"au197","country":"AU","num":197},{"id":"au198","country":"AU","num":198},{"id":"au199","country":"AU","num":199},{"id":"au200","country":"AU","num":200},{"id":"au201","country":"AU","num":201},{"id":"au202","country":"AU","num":202},{"id":"au203","country":"AU","num":203},{"id":"au204","country":"AU","num":204},{"id":"au205","country":"AU","num":205},{"id":"au206","country":"AU","num":206},{"id":"au207","country":"AU","num":207},{"id":"au208","country":"AU","num":208},{"id":"au209","country":"AU","num":209},{"id":"au210","country":"AU","num":210},{"id":"au211","country":"AU","num":211},{"id":"au212","country":"AU","num":212},{"id":"au213","country":"AU","num":213},{"id":"au214","country":"AU","num":214},{"id":"au215","country":"AU","num":215},{"id":"au216","country":"AU","num":216},{"id":"au217","country":"AU","num":217},{"id":"au218","country":"AU","num":218},{"id":"au219","country":"AU","num":219},{"id":"au220","country":"AU","num":220},{"id":"au221","country":"AU","num":221},{"id":"au222","country":"AU","num":222},{"id":"au223","country":"AU","num":223},{"id":"au224","country":"AU","num":224},{"id":"au225","country":"AU","num":225},{"id":"au226","country":"AU","num":226},{"id":"au227","country":"AU","num":227},{"id":"au228","country":"AU","num":228},{"id":"au229","country":"AU","num":229},{"id":"au230","country":"AU","num":230},{"id":"au231","country":"AU","num":231},{"id":"au232","country":"AU","num":232},{"id":"au233","country":"AU","num":233},{"id":"au234","country":"AU","num":234},{"id":"au235","country":"AU","num":235},{"id":"au236","country":"AU","num":236},{"id":"au237","country":"AU","num":237},{"id":"au238","country":"AU","num":238},{"id":"au239","country":"AU","num":239},{"id":"au240","country":"AU","num":240},{"id":"au241","country":"AU","num":241},{"id":"au242","country":"AU","num":242},{"id":"au243","country":"AU","num":243},{"id":"au244","country":"AU","num":244},{"id":"au245","country":"AU","num":245},{"id":"au246","country":"AU","num":246},{"id":"au251","country":"AU","num":251},{"id":"au252","country":"AU","num":252},{"id":"au253","country":"AU","num":253},{"id":"au254","country":"AU","num":254},{"id":"au255","country":"AU","num":255},{"id":"au256","country":"AU","num":256},{"id":"au257","country":"AU","num":257},{"id":"au258","country":"AU","num":258},{"id":"au259","country":"AU","num":259},{"id":"au260","country":"AU","num":260},{"id":"au261","country":"AU","num":261},{"id":"au262","country":"AU","num":262},{"id":"au263","country":"AU","num":263},{"id":"au264","country":"AU","num":264},{"id":"au265","country":"AU","num":265},{"id":"au266","country":"AU","num":266},{"id":"au267","country":"AU","num":267},{"id":"au268","country":"AU","num":268},{"id":"au269","country":"AU","num":269},{"id":"au270","country":"AU","num":270},{"id":"au271","country":"AU","num":271},{"id":"au272","country":"AU","num":272},{"id":"au273","country":"AU","num":273},{"id":"au274","country":"AU","num":274},{"id":"au275","country":"AU","num":275},{"id":"au276","country":"AU","num":276},{"id":"au277","country":"AU","num":277},{"id":"au278","country":"AU","num":278},{"id":"au279","country":"AU","num":279},{"id":"au280","country":"AU","num":280},{"id":"au281","country":"AU","num":281},{"id":"au282","country":"AU","num":282},{"id":"au283","country":"AU","num":283},{"id":"au284","country":"AU","num":284},{"id":"au285","country":"AU","num":285},{"id":"au286","country":"AU","num":286},{"id":"au287","country":"AU","num":287},{"id":"au288","country":"AU","num":288},{"id":"au289","country":"AU","num":289},{"id":"au290","country":"AU","num":290},{"id":"au291","country":"AU","num":291},{"id":"au292","country":"AU","num":292},{"id":"au293","country":"AU","num":293},{"id":"au294","country":"AU","num":294},{"id":"au295","country":"AU","num":295},{"id":"au296","country":"AU","num":296},{"id":"au297","country":"AU","num":297},{"id":"au298","country":"AU","num":298},{"id":"au299","country":"AU","num":299},{"id":"au300","country":"AU","num":300},{"id":"au301","country":"AU","num":301},{"id":"au302","country":"AU","num":302},{"id":"au303","country":"AU","num":303},{"id":"au305","country":"AU","num":305},{"id":"au306","country":"AU","num":306},{"id":"au307","country":"AU","num":307},{"id":"au308","country":"AU","num":308},{"id":"au309","country":"AU","num":309},{"id":"au310","country":"AU","num":310},{"id":"au311","country":"AU","num":311},{"id":"au312","country":"AU","num":312},{"id":"au313","country":"AU","num":313},{"id":"au314","country":"AU","num":314},{"id":"au315","country":"AU","num":315},{"id":"au316","country":"AU","num":316},{"id":"au317","country":"AU","num":317},{"id":"au318","country":"AU","num":318},{"id":"au319","country":"AU","num":319},{"id":"au320","country":"AU","num":320},{"id":"au321","country":"AU","num":321},{"id":"au322","country":"AU","num":322},{"id":"au323","country":"AU","num":323},{"id":"au324","country":"AU","num":324},{"id":"au325","country":"AU","num":325},{"id":"au326","country":"AU","num":326},{"id":"au327","country":"AU","num":327},{"id":"au328","country":"AU","num":328},{"id":"au329","country":"AU","num":329},{"id":"au330","country":"AU","num":330},{"id":"au331","country":"AU","num":331},{"id":"au332","country":"AU","num":332},{"id":"au333","country":"AU","num":333},{"id":"au334","country":"AU","num":334},{"id":"au335","country":"AU","num":335},{"id":"au336","country":"AU","num":336},{"id":"au337","country":"AU","num":337},{"id":"au338","country":"AU","num":338},{"id":"au339","country":"AU","num":339},{"id":"au340","country":"AU","num":340},{"id":"au341","country":"AU","num":341},{"id":"au342","country":"AU","num":342},{"id":"au343","country":"AU","num":343},{"id":"au344","country":"AU","num":344},{"id":"au347","country":"AU","num":347},{"id":"au348","country":"AU","num":348},{"id":"au349","country":"AU","num":349},{"id":"au350","country":"AU","num":350},{"id":"au351","country":"AU","num":351},{"id":"au352","country":"AU","num":352},{"id":"au353","country":"AU","num":353},{"id":"au354","country":"AU","num":354},{"id":"au355","country":"AU","num":355},{"id":"au356","country":"AU","num":356},{"id":"au357","country":"AU","num":357},{"id":"au358","country":"AU","num":358},{"id":"au359","country":"AU","num":359},{"id":"au360","country":"AU","num":360},{"id":"au361","country":"AU","num":361},{"id":"au362","country":"AU","num":362},{"id":"au363","country":"AU","num":363},{"id":"au364","country":"AU","num":364},{"id":"au365","country":"AU","num":365},{"id":"au366","country":"AU","num":366},{"id":"au367","country":"AU","num":367},{"id":"au368","country":"AU","num":368},{"id":"au369","country":"AU","num":369},{"id":"au370","country":"AU","num":370},{"id":"au371","country":"AU","num":371},{"id":"au372","country":"AU","num":372},{"id":"au373","country":"AU","num":373},{"id":"au374","country":"AU","num":374},{"id":"au375","country":"AU","num":375},{"id":"au376","country":"AU","num":376}]},{"country":"BA","pools":[{"id":"ba5","country":"BA","num":5},{"id":"ba6","country":"BA","num":6},{"id":"ba7","country":"BA","num":7},{"id":"ba8","country":"BA","num":8}]},{"country":"BE","pools":[{"id":"be100","country":"BE","num":100},{"id":"be101","country":"BE","num":101},{"id":"be102","country":"BE","num":102},{"id":"be103","country":"BE","num":103},{"id":"be104","country":"BE","num":104},{"id":"be27","country":"BE","num":27},{"id":"be28","country":"BE","num":28},{"id":"be29","country":"BE","num":29},{"id":"be30","country":"BE","num":30},{"id":"be47","country":"BE","num":47},{"id":"be48","country":"BE","num":48},{"id":"be49","country":"BE","num":49},{"id":"be50","country":"BE","num":50},{"id":"be51","country":"BE","num":51},{"id":"be52","country":"BE","num":52},{"id":"be53","country":"BE","num":53},{"id":"be54","country":"BE","num":54},{"id":"be55","country":"BE","num":55},{"id":"be56","country":"BE","num":56},{"id":"be57","country":"BE","num":57},{"id":"be58","country":"BE","num":58},{"id":"be59","country":"BE","num":59},{"id":"be60","country":"BE","num":60},{"id":"be61","country":"BE","num":61},{"id":"be62","country":"BE","num":62},{"id":"be63","country":"BE","num":63},{"id":"be64","country":"BE","num":64},{"id":"be65","country":"BE","num":65},{"id":"be66","country":"BE","num":66},{"id":"be67","country":"BE","num":67},{"id":"be68","country":"BE","num":68},{"id":"be69","country":"BE","num":69},{"id":"be70","country":"BE","num":70},{"id":"be71","country":"BE","num":71},{"id":"be72","country":"BE","num":72},{"id":"be73","country":"BE","num":73},{"id":"be74","country":"BE","num":74},{"id":"be75","country":"BE","num":75},{"id":"be76","country":"BE","num":76},{"id":"be77","country":"BE","num":77},{"id":"be78","country":"BE","num":78},{"id":"be79","country":"BE","num":79},{"id":"be80","country":"BE","num":80},{"id":"be81","country":"BE","num":81},{"id":"be82","country":"BE","num":82},{"id":"be83","country":"BE","num":83},{"id":"be84","country":"BE","num":84},{"id":"be85","country":"BE","num":85},{"id":"be86","country":"BE","num":86},{"id":"be87","country":"BE","num":87},{"id":"be88","country":"BE","num":88},{"id":"be89","country":"BE","num":89},{"id":"be90","country":"BE","num":90},{"id":"be91","country":"BE","num":91},{"id":"be92","country":"BE","num":92},{"id":"be93","country":"BE","num":93},{"id":"be94","country":"BE","num":94},{"id":"be95","country":"BE","num":95},{"id":"be96","country":"BE","num":96},{"id":"be97","country":"BE","num":97},{"id":"be98","country":"BE","num":98},{"id":"be99","country":"BE","num":99}]},{"country":"BG","pools":[{"id":"bg14","country":"BG","num":14},{"id":"bg15","country":"BG","num":15},{"id":"bg16","country":"BG","num":16},{"id":"bg17","country":"BG","num":17},{"id":"bg18","country":"BG","num":18},{"id":"bg19","country":"BG","num":19},{"id":"bg20","country":"BG","num":20},{"id":"bg21","country":"BG","num":21},{"id":"bg22","country":"BG","num":22},{"id":"bg23","country":"BG","num":23},{"id":"bg24","country":"BG","num":24}]},{"country":"BR","pools":[{"id":"br13","country":"BR","num":13},{"id":"br14","country":"BR","num":14},{"id":"br15","country":"BR","num":15},{"id":"br16","country":"BR","num":16},{"id":"br17","country":"BR","num":17},{"id":"br18","country":"BR","num":18},{"id":"br19","country":"BR","num":19},{"id":"br20","country":"BR","num":20},{"id":"br21","country":"BR","num":21},{"id":"br22","country":"BR","num":22},{"id":"br23","country":"BR","num":23},{"id":"br24","country":"BR","num":24},{"id":"br25","country":"BR","num":25},{"id":"br26","country":"BR","num":26},{"id":"br27","country":"BR","num":27},{"id":"br28","country":"BR","num":28},{"id":"br35","country":"BR","num":35},{"id":"br36","country":"BR","num":36},{"id":"br37","country":"BR","num":37},{"id":"br38","country":"BR","num":38}]},{"country":"CA","pools":[{"id":"ca117","country":"CA","num":117},{"id":"ca118","country":"CA","num":118},{"id":"ca119","country":"CA","num":119},{"id":"ca120","country":"CA","num":120},{"id":"ca121","country":"CA","num":121},{"id":"ca122","country":"CA","num":122},{"id":"ca123","country":"CA","num":123},{"id":"ca124","country":"CA","num":124},{"id":"ca165","country":"CA","num":165},{"id":"ca166","country":"CA","num":166},{"id":"ca167","country":"CA","num":167},{"id":"ca168","country":"CA","num":168},{"id":"ca171","country":"CA","num":171},{"id":"ca172","country":"CA","num":172},{"id":"ca173","country":"CA","num":173},{"id":"ca174","country":"CA","num":174},{"id":"ca175","country":"CA","num":175},{"id":"ca176","country":"CA","num":176},{"id":"ca177","country":"CA","num":177},{"id":"ca178","country":"CA","num":178},{"id":"ca179","country":"CA","num":179},{"id":"ca180","country":"CA","num":180},{"id":"ca181","country":"CA","num":181},{"id":"ca182","country":"CA","num":182},{"id":"ca183","country":"CA","num":183},{"id":"ca184","country":"CA","num":184},{"id":"ca185","country":"CA","num":185},{"id":"ca186","country":"CA","num":186},{"id":"ca187","country":"CA","num":187},{"id":"ca188","country":"CA","num":188},{"id":"ca189","country":"CA","num":189},{"id":"ca190","country":"CA","num":190},{"id":"ca191","country":"CA","num":191},{"id":"ca192","country":"CA","num":192},{"id":"ca193","country":"CA","num":193},{"id":"ca194","country":"CA","num":194},{"id":"ca199","country":"CA","num":199},{"id":"ca200","country":"CA","num":200},{"id":"ca201","country":"CA","num":201},{"id":"ca202","country":"CA","num":202},{"id":"ca203","country":"CA","num":203},{"id":"ca204","country":"CA","num":204},{"id":"ca205","country":"CA","num":205},{"id":"ca206","country":"CA","num":206},{"id":"ca207","country":"CA","num":207},{"id":"ca208","country":"CA","num":208},{"id":"ca209","country":"CA","num":209},{"id":"ca210","country":"CA","num":210},{"id":"ca211","country":"CA","num":211},{"id":"ca212","country":"CA","num":212},{"id":"ca213","country":"CA","num":213},{"id":"ca214","country":"CA","num":214},{"id":"ca215","country":"CA","num":215},{"id":"ca216","country":"CA","num":216},{"id":"ca217","country":"CA","num":217},{"id":"ca218","country":"CA","num":218},{"id":"ca295","country":"CA","num":295},{"id":"ca296","country":"CA","num":296},{"id":"ca297","country":"CA","num":297},{"id":"ca298","country":"CA","num":298},{"id":"ca299","country":"CA","num":299},{"id":"ca300","country":"CA","num":300},{"id":"ca301","country":"CA","num":301},{"id":"ca302","country":"CA","num":302},{"id":"ca303","country":"CA","num":303},{"id":"ca304","country":"CA","num":304},{"id":"ca305","country":"CA","num":305},{"id":"ca306","country":"CA","num":306},{"id":"ca307","country":"CA","num":307},{"id":"ca308","country":"CA","num":308},{"id":"ca309","country":"CA","num":309},{"id":"ca310","country":"CA","num":310},{"id":"ca311","country":"CA","num":311},{"id":"ca312","country":"CA","num":312},{"id":"ca313","country":"CA","num":313},{"id":"ca314","country":"CA","num":314},{"id":"ca315","country":"CA","num":315},{"id":"ca316","country":"CA","num":316},{"id":"ca317","country":"CA","num":317},{"id":"ca318","country":"CA","num":318},{"id":"ca319","country":"CA","num":319},{"id":"ca320","country":"CA","num":320},{"id":"ca321","country":"CA","num":321},{"id":"ca322","country":"CA","num":322},{"id":"ca323","country":"CA","num":323},{"id":"ca324","country":"CA","num":324},{"id":"ca325","country":"CA","num":325},{"id":"ca326","country":"CA","num":326},{"id":"ca327","country":"CA","num":327},{"id":"ca328","country":"CA","num":328},{"id":"ca329","country":"CA","num":329},{"id":"ca330","country":"CA","num":330},{"id":"ca331","country":"CA","num":331},{"id":"ca332","country":"CA","num":332},{"id":"ca333","country":"CA","num":333},{"id":"ca334","country":"CA","num":334},{"id":"ca367","country":"CA","num":367},{"id":"ca368","country":"CA","num":368},{"id":"ca369","country":"CA","num":369},{"id":"ca370","country":"CA","num":370},{"id":"ca371","country":"CA","num":371},{"id":"ca372","country":"CA","num":372},{"id":"ca373","country":"CA","num":373},{"id":"ca374","country":"CA","num":374},{"id":"ca375","country":"CA","num":375},{"id":"ca376","country":"CA","num":376},{"id":"ca377","country":"CA","num":377},{"id":"ca378","country":"CA","num":378},{"id":"ca379","country":"CA","num":379},{"id":"ca380","country":"CA","num":380},{"id":"ca381","country":"CA","num":381},{"id":"ca382","country":"CA","num":382},{"id":"ca383","country":"CA","num":383},{"id":"ca384","country":"CA","num":384},{"id":"ca385","country":"CA","num":385},{"id":"ca386","country":"CA","num":386},{"id":"ca387","country":"CA","num":387},{"id":"ca388","country":"CA","num":388},{"id":"ca389","country":"CA","num":389},{"id":"ca390","country":"CA","num":390},{"id":"ca391","country":"CA","num":391},{"id":"ca392","country":"CA","num":392},{"id":"ca393","country":"CA","num":393},{"id":"ca394","country":"CA","num":394},{"id":"ca395","country":"CA","num":395},{"id":"ca396","country":"CA","num":396},{"id":"ca397","country":"CA","num":397},{"id":"ca398","country":"CA","num":398},{"id":"ca399","country":"CA","num":399},{"id":"ca400","country":"CA","num":400},{"id":"ca401","country":"CA","num":401},{"id":"ca402","country":"CA","num":402},{"id":"ca403","country":"CA","num":403},{"id":"ca404","country":"CA","num":404},{"id":"ca405","country":"CA","num":405},{"id":"ca406","country":"CA","num":406},{"id":"ca407","country":"CA","num":407},{"id":"ca408","country":"CA","num":408},{"id":"ca409","country":"CA","num":409},{"id":"ca410","country":"CA","num":410},{"id":"ca411","country":"CA","num":411},{"id":"ca412","country":"CA","num":412},{"id":"ca413","country":"CA","num":413},{"id":"ca414","country":"CA","num":414},{"id":"ca415","country":"CA","num":415},{"id":"ca416","country":"CA","num":416},{"id":"ca417","country":"CA","num":417},{"id":"ca418","country":"CA","num":418},{"id":"ca419","country":"CA","num":419},{"id":"ca420","country":"CA","num":420},{"id":"ca421","country":"CA","num":421},{"id":"ca422","country":"CA","num":422},{"id":"ca423","country":"CA","num":423},{"id":"ca424","country":"CA","num":424},{"id":"ca425","country":"CA","num":425},{"id":"ca426","country":"CA","num":426},{"id":"ca427","country":"CA","num":427},{"id":"ca428","country":"CA","num":428},{"id":"ca429","country":"CA","num":429},{"id":"ca430","country":"CA","num":430},{"id":"ca431","country":"CA","num":431},{"id":"ca432","country":"CA","num":432},{"id":"ca433","country":"CA","num":433},{"id":"ca434","country":"CA","num":434},{"id":"ca435","country":"CA","num":435},{"id":"ca436","country":"CA","num":436},{"id":"ca437","country":"CA","num":437},{"id":"ca438","country":"CA","num":438},{"id":"ca439","country":"CA","num":439},{"id":"ca440","country":"CA","num":440},{"id":"ca441","country":"CA","num":441},{"id":"ca442","country":"CA","num":442},{"id":"ca443","country":"CA","num":443},{"id":"ca444","country":"CA","num":444},{"id":"ca445","country":"CA","num":445},{"id":"ca446","country":"CA","num":446},{"id":"ca447","country":"CA","num":447},{"id":"ca448","country":"CA","num":448},{"id":"ca449","country":"CA","num":449},{"id":"ca450","country":"CA","num":450},{"id":"ca451","country":"CA","num":451},{"id":"ca452","country":"CA","num":452},{"id":"ca453","country":"CA","num":453},{"id":"ca454","country":"CA","num":454},{"id":"ca455","country":"CA","num":455},{"id":"ca456","country":"CA","num":456},{"id":"ca457","country":"CA","num":457},{"id":"ca458","country":"CA","num":458},{"id":"ca459","country":"CA","num":459},{"id":"ca460","country":"CA","num":460},{"id":"ca461","country":"CA","num":461},{"id":"ca462","country":"CA","num":462},{"id":"ca463","country":"CA","num":463},{"id":"ca464","country":"CA","num":464},{"id":"ca465","country":"CA","num":465},{"id":"ca466","country":"CA","num":466},{"id":"ca467","country":"CA","num":467},{"id":"ca468","country":"CA","num":468},{"id":"ca469","country":"CA","num":469},{"id":"ca470","country":"CA","num":470},{"id":"ca471","country":"CA","num":471},{"id":"ca472","country":"CA","num":472},{"id":"ca473","country":"CA","num":473},{"id":"ca474","country":"CA","num":474},{"id":"ca475","country":"CA","num":475},{"id":"ca476","country":"CA","num":476},{"id":"ca477","country":"CA","num":477},{"id":"ca478","country":"CA","num":478},{"id":"ca479","country":"CA","num":479},{"id":"ca480","country":"CA","num":480},{"id":"ca481","country":"CA","num":481},{"id":"ca482","country":"CA","num":482},{"id":"ca483","country":"CA","num":483},{"id":"ca484","country":"CA","num":484},{"id":"ca485","country":"CA","num":485},{"id":"ca486","country":"CA","num":486},{"id":"ca487","country":"CA","num":487},{"id":"ca488","country":"CA","num":488},{"id":"ca489","country":"CA","num":489},{"id":"ca490","country":"CA","num":490},{"id":"ca491","country":"CA","num":491},{"id":"ca492","country":"CA","num":492},{"id":"ca493","country":"CA","num":493},{"id":"ca494","country":"CA","num":494},{"id":"ca495","country":"CA","num":495},{"id":"ca496","country":"CA","num":496},{"id":"ca497","country":"CA","num":497},{"id":"ca498","country":"CA","num":498},{"id":"ca499","country":"CA","num":499},{"id":"ca500","country":"CA","num":500},{"id":"ca501","country":"CA","num":501},{"id":"ca502","country":"CA","num":502},{"id":"ca503","country":"CA","num":503},{"id":"ca504","country":"CA","num":504},{"id":"ca505","country":"CA","num":505},{"id":"ca506","country":"CA","num":506},{"id":"ca507","country":"CA","num":507},{"id":"ca508","country":"CA","num":508},{"id":"ca509","country":"CA","num":509},{"id":"ca510","country":"CA","num":510},{"id":"ca511","country":"CA","num":511},{"id":"ca512","country":"CA","num":512},{"id":"ca513","country":"CA","num":513},{"id":"ca514","country":"CA","num":514},{"id":"ca515","country":"CA","num":515},{"id":"ca516","country":"CA","num":516},{"id":"ca517","country":"CA","num":517},{"id":"ca518","country":"CA","num":518},{"id":"ca519","country":"CA","num":519},{"id":"ca520","country":"CA","num":520},{"id":"ca521","country":"CA","num":521},{"id":"ca522","country":"CA","num":522},{"id":"ca523","country":"CA","num":523},{"id":"ca524","country":"CA","num":524},{"id":"ca525","country":"CA","num":525},{"id":"ca526","country":"CA","num":526},{"id":"ca527","country":"CA","num":527},{"id":"ca528","country":"CA","num":528},{"id":"ca529","country":"CA","num":529},{"id":"ca530","country":"CA","num":530},{"id":"ca531","country":"CA","num":531},{"id":"ca532","country":"CA","num":532},{"id":"ca533","country":"CA","num":533},{"id":"ca534","country":"CA","num":534},{"id":"ca535","country":"CA","num":535},{"id":"ca536","country":"CA","num":536},{"id":"ca537","country":"CA","num":537},{"id":"ca538","country":"CA","num":538},{"id":"ca539","country":"CA","num":539},{"id":"ca53","country":"CA","num":53},{"id":"ca540","country":"CA","num":540},{"id":"ca541","country":"CA","num":541},{"id":"ca542","country":"CA","num":542},{"id":"ca543","country":"CA","num":543},{"id":"ca544","country":"CA","num":544},{"id":"ca545","country":"CA","num":545},{"id":"ca546","country":"CA","num":546},{"id":"ca547","country":"CA","num":547},{"id":"ca548","country":"CA","num":548},{"id":"ca549","country":"CA","num":549},{"id":"ca54","country":"CA","num":54},{"id":"ca550","country":"CA","num":550},{"id":"ca551","country":"CA","num":551},{"id":"ca552","country":"CA","num":552},{"id":"ca553","country":"CA","num":553},{"id":"ca554","country":"CA","num":554},{"id":"ca555","country":"CA","num":555},{"id":"ca556","country":"CA","num":556},{"id":"ca557","country":"CA","num":557},{"id":"ca558","country":"CA","num":558},{"id":"ca559","country":"CA","num":559},{"id":"ca55","country":"CA","num":55},{"id":"ca560","country":"CA","num":560},{"id":"ca561","country":"CA","num":561},{"id":"ca562","country":"CA","num":562},{"id":"ca563","country":"CA","num":563},{"id":"ca564","country":"CA","num":564},{"id":"ca565","country":"CA","num":565},{"id":"ca566","country":"CA","num":566},{"id":"ca567","country":"CA","num":567},{"id":"ca568","country":"CA","num":568},{"id":"ca569","country":"CA","num":569},{"id":"ca56","country":"CA","num":56},{"id":"ca570","country":"CA","num":570},{"id":"ca571","country":"CA","num":571},{"id":"ca572","country":"CA","num":572},{"id":"ca573","country":"CA","num":573},{"id":"ca574","country":"CA","num":574},{"id":"ca575","country":"CA","num":575},{"id":"ca576","country":"CA","num":576},{"id":"ca577","country":"CA","num":577},{"id":"ca578","country":"CA","num":578},{"id":"ca579","country":"CA","num":579},{"id":"ca580","country":"CA","num":580},{"id":"ca581","country":"CA","num":581},{"id":"ca582","country":"CA","num":582},{"id":"ca583","country":"CA","num":583},{"id":"ca584","country":"CA","num":584},{"id":"ca585","country":"CA","num":585},{"id":"ca586","country":"CA","num":586},{"id":"ca587","country":"CA","num":587},{"id":"ca588","country":"CA","num":588},{"id":"ca589","country":"CA","num":589},{"id":"ca590","country":"CA","num":590},{"id":"ca591","country":"CA","num":591},{"id":"ca592","country":"CA","num":592},{"id":"ca593","country":"CA","num":593},{"id":"ca595","country":"CA","num":595},{"id":"ca597","country":"CA","num":597},{"id":"ca598","country":"CA","num":598},{"id":"ca599","country":"CA","num":599},{"id":"ca600","country":"CA","num":600},{"id":"ca601","country":"CA","num":601},{"id":"ca602","country":"CA","num":602},{"id":"ca603","country":"CA","num":603},{"id":"ca604","country":"CA","num":604},{"id":"ca605","country":"CA","num":605},{"id":"ca606","country":"CA","num":606},{"id":"ca607","country":"CA","num":607},{"id":"ca608","country":"CA","num":608},{"id":"ca609","country":"CA","num":609},{"id":"ca610","country":"CA","num":610},{"id":"ca611","country":"CA","num":611},{"id":"ca612","country":"CA","num":612},{"id":"ca613","country":"CA","num":613},{"id":"ca614","country":"CA","num":614},{"id":"ca615","country":"CA","num":615},{"id":"ca616","country":"CA","num":616},{"id":"ca617","country":"CA","num":617},{"id":"ca618","country":"CA","num":618},{"id":"ca619","country":"CA","num":619},{"id":"ca61","country":"CA","num":61},{"id":"ca620","country":"CA","num":620},{"id":"ca621","country":"CA","num":621},{"id":"ca622","country":"CA","num":622},{"id":"ca623","country":"CA","num":623},{"id":"ca624","country":"CA","num":624},{"id":"ca625","country":"CA","num":625},{"id":"ca626","country":"CA","num":626},{"id":"ca62","country":"CA","num":62},{"id":"ca63","country":"CA","num":63},{"id":"ca64","country":"CA","num":64},{"id":"ca69","country":"CA","num":69},{"id":"ca70","country":"CA","num":70},{"id":"ca71","country":"CA","num":71},{"id":"ca72","country":"CA","num":72},{"id":"ca73","country":"CA","num":73},{"id":"ca74","country":"CA","num":74},{"id":"ca75","country":"CA","num":75},{"id":"ca76","country":"CA","num":76},{"id":"ca81","country":"CA","num":81},{"id":"ca82","country":"CA","num":82},{"id":"ca83","country":"CA","num":83},{"id":"ca84","country":"CA","num":84},{"id":"ca85","country":"CA","num":85},{"id":"ca86","country":"CA","num":86},{"id":"ca87","country":"CA","num":87},{"id":"ca88","country":"CA","num":88}]},{"country":"CH","pools":[{"id":"ch100","country":"CH","num":100},{"id":"ch101","country":"CH","num":101},{"id":"ch102","country":"CH","num":102},{"id":"ch103","country":"CH","num":103},{"id":"ch104","country":"CH","num":104},{"id":"ch105","country":"CH","num":105},{"id":"ch106","country":"CH","num":106},{"id":"ch107","country":"CH","num":107},{"id":"ch108","country":"CH","num":108},{"id":"ch109","country":"CH","num":109},{"id":"ch110","country":"CH","num":110},{"id":"ch111","country":"CH","num":111},{"id":"ch112","country":"CH","num":112},{"id":"ch113","country":"CH","num":113},{"id":"ch114","country":"CH","num":114},{"id":"ch115","country":"CH","num":115},{"id":"ch116","country":"CH","num":116},{"id":"ch117","country":"CH","num":117},{"id":"ch118","country":"CH","num":118},{"id":"ch119","country":"CH","num":119},{"id":"ch120","country":"CH","num":120},{"id":"ch121","country":"CH","num":121},{"id":"ch122","country":"CH","num":122},{"id":"ch123","country":"CH","num":123},{"id":"ch124","country":"CH","num":124},{"id":"ch125","country":"CH","num":125},{"id":"ch126","country":"CH","num":126},{"id":"ch127","country":"CH","num":127},{"id":"ch128","country":"CH","num":128},{"id":"ch129","country":"CH","num":129},{"id":"ch130","country":"CH","num":130},{"id":"ch131","country":"CH","num":131},{"id":"ch132","country":"CH","num":132},{"id":"ch133","country":"CH","num":133},{"id":"ch134","country":"CH","num":134},{"id":"ch135","country":"CH","num":135},{"id":"ch136","country":"CH","num":136},{"id":"ch137","country":"CH","num":137},{"id":"ch138","country":"CH","num":138},{"id":"ch139","country":"CH","num":139},{"id":"ch140","country":"CH","num":140},{"id":"ch141","country":"CH","num":141},{"id":"ch142","country":"CH","num":142},{"id":"ch143","country":"CH","num":143},{"id":"ch144","country":"CH","num":144},{"id":"ch145","country":"CH","num":145},{"id":"ch146","country":"CH","num":146},{"id":"ch147","country":"CH","num":147},{"id":"ch148","country":"CH","num":148},{"id":"ch149","country":"CH","num":149},{"id":"ch150","country":"CH","num":150},{"id":"ch151","country":"CH","num":151},{"id":"ch152","country":"CH","num":152},{"id":"ch153","country":"CH","num":153},{"id":"ch154","country":"CH","num":154},{"id":"ch155","country":"CH","num":155},{"id":"ch156","country":"CH","num":156},{"id":"ch157","country":"CH","num":157},{"id":"ch64","country":"CH","num":64},{"id":"ch65","country":"CH","num":65},{"id":"ch66","country":"CH","num":66},{"id":"ch67","country":"CH","num":67},{"id":"ch72","country":"CH","num":72},{"id":"ch73","country":"CH","num":73},{"id":"ch74","country":"CH","num":74},{"id":"ch75","country":"CH","num":75},{"id":"ch76","country":"CH","num":76},{"id":"ch77","country":"CH","num":77},{"id":"ch78","country":"CH","num":78},{"id":"ch79","country":"CH","num":79},{"id":"ch80","country":"CH","num":80},{"id":"ch81","country":"CH","num":81},{"id":"ch82","country":"CH","num":82},{"id":"ch83","country":"CH","num":83},{"id":"ch84","country":"CH","num":84},{"id":"ch85","country":"CH","num":85},{"id":"ch86","country":"CH","num":86},{"id":"ch87","country":"CH","num":87},{"id":"ch88","country":"CH","num":88},{"id":"ch89","country":"CH","num":89},{"id":"ch90","country":"CH","num":90},{"id":"ch91","country":"CH","num":91},{"id":"ch92","country":"CH","num":92},{"id":"ch93","country":"CH","num":93},{"id":"ch94","country":"CH","num":94},{"id":"ch95","country":"CH","num":95},{"id":"ch96","country":"CH","num":96},{"id":"ch97","country":"CH","num":97},{"id":"ch98","country":"CH","num":98},{"id":"ch99","country":"CH","num":99},{"id":"ch-onion1","country":"CH","tags":["onion"],"num":1}]},{"country":"CL","pools":[{"id":"cl10","country":"CL","num":10},{"id":"cl7","country":"CL","num":7},{"id":"cl9","country":"CL","num":9}]},{"country":"CR","pools":[{"id":"cr10","country":"CR","num":10},{"id":"cr11","country":"CR","num":11},{"id":"cr12","country":"CR","num":12},{"id":"cr13","country":"CR","num":13},{"id":"cr14","country":"CR","num":14},{"id":"cr15","country":"CR","num":15},{"id":"cr16","country":"CR","num":16},{"id":"cr17","country":"CR","num":17},{"id":"cr18","country":"CR","num":18},{"id":"cr19","country":"CR","num":19},{"id":"cr8","country":"CR","num":8},{"id":"cr9","country":"CR","num":9}]},{"country":"CY","pools":[{"id":"cy10","country":"CY","num":10},{"id":"cy4","country":"CY","num":4},{"id":"cy5","country":"CY","num":5},{"id":"cy6","country":"CY","num":6},{"id":"cy7","country":"CY","num":7},{"id":"cy8","country":"CY","num":8},{"id":"cy9","country":"CY","num":9}]},{"country":"CZ","pools":[{"id":"cz32","country":"CZ","num":32},{"id":"cz33","country":"CZ","num":33},{"id":"cz34","country":"CZ","num":34},{"id":"cz35","country":"CZ","num":35},{"id":"cz40","country":"CZ","num":40},{"id":"cz41","country":"CZ","num":41},{"id":"cz42","country":"CZ","num":42},{"id":"cz43","country":"CZ","num":43},{"id":"cz44","country":"CZ","num":44},{"id":"cz45","country":"CZ","num":45},{"id":"cz46","country":"CZ","num":46},{"id":"cz47","country":"CZ","num":47},{"id":"cz48","country":"CZ","num":48},{"id":"cz49","country":"CZ","num":49},{"id":"cz50","country":"CZ","num":50},{"id":"cz51","country":"CZ","num":51},{"id":"cz52","country":"CZ","num":52},{"id":"cz53","country":"CZ","num":53},{"id":"cz54","country":"CZ","num":54},{"id":"cz55","country":"CZ","num":55},{"id":"cz56","country":"CZ","num":56},{"id":"cz57","country":"CZ","num":57},{"id":"cz58","country":"CZ","num":58},{"id":"cz59","country":"CZ","num":59},{"id":"cz60","country":"CZ","num":60},{"id":"cz61","country":"CZ","num":61},{"id":"cz62","country":"CZ","num":62},{"id":"cz63","country":"CZ","num":63},{"id":"cz64","country":"CZ","num":64},{"id":"cz65","country":"CZ","num":65},{"id":"cz66","country":"CZ","num":66},{"id":"cz67","country":"CZ","num":67},{"id":"cz68","country":"CZ","num":68},{"id":"cz69","country":"CZ","num":69},{"id":"cz70","country":"CZ","num":70},{"id":"cz71","country":"CZ","num":71},{"id":"cz72","country":"CZ","num":72},{"id":"cz73","country":"CZ","num":73},{"id":"cz74","country":"CZ","num":74},{"id":"cz75","country":"CZ","num":75},{"id":"cz76","country":"CZ","num":76},{"id":"cz77","country":"CZ","num":77},{"id":"cz78","country":"CZ","num":78}]},{"country":"DE","pools":[{"id":"de111","country":"DE","num":111},{"id":"de112","country":"DE","num":112},{"id":"de113","country":"DE","num":113},{"id":"de114","country":"DE","num":114},{"id":"de119","country":"DE","num":119},{"id":"de120","country":"DE","num":120},{"id":"de121","country":"DE","num":121},{"id":"de122","country":"DE","num":122},{"id":"de283","country":"DE","num":283},{"id":"de284","country":"DE","num":284},{"id":"de285","country":"DE","num":285},{"id":"de286","country":"DE","num":286},{"id":"de331","country":"DE","num":331},{"id":"de332","country":"DE","num":332},{"id":"de333","country":"DE","num":333},{"id":"de334","country":"DE","num":334},{"id":"de335","country":"DE","num":335},{"id":"de336","country":"DE","num":336},{"id":"de337","country":"DE","num":337},{"id":"de338","country":"DE","num":338},{"id":"de339","country":"DE","num":339},{"id":"de340","country":"DE","num":340},{"id":"de341","country":"DE","num":341},{"id":"de342","country":"DE","num":342},{"id":"de343","country":"DE","num":343},{"id":"de344","country":"DE","num":344},{"id":"de345","country":"DE","num":345},{"id":"de346","country":"DE","num":346},{"id":"de347","country":"DE","num":347},{"id":"de348","country":"DE","num":348},{"id":"de349","country":"DE","num":349},{"id":"de350","country":"DE","num":350},{"id":"de351","country":"DE","num":351},{"id":"de352","country":"DE","num":352},{"id":"de353","country":"DE","num":353},{"id":"de354","country":"DE","num":354},{"id":"de355","country":"DE","num":355},{"id":"de356","country":"DE","num":356},{"id":"de357","country":"DE","num":357},{"id":"de358","country":"DE","num":358},{"id":"de359","country":"DE","num":359},{"id":"de360","country":"DE","num":360},{"id":"de361","country":"DE","num":361},{"id":"de362","country":"DE","num":362},{"id":"de363","country":"DE","num":363},{"id":"de364","country":"DE","num":364},{"id":"de365","country":"DE","num":365},{"id":"de366","country":"DE","num":366},{"id":"de367","country":"DE","num":367},{"id":"de368","country":"DE","num":368},{"id":"de369","country":"DE","num":369},{"id":"de370","country":"DE","num":370},{"id":"de371","country":"DE","num":371},{"id":"de372","country":"DE","num":372},{"id":"de373","country":"DE","num":373},{"id":"de374","country":"DE","num":374},{"id":"de375","country":"DE","num":375},{"id":"de376","country":"DE","num":376},{"id":"de377","country":"DE","num":377},{"id":"de378","country":"DE","num":378},{"id":"de379","country":"DE","num":379},{"id":"de380","country":"DE","num":380},{"id":"de381","country":"DE","num":381},{"id":"de382","country":"DE","num":382},{"id":"de383","country":"DE","num":383},{"id":"de384","country":"DE","num":384},{"id":"de385","country":"DE","num":385},{"id":"de386","country":"DE","num":386},{"id":"de387","country":"DE","num":387},{"id":"de388","country":"DE","num":388},{"id":"de389","country":"DE","num":389},{"id":"de390","country":"DE","num":390},{"id":"de391","country":"DE","num":391},{"id":"de392","country":"DE","num":392},{"id":"de393","country":"DE","num":393},{"id":"de394","country":"DE","num":394},{"id":"de395","country":"DE","num":395},{"id":"de396","country":"DE","num":396},{"id":"de397","country":"DE","num":397},{"id":"de398","country":"DE","num":398},{"id":"de399","country":"DE","num":399},{"id":"de400","country":"DE","num":400},{"id":"de401","country":"DE","num":401},{"id":"de402","country":"DE","num":402},{"id":"de403","country":"DE","num":403},{"id":"de404","country":"DE","num":404},{"id":"de405","country":"DE","num":405},{"id":"de406","country":"DE","num":406},{"id":"de415","country":"DE","num":415},{"id":"de416","country":"DE","num":416},{"id":"de417","country":"DE","num":417},{"id":"de419","country":"DE","num":419},{"id":"de420","country":"DE","num":420},{"id":"de421","country":"DE","num":421},{"id":"de422","country":"DE","num":422},{"id":"de423","country":"DE","num":423},{"id":"de424","country":"DE","num":424},{"id":"de425","country":"DE","num":425},{"id":"de426","country":"DE","num":426},{"id":"de427","country":"DE","num":427},{"id":"de428","country":"DE","num":428},{"id":"de429","country":"DE","num":429},{"id":"de430","country":"DE","num":430},{"id":"de431","country":"DE","num":431},{"id":"de432","country":"DE","num":432},{"id":"de433","country":"DE","num":433},{"id":"de434","country":"DE","num":434},{"id":"de435","country":"DE","num":435},{"id":"de436","country":"DE","num":436},{"id":"de437","country":"DE","num":437},{"id":"de438","country":"DE","num":438},{"id":"de439","country":"DE","num":439},{"id":"de440","country":"DE","num":440},{"id":"de441","country":"DE","num":441},{"id":"de442","country":"DE","num":442},{"id":"de443","country":"DE","num":443},{"id":"de444","country":"DE","num":444},{"id":"de445","country":"DE","num":445},{"id":"de446","country":"DE","num":446},{"id":"de447","country":"DE","num":447},{"id":"de448","country":"DE","num":448},{"id":"de449","country":"DE","num":449},{"id":"de450","country":"DE","num":450},{"id":"de451","country":"DE","num":451},{"id":"de452","country":"DE","num":452},{"id":"de453","country":"DE","num":453},{"id":"de454","country":"DE","num":454},{"id":"de455","country":"DE","num":455},{"id":"de456","country":"DE","num":456},{"id":"de457","country":"DE","num":457},{"id":"de458","country":"DE","num":458},{"id":"de459","country":"DE","num":459},{"id":"de460","country":"DE","num":460},{"id":"de461","country":"DE","num":461},{"id":"de462","country":"DE","num":462},{"id":"de463","country":"DE","num":463},{"id":"de464","country":"DE","num":464},{"id":"de465","country":"DE","num":465},{"id":"de466","country":"DE","num":466},{"id":"de467","country":"DE","num":467},{"id":"de468","country":"DE","num":468},{"id":"de469","country":"DE","num":469},{"id":"de470","country":"DE","num":470},{"id":"de471","country":"DE","num":471},{"id":"de472","country":"DE","num":472},{"id":"de473","country":"DE","num":473},{"id":"de474","country":"DE","num":474},{"id":"de475","country":"DE","num":475},{"id":"de476","country":"DE","num":476},{"id":"de477","country":"DE","num":477},{"id":"de478","country":"DE","num":478},{"id":"de487","country":"DE","num":487},{"id":"de488","country":"DE","num":488},{"id":"de489","country":"DE","num":489},{"id":"de490","country":"DE","num":490},{"id":"de491","country":"DE","num":491},{"id":"de492","country":"DE","num":492},{"id":"de493","country":"DE","num":493},{"id":"de494","country":"DE","num":494},{"id":"de495","country":"DE","num":495},{"id":"de496","country":"DE","num":496},{"id":"de497","country":"DE","num":497},{"id":"de498","country":"DE","num":498},{"id":"de499","country":"DE","num":499},{"id":"de500","country":"DE","num":500},{"id":"de501","country":"DE","num":501},{"id":"de502","country":"DE","num":502},{"id":"de503","country":"DE","num":503},{"id":"de504","country":"DE","num":504},{"id":"de505","country":"DE","num":505},{"id":"de506","country":"DE","num":506},{"id":"de507","country":"DE","num":507},{"id":"de508","country":"DE","num":508},{"id":"de509","country":"DE","num":509},{"id":"de510","country":"DE","num":510},{"id":"de511","country":"DE","num":511},{"id":"de512","country":"DE","num":512},{"id":"de513","country":"DE","num":513},{"id":"de514","country":"DE","num":514},{"id":"de515","country":"DE","num":515},{"id":"de516","country":"DE","num":516},{"id":"de517","country":"DE","num":517},{"id":"de518","country":"DE","num":518},{"id":"de519","country":"DE","num":519},{"id":"de520","country":"DE","num":520},{"id":"de521","country":"DE","num":521},{"id":"de522","country":"DE","num":522},{"id":"de523","country":"DE","num":523},{"id":"de524","country":"DE","num":524},{"id":"de525","country":"DE","num":525},{"id":"de526","country":"DE","num":526},{"id":"de527","country":"DE","num":527},{"id":"de528","country":"DE","num":528},{"id":"de529","country":"DE","num":529},{"id":"de530","country":"DE","num":530},{"id":"de531","country":"DE","num":531},{"id":"de532","country":"DE","num":532},{"id":"de533","country":"DE","num":533},{"id":"de534","country":"DE","num":534},{"id":"de535","country":"DE","num":535},{"id":"de536","country":"DE","num":536},{"id":"de537","country":"DE","num":537},{"id":"de538","country":"DE","num":538},{"id":"de539","country":"DE","num":539},{"id":"de540","country":"DE","num":540},{"id":"de541","country":"DE","num":541},{"id":"de542","country":"DE","num":542},{"id":"de543","country":"DE","num":543},{"id":"de544","country":"DE","num":544},{"id":"de545","country":"DE","num":545},{"id":"de546","country":"DE","num":546},{"id":"de547","country":"DE","num":547},{"id":"de548","country":"DE","num":548},{"id":"de549","country":"DE","num":549},{"id":"de550","country":"DE","num":550},{"id":"de551","country":"DE","num":551},{"id":"de552","country":"DE","num":552},{"id":"de553","country":"DE","num":553},{"id":"de554","country":"DE","num":554},{"id":"de555","country":"DE","num":555},{"id":"de556","country":"DE","num":556},{"id":"de557","country":"DE","num":557},{"id":"de558","country":"DE","num":558},{"id":"de559","country":"DE","num":559},{"id":"de560","country":"DE","num":560},{"id":"de561","country":"DE","num":561},{"id":"de562","country":"DE","num":562},{"id":"de563","country":"DE","num":563},{"id":"de564","country":"DE","num":564},{"id":"de565","country":"DE","num":565},{"id":"de568","country":"DE","num":568},{"id":"de569","country":"DE","num":569},{"id":"de570","country":"DE","num":570},{"id":"de571","country":"DE","num":571},{"id":"de572","country":"DE","num":572},{"id":"de573","country":"DE","num":573},{"id":"de574","country":"DE","num":574},{"id":"de575","country":"DE","num":575}]},{"country":"DK","pools":[{"id":"dk100","country":"DK","num":100},{"id":"dk101","country":"DK","num":101},{"id":"dk102","country":"DK","num":102},{"id":"dk103","country":"DK","num":103},{"id":"dk104","country":"DK","num":104},{"id":"dk105","country":"DK","num":105},{"id":"dk106","country":"DK","num":106},{"id":"dk107","country":"DK","num":107},{"id":"dk108","country":"DK","num":108},{"id":"dk109","country":"DK","num":109},{"id":"dk110","country":"DK","num":110},{"id":"dk111","country":"DK","num":111},{"id":"dk112","country":"DK","num":112},{"id":"dk113","country":"DK","num":113},{"id":"dk114","country":"DK","num":114},{"id":"dk115","country":"DK","num":115},{"id":"dk116","country":"DK","num":116},{"id":"dk117","country":"DK","num":117},{"id":"dk118","country":"DK","num":118},{"id":"dk119","country":"DK","num":119},{"id":"dk120","country":"DK","num":120},{"id":"dk20","country":"DK","num":20},{"id":"dk21","country":"DK","num":21},{"id":"dk22","country":"DK","num":22},{"id":"dk23","country":"DK","num":23},{"id":"dk40","country":"DK","num":40},{"id":"dk41","country":"DK","num":41},{"id":"dk42","country":"DK","num":42},{"id":"dk43","country":"DK","num":43},{"id":"dk44","country":"DK","num":44},{"id":"dk45","country":"DK","num":45},{"id":"dk46","country":"DK","num":46},{"id":"dk47","country":"DK","num":47},{"id":"dk48","country":"DK","num":48},{"id":"dk49","country":"DK","num":49},{"id":"dk50","country":"DK","num":50},{"id":"dk51","country":"DK","num":51},{"id":"dk52","country":"DK","num":52},{"id":"dk53","country":"DK","num":53},{"id":"dk54","country":"DK","num":54},{"id":"dk55","country":"DK","num":55},{"id":"dk56","country":"DK","num":56},{"id":"dk57","country":"DK","num":57},{"id":"dk58","country":"DK","num":58},{"id":"dk59","country":"DK","num":59},{"id":"dk60","country":"DK","num":60},{"id":"dk61","country":"DK","num":61},{"id":"dk62","country":"DK","num":62},{"id":"dk63","country":"DK","num":63},{"id":"dk66","country":"DK","num":66},{"id":"dk67","country":"DK","num":67},{"id":"dk68","country":"DK","num":68},{"id":"dk69","country":"DK","num":69},{"id":"dk70","country":"DK","num":70},{"id":"dk71","country":"DK","num":71},{"id":"dk72","country":"DK","num":72},{"id":"dk73","country":"DK","num":73},{"id":"dk74","country":"DK","num":74},{"id":"dk75","country":"DK","num":75},{"id":"dk76","country":"DK","num":76},{"id":"dk77","country":"DK","num":77},{"id":"dk78","country":"DK","num":78},{"id":"dk79","country":"DK","num":79},{"id":"dk80","country":"DK","num":80},{"id":"dk81","country":"DK","num":81},{"id":"dk82","country":"DK","num":82},{"id":"dk83","country":"DK","num":83},{"id":"dk84","country":"DK","num":84},{"id":"dk85","country":"DK","num":85},{"id":"dk86","country":"DK","num":86},{"id":"dk87","country":"DK","num":87},{"id":"dk88","country":"DK","num":88},{"id":"dk89","country":"DK","num":89},{"id":"dk90","country":"DK","num":90},{"id":"dk91","country":"DK","num":91},{"id":"dk92","country":"DK","num":92},{"id":"dk93","country":"DK","num":93},{"id":"dk94","country":"DK","num":94},{"id":"dk95","country":"DK","num":95},{"id":"dk96","country":"DK","num":96},{"id":"dk97","country":"DK","num":97},{"id":"dk98","country":"DK","num":98},{"id":"dk99","country":"DK","num":99}]},{"country":"EE","pools":[{"id":"ee14","country":"EE","num":14},{"id":"ee15","country":"EE","num":15},{"id":"ee16","country":"EE","num":16},{"id":"ee17","country":"EE","num":17},{"id":"ee22","country":"EE","num":22},{"id":"ee23","country":"EE","num":23},{"id":"ee24","country":"EE","num":24},{"id":"ee25","country":"EE","num":25},{"id":"ee26","country":"EE","num":26},{"id":"ee27","country":"EE","num":27},{"id":"ee28","country":"EE","num":28},{"id":"ee29","country":"EE","num":29}]},{"country":"ES","pools":[{"id":"es38","country":"ES","num":38},{"id":"es39","country":"ES","num":39},{"id":"es40","country":"ES","num":40},{"id":"es41","country":"ES","num":41},{"id":"es42","country":"ES","num":42},{"id":"es43","country":"ES","num":43},{"id":"es44","country":"ES","num":44},{"id":"es45","country":"ES","num":45},{"id":"es46","country":"ES","num":46},{"id":"es47","country":"ES","num":47},{"id":"es48","country":"ES","num":48},{"id":"es49","country":"ES","num":49},{"id":"es50","country":"ES","num":50},{"id":"es51","country":"ES","num":51},{"id":"es52","country":"ES","num":52},{"id":"es53","country":"ES","num":53},{"id":"es54","country":"ES","num":54},{"id":"es55","country":"ES","num":55},{"id":"es56","country":"ES","num":56},{"id":"es57","country":"ES","num":57},{"id":"es58","country":"ES","num":58},{"id":"es59","country":"ES","num":59},{"id":"es60","country":"ES","num":60},{"id":"es61","country":"ES","num":61},{"id":"es62","country":"ES","num":62},{"id":"es63","country":"ES","num":63},{"id":"es64","country":"ES","num":64},{"id":"es65","country":"ES","num":65},{"id":"es66","country":"ES","num":66},{"id":"es67","country":"ES","num":67},{"id":"es68","country":"ES","num":68},{"id":"es69","country":"ES","num":69},{"id":"es70","country":"ES","num":70},{"id":"es71","country":"ES","num":71},{"id":"es72","country":"ES","num":72},{"id":"es73","country":"ES","num":73},{"id":"es74","country":"ES","num":74},{"id":"es75","country":"ES","num":75},{"id":"es76","country":"ES","num":76}]},{"country":"FI","pools":[{"id":"fi50","country":"FI","num":50},{"id":"fi52","country":"FI","num":52},{"id":"fi53","country":"FI","num":53},{"id":"fi54","country":"FI","num":54},{"id":"fi55","country":"FI","num":55},{"id":"fi56","country":"FI","num":56},{"id":"fi62","country":"FI","num":62},{"id":"fi63","country":"FI","num":63},{"id":"fi64","country":"FI","num":64},{"id":"fi65","country":"FI","num":65},{"id":"fi66","country":"FI","num":66},{"id":"fi67","country":"FI","num":67},{"id":"fi68","country":"FI","num":68},{"id":"fi69","country":"FI","num":69},{"id":"fi70","country":"FI","num":70},{"id":"fi71","country":"FI","num":71},{"id":"fi72","country":"FI","num":72},{"id":"fi73","country":"FI","num":73}]},{"country":"FR","pools":[{"id":"fr109","country":"FR","num":109},{"id":"fr110","country":"FR","num":110},{"id":"fr111","country":"FR","num":111},{"id":"fr112","country":"FR","num":112},{"id":"fr117","country":"FR","num":117},{"id":"fr118","country":"FR","num":118},{"id":"fr119","country":"FR","num":119},{"id":"fr120","country":"FR","num":120},{"id":"fr121","country":"FR","num":121},{"id":"fr122","country":"FR","num":122},{"id":"fr123","country":"FR","num":123},{"id":"fr124","country":"FR","num":124},{"id":"fr165","country":"FR","num":165},{"id":"fr166","country":"FR","num":166},{"id":"fr167","country":"FR","num":167},{"id":"fr168","country":"FR","num":168},{"id":"fr169","country":"FR","num":169},{"id":"fr170","country":"FR","num":170},{"id":"fr171","country":"FR","num":171},{"id":"fr172","country":"FR","num":172},{"id":"fr173","country":"FR","num":173},{"id":"fr174","country":"FR","num":174},{"id":"fr175","country":"FR","num":175},{"id":"fr176","country":"FR","num":176},{"id":"fr177","country":"FR","num":177},{"id":"fr181","country":"FR","num":181},{"id":"fr182","country":"FR","num":182},{"id":"fr183","country":"FR","num":183},{"id":"fr184","country":"FR","num":184},{"id":"fr185","country":"FR","num":185},{"id":"fr186","country":"FR","num":186},{"id":"fr187","country":"FR","num":187},{"id":"fr188","country":"FR","num":188},{"id":"fr189","country":"FR","num":189},{"id":"fr190","country":"FR","num":190},{"id":"fr191","country":"FR","num":191},{"id":"fr192","country":"FR","num":192},{"id":"fr193","country":"FR","num":193},{"id":"fr194","country":"FR","num":194},{"id":"fr195","country":"FR","num":195},{"id":"fr196","country":"FR","num":196},{"id":"fr200","country":"FR","num":200},{"id":"fr201","country":"FR","num":201},{"id":"fr202","country":"FR","num":202},{"id":"fr203","country":"FR","num":203},{"id":"fr204","country":"FR","num":204},{"id":"fr205","country":"FR","num":205},{"id":"fr206","country":"FR","num":206},{"id":"fr207","country":"FR","num":207},{"id":"fr208","country":"FR","num":208},{"id":"fr209","country":"FR","num":209},{"id":"fr210","country":"FR","num":210},{"id":"fr211","country":"FR","num":211},{"id":"fr212","country":"FR","num":212},{"id":"fr213","country":"FR","num":213},{"id":"fr214","country":"FR","num":214},{"id":"fr215","country":"FR","num":215},{"id":"fr216","country":"FR","num":216},{"id":"fr217","country":"FR","num":217},{"id":"fr218","country":"FR","num":218},{"id":"fr219","country":"FR","num":219},{"id":"fr220","country":"FR","num":220},{"id":"fr221","country":"FR","num":221},{"id":"fr222","country":"FR","num":222},{"id":"fr223","country":"FR","num":223},{"id":"fr224","country":"FR","num":224},{"id":"fr225","country":"FR","num":225},{"id":"fr226","country":"FR","num":226},{"id":"fr227","country":"FR","num":227},{"id":"fr228","country":"FR","num":228},{"id":"fr229","country":"FR","num":229},{"id":"fr230","country":"FR","num":230},{"id":"fr231","country":"FR","num":231},{"id":"fr232","country":"FR","num":232},{"id":"fr233","country":"FR","num":233},{"id":"fr234","country":"FR","num":234},{"id":"fr235","country":"FR","num":235},{"id":"fr236","country":"FR","num":236},{"id":"fr237","country":"FR","num":237},{"id":"fr238","country":"FR","num":238},{"id":"fr239","country":"FR","num":239},{"id":"fr240","country":"FR","num":240},{"id":"fr241","country":"FR","num":241},{"id":"fr242","country":"FR","num":242},{"id":"fr243","country":"FR","num":243},{"id":"fr252","country":"FR","num":252},{"id":"fr253","country":"FR","num":253},{"id":"fr254","country":"FR","num":254},{"id":"fr255","country":"FR","num":255},{"id":"fr256","country":"FR","num":256},{"id":"fr257","country":"FR","num":257},{"id":"fr258","country":"FR","num":258},{"id":"fr259","country":"FR","num":259},{"id":"fr260","country":"FR","num":260},{"id":"fr270","country":"FR","num":270},{"id":"fr271","country":"FR","num":271},{"id":"fr272","country":"FR","num":272},{"id":"fr273","country":"FR","num":273},{"id":"fr278","country":"FR","num":278},{"id":"fr279","country":"FR","num":279},{"id":"fr288","country":"FR","num":288},{"id":"fr289","country":"FR","num":289},{"id":"fr290","country":"FR","num":290},{"id":"fr291","country":"FR","num":291},{"id":"fr292","country":"FR","num":292},{"id":"fr293","country":"FR","num":293},{"id":"fr294","country":"FR","num":294},{"id":"fr303","country":"FR","num":303},{"id":"fr304","country":"FR","num":304},{"id":"fr305","country":"FR","num":305},{"id":"fr306","country":"FR","num":306},{"id":"fr307","country":"FR","num":307},{"id":"fr308","country":"FR","num":308},{"id":"fr309","country":"FR","num":309},{"id":"fr310","country":"FR","num":310},{"id":"fr311","country":"FR","num":311},{"id":"fr312","country":"FR","num":312},{"id":"fr313","country":"FR","num":313},{"id":"fr314","country":"FR","num":314},{"id":"fr315","country":"FR","num":315},{"id":"fr316","country":"FR","num":316},{"id":"fr333","country":"FR","num":333},{"id":"fr334","country":"FR","num":334},{"id":"fr335","country":"FR","num":335},{"id":"fr336","country":"FR","num":336},{"id":"fr337","country":"FR","num":337},{"id":"fr338","country":"FR","num":338},{"id":"fr339","country":"FR","num":339},{"id":"fr340","country":"FR","num":340},{"id":"fr341","country":"FR","num":341},{"id":"fr342","country":"FR","num":342},{"id":"fr343","country":"FR","num":343},{"id":"fr344","country":"FR","num":344},{"id":"fr345","country":"FR","num":345},{"id":"fr346","country":"FR","num":346},{"id":"fr347","country":"FR","num":347},{"id":"fr348","country":"FR","num":348},{"id":"fr349","country":"FR","num":349},{"id":"fr350","country":"FR","num":350},{"id":"fr351","country":"FR","num":351},{"id":"fr352","country":"FR","num":352},{"id":"fr353","country":"FR","num":353},{"id":"fr354","country":"FR","num":354}]},{"country":"GE","pools":[{"id":"ge5","country":"GE","num":5}]},{"country":"GR","pools":[{"id":"gr10","country":"GR","num":10},{"id":"gr11","country":"GR","num":11},{"id":"gr12","country":"GR","num":12},{"id":"gr13","country":"GR","num":13},{"id":"gr7","country":"GR","num":7},{"id":"gr8","country":"GR","num":8},{"id":"gr9","country":"GR","num":9}]},{"country":"HK","pools":[{"id":"hk100","country":"HK","num":100},{"id":"hk101","country":"HK","num":101},{"id":"hk102","country":"HK","num":102},{"id":"hk103","country":"HK","num":103},{"id":"hk104","country":"HK","num":104},{"id":"hk105","country":"HK","num":105},{"id":"hk106","country":"HK","num":106},{"id":"hk107","country":"HK","num":107},{"id":"hk108","country":"HK","num":108},{"id":"hk10","country":"HK","num":10},{"id":"hk45","country":"HK","num":45},{"id":"hk46","country":"HK","num":46},{"id":"hk47","country":"HK","num":47},{"id":"hk48","country":"HK","num":48},{"id":"hk69","country":"HK","num":69},{"id":"hk70","country":"HK","num":70},{"id":"hk71","country":"HK","num":71},{"id":"hk72","country":"HK","num":72},{"id":"hk73","country":"HK","num":73},{"id":"hk74","country":"HK","num":74},{"id":"hk7","country":"HK","num":7},{"id":"hk85","country":"HK","num":85},{"id":"hk86","country":"HK","num":86},{"id":"hk87","country":"HK","num":87},{"id":"hk88","country":"HK","num":88},{"id":"hk89","country":"HK","num":89},{"id":"hk8","country":"HK","num":8},{"id":"hk90","country":"HK","num":90},{"id":"hk91","country":"HK","num":91},{"id":"hk92","country":"HK","num":92},{"id":"hk93","country":"HK","num":93},{"id":"hk94","country":"HK","num":94},{"id":"hk95","country":"HK","num":95},{"id":"hk96","country":"HK","num":96},{"id":"hk99","country":"HK","num":99},{"id":"hk9","country":"HK","num":9}]},{"country":"HR","pools":[{"id":"hr17","country":"HR","num":17},{"id":"hr18","country":"HR","num":18},{"id":"hr21","country":"HR","num":21},{"id":"hr22","country":"HR","num":22},{"id":"hr23","country":"HR","num":23},{"id":"hr24","country":"HR","num":24}]},{"country":"HU","pools":[{"id":"hu24","country":"HU","num":24},{"id":"hu25","country":"HU","num":25},{"id":"hu26","country":"HU","num":26},{"id":"hu27","country":"HU","num":27},{"id":"hu28","country":"HU","num":28},{"id":"hu29","country":"HU","num":29},{"id":"hu30","country":"HU","num":30},{"id":"hu31","country":"HU","num":31},{"id":"hu32","country":"HU","num":32},{"id":"hu33","country":"HU","num":33},{"id":"hu34","country":"HU","num":34}]},{"country":"ID","pools":[{"id":"id6","country":"ID","num":6},{"id":"id7","country":"ID","num":7},{"id":"id8","country":"ID","num":8},{"id":"id9","country":"ID","num":9}]},{"country":"IE","pools":[{"id":"ie19","country":"IE","num":19},{"id":"ie20","country":"IE","num":20},{"id":"ie21","country":"IE","num":21},{"id":"ie22","country":"IE","num":22},{"id":"ie23","country":"IE","num":23},{"id":"ie24","country":"IE","num":24},{"id":"ie25","country":"IE","num":25},{"id":"ie26","country":"IE","num":26},{"id":"ie27","country":"IE","num":27},{"id":"ie28","country":"IE","num":28},{"id":"ie29","country":"IE","num":29},{"id":"ie30","country":"IE","num":30},{"id":"ie31","country":"IE","num":31},{"id":"ie32","country":"IE","num":32},{"id":"ie33","country":"IE","num":33},{"id":"ie34","country":"IE","num":34},{"id":"ie35","country":"IE","num":35},{"id":"ie36","country":"IE","num":36},{"id":"ie37","country":"IE","num":37},{"id":"ie38","country":"IE","num":38},{"id":"ie39","country":"IE","num":39},{"id":"ie40","country":"IE","num":40},{"id":"ie41","country":"IE","num":41},{"id":"ie42","country":"IE","num":42},{"id":"ie43","country":"IE","num":43},{"id":"ie44","country":"IE","num":44},{"id":"ie45","country":"IE","num":45},{"id":"ie46","country":"IE","num":46},{"id":"ie47","country":"IE","num":47},{"id":"ie48","country":"IE","num":48},{"id":"ie49","country":"IE","num":49},{"id":"ie50","country":"IE","num":50},{"id":"ie51","country":"IE","num":51},{"id":"ie52","country":"IE","num":52},{"id":"ie53","country":"IE","num":53},{"id":"ie54","country":"IE","num":54},{"id":"ie55","country":"IE","num":55},{"id":"ie56","country":"IE","num":56},{"id":"ie57","country":"IE","num":57},{"id":"ie58","country":"IE","num":58},{"id":"ie59","country":"IE","num":59},{"id":"ie60","country":"IE","num":60},{"id":"ie61","country":"IE","num":61}]},{"country":"IL","pools":[{"id":"il12","country":"IL","num":12},{"id":"il13","country":"IL","num":13},{"id":"il14","country":"IL","num":14},{"id":"il15","country":"IL","num":15},{"id":"il16","country":"IL","num":16},{"id":"il17","country":"IL","num":17},{"id":"il18","country":"IL","num":18},{"id":"il19","country":"IL","num":19},{"id":"il20","country":"IL","num":20},{"id":"il21","country":"IL","num":21},{"id":"il22","country":"IL","num":22}]},{"country":"IN","pools":[{"id":"in19","country":"IN","num":19},{"id":"in20","country":"IN","num":20},{"id":"in21","country":"IN","num":21},{"id":"in22","country":"IN","num":22},{"id":"in23","country":"IN","num":23},{"id":"in24","country":"IN","num":24},{"id":"in25","country":"IN","num":25},{"id":"in26","country":"IN","num":26},{"id":"in27","country":"IN","num":27},{"id":"in28","country":"IN","num":28},{"id":"in29","country":"IN","num":29},{"id":"in30","country":"IN","num":30},{"id":"in31","country":"IN","num":31},{"id":"in32","country":"IN","num":32},{"id":"in33","country":"IN","num":33}]},{"country":"IS","pools":[{"id":"is20","country":"IS","num":20},{"id":"is21","country":"IS","num":21},{"id":"is22","country":"IS","num":22},{"id":"is23","country":"IS","num":23},{"id":"is24","country":"IS","num":24},{"id":"is25","country":"IS","num":25},{"id":"is26","country":"IS","num":26},{"id":"is27","country":"IS","num":27},{"id":"is28","country":"IS","num":28},{"id":"is29","country":"IS","num":29},{"id":"is30","country":"IS","num":30},{"id":"is31","country":"IS","num":31},{"id":"is32","country":"IS","num":32},{"id":"is33","country":"IS","num":33},{"id":"is34","country":"IS","num":34},{"id":"is35","country":"IS","num":35},{"id":"is36","country":"IS","num":36},{"id":"is37","country":"IS","num":37},{"id":"is38","country":"IS","num":38},{"id":"is39","country":"IS","num":39},{"id":"is40","country":"IS","num":40},{"id":"is41","country":"IS","num":41},{"id":"is42","country":"IS","num":42},{"id":"is43","country":"IS","num":43}]},{"country":"IT","pools":[{"id":"it36","country":"IT","num":36},{"id":"it37","country":"IT","num":37},{"id":"it38","country":"IT","num":38},{"id":"it39","country":"IT","num":39},{"id":"it40","country":"IT","num":40},{"id":"it41","country":"IT","num":41},{"id":"it42","country":"IT","num":42},{"id":"it43","country":"IT","num":43},{"id":"it44","country":"IT","num":44},{"id":"it45","country":"IT","num":45},{"id":"it46","country":"IT","num":46},{"id":"it47","country":"IT","num":47},{"id":"it52","country":"IT","num":52},{"id":"it53","country":"IT","num":53},{"id":"it54","country":"IT","num":54},{"id":"it55","country":"IT","num":55},{"id":"it56","country":"IT","num":56},{"id":"it57","country":"IT","num":57},{"id":"it58","country":"IT","num":58},{"id":"it59","country":"IT","num":59},{"id":"it60","country":"IT","num":60},{"id":"it61","country":"IT","num":61},{"id":"it62","country":"IT","num":62},{"id":"it63","country":"IT","num":63},{"id":"it66","country":"IT","num":66},{"id":"it67","country":"IT","num":67},{"id":"it68","country":"IT","num":68},{"id":"it69","country":"IT","num":69},{"id":"it70","country":"IT","num":70},{"id":"it71","country":"IT","num":71},{"id":"it72","country":"IT","num":72},{"id":"it73","country":"IT","num":73},{"id":"it74","country":"IT","num":74},{"id":"it75","country":"IT","num":75},{"id":"it76","country":"IT","num":76},{"id":"it77","country":"IT","num":77},{"id":"it78","country":"IT","num":78},{"id":"it79","country":"IT","num":79},{"id":"it80","country":"IT","num":80},{"id":"it81","country":"IT","num":81},{"id":"it82","country":"IT","num":82},{"id":"it83","country":"IT","num":83},{"id":"it84","country":"IT","num":84},{"id":"it85","country":"IT","num":85},{"id":"it86","country":"IT","num":86},{"id":"it87","country":"IT","num":87},{"id":"it88","country":"IT","num":88},{"id":"it89","country":"IT","num":89},{"id":"it90","country":"IT","num":90},{"id":"it91","country":"IT","num":91}]},{"country":"JP","pools":[{"id":"jp119","country":"JP","num":119},{"id":"jp120","country":"JP","num":120},{"id":"jp121","country":"JP","num":121},{"id":"jp122","country":"JP","num":122},{"id":"jp123","country":"JP","num":123},{"id":"jp124","country":"JP","num":124},{"id":"jp125","country":"JP","num":125},{"id":"jp126","country":"JP","num":126},{"id":"jp176","country":"JP","num":176},{"id":"jp181","country":"JP","num":181},{"id":"jp190","country":"JP","num":190},{"id":"jp191","country":"JP","num":191},{"id":"jp192","country":"JP","num":192},{"id":"jp201","country":"JP","num":201},{"id":"jp202","country":"JP","num":202},{"id":"jp203","country":"JP","num":203},{"id":"jp204","country":"JP","num":204},{"id":"jp206","country":"JP","num":206},{"id":"jp207","country":"JP","num":207},{"id":"jp210","country":"JP","num":210},{"id":"jp211","country":"JP","num":211},{"id":"jp216","country":"JP","num":216},{"id":"jp217","country":"JP","num":217}]},{"country":"KR","pools":[{"id":"kr18","country":"KR","num":18},{"id":"kr19","country":"KR","num":19},{"id":"kr20","country":"KR","num":20},{"id":"kr21","country":"KR","num":21},{"id":"kr22","country":"KR","num":22},{"id":"kr23","country":"KR","num":23},{"id":"kr24","country":"KR","num":24},{"id":"kr25","country":"KR","num":25},{"id":"kr26","country":"KR","num":26},{"id":"kr27","country":"KR","num":27}]},{"country":"LU","pools":[{"id":"lu29","country":"LU","num":29},{"id":"lu30","country":"LU","num":30},{"id":"lu31","country":"LU","num":31},{"id":"lu32","country":"LU","num":32},{"id":"lu33","country":"LU","num":33},{"id":"lu34","country":"LU","num":34},{"id":"lu35","country":"LU","num":35},{"id":"lu36","country":"LU","num":36},{"id":"lu37","country":"LU","num":37},{"id":"lu38","country":"LU","num":38},{"id":"lu39","country":"LU","num":39},{"id":"lu40","country":"LU","num":40},{"id":"lu41","country":"LU","num":41},{"id":"lu42","country":"LU","num":42},{"id":"lu43","country":"LU","num":43},{"id":"lu44","country":"LU","num":44},{"id":"lu45","country":"LU","num":45},{"id":"lu46","country":"LU","num":46},{"id":"lu47","country":"LU","num":47},{"id":"lu48","country":"LU","num":48},{"id":"lu49","country":"LU","num":49},{"id":"lu50","country":"LU","num":50},{"id":"lu51","country":"LU","num":51},{"id":"lu52","country":"LU","num":52},{"id":"lu53","country":"LU","num":53},{"id":"lu54","country":"LU","num":54},{"id":"lu55","country":"LU","num":55},{"id":"lu56","country":"LU","num":56},{"id":"lu57","country":"LU","num":57},{"id":"lu58","country":"LU","num":58},{"id":"lu59","country":"LU","num":59},{"id":"lu60","country":"LU","num":60},{"id":"lu61","country":"LU","num":61},{"id":"lu62","country":"LU","num":62},{"id":"lu63","country":"LU","num":63}]},{"country":"LV","pools":[{"id":"lv17","country":"LV","num":17},{"id":"lv18","country":"LV","num":18},{"id":"lv19","country":"LV","num":19},{"id":"lv20","country":"LV","num":20},{"id":"lv21","country":"LV","num":21},{"id":"lv22","country":"LV","num":22},{"id":"lv23","country":"LV","num":23},{"id":"lv24","country":"LV","num":24},{"id":"lv25","country":"LV","num":25},{"id":"lv26","country":"LV","num":26},{"id":"lv27","country":"LV","num":27},{"id":"lv28","country":"LV","num":28},{"id":"lv29","country":"LV","num":29},{"id":"lv30","country":"LV","num":30},{"id":"lv31","country":"LV","num":31}]},{"country":"MD","pools":[{"id":"md10","country":"MD","num":10},{"id":"md6","country":"MD","num":6},{"id":"md7","country":"MD","num":7},{"id":"md8","country":"MD","num":8},{"id":"md9","country":"MD","num":9}]},{"country":"MK","pools":[{"id":"mk5","country":"MK","num":5},{"id":"mk6","country":"MK","num":6}]},{"country":"MX","pools":[{"id":"mx12","country":"MX","num":12},{"id":"mx13","country":"MX","num":13}]},{"country":"MY","pools":[{"id":"my10","country":"MY","num":10},{"id":"my11","country":"MY","num":11},{"id":"my12","country":"MY","num":12},{"id":"my5","country":"MY","num":5},{"id":"my6","country":"MY","num":6},{"id":"my7","country":"MY","num":7},{"id":"my9","country":"MY","num":9}]},{"country":"NL","pools":[{"id":"nl104","country":"NL","num":104},{"id":"nl105","country":"NL","num":105},{"id":"nl106","country":"NL","num":106},{"id":"nl107","country":"NL","num":107},{"id":"nl108","country":"NL","num":108},{"id":"nl109","country":"NL","num":109},{"id":"nl110","country":"NL","num":110},{"id":"nl111","country":"NL","num":111},{"id":"nl112","country":"NL","num":112},{"id":"nl113","country":"NL","num":113},{"id":"nl114","country":"NL","num":114},{"id":"nl115","country":"NL","num":115},{"id":"nl116","country":"NL","num":116},{"id":"nl117","country":"NL","num":117},{"id":"nl118","country":"NL","num":118},{"id":"nl119","country":"NL","num":119},{"id":"nl120","country":"NL","num":120},{"id":"nl121","country":"NL","num":121},{"id":"nl122","country":"NL","num":122},{"id":"nl123","country":"NL","num":123},{"id":"nl124","country":"NL","num":124},{"id":"nl125","country":"NL","num":125},{"id":"nl126","country":"NL","num":126},{"id":"nl127","country":"NL","num":127},{"id":"nl229","country":"NL","num":229},{"id":"nl230","country":"NL","num":230},{"id":"nl231","country":"NL","num":231},{"id":"nl232","country":"NL","num":232},{"id":"nl257","country":"NL","num":257},{"id":"nl258","country":"NL","num":258},{"id":"nl259","country":"NL","num":259},{"id":"nl260","country":"NL","num":260},{"id":"nl261","country":"NL","num":261},{"id":"nl262","country":"NL","num":262},{"id":"nl263","country":"NL","num":263},{"id":"nl264","country":"NL","num":264},{"id":"nl265","country":"NL","num":265},{"id":"nl266","country":"NL","num":266},{"id":"nl267","country":"NL","num":267},{"id":"nl268","country":"NL","num":268},{"id":"nl284","country":"NL","num":284},{"id":"nl285","country":"NL","num":285},{"id":"nl286","country":"NL","num":286},{"id":"nl287","country":"NL","num":287},{"id":"nl288","country":"NL","num":288},{"id":"nl289","country":"NL","num":289},{"id":"nl290","country":"NL","num":290},{"id":"nl291","country":"NL","num":291},{"id":"nl292","country":"NL","num":292},{"id":"nl293","country":"NL","num":293},{"id":"nl294","country":"NL","num":294},{"id":"nl295","country":"NL","num":295},{"id":"nl296","country":"NL","num":296},{"id":"nl297","country":"NL","num":297},{"id":"nl298","country":"NL","num":298},{"id":"nl299","country":"NL","num":299},{"id":"nl300","country":"NL","num":300},{"id":"nl301","country":"NL","num":301},{"id":"nl302","country":"NL","num":302},{"id":"nl303","country":"NL","num":303},{"id":"nl304","country":"NL","num":304},{"id":"nl305","country":"NL","num":305},{"id":"nl306","country":"NL","num":306},{"id":"nl307","country":"NL","num":307},{"id":"nl308","country":"NL","num":308},{"id":"nl309","country":"NL","num":309},{"id":"nl310","country":"NL","num":310},{"id":"nl311","country":"NL","num":311},{"id":"nl312","country":"NL","num":312},{"id":"nl313","country":"NL","num":313},{"id":"nl314","country":"NL","num":314},{"id":"nl315","country":"NL","num":315},{"id":"nl316","country":"NL","num":316},{"id":"nl317","country":"NL","num":317},{"id":"nl318","country":"NL","num":318},{"id":"nl319","country":"NL","num":319},{"id":"nl320","country":"NL","num":320},{"id":"nl321","country":"NL","num":321},{"id":"nl322","country":"NL","num":322},{"id":"nl323","country":"NL","num":323},{"id":"nl324","country":"NL","num":324},{"id":"nl325","country":"NL","num":325},{"id":"nl326","country":"NL","num":326},{"id":"nl327","country":"NL","num":327},{"id":"nl328","country":"NL","num":328},{"id":"nl329","country":"NL","num":329},{"id":"nl330","country":"NL","num":330},{"id":"nl331","country":"NL","num":331},{"id":"nl344","country":"NL","num":344},{"id":"nl345","country":"NL","num":345},{"id":"nl346","country":"NL","num":346},{"id":"nl347","country":"NL","num":347},{"id":"nl348","country":"NL","num":348},{"id":"nl349","country":"NL","num":349},{"id":"nl350","country":"NL","num":350},{"id":"nl351","country":"NL","num":351},{"id":"nl352","country":"NL","num":352},{"id":"nl353","country":"NL","num":353},{"id":"nl354","country":"NL","num":354},{"id":"nl355","country":"NL","num":355},{"id":"nl356","country":"NL","num":356},{"id":"nl357","country":"NL","num":357},{"id":"nl358","country":"NL","num":358},{"id":"nl359","country":"NL","num":359},{"id":"nl360","country":"NL","num":360},{"id":"nl361","country":"NL","num":361},{"id":"nl362","country":"NL","num":362},{"id":"nl363","country":"NL","num":363},{"id":"nl364","country":"NL","num":364},{"id":"nl365","country":"NL","num":365},{"id":"nl366","country":"NL","num":366},{"id":"nl367","country":"NL","num":367},{"id":"nl368","country":"NL","num":368},{"id":"nl369","country":"NL","num":369},{"id":"nl370","country":"NL","num":370},{"id":"nl371","country":"NL","num":371},{"id":"nl372","country":"NL","num":372},{"id":"nl373","country":"NL","num":373},{"id":"nl375","country":"NL","num":375},{"id":"nl376","country":"NL","num":376},{"id":"nl377","country":"NL","num":377},{"id":"nl378","country":"NL","num":378},{"id":"nl379","country":"NL","num":379},{"id":"nl380","country":"NL","num":380},{"id":"nl381","country":"NL","num":381},{"id":"nl382","country":"NL","num":382},{"id":"nl383","country":"NL","num":383},{"id":"nl384","country":"NL","num":384},{"id":"nl385","country":"NL","num":385},{"id":"nl396","country":"NL","num":396},{"id":"nl397","country":"NL","num":397},{"id":"nl398","country":"NL","num":398},{"id":"nl399","country":"NL","num":399},{"id":"nl39","country":"NL","num":39},{"id":"nl400","country":"NL","num":400},{"id":"nl401","country":"NL","num":401},{"id":"nl402","country":"NL","num":402},{"id":"nl403","country":"NL","num":403},{"id":"nl404","country":"NL","num":404},{"id":"nl405","country":"NL","num":405},{"id":"nl40","country":"NL","num":40},{"id":"nl410","country":"NL","num":410},{"id":"nl411","country":"NL","num":411},{"id":"nl412","country":"NL","num":412},{"id":"nl413","country":"NL","num":413},{"id":"nl414","country":"NL","num":414},{"id":"nl415","country":"NL","num":415},{"id":"nl416","country":"NL","num":416},{"id":"nl417","country":"NL","num":417},{"id":"nl41","country":"NL","num":41},{"id":"nl426","country":"NL","num":426},{"id":"nl427","country":"NL","num":427},{"id":"nl428","country":"NL","num":428},{"id":"nl429","country":"NL","num":429},{"id":"nl42","country":"NL","num":42},{"id":"nl430","country":"NL","num":430},{"id":"nl431","country":"NL","num":431},{"id":"nl432","country":"NL","num":432},{"id":"nl433","country":"NL","num":433},{"id":"nl434","country":"NL","num":434},{"id":"nl435","country":"NL","num":435},{"id":"nl436","country":"NL","num":436},{"id":"nl437","country":"NL","num":437},{"id":"nl438","country":"NL","num":438},{"id":"nl439","country":"NL","num":439},{"id":"nl441","country":"NL","num":441},{"id":"nl442","country":"NL","num":442},{"id":"nl443","country":"NL","num":443},{"id":"nl444","country":"NL","num":444},{"id":"nl445","country":"NL","num":445},{"id":"nl446","country":"NL","num":446},{"id":"nl447","country":"NL","num":447},{"id":"nl448","country":"NL","num":448},{"id":"nl449","country":"NL","num":449},{"id":"nl450","country":"NL","num":450},{"id":"nl451","country":"NL","num":451},{"id":"nl452","country":"NL","num":452},{"id":"nl453","country":"NL","num":453},{"id":"nl454","country":"NL","num":454},{"id":"nl455","country":"NL","num":455},{"id":"nl456","country":"NL","num":456},{"id":"nl457","country":"NL","num":457},{"id":"nl458","country":"NL","num":458},{"id":"nl459","country":"NL","num":459},{"id":"nl460","country":"NL","num":460},{"id":"nl461","country":"NL","num":461},{"id":"nl462","country":"NL","num":462},{"id":"nl463","country":"NL","num":463},{"id":"nl464","country":"NL","num":464},{"id":"nl465","country":"NL","num":465},{"id":"nl466","country":"NL","num":466},{"id":"nl467","country":"NL","num":467},{"id":"nl468","country":"NL","num":468},{"id":"nl469","country":"NL","num":469},{"id":"nl470","country":"NL","num":470},{"id":"nl471","country":"NL","num":471},{"id":"nl472","country":"NL","num":472},{"id":"nl473","country":"NL","num":473},{"id":"nl474","country":"NL","num":474},{"id":"nl475","country":"NL","num":475},{"id":"nl476","country":"NL","num":476},{"id":"nl477","country":"NL","num":477},{"id":"nl478","country":"NL","num":478},{"id":"nl479","country":"NL","num":479},{"id":"nl480","country":"NL","num":480},{"id":"nl481","country":"NL","num":481},{"id":"nl482","country":"NL","num":482},{"id":"nl483","country":"NL","num":483},{"id":"nl484","country":"NL","num":484},{"id":"nl485","country":"NL","num":485},{"id":"nl486","country":"NL","num":486},{"id":"nl487","country":"NL","num":487},{"id":"nl488","country":"NL","num":488},{"id":"nl489","country":"NL","num":489},{"id":"nl490","country":"NL","num":490},{"id":"nl491","country":"NL","num":491},{"id":"nl492","country":"NL","num":492},{"id":"nl493","country":"NL","num":493},{"id":"nl494","country":"NL","num":494},{"id":"nl495","country":"NL","num":495},{"id":"nl496","country":"NL","num":496},{"id":"nl497","country":"NL","num":497},{"id":"nl498","country":"NL","num":498},{"id":"nl499","country":"NL","num":499},{"id":"nl500","country":"NL","num":500},{"id":"nl501","country":"NL","num":501},{"id":"nl502","country":"NL","num":502},{"id":"nl503","country":"NL","num":503},{"id":"nl504","country":"NL","num":504},{"id":"nl506","country":"NL","num":506},{"id":"nl68","country":"NL","num":68},{"id":"nl69","country":"NL","num":69},{"id":"nl70","country":"NL","num":70},{"id":"nl71","country":"NL","num":71},{"id":"nl72","country":"NL","num":72},{"id":"nl73","country":"NL","num":73},{"id":"nl74","country":"NL","num":74},{"id":"nl75","country":"NL","num":75},{"id":"nl76","country":"NL","num":76},{"id":"nl77","country":"NL","num":77},{"id":"nl78","country":"NL","num":78},{"id":"nl79","country":"NL","num":79},{"id":"nl92","country":"NL","num":92},{"id":"nl93","country":"NL","num":93},{"id":"nl94","country":"NL","num":94},{"id":"nl95","country":"NL","num":95},{"id":"nl-onion2","country":"NL","tags":["onion"],"num":2},{"id":"nl-onion3","country":"NL","tags":["onion"],"num":3}]},{"country":"NO","pools":[{"id":"no100","country":"NO","num":100},{"id":"no101","country":"NO","num":101},{"id":"no102","country":"NO","num":102},{"id":"no103","country":"NO","num":103},{"id":"no104","country":"NO","num":104},{"id":"no105","country":"NO","num":105},{"id":"no106","country":"NO","num":106},{"id":"no107","country":"NO","num":107},{"id":"no108","country":"NO","num":108},{"id":"no109","country":"NO","num":109},{"id":"no110","country":"NO","num":110},{"id":"no111","country":"NO","num":111},{"id":"no112","country":"NO","num":112},{"id":"no113","country":"NO","num":113},{"id":"no46","country":"NO","num":46},{"id":"no47","country":"NO","num":47},{"id":"no48","country":"NO","num":48},{"id":"no49","country":"NO","num":49},{"id":"no50","country":"NO","num":50},{"id":"no51","country":"NO","num":51},{"id":"no52","country":"NO","num":52},{"id":"no53","country":"NO","num":53},{"id":"no54","country":"NO","num":54},{"id":"no55","country":"NO","num":55},{"id":"no56","country":"NO","num":56},{"id":"no57","country":"NO","num":57},{"id":"no58","country":"NO","num":58},{"id":"no59","country":"NO","num":59},{"id":"no60","country":"NO","num":60},{"id":"no61","country":"NO","num":61},{"id":"no62","country":"NO","num":62},{"id":"no63","country":"NO","num":63},{"id":"no64","country":"NO","num":64},{"id":"no65","country":"NO","num":65},{"id":"no66","country":"NO","num":66},{"id":"no67","country":"NO","num":67},{"id":"no68","country":"NO","num":68},{"id":"no69","country":"NO","num":69},{"id":"no70","country":"NO","num":70},{"id":"no71","country":"NO","num":71},{"id":"no72","country":"NO","num":72},{"id":"no73","country":"NO","num":73},{"id":"no74","country":"NO","num":74},{"id":"no75","country":"NO","num":75},{"id":"no76","country":"NO","num":76},{"id":"no77","country":"NO","num":77},{"id":"no78","country":"NO","num":78},{"id":"no79","country":"NO","num":79},{"id":"no80","country":"NO","num":80},{"id":"no81","country":"NO","num":81},{"id":"no82","country":"NO","num":82},{"id":"no83","country":"NO","num":83},{"id":"no84","country":"NO","num":84},{"id":"no85","country":"NO","num":85},{"id":"no86","country":"NO","num":86},{"id":"no87","country":"NO","num":87},{"id":"no88","country":"NO","num":88},{"id":"no89","country":"NO","num":89},{"id":"no90","country":"NO","num":90},{"id":"no91","country":"NO","num":91},{"id":"no92","country":"NO","num":92},{"id":"no93","country":"NO","num":93},{"id":"no94","country":"NO","num":94},{"id":"no95","country":"NO","num":95},{"id":"no96","country":"NO","num":96},{"id":"no97","country":"NO","num":97},{"id":"no98","country":"NO","num":98},{"id":"no99","country":"NO","num":99}]},{"country":"NZ","pools":[{"id":"nz24","country":"NZ","num":24},{"id":"nz25","country":"NZ","num":25},{"id":"nz26","country":"NZ","num":26},{"id":"nz27","country":"NZ","num":27},{"id":"nz28","country":"NZ","num":28},{"id":"nz29","country":"NZ","num":29},{"id":"nz30","country":"NZ","num":30},{"id":"nz31","country":"NZ","num":31},{"id":"nz32","country":"NZ","num":32},{"id":"nz33","country":"NZ","num":33},{"id":"nz34","country":"NZ","num":34},{"id":"nz35","country":"NZ","num":35},{"id":"nz36","country":"NZ","num":36},{"id":"nz37","country":"NZ","num":37},{"id":"nz38","country":"NZ","num":38},{"id":"nz39","country":"NZ","num":39},{"id":"nz40","country":"NZ","num":40},{"id":"nz41","country":"NZ","num":41}]},{"country":"PL","pools":[{"id":"pl44","country":"PL","num":44},{"id":"pl45","country":"PL","num":45},{"id":"pl46","country":"PL","num":46},{"id":"pl47","country":"PL","num":47},{"id":"pl48","country":"PL","num":48},{"id":"pl49","country":"PL","num":49},{"id":"pl50","country":"PL","num":50},{"id":"pl51","country":"PL","num":51},{"id":"pl54","country":"PL","num":54},{"id":"pl55","country":"PL","num":55},{"id":"pl56","country":"PL","num":56},{"id":"pl57","country":"PL","num":57},{"id":"pl58","country":"PL","num":58},{"id":"pl59","country":"PL","num":59},{"id":"pl60","country":"PL","num":60},{"id":"pl61","country":"PL","num":61},{"id":"pl62","country":"PL","num":62},{"id":"pl63","country":"PL","num":63},{"id":"pl64","country":"PL","num":64},{"id":"pl65","country":"PL","num":65},{"id":"pl66","country":"PL","num":66},{"id":"pl67","country":"PL","num":67},{"id":"pl68","country":"PL","num":68},{"id":"pl69","country":"PL","num":69},{"id":"pl70","country":"PL","num":70},{"id":"pl71","country":"PL","num":71},{"id":"pl72","country":"PL","num":72},{"id":"pl73","country":"PL","num":73},{"id":"pl74","country":"PL","num":74},{"id":"pl75","country":"PL","num":75},{"id":"pl76","country":"PL","num":76},{"id":"pl77","country":"PL","num":77},{"id":"pl78","country":"PL","num":78},{"id":"pl79","country":"PL","num":79},{"id":"pl80","country":"PL","num":80},{"id":"pl81","country":"PL","num":81},{"id":"pl82","country":"PL","num":82},{"id":"pl83","country":"PL","num":83},{"id":"pl84","country":"PL","num":84},{"id":"pl85","country":"PL","num":85},{"id":"pl86","country":"PL","num":86},{"id":"pl87","country":"PL","num":87},{"id":"pl88","country":"PL","num":88},{"id":"pl89","country":"PL","num":89},{"id":"pl90","country":"PL","num":90},{"id":"pl91","country":"PL","num":91},{"id":"pl92","country":"PL","num":92}]},{"country":"PT","pools":[{"id":"pt15","country":"PT","num":15},{"id":"pt16","country":"PT","num":16},{"id":"pt17","country":"PT","num":17},{"id":"pt18","country":"PT","num":18},{"id":"pt19","country":"PT","num":19},{"id":"pt20","country":"PT","num":20},{"id":"pt21","country":"PT","num":21},{"id":"pt22","country":"PT","num":22},{"id":"pt23","country":"PT","num":23},{"id":"pt24","country":"PT","num":24},{"id":"pt25","country":"PT","num":25},{"id":"pt26","country":"PT","num":26},{"id":"pt27","country":"PT","num":27},{"id":"pt28","country":"PT","num":28},{"id":"pt29","country":"PT","num":29},{"id":"pt30","country":"PT","num":30},{"id":"pt31","country":"PT","num":31}]},{"country":"RO","pools":[{"id":"ro33","country":"RO","num":33},{"id":"ro34","country":"RO","num":34},{"id":"ro35","country":"RO","num":35},{"id":"ro36","country":"RO","num":36},{"id":"ro37","country":"RO","num":37},{"id":"ro38","country":"RO","num":38},{"id":"ro39","country":"RO","num":39},{"id":"ro40","country":"RO","num":40},{"id":"ro41","country":"RO","num":41},{"id":"ro42","country":"RO","num":42},{"id":"ro43","country":"RO","num":43},{"id":"ro44","country":"RO","num":44},{"id":"ro45","country":"RO","num":45},{"id":"ro46","country":"RO","num":46}]},{"country":"RS","pools":[{"id":"rs10","country":"RS","num":10},{"id":"rs11","country":"RS","num":11},{"id":"rs12","country":"RS","num":12},{"id":"rs13","country":"RS","num":13},{"id":"rs14","country":"RS","num":14},{"id":"rs15","country":"RS","num":15},{"id":"rs16","country":"RS","num":16},{"id":"rs17","country":"RS","num":17},{"id":"rs18","country":"RS","num":18},{"id":"rs19","country":"RS","num":19},{"id":"rs20","country":"RS","num":20},{"id":"rs21","country":"RS","num":21},{"id":"rs22","country":"RS","num":22},{"id":"rs23","country":"RS","num":23},{"id":"rs24","country":"RS","num":24},{"id":"rs25","country":"RS","num":25},{"id":"rs26","country":"RS","num":26},{"id":"rs27","country":"RS","num":27},{"id":"rs28","country":"RS","num":28},{"id":"rs29","country":"RS","num":29},{"id":"rs30","country":"RS","num":30},{"id":"rs31","country":"RS","num":31},{"id":"rs32","country":"RS","num":32},{"id":"rs33","country":"RS","num":33},{"id":"rs34","country":"RS","num":34},{"id":"rs35","country":"RS","num":35},{"id":"rs36","country":"RS","num":36},{"id":"rs37","country":"RS","num":37},{"id":"rs38","country":"RS","num":38},{"id":"rs39","country":"RS","num":39},{"id":"rs40","country":"RS","num":40},{"id":"rs41","country":"RS","num":41},{"id":"rs42","country":"RS","num":42},{"id":"rs43","country":"RS","num":43},{"id":"rs44","country":"RS","num":44},{"id":"rs45","country":"RS","num":45},{"id":"rs6","country":"RS","num":6},{"id":"rs7","country":"RS","num":7},{"id":"rs8","country":"RS","num":8},{"id":"rs9","country":"RS","num":9}]},{"country":"SE","pools":[{"id":"se112","country":"SE","num":112},{"id":"se113","country":"SE","num":113},{"id":"se114","country":"SE","num":114},{"id":"se115","country":"SE","num":115},{"id":"se120","country":"SE","num":120},{"id":"se121","country":"SE","num":121},{"id":"se122","country":"SE","num":122},{"id":"se123","country":"SE","num":123},{"id":"se124","country":"SE","num":124},{"id":"se125","country":"SE","num":125},{"id":"se126","country":"SE","num":126},{"id":"se127","country":"SE","num":127},{"id":"se128","country":"SE","num":128},{"id":"se129","country":"SE","num":129},{"id":"se130","country":"SE","num":130},{"id":"se131","country":"SE","num":131},{"id":"se136","country":"SE","num":136},{"id":"se137","country":"SE","num":137},{"id":"se138","country":"SE","num":138},{"id":"se139","country":"SE","num":139},{"id":"se144","country":"SE","num":144},{"id":"se145","country":"SE","num":145},{"id":"se146","country":"SE","num":146},{"id":"se147","country":"SE","num":147},{"id":"se152","country":"SE","num":152},{"id":"se153","country":"SE","num":153},{"id":"se154","country":"SE","num":154},{"id":"se155","country":"SE","num":155},{"id":"se156","country":"SE","num":156},{"id":"se157","country":"SE","num":157},{"id":"se158","country":"SE","num":158},{"id":"se159","country":"SE","num":159},{"id":"se160","country":"SE","num":160},{"id":"se161","country":"SE","num":161},{"id":"se162","country":"SE","num":162},{"id":"se163","country":"SE","num":163},{"id":"se164","country":"SE","num":164},{"id":"se165","country":"SE","num":165},{"id":"se166","country":"SE","num":166},{"id":"se167","country":"SE","num":167},{"id":"se168","country":"SE","num":168},{"id":"se169","country":"SE","num":169},{"id":"se170","country":"SE","num":170},{"id":"se171","country":"SE","num":171},{"id":"se172","country":"SE","num":172},{"id":"se173","country":"SE","num":173},{"id":"se174","country":"SE","num":174},{"id":"se175","country":"SE","num":175},{"id":"se176","country":"SE","num":176},{"id":"se177","country":"SE","num":177},{"id":"se178","country":"SE","num":178},{"id":"se179","country":"SE","num":179},{"id":"se192","country":"SE","num":192},{"id":"se193","country":"SE","num":193},{"id":"se194","country":"SE","num":194},{"id":"se195","country":"SE","num":195},{"id":"se196","country":"SE","num":196},{"id":"se200","country":"SE","num":200},{"id":"se201","country":"SE","num":201},{"id":"se202","country":"SE","num":202},{"id":"se203","country":"SE","num":203},{"id":"se204","country":"SE","num":204},{"id":"se205","country":"SE","num":205},{"id":"se206","country":"SE","num":206},{"id":"se207","country":"SE","num":207},{"id":"se208","country":"SE","num":208},{"id":"se209","country":"SE","num":209},{"id":"se210","country":"SE","num":210},{"id":"se211","country":"SE","num":211},{"id":"se212","country":"SE","num":212},{"id":"se213","country":"SE","num":213},{"id":"se214","country":"SE","num":214},{"id":"se215","country":"SE","num":215},{"id":"se216","country":"SE","num":216},{"id":"se217","country":"SE","num":217},{"id":"se218","country":"SE","num":218},{"id":"se219","country":"SE","num":219},{"id":"se220","country":"SE","num":220},{"id":"se221","country":"SE","num":221},{"id":"se222","country":"SE","num":222},{"id":"se223","country":"SE","num":223},{"id":"se224","country":"SE","num":224},{"id":"se225","country":"SE","num":225},{"id":"se226","country":"SE","num":226},{"id":"se227","country":"SE","num":227},{"id":"se228","country":"SE","num":228},{"id":"se229","country":"SE","num":229},{"id":"se230","country":"SE","num":230},{"id":"se231","country":"SE","num":231},{"id":"se232","country":"SE","num":232},{"id":"se233","country":"SE","num":233},{"id":"se234","country":"SE","num":234},{"id":"se235","country":"SE","num":235},{"id":"se236","country":"SE","num":236},{"id":"se237","country":"SE","num":237},{"id":"se238","country":"SE","num":238},{"id":"se239","country":"SE","num":239},{"id":"se240","country":"SE","num":240},{"id":"se241","country":"SE","num":241},{"id":"se242","country":"SE","num":242},{"id":"se243","country":"SE","num":243},{"id":"se244","country":"SE","num":244},{"id":"se245","country":"SE","num":245},{"id":"se246","country":"SE","num":246},{"id":"se247","country":"SE","num":247},{"id":"se248","country":"SE","num":248},{"id":"se249","country":"SE","num":249},{"id":"se250","country":"SE","num":250},{"id":"se251","country":"SE","num":251},{"id":"se252","country":"SE","num":252},{"id":"se253","country":"SE","num":253},{"id":"se254","country":"SE","num":254},{"id":"se255","country":"SE","num":255},{"id":"se256","country":"SE","num":256},{"id":"se257","country":"SE","num":257},{"id":"se258","country":"SE","num":258},{"id":"se259","country":"SE","num":259},{"id":"se260","country":"SE","num":260},{"id":"se261","country":"SE","num":261},{"id":"se262","country":"SE","num":262},{"id":"se263","country":"SE","num":263},{"id":"se264","country":"SE","num":264},{"id":"se265","country":"SE","num":265},{"id":"se266","country":"SE","num":266},{"id":"se267","country":"SE","num":267},{"id":"se268","country":"SE","num":268},{"id":"se269","country":"SE","num":269},{"id":"se270","country":"SE","num":270},{"id":"se271","country":"SE","num":271},{"id":"se272","country":"SE","num":272},{"id":"se273","country":"SE","num":273},{"id":"se274","country":"SE","num":274},{"id":"se275","country":"SE","num":275},{"id":"se276","country":"SE","num":276},{"id":"se277","country":"SE","num":277},{"id":"se278","country":"SE","num":278},{"id":"se279","country":"SE","num":279},{"id":"se280","country":"SE","num":280},{"id":"se281","country":"SE","num":281},{"id":"se282","country":"SE","num":282},{"id":"se283","country":"SE","num":283},{"id":"se284","country":"SE","num":284},{"id":"se285","country":"SE","num":285},{"id":"se286","country":"SE","num":286},{"id":"se287","country":"SE","num":287},{"id":"se288","country":"SE","num":288},{"id":"se289","country":"SE","num":289},{"id":"se290","country":"SE","num":290},{"id":"se291","country":"SE","num":291},{"id":"se292","country":"SE","num":292},{"id":"se293","country":"SE","num":293},{"id":"se294","country":"SE","num":294},{"id":"se295","country":"SE","num":295},{"id":"se296","country":"SE","num":296},{"id":"se299","country":"SE","num":299},{"id":"se300","country":"SE","num":300},{"id":"se301","country":"SE","num":301},{"id":"se302","country":"SE","num":302},{"id":"se303","country":"SE","num":303},{"id":"se304","country":"SE","num":304},{"id":"se305","country":"SE","num":305},{"id":"se306","country":"SE","num":306},{"id":"se307","country":"SE","num":307},{"id":"se308","country":"SE","num":308},{"id":"se309","country":"SE","num":309},{"id":"se310","country":"SE","num":310},{"id":"se60","country":"SE","num":60},{"id":"se61","country":"SE","num":61},{"id":"se62","country":"SE","num":62},{"id":"se63","country":"SE","num":63}]},{"country":"SG","pools":[{"id":"sg114","country":"SG","num":114},{"id":"sg115","country":"SG","num":115},{"id":"sg170","country":"SG","num":170},{"id":"sg171","country":"SG","num":171},{"id":"sg172","country":"SG","num":172},{"id":"sg173","country":"SG","num":173},{"id":"sg174","country":"SG","num":174},{"id":"sg175","country":"SG","num":175},{"id":"sg176","country":"SG","num":176},{"id":"sg177","country":"SG","num":177},{"id":"sg178","country":"SG","num":178},{"id":"sg179","country":"SG","num":179},{"id":"sg180","country":"SG","num":180},{"id":"sg181","country":"SG","num":181},{"id":"sg182","country":"SG","num":182},{"id":"sg183","country":"SG","num":183},{"id":"sg188","country":"SG","num":188},{"id":"sg189","country":"SG","num":189},{"id":"sg192","country":"SG","num":192},{"id":"sg193","country":"SG","num":193},{"id":"sg196","country":"SG","num":196},{"id":"sg197","country":"SG","num":197},{"id":"sg200","country":"SG","num":200},{"id":"sg201","country":"SG","num":201},{"id":"sg202","country":"SG","num":202},{"id":"sg203","country":"SG","num":203},{"id":"sg204","country":"SG","num":204},{"id":"sg205","country":"SG","num":205},{"id":"sg206","country":"SG","num":206},{"id":"sg207","country":"SG","num":207},{"id":"sg208","country":"SG","num":208},{"id":"sg209","country":"SG","num":209},{"id":"sg210","country":"SG","num":210},{"id":"sg211","country":"SG","num":211}]},{"country":"SI","pools":[{"id":"si5","country":"SI","num":5},{"id":"si6","country":"SI","num":6},{"id":"si7","country":"SI","num":7},{"id":"si8","country":"SI","num":8}]},{"country":"SK","pools":[{"id":"sk11","country":"SK","num":11},{"id":"sk12","country":"SK","num":12},{"id":"sk13","country":"SK","num":13},{"id":"sk14","country":"SK","num":14},{"id":"sk15","country":"SK","num":15},{"id":"sk16","country":"SK","num":16},{"id":"sk17","country":"SK","num":17},{"id":"sk18","country":"SK","num":18},{"id":"sk19","country":"SK","num":19},{"id":"sk20","country":"SK","num":20},{"id":"sk21","country":"SK","num":21},{"id":"sk22","country":"SK","num":22},{"id":"sk23","country":"SK","num":23},{"id":"sk3","country":"SK","num":3},{"id":"sk4","country":"SK","num":4},{"id":"sk5","country":"SK","num":5},{"id":"sk6","country":"SK","num":6}]},{"country":"TH","pools":[{"id":"th2","country":"TH","num":2},{"id":"th3","country":"TH","num":3},{"id":"th5","country":"TH","num":5},{"id":"th6","country":"TH","num":6},{"id":"th7","country":"TH","num":7},{"id":"th8","country":"TH","num":8},{"id":"th9","country":"TH","num":9}]},{"country":"TR","pools":[{"id":"tr12","country":"TR","num":12},{"id":"tr13","country":"TR","num":13},{"id":"tr14","country":"TR","num":14},{"id":"tr15","country":"TR","num":15},{"id":"tr16","country":"TR","num":16},{"id":"tr17","country":"TR","num":17},{"id":"tr18","country":"TR","num":18},{"id":"tr19","country":"TR","num":19},{"id":"tr20","country":"TR","num":20},{"id":"tr21","country":"TR","num":21}]},{"country":"TW","pools":[{"id":"tw12","country":"TW","num":12},{"id":"tw13","country":"TW","num":13},{"id":"tw16","country":"TW","num":16},{"id":"tw17","country":"TW","num":17},{"id":"tw19","country":"TW","num":19},{"id":"tw20","country":"TW","num":20},{"id":"tw21","country":"TW","num":21}]},{"country":"UA","pools":[{"id":"ua10","country":"UA","num":10},{"id":"ua11","country":"UA","num":11},{"id":"ua13","country":"UA","num":13},{"id":"ua14","country":"UA","num":14},{"id":"ua15","country":"UA","num":15},{"id":"ua16","country":"UA","num":16},{"id":"ua17","country":"UA","num":17},{"id":"ua6","country":"UA","num":6},{"id":"ua8","country":"UA","num":8},{"id":"ua9","country":"UA","num":9}]},{"country":"GB","pools":[{"id":"uk1000","country":"GB","num":1000},{"id":"uk1001","country":"GB","num":1001},{"id":"uk1002","country":"GB","num":1002},{"id":"uk1003","country":"GB","num":1003},{"id":"uk1004","country":"GB","num":1004},{"id":"uk1005","country":"GB","num":1005},{"id":"uk1006","country":"GB","num":1006},{"id":"uk1007","country":"GB","num":1007},{"id":"uk1008","country":"GB","num":1008},{"id":"uk1009","country":"GB","num":1009},{"id":"uk1010","country":"GB","num":1010},{"id":"uk1011","country":"GB","num":1011},{"id":"uk1012","country":"GB","num":1012},{"id":"uk1013","country":"GB","num":1013},{"id":"uk1014","country":"GB","num":1014},{"id":"uk1015","country":"GB","num":1015},{"id":"uk1016","country":"GB","num":1016},{"id":"uk1017","country":"GB","num":1017},{"id":"uk1018","country":"GB","num":1018},{"id":"uk1019","country":"GB","num":1019},{"id":"uk1020","country":"GB","num":1020},{"id":"uk1021","country":"GB","num":1021},{"id":"uk1022","country":"GB","num":1022},{"id":"uk1023","country":"GB","num":1023},{"id":"uk1024","country":"GB","num":1024},{"id":"uk1025","country":"GB","num":1025},{"id":"uk1026","country":"GB","num":1026},{"id":"uk1027","country":"GB","num":1027},{"id":"uk1028","country":"GB","num":1028},{"id":"uk1029","country":"GB","num":1029},{"id":"uk1030","country":"GB","num":1030},{"id":"uk1031","country":"GB","num":1031},{"id":"uk1032","country":"GB","num":1032},{"id":"uk1033","country":"GB","num":1033},{"id":"uk1034","country":"GB","num":1034},{"id":"uk1035","country":"GB","num":1035},{"id":"uk1036","country":"GB","num":1036},{"id":"uk1037","country":"GB","num":1037},{"id":"uk1038","country":"GB","num":1038},{"id":"uk1039","country":"GB","num":1039},{"id":"uk1040","country":"GB","num":1040},{"id":"uk1041","country":"GB","num":1041},{"id":"uk1042","country":"GB","num":1042},{"id":"uk1043","country":"GB","num":1043},{"id":"uk1044","country":"GB","num":1044},{"id":"uk1045","country":"GB","num":1045},{"id":"uk1046","country":"GB","num":1046},{"id":"uk1047","country":"GB","num":1047},{"id":"uk1048","country":"GB","num":1048},{"id":"uk1049","country":"GB","num":1049},{"id":"uk1050","country":"GB","num":1050},{"id":"uk1051","country":"GB","num":1051},{"id":"uk1052","country":"GB","num":1052},{"id":"uk1053","country":"GB","num":1053},{"id":"uk1054","country":"GB","num":1054},{"id":"uk1055","country":"GB","num":1055},{"id":"uk1057","country":"GB","num":1057},{"id":"uk1058","country":"GB","num":1058},{"id":"uk1059","country":"GB","num":1059},{"id":"uk1060","country":"GB","num":1060},{"id":"uk1061","country":"GB","num":1061},{"id":"uk1062","country":"GB","num":1062},{"id":"uk1063","country":"GB","num":1063},{"id":"uk1064","country":"GB","num":1064},{"id":"uk1065","country":"GB","num":1065},{"id":"uk1066","country":"GB","num":1066},{"id":"uk1067","country":"GB","num":1067},{"id":"uk1068","country":"GB","num":1068},{"id":"uk1069","country":"GB","num":1069},{"id":"uk1070","country":"GB","num":1070},{"id":"uk1071","country":"GB","num":1071},{"id":"uk1072","country":"GB","num":1072},{"id":"uk1073","country":"GB","num":1073},{"id":"uk1074","country":"GB","num":1074},{"id":"uk1075","country":"GB","num":1075},{"id":"uk1076","country":"GB","num":1076},{"id":"uk1077","country":"GB","num":1077},{"id":"uk1078","country":"GB","num":1078},{"id":"uk1079","country":"GB","num":1079},{"id":"uk1080","country":"GB","num":1080},{"id":"uk1081","country":"GB","num":1081},{"id":"uk1082","country":"GB","num":1082},{"id":"uk1083","country":"GB","num":1083},{"id":"uk1084","country":"GB","num":1084},{"id":"uk1085","country":"GB","num":1085},{"id":"uk1086","country":"GB","num":1086},{"id":"uk1087","country":"GB","num":1087},{"id":"uk1088","country":"GB","num":1088},{"id":"uk1089","country":"GB","num":1089},{"id":"uk1090","country":"GB","num":1090},{"id":"uk1091","country":"GB","num":1091},{"id":"uk1092","country":"GB","num":1092},{"id":"uk1093","country":"GB","num":1093},{"id":"uk1094","country":"GB","num":1094},{"id":"uk1095","country":"GB","num":1095},{"id":"uk1096","country":"GB","num":1096},{"id":"uk1097","country":"GB","num":1097},{"id":"uk1098","country":"GB","num":1098},{"id":"uk1099","country":"GB","num":1099},{"id":"uk1100","country":"GB","num":1100},{"id":"uk1101","country":"GB","num":1101},{"id":"uk1102","country":"GB","num":1102},{"id":"uk1103","country":"GB","num":1103},{"id":"uk1104","country":"GB","num":1104},{"id":"uk1105","country":"GB","num":1105},{"id":"uk1106","country":"GB","num":1106},{"id":"uk1107","country":"GB","num":1107},{"id":"uk1108","country":"GB","num":1108},{"id":"uk1109","country":"GB","num":1109},{"id":"uk1110","country":"GB","num":1110},{"id":"uk1111","country":"GB","num":1111},{"id":"uk1112","country":"GB","num":1112},{"id":"uk1113","country":"GB","num":1113},{"id":"uk1114","country":"GB","num":1114},{"id":"uk1115","country":"GB","num":1115},{"id":"uk1116","country":"GB","num":1116},{"id":"uk1117","country":"GB","num":1117},{"id":"uk1118","country":"GB","num":1118},{"id":"uk1119","country":"GB","num":1119},{"id":"uk1120","country":"GB","num":1120},{"id":"uk1121","country":"GB","num":1121},{"id":"uk1122","country":"GB","num":1122},{"id":"uk1123","country":"GB","num":1123},{"id":"uk1124","country":"GB","num":1124},{"id":"uk1125","country":"GB","num":1125},{"id":"uk1126","country":"GB","num":1126},{"id":"uk1127","country":"GB","num":1127},{"id":"uk1128","country":"GB","num":1128},{"id":"uk1129","country":"GB","num":1129},{"id":"uk1130","country":"GB","num":1130},{"id":"uk1131","country":"GB","num":1131},{"id":"uk1132","country":"GB","num":1132},{"id":"uk1133","country":"GB","num":1133},{"id":"uk1134","country":"GB","num":1134},{"id":"uk1135","country":"GB","num":1135},{"id":"uk1136","country":"GB","num":1136},{"id":"uk1137","country":"GB","num":1137},{"id":"uk1138","country":"GB","num":1138},{"id":"uk1139","country":"GB","num":1139},{"id":"uk1140","country":"GB","num":1140},{"id":"uk1141","country":"GB","num":1141},{"id":"uk1142","country":"GB","num":1142},{"id":"uk1143","country":"GB","num":1143},{"id":"uk1146","country":"GB","num":1146},{"id":"uk1147","country":"GB","num":1147},{"id":"uk1148","country":"GB","num":1148},{"id":"uk1149","country":"GB","num":1149},{"id":"uk1150","country":"GB","num":1150},{"id":"uk1151","country":"GB","num":1151},{"id":"uk1152","country":"GB","num":1152},{"id":"uk1153","country":"GB","num":1153},{"id":"uk1154","country":"GB","num":1154},{"id":"uk1155","country":"GB","num":1155},{"id":"uk1156","country":"GB","num":1156},{"id":"uk1157","country":"GB","num":1157},{"id":"uk1158","country":"GB","num":1158},{"id":"uk1159","country":"GB","num":1159},{"id":"uk1160","country":"GB","num":1160},{"id":"uk1161","country":"GB","num":1161},{"id":"uk1162","country":"GB","num":1162},{"id":"uk1163","country":"GB","num":1163},{"id":"uk1164","country":"GB","num":1164},{"id":"uk1165","country":"GB","num":1165},{"id":"uk1166","country":"GB","num":1166},{"id":"uk1167","country":"GB","num":1167},{"id":"uk1168","country":"GB","num":1168},{"id":"uk1169","country":"GB","num":1169},{"id":"uk1170","country":"GB","num":1170},{"id":"uk1171","country":"GB","num":1171},{"id":"uk1172","country":"GB","num":1172},{"id":"uk1173","country":"GB","num":1173},{"id":"uk1174","country":"GB","num":1174},{"id":"uk1175","country":"GB","num":1175},{"id":"uk118","country":"GB","num":118},{"id":"uk119","country":"GB","num":119},{"id":"uk120","country":"GB","num":120},{"id":"uk121","country":"GB","num":121},{"id":"uk122","country":"GB","num":122},{"id":"uk123","country":"GB","num":123},{"id":"uk124","country":"GB","num":124},{"id":"uk125","country":"GB","num":125},{"id":"uk268","country":"GB","num":268},{"id":"uk269","country":"GB","num":269},{"id":"uk270","country":"GB","num":270},{"id":"uk271","country":"GB","num":271},{"id":"uk437","country":"GB","num":437},{"id":"uk438","country":"GB","num":438},{"id":"uk439","country":"GB","num":439},{"id":"uk440","country":"GB","num":440},{"id":"uk441","country":"GB","num":441},{"id":"uk442","country":"GB","num":442},{"id":"uk443","country":"GB","num":443},{"id":"uk444","country":"GB","num":444},{"id":"uk445","country":"GB","num":445},{"id":"uk446","country":"GB","num":446},{"id":"uk447","country":"GB","num":447},{"id":"uk448","country":"GB","num":448},{"id":"uk449","country":"GB","num":449},{"id":"uk450","country":"GB","num":450},{"id":"uk451","country":"GB","num":451},{"id":"uk452","country":"GB","num":452},{"id":"uk453","country":"GB","num":453},{"id":"uk454","country":"GB","num":454},{"id":"uk455","country":"GB","num":455},{"id":"uk456","country":"GB","num":456},{"id":"uk457","country":"GB","num":457},{"id":"uk458","country":"GB","num":458},{"id":"uk459","country":"GB","num":459},{"id":"uk460","country":"GB","num":460},{"id":"uk461","country":"GB","num":461},{"id":"uk462","country":"GB","num":462},{"id":"uk463","country":"GB","num":463},{"id":"uk464","country":"GB","num":464},{"id":"uk465","country":"GB","num":465},{"id":"uk466","country":"GB","num":466},{"id":"uk467","country":"GB","num":467},{"id":"uk468","country":"GB","num":468},{"id":"uk469","country":"GB","num":469},{"id":"uk470","country":"GB","num":470},{"id":"uk471","country":"GB","num":471},{"id":"uk472","country":"GB","num":472},{"id":"uk488","country":"GB","num":488},{"id":"uk489","country":"GB","num":489},{"id":"uk490","country":"GB","num":490},{"id":"uk491","country":"GB","num":491},{"id":"uk557","country":"GB","num":557},{"id":"uk558","country":"GB","num":558},{"id":"uk559","country":"GB","num":559},{"id":"uk560","country":"GB","num":560},{"id":"uk561","country":"GB","num":561},{"id":"uk562","country":"GB","num":562},{"id":"uk563","country":"GB","num":563},{"id":"uk564","country":"GB","num":564},{"id":"uk565","country":"GB","num":565},{"id":"uk566","country":"GB","num":566},{"id":"uk567","country":"GB","num":567},{"id":"uk568","country":"GB","num":568},{"id":"uk569","country":"GB","num":569},{"id":"uk570","country":"GB","num":570},{"id":"uk571","country":"GB","num":571},{"id":"uk572","country":"GB","num":572},{"id":"uk573","country":"GB","num":573},{"id":"uk574","country":"GB","num":574},{"id":"uk575","country":"GB","num":575},{"id":"uk576","country":"GB","num":576},{"id":"uk577","country":"GB","num":577},{"id":"uk578","country":"GB","num":578},{"id":"uk579","country":"GB","num":579},{"id":"uk580","country":"GB","num":580},{"id":"uk585","country":"GB","num":585},{"id":"uk586","country":"GB","num":586},{"id":"uk587","country":"GB","num":587},{"id":"uk588","country":"GB","num":588},{"id":"uk589","country":"GB","num":589},{"id":"uk58","country":"GB","num":58},{"id":"uk590","country":"GB","num":590},{"id":"uk591","country":"GB","num":591},{"id":"uk592","country":"GB","num":592},{"id":"uk593","country":"GB","num":593},{"id":"uk594","country":"GB","num":594},{"id":"uk595","country":"GB","num":595},{"id":"uk596","country":"GB","num":596},{"id":"uk597","country":"GB","num":597},{"id":"uk598","country":"GB","num":598},{"id":"uk599","country":"GB","num":599},{"id":"uk59","country":"GB","num":59},{"id":"uk600","country":"GB","num":600},{"id":"uk601","country":"GB","num":601},{"id":"uk602","country":"GB","num":602},{"id":"uk603","country":"GB","num":603},{"id":"uk604","country":"GB","num":604},{"id":"uk605","country":"GB","num":605},{"id":"uk606","country":"GB","num":606},{"id":"uk607","country":"GB","num":607},{"id":"uk608","country":"GB","num":608},{"id":"uk609","country":"GB","num":609},{"id":"uk610","country":"GB","num":610},{"id":"uk611","country":"GB","num":611},{"id":"uk612","country":"GB","num":612},{"id":"uk613","country":"GB","num":613},{"id":"uk614","country":"GB","num":614},{"id":"uk615","country":"GB","num":615},{"id":"uk616","country":"GB","num":616},{"id":"uk617","country":"GB","num":617},{"id":"uk618","country":"GB","num":618},{"id":"uk619","country":"GB","num":619},{"id":"uk620","country":"GB","num":620},{"id":"uk621","country":"GB","num":621},{"id":"uk622","country":"GB","num":622},{"id":"uk623","country":"GB","num":623},{"id":"uk624","country":"GB","num":624},{"id":"uk625","country":"GB","num":625},{"id":"uk626","country":"GB","num":626},{"id":"uk627","country":"GB","num":627},{"id":"uk628","country":"GB","num":628},{"id":"uk633","country":"GB","num":633},{"id":"uk634","country":"GB","num":634},{"id":"uk635","country":"GB","num":635},{"id":"uk636","country":"GB","num":636},{"id":"uk637","country":"GB","num":637},{"id":"uk638","country":"GB","num":638},{"id":"uk639","country":"GB","num":639},{"id":"uk640","country":"GB","num":640},{"id":"uk641","country":"GB","num":641},{"id":"uk642","country":"GB","num":642},{"id":"uk643","country":"GB","num":643},{"id":"uk644","country":"GB","num":644},{"id":"uk645","country":"GB","num":645},{"id":"uk646","country":"GB","num":646},{"id":"uk647","country":"GB","num":647},{"id":"uk648","country":"GB","num":648},{"id":"uk649","country":"GB","num":649},{"id":"uk650","country":"GB","num":650},{"id":"uk651","country":"GB","num":651},{"id":"uk652","country":"GB","num":652},{"id":"uk653","country":"GB","num":653},{"id":"uk654","country":"GB","num":654},{"id":"uk655","country":"GB","num":655},{"id":"uk656","country":"GB","num":656},{"id":"uk673","country":"GB","num":673},{"id":"uk674","country":"GB","num":674},{"id":"uk675","country":"GB","num":675},{"id":"uk676","country":"GB","num":676},{"id":"uk677","country":"GB","num":677},{"id":"uk678","country":"GB","num":678},{"id":"uk679","country":"GB","num":679},{"id":"uk680","country":"GB","num":680},{"id":"uk681","country":"GB","num":681},{"id":"uk682","country":"GB","num":682},{"id":"uk683","country":"GB","num":683},{"id":"uk684","country":"GB","num":684},{"id":"uk685","country":"GB","num":685},{"id":"uk686","country":"GB","num":686},{"id":"uk687","country":"GB","num":687},{"id":"uk688","country":"GB","num":688},{"id":"uk689","country":"GB","num":689},{"id":"uk690","country":"GB","num":690},{"id":"uk697","country":"GB","num":697},{"id":"uk698","country":"GB","num":698},{"id":"uk699","country":"GB","num":699},{"id":"uk700","country":"GB","num":700},{"id":"uk701","country":"GB","num":701},{"id":"uk702","country":"GB","num":702},{"id":"uk703","country":"GB","num":703},{"id":"uk704","country":"GB","num":704},{"id":"uk705","country":"GB","num":705},{"id":"uk706","country":"GB","num":706},{"id":"uk707","country":"GB","num":707},{"id":"uk708","country":"GB","num":708},{"id":"uk713","country":"GB","num":713},{"id":"uk714","country":"GB","num":714},{"id":"uk715","country":"GB","num":715},{"id":"uk716","country":"GB","num":716},{"id":"uk717","country":"GB","num":717},{"id":"uk718","country":"GB","num":718},{"id":"uk719","country":"GB","num":719},{"id":"uk720","country":"GB","num":720},{"id":"uk725","country":"GB","num":725},{"id":"uk726","country":"GB","num":726},{"id":"uk727","country":"GB","num":727},{"id":"uk728","country":"GB","num":728},{"id":"uk729","country":"GB","num":729},{"id":"uk730","country":"GB","num":730},{"id":"uk731","country":"GB","num":731},{"id":"uk732","country":"GB","num":732},{"id":"uk733","country":"GB","num":733},{"id":"uk734","country":"GB","num":734},{"id":"uk735","country":"GB","num":735},{"id":"uk736","country":"GB","num":736},{"id":"uk737","country":"GB","num":737},{"id":"uk738","country":"GB","num":738},{"id":"uk739","country":"GB","num":739},{"id":"uk73","country":"GB","num":73},{"id":"uk740","country":"GB","num":740},{"id":"uk741","country":"GB","num":741},{"id":"uk742","country":"GB","num":742},{"id":"uk743","country":"GB","num":743},{"id":"uk744","country":"GB","num":744},{"id":"uk745","country":"GB","num":745},{"id":"uk746","country":"GB","num":746},{"id":"uk747","country":"GB","num":747},{"id":"uk748","country":"GB","num":748},{"id":"uk749","country":"GB","num":749},{"id":"uk74","country":"GB","num":74},{"id":"uk750","country":"GB","num":750},{"id":"uk751","country":"GB","num":751},{"id":"uk752","country":"GB","num":752},{"id":"uk753","country":"GB","num":753},{"id":"uk754","country":"GB","num":754},{"id":"uk755","country":"GB","num":755},{"id":"uk756","country":"GB","num":756},{"id":"uk757","country":"GB","num":757},{"id":"uk758","country":"GB","num":758},{"id":"uk759","country":"GB","num":759},{"id":"uk75","country":"GB","num":75},{"id":"uk760","country":"GB","num":760},{"id":"uk761","country":"GB","num":761},{"id":"uk762","country":"GB","num":762},{"id":"uk763","country":"GB","num":763},{"id":"uk764","country":"GB","num":764},{"id":"uk765","country":"GB","num":765},{"id":"uk766","country":"GB","num":766},{"id":"uk768","country":"GB","num":768},{"id":"uk769","country":"GB","num":769},{"id":"uk76","country":"GB","num":76},{"id":"uk770","country":"GB","num":770},{"id":"uk771","country":"GB","num":771},{"id":"uk772","country":"GB","num":772},{"id":"uk773","country":"GB","num":773},{"id":"uk774","country":"GB","num":774},{"id":"uk775","country":"GB","num":775},{"id":"uk776","country":"GB","num":776},{"id":"uk777","country":"GB","num":777},{"id":"uk778","country":"GB","num":778},{"id":"uk779","country":"GB","num":779},{"id":"uk77","country":"GB","num":77},{"id":"uk780","country":"GB","num":780},{"id":"uk781","country":"GB","num":781},{"id":"uk782","country":"GB","num":782},{"id":"uk783","country":"GB","num":783},{"id":"uk784","country":"GB","num":784},{"id":"uk785","country":"GB","num":785},{"id":"uk786","country":"GB","num":786},{"id":"uk787","country":"GB","num":787},{"id":"uk788","country":"GB","num":788},{"id":"uk789","country":"GB","num":789},{"id":"uk78","country":"GB","num":78},{"id":"uk790","country":"GB","num":790},{"id":"uk791","country":"GB","num":791},{"id":"uk792","country":"GB","num":792},{"id":"uk793","country":"GB","num":793},{"id":"uk794","country":"GB","num":794},{"id":"uk795","country":"GB","num":795},{"id":"uk796","country":"GB","num":796},{"id":"uk797","country":"GB","num":797},{"id":"uk798","country":"GB","num":798},{"id":"uk799","country":"GB","num":799},{"id":"uk79","country":"GB","num":79},{"id":"uk800","country":"GB","num":800},{"id":"uk801","country":"GB","num":801},{"id":"uk802","country":"GB","num":802},{"id":"uk803","country":"GB","num":803},{"id":"uk804","country":"GB","num":804},{"id":"uk805","country":"GB","num":805},{"id":"uk806","country":"GB","num":806},{"id":"uk807","country":"GB","num":807},{"id":"uk808","country":"GB","num":808},{"id":"uk809","country":"GB","num":809},{"id":"uk80","country":"GB","num":80},{"id":"uk810","country":"GB","num":810},{"id":"uk811","country":"GB","num":811},{"id":"uk812","country":"GB","num":812},{"id":"uk813","country":"GB","num":813},{"id":"uk814","country":"GB","num":814},{"id":"uk815","country":"GB","num":815},{"id":"uk816","country":"GB","num":816},{"id":"uk817","country":"GB","num":817},{"id":"uk818","country":"GB","num":818},{"id":"uk819","country":"GB","num":819},{"id":"uk81","country":"GB","num":81},{"id":"uk820","country":"GB","num":820},{"id":"uk821","country":"GB","num":821},{"id":"uk822","country":"GB","num":822},{"id":"uk823","country":"GB","num":823},{"id":"uk824","country":"GB","num":824},{"id":"uk825","country":"GB","num":825},{"id":"uk826","country":"GB","num":826},{"id":"uk827","country":"GB","num":827},{"id":"uk828","country":"GB","num":828},{"id":"uk829","country":"GB","num":829},{"id":"uk82","country":"GB","num":82},{"id":"uk830","country":"GB","num":830},{"id":"uk831","country":"GB","num":831},{"id":"uk832","country":"GB","num":832},{"id":"uk833","country":"GB","num":833},{"id":"uk834","country":"GB","num":834},{"id":"uk835","country":"GB","num":835},{"id":"uk836","country":"GB","num":836},{"id":"uk837","country":"GB","num":837},{"id":"uk838","country":"GB","num":838},{"id":"uk839","country":"GB","num":839},{"id":"uk83","country":"GB","num":83},{"id":"uk840","country":"GB","num":840},{"id":"uk841","country":"GB","num":841},{"id":"uk842","country":"GB","num":842},{"id":"uk843","country":"GB","num":843},{"id":"uk844","country":"GB","num":844},{"id":"uk845","country":"GB","num":845},{"id":"uk846","country":"GB","num":846},{"id":"uk847","country":"GB","num":847},{"id":"uk848","country":"GB","num":848},{"id":"uk849","country":"GB","num":849},{"id":"uk84","country":"GB","num":84},{"id":"uk850","country":"GB","num":850},{"id":"uk851","country":"GB","num":851},{"id":"uk852","country":"GB","num":852},{"id":"uk853","country":"GB","num":853},{"id":"uk854","country":"GB","num":854},{"id":"uk855","country":"GB","num":855},{"id":"uk856","country":"GB","num":856},{"id":"uk857","country":"GB","num":857},{"id":"uk858","country":"GB","num":858},{"id":"uk859","country":"GB","num":859},{"id":"uk860","country":"GB","num":860},{"id":"uk861","country":"GB","num":861},{"id":"uk862","country":"GB","num":862},{"id":"uk863","country":"GB","num":863},{"id":"uk870","country":"GB","num":870},{"id":"uk871","country":"GB","num":871},{"id":"uk872","country":"GB","num":872},{"id":"uk873","country":"GB","num":873},{"id":"uk874","country":"GB","num":874},{"id":"uk875","country":"GB","num":875},{"id":"uk876","country":"GB","num":876},{"id":"uk877","country":"GB","num":877},{"id":"uk878","country":"GB","num":878},{"id":"uk879","country":"GB","num":879},{"id":"uk880","country":"GB","num":880},{"id":"uk881","country":"GB","num":881},{"id":"uk882","country":"GB","num":882},{"id":"uk883","country":"GB","num":883},{"id":"uk884","country":"GB","num":884},{"id":"uk885","country":"GB","num":885},{"id":"uk886","country":"GB","num":886},{"id":"uk887","country":"GB","num":887},{"id":"uk888","country":"GB","num":888},{"id":"uk900","country":"GB","num":900},{"id":"uk901","country":"GB","num":901},{"id":"uk902","country":"GB","num":902},{"id":"uk903","country":"GB","num":903},{"id":"uk904","country":"GB","num":904},{"id":"uk905","country":"GB","num":905},{"id":"uk906","country":"GB","num":906},{"id":"uk907","country":"GB","num":907},{"id":"uk908","country":"GB","num":908},{"id":"uk909","country":"GB","num":909},{"id":"uk912","country":"GB","num":912},{"id":"uk913","country":"GB","num":913},{"id":"uk914","country":"GB","num":914},{"id":"uk915","country":"GB","num":915},{"id":"uk916","country":"GB","num":916},{"id":"uk917","country":"GB","num":917},{"id":"uk920","country":"GB","num":920},{"id":"uk921","country":"GB","num":921},{"id":"uk922","country":"GB","num":922},{"id":"uk923","country":"GB","num":923},{"id":"uk924","country":"GB","num":924},{"id":"uk925","country":"GB","num":925},{"id":"uk926","country":"GB","num":926},{"id":"uk927","country":"GB","num":927},{"id":"uk928","country":"GB","num":928},{"id":"uk929","country":"GB","num":929},{"id":"uk930","country":"GB","num":930},{"id":"uk931","country":"GB","num":931},{"id":"uk932","country":"GB","num":932},{"id":"uk933","country":"GB","num":933},{"id":"uk934","country":"GB","num":934},{"id":"uk935","country":"GB","num":935},{"id":"uk936","country":"GB","num":936},{"id":"uk937","country":"GB","num":937},{"id":"uk938","country":"GB","num":938},{"id":"uk939","country":"GB","num":939},{"id":"uk940","country":"GB","num":940},{"id":"uk941","country":"GB","num":941},{"id":"uk942","country":"GB","num":942},{"id":"uk943","country":"GB","num":943},{"id":"uk944","country":"GB","num":944},{"id":"uk945","country":"GB","num":945},{"id":"uk946","country":"GB","num":946},{"id":"uk947","country":"GB","num":947},{"id":"uk948","country":"GB","num":948},{"id":"uk949","country":"GB","num":949},{"id":"uk950","country":"GB","num":950},{"id":"uk951","country":"GB","num":951},{"id":"uk954","country":"GB","num":954},{"id":"uk955","country":"GB","num":955},{"id":"uk956","country":"GB","num":956},{"id":"uk957","country":"GB","num":957},{"id":"uk958","country":"GB","num":958},{"id":"uk959","country":"GB","num":959},{"id":"uk960","country":"GB","num":960},{"id":"uk961","country":"GB","num":961},{"id":"uk962","country":"GB","num":962},{"id":"uk963","country":"GB","num":963},{"id":"uk964","country":"GB","num":964},{"id":"uk965","country":"GB","num":965},{"id":"uk966","country":"GB","num":966},{"id":"uk967","country":"GB","num":967},{"id":"uk968","country":"GB","num":968},{"id":"uk969","country":"GB","num":969},{"id":"uk970","country":"GB","num":970},{"id":"uk971","country":"GB","num":971},{"id":"uk972","country":"GB","num":972},{"id":"uk973","country":"GB","num":973},{"id":"uk974","country":"GB","num":974},{"id":"uk975","country":"GB","num":975},{"id":"uk976","country":"GB","num":976},{"id":"uk977","country":"GB","num":977},{"id":"uk978","country":"GB","num":978},{"id":"uk979","country":"GB","num":979},{"id":"uk980","country":"GB","num":980},{"id":"uk981","country":"GB","num":981},{"id":"uk982","country":"GB","num":982},{"id":"uk983","country":"GB","num":983},{"id":"uk984","country":"GB","num":984},{"id":"uk985","country":"GB","num":985},{"id":"uk986","country":"GB","num":986},{"id":"uk987","country":"GB","num":987},{"id":"uk988","country":"GB","num":988},{"id":"uk989","country":"GB","num":989},{"id":"uk990","country":"GB","num":990},{"id":"uk991","country":"GB","num":991},{"id":"uk992","country":"GB","num":992},{"id":"uk993","country":"GB","num":993},{"id":"uk994","country":"GB","num":994},{"id":"uk995","country":"GB","num":995},{"id":"uk996","country":"GB","num":996},{"id":"uk997","country":"GB","num":997},{"id":"uk998","country":"GB","num":998},{"id":"uk999","country":"GB","num":999}]},{"country":"US","pools":[{"id":"us1472","country":"US","num":1472},{"id":"us1473","country":"US","num":1473},{"id":"us1474","country":"US","num":1474},{"id":"us1475","country":"US","num":1475},{"id":"us1524","country":"US","num":1524},{"id":"us1525","country":"US","num":1525},{"id":"us1526","country":"US","num":1526},{"id":"us1527","country":"US","num":1527},{"id":"us1528","country":"US","num":1528},{"id":"us1529","country":"US","num":1529},{"id":"us1530","country":"US","num":1530},{"id":"us1531","country":"US","num":1531},{"id":"us1532","country":"US","num":1532},{"id":"us1533","country":"US","num":1533},{"id":"us1534","country":"US","num":1534},{"id":"us1535","country":"US","num":1535},{"id":"us1536","country":"US","num":1536},{"id":"us1537","country":"US","num":1537},{"id":"us1538","country":"US","num":1538},{"id":"us1539","country":"US","num":1539},{"id":"us1564","country":"US","num":1564},{"id":"us1565","country":"US","num":1565},{"id":"us1566","country":"US","num":1566},{"id":"us1567","country":"US","num":1567},{"id":"us1568","country":"US","num":1568},{"id":"us1569","country":"US","num":1569},{"id":"us1570","country":"US","num":1570},{"id":"us1571","country":"US","num":1571},{"id":"us1576","country":"US","num":1576},{"id":"us1577","country":"US","num":1577},{"id":"us1578","country":"US","num":1578},{"id":"us1579","country":"US","num":1579},{"id":"us1700","country":"US","num":1700},{"id":"us1701","country":"US","num":1701},{"id":"us1702","country":"US","num":1702},{"id":"us1703","country":"US","num":1703},{"id":"us1729","country":"US","num":1729},{"id":"us1730","country":"US","num":1730},{"id":"us1731","country":"US","num":1731},{"id":"us1732","country":"US","num":1732},{"id":"us1746","country":"US","num":1746},{"id":"us1747","country":"US","num":1747},{"id":"us1748","country":"US","num":1748},{"id":"us1749","country":"US","num":1749},{"id":"us1750","country":"US","num":1750},{"id":"us1751","country":"US","num":1751},{"id":"us1752","country":"US","num":1752},{"id":"us1753","country":"US","num":1753},{"id":"us1754","country":"US","num":1754},{"id":"us1755","country":"US","num":1755},{"id":"us1756","country":"US","num":1756},{"id":"us1757","country":"US","num":1757},{"id":"us1758","country":"US","num":1758},{"id":"us1759","country":"US","num":1759},{"id":"us1760","country":"US","num":1760},{"id":"us1761","country":"US","num":1761},{"id":"us1762","country":"US","num":1762},{"id":"us1763","country":"US","num":1763},{"id":"us1764","country":"US","num":1764},{"id":"us1765","country":"US","num":1765},{"id":"us1766","country":"US","num":1766},{"id":"us1767","country":"US","num":1767},{"id":"us1768","country":"US","num":1768},{"id":"us1769","country":"US","num":1769},{"id":"us1770","country":"US","num":1770},{"id":"us1771","country":"US","num":1771},{"id":"us1772","country":"US","num":1772},{"id":"us1773","country":"US","num":1773},{"id":"us1774","country":"US","num":1774},{"id":"us1775","country":"US","num":1775},{"id":"us1776","country":"US","num":1776},{"id":"us1777","country":"US","num":1777},{"id":"us1778","country":"US","num":1778},{"id":"us1779","country":"US","num":1779},{"id":"us1780","country":"US","num":1780},{"id":"us1781","country":"US","num":1781},{"id":"us1782","country":"US","num":1782},{"id":"us1783","country":"US","num":1783},{"id":"us1784","country":"US","num":1784},{"id":"us1785","country":"US","num":1785},{"id":"us1786","country":"US","num":1786},{"id":"us1787","country":"US","num":1787},{"id":"us1788","country":"US","num":1788},{"id":"us1789","country":"US","num":1789},{"id":"us1790","country":"US","num":1790},{"id":"us1791","country":"US","num":1791},{"id":"us1792","country":"US","num":1792},{"id":"us1793","country":"US","num":1793},{"id":"us1794","country":"US","num":1794},{"id":"us1795","country":"US","num":1795},{"id":"us1796","country":"US","num":1796},{"id":"us1797","country":"US","num":1797},{"id":"us1798","country":"US","num":1798},{"id":"us1799","country":"US","num":1799},{"id":"us1800","country":"US","num":1800},{"id":"us1801","country":"US","num":1801},{"id":"us1806","country":"US","num":1806},{"id":"us1807","country":"US","num":1807},{"id":"us1808","country":"US","num":1808},{"id":"us1809","country":"US","num":1809},{"id":"us1810","country":"US","num":1810},{"id":"us1811","country":"US","num":1811},{"id":"us1812","country":"US","num":1812},{"id":"us1813","country":"US","num":1813},{"id":"us1814","country":"US","num":1814},{"id":"us1815","country":"US","num":1815},{"id":"us1816","country":"US","num":1816},{"id":"us1817","country":"US","num":1817},{"id":"us1818","country":"US","num":1818},{"id":"us1819","country":"US","num":1819},{"id":"us1820","country":"US","num":1820},{"id":"us1821","country":"US","num":1821},{"id":"us1822","country":"US","num":1822},{"id":"us1823","country":"US","num":1823},{"id":"us1824","country":"US","num":1824},{"id":"us1825","country":"US","num":1825},{"id":"us1826","country":"US","num":1826},{"id":"us1827","country":"US","num":1827},{"id":"us1828","country":"US","num":1828},{"id":"us1829","country":"US","num":1829},{"id":"us1830","country":"US","num":1830},{"id":"us1831","country":"US","num":1831},{"id":"us1832","country":"US","num":1832},{"id":"us1833","country":"US","num":1833},{"id":"us1834","country":"US","num":1834},{"id":"us1835","country":"US","num":1835},{"id":"us1836","country":"US","num":1836},{"id":"us1837","country":"US","num":1837},{"id":"us1838","country":"US","num":1838},{"id":"us1839","country":"US","num":1839},{"id":"us1840","country":"US","num":1840},{"id":"us1841","country":"US","num":1841},{"id":"us1842","country":"US","num":1842},{"id":"us1843","country":"US","num":1843},{"id":"us1844","country":"US","num":1844},{"id":"us1845","country":"US","num":1845},{"id":"us1846","country":"US","num":1846},{"id":"us1847","country":"US","num":1847},{"id":"us1848","country":"US","num":1848},{"id":"us1849","country":"US","num":1849},{"id":"us1850","country":"US","num":1850},{"id":"us1851","country":"US","num":1851},{"id":"us1852","country":"US","num":1852},{"id":"us1853","country":"US","num":1853},{"id":"us1854","country":"US","num":1854},{"id":"us1855","country":"US","num":1855},{"id":"us1856","country":"US","num":1856},{"id":"us1857","country":"US","num":1857},{"id":"us1858","country":"US","num":1858},{"id":"us1859","country":"US","num":1859},{"id":"us1860","country":"US","num":1860},{"id":"us1861","country":"US","num":1861},{"id":"us1862","country":"US","num":1862},{"id":"us1863","country":"US","num":1863},{"id":"us1864","country":"US","num":1864},{"id":"us1865","country":"US","num":1865},{"id":"us1866","country":"US","num":1866},{"id":"us1867","country":"US","num":1867},{"id":"us1868","country":"US","num":1868},{"id":"us1869","country":"US","num":1869},{"id":"us1870","country":"US","num":1870},{"id":"us1871","country":"US","num":1871},{"id":"us1872","country":"US","num":1872},{"id":"us1873","country":"US","num":1873},{"id":"us1874","country":"US","num":1874},{"id":"us1875","country":"US","num":1875},{"id":"us1876","country":"US","num":1876},{"id":"us1877","country":"US","num":1877},{"id":"us1878","country":"US","num":1878},{"id":"us1879","country":"US","num":1879},{"id":"us1880","country":"US","num":1880},{"id":"us1881","country":"US","num":1881},{"id":"us1882","country":"US","num":1882},{"id":"us1883","country":"US","num":1883},{"id":"us1884","country":"US","num":1884},{"id":"us1885","country":"US","num":1885},{"id":"us1886","country":"US","num":1886},{"id":"us1887","country":"US","num":1887},{"id":"us1888","country":"US","num":1888},{"id":"us1889","country":"US","num":1889},{"id":"us1890","country":"US","num":1890},{"id":"us1891","country":"US","num":1891},{"id":"us1892","country":"US","num":1892},{"id":"us1893","country":"US","num":1893},{"id":"us1894","country":"US","num":1894},{"id":"us1895","country":"US","num":1895},{"id":"us1896","country":"US","num":1896},{"id":"us1897","country":"US","num":1897},{"id":"us1898","country":"US","num":1898},{"id":"us1899","country":"US","num":1899},{"id":"us1900","country":"US","num":1900},{"id":"us1901","country":"US","num":1901},{"id":"us1902","country":"US","num":1902},{"id":"us1903","country":"US","num":1903},{"id":"us1904","country":"US","num":1904},{"id":"us1905","country":"US","num":1905},{"id":"us1906","country":"US","num":1906},{"id":"us1907","country":"US","num":1907},{"id":"us1908","country":"US","num":1908},{"id":"us1909","country":"US","num":1909},{"id":"us1910","country":"US","num":1910},{"id":"us1911","country":"US","num":1911},{"id":"us1912","country":"US","num":1912},{"id":"us1913","country":"US","num":1913},{"id":"us1914","country":"US","num":1914},{"id":"us1915","country":"US","num":1915},{"id":"us1916","country":"US","num":1916},{"id":"us1917","country":"US","num":1917},{"id":"us1918","country":"US","num":1918},{"id":"us1919","country":"US","num":1919},{"id":"us1920","country":"US","num":1920},{"id":"us1921","country":"US","num":1921},{"id":"us1922","country":"US","num":1922},{"id":"us1923","country":"US","num":1923},{"id":"us1924","country":"US","num":1924},{"id":"us1925","country":"US","num":1925},{"id":"us1926","country":"US","num":1926},{"id":"us1927","country":"US","num":1927},{"id":"us1928","country":"US","num":1928},{"id":"us1929","country":"US","num":1929},{"id":"us1930","country":"US","num":1930},{"id":"us1931","country":"US","num":1931},{"id":"us1932","country":"US","num":1932},{"id":"us1933","country":"US","num":1933},{"id":"us1934","country":"US","num":1934},{"id":"us1935","country":"US","num":1935},{"id":"us1936","country":"US","num":1936},{"id":"us1937","country":"US","num":1937},{"id":"us1938","country":"US","num":1938},{"id":"us1939","country":"US","num":1939},{"id":"us1940","country":"US","num":1940},{"id":"us1941","country":"US","num":1941},{"id":"us1942","country":"US","num":1942},{"id":"us1943","country":"US","num":1943},{"id":"us1944","country":"US","num":1944},{"id":"us1945","country":"US","num":1945},{"id":"us1946","country":"US","num":1946},{"id":"us1947","country":"US","num":1947},{"id":"us1948","country":"US","num":1948},{"id":"us1949","country":"US","num":1949},{"id":"us1950","country":"US","num":1950},{"id":"us1951","country":"US","num":1951},{"id":"us1952","country":"US","num":1952},{"id":"us1953","country":"US","num":1953},{"id":"us1954","country":"US","num":1954},{"id":"us1955","country":"US","num":1955},{"id":"us1956","country":"US","num":1956},{"id":"us1957","country":"US","num":1957},{"id":"us1958","country":"US","num":1958},{"id":"us1959","country":"US","num":1959},{"id":"us1960","country":"US","num":1960},{"id":"us1961","country":"US","num":1961},{"id":"us1962","country":"US","num":1962},{"id":"us1963","country":"US","num":1963},{"id":"us1964","country":"US","num":1964},{"id":"us1965","country":"US","num":1965},{"id":"us1966","country":"US","num":1966},{"id":"us1967","country":"US","num":1967},{"id":"us1968","country":"US","num":1968},{"id":"us1969","country":"US","num":1969},{"id":"us1970","country":"US","num":1970},{"id":"us1971","country":"US","num":1971},{"id":"us1972","country":"US","num":1972},{"id":"us1973","country":"US","num":1973},{"id":"us1974","country":"US","num":1974},{"id":"us1975","country":"US","num":1975},{"id":"us1976","country":"US","num":1976},{"id":"us1977","country":"US","num":1977},{"id":"us1978","country":"US","num":1978},{"id":"us1979","country":"US","num":1979},{"id":"us1980","country":"US","num":1980},{"id":"us1981","country":"US","num":1981},{"id":"us1982","country":"US","num":1982},{"id":"us1983","country":"US","num":1983},{"id":"us1984","country":"US","num":1984},{"id":"us1985","country":"US","num":1985},{"id":"us1986","country":"US","num":1986},{"id":"us1987","country":"US","num":1987},{"id":"us1988","country":"US","num":1988},{"id":"us1989","country":"US","num":1989},{"id":"us1990","country":"US","num":1990},{"id":"us1991","country":"US","num":1991},{"id":"us1992","country":"US","num":1992},{"id":"us1993","country":"US","num":1993},{"id":"us1994","country":"US","num":1994},{"id":"us1995","country":"US","num":1995},{"id":"us1996","country":"US","num":1996},{"id":"us1997","country":"US","num":1997},{"id":"us1998","country":"US","num":1998},{"id":"us1999","country":"US","num":1999},{"id":"us2000","country":"US","num":2000},{"id":"us2001","country":"US","num":2001},{"id":"us2002","country":"US","num":2002},{"id":"us2003","country":"US","num":2003},{"id":"us2004","country":"US","num":2004},{"id":"us2005","country":"US","num":2005},{"id":"us2006","country":"US","num":2006},{"id":"us2007","country":"US","num":2007},{"id":"us2008","country":"US","num":2008},{"id":"us2009","country":"US","num":2009},{"id":"us2010","country":"US","num":2010},{"id":"us2011","country":"US","num":2011},{"id":"us2012","country":"US","num":2012},{"id":"us2013","country":"US","num":2013},{"id":"us2014","country":"US","num":2014},{"id":"us2015","country":"US","num":2015},{"id":"us2016","country":"US","num":2016},{"id":"us2017","country":"US","num":2017},{"id":"us2018","country":"US","num":2018},{"id":"us2019","country":"US","num":2019},{"id":"us2020","country":"US","num":2020},{"id":"us2021","country":"US","num":2021},{"id":"us2022","country":"US","num":2022},{"id":"us2023","country":"US","num":2023},{"id":"us2024","country":"US","num":2024},{"id":"us2025","country":"US","num":2025},{"id":"us2026","country":"US","num":2026},{"id":"us2027","country":"US","num":2027},{"id":"us2028","country":"US","num":2028},{"id":"us2029","country":"US","num":2029},{"id":"us2030","country":"US","num":2030},{"id":"us2031","country":"US","num":2031},{"id":"us2032","country":"US","num":2032},{"id":"us2033","country":"US","num":2033},{"id":"us2034","country":"US","num":2034},{"id":"us2035","country":"US","num":2035},{"id":"us2036","country":"US","num":2036},{"id":"us2037","country":"US","num":2037},{"id":"us2038","country":"US","num":2038},{"id":"us2039","country":"US","num":2039},{"id":"us2040","country":"US","num":2040},{"id":"us2041","country":"US","num":2041},{"id":"us2042","country":"US","num":2042},{"id":"us2043","country":"US","num":2043},{"id":"us2044","country":"US","num":2044},{"id":"us2045","country":"US","num":2045},{"id":"us2048","country":"US","num":2048},{"id":"us2049","country":"US","num":2049},{"id":"us2050","country":"US","num":2050},{"id":"us2051","country":"US","num":2051},{"id":"us2052","country":"US","num":2052},{"id":"us2053","country":"US","num":2053},{"id":"us2054","country":"US","num":2054},{"id":"us2055","country":"US","num":2055},{"id":"us2056","country":"US","num":2056},{"id":"us2057","country":"US","num":2057},{"id":"us2058","country":"US","num":2058},{"id":"us2059","country":"US","num":2059},{"id":"us2060","country":"US","num":2060},{"id":"us2061","country":"US","num":2061},{"id":"us2062","country":"US","num":2062},{"id":"us2063","country":"US","num":2063},{"id":"us2064","country":"US","num":2064},{"id":"us2065","country":"US","num":2065},{"id":"us2066","country":"US","num":2066},{"id":"us2067","country":"US","num":2067},{"id":"us2068","country":"US","num":2068},{"id":"us2069","country":"US","num":2069},{"id":"us2070","country":"US","num":2070},{"id":"us2071","country":"US","num":2071},{"id":"us2072","country":"US","num":2072},{"id":"us2073","country":"US","num":2073},{"id":"us2074","country":"US","num":2074},{"id":"us2075","country":"US","num":2075},{"id":"us2076","country":"US","num":2076},{"id":"us2077","country":"US","num":2077},{"id":"us2078","country":"US","num":2078},{"id":"us2079","country":"US","num":2079},{"id":"us2080","country":"US","num":2080},{"id":"us2081","country":"US","num":2081},{"id":"us2082","country":"US","num":2082},{"id":"us2083","country":"US","num":2083},{"id":"us2084","country":"US","num":2084},{"id":"us2085","country":"US","num":2085},{"id":"us2086","country":"US","num":2086},{"id":"us2087","country":"US","num":2087},{"id":"us2088","country":"US","num":2088},{"id":"us2089","country":"US","num":2089},{"id":"us2090","country":"US","num":2090},{"id":"us2091","country":"US","num":2091},{"id":"us2092","country":"US","num":2092},{"id":"us2093","country":"US","num":2093},{"id":"us2094","country":"US","num":2094},{"id":"us2095","country":"US","num":2095},{"id":"us2096","country":"US","num":2096},{"id":"us2097","country":"US","num":2097},{"id":"us2098","country":"US","num":2098},{"id":"us2099","country":"US","num":2099},{"id":"us2100","country":"US","num":2100},{"id":"us2101","country":"US","num":2101},{"id":"us2102","country":"US","num":2102},{"id":"us2103","country":"US","num":2103},{"id":"us2104","country":"US","num":2104},{"id":"us2105","country":"US","num":2105},{"id":"us2106","country":"US","num":2106},{"id":"us2107","country":"US","num":2107},{"id":"us2108","country":"US","num":2108},{"id":"us2109","country":"US","num":2109},{"id":"us2110","country":"US","num":2110},{"id":"us2111","country":"US","num":2111},{"id":"us2112","country":"US","num":2112},{"id":"us2113","country":"US","num":2113},{"id":"us2114","country":"US","num":2114},{"id":"us2115","country":"US","num":2115},{"id":"us2116","country":"US","num":2116},{"id":"us2117","country":"US","num":2117},{"id":"us2118","country":"US","num":2118},{"id":"us2119","country":"US","num":2119},{"id":"us2120","country":"US","num":2120},{"id":"us2121","country":"US","num":2121},{"id":"us2122","country":"US","num":2122},{"id":"us2123","country":"US","num":2123},{"id":"us2124","country":"US","num":2124},{"id":"us2125","country":"US","num":2125},{"id":"us2126","country":"US","num":2126},{"id":"us2127","country":"US","num":2127},{"id":"us2128","country":"US","num":2128},{"id":"us2129","country":"US","num":2129},{"id":"us2130","country":"US","num":2130},{"id":"us2131","country":"US","num":2131},{"id":"us2132","country":"US","num":2132},{"id":"us2133","country":"US","num":2133},{"id":"us2134","country":"US","num":2134},{"id":"us2135","country":"US","num":2135},{"id":"us2136","country":"US","num":2136},{"id":"us2137","country":"US","num":2137},{"id":"us2138","country":"US","num":2138},{"id":"us2139","country":"US","num":2139},{"id":"us2140","country":"US","num":2140},{"id":"us2141","country":"US","num":2141},{"id":"us2142","country":"US","num":2142},{"id":"us2143","country":"US","num":2143},{"id":"us2144","country":"US","num":2144},{"id":"us2145","country":"US","num":2145},{"id":"us2146","country":"US","num":2146},{"id":"us2147","country":"US","num":2147},{"id":"us2148","country":"US","num":2148},{"id":"us2149","country":"US","num":2149},{"id":"us2150","country":"US","num":2150},{"id":"us2151","country":"US","num":2151},{"id":"us2152","country":"US","num":2152},{"id":"us2153","country":"US","num":2153},{"id":"us2154","country":"US","num":2154},{"id":"us2155","country":"US","num":2155},{"id":"us2156","country":"US","num":2156},{"id":"us2157","country":"US","num":2157},{"id":"us2158","country":"US","num":2158},{"id":"us2159","country":"US","num":2159},{"id":"us2160","country":"US","num":2160},{"id":"us2161","country":"US","num":2161},{"id":"us2162","country":"US","num":2162},{"id":"us2163","country":"US","num":2163},{"id":"us2164","country":"US","num":2164},{"id":"us2165","country":"US","num":2165},{"id":"us2166","country":"US","num":2166},{"id":"us2167","country":"US","num":2167},{"id":"us2168","country":"US","num":2168},{"id":"us2169","country":"US","num":2169},{"id":"us2170","country":"US","num":2170},{"id":"us2171","country":"US","num":2171},{"id":"us2172","country":"US","num":2172},{"id":"us2173","country":"US","num":2173},{"id":"us2174","country":"US","num":2174},{"id":"us2175","country":"US","num":2175},{"id":"us2176","country":"US","num":2176},{"id":"us2177","country":"US","num":2177},{"id":"us2178","country":"US","num":2178},{"id":"us2179","country":"US","num":2179},{"id":"us2180","country":"US","num":2180},{"id":"us2181","country":"US","num":2181},{"id":"us2182","country":"US","num":2182},{"id":"us2183","country":"US","num":2183},{"id":"us2184","country":"US","num":2184},{"id":"us2185","country":"US","num":2185},{"id":"us2186","country":"US","num":2186},{"id":"us2187","country":"US","num":2187},{"id":"us2188","country":"US","num":2188},{"id":"us2189","country":"US","num":2189},{"id":"us2190","country":"US","num":2190},{"id":"us2191","country":"US","num":2191},{"id":"us2192","country":"US","num":2192},{"id":"us2193","country":"US","num":2193},{"id":"us2194","country":"US","num":2194},{"id":"us2195","country":"US","num":2195},{"id":"us2196","country":"US","num":2196},{"id":"us2197","country":"US","num":2197},{"id":"us2198","country":"US","num":2198},{"id":"us2199","country":"US","num":2199},{"id":"us2200","country":"US","num":2200},{"id":"us2201","country":"US","num":2201},{"id":"us2202","country":"US","num":2202},{"id":"us2203","country":"US","num":2203},{"id":"us2216","country":"US","num":2216},{"id":"us2217","country":"US","num":2217},{"id":"us2218","country":"US","num":2218},{"id":"us2219","country":"US","num":2219},{"id":"us2220","country":"US","num":2220},{"id":"us2221","country":"US","num":2221},{"id":"us2222","country":"US","num":2222},{"id":"us2223","country":"US","num":2223},{"id":"us2228","country":"US","num":2228},{"id":"us2229","country":"US","num":2229},{"id":"us2230","country":"US","num":2230},{"id":"us2231","country":"US","num":2231},{"id":"us2232","country":"US","num":2232},{"id":"us2233","country":"US","num":2233},{"id":"us2234","country":"US","num":2234},{"id":"us2235","country":"US","num":2235},{"id":"us2236","country":"US","num":2236},{"id":"us2237","country":"US","num":2237},{"id":"us2238","country":"US","num":2238},{"id":"us2239","country":"US","num":2239},{"id":"us2240","country":"US","num":2240},{"id":"us2241","country":"US","num":2241},{"id":"us2242","country":"US","num":2242},{"id":"us2243","country":"US","num":2243},{"id":"us2244","country":"US","num":2244},{"id":"us2245","country":"US","num":2245},{"id":"us2246","country":"US","num":2246},{"id":"us2247","country":"US","num":2247},{"id":"us2248","country":"US","num":2248},{"id":"us2249","country":"US","num":2249},{"id":"us2250","country":"US","num":2250},{"id":"us2251","country":"US","num":2251},{"id":"us2252","country":"US","num":2252},{"id":"us2253","country":"US","num":2253},{"id":"us2254","country":"US","num":2254},{"id":"us2255","country":"US","num":2255},{"id":"us2256","country":"US","num":2256},{"id":"us2257","country":"US","num":2257},{"id":"us2258","country":"US","num":2258},{"id":"us2259","country":"US","num":2259},{"id":"us2260","country":"US","num":2260},{"id":"us2261","country":"US","num":2261},{"id":"us2262","country":"US","num":2262},{"id":"us2263","country":"US","num":2263},{"id":"us2264","country":"US","num":2264},{"id":"us2265","country":"US","num":2265},{"id":"us2266","country":"US","num":2266},{"id":"us2267","country":"US","num":2267},{"id":"us2268","country":"US","num":2268},{"id":"us2269","country":"US","num":2269},{"id":"us2270","country":"US","num":2270},{"id":"us2271","country":"US","num":2271},{"id":"us2272","country":"US","num":2272},{"id":"us2273","country":"US","num":2273},{"id":"us2274","country":"US","num":2274},{"id":"us2275","country":"US","num":2275},{"id":"us2276","country":"US","num":2276},{"id":"us2277","country":"US","num":2277},{"id":"us2278","country":"US","num":2278},{"id":"us2279","country":"US","num":2279},{"id":"us2280","country":"US","num":2280},{"id":"us2281","country":"US","num":2281},{"id":"us2282","country":"US","num":2282},{"id":"us2283","country":"US","num":2283},{"id":"us2284","country":"US","num":2284},{"id":"us2285","country":"US","num":2285},{"id":"us2286","country":"US","num":2286},{"id":"us2287","country":"US","num":2287},{"id":"us2288","country":"US","num":2288},{"id":"us2289","country":"US","num":2289},{"id":"us2290","country":"US","num":2290},{"id":"us2291","country":"US","num":2291},{"id":"us2292","country":"US","num":2292},{"id":"us2293","country":"US","num":2293},{"id":"us2294","country":"US","num":2294},{"id":"us2295","country":"US","num":2295},{"id":"us2296","country":"US","num":2296},{"id":"us2297","country":"US","num":2297},{"id":"us2298","country":"US","num":2298},{"id":"us2299","country":"US","num":2299},{"id":"us2300","country":"US","num":2300},{"id":"us2301","country":"US","num":2301},{"id":"us2302","country":"US","num":2302},{"id":"us2303","country":"US","num":2303},{"id":"us2304","country":"US","num":2304},{"id":"us2305","country":"US","num":2305},{"id":"us2306","country":"US","num":2306},{"id":"us2307","country":"US","num":2307},{"id":"us2308","country":"US","num":2308},{"id":"us2309","country":"US","num":2309},{"id":"us2310","country":"US","num":2310},{"id":"us2311","country":"US","num":2311},{"id":"us2312","country":"US","num":2312},{"id":"us2313","country":"US","num":2313},{"id":"us2314","country":"US","num":2314},{"id":"us2315","country":"US","num":2315},{"id":"us2316","country":"US","num":2316},{"id":"us2317","country":"US","num":2317},{"id":"us2318","country":"US","num":2318},{"id":"us2319","country":"US","num":2319},{"id":"us2320","country":"US","num":2320},{"id":"us2321","country":"US","num":2321},{"id":"us2322","country":"US","num":2322},{"id":"us2323","country":"US","num":2323},{"id":"us2324","country":"US","num":2324},{"id":"us2325","country":"US","num":2325},{"id":"us2326","country":"US","num":2326},{"id":"us2327","country":"US","num":2327},{"id":"us2328","country":"US","num":2328},{"id":"us2329","country":"US","num":2329},{"id":"us2330","country":"US","num":2330},{"id":"us2331","country":"US","num":2331},{"id":"us2332","country":"US","num":2332},{"id":"us2333","country":"US","num":2333},{"id":"us2334","country":"US","num":2334},{"id":"us2335","country":"US","num":2335},{"id":"us2336","country":"US","num":2336},{"id":"us2337","country":"US","num":2337},{"id":"us2338","country":"US","num":2338},{"id":"us2339","country":"US","num":2339},{"id":"us2340","country":"US","num":2340},{"id":"us2341","country":"US","num":2341},{"id":"us2342","country":"US","num":2342},{"id":"us2343","country":"US","num":2343},{"id":"us2344","country":"US","num":2344},{"id":"us2345","country":"US","num":2345},{"id":"us2346","country":"US","num":2346},{"id":"us2347","country":"US","num":2347},{"id":"us2348","country":"US","num":2348},{"id":"us2349","country":"US","num":2349},{"id":"us2350","country":"US","num":2350},{"id":"us2351","country":"US","num":2351},{"id":"us2352","country":"US","num":2352},{"id":"us2353","country":"US","num":2353},{"id":"us2354","country":"US","num":2354},{"id":"us2355","country":"US","num":2355},{"id":"us2356","country":"US","num":2356},{"id":"us2357","country":"US","num":2357},{"id":"us2358","country":"US","num":2358},{"id":"us2359","country":"US","num":2359},{"id":"us2360","country":"US","num":2360},{"id":"us2361","country":"US","num":2361},{"id":"us2362","country":"US","num":2362},{"id":"us2363","country":"US","num":2363},{"id":"us2364","country":"US","num":2364},{"id":"us2365","country":"US","num":2365},{"id":"us2366","country":"US","num":2366},{"id":"us2367","country":"US","num":2367},{"id":"us2368","country":"US","num":2368},{"id":"us2369","country":"US","num":2369},{"id":"us2370","country":"US","num":2370},{"id":"us2371","country":"US","num":2371},{"id":"us2452","country":"US","num":2452},{"id":"us2453","country":"US","num":2453},{"id":"us2454","country":"US","num":2454},{"id":"us2455","country":"US","num":2455},{"id":"us2456","country":"US","num":2456},{"id":"us2457","country":"US","num":2457},{"id":"us2458","country":"US","num":2458},{"id":"us2459","country":"US","num":2459},{"id":"us2460","country":"US","num":2460},{"id":"us2461","country":"US","num":2461},{"id":"us2462","country":"US","num":2462},{"id":"us2463","country":"US","num":2463},{"id":"us2464","country":"US","num":2464},{"id":"us2465","country":"US","num":2465},{"id":"us2466","country":"US","num":2466},{"id":"us2467","country":"US","num":2467},{"id":"us2468","country":"US","num":2468},{"id":"us2469","country":"US","num":2469},{"id":"us2470","country":"US","num":2470},{"id":"us2471","country":"US","num":2471},{"id":"us2472","country":"US","num":2472},{"id":"us2473","country":"US","num":2473},{"id":"us2474","country":"US","num":2474},{"id":"us2475","country":"US","num":2475},{"id":"us2476","country":"US","num":2476},{"id":"us2477","country":"US","num":2477},{"id":"us2478","country":"US","num":2478},{"id":"us2479","country":"US","num":2479},{"id":"us2481","country":"US","num":2481},{"id":"us2482","country":"US","num":2482},{"id":"us2483","country":"US","num":2483},{"id":"us2484","country":"US","num":2484},{"id":"us2485","country":"US","num":2485},{"id":"us2486","country":"US","num":2486},{"id":"us2487","country":"US","num":2487},{"id":"us2488","country":"US","num":2488},{"id":"us2489","country":"US","num":2489},{"id":"us2490","country":"US","num":2490},{"id":"us2491","country":"US","num":2491},{"id":"us2492","country":"US","num":2492},{"id":"us2493","country":"US","num":2493},{"id":"us2494","country":"US","num":2494},{"id":"us2495","country":"US","num":2495},{"id":"us2496","country":"US","num":2496},{"id":"us2497","country":"US","num":2497},{"id":"us2498","country":"US","num":2498},{"id":"us2499","country":"US","num":2499},{"id":"us2500","country":"US","num":2500},{"id":"us2505","country":"US","num":2505},{"id":"us2506","country":"US","num":2506},{"id":"us2507","country":"US","num":2507},{"id":"us2508","country":"US","num":2508},{"id":"us2509","country":"US","num":2509},{"id":"us2510","country":"US","num":2510},{"id":"us2511","country":"US","num":2511},{"id":"us2512","country":"US","num":2512},{"id":"us2513","country":"US","num":2513},{"id":"us2514","country":"US","num":2514},{"id":"us2515","country":"US","num":2515},{"id":"us2516","country":"US","num":2516},{"id":"us2517","country":"US","num":2517},{"id":"us2518","country":"US","num":2518},{"id":"us2519","country":"US","num":2519},{"id":"us2520","country":"US","num":2520},{"id":"us2521","country":"US","num":2521},{"id":"us2522","country":"US","num":2522},{"id":"us2523","country":"US","num":2523},{"id":"us2524","country":"US","num":2524},{"id":"us2525","country":"US","num":2525},{"id":"us2526","country":"US","num":2526},{"id":"us2527","country":"US","num":2527},{"id":"us2528","country":"US","num":2528},{"id":"us2529","country":"US","num":2529},{"id":"us2530","country":"US","num":2530},{"id":"us2531","country":"US","num":2531},{"id":"us2532","country":"US","num":2532},{"id":"us2533","country":"US","num":2533},{"id":"us2534","country":"US","num":2534},{"id":"us2535","country":"US","num":2535},{"id":"us2536","country":"US","num":2536},{"id":"us2537","country":"US","num":2537},{"id":"us2538","country":"US","num":2538},{"id":"us2539","country":"US","num":2539},{"id":"us2540","country":"US","num":2540},{"id":"us2541","country":"US","num":2541},{"id":"us2542","country":"US","num":2542},{"id":"us2543","country":"US","num":2543},{"id":"us2544","country":"US","num":2544},{"id":"us2545","country":"US","num":2545},{"id":"us2546","country":"US","num":2546},{"id":"us2547","country":"US","num":2547},{"id":"us2548","country":"US","num":2548},{"id":"us2549","country":"US","num":2549},{"id":"us2550","country":"US","num":2550},{"id":"us2551","country":"US","num":2551},{"id":"us2552","country":"US","num":2552},{"id":"us2553","country":"US","num":2553},{"id":"us2554","country":"US","num":2554},{"id":"us2555","country":"US","num":2555},{"id":"us2556","country":"US","num":2556},{"id":"us2561","country":"US","num":2561},{"id":"us2562","country":"US","num":2562},{"id":"us2563","country":"US","num":2563},{"id":"us2564","country":"US","num":2564},{"id":"us2565","country":"US","num":2565},{"id":"us2566","country":"US","num":2566},{"id":"us2567","country":"US","num":2567},{"id":"us2568","country":"US","num":2568},{"id":"us2569","country":"US","num":2569},{"id":"us2570","country":"US","num":2570},{"id":"us2571","country":"US","num":2571},{"id":"us2572","country":"US","num":2572},{"id":"us2573","country":"US","num":2573},{"id":"us2574","country":"US","num":2574},{"id":"us2575","country":"US","num":2575},{"id":"us2576","country":"US","num":2576},{"id":"us2577","country":"US","num":2577},{"id":"us2578","country":"US","num":2578},{"id":"us2579","country":"US","num":2579},{"id":"us2580","country":"US","num":2580},{"id":"us2581","country":"US","num":2581},{"id":"us2582","country":"US","num":2582},{"id":"us2583","country":"US","num":2583},{"id":"us2584","country":"US","num":2584},{"id":"us2585","country":"US","num":2585},{"id":"us2586","country":"US","num":2586},{"id":"us2587","country":"US","num":2587},{"id":"us2588","country":"US","num":2588},{"id":"us2589","country":"US","num":2589},{"id":"us2590","country":"US","num":2590},{"id":"us2591","country":"US","num":2591},{"id":"us2592","country":"US","num":2592},{"id":"us2593","country":"US","num":2593},{"id":"us2594","country":"US","num":2594},{"id":"us2595","country":"US","num":2595},{"id":"us2596","country":"US","num":2596},{"id":"us2597","country":"US","num":2597},{"id":"us2598","country":"US","num":2598},{"id":"us2599","country":"US","num":2599},{"id":"us2600","country":"US","num":2600},{"id":"us2601","country":"US","num":2601},{"id":"us2602","country":"US","num":2602},{"id":"us2603","country":"US","num":2603},{"id":"us2604","country":"US","num":2604},{"id":"us2605","country":"US","num":2605},{"id":"us2606","country":"US","num":2606},{"id":"us2607","country":"US","num":2607},{"id":"us2608","country":"US","num":2608},{"id":"us2609","country":"US","num":2609},{"id":"us2610","country":"US","num":2610},{"id":"us2611","country":"US","num":2611},{"id":"us2612","country":"US","num":2612},{"id":"us2613","country":"US","num":2613},{"id":"us2614","country":"US","num":2614},{"id":"us2615","country":"US","num":2615},{"id":"us2616","country":"US","num":2616},{"id":"us2617","country":"US","num":2617},{"id":"us2618","country":"US","num":2618},{"id":"us2619","country":"US","num":2619},{"id":"us2620","country":"US","num":2620},{"id":"us2621","country":"US","num":2621},{"id":"us2622","country":"US","num":2622},{"id":"us2623","country":"US","num":2623},{"id":"us2624","country":"US","num":2624},{"id":"us2625","country":"US","num":2625},{"id":"us2626","country":"US","num":2626},{"id":"us2627","country":"US","num":2627},{"id":"us2628","country":"US","num":2628},{"id":"us2629","country":"US","num":2629},{"id":"us2630","country":"US","num":2630},{"id":"us2631","country":"US","num":2631},{"id":"us2632","country":"US","num":2632},{"id":"us2633","country":"US","num":2633},{"id":"us2634","country":"US","num":2634},{"id":"us2635","country":"US","num":2635},{"id":"us2636","country":"US","num":2636},{"id":"us2637","country":"US","num":2637},{"id":"us2638","country":"US","num":2638},{"id":"us2639","country":"US","num":2639},{"id":"us2640","country":"US","num":2640},{"id":"us2662","country":"US","num":2662},{"id":"us2663","country":"US","num":2663},{"id":"us2664","country":"US","num":2664},{"id":"us2665","country":"US","num":2665},{"id":"us2674","country":"US","num":2674},{"id":"us2675","country":"US","num":2675},{"id":"us2676","country":"US","num":2676},{"id":"us2677","country":"US","num":2677},{"id":"us2686","country":"US","num":2686},{"id":"us2687","country":"US","num":2687},{"id":"us2688","country":"US","num":2688},{"id":"us2689","country":"US","num":2689},{"id":"us2690","country":"US","num":2690},{"id":"us2691","country":"US","num":2691},{"id":"us2692","country":"US","num":2692},{"id":"us2693","country":"US","num":2693},{"id":"us2694","country":"US","num":2694},{"id":"us2695","country":"US","num":2695},{"id":"us2696","country":"US","num":2696},{"id":"us2697","country":"US","num":2697},{"id":"us2698","country":"US","num":2698},{"id":"us2699","country":"US","num":2699},{"id":"us2700","country":"US","num":2700},{"id":"us2701","country":"US","num":2701},{"id":"us2702","country":"US","num":2702},{"id":"us2703","country":"US","num":2703},{"id":"us2704","country":"US","num":2704},{"id":"us2705","country":"US","num":2705},{"id":"us2706","country":"US","num":2706},{"id":"us2707","country":"US","num":2707},{"id":"us2708","country":"US","num":2708},{"id":"us2709","country":"US","num":2709},{"id":"us2714","country":"US","num":2714},{"id":"us2715","country":"US","num":2715},{"id":"us2716","country":"US","num":2716},{"id":"us2717","country":"US","num":2717},{"id":"us2722","country":"US","num":2722},{"id":"us2723","country":"US","num":2723},{"id":"us2726","country":"US","num":2726},{"id":"us2727","country":"US","num":2727},{"id":"us2728","country":"US","num":2728},{"id":"us2729","country":"US","num":2729},{"id":"us2730","country":"US","num":2730},{"id":"us2731","country":"US","num":2731},{"id":"us2732","country":"US","num":2732},{"id":"us2733","country":"US","num":2733},{"id":"us2734","country":"US","num":2734},{"id":"us2735","country":"US","num":2735},{"id":"us2736","country":"US","num":2736},{"id":"us2737","country":"US","num":2737},{"id":"us2738","country":"US","num":2738},{"id":"us2739","country":"US","num":2739},{"id":"us2740","country":"US","num":2740},{"id":"us2741","country":"US","num":2741},{"id":"us2742","country":"US","num":2742},{"id":"us2743","country":"US","num":2743},{"id":"us2744","country":"US","num":2744},{"id":"us2745","country":"US","num":2745},{"id":"us2746","country":"US","num":2746},{"id":"us2747","country":"US","num":2747},{"id":"us2748","country":"US","num":2748},{"id":"us2749","country":"US","num":2749},{"id":"us2750","country":"US","num":2750},{"id":"us2751","country":"US","num":2751},{"id":"us2752","country":"US","num":2752},{"id":"us2753","country":"US","num":2753},{"id":"us2754","country":"US","num":2754},{"id":"us2755","country":"US","num":2755},{"id":"us2756","country":"US","num":2756},{"id":"us2757","country":"US","num":2757},{"id":"us2758","country":"US","num":2758},{"id":"us2759","country":"US","num":2759},{"id":"us2760","country":"US","num":2760},{"id":"us2761","country":"US","num":2761},{"id":"us2762","country":"US","num":2762},{"id":"us2763","country":"US","num":2763},{"id":"us2764","country":"US","num":2764},{"id":"us2765","country":"US","num":2765},{"id":"us2766","country":"US","num":2766},{"id":"us2767","country":"US","num":2767},{"id":"us2768","country":"US","num":2768},{"id":"us2769","country":"US","num":2769},{"id":"us2770","country":"US","num":2770},{"id":"us2771","country":"US","num":2771},{"id":"us2772","country":"US","num":2772},{"id":"us2773","country":"US","num":2773},{"id":"us2774","country":"US","num":2774},{"id":"us2775","country":"US","num":2775},{"id":"us2776","country":"US","num":2776},{"id":"us2777","country":"US","num":2777},{"id":"us2778","country":"US","num":2778},{"id":"us2779","country":"US","num":2779},{"id":"us2780","country":"US","num":2780},{"id":"us2781","country":"US","num":2781},{"id":"us2782","country":"US","num":2782},{"id":"us2783","country":"US","num":2783},{"id":"us2784","country":"US","num":2784},{"id":"us2785","country":"US","num":2785},{"id":"us2786","country":"US","num":2786},{"id":"us2787","country":"US","num":2787},{"id":"us2788","country":"US","num":2788},{"id":"us2789","country":"US","num":2789},{"id":"us2790","country":"US","num":2790},{"id":"us2791","country":"US","num":2791},{"id":"us2792","country":"US","num":2792},{"id":"us2793","country":"US","num":2793},{"id":"us2794","country":"US","num":2794},{"id":"us2795","country":"US","num":2795},{"id":"us2796","country":"US","num":2796},{"id":"us2797","country":"US","num":2797},{"id":"us2798","country":"US","num":2798},{"id":"us2799","country":"US","num":2799},{"id":"us2800","country":"US","num":2800},{"id":"us2801","country":"US","num":2801},{"id":"us2802","country":"US","num":2802},{"id":"us2803","country":"US","num":2803},{"id":"us2804","country":"US","num":2804},{"id":"us2805","country":"US","num":2805},{"id":"us2806","country":"US","num":2806},{"id":"us2807","country":"US","num":2807},{"id":"us2808","country":"US","num":2808},{"id":"us2809","country":"US","num":2809},{"id":"us2810","country":"US","num":2810},{"id":"us2811","country":"US","num":2811},{"id":"us2812","country":"US","num":2812},{"id":"us2813","country":"US","num":2813},{"id":"us2814","country":"US","num":2814},{"id":"us2815","country":"US","num":2815},{"id":"us2816","country":"US","num":2816},{"id":"us2817","country":"US","num":2817},{"id":"us2818","country":"US","num":2818},{"id":"us2819","country":"US","num":2819},{"id":"us2820","country":"US","num":2820},{"id":"us2821","country":"US","num":2821},{"id":"us2822","country":"US","num":2822},{"id":"us2823","country":"US","num":2823},{"id":"us2824","country":"US","num":2824},{"id":"us2825","country":"US","num":2825},{"id":"us2826","country":"US","num":2826},{"id":"us2827","country":"US","num":2827},{"id":"us2828","country":"US","num":2828},{"id":"us2829","country":"US","num":2829},{"id":"us2830","country":"US","num":2830},{"id":"us2831","country":"US","num":2831},{"id":"us2832","country":"US","num":2832},{"id":"us2833","country":"US","num":2833},{"id":"us2836","country":"US","num":2836},{"id":"us2837","country":"US","num":2837},{"id":"us2838","country":"US","num":2838},{"id":"us2839","country":"US","num":2839},{"id":"us2840","country":"US","num":2840},{"id":"us2841","country":"US","num":2841},{"id":"us2842","country":"US","num":2842},{"id":"us2843","country":"US","num":2843},{"id":"us2844","country":"US","num":2844},{"id":"us2845","country":"US","num":2845},{"id":"us2846","country":"US","num":2846},{"id":"us2847","country":"US","num":2847},{"id":"us2852","country":"US","num":2852},{"id":"us2853","country":"US","num":2853},{"id":"us2862","country":"US","num":2862},{"id":"us2863","country":"US","num":2863},{"id":"us2864","country":"US","num":2864},{"id":"us2865","country":"US","num":2865},{"id":"us2866","country":"US","num":2866},{"id":"us2867","country":"US","num":2867},{"id":"us2868","country":"US","num":2868},{"id":"us2869","country":"US","num":2869},{"id":"us2870","country":"US","num":2870},{"id":"us2872","country":"US","num":2872},{"id":"us2873","country":"US","num":2873},{"id":"us2874","country":"US","num":2874},{"id":"us2875","country":"US","num":2875},{"id":"us2876","country":"US","num":2876},{"id":"us2877","country":"US","num":2877},{"id":"us2879","country":"US","num":2879},{"id":"us2880","country":"US","num":2880},{"id":"us2881","country":"US","num":2881},{"id":"us2883","country":"US","num":2883},{"id":"us2884","country":"US","num":2884},{"id":"us2885","country":"US","num":2885},{"id":"us2886","country":"US","num":2886},{"id":"us2887","country":"US","num":2887},{"id":"us2889","country":"US","num":2889},{"id":"us2890","country":"US","num":2890},{"id":"us2891","country":"US","num":2891},{"id":"us2892","country":"US","num":2892},{"id":"us2893","country":"US","num":2893},{"id":"us2894","country":"US","num":2894},{"id":"us2895","country":"US","num":2895},{"id":"us2896","country":"US","num":2896},{"id":"us2897","country":"US","num":2897},{"id":"us2898","country":"US","num":2898},{"id":"us2899","country":"US","num":2899},{"id":"us2900","country":"US","num":2900},{"id":"us2901","country":"US","num":2901},{"id":"us2902","country":"US","num":2902},{"id":"us2903","country":"US","num":2903},{"id":"us2904","country":"US","num":2904},{"id":"us2905","country":"US","num":2905},{"id":"us2906","country":"US","num":2906},{"id":"us2907","country":"US","num":2907},{"id":"us2908","country":"US","num":2908},{"id":"us2909","country":"US","num":2909},{"id":"us2910","country":"US","num":2910},{"id":"us2911","country":"US","num":2911},{"id":"us2912","country":"US","num":2912},{"id":"us2913","country":"US","num":2913},{"id":"us2914","country":"US","num":2914},{"id":"us2915","country":"US","num":2915},{"id":"us2916","country":"US","num":2916},{"id":"us2917","country":"US","num":2917},{"id":"us2918","country":"US","num":2918},{"id":"us2919","country":"US","num":2919},{"id":"us2920","country":"US","num":2920},{"id":"us2921","country":"US","num":2921},{"id":"us2922","country":"US","num":2922},{"id":"us2923","country":"US","num":2923},{"id":"us2924","country":"US","num":2924},{"id":"us2925","country":"US","num":2925},{"id":"us2926","country":"US","num":2926},{"id":"us2927","country":"US","num":2927},{"id":"us2929","country":"US","num":2929},{"id":"us2931","country":"US","num":2931},{"id":"us2933","country":"US","num":2933},{"id":"us2934","country":"US","num":2934},{"id":"us2952","country":"US","num":2952},{"id":"us2953","country":"US","num":2953},{"id":"us2954","country":"US","num":2954},{"id":"us2955","country":"US","num":2955},{"id":"us2956","country":"US","num":2956},{"id":"us2957","country":"US","num":2957},{"id":"us2958","country":"US","num":2958},{"id":"us2959","country":"US","num":2959},{"id":"us2960","country":"US","num":2960},{"id":"us2961","country":"US","num":2961},{"id":"us2962","country":"US","num":2962},{"id":"us2963","country":"US","num":2963},{"id":"us2964","country":"US","num":2964},{"id":"us2965","country":"US","num":2965},{"id":"us2966","country":"US","num":2966},{"id":"us2967","country":"US","num":2967},{"id":"us2968","country":"US","num":2968},{"id":"us2969","country":"US","num":2969},{"id":"us2970","country":"US","num":2970},{"id":"us2971","country":"US","num":2971},{"id":"us2972","country":"US","num":2972},{"id":"us2973","country":"US","num":2973},{"id":"us2974","country":"US","num":2974},{"id":"us2975","country":"US","num":2975},{"id":"us2976","country":"US","num":2976},{"id":"us2977","country":"US","num":2977},{"id":"us2978","country":"US","num":2978},{"id":"us2979","country":"US","num":2979},{"id":"us2980","country":"US","num":2980},{"id":"us2981","country":"US","num":2981},{"id":"us2982","country":"US","num":2982},{"id":"us2983","country":"US","num":2983},{"id":"us2984","country":"US","num":2984},{"id":"us2985","country":"US","num":2985},{"id":"us2986","country":"US","num":2986},{"id":"us2987","country":"US","num":2987},{"id":"us2988","country":"US","num":2988},{"id":"us2989","country":"US","num":2989},{"id":"us2990","country":"US","num":2990},{"id":"us2991","country":"US","num":2991},{"id":"us3012","country":"US","num":3012},{"id":"us3013","country":"US","num":3013},{"id":"us3014","country":"US","num":3014},{"id":"us3015","country":"US","num":3015},{"id":"us3016","country":"US","num":3016},{"id":"us3017","country":"US","num":3017},{"id":"us3018","country":"US","num":3018},{"id":"us3019","country":"US","num":3019},{"id":"us3020","country":"US","num":3020},{"id":"us3021","country":"US","num":3021},{"id":"us3022","country":"US","num":3022},{"id":"us3023","country":"US","num":3023},{"id":"us3024","country":"US","num":3024},{"id":"us3025","country":"US","num":3025},{"id":"us3026","country":"US","num":3026},{"id":"us3027","country":"US","num":3027},{"id":"us3028","country":"US","num":3028},{"id":"us3029","country":"US","num":3029},{"id":"us3030","country":"US","num":3030},{"id":"us3031","country":"US","num":3031},{"id":"us3032","country":"US","num":3032},{"id":"us3033","country":"US","num":3033},{"id":"us3034","country":"US","num":3034},{"id":"us3035","country":"US","num":3035},{"id":"us3036","country":"US","num":3036},{"id":"us3037","country":"US","num":3037},{"id":"us3038","country":"US","num":3038},{"id":"us3039","country":"US","num":3039},{"id":"us3040","country":"US","num":3040},{"id":"us3061","country":"US","num":3061},{"id":"us3062","country":"US","num":3062},{"id":"us3063","country":"US","num":3063},{"id":"us3064","country":"US","num":3064},{"id":"us3065","country":"US","num":3065},{"id":"us3066","country":"US","num":3066},{"id":"us3067","country":"US","num":3067},{"id":"us3068","country":"US","num":3068},{"id":"us3069","country":"US","num":3069},{"id":"us3070","country":"US","num":3070},{"id":"us3071","country":"US","num":3071},{"id":"us3072","country":"US","num":3072},{"id":"us3073","country":"US","num":3073},{"id":"us3074","country":"US","num":3074},{"id":"us3075","country":"US","num":3075},{"id":"us3076","country":"US","num":3076},{"id":"us3077","country":"US","num":3077},{"id":"us3078","country":"US","num":3078},{"id":"us3079","country":"US","num":3079},{"id":"us3080","country":"US","num":3080},{"id":"us3081","country":"US","num":3081},{"id":"us3082","country":"US","num":3082},{"id":"us3083","country":"US","num":3083},{"id":"us3084","country":"US","num":3084},{"id":"us3085","country":"US","num":3085},{"id":"us3086","country":"US","num":3086},{"id":"us3087","country":"US","num":3087},{"id":"us3088","country":"US","num":3088},{"id":"us3089","country":"US","num":3089},{"id":"us3090","country":"US","num":3090},{"id":"us3091","country":"US","num":3091},{"id":"us3092","country":"US","num":3092},{"id":"us3093","country":"US","num":3093},{"id":"us3094","country":"US","num":3094},{"id":"us3095","country":"US","num":3095},{"id":"us3096","country":"US","num":3096},{"id":"us3097","country":"US","num":3097},{"id":"us3098","country":"US","num":3098},{"id":"us3099","country":"US","num":3099},{"id":"us3100","country":"US","num":3100},{"id":"us3101","country":"US","num":3101},{"id":"us3102","country":"US","num":3102},{"id":"us3106","country":"US","num":3106},{"id":"us3107","country":"US","num":3107},{"id":"us3108","country":"US","num":3108},{"id":"us3109","country":"US","num":3109},{"id":"us3110","country":"US","num":3110},{"id":"us3111","country":"US","num":3111},{"id":"us3112","country":"US","num":3112},{"id":"us3113","country":"US","num":3113},{"id":"us3114","country":"US","num":3114},{"id":"us3115","country":"US","num":3115},{"id":"us3116","country":"US","num":3116},{"id":"us3117","country":"US","num":3117},{"id":"us3118","country":"US","num":3118},{"id":"us3119","country":"US","num":3119},{"id":"us3120","country":"US","num":3120},{"id":"us3121","country":"US","num":3121},{"id":"us3122","country":"US","num":3122},{"id":"us3124","country":"US","num":3124},{"id":"us3125","country":"US","num":3125},{"id":"us3126","country":"US","num":3126},{"id":"us3129","country":"US","num":3129},{"id":"us3130","country":"US","num":3130},{"id":"us3131","country":"US","num":3131},{"id":"us3132","country":"US","num":3132},{"id":"us3135","country":"US","num":3135},{"id":"us3136","country":"US","num":3136},{"id":"us3137","country":"US","num":3137},{"id":"us3138","country":"US","num":3138},{"id":"us3139","country":"US","num":3139},{"id":"us3140","country":"US","num":3140},{"id":"us3141","country":"US","num":3141},{"id":"us3142","country":"US","num":3142},{"id":"us3143","country":"US","num":3143},{"id":"us3144","country":"US","num":3144},{"id":"us3145","country":"US","num":3145},{"id":"us3146","country":"US","num":3146},{"id":"us3147","country":"US","num":3147},{"id":"us3148","country":"US","num":3148},{"id":"us3149","country":"US","num":3149},{"id":"us3150","country":"US","num":3150},{"id":"us3151","country":"US","num":3151},{"id":"us3152","country":"US","num":3152},{"id":"us3153","country":"US","num":3153},{"id":"us3154","country":"US","num":3154},{"id":"us3155","country":"US","num":3155},{"id":"us3156","country":"US","num":3156},{"id":"us3157","country":"US","num":3157},{"id":"us3158","country":"US","num":3158},{"id":"us3159","country":"US","num":3159},{"id":"us3160","country":"US","num":3160},{"id":"us3161","country":"US","num":3161},{"id":"us3162","country":"US","num":3162},{"id":"us3163","country":"US","num":3163},{"id":"us3164","country":"US","num":3164},{"id":"us3165","country":"US","num":3165},{"id":"us3166","country":"US","num":3166},{"id":"us3173","country":"US","num":3173},{"id":"us3174","country":"US","num":3174},{"id":"us3175","country":"US","num":3175},{"id":"us3176","country":"US","num":3176},{"id":"us3179","country":"US","num":3179},{"id":"us3180","country":"US","num":3180},{"id":"us3181","country":"US","num":3181},{"id":"us3182","country":"US","num":3182},{"id":"us3183","country":"US","num":3183},{"id":"us3184","country":"US","num":3184},{"id":"us3185","country":"US","num":3185},{"id":"us3186","country":"US","num":3186},{"id":"us3187","country":"US","num":3187},{"id":"us3188","country":"US","num":3188},{"id":"us3191","country":"US","num":3191},{"id":"us3192","country":"US","num":3192},{"id":"us3193","country":"US","num":3193},{"id":"us3194","country":"US","num":3194},{"id":"us3195","country":"US","num":3195},{"id":"us3196","country":"US","num":3196},{"id":"us3197","country":"US","num":3197},{"id":"us3198","country":"US","num":3198},{"id":"us3199","country":"US","num":3199},{"id":"us3200","country":"US","num":3200},{"id":"us3201","country":"US","num":3201},{"id":"us3202","country":"US","num":3202},{"id":"us3203","country":"US","num":3203},{"id":"us3204","country":"US","num":3204},{"id":"us3205","country":"US","num":3205},{"id":"us3206","country":"US","num":3206},{"id":"us3207","country":"US","num":3207},{"id":"us3208","country":"US","num":3208},{"id":"us3209","country":"US","num":3209},{"id":"us3210","country":"US","num":3210},{"id":"us3211","country":"US","num":3211},{"id":"us3212","country":"US","num":3212},{"id":"us3213","country":"US","num":3213},{"id":"us3214","country":"US","num":3214},{"id":"us3215","country":"US","num":3215},{"id":"us3216","country":"US","num":3216},{"id":"us3217","country":"US","num":3217},{"id":"us3218","country":"US","num":3218},{"id":"us3219","country":"US","num":3219},{"id":"us3220","country":"US","num":3220},{"id":"us3221","country":"US","num":3221},{"id":"us3222","country":"US","num":3222},{"id":"us3223","country":"US","num":3223},{"id":"us3224","country":"US","num":3224},{"id":"us3225","country":"US","num":3225},{"id":"us3226","country":"US","num":3226},{"id":"us3227","country":"US","num":3227},{"id":"us3228","country":"US","num":3228},{"id":"us3229","country":"US","num":3229},{"id":"us3230","country":"US","num":3230},{"id":"us3231","country":"US","num":3231},{"id":"us3232","country":"US","num":3232},{"id":"us3233","country":"US","num":3233},{"id":"us3234","country":"US","num":3234},{"id":"us3235","country":"US","num":3235},{"id":"us3236","country":"US","num":3236},{"id":"us3237","country":"US","num":3237},{"id":"us3238","country":"US","num":3238},{"id":"us3239","country":"US","num":3239},{"id":"us3240","country":"US","num":3240},{"id":"us3241","country":"US","num":3241},{"id":"us3242","country":"US","num":3242},{"id":"us3243","country":"US","num":3243},{"id":"us3244","country":"US","num":3244},{"id":"us3245","country":"US","num":3245},{"id":"us3246","country":"US","num":3246},{"id":"us3247","country":"US","num":3247},{"id":"us3248","country":"US","num":3248},{"id":"us3249","country":"US","num":3249},{"id":"us3250","country":"US","num":3250},{"id":"us3251","country":"US","num":3251},{"id":"us3252","country":"US","num":3252},{"id":"us3253","country":"US","num":3253},{"id":"us3254","country":"US","num":3254},{"id":"us3255","country":"US","num":3255},{"id":"us3256","country":"US","num":3256},{"id":"us3257","country":"US","num":3257},{"id":"us3258","country":"US","num":3258},{"id":"us3259","country":"US","num":3259},{"id":"us3260","country":"US","num":3260},{"id":"us3261","country":"US","num":3261},{"id":"us3262","country":"US","num":3262},{"id":"us3263","country":"US","num":3263},{"id":"us3264","country":"US","num":3264},{"id":"us3265","country":"US","num":3265},{"id":"us3266","country":"US","num":3266},{"id":"us3267","country":"US","num":3267},{"id":"us3268","country":"US","num":3268},{"id":"us3269","country":"US","num":3269},{"id":"us3270","country":"US","num":3270},{"id":"us3271","country":"US","num":3271},{"id":"us3272","country":"US","num":3272},{"id":"us3273","country":"US","num":3273},{"id":"us3274","country":"US","num":3274},{"id":"us3275","country":"US","num":3275},{"id":"us3276","country":"US","num":3276},{"id":"us3277","country":"US","num":3277},{"id":"us3278","country":"US","num":3278},{"id":"us3287","country":"US","num":3287},{"id":"us3288","country":"US","num":3288},{"id":"us3289","country":"US","num":3289},{"id":"us3290","country":"US","num":3290},{"id":"us3291","country":"US","num":3291},{"id":"us3292","country":"US","num":3292},{"id":"us3293","country":"US","num":3293},{"id":"us3294","country":"US","num":3294},{"id":"us3295","country":"US","num":3295},{"id":"us3296","country":"US","num":3296},{"id":"us3297","country":"US","num":3297},{"id":"us3298","country":"US","num":3298},{"id":"us3299","country":"US","num":3299},{"id":"us3300","country":"US","num":3300},{"id":"us3301","country":"US","num":3301},{"id":"us3302","country":"US","num":3302},{"id":"us3303","country":"US","num":3303},{"id":"us3304","country":"US","num":3304},{"id":"us3305","country":"US","num":3305},{"id":"us3306","country":"US","num":3306},{"id":"us3307","country":"US","num":3307},{"id":"us3308","country":"US","num":3308},{"id":"us3309","country":"US","num":3309},{"id":"us3310","country":"US","num":3310},{"id":"us3311","country":"US","num":3311},{"id":"us3312","country":"US","num":3312},{"id":"us3313","country":"US","num":3313},{"id":"us3314","country":"US","num":3314},{"id":"us3315","country":"US","num":3315},{"id":"us3316","country":"US","num":3316},{"id":"us3317","country":"US","num":3317},{"id":"us3318","country":"US","num":3318},{"id":"us3319","country":"US","num":3319},{"id":"us3320","country":"US","num":3320},{"id":"us3321","country":"US","num":3321},{"id":"us3322","country":"US","num":3322},{"id":"us3323","country":"US","num":3323},{"id":"us3324","country":"US","num":3324},{"id":"us3325","country":"US","num":3325},{"id":"us3326","country":"US","num":3326},{"id":"us3327","country":"US","num":3327},{"id":"us3328","country":"US","num":3328},{"id":"us3329","country":"US","num":3329},{"id":"us3330","country":"US","num":3330},{"id":"us3331","country":"US","num":3331},{"id":"us3332","country":"US","num":3332},{"id":"us3333","country":"US","num":3333},{"id":"us3334","country":"US","num":3334},{"id":"us3335","country":"US","num":3335},{"id":"us3336","country":"US","num":3336},{"id":"us3337","country":"US","num":3337},{"id":"us3338","country":"US","num":3338},{"id":"us3339","country":"US","num":3339},{"id":"us3340","country":"US","num":3340},{"id":"us3341","country":"US","num":3341},{"id":"us3342","country":"US","num":3342},{"id":"us3343","country":"US","num":3343},{"id":"us3344","country":"US","num":3344},{"id":"us3345","country":"US","num":3345},{"id":"us3346","country":"US","num":3346},{"id":"us3347","country":"US","num":3347},{"id":"us3348","country":"US","num":3348},{"id":"us3349","country":"US","num":3349},{"id":"us3350","country":"US","num":3350},{"id":"us3351","country":"US","num":3351},{"id":"us3352","country":"US","num":3352},{"id":"us3353","country":"US","num":3353},{"id":"us3354","country":"US","num":3354},{"id":"us3355","country":"US","num":3355},{"id":"us3356","country":"US","num":3356},{"id":"us3357","country":"US","num":3357},{"id":"us3358","country":"US","num":3358},{"id":"us3359","country":"US","num":3359},{"id":"us3360","country":"US","num":3360},{"id":"us3361","country":"US","num":3361},{"id":"us3362","country":"US","num":3362},{"id":"us3363","country":"US","num":3363},{"id":"us3364","country":"US","num":3364},{"id":"us3365","country":"US","num":3365},{"id":"us3366","country":"US","num":3366},{"id":"us3367","country":"US","num":3367},{"id":"us3368","country":"US","num":3368},{"id":"us3369","country":"US","num":3369},{"id":"us3370","country":"US","num":3370},{"id":"us3371","country":"US","num":3371},{"id":"us3372","country":"US","num":3372},{"id":"us3373","country":"US","num":3373},{"id":"us3374","country":"US","num":3374},{"id":"us3375","country":"US","num":3375},{"id":"us3376","country":"US","num":3376},{"id":"us3377","country":"US","num":3377},{"id":"us3378","country":"US","num":3378},{"id":"us3379","country":"US","num":3379},{"id":"us3380","country":"US","num":3380},{"id":"us3381","country":"US","num":3381},{"id":"us3382","country":"US","num":3382},{"id":"us3383","country":"US","num":3383},{"id":"us3384","country":"US","num":3384},{"id":"us3385","country":"US","num":3385},{"id":"us3386","country":"US","num":3386},{"id":"us3387","country":"US","num":3387},{"id":"us3388","country":"US","num":3388},{"id":"us3389","country":"US","num":3389},{"id":"us3390","country":"US","num":3390},{"id":"us3391","country":"US","num":3391},{"id":"us3392","country":"US","num":3392},{"id":"us3393","country":"US","num":3393},{"id":"us3394","country":"US","num":3394},{"id":"us3395","country":"US","num":3395},{"id":"us3396","country":"US","num":3396},{"id":"us3397","country":"US","num":3397},{"id":"us3398","country":"US","num":3398},{"id":"us3399","country":"US","num":3399},{"id":"us3400","country":"US","num":3400},{"id":"us3401","country":"US","num":3401},{"id":"us3402","country":"US","num":3402},{"id":"us3403","country":"US","num":3403},{"id":"us3404","country":"US","num":3404},{"id":"us3405","country":"US","num":3405},{"id":"us3406","country":"US","num":3406},{"id":"us3407","country":"US","num":3407},{"id":"us3408","country":"US","num":3408},{"id":"us3409","country":"US","num":3409},{"id":"us3410","country":"US","num":3410},{"id":"us3411","country":"US","num":3411},{"id":"us3412","country":"US","num":3412},{"id":"us3413","country":"US","num":3413},{"id":"us3414","country":"US","num":3414},{"id":"us3415","country":"US","num":3415},{"id":"us3416","country":"US","num":3416},{"id":"us3417","country":"US","num":3417},{"id":"us3418","country":"US","num":3418},{"id":"us3419","country":"US","num":3419},{"id":"us3420","country":"US","num":3420},{"id":"us3421","country":"US","num":3421},{"id":"us3422","country":"US","num":3422},{"id":"us3423","country":"US","num":3423},{"id":"us3424","country":"US","num":3424},{"id":"us3425","country":"US","num":3425},{"id":"us3426","country":"US","num":3426},{"id":"us3427","country":"US","num":3427},{"id":"us3428","country":"US","num":3428},{"id":"us3429","country":"US","num":3429},{"id":"us3430","country":"US","num":3430},{"id":"us3431","country":"US","num":3431},{"id":"us3432","country":"US","num":3432},{"id":"us3433","country":"US","num":3433},{"id":"us3434","country":"US","num":3434},{"id":"us3435","country":"US","num":3435},{"id":"us3436","country":"US","num":3436},{"id":"us3438","country":"US","num":3438},{"id":"us3439","country":"US","num":3439},{"id":"us3440","country":"US","num":3440},{"id":"us3441","country":"US","num":3441},{"id":"us3444","country":"US","num":3444},{"id":"us3445","country":"US","num":3445},{"id":"us3446","country":"US","num":3446},{"id":"us3447","country":"US","num":3447},{"id":"us3448","country":"US","num":3448},{"id":"us3449","country":"US","num":3449},{"id":"us3450","country":"US","num":3450},{"id":"us3451","country":"US","num":3451},{"id":"us3452","country":"US","num":3452},{"id":"us3453","country":"US","num":3453},{"id":"us3454","country":"US","num":3454},{"id":"us3455","country":"US","num":3455},{"id":"us3456","country":"US","num":3456},{"id":"us3457","country":"US","num":3457},{"id":"us3458","country":"US","num":3458},{"id":"us3459","country":"US","num":3459},{"id":"us3460","country":"US","num":3460},{"id":"us3461","country":"US","num":3461},{"id":"us3462","country":"US","num":3462},{"id":"us3463","country":"US","num":3463},{"id":"us3464","country":"US","num":3464},{"id":"us3465","country":"US","num":3465},{"id":"us3466","country":"US","num":3466},{"id":"us3467","country":"US","num":3467},{"id":"us3468","country":"US","num":3468},{"id":"us3469","country":"US","num":3469},{"id":"us3470","country":"US","num":3470},{"id":"us3471","country":"US","num":3471},{"id":"us3472","country":"US","num":3472},{"id":"us3473","country":"US","num":3473},{"id":"us3474","country":"US","num":3474},{"id":"us3475","country":"US","num":3475},{"id":"us3476","country":"US","num":3476},{"id":"us3477","country":"US","num":3477},{"id":"us3478","country":"US","num":3478},{"id":"us3479","country":"US","num":3479},{"id":"us3480","country":"US","num":3480},{"id":"us3481","country":"US","num":3481},{"id":"us3482","country":"US","num":3482},{"id":"us3483","country":"US","num":3483},{"id":"us3484","country":"US","num":3484},{"id":"us3485","country":"US","num":3485},{"id":"us3486","country":"US","num":3486},{"id":"us3487","country":"US","num":3487},{"id":"us3488","country":"US","num":3488},{"id":"us3489","country":"US","num":3489},{"id":"us3490","country":"US","num":3490},{"id":"us3491","country":"US","num":3491},{"id":"us3492","country":"US","num":3492},{"id":"us3493","country":"US","num":3493},{"id":"us3494","country":"US","num":3494},{"id":"us3495","country":"US","num":3495},{"id":"us3496","country":"US","num":3496},{"id":"us3497","country":"US","num":3497},{"id":"us3498","country":"US","num":3498},{"id":"us3499","country":"US","num":3499},{"id":"us349","country":"US","num":349},{"id":"us3500","country":"US","num":3500},{"id":"us3501","country":"US","num":3501},{"id":"us3502","country":"US","num":3502},{"id":"us3503","country":"US","num":3503},{"id":"us3504","country":"US","num":3504},{"id":"us3505","country":"US","num":3505},{"id":"us3506","country":"US","num":3506},{"id":"us3507","country":"US","num":3507},{"id":"us3508","country":"US","num":3508},{"id":"us3509","country":"US","num":3509},{"id":"us350","country":"US","num":350},{"id":"us3510","country":"US","num":3510},{"id":"us3511","country":"US","num":3511},{"id":"us3512","country":"US","num":3512},{"id":"us3513","country":"US","num":3513},{"id":"us3514","country":"US","num":3514},{"id":"us3515","country":"US","num":3515},{"id":"us3516","country":"US","num":3516},{"id":"us3517","country":"US","num":3517},{"id":"us3518","country":"US","num":3518},{"id":"us3519","country":"US","num":3519},{"id":"us351","country":"US","num":351},{"id":"us3520","country":"US","num":3520},{"id":"us3521","country":"US","num":3521},{"id":"us3522","country":"US","num":3522},{"id":"us3523","country":"US","num":3523},{"id":"us3524","country":"US","num":3524},{"id":"us3525","country":"US","num":3525},{"id":"us3526","country":"US","num":3526},{"id":"us3527","country":"US","num":3527},{"id":"us3528","country":"US","num":3528},{"id":"us3529","country":"US","num":3529},{"id":"us352","country":"US","num":352},{"id":"us3530","country":"US","num":3530},{"id":"us3531","country":"US","num":3531},{"id":"us3532","country":"US","num":3532},{"id":"us3533","country":"US","num":3533},{"id":"us3534","country":"US","num":3534},{"id":"us3535","country":"US","num":3535},{"id":"us3536","country":"US","num":3536},{"id":"us3537","country":"US","num":3537},{"id":"us3538","country":"US","num":3538},{"id":"us3539","country":"US","num":3539},{"id":"us353","country":"US","num":353},{"id":"us3540","country":"US","num":3540},{"id":"us3542","country":"US","num":3542},{"id":"us3543","country":"US","num":3543},{"id":"us3544","country":"US","num":3544},{"id":"us3545","country":"US","num":3545},{"id":"us3548","country":"US","num":3548},{"id":"us3549","country":"US","num":3549},{"id":"us354","country":"US","num":354},{"id":"us3550","country":"US","num":3550},{"id":"us3551","country":"US","num":3551},{"id":"us3552","country":"US","num":3552},{"id":"us3553","country":"US","num":3553},{"id":"us3554","country":"US","num":3554},{"id":"us3555","country":"US","num":3555},{"id":"us3556","country":"US","num":3556},{"id":"us3557","country":"US","num":3557},{"id":"us3558","country":"US","num":3558},{"id":"us3559","country":"US","num":3559},{"id":"us355","country":"US","num":355},{"id":"us3562","country":"US","num":3562},{"id":"us3563","country":"US","num":3563},{"id":"us3564","country":"US","num":3564},{"id":"us3565","country":"US","num":3565},{"id":"us3566","country":"US","num":3566},{"id":"us3567","country":"US","num":3567},{"id":"us3568","country":"US","num":3568},{"id":"us3569","country":"US","num":3569},{"id":"us356","country":"US","num":356},{"id":"us3570","country":"US","num":3570},{"id":"us3571","country":"US","num":3571},{"id":"us3572","country":"US","num":3572},{"id":"us3573","country":"US","num":3573},{"id":"us3574","country":"US","num":3574},{"id":"us3575","country":"US","num":3575},{"id":"us3576","country":"US","num":3576},{"id":"us3577","country":"US","num":3577},{"id":"us3578","country":"US","num":3578},{"id":"us3579","country":"US","num":3579},{"id":"us3580","country":"US","num":3580},{"id":"us3581","country":"US","num":3581},{"id":"us3582","country":"US","num":3582},{"id":"us3583","country":"US","num":3583},{"id":"us3584","country":"US","num":3584},{"id":"us3585","country":"US","num":3585},{"id":"us3586","country":"US","num":3586},{"id":"us3587","country":"US","num":3587},{"id":"us3588","country":"US","num":3588},{"id":"us3589","country":"US","num":3589},{"id":"us3590","country":"US","num":3590},{"id":"us3591","country":"US","num":3591},{"id":"us3592","country":"US","num":3592},{"id":"us3593","country":"US","num":3593},{"id":"us3594","country":"US","num":3594},{"id":"us3595","country":"US","num":3595},{"id":"us3596","country":"US","num":3596},{"id":"us3597","country":"US","num":3597},{"id":"us3598","country":"US","num":3598},{"id":"us3599","country":"US","num":3599},{"id":"us3600","country":"US","num":3600},{"id":"us3601","country":"US","num":3601},{"id":"us3602","country":"US","num":3602},{"id":"us3603","country":"US","num":3603},{"id":"us3604","country":"US","num":3604},{"id":"us3605","country":"US","num":3605},{"id":"us3606","country":"US","num":3606},{"id":"us3607","country":"US","num":3607},{"id":"us381","country":"US","num":381},{"id":"us382","country":"US","num":382},{"id":"us383","country":"US","num":383},{"id":"us384","country":"US","num":384},{"id":"us435","country":"US","num":435},{"id":"us436","country":"US","num":436},{"id":"us437","country":"US","num":437},{"id":"us438","country":"US","num":438},{"id":"us502","country":"US","num":502},{"id":"us503","country":"US","num":503},{"id":"us504","country":"US","num":504},{"id":"us505","country":"US","num":505},{"id":"us510","country":"US","num":510},{"id":"us511","country":"US","num":511},{"id":"us512","country":"US","num":512},{"id":"us513","country":"US","num":513},{"id":"us793","country":"US","num":793},{"id":"us794","country":"US","num":794},{"id":"us795","country":"US","num":795},{"id":"us796","country":"US","num":796},{"id":"us801","country":"US","num":801},{"id":"us802","country":"US","num":802},{"id":"us803","country":"US","num":803},{"id":"us804","country":"US","num":804},{"id":"us964","country":"US","num":964},{"id":"us965","country":"US","num":965},{"id":"us966","country":"US","num":966},{"id":"us967","country":"US","num":967}]},{"country":"VN","pools":[{"id":"vn3","country":"VN","num":3},{"id":"vn4","country":"VN","num":4},{"id":"vn5","country":"VN","num":5},{"id":"vn6","country":"VN","num":6}]},{"country":"ZA","pools":[{"id":"za12","country":"ZA","num":12},{"id":"za13","country":"ZA","num":13},{"id":"za14","country":"ZA","num":14},{"id":"za15","country":"ZA","num":15},{"id":"za16","country":"ZA","num":16},{"id":"za17","country":"ZA","num":17},{"id":"za18","country":"ZA","num":18},{"id":"za21","country":"ZA","num":21},{"id":"za22","country":"ZA","num":22},{"id":"za23","country":"ZA","num":23},{"id":"za24","country":"ZA","num":24},{"id":"za25","country":"ZA","num":25},{"id":"za26","country":"ZA","num":26},{"id":"za27","country":"ZA","num":27},{"id":"za28","country":"ZA","num":28},{"id":"za29","country":"ZA","num":29},{"id":"za30","country":"ZA","num":30},{"id":"za31","country":"ZA","num":31},{"id":"za32","country":"ZA","num":32}]}],"presets":["default"]},{"name":"double","groups":[{"country":"CA","pools":[{"id":"ca-us10","country":"CA","extra_countries":["US"],"num":10},{"id":"ca-us11","country":"CA","extra_countries":["US"],"num":11},{"id":"ca-us12","country":"CA","extra_countries":["US"],"num":12},{"id":"ca-us5","country":"CA","extra_countries":["US"],"num":5},{"id":"ca-us6","country":"CA","extra_countries":["US"],"num":6},{"id":"ca-us7","country":"CA","extra_countries":["US"],"num":7},{"id":"ca-us8","country":"CA","extra_countries":["US"],"num":8},{"id":"ca-us9","country":"CA","extra_countries":["US"],"num":9}]},{"country":"CH","pools":[{"id":"ch-nl2","country":"CH","extra_countries":["NL"],"num":2},{"id":"ch-se2","country":"CH","extra_countries":["SE"],"num":2}]},{"country":"FR","pools":[{"id":"fr-uk2","country":"FR","extra_countries":["GB"],"num":2},{"id":"fr-uk3","country":"FR","extra_countries":["GB"],"num":3}]},{"country":"NL","pools":[{"id":"nl-ch2","country":"NL","extra_countries":["CH"],"num":2},{"id":"nl-se2","country":"NL","extra_countries":["SE"],"num":2},{"id":"nl-uk2","country":"NL","extra_countries":["GB"],"num":2},{"id":"nl-uk3","country":"NL","extra_countries":["GB"],"num":3}]},{"country":"SE","pools":[{"id":"se-ch2","country":"SE","extra_countries":["CH"],"num":2},{"id":"se-nl2","country":"SE","extra_countries":["NL"],"num":2}]},{"country":"TW","pools":[{"id":"tw-hk3","country":"TW","extra_countries":["HK"],"num":3}]},{"country":"GB","pools":[{"id":"uk-fr2","country":"GB","extra_countries":["FR"],"num":2},{"id":"uk-fr3","country":"GB","extra_countries":["FR"],"num":3},{"id":"uk-nl2","country":"GB","extra_countries":["NL"],"num":2},{"id":"uk-nl3","country":"GB","extra_countries":["NL"],"num":3}]},{"country":"US","pools":[{"id":"us-ca10","country":"US","extra_countries":["CA"],"num":10},{"id":"us-ca11","country":"US","extra_countries":["CA"],"num":11},{"id":"us-ca4","country":"US","extra_countries":["CA"],"num":4},{"id":"us-ca5","country":"US","extra_countries":["CA"],"num":5},{"id":"us-ca7","country":"US","extra_countries":["CA"],"num":7},{"id":"us-ca8","country":"US","extra_countries":["CA"],"num":8},{"id":"us-ca9","country":"US","extra_countries":["CA"],"num":9}]}],"presets":["double"]}],"build":1779,"name":"NordVPN"}
\ No newline at end of file
diff --git a/Passepartout/Resources/Web/net/pia.json b/Passepartout/Resources/Web/net/pia.json
deleted file mode 100644
index eb072a15..00000000
--- a/Passepartout/Resources/Web/net/pia.json
+++ /dev/null
@@ -1 +0,0 @@
-{"presets":[{"id":"recommended","name":"Recommended","comment":"128-bit encryption","cfg":{"ep":["UDP:1194","UDP:8080","UDP:9201","UDP:53","UDP:1198","UDP:1197","TCP:443","TCP:110","TCP:80","TCP:502","TCP:501"],"frame":1,"ping":10,"reneg":3600,"pia":true,"eku":true,"ca":"-----BEGIN CERTIFICATE-----\nMIIFqzCCBJOgAwIBAgIJAKZ7D5Yv87qDMA0GCSqGSIb3DQEBDQUAMIHoMQswCQYD\nVQQGEwJVUzELMAkGA1UECBMCQ0ExEzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNV\nBAoTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIElu\ndGVybmV0IEFjY2VzczEgMB4GA1UEAxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3Mx\nIDAeBgNVBCkTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkB\nFiBzZWN1cmVAcHJpdmF0ZWludGVybmV0YWNjZXNzLmNvbTAeFw0xNDA0MTcxNzM1\nMThaFw0zNDA0MTIxNzM1MThaMIHoMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex\nEzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNVBAoTF1ByaXZhdGUgSW50ZXJuZXQg\nQWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UE\nAxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBCkTF1ByaXZhdGUgSW50\nZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkBFiBzZWN1cmVAcHJpdmF0ZWludGVy\nbmV0YWNjZXNzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPXD\nL1L9tX6DGf36liA7UBTy5I869z0UVo3lImfOs/GSiFKPtInlesP65577nd7UNzzX\nlH/P/CnFPdBWlLp5ze3HRBCc/Avgr5CdMRkEsySL5GHBZsx6w2cayQ2EcRhVTwWp\ncdldeNO+pPr9rIgPrtXqT4SWViTQRBeGM8CDxAyTopTsobjSiYZCF9Ta1gunl0G/\n8Vfp+SXfYCC+ZzWvP+L1pFhPRqzQQ8k+wMZIovObK1s+nlwPaLyayzw9a8sUnvWB\n/5rGPdIYnQWPgoNlLN9HpSmsAcw2z8DXI9pIxbr74cb3/HSfuYGOLkRqrOk6h4RC\nOfuWoTrZup1uEOn+fw8CAwEAAaOCAVQwggFQMB0GA1UdDgQWBBQv63nQ/pJAt5tL\ny8VJcbHe22ZOsjCCAR8GA1UdIwSCARYwggESgBQv63nQ/pJAt5tLy8VJcbHe22ZO\nsqGB7qSB6zCB6DELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRMwEQYDVQQHEwpM\nb3NBbmdlbGVzMSAwHgYDVQQKExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4G\nA1UECxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBAMTF1ByaXZhdGUg\nSW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQpExdQcml2YXRlIEludGVybmV0IEFjY2Vz\nczEvMC0GCSqGSIb3DQEJARYgc2VjdXJlQHByaXZhdGVpbnRlcm5ldGFjY2Vzcy5j\nb22CCQCmew+WL/O6gzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBDQUAA4IBAQAn\na5PgrtxfwTumD4+3/SYvwoD66cB8IcK//h1mCzAduU8KgUXocLx7QgJWo9lnZ8xU\nryXvWab2usg4fqk7FPi00bED4f4qVQFVfGfPZIH9QQ7/48bPM9RyfzImZWUCenK3\n7pdw4Bvgoys2rHLHbGen7f28knT2j/cbMxd78tQc20TIObGjo8+ISTRclSTRBtyC\nGohseKYpTS9himFERpUgNtefvYHbn70mIOzfOJFTVqfrptf9jXa9N8Mpy3ayfodz\n1wiqdteqFXkTYoSDctgKMiZ6GdocK9nMroQipIQtpnwd4yBDWIyC6Bvlkrq5TQUt\nYDQ8z9v+DMO6iwyIDRiU\n-----END CERTIFICATE-----\n","cipher":"AES-128-GCM"},"external":{"hostname":"${id}.privateinternetaccess.com"}},{"id":"strong","name":"Strong","comment":"256-bit encryption","cfg":{"ep":["UDP:1194","UDP:8080","UDP:9201","UDP:53","UDP:1198","UDP:1197","TCP:443","TCP:110","TCP:80","TCP:502","TCP:501"],"frame":1,"ping":10,"reneg":3600,"pia":true,"eku":true,"ca":"-----BEGIN CERTIFICATE-----\nMIIHqzCCBZOgAwIBAgIJAJ0u+vODZJntMA0GCSqGSIb3DQEBDQUAMIHoMQswCQYD\nVQQGEwJVUzELMAkGA1UECBMCQ0ExEzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNV\nBAoTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIElu\ndGVybmV0IEFjY2VzczEgMB4GA1UEAxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3Mx\nIDAeBgNVBCkTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkB\nFiBzZWN1cmVAcHJpdmF0ZWludGVybmV0YWNjZXNzLmNvbTAeFw0xNDA0MTcxNzQw\nMzNaFw0zNDA0MTIxNzQwMzNaMIHoMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0Ex\nEzARBgNVBAcTCkxvc0FuZ2VsZXMxIDAeBgNVBAoTF1ByaXZhdGUgSW50ZXJuZXQg\nQWNjZXNzMSAwHgYDVQQLExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UE\nAxMXUHJpdmF0ZSBJbnRlcm5ldCBBY2Nlc3MxIDAeBgNVBCkTF1ByaXZhdGUgSW50\nZXJuZXQgQWNjZXNzMS8wLQYJKoZIhvcNAQkBFiBzZWN1cmVAcHJpdmF0ZWludGVy\nbmV0YWNjZXNzLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALVk\nhjumaqBbL8aSgj6xbX1QPTfTd1qHsAZd2B97m8Vw31c/2yQgZNf5qZY0+jOIHULN\nDe4R9TIvyBEbvnAg/OkPw8n/+ScgYOeH876VUXzjLDBnDb8DLr/+w9oVsuDeFJ9K\nV2UFM1OYX0SnkHnrYAN2QLF98ESK4NCSU01h5zkcgmQ+qKSfA9Ny0/UpsKPBFqsQ\n25NvjDWFhCpeqCHKUJ4Be27CDbSl7lAkBuHMPHJs8f8xPgAbHRXZOxVCpayZ2SND\nfCwsnGWpWFoMGvdMbygngCn6jA/W1VSFOlRlfLuuGe7QFfDwA0jaLCxuWt/BgZyl\np7tAzYKR8lnWmtUCPm4+BtjyVDYtDCiGBD9Z4P13RFWvJHw5aapx/5W/CuvVyI7p\nKwvc2IT+KPxCUhH1XI8ca5RN3C9NoPJJf6qpg4g0rJH3aaWkoMRrYvQ+5PXXYUzj\ntRHImghRGd/ydERYoAZXuGSbPkm9Y/p2X8unLcW+F0xpJD98+ZI+tzSsI99Zs5wi\njSUGYr9/j18KHFTMQ8n+1jauc5bCCegN27dPeKXNSZ5riXFL2XX6BkY68y58UaNz\nmeGMiUL9BOV1iV+PMb7B7PYs7oFLjAhh0EdyvfHkrh/ZV9BEhtFa7yXp8XR0J6vz\n1YV9R6DYJmLjOEbhU8N0gc3tZm4Qz39lIIG6w3FDAgMBAAGjggFUMIIBUDAdBgNV\nHQ4EFgQUrsRtyWJftjpdRM0+925Y6Cl08SUwggEfBgNVHSMEggEWMIIBEoAUrsRt\nyWJftjpdRM0+925Y6Cl08SWhge6kgeswgegxCzAJBgNVBAYTAlVTMQswCQYDVQQI\nEwJDQTETMBEGA1UEBxMKTG9zQW5nZWxlczEgMB4GA1UEChMXUHJpdmF0ZSBJbnRl\ncm5ldCBBY2Nlc3MxIDAeBgNVBAsTF1ByaXZhdGUgSW50ZXJuZXQgQWNjZXNzMSAw\nHgYDVQQDExdQcml2YXRlIEludGVybmV0IEFjY2VzczEgMB4GA1UEKRMXUHJpdmF0\nZSBJbnRlcm5ldCBBY2Nlc3MxLzAtBgkqhkiG9w0BCQEWIHNlY3VyZUBwcml2YXRl\naW50ZXJuZXRhY2Nlc3MuY29tggkAnS7684Nkme0wDAYDVR0TBAUwAwEB/zANBgkq\nhkiG9w0BAQ0FAAOCAgEAJsfhsPk3r8kLXLxY+v+vHzbr4ufNtqnL9/1Uuf8NrsCt\npXAoyZ0YqfbkWx3NHTZ7OE9ZRhdMP/RqHQE1p4N4Sa1nZKhTKasV6KhHDqSCt/dv\nEm89xWm2MVA7nyzQxVlHa9AkcBaemcXEiyT19XdpiXOP4Vhs+J1R5m8zQOxZlV1G\ntF9vsXmJqWZpOVPmZ8f35BCsYPvv4yMewnrtAC8PFEK/bOPeYcKN50bol22QYaZu\nLfpkHfNiFTnfMh8sl/ablPyNY7DUNiP5DRcMdIwmfGQxR5WEQoHL3yPJ42LkB5zs\n6jIm26DGNXfwura/mi105+ENH1CaROtRYwkiHb08U6qLXXJz80mWJkT90nr8Asj3\n5xN2cUppg74nG3YVav/38P48T56hG1NHbYF5uOCske19F6wi9maUoto/3vEr0rnX\nJUp2KODmKdvBI7co245lHBABWikk8VfejQSlCtDBXn644ZMtAdoxKNfR2WTFVEwJ\niyd1Fzx0yujuiXDROLhISLQDRjVVAvawrAtLZWYK31bY7KlezPlQnl/D9Asxe85l\n8jO5+0LdJ6VyOs/Hd4w52alDW/MFySDZSfQHMTIc30hLBJ8OnCEIvluVQQ2UQvoW\n+no177N9L2Y+M9TcTA62ZyMXShHQGeh20rb4kK8f+iFX8NxtdHVSkxMEFSfDDyQ=\n-----END CERTIFICATE-----\n","cipher":"AES-256-GCM"},"external":{"hostname":"${id}.privateinternetaccess.com"}}],"defaults":{"username":"p1234567","pool":"us-east","preset":"recommended"},"categories":[{"name":"","groups":[{"country":"US","area":"california","pools":[{"id":"us-california","country":"US","addrs":[3119863752,3119863716,1540337620,1540337466,1540337517,3119863715,1540337508,1540337605,1540337465,1540337591,1540337443,1540337589,1540337574],"area":"california"}]},{"country":"US","area":"east","pools":[{"id":"us-east","country":"US","addrs":[3240492428,3258710813,3258710823,3240492404,3258710917,3258710862,3240492387,3258710925,3258710927,3240492405,3258711004,3240492358,3258710852],"area":"east"}]},{"country":"US","area":"chicago","pools":[{"id":"us-chicago","country":"US","addrs":[3346297735,3346297749,1757976928,1757976932,1757976924,1757976925,3346297738,3346297742,1757976909,1757976923,3346297737,1757976930,3346297733],"area":"chicago"}]},{"country":"US","area":"texas","pools":[{"id":"us-texas","country":"US","addrs":[2732076655,2732076619,2732076584,2732076601,2732076611,2732076560,2732076660,2732076547,2732076698,2732076644,2732076570,2732076590,2732076588],"area":"texas"}]},{"country":"US","area":"florida","pools":[{"id":"us-florida","country":"US","addrs":[3240492101,3240492158,3240492131,3240492081,3240492087,3240492099,3240492142,3240492074,3240492110,3240492137,3240492084,3240492108,3240492150],"area":"florida"}]},{"country":"US","area":"seattle","pools":[{"id":"us-seattle","country":"US","addrs":[1757977152,1757977096,1757977188,1757977160,1757977169,1757977151,1757977176,1757977104,1757977145,1757977098,1757977147,1757977105,1757977144],"area":"seattle"}]},{"country":"US","area":"west","pools":[{"id":"us-west","country":"US","addrs":[1757976374,1757976398,1757976367,1757976346,1757976361,1757976392,1757976393,1757976402,1757976356,1757976323,1757976364,1757976381,1757976360],"area":"west"}]},{"country":"US","area":"siliconvalley","pools":[{"id":"us-siliconvalley","country":"US","addrs":[3346298522,3346298598,3346298610,3346298536,3346298574,3346298546,3346298617,3346298600,3346298570,3346298551,3346298566,3346298508,3346298519],"area":"siliconvalley"}]},{"country":"US","area":"newyorkcity","pools":[{"id":"us-newyorkcity","country":"US","addrs":[3512677022,1807148879,3512676998,1807148825,2918506362,1807148826,3512676923,3512676931,3512676919,3512676890,1807148830,3512676920,3512676889],"area":"newyorkcity"}]},{"country":"US","area":"washingtondc","pools":[{"id":"us-washingtondc","country":"US","addrs":[1176502408,1176502337,1176502347,1176502407,1176502405,1176502350,1176502374,1176502379,1176502319,1176502397,1176502382,1176502346,1176502336],"area":"washingtondc"}]},{"country":"US","area":"atlanta","pools":[{"id":"us-atlanta","country":"US","addrs":[1114876372,1114876358,1114876402,1114876360,1114875921,1114875919,1114875917,1114876395,1114876365,1114875915,1114875926,1114876386,1114875929],"area":"atlanta"}]},{"country":"US","area":"lasvegas","pools":[{"id":"us-lasvegas","country":"US","addrs":[3347003478,2734418953,3347003512,3347003477,3347003482,3347003514,3347003480,3347003475,3347003479,3347003474,2734418946,2734418952,3347003507],"area":"lasvegas"}]},{"country":"US","area":"houston","pools":[{"id":"us-houston","country":"US","addrs":[3455817434,3455817410,3455817402,3455816786,3455816834,3455816890,3455816778,3455816866,3455816770,3455816842,3455816762,3455817442,3455817386],"area":"houston"}]},{"country":"US","area":"denver","pools":[{"id":"us-denver","country":"US","addrs":[2927681914,2927686522,3346227866,2927686386,2927681978,2927686722,2927684706,2927686514,2927682058,2927682066,2927681890,2927687010,2927686826],"area":"denver"}]},{"country":"GB","area":"london","pools":[{"id":"uk-london","country":"GB","addrs":[1508809464,1508809458,1508809470,1508809238,1508809451,1508809381,1508808199,1508808217,1508809466,1508808202,1508809460,1508809467,1508809469],"area":"london"}]},{"country":"GB","area":"southampton","pools":[{"id":"uk-southampton","country":"GB","addrs":[521724657,521724557,521724649,521724652,521724618,521724668,521724620,521724556,521725892,521724647,521724604,521724605,521724651],"area":"southampton"}]},{"country":"GB","area":"manchester","pools":[{"id":"uk-manchester","country":"GB","addrs":[1508805430,1508804907,1508805386,1508805385,1508805431,1508805387,1508804903,1508804901,1508805432,1508805429,1508805383,1508804904,1508804905],"area":"manchester"}]},{"country":"CA","area":"toronto","pools":[{"id":"ca-toronto","country":"CA","addrs":[2892120911,2892120903,2892120873,2892120919,2892120923,2892120854,2892120858,2892120879,2892120845,2892120898,2892120876,2892120855,2892120846],"area":"toronto"}]},{"country":"CA","area":"montreal","pools":[{"id":"ca-montreal","country":"CA","addrs":[3353737624,3353737620,3353737646,3353737612,3353737666,3353737664,3353737609,3353737653,3353737627,3353737631,3353737663,3353737602,3353737608],"area":"montreal"}]},{"country":"CA","area":"vancouver","pools":[{"id":"ca-vancouver","country":"CA","addrs":[2891130978,1807072595,1807072586,2891130907,1807072598,2891130994,1807072596,2891130990,2891130903,2891130991,1807072585,2891130901,1807072588],"area":"vancouver"}]},{"country":"AU","area":"sydney","pools":[{"id":"au-sydney","country":"AU","addrs":[2302409901,2302409898,2302409918,2302409876,2302409903,2302409890,2302409868,2302409917,2302409907,2302409902,2302409952,2302409892,2302409893],"area":"sydney"}]},{"country":"AU","area":"melbourne","pools":[{"id":"au-melbourne","country":"AU","addrs":[2818666609,2818663404,2818663380,2818657077,2818657047,2818657076,2818666564,2818663377,2818663366,2818663367,2818657028,2818657031,2818666593],"area":"melbourne"}]},{"country":"AU","area":"perth","pools":[{"id":"au-perth","country":"AU","addrs":[1743214860,1743214858,1743214851,1743214861,1743214850,1743214859,1743214852],"area":"perth"}]},{"country":"DE","area":"berlin","pools":[{"id":"de-berlin","country":"DE","addrs":[3118890991,3118890995,3249559210,3118890989,3118890988,3249559206,3249559170,3249559164,3118890992,3118890987,3249559198,3249559162,3118890984],"area":"berlin"}]},{"country":"DE","area":"frankfurt","pools":[{"id":"de-frankfurt","country":"DE","addrs":[3118220973,3118220952,3118220950,3118220933,3118220934,3118220965,3118220972,3118220962,3118220945,3118220963,3118220937,3118220940,3118220938],"area":"frankfurt"}]},{"country":"NZ","pools":[{"id":"nz","country":"NZ","addrs":[1743215429,1743215276,1743215277,1743215428,1743215278,1743215434,1743215427,1743215394,1743215395,1743215398,1743215274,1743215426,1743215275]}]},{"country":"NL","pools":[{"id":"nl","country":"NL","addrs":[1841924848,782666391,782666229,782679279,782679282,782679735,782666217,782679746,782679245,3562827041,782679733,1841928417,782666397]}]},{"country":"SE","pools":[{"id":"sweden","country":"SE","addrs":[787905416,787905374,787905419,787905332,787905431,787905289,787905359,787905304,787905344,787905316,787905310,787905437,787905407]}]},{"country":"NO","pools":[{"id":"no","country":"NO","addrs":[1382423352,1382423353,1382423346,1382423349,1382423350,1382423421,1382423374,1382423370,1382423412,3120390628,1382423306,1382423373,1382423348]}]},{"country":"DK","pools":[{"id":"denmark","country":"DK","addrs":[1382421669,1382421678,1382421674,1382421672,1382421667,1382421681,1382421668,1382421682,1382421666,1382421684,1382421677,1382421671,1382421670]}]},{"country":"FI","pools":[{"id":"fi","country":"FI","addrs":[3223871234,3223871247,3223871245,3223871236,3223871244,3223871242,3223871235,3223871240,3223871238,3223871250,3223871241,3223871237,3223871246]}]},{"country":"CH","pools":[{"id":"swiss","country":"CH","addrs":[3117722290,1382422697,3114053468,1382422690,3117722295,3114053469,3118890322,1535412267,3118890281,3117722301,3118890274,3118890280,1382422695]}]},{"country":"FR","pools":[{"id":"france","country":"FR","addrs":[3267098931,3267098933,3267099070,3267098935,3267099060,3267098926,3267098934,3267098930,3267098940,3267099065,3267098919,3267099064,3267098936]}]},{"country":"BE","pools":[{"id":"belgium","country":"BE","addrs":[1307819795,1307819803,1307819794,1307819802,1307819796,1307819798,1307819799,3118994717,3118994715,3110648346,1307819797,3118994716]}]},{"country":"AT","pools":[{"id":"austria","country":"AT","addrs":[3117949678,3117949670,3117603739,3117949676,3117949669,3117949668,3117949667,3117603731,3117949677,3117603738,3117949673,3117949671,3117949666]}]},{"country":"CZ","pools":[{"id":"czech","country":"CZ","addrs":[1508817635,3119646238,3117949766,3117949765,3119646237,3117949762,1508817638,1508817634,3117949764,1508817636,1508817637,3119646234,3117949763]}]},{"country":"LU","pools":[{"id":"lu","country":"LU","addrs":[3564485634,1592976591,1592976593,1592976605,1592976592,1592976429,1592976479,3564485652]}]},{"country":"IE","pools":[{"id":"ireland","country":"IE","addrs":[391937826,391937810,391937850,391937802,391937858,391937794,391937842,391937834]}]},{"country":"IT","pools":[{"id":"italy","country":"IT","addrs":[1382421973,1382421972,1382421858,1382421970,1382421979,1382421976,1382421974,1382421975,1382421977,1382421978,1382421971]}]},{"country":"ES","pools":[{"id":"spain","country":"ES","addrs":[3285085178,3118890034,3261294621,3261294618,628659286,3118890036,3118890035,3261294619,3118890038,3118890037,3261294620]}]},{"country":"RO","pools":[{"id":"ro","country":"RO","addrs":[3117603429,1449728331,3117603430,1449728323,1449728322,1449728326,1449728333,3117603431,3117603427,3117603432,1449728330,3117603428,1567819590]}]},{"country":"HU","pools":[{"id":"hungary","country":"HU","addrs":[3112180242,3112180244,3112180243,3116200546,3112180248,3112180247,3112180246,3112180245]}]},{"country":"PL","pools":[{"id":"poland","country":"PL","addrs":[3119830724,3119830728,3119830726,3119830727,3119830725,3119830723,3119830722,3119830542]}]},{"country":"AE","pools":[{"id":"ae","country":"AE","addrs":[3478722150,3478722148,3478722180,3478722178,3478722147,3478722146,3478722149,3478722179]}]},{"country":"HK","pools":[{"id":"hk","country":"HK","addrs":[2001831731,2001831733,2001831708,2001831685,2001831709,2001862130]}]},{"country":"SG","pools":[{"id":"sg","country":"SG","addrs":[3636029326,2001814215,2001814261,3636029324,2001814210,2001814270]}]},{"country":"JP","pools":[{"id":"japan","country":"JP","addrs":[1741741199,1741741195,1741741193,1741741188,1741741192,1741741190,1741741198,1741741196,1741741191,1741741189,1741741197]}]},{"country":"IL","pools":[{"id":"israel","country":"IL","addrs":[531147921,531147922,531147912,531147919,531147918,531147923]}]},{"country":"MX","pools":[{"id":"mexico","country":"MX","addrs":[2839085261,2839085287,2839085289,2839085304,2839085277,2839085280,2839085281,2839085263,2839085286,2839085292,2839085291,2839085299,2839085294]}]},{"country":"BR","pools":[{"id":"brazil","country":"BR","addrs":[2979695559,2979695561,2979697001,2979695558,2979696997,2979695563,2979695556]}]},{"country":"IN","pools":[{"id":"in","country":"IN","addrs":[2323690562,2323690634,2323690594,2323690570,2323690578,2323690690,2323690618,2323690586]}]},{"country":"ZA","pools":[{"id":"za","country":"ZA","addrs":[2617144134,2617144130,2617144133,2617144139,2617144132,2617144131]}]}]}],"build":1779,"name":"PIA"}
diff --git a/Passepartout/Resources/Web/net/protonvpn.json b/Passepartout/Resources/Web/net/protonvpn.json
deleted file mode 100644
index a5e22763..00000000
--- a/Passepartout/Resources/Web/net/protonvpn.json
+++ /dev/null
@@ -1 +0,0 @@
-{"presets":[{"id":"default","name":"Default","comment":"256-bit encryption","cfg":{"ca":"-----BEGIN CERTIFICATE-----\nMIIFozCCA4ugAwIBAgIBATANBgkqhkiG9w0BAQ0FADBAMQswCQYDVQQGEwJDSDEV\nMBMGA1UEChMMUHJvdG9uVlBOIEFHMRowGAYDVQQDExFQcm90b25WUE4gUm9vdCBD\nQTAeFw0xNzAyMTUxNDM4MDBaFw0yNzAyMTUxNDM4MDBaMEAxCzAJBgNVBAYTAkNI\nMRUwEwYDVQQKEwxQcm90b25WUE4gQUcxGjAYBgNVBAMTEVByb3RvblZQTiBSb290\nIENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAt+BsSsZg7+AuqTq7\nvDbPzfygtl9f8fLJqO4amsyOXlI7pquL5IsEZhpWyJIIvYybqS4s1/T7BbvHPLVE\nwlrq8A5DBIXcfuXrBbKoYkmpICGc2u1KYVGOZ9A+PH9z4Tr6OXFfXRnsbZToie8t\n2Xjv/dZDdUDAqeW89I/mXg3k5x08m2nfGCQDm4gCanN1r5MT7ge56z0MkY3FFGCO\nqRwspIEUzu1ZqGSTkG1eQiOYIrdOF5cc7n2APyvBIcfvp/W3cpTOEmEBJ7/14RnX\nnHo0fcx61Inx/6ZxzKkW8BMdGGQF3tF6u2M0FjVN0lLH9S0ul1TgoOS56yEJ34hr\nJSRTqHuar3t/xdCbKFZjyXFZFNsXVvgJu34CNLrHHTGJj9jiUfFnxWQYMo9UNUd4\na3PPG1HnbG7LAjlvj5JlJ5aqO5gshdnqb9uIQeR2CdzcCJgklwRGCyDT1pm7eoiv\nWV19YBd81vKulLzgPavu3kRRe83yl29It2hwQ9FMs5w6ZV/X6ciTKo3etkX9nBD9\nZzJPsGQsBUy7CzO1jK4W01+u3ItmQS+1s4xtcFxdFY8o/q1zoqBlxpe5MQIWN6Qa\nlryiET74gMHE/S5WrPlsq/gehxsdgc6GDUXG4dk8vn6OUMa6wb5wRO3VXGEc67IY\nm4mDFTYiPvLaFOxtndlUWuCruKcCAwEAAaOBpzCBpDAMBgNVHRMEBTADAQH/MB0G\nA1UdDgQWBBSDkIaYhLVZTwyLNTetNB2qV0gkVDBoBgNVHSMEYTBfgBSDkIaYhLVZ\nTwyLNTetNB2qV0gkVKFEpEIwQDELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFByb3Rv\nblZQTiBBRzEaMBgGA1UEAxMRUHJvdG9uVlBOIFJvb3QgQ0GCAQEwCwYDVR0PBAQD\nAgEGMA0GCSqGSIb3DQEBDQUAA4ICAQCYr7LpvnfZXBCxVIVc2ea1fjxQ6vkTj0zM\nhtFs3qfeXpMRf+g1NAh4vv1UIwLsczilMt87SjpJ25pZPyS3O+/VlI9ceZMvtGXd\nMGfXhTDp//zRoL1cbzSHee9tQlmEm1tKFxB0wfWd/inGRjZxpJCTQh8oc7CTziHZ\nufS+Jkfpc4Rasr31fl7mHhJahF1j/ka/OOWmFbiHBNjzmNWPQInJm+0ygFqij5qs\n51OEvubR8yh5Mdq4TNuWhFuTxpqoJ87VKaSOx/Aefca44Etwcj4gHb7LThidw/ky\nzysZiWjyrbfX/31RX7QanKiMk2RDtgZaWi/lMfsl5O+6E2lJ1vo4xv9pW8225B5X\neAeXHCfjV/vrrCFqeCprNF6a3Tn/LX6VNy3jbeC+167QagBOaoDA01XPOx7Odhsb\nGd7cJ5VkgyycZgLnT9zrChgwjx59JQosFEG1DsaAgHfpEl/N3YPJh68N7fwN41Cj\nzsk39v6iZdfuet/sP7oiP5/gLmA/CIPNhdIYxaojbLjFPkftVjVPn49RqwqzJJPR\nN8BOyb94yhQ7KO4F3IcLT/y/dsWitY0ZH4lCnAVV/v2YjWAWS3OWyC8BFx/Jmc3W\nDK/yPwECUcPgHIeXiRjHnJt0Zcm23O2Q3RphpU+1SO3XixsXpOVOYP6rJIXW9bMZ\nA1gTTlpi7A==\n-----END CERTIFICATE-----\n","wrap":{"strategy":"auth","key":{"dir":1,"data":"as7wP2JnW0sbvQPlOxh3J0I86nQiQhBsspFqikyCl1Y9IsflzvQwsRA8b2brH8WzdaZy8Vji4uk2w/qkiwNabeF76qwjtfA7ELho1T0DUh2LoRUFnad3pgy/17LJxXRyeKFbj25oo+9/1YPsnzmMi9RzXatAy9HjxiqCLpdIkYbDCgtIx8OOoyzrBW0/pacQ4QzMeg3bNjsIw9J3ejOV4QwLYID1YwkZKrWqzUtF9V2mH8d685vYGhkhinl2LDOGLfVXhQdfN9jHHcikIJfuQzRHOaDdSNAwJbBFDPH7XoyuuJPZqW0fFVGbs8TctA7jFmcuoWwBJmT4qfESVVGN6w=="}},"ep":["UDP:80","UDP:443","UDP:4569","UDP:1194","UDP:5060","TCP:443","TCP:3389","TCP:8080","TCP:8443"],"cipher":"AES-256-CBC","auth":"SHA512","frame":1,"reneg":0,"eku":true,"random":true},"external":{"hostname":"${id}.protonvpn.com"}}],"defaults":{"username":"ABCdefGH012_jklMNop34Q_R","pool":"us-free-01","preset":"default"},"categories":[{"name":"","groups":[{"country":"AT","pools":[{"id":"at-01","country":"AT","num":1,"addrs":[3119830075]},{"id":"at-02","country":"AT","num":2,"addrs":[3119830076]},{"id":"at-03","country":"AT","num":3,"addrs":[3119830077]},{"id":"at-04","country":"AT","num":4,"addrs":[3119830078]},{"id":"at-05","country":"AT","num":5,"addrs":[3119830235]},{"id":"at-06","country":"AT","num":6,"addrs":[3119830236]},{"id":"at-07","country":"AT","num":7,"addrs":[3119830237]},{"id":"at-08","country":"AT","num":8,"addrs":[3119830238]}]},{"country":"AU","pools":[{"id":"au-01","country":"AU","num":1,"addrs":[3114387722]},{"id":"au-02","country":"AU","num":2,"addrs":[3114387723]},{"id":"au-03","country":"AU","num":3,"addrs":[3114387724]},{"id":"au-04","country":"AU","num":4,"addrs":[3114387725]},{"id":"au-05","country":"AU","num":5,"addrs":[3114387726]},{"id":"au-06","country":"AU","num":6,"addrs":[3114387727]},{"id":"au-07","country":"AU","num":7,"addrs":[3114387728]},{"id":"au-08","country":"AU","num":8,"addrs":[3114387729]},{"id":"au-09","country":"AU","num":9,"addrs":[771247235]},{"id":"au-10","country":"AU","num":10,"addrs":[771247236]},{"id":"au-11","country":"AU","num":11,"addrs":[771247237]},{"id":"au-12","country":"AU","num":12,"addrs":[771247238]}]},{"country":"BE","pools":[{"id":"be-01","country":"BE","num":1,"addrs":[3238621875]},{"id":"be-02","country":"BE","num":2,"addrs":[3238621876]},{"id":"be-03","country":"BE","num":3,"addrs":[3238621877]},{"id":"be-04","country":"BE","num":4,"addrs":[3238621878]}]},{"country":"BR","pools":[{"id":"br-01","country":"BR","num":1,"addrs":[3050702404]},{"id":"br-02","country":"BR","num":2,"addrs":[3050702405]},{"id":"br-03","country":"BR","num":3,"addrs":[3050702406]},{"id":"br-04","country":"BR","num":4,"addrs":[3050702407]}]},{"country":"CA","pools":[{"id":"ca-01","country":"CA","num":1,"addrs":[1761500219]},{"id":"ca-02","country":"CA","num":2,"addrs":[1761500220]},{"id":"ca-03","country":"CA","num":3,"addrs":[1761500221]},{"id":"ca-04","country":"CA","num":4,"addrs":[1761500222]},{"id":"ca-05","country":"CA","num":5,"addrs":[2891130947]},{"id":"ca-06","country":"CA","num":6,"addrs":[2891130948]},{"id":"ca-07","country":"CA","num":7,"addrs":[2891130949]},{"id":"ca-08","country":"CA","num":8,"addrs":[2891130950]},{"id":"ca-09","country":"CA","num":9,"addrs":[3485278043]},{"id":"ca-10","country":"CA","num":10,"addrs":[3485278044]},{"id":"ca-11","country":"CA","num":11,"addrs":[3485278045]},{"id":"ca-12","country":"CA","num":12,"addrs":[3485278046]}]},{"country":"CH","pools":[{"id":"ch-05","country":"CH","num":5,"addrs":[3114245384]},{"id":"ch-06","country":"CH","num":6,"addrs":[3114245385]},{"id":"ch-07","country":"CH","num":7,"addrs":[3114245386]},{"id":"ch-08","country":"CH","num":8,"addrs":[3114245387]},{"id":"ch-10","country":"CH","num":10,"addrs":[3114245395]},{"id":"ch-11","country":"CH","num":11,"addrs":[3114245396]},{"id":"ch-12","country":"CH","num":12,"addrs":[3114245397]},{"id":"ch-13","country":"CH","num":13,"addrs":[3114245398]},{"id":"ch-14","country":"CH","num":14,"addrs":[3240392171]},{"id":"ch-15","country":"CH","num":15,"addrs":[3240392172]},{"id":"ch-16","country":"CH","num":16,"addrs":[3240392173]},{"id":"ch-17","country":"CH","num":17,"addrs":[3240392174]},{"id":"ch-18-tor","country":"CH","num":18,"addrs":[3240392166]}]},{"country":"CZ","pools":[{"id":"cz-01","country":"CZ","num":1,"addrs":[3119646211]},{"id":"cz-02","country":"CZ","num":2,"addrs":[3119646212]},{"id":"cz-03","country":"CZ","num":3,"addrs":[3119646213]},{"id":"cz-04","country":"CZ","num":4,"addrs":[3119646214]}]},{"country":"DE","pools":[{"id":"de-01","country":"DE","num":1,"addrs":[624573157]},{"id":"de-02","country":"DE","num":2,"addrs":[624573158]},{"id":"de-03","country":"DE","num":3,"addrs":[624573159]},{"id":"de-04","country":"DE","num":4,"addrs":[624573160]},{"id":"de-05","country":"DE","num":5,"addrs":[2918785673]},{"id":"de-06","country":"DE","num":6,"addrs":[2918785674]},{"id":"de-07","country":"DE","num":7,"addrs":[2918785675]},{"id":"de-08","country":"DE","num":8,"addrs":[2918785676]},{"id":"de-09","country":"DE","num":9,"addrs":[1382420675]},{"id":"de-10","country":"DE","num":10,"addrs":[1382420676]},{"id":"de-11","country":"DE","num":11,"addrs":[1382420677]},{"id":"de-12","country":"DE","num":12,"addrs":[1382420678]}]},{"country":"DK","pools":[{"id":"dk-01","country":"DK","num":1,"addrs":[1605255427]},{"id":"dk-02","country":"DK","num":2,"addrs":[1605255428]},{"id":"dk-03","country":"DK","num":3,"addrs":[1605255429]},{"id":"dk-04","country":"DK","num":4,"addrs":[1605255430]}]},{"country":"ES","pools":[{"id":"es-05","country":"ES","num":5,"addrs":[3283462035]},{"id":"es-06","country":"ES","num":6,"addrs":[3283462036]},{"id":"es-07","country":"ES","num":7,"addrs":[3283462037]},{"id":"es-08","country":"ES","num":8,"addrs":[3283462038]}]},{"country":"FI","pools":[{"id":"fi-01","country":"FI","num":1,"addrs":[3257041976]},{"id":"fi-02","country":"FI","num":2,"addrs":[3257041977]},{"id":"fi-03","country":"FI","num":3,"addrs":[3257041978]},{"id":"fi-04","country":"FI","num":4,"addrs":[3257041979]}]},{"country":"FR","pools":[{"id":"fr-05","country":"FR","num":5,"addrs":[3109993915]},{"id":"fr-06","country":"FR","num":6,"addrs":[3109993916]},{"id":"fr-07","country":"FR","num":7,"addrs":[3109993917]},{"id":"fr-08","country":"FR","num":8,"addrs":[3109993918]},{"id":"fr-09","country":"FR","num":9,"addrs":[3258710291]},{"id":"fr-10","country":"FR","num":10,"addrs":[3258710292]},{"id":"fr-11","country":"FR","num":11,"addrs":[3258710293]},{"id":"fr-12","country":"FR","num":12,"addrs":[3258710294]}]},{"country":"HK","pools":[{"id":"hk-01","country":"HK","num":1,"addrs":[3510286823]},{"id":"hk-02","country":"HK","num":2,"addrs":[3510286824]},{"id":"hk-03","country":"HK","num":3,"addrs":[3510286825]},{"id":"hk-04","country":"HK","num":4,"addrs":[3510286826]},{"id":"hk-05-tor","country":"HK","num":5,"addrs":[3510286746]}]},{"country":"IE","pools":[{"id":"ie-01","country":"IE","num":1,"addrs":[94178563]},{"id":"ie-02","country":"IE","num":2,"addrs":[94178564]},{"id":"ie-03","country":"IE","num":3,"addrs":[94178565]},{"id":"ie-04","country":"IE","num":4,"addrs":[94178566]}]},{"country":"IL","pools":[{"id":"il-01","country":"IL","num":1,"addrs":[1475346277]},{"id":"il-02","country":"IL","num":2,"addrs":[1475346278]},{"id":"il-03","country":"IL","num":3,"addrs":[1475346279]},{"id":"il-04","country":"IL","num":4,"addrs":[1475346280]}]},{"country":"IN","pools":[{"id":"in-01","country":"IN","num":1,"addrs":[1742596363]},{"id":"in-02","country":"IN","num":2,"addrs":[1742596364]}]},{"country":"IS","pools":[{"id":"is-01","country":"IS","num":1,"addrs":[3114245732]},{"id":"is-02","country":"IS","num":2,"addrs":[3114245733]},{"id":"is-03","country":"IS","num":3,"addrs":[3114245682]},{"id":"is-04","country":"IS","num":4,"addrs":[3114245683]},{"id":"is-05","country":"IS","num":5,"addrs":[3114245689]},{"id":"is-06","country":"IS","num":6,"addrs":[3114245690]},{"id":"is-07","country":"IS","num":7,"addrs":[3114245739]},{"id":"is-08","country":"IS","num":8,"addrs":[3114245740]}]},{"country":"IT","pools":[{"id":"it-01","country":"IT","num":1,"addrs":[3112180579]},{"id":"it-02","country":"IT","num":2,"addrs":[3112180580]},{"id":"it-03","country":"IT","num":3,"addrs":[3112180581]},{"id":"it-04","country":"IT","num":4,"addrs":[3112180582]}]},{"country":"JP","pools":[{"id":"jp-01","country":"JP","num":1,"addrs":[3114387466]},{"id":"jp-02","country":"JP","num":2,"addrs":[3114387467]},{"id":"jp-03","country":"JP","num":3,"addrs":[3114387468]},{"id":"jp-04","country":"JP","num":4,"addrs":[3114387469]},{"id":"jp-05","country":"JP","num":5,"addrs":[3114387470]},{"id":"jp-06","country":"JP","num":6,"addrs":[3114387471]},{"id":"jp-07","country":"JP","num":7,"addrs":[3114387472]},{"id":"jp-08","country":"JP","num":8,"addrs":[3114387473]},{"id":"jp-09","country":"JP","num":9,"addrs":[3119645899]},{"id":"jp-10","country":"JP","num":10,"addrs":[3119645900]},{"id":"jp-11","country":"JP","num":11,"addrs":[3119645901]},{"id":"jp-12","country":"JP","num":12,"addrs":[3119645902]},{"id":"jp-13","country":"JP","num":13,"addrs":[1540337323]},{"id":"jp-14","country":"JP","num":14,"addrs":[1540337324]},{"id":"jp-15","country":"JP","num":15,"addrs":[1540337325]},{"id":"jp-16","country":"JP","num":16,"addrs":[1540337326]},{"id":"jp-17","country":"JP","num":17,"addrs":[3247706339]},{"id":"jp-18","country":"JP","num":18,"addrs":[3247706340]},{"id":"jp-19","country":"JP","num":19,"addrs":[3247706341]},{"id":"jp-20","country":"JP","num":20,"addrs":[3247706342]}]},{"country":"KR","pools":[{"id":"kr-01","country":"KR","num":1,"addrs":[469720102]},{"id":"kr-02","country":"KR","num":2,"addrs":[469720103]},{"id":"kr-03","country":"KR","num":3,"addrs":[469720104]},{"id":"kr-04","country":"KR","num":4,"addrs":[469720105]}]},{"country":"LU","pools":[{"id":"lu-01","country":"LU","num":1,"addrs":[1592976564]},{"id":"lu-02","country":"LU","num":2,"addrs":[1592976556]},{"id":"lu-03","country":"LU","num":3,"addrs":[1592976557]},{"id":"lu-04","country":"LU","num":4,"addrs":[1592976558]}]},{"country":"NL","pools":[{"id":"nl-01","country":"NL","num":1,"addrs":[1047529893]},{"id":"nl-02","country":"NL","num":2,"addrs":[1047529894]},{"id":"nl-03","country":"NL","num":3,"addrs":[1047529895]},{"id":"nl-04","country":"NL","num":4,"addrs":[1047529965]},{"id":"nl-05","country":"NL","num":5,"addrs":[1308078774]},{"id":"nl-06","country":"NL","num":6,"addrs":[1308078775]},{"id":"nl-07","country":"NL","num":7,"addrs":[1308078777]},{"id":"nl-08","country":"NL","num":8,"addrs":[1308078778]},{"id":"nl-09","country":"NL","num":9,"addrs":[1495755728]},{"id":"nl-101","country":"NL","num":101,"addrs":[3642164059]},{"id":"nl-102","country":"NL","num":102,"addrs":[3642164060]},{"id":"nl-103","country":"NL","num":103,"addrs":[3642164064]},{"id":"nl-104","country":"NL","num":104,"addrs":[3642164139]},{"id":"nl-105","country":"NL","num":105,"addrs":[1495755722]},{"id":"nl-106","country":"NL","num":106,"addrs":[1495755723]},{"id":"nl-107","country":"NL","num":107,"addrs":[1495755724]},{"id":"nl-108","country":"NL","num":108,"addrs":[1495755725]},{"id":"nl-109","country":"NL","num":109,"addrs":[1495755718]},{"id":"nl-10","country":"NL","num":10,"addrs":[1495755729]},{"id":"nl-110","country":"NL","num":110,"addrs":[1495755719]},{"id":"nl-111","country":"NL","num":111,"addrs":[1495755720]},{"id":"nl-112","country":"NL","num":112,"addrs":[1495755721]},{"id":"nl-113","country":"NL","num":113,"addrs":[1495755714]},{"id":"nl-114","country":"NL","num":114,"addrs":[1495755715]},{"id":"nl-115","country":"NL","num":115,"addrs":[1495755716]},{"id":"nl-116","country":"NL","num":116,"addrs":[1495755717]},{"id":"nl-117","country":"NL","num":117,"addrs":[1495755710]},{"id":"nl-118","country":"NL","num":118,"addrs":[1495755711]},{"id":"nl-119","country":"NL","num":119,"addrs":[1495755712]},{"id":"nl-11","country":"NL","num":11,"addrs":[1495755730]},{"id":"nl-120","country":"NL","num":120,"addrs":[1495755713]},{"id":"nl-125","country":"NL","num":125,"addrs":[1841923350]},{"id":"nl-126","country":"NL","num":126,"addrs":[1841923352]},{"id":"nl-127","country":"NL","num":127,"addrs":[1841923354]},{"id":"nl-128","country":"NL","num":128,"addrs":[1841923358]},{"id":"nl-129","country":"NL","num":129,"addrs":[782667478]},{"id":"nl-12","country":"NL","num":12,"addrs":[1495755731]},{"id":"nl-130","country":"NL","num":130,"addrs":[782667479]},{"id":"nl-131","country":"NL","num":131,"addrs":[782667480]},{"id":"nl-132","country":"NL","num":132,"addrs":[782667481]},{"id":"nl-133","country":"NL","num":133,"addrs":[782667483]},{"id":"nl-134","country":"NL","num":134,"addrs":[782667484]},{"id":"nl-135","country":"NL","num":135,"addrs":[782667485]},{"id":"nl-136","country":"NL","num":136,"addrs":[782667486]},{"id":"nl-137","country":"NL","num":137,"addrs":[3114660131]},{"id":"nl-138","country":"NL","num":138,"addrs":[3114660132]},{"id":"nl-139","country":"NL","num":139,"addrs":[3114660133]},{"id":"nl-140","country":"NL","num":140,"addrs":[3114660134]}]},{"country":"NO","pools":[{"id":"no-01","country":"NO","num":1,"addrs":[1605255739]},{"id":"no-02","country":"NO","num":2,"addrs":[1605255740]},{"id":"no-03","country":"NO","num":3,"addrs":[1605255741]},{"id":"no-04","country":"NO","num":4,"addrs":[1605255742]}]},{"country":"NZ","pools":[{"id":"nz-01","country":"NZ","num":1,"addrs":[3029723043]},{"id":"nz-02","country":"NZ","num":2,"addrs":[3029723044]},{"id":"nz-03","country":"NZ","num":3,"addrs":[3029723045]},{"id":"nz-04","country":"NZ","num":4,"addrs":[3029723046]}]},{"country":"PL","pools":[{"id":"pl-01","country":"PL","num":1,"addrs":[3261294923]},{"id":"pl-02","country":"PL","num":2,"addrs":[3261294924]},{"id":"pl-03","country":"PL","num":3,"addrs":[3261294925]},{"id":"pl-04","country":"PL","num":4,"addrs":[3261294926]}]},{"country":"PT","pools":[{"id":"pt-01","country":"PT","num":1,"addrs":[3115228162]},{"id":"pt-02","country":"PT","num":2,"addrs":[3115228163]},{"id":"pt-03","country":"PT","num":3,"addrs":[3115228164]},{"id":"pt-04","country":"PT","num":4,"addrs":[3115228165]}]},{"country":"RU","pools":[{"id":"ru-01","country":"RU","num":1,"addrs":[84414699]},{"id":"ru-02","country":"RU","num":2,"addrs":[84414700]},{"id":"ru-03","country":"RU","num":3,"addrs":[84414701]},{"id":"ru-04","country":"RU","num":4,"addrs":[84414702]}]},{"country":"SE","pools":[{"id":"se-01","country":"SE","num":1,"addrs":[3114245123]},{"id":"se-02","country":"SE","num":2,"addrs":[3114245124]},{"id":"se-03","country":"SE","num":3,"addrs":[3114245125]},{"id":"se-04","country":"SE","num":4,"addrs":[3114245126]},{"id":"se-05","country":"SE","num":5,"addrs":[3114245137]},{"id":"se-06","country":"SE","num":6,"addrs":[3114245138]},{"id":"se-07","country":"SE","num":7,"addrs":[3114245139]},{"id":"se-08","country":"SE","num":8,"addrs":[3114245140]},{"id":"se-09","country":"SE","num":9,"addrs":[1334725703]},{"id":"se-10","country":"SE","num":10,"addrs":[1334725704]},{"id":"se-11","country":"SE","num":11,"addrs":[1334725705]},{"id":"se-12","country":"SE","num":12,"addrs":[1334725706]},{"id":"se-13","country":"SE","num":13,"addrs":[3119939666]},{"id":"se-14","country":"SE","num":14,"addrs":[3119939667]},{"id":"se-15","country":"SE","num":15,"addrs":[3119939668]},{"id":"se-16","country":"SE","num":16,"addrs":[3119939669]}]},{"country":"SG","pools":[{"id":"sg-01","country":"SG","num":1,"addrs":[3510282470]},{"id":"sg-02","country":"SG","num":2,"addrs":[3510282471]},{"id":"sg-03","country":"SG","num":3,"addrs":[3510282472]},{"id":"sg-04","country":"SG","num":4,"addrs":[3510282473]},{"id":"sg-05","country":"SG","num":5,"addrs":[3510283112]},{"id":"sg-06","country":"SG","num":6,"addrs":[3510283113]},{"id":"sg-07","country":"SG","num":7,"addrs":[3510283114]},{"id":"sg-08","country":"SG","num":8,"addrs":[3510283115]},{"id":"sg-09","country":"SG","num":9,"addrs":[1540336971]},{"id":"sg-10","country":"SG","num":10,"addrs":[1540336972]},{"id":"sg-11","country":"SG","num":11,"addrs":[1540336973]},{"id":"sg-12","country":"SG","num":12,"addrs":[1540336974]},{"id":"sg-13","country":"SG","num":13,"addrs":[3112179731]},{"id":"sg-14","country":"SG","num":14,"addrs":[3112179732]},{"id":"sg-15","country":"SG","num":15,"addrs":[3112179733]},{"id":"sg-16","country":"SG","num":16,"addrs":[3112179734]},{"id":"sg-17","country":"SG","num":17,"addrs":[3112179739]},{"id":"sg-18","country":"SG","num":18,"addrs":[3112179740]},{"id":"sg-19","country":"SG","num":19,"addrs":[3112179741]},{"id":"sg-20","country":"SG","num":20,"addrs":[3112179742]}]},{"country":"GB","pools":[{"id":"uk-05","country":"GB","num":5,"addrs":[3106688118]},{"id":"uk-06","country":"GB","num":6,"addrs":[3106688119]},{"id":"uk-07","country":"GB","num":7,"addrs":[3106688120]},{"id":"uk-08","country":"GB","num":8,"addrs":[3106688121]},{"id":"uk-09","country":"GB","num":9,"addrs":[1318966251]},{"id":"uk-10","country":"GB","num":10,"addrs":[1318966252]},{"id":"uk-11","country":"GB","num":11,"addrs":[1318966253]},{"id":"uk-12","country":"GB","num":12,"addrs":[1318966254]}]},{"country":"US","area":"ca","pools":[{"id":"us-ca-01","country":"US","area":"ca","num":1,"addrs":[3510272353]},{"id":"us-ca-02","country":"US","area":"ca","num":2,"addrs":[3510272354]},{"id":"us-ca-03","country":"US","area":"ca","num":3,"addrs":[3510272355]},{"id":"us-ca-04","country":"US","area":"ca","num":4,"addrs":[3510272356]},{"id":"us-ca-09","country":"US","area":"ca","num":9,"addrs":[3325306424]},{"id":"us-ca-101","country":"US","area":"ca","num":101,"addrs":[3510275738]},{"id":"us-ca-102","country":"US","area":"ca","num":102,"addrs":[3510275739]},{"id":"us-ca-103","country":"US","area":"ca","num":103,"addrs":[3510275740]},{"id":"us-ca-104","country":"US","area":"ca","num":104,"addrs":[3510275741]},{"id":"us-ca-105","country":"US","area":"ca","num":105,"addrs":[3510275742]},{"id":"us-ca-106","country":"US","area":"ca","num":106,"addrs":[3510275743]},{"id":"us-ca-107","country":"US","area":"ca","num":107,"addrs":[3510275744]},{"id":"us-ca-108","country":"US","area":"ca","num":108,"addrs":[3510275745]},{"id":"us-ca-10","country":"US","area":"ca","num":10,"addrs":[3325306425]},{"id":"us-ca-113","country":"US","area":"ca","num":113,"addrs":[3325306420]},{"id":"us-ca-114","country":"US","area":"ca","num":114,"addrs":[3325306421]},{"id":"us-ca-115","country":"US","area":"ca","num":115,"addrs":[3325306422]},{"id":"us-ca-116","country":"US","area":"ca","num":116,"addrs":[3325306423]},{"id":"us-ca-11","country":"US","area":"ca","num":11,"addrs":[3325306426]},{"id":"us-ca-12","country":"US","area":"ca","num":12,"addrs":[3325306427]}]},{"country":"US","area":"co","pools":[{"id":"us-co-09","country":"US","area":"co","num":9,"addrs":[3325305875]},{"id":"us-co-10","country":"US","area":"co","num":10,"addrs":[3325305876]},{"id":"us-co-11","country":"US","area":"co","num":11,"addrs":[3325305877]},{"id":"us-co-12","country":"US","area":"co","num":12,"addrs":[3325305878]},{"id":"us-co-13","country":"US","area":"co","num":13,"addrs":[2455290187]},{"id":"us-co-14","country":"US","area":"co","num":14,"addrs":[2455290188]},{"id":"us-co-15","country":"US","area":"co","num":15,"addrs":[2455290189]},{"id":"us-co-16","country":"US","area":"co","num":16,"addrs":[2455290190]}]},{"country":"US","area":"il","pools":[{"id":"us-il-05","country":"US","area":"il","num":5,"addrs":[3496225721]},{"id":"us-il-06","country":"US","area":"il","num":6,"addrs":[3496225722]},{"id":"us-il-07","country":"US","area":"il","num":7,"addrs":[3496225723]},{"id":"us-il-08","country":"US","area":"il","num":8,"addrs":[3496225724]},{"id":"us-il-09","country":"US","area":"il","num":9,"addrs":[1168230216]},{"id":"us-il-105","country":"US","area":"il","num":105,"addrs":[1168230212]},{"id":"us-il-106","country":"US","area":"il","num":106,"addrs":[1168230213]},{"id":"us-il-107","country":"US","area":"il","num":107,"addrs":[1168230214]},{"id":"us-il-108","country":"US","area":"il","num":108,"addrs":[1168230215]},{"id":"us-il-10","country":"US","area":"il","num":10,"addrs":[1168230217]},{"id":"us-il-11","country":"US","area":"il","num":11,"addrs":[1168230218]},{"id":"us-il-12","country":"US","area":"il","num":12,"addrs":[1168230219]}]},{"country":"US","area":"nj","pools":[{"id":"us-nj-05","country":"US","area":"nj","num":5,"addrs":[3237797411]},{"id":"us-nj-06","country":"US","area":"nj","num":6,"addrs":[3237797412]},{"id":"us-nj-07","country":"US","area":"nj","num":7,"addrs":[3237797413]},{"id":"us-nj-08","country":"US","area":"nj","num":8,"addrs":[3237797414]}]},{"country":"US","area":"ny","pools":[{"id":"us-ny-01","country":"US","area":"ny","num":1,"addrs":[1759418739]},{"id":"us-ny-02","country":"US","area":"ny","num":2,"addrs":[1759418740]},{"id":"us-ny-03","country":"US","area":"ny","num":3,"addrs":[1759418741]},{"id":"us-ny-04","country":"US","area":"ny","num":4,"addrs":[1759418742]}]},{"country":"US","area":"tx","pools":[{"id":"us-tx-01","country":"US","area":"tx","num":1,"addrs":[3510276906]},{"id":"us-tx-02","country":"US","area":"tx","num":2,"addrs":[3510276907]},{"id":"us-tx-03","country":"US","area":"tx","num":3,"addrs":[3510276908]},{"id":"us-tx-04-tor","country":"US","area":"tx","num":4,"addrs":[3510276909]},{"id":"us-tx-05","country":"US","area":"tx","num":5,"addrs":[3495205699]},{"id":"us-tx-06","country":"US","area":"tx","num":6,"addrs":[3495205700]},{"id":"us-tx-07","country":"US","area":"tx","num":7,"addrs":[3495205701]},{"id":"us-tx-08","country":"US","area":"tx","num":8,"addrs":[3495205702]},{"id":"us-tx-101","country":"US","area":"tx","num":101,"addrs":[3510277074]},{"id":"us-tx-102","country":"US","area":"tx","num":102,"addrs":[3510277102]},{"id":"us-tx-103","country":"US","area":"tx","num":103,"addrs":[3510277103]},{"id":"us-tx-104","country":"US","area":"tx","num":104,"addrs":[3510277105]},{"id":"us-tx-105","country":"US","area":"tx","num":105,"addrs":[3510277106]},{"id":"us-tx-106","country":"US","area":"tx","num":106,"addrs":[3510277107]},{"id":"us-tx-107","country":"US","area":"tx","num":107,"addrs":[3510277108]},{"id":"us-tx-108","country":"US","area":"tx","num":108,"addrs":[3510277109]}]},{"country":"US","area":"va","pools":[{"id":"us-va-01","country":"US","area":"va","num":1,"addrs":[2731720861]},{"id":"us-va-02","country":"US","area":"va","num":2,"addrs":[2731720862]},{"id":"us-va-03","country":"US","area":"va","num":3,"addrs":[2731720863]},{"id":"us-va-04","country":"US","area":"va","num":4,"addrs":[2731720864]},{"id":"us-va-05","country":"US","area":"va","num":5,"addrs":[1118512459]},{"id":"us-va-06","country":"US","area":"va","num":6,"addrs":[1118512460]},{"id":"us-va-07","country":"US","area":"va","num":7,"addrs":[1118512461]},{"id":"us-va-08","country":"US","area":"va","num":8,"addrs":[1118512462]},{"id":"us-va-101","country":"US","area":"va","num":101,"addrs":[1815805989]},{"id":"us-va-102","country":"US","area":"va","num":102,"addrs":[1815805990]},{"id":"us-va-103","country":"US","area":"va","num":103,"addrs":[1815805991]},{"id":"us-va-104","country":"US","area":"va","num":104,"addrs":[1815805992]},{"id":"us-va-105","country":"US","area":"va","num":105,"addrs":[3227568965]},{"id":"us-va-106","country":"US","area":"va","num":106,"addrs":[3227568966]},{"id":"us-va-107","country":"US","area":"va","num":107,"addrs":[3227568967]},{"id":"us-va-108","country":"US","area":"va","num":108,"addrs":[3227568968]},{"id":"us-va-109","country":"US","area":"va","num":109,"addrs":[3488902579]},{"id":"us-va-110","country":"US","area":"va","num":110,"addrs":[3488902580]},{"id":"us-va-111","country":"US","area":"va","num":111,"addrs":[3488902581]},{"id":"us-va-112","country":"US","area":"va","num":112,"addrs":[3488902582]}]},{"country":"US","area":"wa","pools":[{"id":"us-wa-01","country":"US","area":"wa","num":1,"addrs":[1116032612]},{"id":"us-wa-02","country":"US","area":"wa","num":2,"addrs":[1116032613]},{"id":"us-wa-03","country":"US","area":"wa","num":3,"addrs":[1116032614]},{"id":"us-wa-04","country":"US","area":"wa","num":4,"addrs":[1116032615]},{"id":"us-wa-05","country":"US","area":"wa","num":5,"addrs":[1116032616]},{"id":"us-wa-06","country":"US","area":"wa","num":6,"addrs":[1116032617]},{"id":"us-wa-07","country":"US","area":"wa","num":7,"addrs":[1116032618]},{"id":"us-wa-08","country":"US","area":"wa","num":8,"addrs":[1116032619]}]},{"country":"ZA","pools":[{"id":"za-01","country":"ZA","num":1,"addrs":[3236310403]},{"id":"za-02","country":"ZA","num":2,"addrs":[3236310404]},{"id":"za-03","country":"ZA","num":3,"addrs":[3236310405]},{"id":"za-04","country":"ZA","num":4,"addrs":[3236310406]}]}]},{"name":"free","groups":[{"country":"JP","pools":[{"id":"jp-free-01","country":"JP","num":1,"addrs":[3114387467,1540337326,1540337324,1540337325,3114387466]},{"id":"jp-free-02","country":"JP","num":2,"addrs":[3119645902,3119645901,3119645899,1540337323,3119645900]},{"id":"jp-free-03","country":"JP","num":3,"addrs":[3247706341,3247706340,3247706342,3247706339]}]},{"country":"NL","pools":[{"id":"nl-free-01","country":"NL","num":1,"addrs":[782667479,1495755719,1495755712,782667483,1495755723,1495755710,1495755715,1841923352,1495755716,3642164064,1495755711,1495755720,3642164060,782667478,1495755722,1495755714,1841923350,1495755724,782667484,1841923354,3642164059,1495755718]},{"id":"nl-free-02","country":"NL","num":2,"addrs":[782667486,782667480,1495755713,782667485,1495755721,1495755725,782667481,1841923358,1495755717,3642164139]}]},{"country":"US","pools":[{"id":"us-free-01","country":"US","num":1,"addrs":[3227568966,3510277109,3488902579,1168230214,3510277102,3510277106,3510275741,3227568965,3510275745,3488902580,3510277108,1815805989,1168230212,3510275743,3510275739,3510275742,1815805990,1168230213,3510277103,3510277074,3510277105,3510275738,1815805991]},{"id":"us-free-02","country":"US","num":2,"addrs":[3488902582,3227568968,3325306423,3325306420,1168230215,3510275740,3510275744,3325306421,3227568967,3325306422,1815805992,3510277107,3488902581]}]}]},{"name":"secure core","groups":[{"country":"CH","pools":[{"id":"ch-at-01","country":"CH","extra_countries":["AT"],"num":1,"resolved":true,"addrs":[3114245410,3114245411,3114245423]},{"id":"ch-ca-01","country":"CH","extra_countries":["CA"],"num":1,"resolved":true,"addrs":[3114245390,3114245393,3114245405,3114245406,3114245407]},{"id":"ch-cz-01","country":"CH","extra_countries":["CZ"],"num":1,"resolved":true,"addrs":[3114245414,3114245415]},{"id":"ch-dk-01","country":"CH","extra_countries":["DK"],"num":1,"resolved":true,"addrs":[3114245412,3114245413]},{"id":"ch-in-01","country":"CH","extra_countries":["IN"],"num":1,"resolved":true,"addrs":[3114245416]},{"id":"ch-it-01","country":"CH","extra_countries":["IT"],"num":1,"resolved":true,"addrs":[3114245394]},{"id":"ch-lu-01","country":"CH","extra_countries":["LU"],"num":1,"resolved":true,"addrs":[3114245420,3114245421,3114245422]},{"id":"ch-pl-01","country":"CH","extra_countries":["PL"],"num":1,"resolved":true,"addrs":[3114245408,3114245409]},{"id":"ch-sg-01","country":"CH","extra_countries":["SG"],"num":1,"resolved":true,"addrs":[3114245417,3114245418,3114245419]},{"id":"ch-uk-01","country":"CH","extra_countries":["GB"],"num":1,"resolved":true,"addrs":[3114245388,3114245391,3114245399,3114245400,3114245401,3114245402]},{"id":"ch-us-01","country":"CH","extra_countries":["US"],"num":1,"resolved":true,"addrs":[3114245389,3114245392,3114245403,3114245404]}]},{"country":"IS","pools":[{"id":"is-be-01","country":"IS","extra_countries":["BE"],"num":1,"resolved":true,"addrs":[3114245759,3114245760,3114245761]},{"id":"is-br-01","country":"IS","extra_countries":["BR"],"num":1,"resolved":true,"addrs":[3114245756,3114245757,3114245758]},{"id":"is-ca-01","country":"IS","extra_countries":["CA"],"num":1,"resolved":true,"addrs":[3114245735,3114245685,3114245743,3114245744,3114245749]},{"id":"is-de-01","country":"IS","extra_countries":["DE"],"num":1,"resolved":true,"addrs":[3114245738,3114245688,3114245745,3114245746,3114245747,3114245748]},{"id":"is-es-01","country":"IS","extra_countries":["ES"],"num":1,"resolved":true,"addrs":[3114245736,3114245686]},{"id":"is-ie-01","country":"IS","extra_countries":["IE"],"num":1,"resolved":true,"addrs":[3114245750,3114245751,3114245752]},{"id":"is-il-01","country":"IS","extra_countries":["IL"],"num":1,"resolved":true,"addrs":[3114245762,3114245763]},{"id":"is-nl-01","country":"IS","extra_countries":["NL"],"num":1,"resolved":true,"addrs":[3114245737,3114245687]},{"id":"is-no-01","country":"IS","extra_countries":["NO"],"num":1,"resolved":true,"addrs":[3114245753,3114245754,3114245755]},{"id":"is-ru-01","country":"IS","extra_countries":["RU"],"num":1,"resolved":true,"addrs":[3114245764]},{"id":"is-us-01","country":"IS","extra_countries":["US"],"num":1,"resolved":true,"addrs":[3114245734,3114245684,3114245741,3114245742]}]},{"country":"SE","pools":[{"id":"se-au-01","country":"SE","extra_countries":["AU"],"num":1,"resolved":true,"addrs":[3114245129,3114245130]},{"id":"se-fi-01","country":"SE","extra_countries":["FI"],"num":1,"resolved":true,"addrs":[3114245146,3114245147,3114245148]},{"id":"se-fr-01","country":"SE","extra_countries":["FR"],"num":1,"resolved":true,"addrs":[3114245135,3114245136,3114245141,3114245142]},{"id":"se-hk-01","country":"SE","extra_countries":["HK"],"num":1,"resolved":true,"addrs":[3114245131,3114245132]},{"id":"se-jp-01","country":"SE","extra_countries":["JP"],"num":1,"resolved":true,"addrs":[3114245127,3114245128,3114245152]},{"id":"se-kr-01","country":"SE","extra_countries":["KR"],"num":1,"resolved":true,"addrs":[3114245143,3114245144,3114245145]},{"id":"se-nz-01a","country":"SE","extra_countries":["NZ"],"num":1,"resolved":true,"addrs":[3114245156]},{"id":"se-pt-01","country":"SE","extra_countries":["PT"],"num":1,"resolved":true,"addrs":[3114245153,3114245154]},{"id":"se-ru-01","country":"SE","extra_countries":["RU"],"num":1,"resolved":true,"addrs":[3114245155]},{"id":"se-za-01","country":"SE","extra_countries":["ZA"],"num":1,"resolved":true,"addrs":[3114245149,3114245150,3114245151]}]}]}],"build":1779,"name":"ProtonVPN"}
\ No newline at end of file
diff --git a/Passepartout/Resources/Web/net/tunnelbear.json b/Passepartout/Resources/Web/net/tunnelbear.json
deleted file mode 100644
index 16351b24..00000000
--- a/Passepartout/Resources/Web/net/tunnelbear.json
+++ /dev/null
@@ -1 +0,0 @@
-{"presets":[{"id":"default","name":"Default","comment":"256-bit encryption","cfg":{"ca":"-----BEGIN CERTIFICATE-----\nMIIG6zCCBNOgAwIBAgIJAJhm2PWFkE8NMA0GCSqGSIb3DQEBCwUAMIGpMQswCQYD\nVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxEzAR\nBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAsTCkRldmVsb3BlcnMxFjAUBgNVBAMT\nDUdvb2dsZSBJbmMgQ0ExEDAOBgNVBCkTB0Vhc3lSU0ExITAfBgkqhkiG9w0BCQEW\nEnN1cHBvcnRAZ29vZ2xlLmNvbTAeFw0xNTAyMDIwNTMwMDlaFw0yNTAxMzAwNTMw\nMDlaMIGpMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50\nYWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAsTCkRldmVsb3Bl\ncnMxFjAUBgNVBAMTDUdvb2dsZSBJbmMgQ0ExEDAOBgNVBCkTB0Vhc3lSU0ExITAf\nBgkqhkiG9w0BCQEWEnN1cHBvcnRAZ29vZ2xlLmNvbTCCAiIwDQYJKoZIhvcNAQEB\nBQADggIPADCCAgoCggIBAN8T5cgRQ8+zsE2FWRpArqTlBh7MvoQU9Z4659eJ3Mhq\n+pvR960HG9Bg6MkH0gwdcU65l0TLTwweOLBIZoxhLB+OVvl/x0FD4EnK9Pmp5SIU\nP7cEqcqqRfRAI+9k0jwiGcPOl7KKqfz70c6QsQYn2VvrTMqgDt4IS/zpaToZsftq\nibCtKh0bPv4UMLg6Y31cItYlVIrrbGrM4Kvdb8yN8ho3ms5KV421G9s9w/6KYBZt\nzr3mHoI9o+njE0ScTIRDnygbTevMZuCStIMjFRYaSvw0mHJu/07AQb+jwRBlZixw\nB79tuZzd0pZvDPpvjqWNfvE8iIoqVAv+eMe+/XG0n5ptUfhz27yDHOoZmaPjVThg\n4/DR8dBm6vKH4lsbCXdcZqSyBHhHNNVcGF024RItvULC/wu4xmjJOTzWV5YqjHWY\n1P+7APCTYWOfvl/xZ0W42yYB2oBcsl3wpyrbFoqXVqfkOkUArp8h0zNose7+G6jW\nxsFGqp566xD72GmULEn1TaIstdvbkvLhtgJzHkP3zSsaspSxgJNc46ZwQs5acDOB\n6NpUMeyT9dYzgiLGL8F/aBcYYs03qV9Ae6puuNlH60wZyDe7xCfrrbLHfal6wKXD\nULdv6HJ6tmcgzHx+qt5vdlqDeocSOmOgK0Xpv+GUTCMpTB8uSztb3puyLQ5A1xgT\nAgMBAAGjggESMIIBDjAdBgNVHQ4EFgQUrnDngftZs+1zGhU3iSaU0yJg4oAwgd4G\nA1UdIwSB1jCB04AUrnDngftZs+1zGhU3iSaU0yJg4oChga+kgawwgakxCzAJBgNV\nBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzETMBEG\nA1UEChMKR29vZ2xlIEluYzETMBEGA1UECxMKRGV2ZWxvcGVyczEWMBQGA1UEAxMN\nR29vZ2xlIEluYyBDQTEQMA4GA1UEKRMHRWFzeVJTQTEhMB8GCSqGSIb3DQEJARYS\nc3VwcG9ydEBnb29nbGUuY29tggkAmGbY9YWQTw0wDAYDVR0TBAUwAwEB/zANBgkq\nhkiG9w0BAQsFAAOCAgEARGOf8IUhXm0rLSmhydWwHKdcTH0LKkw/muknDkBm6j+q\nVQHYyJIrPOe3jZZ+Vzk5mnEj8RCJ/H5DiYnxPSlpr7slNtI/AqG4d5ODwU3uGsrs\nLaoUK5OWc81R0l5EBfzo+rfYI5O/0uG7M9BsGQZVz0ZpiqHuUb9BXlZ6gRVCWepm\nl7cqF8038o6ZraHpeNAI6FejBEMrO45Wc5eutpbcg18FTkotiRWS3I6K4xg75lZp\ntjF1aYGTAhC/8yoAYmBKzbKJXyNW2Vq93/9y+43OUJridoijB7cqbUpZFOVdtnZ5\nLHb3h7hLV/3C2WgehM73f/UMc65fIk+9CpwD7Cgpu9duBknf0c0s0Sw3HA/s6SL6\nV4FhARi7flTF9TGR6+e0i2oreXEwJXP3GoXpazOqzrGekSXRMqwLY83fJ/RzP0Ap\nPMc5TfiQVcL/h92CUAwwH1vRJkAhrTvNXh1Ynd7zdFT/wYWrK0twm4qlTjKYpbVL\nRIoeppgOUG+1t82/HW2geWLYSNRfZiTbpAvm00HJavD12qOD0NUIErlQnOZvW2UC\n/RzA/yu9ZguEIlV+8qmkiUCKyajyLFydWqqScMYAeJMh6aJzfQ4UHu2bzr9Qo2MV\nHiT8esMeX+/orMetzuTPgZInMhznvVdNdfwAfibwlXOKvm154UgDVgnKV405oNM=\n-----END CERTIFICATE-----\n","client":"-----BEGIN CERTIFICATE-----\nMIIHPTCCBSWgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBqTELMAkGA1UEBhMCVVMx\nCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKEwpH\nb29nbGUgSW5jMRMwEQYDVQQLEwpEZXZlbG9wZXJzMRYwFAYDVQQDEw1Hb29nbGUg\nSW5jIENBMRAwDgYDVQQpEwdFYXN5UlNBMSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0\nQGdvb2dsZS5jb20wHhcNMTUwMjAyMDUzODUxWhcNMjUwMTMwMDUzODUxWjCBojEL\nMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3\nMRMwEQYDVQQKEwpHb29nbGUgSW5jMRMwEQYDVQQLEwpEZXZlbG9wZXJzMQ8wDQYD\nVQQDEwZjbGllbnQxEDAOBgNVBCkTB0Vhc3lSU0ExITAfBgkqhkiG9w0BCQEWEnN1\ncHBvcnRAZ29vZ2xlLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB\nAO+ClQmiqC8eZsXbLtS+3UF+CUBdabPOFpKOvhmpgsxCdylzALWK5WAOx4an+uXg\nL8LrhF5sjHSEtTXiRzh6e+vqzn228t6ZKJIA5jDCZ44CTCTZKdxu1X+wSJNIEOzz\nu5OVzVM5gQPWOewBOq81NMbLHxWXHVB3gybE5KU859XBLJush8vCBK5No3VOMlmI\nqUbwVCfX8kh322N4PIe8dvsGyAFjqn05y0bD83IuXAY0HtijUwquiWEeZO8dluIt\nNqpYkeMpMGaU208/7P6/btT9EXtuHV6fMEeeO/SXIrE9EGmrWsieXg+TEilXuGMc\nhHDfkRw6xeXTFD5P0Jxrb5EhKZMV9GRIg+62VyP6s3de/3xOY7/2BKoWilmxdWcm\nVLz0i5Zxl7wokHf8egEInECZmyYCwGgu/KS/kChm8JLYiQ5oJJ+1+JZyQciko+xk\nqvngbx9pTHtcJYE1mW6jEw4V5f7ID3LdOqLmiitKQ34ke/2OPY1NSBspAL/P2Mi0\nW33GRHOfAIRy5PEqAk7GjEEPPpyEyAUXS0TpFdvgQEOKqw4oxJuZ1GPWGDxNfp1g\nJKg2HBM+Nc7QepMXLh5LHTNSOSWvJf3LsrUQ6goKp2PA0ucpktXxh08uNBJ5nUrJ\nZyituebSAv51C5r45VNCDk542vvNZVGx+mXOjRXQfVL3AgMBAAGjggFzMIIBbzAJ\nBgNVHRMEAjAAMC0GCWCGSAGG+EIBDQQgFh5FYXN5LVJTQSBHZW5lcmF0ZWQgQ2Vy\ndGlmaWNhdGUwHQYDVR0OBBYEFC6k0HKIbIzDih6+khKzUr3uIULVMIHeBgNVHSME\ngdYwgdOAFK5w54H7WbPtcxoVN4kmlNMiYOKAoYGvpIGsMIGpMQswCQYDVQQGEwJV\nUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxEzARBgNVBAoT\nCkdvb2dsZSBJbmMxEzARBgNVBAsTCkRldmVsb3BlcnMxFjAUBgNVBAMTDUdvb2ds\nZSBJbmMgQ0ExEDAOBgNVBCkTB0Vhc3lSU0ExITAfBgkqhkiG9w0BCQEWEnN1cHBv\ncnRAZ29vZ2xlLmNvbYIJAJhm2PWFkE8NMBMGA1UdJQQMMAoGCCsGAQUFBwMCMAsG\nA1UdDwQEAwIHgDARBgNVHREECjAIggZjbGllbnQwDQYJKoZIhvcNAQELBQADggIB\nACEBDTW4moXsrkIOJVC66vlbcHqphCLkTsvSt3e7FU8+UGR7eKnvg61kG16HmBcZ\nAQ/ChFyNafCdHXOmHFp9s7hRHFJ1LZ5xidBxQhBOTf66aoDzILj67MvLoCFnuxEq\nf3Ok5ayGKWVppfMUs7RgTPL+XSMLM1lsHpFMcy983MNZ+w8sSVgHiWrso2q6nTSG\naZYn7nSTpxlDHSVDB757wsIcDKT8FF/4nA0649meuEVMtNYR3hCmqiAkK9QwK8MR\nBCt3emHq5jVg51NNrhGKoaXwgab+p/YehHx1XFcDTUXIImkN0s1hZy4DlrUYkOBT\n3izKnWFziq2Zkpx9N6ZEdknQvFXeQg+EAMnVcvpf78WBvq8BIa+PlIMlSojj3tjP\nkrsyjTwWk4/f3IL4Y9B8SpoGHW3hzsEA1Z1QdYy1LnRi0MQ6XIM06vMrM/JW6H/r\nfHGa7wDILYCwgzmgqX8ek8R5v9fOdtzpJxL54o3mgkNsPuDglylNy87sR4xTd5Cr\nNOQ9Q/PuNi0u2pEMsbmj3OrPjy2TFsW6BiDKr5y48lHin7OqmuiQZMnDX/o75Ylc\nbcdJrlfMT2PJrSvH6ap61NqQK9xnIqKOhuI9xwVCvizI67GuGxiwCgiF+YSR5nOA\nkiJ6Ts2iqIvR7T7Eme2vBYH/UJ1DXrdCJx6IDGxxgoXk\n-----END CERTIFICATE-----\n","key":"-----BEGIN PRIVATE KEY-----\nMIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDvgpUJoqgvHmbF\n2y7Uvt1BfglAXWmzzhaSjr4ZqYLMQncpcwC1iuVgDseGp/rl4C/C64RebIx0hLU1\n4kc4envr6s59tvLemSiSAOYwwmeOAkwk2SncbtV/sEiTSBDs87uTlc1TOYED1jns\nATqvNTTGyx8Vlx1Qd4MmxOSlPOfVwSybrIfLwgSuTaN1TjJZiKlG8FQn1/JId9tj\neDyHvHb7BsgBY6p9OctGw/NyLlwGNB7Yo1MKrolhHmTvHZbiLTaqWJHjKTBmlNtP\nP+z+v27U/RF7bh1enzBHnjv0lyKxPRBpq1rInl4PkxIpV7hjHIRw35EcOsXl0xQ+\nT9Cca2+RISmTFfRkSIPutlcj+rN3Xv98TmO/9gSqFopZsXVnJlS89IuWcZe8KJB3\n/HoBCJxAmZsmAsBoLvykv5AoZvCS2IkOaCSftfiWckHIpKPsZKr54G8faUx7XCWB\nNZluoxMOFeX+yA9y3Tqi5oorSkN+JHv9jj2NTUgbKQC/z9jItFt9xkRznwCEcuTx\nKgJOxoxBDz6chMgFF0tE6RXb4EBDiqsOKMSbmdRj1hg8TX6dYCSoNhwTPjXO0HqT\nFy4eSx0zUjklryX9y7K1EOoKCqdjwNLnKZLV8YdPLjQSeZ1KyWcorbnm0gL+dQua\n+OVTQg5OeNr7zWVRsfplzo0V0H1S9wIDAQABAoICAGL0e6kod/5HvESA419ooDd/\n4Eikj5iHTFIvAaHOpEjKKTuJ1UAsa8p9MLiUzJePQYxyDBWLGZjGf6wMmkpeaLa3\nI6tTHBMWCmoQTwrUNz63+ke7JY16iWEhL0sSmlOb++LlIJkDCCfSqcm1VE6xV+XO\nZEBiV+04A4rQDHusp0hscIa9CLoJpi9xylgb/7d4PCAgCVUQ5nxEcPMu6StXlXzv\nd1EDoZvtdev956ZEOycg/6GYESY3qHDkwuT8P6ug7JYC0/ubt/CaDeY3Ti6OXzdG\ne6OYgi/m62abnL/Yda/uv8o4zuBWdhxPMlC8emUQkjOkWurj6YGj7Rg1l8YYqVXr\nVVzRVq5bwL2FaDlQA//K2RGhRqScG3/M9qYJYRYNNPsVR3dBkewiqFnQcyyBOvIM\nc4xFoCxFbhf+TXRH/74W1wIVQH/w4A55PsYdZfm4g1DRFbbsGmo/tsfDq73tz2Pi\nsUXR2JzNW9Sj7q6F2RPiMrIV3E7apdCeylgGS9Uhf7ZNorBjhgKVkm0UxQeRkedk\nBvH/r3AqVqWc3IhJ/KadcBm+mPyStTcL452odXrpLqPyENTGsNy4MZ12QQbXa6uT\nRaRDhO7G6ocTR6UlUstsjiFe3LKSrXRlJdZ+4xJsquBBcTS6PYzeOr2ZnS+/QGpE\nR+iJHidYRJcCe2kP7KwRAoIBAQD4pUUUZfBaSFzEq17sWwpL8enDIJJAybIQ808L\nv7CuJeemZqiDh+La0htvd+/qZhZfEZKJPCiV1ml/o3ArwK5CnFK/ZLTjRC9ocm5c\nPOwJhKo52Y0FsazOLmVD6SqS5jKvl4Gvn+KkkGLZrvefAFWpthyLWHRYaDXeIUkd\ny6piGh99v3/9KZSN7gpZjdl1AdCQAR7tdOC1rQx7Nzl6gxpmJ1/SmRQ5XYYfJU5a\n6q1w2x+nt6fGE3BLJ/rxx5kKAJmwFeYlsuFAFkXypRjXtF66jewP/3j/lckArlXA\n3X3K17BJ8R/x5DGaybwk17Vv6UFMlFJSTYOyGbsUIWJVvWVZAoIBAQD2mCOMdSCH\nNx+2kFEEuisv9PBboMKs+bvIYJCNJ7/FGscGxr916/GAc/p2Sfp2Dweybxi5msUj\nOqidpw2hLDlGEioJyQxrvrk5Pa75ipZKZ8VnKIhlupIZ5FGJmVU/DDak+Drw6W0N\nAe5w6Q7Pbf1YcCle9ZRUN5MITdGMIWnLKUVF1ZbL153mOMizJRWa0XsnJjacLiXi\n/tYsSrBKaA4N+j0rOutN9FIF7PyjoZ+3YKEttmRYV5W3OtkLC82zORFWahX5K/3n\nmcSZLkG7n9dWQkcOvXgpPh+7f6u3MX0H0EWze0RhRp8h8fZiuVELyZL3evdWquwN\nK9i7s9pTL2DPAoIBAEObzLjLLxudaXwgjOL/rkEQOlvQU3RCY6SwQ+IR8Vyo+eAJ\nMfDx1gFh+AvLNPUrZRHcmVevf+meL3mBW1LKRZffIbDhFT5mn+1qkA+MkTHVXOP1\n/554vWAixW49zFG9PjL4o065zsqoZ/iA1tvpH2HSHtjU6G3RiDQqINN1OZMLP1zV\n4VtZHweoni/TnjlukONXKq2uhhtgPnCSh5KEa30zX57H+PPQNlPptPCLtzVkn6rf\nCUOWrYYCDP4JI9fQafmzOq0tgooGhGaB9ctRRCC9zl5bPO9iLxF8VdznXPj2xPyW\nD/WZ8tL/36S08qTHa/YCro+qfBDFZlUG7tIZeaECggEAeTrERzoR2se73InIetV3\ng+UcAT/gVR+VNOZcSjjfa2xFqkwtNjDfknHyERM/gajT9OHvOtge0Ln2yUKmTbUr\nFwq5BgSECbhC4SQ1EFMUndG0V4myvKhjST1Y5JewNAWyG5o5h9SKGxn2+iVpdYqy\nQTcq75c1681CiJORUB3hH9LTToi50M7YvqTt7jxuCaWwsMd1k4SQda8o5a92Sa4s\nMqzyQ318zt8tL+KZNWyw03s64flIDbJJVUImD+smnlSQ9HXFBbGd6q1K3K/D+xSS\nzcJZoqJ9H3F+MjSK284FlMDMc3dHX7dTZmHI6jIG6Q+ZI/ec/0uaLsN+kpDR5ZFm\nOwKCAQEA11nK0Orlb85QRRNWIp2TiclXPBK/x6fhtDDEtyIfNtw0cVLr8EjABepP\n12H57Hs1f9qLeWFa20dbTh2OeEvOnqzdXR1/27sjSc8UqreEwzrv/bkmBEF92xxy\n66LIr0o2S72ZT6E6IImJ2N563GrOWla7LpQN5V64RAc3C2vb5DiL70oCE0Qpb9Vn\nM69t86apMrAxkUxVJAWLRBd9fbYyzJgTW61tFqXWTZpiz6bhuWApSEzaHcL3/f5l\n3qibvYTFj6CIqcdHA6Sy+UTEyb7zWnFwWVNEwAadsMmq45mhdoFjlm/5onPrpj+l\n1LXZrtjAB4U+/F7um6YyAavpHYq9hg==\n-----END PRIVATE KEY-----\n","ep":["UDP:443","UDP:7011","TCP:443"],"cipher":"AES-256-CBC","auth":"SHA256","frame":1,"ping":10,"eku":true},"external":{"hostname":"${id}.lazerpenguin.com"}}],"defaults":{"username":"user@mail.com","pool":"us","preset":"default"},"categories":[{"name":"","groups":[{"country":"AU","pools":[{"id":"au","country":"AU","addrs":[2419074099,1730890649,2419074100,759986119,1729706859,2419074098,1729706861,1815991505,2501684924,1815961795,771247475,771247476,759110314,760081843,1729706860,759984655]}]},{"country":"BR","pools":[{"id":"br","country":"BR","addrs":[2839139670,2839139830,2839139834,2839134177,2839139717,3210757735,2839139682,2839139761,2839139642,2839139823,2839139744,2839134182,3171002503,2839139757,2839127404,2839139649,2973144547,2973144602,2839139808,2839133981]}]},{"country":"CA","pools":[{"id":"ca","country":"CA","addrs":[1152893120,2994793302,2994793366,2388496732,2388498202,1152893591,2328210245,1152892958,2994792639,1152895635,2328210821,1152893065,2388496678,2388500197,2783126650,2388498757,2994794008,1152896643,1152896878,1152896999]}]},{"country":"DK","pools":[{"id":"dk","country":"DK","addrs":[628658435,3119863004,3119862998,3119862988,3119862990,3119862996,3119862980,3119862978,628658436,628658437,628658468,628658482,3119862992,628658469,3119863000,628658475,628658476,3119863002,3119862982,628658484]}]},{"country":"FR","pools":[{"id":"fr","country":"FR","addrs":[1053975472,3485270068,1053975425,3281710428,3281714012,1053975442,1053975459,3281711425,3485270067,1053975483,3485270072,1053982180,3281711823,3281710486,1053975424,3281714011,1053975465,3281706616,3281708745,1053975513]}]},{"country":"DE","pools":[{"id":"de","country":"DE","addrs":[2769701527,1761091376,2769701523,1210316649,2769701485,2261902308,1210316648,1210316636,2649122243,2769701488,1210316612,1210316613,1210316637,1210316616,1210316638,2769702727,1210316635,1210316634,1210316614,1210316618]}]},{"country":"HK","pools":[{"id":"hk","country":"HK","addrs":[453044406,3510287477,1168229243,1732998542,453044255,453044429,1168229244,1168229246,453044289,3510287873,453044446,1168229245,453044414]}]},{"country":"IN","pools":[{"id":"in","country":"IN","addrs":[1743034856,1743034853,1743034854,1743034855,1743034852,2388515001,2261882120,2335904479,2335914472,1743034857,2388515448,3468527071,1152867647]}]},{"country":"IE","pools":[{"id":"ie","country":"IE","addrs":[3110895643,3110895638,3110895637,3648221405,3110895641,3110895640,3110895897,3110895636,3110895896,3110895642,3110895939,3110895639,3648225069,3648221409,3648221406]}]},{"country":"IT","pools":[{"id":"it","country":"IT","addrs":[2961068907,3230760731,3230760723,3230760725,2961068921,3118024484,3118024486,1603085431,2961068905,3230760724,2961068908,2961068989,3230760730,1382423115,3230760708,3230760709,3230760716,1382423117,1382423126,3230760715]}]},{"country":"JP","pools":[{"id":"jp","country":"JP","addrs":[1732998669,1116032008,1116032006,1732998785,1732998832,1732998815,1732998767,1732998871,1116032005,1116032009,1116032004,1732998713,1732998668,1116032007,1732998779,1116032003]}]},{"country":"MX","pools":[{"id":"mx","country":"MX","addrs":[2839108299,2839108237,2839108309,2839108302,2839094108,2839108232,2839108235,2839085301,2839108254,2839108265,2839108267,2839108283,2839108286,2839108290,2839108293,2839085257,2839094103,2839094090,2839108313,2839108332]}]},{"country":"NL","pools":[{"id":"nl","country":"NL","addrs":[2808293187,2808293191,2388520623,629866505,2461631800,2808294563,2928281726,1761106511,629868492,2808294808,3468496404,2671888560,629872508,2461633693,3165019796,2461632493,2388520613,2928280877,1761105940,1388578180]}]},{"country":"NZ","pools":[{"id":"nz","country":"NZ","addrs":[1732999012,1732999038,1732999022,1732999027,1732999043,1732999029,3029723108,1732998922,3029723109,3029723107,1732999036,1732999028]}]},{"country":"NO","pools":[{"id":"no","country":"NO","addrs":[628659469,628659539,628659467,3120390608,3120390617,628659538,1382423395,3120390612,3120390607,3120390615,3120390609,628659540,3120390610,628659470,3120390605,3120390611,3120390614,1382423394,1382423397,3120390606]}]},{"country":"RO","pools":[{"id":"ro","country":"RO","addrs":[1588630758,1449728346,2812311417,2812311413,2812311443,2812311444,3116569431,2812311446,3116569433,2812311415,1588630755,2812311378,3116569430,2812311370,2812311445,2812311449,2812311362,1449728347,3116569432,2812311416]}]},{"country":"SG","pools":[{"id":"sg","country":"SG","addrs":[2338552449,2769747074,2338552211,2338552210,2338552209,2261872208,2338552212,2261869568,2261870588,1152902806]}]},{"country":"ES","pools":[{"id":"es","country":"ES","addrs":[3261294597,3285085140,3118890051,3118890171,628659267,3118890189,3118890181,3118890197,3272356603,3118890193,3118890059,3118890167,3118890191,3118890170,3118890052,628659282,3118890169,3285085142,3118890054,3118890195]}]},{"country":"SE","pools":[{"id":"se","country":"SE","addrs":[1603257294,3258710634,3119940098,3258710636,3258710550,520994603,3118006379,3119939589,3119940202,3258710549,1603257295,3258710554,628660732,1603257254,628660685,628660686,3119940102,520994605,3119940104,3119940101]}]},{"country":"CH","pools":[{"id":"ch","country":"CH","addrs":[1382422741,1535412260,3287471494,3287471496,1535412332,1382422756,1535412252,1535412259,1535412323,1382422740,1382422758,1382422760,1535412324,1535412253,1382422739,3287471497,3287471491,1535412254,1382422744,3287471492]}]},{"country":"GB","pools":[{"id":"uk","country":"GB","addrs":[1836796501,1836796510,1836796617,1836796601,1489679591,1836796606,1836796608,1836796512,1489679608,1836796598,1836796621,1836796491,1836796495,1836796497,1836796612,1836796597,1836796590,1489679589,1836796605,1836796609]}]},{"country":"US","pools":[{"id":"us","country":"US","addrs":[2733838328,2733872848,2649108493,3237059867,2671855868,2673446249,2783135505,1761096715,3237080605,2673448988,2673448278,1806361431,2733842922,3237061524,2673446195,1806365609,2769717596,3237066643,3334957697,2733870306]}]}]}],"build":1779,"name":"TunnelBear"}
\ No newline at end of file
diff --git a/Passepartout/Resources/Web/net/vyprvpn.json b/Passepartout/Resources/Web/net/vyprvpn.json
deleted file mode 100644
index 79519418..00000000
--- a/Passepartout/Resources/Web/net/vyprvpn.json
+++ /dev/null
@@ -1 +0,0 @@
-{"presets":[{"id":"default","name":"Default","comment":"256-bit encryption","cfg":{"ca":"-----BEGIN CERTIFICATE-----\nMIIEpDCCA4ygAwIBAgIJANd2Uwt7SabsMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYD\nVQQGEwJLWTEUMBIGA1UECBMLR3JhbmRDYXltYW4xEzARBgNVBAcTCkdlb3JnZVRv\nd24xFzAVBgNVBAoTDkdvbGRlbkZyb2ctSW5jMRowGAYDVQQDExFHb2xkZW5Gcm9n\nLUluYyBDQTEjMCEGCSqGSIb3DQEJARYUYWRtaW5AZ29sZGVuZnJvZy5jb20wHhcN\nMTAwNDA5MjExOTIxWhcNMjAwNDA2MjExOTIxWjCBkjELMAkGA1UEBhMCS1kxFDAS\nBgNVBAgTC0dyYW5kQ2F5bWFuMRMwEQYDVQQHEwpHZW9yZ2VUb3duMRcwFQYDVQQK\nEw5Hb2xkZW5Gcm9nLUluYzEaMBgGA1UEAxMRR29sZGVuRnJvZy1JbmMgQ0ExIzAh\nBgkqhkiG9w0BCQEWFGFkbWluQGdvbGRlbmZyb2cuY29tMIIBIjANBgkqhkiG9w0B\nAQEFAAOCAQ8AMIIBCgKCAQEA37JesfCwOj69el0AmqwXyiUJ2Bm+q0+eR9hYZEk7\npVoj5dF9RrKirZyCM/9zEvON5z4pZMYjhpzrq6eiLu3j1xV6lX73Hg0dcflweM5i\nqxFAHCwEFIiMpPwOgLV399sfHCuda11boIPE4SRooxUPEju908AGg/i+egntvvR2\nd7pnZl2SCJ1sxlbeAAkYjX6EXmIBFyJdmry1y05BtpdTgPmTlJ0cMj7DlU+2gehP\nss/q6YYRAhrKtlZwxeunc+RD04ieah+boYU0CBZinK2ERRuAjx3hbCE4b0S6eizr\nQmSuGFNu6Ghx+E1xasyl1Tz/fHgHl3P93Jf0tFov7uuygQIDAQABo4H6MIH3MB0G\nA1UdDgQWBBTh9HiMh5RnRVIt/ktXddiGkDkXBTCBxwYDVR0jBIG/MIG8gBTh9HiM\nh5RnRVIt/ktXddiGkDkXBaGBmKSBlTCBkjELMAkGA1UEBhMCS1kxFDASBgNVBAgT\nC0dyYW5kQ2F5bWFuMRMwEQYDVQQHEwpHZW9yZ2VUb3duMRcwFQYDVQQKEw5Hb2xk\nZW5Gcm9nLUluYzEaMBgGA1UEAxMRR29sZGVuRnJvZy1JbmMgQ0ExIzAhBgkqhkiG\n9w0BCQEWFGFkbWluQGdvbGRlbmZyb2cuY29tggkA13ZTC3tJpuwwDAYDVR0TBAUw\nAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAwihrN0QNE19RRvGywBvsYDmzmM5G8ta5\n8yB+02Mzbm0KuVxnPJaoVy4L4WocAnqLeKfmpYWUid1MPwDPtwtQ00U7QmRBRNLU\nhS6Bth1wXtuDvkRoHgymSvg1+wonJNpv/VquNgwt7XbC9oOjVEd9lbUd+ttxzboI\n8P1ci6+I861PylA0DOv9j5bbn1oE0hP8wDv3bTklEa612zzEVnnfgw+ErVnkrnk8\n8fTiv6NZtHgUOllMq7ymlV7ut+BPp20rjBdOCNn2Q7dNCKIkI45qkwHtXjzFXIxz\nGq3tLVeC54g7XZIc7X0S9avgAE7h9SuRYmsSzvLTtiP1obMCHB5ebQ==\n-----END CERTIFICATE-----\n","frame":1,"compression":1,"ping":10,"eku":true,"ep":["UDP:443"],"cipher":"AES-256-GCM"},"external":{"hostname":"${id}.vpn.goldenfrog.com"}}],"defaults":{"username":"user@mail.com","pool":"us","preset":"default"},"categories":[{"name":"","groups":[{"country":"AE","area":"Dubai","pools":[{"id":"ae1","country":"AE","area":"Dubai","addrs":[3512955666]}]},{"country":"AR","area":"Buenos Aires","pools":[{"id":"ar1","country":"AR","area":"Buenos Aires","addrs":[3512954131]}]},{"country":"AT","area":"Vienna","pools":[{"id":"at1","country":"AT","area":"Vienna","addrs":[2153406482]}]},{"country":"AU","area":"Sydney","pools":[{"id":"au1","country":"AU","area":"Sydney","addrs":[3512956178]}]},{"country":"AU","area":"Melbourne","pools":[{"id":"au2","country":"AU","area":"Melbourne","addrs":[3512956179]}]},{"country":"AU","area":"Perth","pools":[{"id":"au3","country":"AU","area":"Perth","addrs":[3512926483]}]},{"country":"BE","area":"Brussels","pools":[{"id":"be1","country":"BE","area":"Brussels","addrs":[2153406484]}]},{"country":"BG","area":"Sofia","pools":[{"id":"bg1","country":"BG","area":"Sofia","addrs":[2153406486]}]},{"country":"BH","area":"Manama","pools":[{"id":"bh1","country":"BH","area":"Manama","addrs":[3512955667]}]},{"country":"BR","area":"São Paulo","pools":[{"id":"br1","country":"BR","area":"São Paulo","addrs":[3512954132]}]},{"country":"CA","area":"Toronto","pools":[{"id":"ca1","country":"CA","area":"Toronto","addrs":[3512931602]}]},{"country":"CH","area":"Zurich","pools":[{"id":"ch1","country":"CH","area":"Zurich","addrs":[3512941586]}]},{"country":"CO","area":"Bogotá","pools":[{"id":"co1","country":"CO","area":"Bogotá","addrs":[3512954133]}]},{"country":"CR","area":"San José","pools":[{"id":"cr1","country":"CR","area":"San José","addrs":[3512954134]}]},{"country":"CZ","area":"Prague","pools":[{"id":"cz1","country":"CZ","area":"Prague","addrs":[2153406488]}]},{"country":"DE","area":"Frankfurt","pools":[{"id":"de1","country":"DE","area":"Frankfurt","addrs":[2153406490]}]},{"country":"DK","area":"Copenhagen","pools":[{"id":"dk1","country":"DK","area":"Copenhagen","addrs":[2153406492]}]},{"country":"DZ","area":"Algiers","pools":[{"id":"dz1","country":"DZ","area":"Algiers","addrs":[3512945428]}]},{"country":"EG","area":"Cairo","pools":[{"id":"eg1","country":"EG","area":"Cairo","addrs":[3512945429]}]},{"country":"ES","area":"Madrid","pools":[{"id":"es1","country":"ES","area":"Madrid","addrs":[2153406494]}]},{"country":"EU","area":"Amsterdam","pools":[{"id":"eu1","country":"EU","area":"Amsterdam","addrs":[2153406480]}]},{"country":"FI","area":"Helsinki","pools":[{"id":"fi1","country":"FI","area":"Helsinki","addrs":[2153406496]}]},{"country":"FR","area":"Paris","pools":[{"id":"fr1","country":"FR","area":"Paris","addrs":[2153406498]}]},{"country":"GR","area":"Athens","pools":[{"id":"gr1","country":"GR","area":"Athens","addrs":[3512945430]}]},{"country":"HK","area":"Hong Kong","pools":[{"id":"hk1","country":"HK","area":"Hong Kong","addrs":[2153440018]}]},{"country":"ID","area":"Jakarta","pools":[{"id":"id1","country":"ID","area":"Jakarta","addrs":[3512926484]}]},{"country":"IE","area":"Dublin","pools":[{"id":"ie1","country":"IE","area":"Dublin","addrs":[3512931859]}]},{"country":"IL","area":"Tel Aviv","pools":[{"id":"il1","country":"IL","area":"Tel Aviv","addrs":[3512945426]}]},{"country":"IN","area":"Mumbai","pools":[{"id":"in1","country":"IN","area":"Mumbai","addrs":[3512955668]}]},{"country":"IS","area":"Reykjavík","pools":[{"id":"is1","country":"IS","area":"Reykjavík","addrs":[3512931860]}]},{"country":"IT","area":"Rome","pools":[{"id":"it1","country":"IT","area":"Rome","addrs":[2153406500]}]},{"country":"JP","area":"Tokyo","pools":[{"id":"jp1","country":"JP","area":"Tokyo","addrs":[3512955154]}]},{"country":"KR","area":"Seoul","pools":[{"id":"kr1","country":"KR","area":"Seoul","addrs":[3512955155]}]},{"country":"LI","area":"Schaan","pools":[{"id":"li1","country":"LI","area":"Schaan","addrs":[2153406502]}]},{"country":"LT","area":"Vilnius","pools":[{"id":"lt1","country":"LT","area":"Vilnius","addrs":[2153406504]}]},{"country":"LU","area":"Luxembourg City","pools":[{"id":"lu1","country":"LU","area":"Luxembourg City","addrs":[2153406506]}]},{"country":"LV","area":"Riga","pools":[{"id":"lv1","country":"LV","area":"Riga","addrs":[2153406508]}]},{"country":"MH","area":"Majuro","pools":[{"id":"mh1","country":"MH","area":"Majuro","addrs":[3512926489]}]},{"country":"MO","area":"Macao","pools":[{"id":"mo1","country":"MO","area":"Macao","addrs":[2153440036]}]},{"country":"MV","area":"Malé","pools":[{"id":"mv1","country":"MV","area":"Malé","addrs":[3512926490]}]},{"country":"MX","area":"Mexico City","pools":[{"id":"mx1","country":"MX","area":"Mexico City","addrs":[3512941843]}]},{"country":"MY","area":"Kuala Lumpur","pools":[{"id":"my1","country":"MY","area":"Kuala Lumpur","addrs":[3512926485]}]},{"country":"NO","area":"Oslo","pools":[{"id":"no1","country":"NO","area":"Oslo","addrs":[2153406510]}]},{"country":"NZ","area":"Auckland","pools":[{"id":"nz1","country":"NZ","area":"Auckland","addrs":[3512956180]}]},{"country":"PA","area":"Panama City","pools":[{"id":"pa1","country":"PA","area":"Panama City","addrs":[3512954135]}]},{"country":"PH","area":"Manila","pools":[{"id":"ph1","country":"PH","area":"Manila","addrs":[3512926486]}]},{"country":"PK","area":"Karachi","pools":[{"id":"pk1","country":"PK","area":"Karachi","addrs":[3512945431]}]},{"country":"PL","area":"Warsaw","pools":[{"id":"pl1","country":"PL","area":"Warsaw","addrs":[2153406512]}]},{"country":"PT","area":"Lisbon","pools":[{"id":"pt1","country":"PT","area":"Lisbon","addrs":[2153406514]}]},{"country":"QA","area":"Doha","pools":[{"id":"qa1","country":"QA","area":"Doha","addrs":[3512955669]}]},{"country":"RO","area":"Bucharest","pools":[{"id":"ro1","country":"RO","area":"Bucharest","addrs":[2153406516]}]},{"country":"RU","area":"Moscow","pools":[{"id":"ru1","country":"RU","area":"Moscow","addrs":[2153406518]}]},{"country":"SA","area":"Riyadh","pools":[{"id":"sa1","country":"SA","area":"Riyadh","addrs":[3512955670]}]},{"country":"SE","area":"Stockholm","pools":[{"id":"se1","country":"SE","area":"Stockholm","addrs":[2153406520]}]},{"country":"SG","area":"Singapore","pools":[{"id":"sg1","country":"SG","area":"Singapore","addrs":[3512926482]}]},{"country":"SI","area":"Ljubljana","pools":[{"id":"si1","country":"SI","area":"Ljubljana","addrs":[2153406522]}]},{"country":"SK","area":"Bratislava","pools":[{"id":"sk1","country":"SK","area":"Bratislava","addrs":[2153406524]}]},{"country":"SV","area":"San Salvador","pools":[{"id":"sv1","country":"SV","area":"San Salvador","addrs":[3512941844]}]},{"country":"TH","area":"Bangkok","pools":[{"id":"th1","country":"TH","area":"Bangkok","addrs":[3512926487]}]},{"country":"TR","area":"Istanbul","pools":[{"id":"tr1","country":"TR","area":"Istanbul","addrs":[2153406526]}]},{"country":"TW","area":"Taipei","pools":[{"id":"tw1","country":"TW","area":"Taipei","addrs":[2153440027]}]},{"country":"UA","area":"Kiev","pools":[{"id":"ua1","country":"UA","area":"Kiev","addrs":[2153406528]}]},{"country":"GB","area":"London","pools":[{"id":"uk1","country":"GB","area":"London","addrs":[3512931858]}]},{"country":"US","area":"Los Angeles","pools":[{"id":"us1","country":"US","area":"Los Angeles","addrs":[3512943378]}]},{"country":"US","area":"Washington","pools":[{"id":"us2","country":"US","area":"Washington","addrs":[3512942098]}]},{"country":"US","area":"Austin","pools":[{"id":"us3","country":"US","area":"Austin","addrs":[3512941842]}]},{"country":"US","area":"Miami","pools":[{"id":"us4","country":"US","area":"Miami","addrs":[3512954130]}]},{"country":"US","area":"New York City","pools":[{"id":"us5","country":"US","area":"New York City","addrs":[3512942354]}]},{"country":"US","area":"Chicago","pools":[{"id":"us6","country":"US","area":"Chicago","addrs":[3512950034]}]},{"country":"US","area":"San Francisco","pools":[{"id":"us7","country":"US","area":"San Francisco","addrs":[3512950546]}]},{"country":"US","area":"Seattle","pools":[{"id":"us8","country":"US","area":"Seattle","addrs":[3512950290]}]},{"country":"UY","area":"Montevideo","pools":[{"id":"uy1","country":"UY","area":"Montevideo","addrs":[3512941845]}]},{"country":"VN","area":"Hanoi","pools":[{"id":"vn1","country":"VN","area":"Hanoi","addrs":[3512926488]}]}]}],"build":1779,"name":"VyprVPN"}
\ No newline at end of file
diff --git a/Passepartout/Resources/Web/net/windscribe.json b/Passepartout/Resources/Web/net/windscribe.json
deleted file mode 100644
index 3f541109..00000000
--- a/Passepartout/Resources/Web/net/windscribe.json
+++ /dev/null
@@ -1 +0,0 @@
-{"presets":[{"id":"default","name":"Default","comment":"256-bit encryption","cfg":{"ca":"-----BEGIN CERTIFICATE-----\r\nMIIF3DCCA8SgAwIBAgIJAMsOivWTmu9fMA0GCSqGSIb3DQEBCwUAMHsxCzAJBgNV\r\nBAYTAkNBMQswCQYDVQQIDAJPTjEQMA4GA1UEBwwHVG9yb250bzEbMBkGA1UECgwS\r\nV2luZHNjcmliZSBMaW1pdGVkMRMwEQYDVQQLDApPcGVyYXRpb25zMRswGQYDVQQD\r\nDBJXaW5kc2NyaWJlIE5vZGUgQ0EwHhcNMTYwMzA5MDMyNjIwWhcNNDAxMDI5MDMy\r\nNjIwWjB7MQswCQYDVQQGEwJDQTELMAkGA1UECAwCT04xEDAOBgNVBAcMB1Rvcm9u\r\ndG8xGzAZBgNVBAoMEldpbmRzY3JpYmUgTGltaXRlZDETMBEGA1UECwwKT3BlcmF0\r\naW9uczEbMBkGA1UEAwwSV2luZHNjcmliZSBOb2RlIENBMIICIjANBgkqhkiG9w0B\r\nAQEFAAOCAg8AMIICCgKCAgEAruBtLR1Vufd71LeQEqChgHS4AQJ0fSRner0gmZPE\r\nr2TL5uWboOEWXFFoEUTthF+P/N8yy3xRZ8HhG/zKlmJ1xw+7KZRbTADD6shJPj3/\r\nuvTIO80sU+9LmsyKSWuPhQ1NkgNA7rrMTfz9eHJ2MVDs4XCpYWyX9iuAQrHSY6aP\r\nq+4TpCbUgprkM3Gwjh9RSt9IoDoc4CF2bWSaVepUcL9yz/SXLPzFx2OT9rFrDhL3\r\nryHRzJQ/tA+VD8A7lo8bhOcDqiXgEFmVOZNMLw+r167Qq1Ck7X86yr2mnW/6HK2g\r\nJOvY0/SPKukfGJAiYZKdG+fe4ekyYcAVhDfPJg7rF9wUqPwUzejJyAs1K18JwX94\r\nY8fnD6vQobjpC3qfHtwQP7Uj2AcI6QC8ytWDegV6UIkHXAMXBQSX5suSQoE11deG\r\n32cy7nyp5vhgy31rTyNoopqlcCAhPm6k0jVVQbvXhLcpTSL8iCCoMdrP28i/xsfv\r\nktBAkl5giHMdK6hxqWgPI+Bx9uPIhRp3fJ2z8AgFm8g1ARB2ZzQ+OZZ2RUIkJuUK\r\nhi2kUhgKSAQ+eF89aoqDjp/J1miZqGRzt4DovSZfQOeL01RkKHEibAPYCfgHG2ZS\r\nwoLoeaxE2vNZiX4dpXiOQYTOIXOwEPZzPvfTQf9T4Kxvx3jzQnt3PzjlMCqKk3Ai\r\npm8CAwEAAaNjMGEwHQYDVR0OBBYEFEH2v9F2z938Ebngsj9RkVSSgs45MB8GA1Ud\r\nIwQYMBaAFEH2v9F2z938Ebngsj9RkVSSgs45MA8GA1UdEwEB/wQFMAMBAf8wDgYD\r\nVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQAgI6NgYkVo5rB6yKStgHjj\r\nZsINsgEvoMuHwkM0YaV22XtKNiHdsiOmY/PGCRemFobTEHk5XHcvcOTWv/D1qVf8\r\nfI21WAoNQVH7h8KEsr4uMGKCB6Lu8l6xALXRMjo1xb6JKBWXwIAzUu691rUD2exT\r\n1E+A5t+xw+gzqV8rWTMIoUaH7O1EKjN6ryGW71Khiik8/ETrP3YT32ZbS2P902iM\r\nKw9rpmuS0wWhnO5k/iO/6YNA1ZMV5JG5oZvZQYEDk7enLD9HvqazofMuy/Sz/n62\r\nZCDdQsnabzxl04wwv5Y3JZbV/6bOM520GgdJEoDxviY05ax2Mz05otyBzrAVjFw9\r\nRZt/Ls8ATifu9BusZ2ootvscdIuE3x+ZCl5lvANcFEnvgGw0qpCeASLpsfxwq1dR\r\ngIn7BOiTauFv4eoeFAQvCD+l+EKGWKu3M2y19DgYX94N2+Xs2bwChroaO5e4iFem\r\nMLMuWKZvYgnqS9OAtRSYWbNX/wliiPz7u13yj+qSWgMfu8WPYNQlMZJXuGWUvKLE\r\nXCUExlu7/o8D4HpsVs30E0pUdaqN0vExB1KegxPWWrmLcYnPG3knXpkC3ZBZ5P/e\r\nl/2eyhZRy9ydiITF8gM3L08E8aeqvzZMw2FDSmousydIzlXgeS5VuEf+lUFA2h8o\r\nZYGQgrLt+ot8MbLhJlkp4Q==\r\n-----END CERTIFICATE-----","wrap":{"strategy":"auth","key":{"dir":1,"data":"WAGSalesLOJ+Pf0d1u+CBC2CvU8/ACEpb1dzT28epxSmYjhFVBxLDD3qCgUP5nRstm36sUzaJ+WuCdfBVapVTzmfpKhj8OjBr3h+XGAqgB06LsQeOVqXjVZylFf+YQLX2ekRmqg2QyELM8Z4+dQQnjFUrJx1nkkMswmzGc9wjK6D3a3DBgp6JlZNGiRBHNVS/mYg6ha3VWl6T8Xm6dDPwMXEoYdGhUKQRqQkwCbbZy5MLEkomAUrpZEo1GIAtA+IACeotmEKTVWb3JNG0zoKawjnXH/UMZKxYr/QrvDHFrMVhIJ2k/Z2+aUEcSNGbwZU6t40lyWGsxxs5+OV9LR4yw=="}},"ep":["UDP:443","UDP:80","UDP:53","UDP:1194","UDP:54783","TCP:443","TCP:587","TCP:21","TCP:22","TCP:80","TCP:143","TCP:3306","TCP:8080","TCP:54783","TCP:1194"],"cipher":"AES-256-GCM","auth":"SHA512","frame":1,"compression":1,"eku":true},"external":{"hostname":"${id}.windscribe.com"}}],"defaults":{"username":"abc1efg2-hijk345","pool":"us-central","preset":"default"},"categories":[{"name":"","groups":[{"country":"AL","pools":[{"id":"al","country":"AL","addrs":[531339531]}]},{"country":"AR","pools":[{"id":"ar","country":"AR","addrs":[3194612786,3194612755,3194612768,2818180729,3361052782]}]},{"country":"AT","pools":[{"id":"at","country":"AT","addrs":[3644882699]}]},{"country":"AU","pools":[{"id":"au","country":"AU","addrs":[762958240,2302409987,762958544,1732129488,762957984]}]},{"country":"AZ","pools":[{"id":"az","country":"AZ","addrs":[1434729851]}]},{"country":"BA","pools":[{"id":"ba","country":"BA","addrs":[3110273816]}]},{"country":"BE","pools":[{"id":"be","country":"BE","addrs":[3118994819,3267099539]}]},{"country":"BG","pools":[{"id":"bg","country":"BG","addrs":[3109994531]}]},{"country":"BR","pools":[{"id":"br","country":"BR","addrs":[2973143108,3171003404,2973978683]}]},{"country":"CA","pools":[{"id":"ca","country":"CA","addrs":[3485277955,3331364227,2915516819,3331364259,1761500171,2915516883,3331364323,3091977307,1761500251,1111921744]}]},{"country":"CH","pools":[{"id":"ch","country":"CH","addrs":[520567282,3114053555]}]},{"country":"CO","pools":[{"id":"co","country":"CO","addrs":[2323237835]}]},{"country":"CZ","pools":[{"id":"cz","country":"CZ","addrs":[3114053131]}]},{"country":"DE","pools":[{"id":"de","country":"DE","addrs":[3112351939,1509507347]}]},{"country":"DK","pools":[{"id":"dk","country":"DK","addrs":[2254083475,3117342915]}]},{"country":"EE","pools":[{"id":"ee","country":"EE","addrs":[773247995]}]},{"country":"ES","pools":[{"id":"es","country":"ES","addrs":[1508815403,3120391043]}]},{"country":"FI","pools":[{"id":"fi","country":"FI","addrs":[3110563533,3111146211]}]},{"country":"FR","pools":[{"id":"fr","country":"FR","addrs":[3114053051,3485270083,1382421027]}]},{"country":"GR","pools":[{"id":"gr","country":"GR","addrs":[1315710619,3118612591,1315710690]}]},{"country":"HK","pools":[{"id":"hk","country":"HK","addrs":[1728759139,1168229251]}]},{"country":"HR","pools":[{"id":"hr","country":"HR","addrs":[1426733308]}]},{"country":"HU","pools":[{"id":"hu","country":"HU","addrs":[3110648619]}]},{"country":"ID","pools":[{"id":"id","country":"ID","addrs":[1742994633,763332187]}]},{"country":"IE","pools":[{"id":"ie","country":"IE","addrs":[3110656770,3105417362]}]},{"country":"IL","pools":[{"id":"il","country":"IL","addrs":[2691956763,3116354955]}]},{"country":"IN","pools":[{"id":"in","country":"IN","addrs":[2837858316,1743024371,2837857468,1729882203,2837858318]}]},{"country":"IS","pools":[{"id":"is","country":"IS","addrs":[1390250790]}]},{"country":"IT","pools":[{"id":"it","country":"IT","addrs":[1382423091,1382421875]}]},{"country":"JP","pools":[{"id":"jp","country":"JP","addrs":[3247706355,3404670705,1168229507]}]},{"country":"KR","pools":[{"id":"kr","country":"KR","addrs":[3672657075,1742003971]}]},{"country":"LT","pools":[{"id":"lt","country":"LT","addrs":[782674993]}]},{"country":"LV","pools":[{"id":"lv","country":"LV","addrs":[1442727959]}]},{"country":"MD","pools":[{"id":"md","country":"MD","addrs":[2997850235]}]},{"country":"MX","pools":[{"id":"mx","country":"MX","addrs":[2415868227,3380837739]}]},{"country":"MY","pools":[{"id":"my","country":"MY","addrs":[1868206410,1735064095]}]},{"country":"NL","pools":[{"id":"nl","country":"NL","addrs":[2709602883,1807044227,3120390147,3117722499,782667618]}]},{"country":"NO","pools":[{"id":"no","country":"NO","addrs":[3117343107]}]},{"country":"NZ","pools":[{"id":"nz","country":"NZ","addrs":[1732129137]}]},{"country":"PH","pools":[{"id":"ph","country":"PH","addrs":[1734803574]}]},{"country":"PL","pools":[{"id":"pl","country":"PL","addrs":[92604580,3119830563,861112384]}]},{"country":"PT","pools":[{"id":"pt","country":"PT","addrs":[1580076503]}]},{"country":"RO","pools":[{"id":"ro","country":"RO","addrs":[1496213395]}]},{"country":"RS","pools":[{"id":"rs","country":"RS","addrs":[2207866907,2372036371]}]},{"country":"RU","pools":[{"id":"ru","country":"RU","addrs":[95571987,84418067,1546995819,3105271684,1607829548,3588800515]}]},{"country":"SE","pools":[{"id":"se","country":"SE","addrs":[3283461761,1334725830,520994627]}]},{"country":"SG","pools":[{"id":"sg","country":"SG","addrs":[1732128992,3116922275,1382422915]}]},{"country":"SI","pools":[{"id":"si","country":"SI","addrs":[3113503070]}]},{"country":"SK","pools":[{"id":"sk","country":"SK","addrs":[3119863043]}]},{"country":"TH","pools":[{"id":"th","country":"TH","addrs":[469664477]}]},{"country":"TN","pools":[{"id":"tn","country":"TN","addrs":[703005975]}]},{"country":"TR","pools":[{"id":"tr","country":"TR","addrs":[763066123,763066012]}]},{"country":"TW","pools":[{"id":"tw","country":"TW","addrs":[3527131181,2112064652]}]},{"country":"UA","pools":[{"id":"ua","country":"UA","addrs":[1299736129,3256659489]}]},{"country":"GB","pools":[{"id":"uk","country":"GB","addrs":[1365036869,635182347,1508808421,1508804485,3117721733,1508803459,3104937347]}]},{"country":"US","area":"CENTRAL","pools":[{"id":"us-central","country":"US","area":"CENTRAL","addrs":[2455290243,1753226531,1158438467,3485276931,2429581507,3583970883,1805000579,3225812291,1754253315,1753289219,3232497443,2709604035,3485277699,3454696835,3485275907,3425464451,1805735555,1753289347,3325525443,3455817547,3225812547,1079318531,3485276675]}]},{"country":"US","area":"EAST","pools":[{"id":"us-east","country":"US","area":"EAST","addrs":[1156264675,3485270531,2918499344,1753255427,3485275651,1118512483,3488897455,400723395,1759477699,3118995139,1118512259,3485276419,2812308803,2918499456,3485277443,400721155,646215395,2905351235,2812324867,3118995075]}]},{"country":"US","area":"WEST","pools":[{"id":"us-west","country":"US","area":"WEST","addrs":[3485276163,3626841475,1759133185,3495404835,1116032643,628659107,1116031587,1116031619,1759133201,2915916867,3485276227,1759417219,1382424131,3325306499,3454696579,3119302691,3583971139]}]},{"country":"VN","pools":[{"id":"vn","country":"VN","addrs":[1728662725]}]},{"country":"ZA","pools":[{"id":"za","country":"ZA","addrs":[2773088347,3321011253,3321011691]}]}]},{"name":"windflix","groups":[{"country":"CA","pools":[{"id":"wf-ca","country":"CA","addrs":[2734589123,1761500259]}]},{"country":"JP","pools":[{"id":"wf-jp","country":"JP","addrs":[1736963088,1736963104]}]},{"country":"GB","pools":[{"id":"wf-uk","country":"GB","addrs":[3119186049,3119185923]}]},{"country":"US","pools":[{"id":"wf-us","country":"US","addrs":[396476419,396476609,396476641,396476544,396476482]}]}]}],"build":1779,"name":"Windscribe"}
\ No newline at end of file
diff --git a/Passepartout/Resources/de.lproj/Intents.strings b/Passepartout/Resources/de.lproj/Intents.strings
deleted file mode 100644
index ffa34e0d..00000000
--- a/Passepartout/Resources/de.lproj/Intents.strings
+++ /dev/null
@@ -1,39 +0,0 @@
-"0jRWn5" = "Entfernt Mobilfunknetz von vertrauten Netzwerken";
-
-"1ZRTCZ" = "VPN deaktivieren";
-
-"66bZBE" = "Mit Anbieter ${providerId}";
-
-"7eoAss" = "Entferne aktuelles WLAN von vertrauten Netzwerken";
-
-"9GpJt5" = "Fügt Mobilnetz zu vertrauten Netzwerken hinzu";
-
-"BKxs8X" = "Fügt aktuelles WLAN zu vertrauten Netzwerken hinzu";
-
-"H4taev" = "Mobilfunknetz vertrauen";
-
-"KjkCfU" = "Connects to a specific location of a provider profile";
-
-"LA99yM" = "Verbinde mit VPN";
-
-"U6o81V" = "Verbinde mit ${profileId}";
-
-"WnTPFg" = "Verbinde mit ${poolName}";
-
-"eQ1yzr" = "Deaktiviert den VPN-Dienst";
-
-"eXXb2z" = "Verbindet mit einem Hostprofil";
-
-"lQ6ziK" = "Aktiviere VPN";
-
-"m2E7SI" = "Vertraue aktuellem WLAN";
-
-"qo3Szz" = "Verbinde mit Anbieter-Ort";
-
-"rd1T8p" = "Aktuellem WLAN nicht vertrauen";
-
-"wB1iYX" = "Mobilfunknetz nicht vertrauen";
-
-"xY97Vu" = "Aktiviert den VPN-Dienst mit dem derzeitig benutzten Profil";
-
-"NCoK9B" = "Mit dem benutzten Profil";
diff --git a/Passepartout/Resources/de.lproj/Localizable.strings b/Passepartout/Resources/de.lproj/Localizable.strings
deleted file mode 100644
index e8890f22..00000000
--- a/Passepartout/Resources/de.lproj/Localizable.strings
+++ /dev/null
@@ -1,283 +0,0 @@
-//
-// Localizable.strings
-// Passepartout
-//
-// Created by Davide De Rosa on 4/23/19.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-"global.ok" = "OK";
-"global.cancel" = "Abbrechen";
-"global.next" = "Weiter";
-"global.close" = "Schließen";
-"global.host.title_input.message" = "Gültige Zeichen beinhalten Buchstaben und Zahlen sowie Bindestrich \"-\", Unterstrich \"_\" und Punkt \".\".";
-"global.host.title_input.placeholder" = "Mein Profil";
-"global.email_not_configured" = "Es wurde kein Email-Account konfiguriert.";
-
-"global.cells.enabled" = "Aktiviert";
-"global.cells.disabled" = "Deaktiviert";
-"global.cells.none" = "Keine";
-"global.cells.automatic" = "Automatisch";
-"global.cells.manual" = "Manuell";
-
-"reddit.title" = "Reddit";
-"reddit.message" = "Wusstest du, daß Passepartout einen Subreddit hat? Abonniere ihn für Updates oder um Features, Probleme, neue Plattformen zu diskutieren - oder was auch immer du möchtest.\n\nDies ist auch ein guter Weg zu zeigen dass dir dieses Projekt etwas bedeutet.";
-"reddit.buttons.subscribe" = "Jetzt abbonnieren!";
-"reddit.buttons.remind" = "Später erinnern";
-"reddit.buttons.never" = "Nicht erneut fragen";
-
-"organizer.sections.providers.header" = "Anbieter";
-"organizer.sections.providers.footer" = "Hier findest du einige Anbieter mit voreingestellten Konfigurationsprofilen.";
-"organizer.sections.hosts.header" = "Hosts";
-"organizer.sections.hosts.footer" = "Importiere Hosts aus .ovpn Konfigurationsdateien.";
-"organizer.sections.siri.header" = "Siri";
-"organizer.sections.siri.footer" = "Erhalte Hilfe von Siri um deine üblichen Interaktionen mit der App zu beschleunigen.";
-"organizer.sections.support.header" = "Support";
-"organizer.sections.feedback.header" = "Feedback";
-"organizer.cells.profile.value.current" = "In Benutzung";
-"organizer.cells.add_provider.caption" = "Neuen Anbieter hinzufügen";
-"organizer.cells.add_host.caption" = "Neuen Host hinzufügen";
-"organizer.cells.siri_shortcuts.caption" = "Kurzbefehle verwalten";
-"organizer.cells.join_community.caption" = "Community beitreten";
-"organizer.cells.write_review.caption" = "Rezension schreiben";
-"organizer.cells.donate.caption" = "Spenden";
-"organizer.cells.patreon.caption" = "Unterstütze mich bei Patreon";
-"organizer.cells.translate.caption" = "Übersetzung anbieten";
-"organizer.cells.about.caption" = "Über %@";
-"organizer.cells.uninstall.caption" = "VPN-Konfiguration entfernen";
-"organizer.alerts.exhausted_providers.message" = "Du hast Profile für alle verfügbaren Anbieter erstellt.";
-"organizer.alerts.add_host.message" = "Öffne eine URL zu einer .ovpn-Konfigurationsdatei aus Safari, Mail oder anderen App um ein Host-Profil einzurichten.\n\nDu kannst auch eine .ovpn-Datei mit iTunes Dateifreigabe importieren.";
-"organizer.alerts.cannot_donate.message" = "Auf diesem Gerät ist keine Bezahlmethode konfiguriert.";
-"organizer.alerts.delete_vpn_profile.message" = "Möchtest du wirklich die VPN-Konfiguration aus deinen Geräte-Einstellungen löschen? Dies behebt möglicherweise manche kaputten VPN-Zustände und beeinflusst nicht deine Anbieter und Hosts-Profile.";
-
-"wizards.host.cells.title_input.caption" = "Titel";
-"wizards.host.sections.existing.header" = "Bestehende Profile";
-"wizards.host.alerts.existing.message" = "Ein Host-Profil mit identischem Titel existiert bereits. Ersetzen?";
-
-"parsed_file.alerts.malformed.message" = "Die Konfigurations-Datei enthält eine ungültige Option (%@).";
-"parsed_file.alerts.missing.message" = "Die Konfigurations-Datei enthält eine benötigte Option nicht (%@).";
-"parsed_file.alerts.unsupported.message" = "Die Konfigurations-Datei enthält eine nicht unterstützte Option (%@).";
-"parsed_file.alerts.potentially_unsupported.message" = "Die Konfigurations-Datei ist korrekt, enthält aber möglicherweise eine nicht unterstützte Option (%@).\n\nDie Verbindung kann, abhängig von den Server-Einstellungen, unterbrochen werden.";
-"parsed_file.alerts.encryption_passphrase.message" = "Bitte die Verschlüsselungs-Passphrase eingeben.";
-"parsed_file.alerts.decryption.message" = "Die Konfiguration enthält einen verschlüsselten Private Key und konnte nicht entschlüsselt werden. Bitte überprüfe ob du die Passphrase eingegeben hast.";
-"parsed_file.alerts.parsing.message" = "Fehler beim Verarbeiten der Konfigurationsdatei (%@).";
-"parsed_file.alerts.buttons.report" = "Ein Problem melden";
-
-"imported_hosts.title" = "Importierte Hosts";
-
-"service.welcome.message" = "Willkommen bei Passepartout!\n\nBenutze den Organizer um ein neues Profil hinzuzufügen.";
-"service.sections.general.header" = "Allgemein";
-"service.sections.vpn.header" = "VPN";
-"service.sections.vpn.footer" = "Die Verbindung wird immer aufgebaut wenn notwendig.";
-"service.sections.status.header" = "Verbindung";
-"service.sections.configuration.header" = "Konfiguration";
-"service.sections.provider_infrastructure.footer" = "Zuletzt aktualisiert am %@.";
-"service.sections.vpn_survives_sleep.footer" = "Deaktivieren um die Batterielaufzeit zu verbessern, allerdings verzögert sich der Verbindungsaufbau beim Aufwachen.";
-"service.sections.vpn_resolves_hostname.footer" = "Bevorzugt in den meisten Netzwerken und benötigt in manchen IPv6 Netzwerken. Deaktivieren wo DNS geblockt ist oder um die Aushandlung zu beschleunigen bei langsam antwortenden DNS.";
-//"service.sections.vpn_prefers_udp.footer" = "UDP is faster than TCP, but may not work in some networks. Disable in networks where UDP might be blocked.";
-"service.sections.trusted.header" = "Vertrauenswürdige Netzwerke";
-"service.sections.trusted.footer" = "Wenn ein vertrauenswürdiges Netzwerk verbunden wird, wird normalerweise die VPN-Verbindung beendet und bleibt deaktiviert. Deaktiviere diese Option um dieses Verhalten zu unterbinden.";
-"service.sections.diagnostics.header" = "Diagnose";
-"service.sections.diagnostics.footer" = "Zensier-Status wird aktiv nach erneutem Verbinden. Netzwerk-Daten sind Hostnamen, IP-Adressen, Routingtabellen, SSID. Zugangsdaten und Private Keys werden nie gelogged.";
-//"service.sections.destruction.footer" = "Delete configuration from device settings.";
-
-"service.cells.use_profile.caption" = "Dieses Profil verwenden";
-"service.cells.vpn_service.caption" = "Aktiviert";
-"service.cells.connection_status.caption" = "Status";
-"service.cells.reconnect.caption" = "Erneut verbinden";
-"service.cells.account.caption" = "Account";
-"service.cells.account.none" = "Keiner konfiguriert";
-"service.cells.endpoint.caption" = "Endpoint";
-"service.cells.provider.pool.caption" = "Ort";
-"service.cells.provider.preset.caption" = "Voreinstellung";
-"service.cells.provider.refresh.caption" = "Infrastruktur neu laden";
-"service.cells.host.parameters.caption" = "Parameter";
-"service.cells.network_settings.caption" = "Netzwerk-Einstellungen";
-"service.cells.vpn_survives_sleep.caption" = "Verbindung aktiv halten trotz Schlafmodus";
-"service.cells.vpn_resolves_hostname.caption" = "Server Hostname auflösen";
-//"service.cells.vpn_prefers_udp.caption" = "Prefer UDP socket";
-"service.cells.trusted_mobile.caption" = "Mobilfunknetz";
-"service.cells.trusted_add_wifi.caption" = "Aktuelles WLAN hinzufügen";
-"service.cells.trusted_policy.caption" = "Vertrauen deaktiviert VPN";
-"service.cells.test_connectivity.caption" = "Verbindung testen";
-"service.cells.data_count.caption" = "Ausgetauschte Datenmenge";
-"service.cells.data_count.none" = "Nicht verfügbar";
-"service.cells.debug_log.caption" = "Debug log";
-"service.cells.masks_private_data.caption" = "Netzwerkdaten zensieren";
-"service.cells.report_issue.caption" = "Verbindungsproblem melden";
-
-"service.alerts.rename.title" = "Profil umbenennen";
-"service.alerts.credentials_needed.message" = "Du musst zuerst die Account-Zugangsdaten eingeben.";
-"service.alerts.reconnect_vpn.message" = "Möchtest du erneut zum VPN verbinden?";
-"service.alerts.trusted.no_network.message" = "Du bist mit keinem WLAN verbunden.";
-"service.alerts.trusted.will_disconnect_trusted.message" = "In dem du diesem Netzwerk vertraust, wird das VPN getrennt. Weiter?";
-"service.alerts.trusted.will_disconnect_policy.message" = "Durch das Ändern der Vertrauens-Policy könnte das VPN deaktiviert werden. Weiter?";
-"service.alerts.test_connectivity.title" = "Konnektivität";
-"service.alerts.test_connectivity.messages.success" = "Dein Gerät ist mit dem Internet verbunden!";
-"service.alerts.test_connectivity.messages.failure" = "Dein Gerät hat keine Verbindung mit dem Internet, bitte prüfe deine Profil-Parameter.";
-"service.alerts.masks_private_data.messages.must_reconnect" = "Um das aktuelle Debug-Log sicher zurückzusetzen und die neuen Zensier-Paramenter anzuwenden, musst du das VPN jetzt erneut verbinden.";
-"service.alerts.buttons.reconnect" = "Erneut verbinden";
-"service.alerts.download.title" = "Download benötigt";
-"service.alerts.download.message" = "%@ benötigt den Download von zusätzlichen Konfigurationsdateien.\n\nBestätige um mit dem Download zu beginnen.";
-"service.alerts.download.failed" = "Herunterladen der Konfigurationsdateien fehlgeschlagen. %@";
-"service.alerts.download.hud.extracting" = "Extrahiere Dateien, bitte warten...";
-
-"account.sections.credentials.header" = "Zugangsdaten";
-"account.sections.guidance.footer.infrastructure.mullvad" = "Benutze deine %@ Web-Zugangsdaten. Dein Benutzername ist üblicherweise numerischt.";
-"account.sections.guidance.footer.infrastructure.nordvpn" = "Benutze deine %@ Web-Zugangsdaten. Dein Benutzername ist üblicherweise deine Email.";
-"account.sections.guidance.footer.infrastructure.pia" = "Benutze deine %@ Web-Zugangsdaten. Dein Benutzername ist üblicherweise numerischt mit einem \"p\" Präfix.";
-"account.sections.guidance.footer.infrastructure.protonvpn" = "Deine Zugangsdaten für %@ findest du unter \"Account > OpenVPN / IKEv2 Username\" auf der Webseite.";
-"account.sections.guidance.footer.infrastructure.tunnelbear" = "Benutze deine %@ Web-Zugangsdaten. Dein Benutzername ist üblicherweise deine Email.";
-"account.sections.guidance.footer.infrastructure.vyprvpn" = "Benutze deine %@ Web-Zugangsdaten. Dein Benutzername ist üblicherweise deine Email.";
-"account.sections.guidance.footer.infrastructure.windscribe" = "Deine Zugangsdaten für %@ findest du im OpenVPN Config Generator auf der Webseite.";
-"account.sections.registration.footer" = "Beantrage einen Account auf der %@ Webseite.";
-"account.cells.username.caption" = "Benutzername";
-"account.cells.username.placeholder" = "Benutzername";
-"account.cells.password.caption" = "Passwort";
-"account.cells.password.placeholder" = "Geheim";
-//"account.cells.password_confirm.caption" = "Confirm";
-//"account.cells.password_confirm.mismatch" = "Passwords don't match!";
-"account.cells.open_guide.caption" = "Siehe deine Zugangsdaten";
-"account.cells.signup.caption" = "Registrieren bei %@";
-
-"endpoint.sections.location_addresses.header" = "Adressen";
-"endpoint.sections.location_protocols.header" = "Protokolle";
-"endpoint.cells.any_address.caption" = "Automatisch";
-"endpoint.cells.any_protocol.caption" = "Automatisch";
-
-"provider.preset.cells.tech_details.caption" = "Technische Details";
-//"provider.preset.sections.main.footer" = "Tap info button to disclose technical details.";
-
-"configuration.sections.communication.header" = "Kommunikation";
-"configuration.sections.reset.footer" = "Wenn du nach einer Änderung der Kommunikations-Parameter dich nicht mehr verbinden kannst, hier tippen um zur originalen Konfiguration zurückzukehren.";
-"configuration.sections.tls.header" = "TLS";
-"configuration.sections.compression.header" = "Komprimierung";
-"configuration.sections.network.header" = "Netzwerk";
-"configuration.sections.other.header" = "Andere";
-"configuration.cells.cipher.caption" = "Chiffre";
-"configuration.cells.digest.caption" = "Authentifizierung";
-"configuration.cells.digest.value.embedded" = "Eingebettet";
-"configuration.cells.reset_original.caption" = "Konfiguration zurücksetzen";
-"configuration.cells.client.caption" = "Client Zertifikat";
-"configuration.cells.client.value.enabled" = "Geprüft";
-"configuration.cells.client.value.disabled" = "Nicht geprüft";
-"configuration.cells.tls_wrapping.caption" = "Wrapping";
-"configuration.cells.tls_wrapping.value.auth" = "Authentifizierung";
-"configuration.cells.tls_wrapping.value.crypt" = "Verschlüsselung";
-"configuration.cells.eku.caption" = "Erweiterte Verifizierung";
-"configuration.cells.default_gateway.caption" = "Standart-Gateway";
-"configuration.cells.dns_server.caption" = "DNS";
-"configuration.cells.dns_domain.caption" = "Domäne";
-"configuration.cells.proxy_http.caption" = "Proxy";
-"configuration.cells.proxy_https.caption" = "Proxy (HTTPS)";
-"configuration.cells.compression_framing.caption" = "Framing";
-"configuration.cells.compression_framing.value.lzo" = "--comp-lzo";
-"configuration.cells.compression_framing.value.compress" = "--compress";
-"configuration.cells.compression_algorithm.caption" = "Algorithmus";
-"configuration.cells.compression_algorithm.value.lzo" = "LZO";
-"configuration.cells.compression_algorithm.value.other" = "Nicht unterstützt";
-"configuration.cells.keep_alive.caption" = "Keep-alive";
-"configuration.cells.keep_alive.value.seconds" = "%d Sekunden";
-"configuration.cells.renegotiation_seconds.caption" = "erneute Aushandlung";
-"configuration.cells.renegotiation_seconds.value.after" = "nach %@";
-"configuration.cells.random_endpoint.caption" = "Endpunkt zufällig wählen";
-
-"network_settings.cells.choice.client" = ".ovpn-Datei einlesen";
-"network_settings.cells.choice.server" = "Vom Server holen";
-"network_settings.cells.address.caption" = "Adresse";
-"network_settings.cells.port.caption" = "Port";
-"network_settings.cells.add_dns_server.caption" = "Adresse hinzufügen";
-"network_settings.cells.proxy_bypass.caption" = "Domäne umgehen";
-"network_settings.cells.add_proxy_bypass.caption" = "Zu umgehende Domäne hinzufügen";
-
-"debug_log.buttons.previous" = "Zurück";
-"debug_log.buttons.next" = "Weiter";
-"debug_log.alerts.empty_log.message" = "Das Debug-Log ist leer.";
-
-"vpn.connecting" = "Verbinde";
-"vpn.active" = "Aktiv";
-"vpn.disconnecting" = "Trenne";
-"vpn.inactive" = "Inaktiv";
-"vpn.disabled" = "Deaktiviert";
-
-"vpn.errors.timeout" = "Timeout";
-"vpn.errors.dns" = "DNS fehlgeschlagen";
-"vpn.errors.auth" = "Authentifizierung fehlgeschlagen";
-"vpn.errors.tls" = "TLS fehlgeschlagen";
-"vpn.errors.encryption" = "Verschlüsselung fehlgeschlagen";
-"vpn.errors.compression" = "Komprimierung nicht unterstützt";
-"vpn.errors.network" = "Netzwerk geändert";
-"vpn.errors.routing" = "Kein Routing";
-"vpn.errors.gateway" = "Kein Gateway";
-
-"issue_reporter.title" = "Problem melden";
-"issue_reporter.message" = "Das Debug-Log deiner letzten Verbindung ist notwendig um dein Verbindungs-Problem zu untersuchen und ist vollständig anonymisiert.\n\nDie .ovpn-Konfigurations-Datei, sofern vorhanden, wird anonymisiert von jeglichen sensiblen Daten, angehangen.\n\nBitte prüfe im Zweifelsfall die Email-Anhänge.";
-"issue_reporter.buttons.accept" = "Ich verstehe";
-
-"translations.title" = "Übersetzungen";
-
-"shortcuts.add.title" = "Füge Kurzbefehl hinzu";
-"shortcuts.add.sections.vpn.header" = "VPN";
-"shortcuts.add.sections.wifi.header" = "WLAN";
-"shortcuts.add.sections.cellular.header" = "Mobilfunknetz";
-"shortcuts.add.cells.connect.caption" = "Verbinde mit";
-"shortcuts.add.cells.enable_vpn.caption" = "Aktiviere VPN";
-"shortcuts.add.cells.disable_vpn.caption" = "Deaktiviere VPN";
-"shortcuts.add.cells.trust_current_wifi.caption" = "Vertraue aktivem WLAN";
-"shortcuts.add.cells.untrust_current_wifi.caption" = "Misstraue aktivem WLAN";
-"shortcuts.add.cells.trust_cellular.caption" = "Vertraue Mobilfunknetz";
-"shortcuts.add.cells.untrust_cellular.caption" = "Misstraue Mobilfunknetz";
-"shortcuts.add.alerts.no_profiles.message" = "Es gibt kein Profil mit dem eine Verbindung hergestellt werden kann.";
-
-"shortcuts.edit.title" = "Kurzbefehle bearbeiten";
-"shortcuts.edit.sections.all.header" = "Existierende Kurzbefehle";
-"shortcuts.edit.cells.add_shortcut.caption" = "Kurzbefehl hinzufügen";
-
-"about.title" = "Über";
-"about.sections.web.header" = "Web";
-"about.sections.share.header" = "Teilen";
-"about.cells.credits.caption" = "Credits";
-"about.cells.website.caption" = "Homepage";
-"about.cells.faq.caption" = "FAQ";
-"about.cells.disclaimer.caption" = "Haftungsausschluss";
-"about.cells.privacy_policy.caption" = "Datenschutzrichtlinie";
-"about.cells.share_twitter.caption" = "Darüber Twittern!";
-"about.cells.share_generic.caption" = "Freund einladen";
-
-"donation.title" = "Spenden";
-"donation.sections.one_time.header" = "Einmalig";
-"donation.sections.one_time.footer" = "Wenn du dich erkenntlich zeigen möchtest für meine Arbeit, gibt es hier ein paar Beträge die du direkt spenden kannst.\n\nDu bezahlst pro Spende nur einmal und kannst mehrmals spenden wenn du möchtest.";
-"donation.cells.loading.caption" = "Lade Spenden";
-"donation.cells.purchasing.caption" = "Führe Spende durch";
-"donation.alerts.purchase.success.title" = "Danke";
-"donation.alerts.purchase.success.message" = "Das bedeutet mir viel und ich hoffe wirklich dass du die App weiterhin benutzt und unterstützt.";
-"donation.alerts.purchase.failure.message" = "Konnte Spende nicht durchführen. %@";
-
-"share.message" = "Passepartout ist ein Benutzerfreundlicher, Open Source OpenVPN client für iOS und macOS";
-
-"version.title" = "Version";
-"version.labels.intro" = "Passepartout und TunnelKit sind geschrieben und gewartet von by Davide De Rosa (keeshux).\n\nQuellcode für Passepartout und TunnelKit ist öffentlich auf GitHub unter GPLv3 verfügbar, du findest die Links auf der Homepage.\n\nPassepartout ist ein inoffizieller client und auf keine Art und Weise mit OpenVPN Inc. verbunden.";
-
-"credits.title" = "Credits";
-"credits.sections.licenses.header" = "Lizenzen";
-"credits.sections.notices.header" = "Notizen";
-"credits.sections.translations.header" = "Übersetzungen";
-
-"label.license.error" = "Konnte vollständigen Lizenz-Inhalt nicht herunterladen.";
diff --git a/Passepartout/Resources/el.lproj/Intents.strings b/Passepartout/Resources/el.lproj/Intents.strings
deleted file mode 100644
index dee101b5..00000000
--- a/Passepartout/Resources/el.lproj/Intents.strings
+++ /dev/null
@@ -1,39 +0,0 @@
-"0jRWn5" = "Αφαιρεί το κινητό δίκτυο από τα αξιόπιστα δίκτυα";
-
-"1ZRTCZ" = "Απενεργοποίηση VPN";
-
-"66bZBE" = "Με ${providerId} πάροχο";
-
-"7eoAss" = "Αφαίρεση συνδεδεμένου Wi-Fi από τα έμπιστα δίκτυα";
-
-"9GpJt5" = "Προσθέτει το κινητό δίκτυο στα αξιόπιστα δίκτυα";
-
-"BKxs8X" = "Προσθήκη τρέχων Wi-Fi στα έμπιστα δίκτυα";
-
-"H4taev" = "Αξιόπιστο Δίκτυο κινητής τηλεφωνίας";
-
-"KjkCfU" = "Συνδέετε σε μια συγκεκριμένη τοποθεσία ενός προφίλ παρόχου";
-
-"LA99yM" = "Σύνδεση VPN";
-
-"U6o81V" = "Σύνδεση στο ${profileId}";
-
-"WnTPFg" = "Σύνδεση σε ${poolName}";
-
-"eQ1yzr" = "Απενεργοποίηση υπηρεσίας VPN";
-
-"eXXb2z" = "Συνδέεται σε ένα προφίλ διακομιστή";
-
-"lQ6ziK" = "Ενεργοποίηση VPN";
-
-"m2E7SI" = "Εμπιστευθείτε το τρέχον Wi-Fi";
-
-"qo3Szz" = "Συνδεθείτε με τη θέση του παρόχου";
-
-"rd1T8p" = "Μην εμπιστευθείτε το τρέχον Wi-Fi";
-
-"wB1iYX" = "Μη αξιόπιστο κινητό δίκτυο";
-
-"xY97Vu" = "Ενεργοποιεί την υπηρεσία VPN με το προφίλ που χρησιμοποιείται αυτήν τη στιγμή";
-
-"NCoK9B" = "Με προφίλ σε χρήση";
diff --git a/Passepartout/Resources/el.lproj/Localizable.strings b/Passepartout/Resources/el.lproj/Localizable.strings
deleted file mode 100644
index da2b9a5e..00000000
--- a/Passepartout/Resources/el.lproj/Localizable.strings
+++ /dev/null
@@ -1,283 +0,0 @@
-//
-// Localizable.strings
-// Passepartout
-//
-// Created by Davide De Rosa on 6/13/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-"global.ok" = "OK";
-"global.cancel" = "Ακύρωση";
-"global.next" = "Επόμενο";
-"global.close" = "Κλείσιμο";
-"global.host.title_input.message" = "Αποδεκτοί χαρακτήρες είναι οι αλφαριθμητικοί συν τη παύλα \"-\", κάτω παύλα \"_\" και τελεία \".\".";
-"global.host.title_input.placeholder" = "Το προφίλ μου";
-"global.email_not_configured" = "Δεν έχει ρυθμιστεί λογαριασμός ηλεκτρονικού ταχυδρομείου.";
-
-"global.cells.enabled" = "Ενεργοποιήθηκε";
-"global.cells.disabled" = "Απενεργοποιήθηκε";
-"global.cells.none" = "Κανένα";
-"global.cells.automatic" = "Αυτόματο";
-"global.cells.manual" = "Χειροκίνητο";
-
-"reddit.title" = "Reddit";
-"reddit.message" = "Γνωρίζατε ότι το Passepartout έχει subreddit? Εγγραφείτε για ενημερώσεις ή για να συζητήσετε προβλήματα της εφαρμογές, νέες δυνατότητες και άλλα.\n\nΕίναι επίσης ένας ωραίος τρόπος να δείξετε ότι ενδιαφέρεστε για τη προσπάθεια αυτή.";
-"reddit.buttons.subscribe" = "Εγγραφή τώρα!";
-"reddit.buttons.remind" = "Υπενθύμιση Αργότερα";
-"reddit.buttons.never" = "Μη με ρωτήσεις ξανά";
-
-"organizer.sections.providers.header" = "Πάροχοι";
-"organizer.sections.providers.footer" = "Εδώ θα βρείτε ορισμένους παρόχους με προκαθορισμένες ρυθμίσεις προφίλ.";
-"organizer.sections.hosts.header" = "Φιλοξενητές";
-"organizer.sections.hosts.footer" = "Εισάγετε φιλοξενητές από ένα raw .ovpn αρχείο.";
-"organizer.sections.siri.header" = "Siri";
-"organizer.sections.siri.footer" = "Get help from Siri to speed up your most common interactions with the app.";
-"organizer.sections.support.header" = "Υποστήριξη";
-"organizer.sections.feedback.header" = "Ανατροφοδότηση";
-"organizer.cells.profile.value.current" = "Σε χρήση";
-"organizer.cells.add_provider.caption" = "Προσθήκη νέου παρόχου";
-"organizer.cells.add_host.caption" = "Προσθήκη νέου διακομιστή";
-"organizer.cells.siri_shortcuts.caption" = "Διαχείριση Συντομεύσεων";
-"organizer.cells.join_community.caption" = "Συμμετοχή στην κοινότητα";
-"organizer.cells.write_review.caption" = "Γράψτε μια κριτική";
-"organizer.cells.donate.caption" = "Κάντε μια δωρεά";
-"organizer.cells.patreon.caption" = "Υποστηρίξτε με στο Patreon";
-"organizer.cells.translate.caption" = "Βοηθήστε στη μετάφραση";
-"organizer.cells.about.caption" = "Σχετικά με %@";
-"organizer.cells.uninstall.caption" = "Αφαίρεση ρύθμισης VPN";
-"organizer.alerts.exhausted_providers.message" = "Έχετε δημιουργήσει προφίλ για οποιονδήποτε διαθέσιμο πάροχο.";
-"organizer.alerts.add_host.message" = "Εισάγετε μια διεύθυνση από ένα αρχείο .ovpn στο Safari, το Mail ή άλλη εφαρμογή για να ρυθμίσετε ένα προφίλ διακομιστή.\n\nΜπορείτε επίσης να εισάγετε ένα .ovpn αρχείο από το iTunes File Sharing.";
-"organizer.alerts.cannot_donate.message" = "Δεν έχει ρυθμιστεί καμία μέθοδος πληρωμής σε αυτήν τη συσκευή.";
-"organizer.alerts.delete_vpn_profile.message" = "Θέλετε πραγματικά να διαγράψετε τη διαμόρφωση VPN από τις ρυθμίσεις της συσκευής σας; Αυτό μπορεί να διορθώσει κάποιες καταστραμμένες καταστάσεις VPN και δεν θα επηρεάσει τα προφίλ του παροχέα και του διακομιστή σας.";
-
-"wizards.host.cells.title_input.caption" = "Τίτλος";
-"wizards.host.sections.existing.header" = "Υπάρχον Προφίλ";
-"wizards.host.alerts.existing.message" = "Ένα προφίλ διακομιστή με τον ίδιο τίτλο υπάρχει ήδη. Αντικατέστησέ το;";
-
-"parsed_file.alerts.malformed.message" = "Το αρχείο ρυθμίσεων περιέχει μια ακατάλληλη επιλογή (%@).";
-"parsed_file.alerts.missing.message" = "Το αρχείο διαμόρφωσης δεν διαθέτει την απαιτούμενη επιλογή (%@).";
-"parsed_file.alerts.unsupported.message" = "Το αρχείο διαμόρφωσης περιέχει μια επιλογή που δεν υποστηρίζεται (%@).";
-"parsed_file.alerts.potentially_unsupported.message" = "Το αρχείο ρυθμίσεων είναι σωστό, αλλά περιέχει μια δυνητικά μη υποστηριζόμενη επιλογή (%@).\n\nΗ δυνατότητα σύνδεσης μπορεί να διακοπεί ανάλογα με τις ρυθμίσεις του διακομιστή.";
-"parsed_file.alerts.encryption_passphrase.message" = "Εισαγάγετε το κωδικό κρυπτογράφησης.";
-"parsed_file.alerts.decryption.message" = "Η διαμόρφωση περιέχει κρυπτογραφημένο ιδιωτικό κλειδί και δεν ήταν δυνατό να αποκρυπτογραφηθεί. Δείτε πάλι το κωδικό που καταχωρίσατε.";
-"parsed_file.alerts.parsing.message" = "Δεν είναι δυνατή η ανάλυση του παρεχόμενου αρχείου ρύθμισης παραμέτρων (%@).";
-"parsed_file.alerts.buttons.report" = "Αναφέρετε ένα πρόβλημα";
-
-"imported_hosts.title" = "Εισαγόμενοι διακομιστές";
-
-"service.welcome.message" = "Καλώς Ήλθατε στο Passepartout!\n\nΧρησιμοποιήστε τον διοργανωτή για να προσθέσετε ένα νέο προφίλ.";
-"service.sections.general.header" = "Γενικά";
-"service.sections.vpn.header" = "VPN";
-"service.sections.vpn.footer" = "Η σύνδεση θα πραγματοποιηθεί όποτε είναι απαραίτητο.";
-"service.sections.status.header" = "Σύνδεση";
-"service.sections.configuration.header" = "Ρύθμιση";
-"service.sections.provider_infrastructure.footer" = "Τελευταία ενημέρωση στις %@.";
-"service.sections.vpn_survives_sleep.footer" = "Απενεργοποιήστε για να βελτιώσετε τη χρήση της μπαταρίας, εις βάρος των περιστασιακών επιβραδύνσεων που οφείλονται σε επανασύνδεση αφύπνισης.";
-"service.sections.vpn_resolves_hostname.footer" = "Προτιμάται στα περισσότερα δίκτυα και απαιτείται σε ορισμένα δίκτυα IPv6. Απενεργοποιήστε το εκεί που μπλοκάρεται το DNS ή για να επιταχύνετε τη επικοινωνία όταν το DNS είναι αργό για να ανταποκριθεί.";
-//"service.sections.vpn_prefers_udp.footer" = "Το UDP είναι πιο γρήγορο από το TCP, αλλά ενδέχεται να μην λειτουργεί σε ορισμένα δίκτυα. Απενεργοποιήστε σε δίκτυα όπου ενδέχεται να αποκλειστεί το UDP.";
-"service.sections.trusted.header" = "Αξιόπιστα δίκτυα";
-"service.sections.trusted.footer" = "Κατά την είσοδο σε ένα αξιόπιστο δίκτυο, το VPN απενεργοποιείται κανονικά και διατηρείται αποσυνδεδεμένο. Απενεργοποιήστε αυτήν την επιλογή για να μην έχετε μια τέτοια συμπεριφορά.";
-"service.sections.diagnostics.header" = "Διαγνωστικά";
-"service.sections.diagnostics.footer" = "Η κατάσταση κάλυψης θα είναι αποτελεσματική μετά την επανασύνδεση. Τα δεδομένα δικτύου είναι του διακομιστή, διευθύνσεις IP, δρομολόγηση και SSID. Τα διαπιστευτήρια και τα ιδιωτικά κλειδιά δεν καταγράφονται ανεξάρτητα.";
-//"service.sections.destruction.footer" = "Διαγραφή ρυθμίσεων από τις ρυθμίσεις της συσκευής.";
-
-"service.cells.use_profile.caption" = "Χρησιμοποιήστε αυτό το προφίλ";
-"service.cells.vpn_service.caption" = "Ενεργοποιήθηκε";
-"service.cells.connection_status.caption" = "Κατάσταση";
-"service.cells.reconnect.caption" = "Επανασύνδεση";
-"service.cells.account.caption" = "Λογαριασμός";
-"service.cells.account.none" = "Δεν έχει διαμορφωθεί";
-"service.cells.endpoint.caption" = "Τελικό σημείο";
-"service.cells.provider.pool.caption" = "Τοποθεσία";
-"service.cells.provider.preset.caption" = "Προεπιλογή";
-"service.cells.provider.refresh.caption" = "Ανανέωση της υποδομής";
-"service.cells.host.parameters.caption" = "Παράμετροι";
-"service.cells.network_settings.caption" = "Ρυθμίσεις Δικτύου";
-"service.cells.vpn_survives_sleep.caption" = "Κρατήστε ζωντανό στον ύπνο";
-"service.cells.vpn_resolves_hostname.caption" = "Επίλυση του ονόματος σέρβερ διακομιστή";
-//"service.cells.vpn_prefers_udp.caption" = "Prefer UDP socket";
-"service.cells.trusted_mobile.caption" = "Δίκτυο Κινητής";
-"service.cells.trusted_add_wifi.caption" = "Προσθέστε το τρέχον Wi-Fi";
-"service.cells.trusted_policy.caption" = "Τα αξιόπιστα δίκτυα απενεργοποιούν το VPN";
-"service.cells.test_connectivity.caption" = "Δοκιμή συνδεσιμότητας";
-"service.cells.data_count.caption" = "Ανταλλαγή δεδομένων";
-"service.cells.data_count.none" = "Μη διαθέσιμο";
-"service.cells.debug_log.caption" = "Μητρώο εντοπισμού σφαλμάτων";
-"service.cells.masks_private_data.caption" = "Μάσκα δεδομένα δικτύου";
-"service.cells.report_issue.caption" = "Αναφορά ζητήματος συνδεσιμότητας";
-
-"service.alerts.rename.title" = "Μετονομασία προφίλ";
-"service.alerts.credentials_needed.message" = "Πρέπει πρώτα να εισαγάγετε διαπιστευτήρια λογαριασμού.";
-"service.alerts.reconnect_vpn.message" = "Θέλετε να συνδεθείτε ξανά με το VPN;";
-"service.alerts.trusted.no_network.message" = "Δεν είστε συνδεδεμένοι σε κανένα δίκτυο Wi-Fi.";
-"service.alerts.trusted.will_disconnect_trusted.message" = "Με εμπιστοσύνη σε αυτό το δίκτυο, το VPN μπορεί να αποσυνδεθεί. Να συνεχίσω;";
-"service.alerts.trusted.will_disconnect_policy.message" = "Αλλάζοντας την πολιτική εμπιστοσύνης, το VPN μπορεί να αποσυνδεθεί. Να συνεχίσω;";
-"service.alerts.test_connectivity.title" = "Συνδεσιμότητα";
-"service.alerts.test_connectivity.messages.success" = "Η συσκευή σας είναι συνδεδεμένη στο Διαδίκτυο!";
-"service.alerts.test_connectivity.messages.failure" = "Η συσκευή σας δεν διαθέτει σύνδεση στο Internet, παρακαλούμε να ελέγξετε τις παραμέτρους του προφίλ σας.";
-"service.alerts.masks_private_data.messages.must_reconnect" = "Για να επαναφέρετε με ασφάλεια την τρέχουσα καταγραφή εντοπισμού σφαλμάτων και να εφαρμόσετε τη νέα προτίμηση κάλυψης, πρέπει να συνδεθείτε ξανά με το VPN.";
-"service.alerts.buttons.reconnect" = "Επανασύνδεση";
-"service.alerts.download.title" = "Απαιτείται λήψη";
-"service.alerts.download.message" = "%@ απαιτεί τη λήψη πρόσθετων αρχείων ρυθμίσεων.\n\nΕπιβεβαιώστε για να ξεκινήσετε τη λήψη.";
-"service.alerts.download.failed" = "Αποτυχία λήψης αρχείων ρυθμίσεων. %@";
-"service.alerts.download.hud.extracting" = "Εξάγοντας τα αρχεία, παρακαλώ να είστε υπομονετικοί...";
-
-"account.sections.credentials.header" = "Διαπιστευτήρια";
-"account.sections.guidance.footer.infrastructure.mullvad" = "Χρησιμοποιήστε τα διαπιστευτήρια ιστοτόπου %@. Το όνομα χρήστη είναι συνήθως αριθμητικό.";
-"account.sections.guidance.footer.infrastructure.nordvpn" = "Χρησιμοποιήστε τα διαπιστευτήρια ιστοτόπου %@. Το όνομα χρήστη είναι συνήθως το ηλεκτρονικό σας ταχυδρομείο.";
-"account.sections.guidance.footer.infrastructure.pia" = "Χρησιμοποιήστε τα διαπιστευτήρια ιστοτόπου %@. Το όνομα χρήστη είναι συνήθως αριθμητικό με πρόθεμα \"p\".";
-"account.sections.guidance.footer.infrastructure.protonvpn" = "Βρείτε τα διαπιστευτήριά σας %@ στην ενότητα \"Λογαριασμός> OpenVPN / IKEv2 Username \" της ιστοσελίδας.";
-"account.sections.guidance.footer.infrastructure.tunnelbear" = "Χρησιμοποιήστε τα διαπιστευτήρια ιστοτόπου %@. Το όνομα χρήστη είναι συνήθως το ηλεκτρονικό σας ταχυδρομείο.";
-"account.sections.guidance.footer.infrastructure.vyprvpn" = "Χρησιμοποιήστε τα διαπιστευτήρια ιστοτόπου %@. Το όνομα χρήστη είναι συνήθως το ηλεκτρονικό σας ταχυδρομείο.";
-"account.sections.guidance.footer.infrastructure.windscribe" = "Βρείτε τα διαπιστευτήριά σας %@ στο OpenVPN Config Generator στον ιστότοπο.";
-"account.sections.registration.footer" = "Πηγαίνετε να αποκτήσετε λογαριασμό στον ιστότοπο %@.";
-"account.cells.username.caption" = "Όνομα χρήστη";
-"account.cells.username.placeholder" = "χρήστης";
-"account.cells.password.caption" = "Κωδικός";
-"account.cells.password.placeholder" = "κωδικός";
-//"account.cells.password_confirm.caption" = "Επιβεβαίωση";
-//"account.cells.password_confirm.mismatch" = "Οι κωδικοί πρόσβασης δεν ταιριάζουν!";
-"account.cells.open_guide.caption" = "Δείτε τα διαπιστευτήρια σας";
-"account.cells.signup.caption" = "Εγγραφείτε με %@";
-
-"endpoint.sections.location_addresses.header" = "Διεθύνσεις";
-"endpoint.sections.location_protocols.header" = "Πρωτόκολλα";
-"endpoint.cells.any_address.caption" = "Αυτόματο";
-"endpoint.cells.any_protocol.caption" = "Αυτόματο";
-
-"provider.preset.cells.tech_details.caption" = "Τεχνικές Λεπτομέρειες";
-//"provider.preset.sections.main.footer" = "Αγγίξτε το κουμπί πληροφοριών για να αποκαλύψετε τεχνικές λεπτομέρειες.";
-
-"configuration.sections.communication.header" = "Επικοινωνία";
-"configuration.sections.reset.footer" = "Αν καταλήξατε σε κατεστραμένη συνδεσιμότητα μετά την αλλαγή των παραμέτρων επικοινωνίας, πατήστε για να επανέλθετε στην αρχική διαμόρφωση.";
-"configuration.sections.tls.header" = "TLS";
-"configuration.sections.compression.header" = "Συμπίεση";
-"configuration.sections.network.header" = "Δίκτυο";
-"configuration.sections.other.header" = "Άλλο";
-"configuration.cells.cipher.caption" = "Cipher";
-"configuration.cells.digest.caption" = "Αυθεντικοποίηση";
-"configuration.cells.digest.value.embedded" = "Ενσωματωμένο";
-"configuration.cells.reset_original.caption" = "Επαναφορά ρυθμίσεων";
-"configuration.cells.client.caption" = "Πιστοποιητικό πελάτη";
-"configuration.cells.client.value.enabled" = "Επαληθεύτηκε";
-"configuration.cells.client.value.disabled" = "Δεν επαληθεύτηκε";
-"configuration.cells.tls_wrapping.caption" = "Wrapping";
-"configuration.cells.tls_wrapping.value.auth" = "Αυθεντικοποίηση";
-"configuration.cells.tls_wrapping.value.crypt" = "Κρυπτογράφηση";
-"configuration.cells.eku.caption" = "Εκτεταμένη επαλήθευση";
-"configuration.cells.default_gateway.caption" = "Προεπιλεγμένη πύλη";
-"configuration.cells.dns_server.caption" = "DNS";
-"configuration.cells.dns_domain.caption" = "Domain";
-"configuration.cells.proxy_http.caption" = "Proxy";
-"configuration.cells.proxy_https.caption" = "Proxy (HTTPS)";
-"configuration.cells.compression_framing.caption" = "Framing";
-"configuration.cells.compression_framing.value.lzo" = "--comp-lzo";
-"configuration.cells.compression_framing.value.compress" = "--συμπίεση";
-"configuration.cells.compression_algorithm.caption" = "Αλγόρυθμος";
-"configuration.cells.compression_algorithm.value.lzo" = "LZO";
-"configuration.cells.compression_algorithm.value.other" = "Δεν υποστηρίζεται";
-"configuration.cells.keep_alive.caption" = "Διατηρήστε ζωντανή";
-"configuration.cells.keep_alive.value.seconds" = "%d δευτερόλεπτα";
-"configuration.cells.renegotiation_seconds.caption" = "Επαναδιαπραγμάτευση";
-"configuration.cells.renegotiation_seconds.value.after" = "μετά από %@";
-"configuration.cells.random_endpoint.caption" = "Τυχαίο τελικό σημείο";
-
-"network_settings.cells.choice.client" = "Ανάγνωση .ovpn";
-"network_settings.cells.choice.server" = "Λήψη από το διακομιστή";
-"network_settings.cells.address.caption" = "Διεύθυνση";
-"network_settings.cells.port.caption" = "Θύρα";
-"network_settings.cells.add_dns_server.caption" = "Προσθήκη Διεύθυνσης";
-"network_settings.cells.proxy_bypass.caption" = "Παράκαμψη Τομέα";
-"network_settings.cells.add_proxy_bypass.caption" = "Προσθήκη τομέα παράκαμψης";
-
-"debug_log.buttons.previous" = "Προηγούμενο";
-"debug_log.buttons.next" = "Επόμενο";
-"debug_log.alerts.empty_log.message" = "Το αρχείο εντοπισμού σφαλμάτων είναι κενό.";
-
-"vpn.connecting" = "Προσπάθεια Σύνδεσης";
-"vpn.active" = "Ενεργό";
-"vpn.disconnecting" = "Αποσυνδέετε";
-"vpn.inactive" = "Μη ενεργό";
-"vpn.disabled" = "Απενεργοποιημένο";
-
-"vpn.errors.timeout" = "Τέλος χρονικού Ορίου";
-"vpn.errors.dns" = "Το DNS απέτυχε";
-"vpn.errors.auth" = "Το Auth απέτυχε";
-"vpn.errors.tls" = "Το TLS απέτυχε";
-"vpn.errors.encryption" = "Η Κρυπτογράφηση απέτυχε";
-"vpn.errors.compression" = "Η συμπίεση δεν υποστηρίζεται";
-"vpn.errors.network" = "Το δίκτυο άλλαξε";
-"vpn.errors.routing" = "Λείπει η δρομολόγηση";
-"vpn.errors.gateway" = "Δεν υπάρχει πύλη";
-
-"issue_reporter.title" = "Αναφορά Προβλήματος";
-"issue_reporter.message" = "The debug log of your latest connections is crucial to resolve your connectivity issues and is completely anonymous.\n\nThe .ovpn configuration file, if any, is attached stripped of any sensitive data.\n\nPlease double check the e-mail attachments if unsure.";
-"issue_reporter.buttons.accept" = "Καταλαβαίνω";
-
-"translations.title" = "Μεταφράσεις";
-
-"shortcuts.add.title" = "Προσθήκη Συντόμευσης";
-"shortcuts.add.sections.vpn.header" = "VPN";
-"shortcuts.add.sections.wifi.header" = "Wi-Fi";
-"shortcuts.add.sections.cellular.header" = "Δίκτυο Κινητής";
-"shortcuts.add.cells.connect.caption" = "Σύνδεση σε";
-"shortcuts.add.cells.enable_vpn.caption" = "Ενεργοποίηση VPN";
-"shortcuts.add.cells.disable_vpn.caption" = "Απενεργοποίηση VPN";
-"shortcuts.add.cells.trust_current_wifi.caption" = "Εμπιστέψου το τρέχον Wi-Fi";
-"shortcuts.add.cells.untrust_current_wifi.caption" = "Μην εμπιστευθείτε το τρέχον Wi-Fi";
-"shortcuts.add.cells.trust_cellular.caption" = "Εμπιστοσύνη δικτύου κινητής τηλεφωνίας";
-"shortcuts.add.cells.untrust_cellular.caption" = "Μην εμπιστευθείτε το δίκτυο κινητής τηλεφωνίας";
-"shortcuts.add.alerts.no_profiles.message" = "Δεν υπάρχει προφίλ για σύνδεση.";
-
-"shortcuts.edit.title" = "Διαχείριση συντομεύσεων";
-"shortcuts.edit.sections.all.header" = "Υπάρχουσες συντομεύσεις";
-"shortcuts.edit.cells.add_shortcut.caption" = "Προσθήκη Συντόμευσης";
-
-"about.title" = "Περι";
-"about.sections.web.header" = "Web";
-"about.sections.share.header" = "Διαμοιράστε";
-"about.cells.credits.caption" = "Συντελεστές";
-"about.cells.website.caption" = "Αρχική Σελίδα";
-"about.cells.faq.caption" = "Συχνές Ερωτήσεις";
-"about.cells.disclaimer.caption" = "Άρνηση Ευθύνης";
-"about.cells.privacy_policy.caption" = "Πολιτική Απορρήτου";
-"about.cells.share_twitter.caption" = "Tweet γι 'αυτό!";
-"about.cells.share_generic.caption" = "Πρόσκληση Φίλου";
-
-"donation.title" = "Δωρεά";
-"donation.sections.one_time.header" = "Μια Φορά";
-"donation.sections.one_time.footer" = "Αν είστε χαρούμενη με τη δουλειά μου, εδώ είναι λίγα ποσά που μπορείτε να δώσετε αμέσως.\n\nΘα χρεωθείτε μόνο μία φορά και μπορείτε να δώσετε πολλές φορές.";
-"donation.cells.loading.caption" = "Φόρτωση δωρεών";
-"donation.cells.purchasing.caption" = "Εκτέλεση δωρεάς";
-"donation.alerts.purchase.success.title" = "Ευχαριστώ";
-"donation.alerts.purchase.success.message" = "Αυτό σημαίνει πολλά για μένα και πραγματικά ελπίζω να συνεχίσετε να χρησιμοποιείτε και να προωθείτε αυτήν την εφαρμογή.";
-"donation.alerts.purchase.failure.message" = "Δεν είναι δυνατή η εκτέλεση της δωρεάς. %@";
-
-"share.message" = "Το Passepartout είναι φιλικό προς το χρήστη, ανοιχτού κώδικα OpenVPN πρόγραμμα για iOS και macOS";
-
-"version.title" = "Έκδοση";
-"version.labels.intro" = "Το Passepartout και το TunnelKit γράφονται και συντηρούνται από τον Davide De Rosa (keeshux).\n\nΟ πηγαίος κώδικας για το Passepartout και το TunnelKit είναι δημόσια διαθέσιμε στο GitHub υπό το GPLv3, μπορείτε να βρείτε συνδέσμους στην αρχική σελίδα.\n\nΤο Passepartout είναι ένας μη επίσημος πελάτης και δεν είναι συνδεδεμένος με το OpenVPN Inc.";
-
-"credits.title" = "Συντελεστές";
-"credits.sections.licenses.header" = "Άδειες";
-"credits.sections.notices.header" = "Σημειώσεις";
-"credits.sections.translations.header" = "Μεταφράσεις";
-
-"label.license.error" = "Δεν είναι δυνατή η λήψη πλήρους περιεχομένου άδειας χρήσης.";
diff --git a/Passepartout/Resources/en.lproj/Intents.strings b/Passepartout/Resources/en.lproj/Intents.strings
deleted file mode 100644
index f4ae960c..00000000
--- a/Passepartout/Resources/en.lproj/Intents.strings
+++ /dev/null
@@ -1,39 +0,0 @@
-"0jRWn5" = "Removes cellular from trusted networks";
-
-"1ZRTCZ" = "Disable VPN";
-
-"66bZBE" = "With ${providerId} provider";
-
-"7eoAss" = "Removes current Wi-Fi from trusted networks";
-
-"9GpJt5" = "Adds cellular to trusted networks";
-
-"BKxs8X" = "Adds current Wi-Fi to trusted networks";
-
-"H4taev" = "Trust cellular network";
-
-"KjkCfU" = "Connects to a specific location of a provider profile";
-
-"LA99yM" = "Connect to VPN";
-
-"U6o81V" = "Connect to ${profileId}";
-
-"WnTPFg" = "Connect to ${poolName}";
-
-"eQ1yzr" = "Disables the VPN service";
-
-"eXXb2z" = "Connects to a host profile";
-
-"lQ6ziK" = "Enable VPN";
-
-"m2E7SI" = "Trust current Wi-Fi";
-
-"qo3Szz" = "Connect to provider location";
-
-"rd1T8p" = "Untrust current Wi-Fi";
-
-"wB1iYX" = "Untrust cellular network";
-
-"xY97Vu" = "Enables the VPN service with the profile currently in use";
-
-"NCoK9B" = "With profile in use";
diff --git a/Passepartout/Resources/en.lproj/Localizable.strings b/Passepartout/Resources/en.lproj/Localizable.strings
deleted file mode 100644
index b9fa7afc..00000000
--- a/Passepartout/Resources/en.lproj/Localizable.strings
+++ /dev/null
@@ -1,283 +0,0 @@
-//
-// Localizable.strings
-// Passepartout
-//
-// Created by Davide De Rosa on 6/13/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-"global.ok" = "OK";
-"global.cancel" = "Cancel";
-"global.next" = "Next";
-"global.close" = "Close";
-"global.host.title_input.message" = "Acceptable characters are alphanumerics plus dash \"-\", underscore \"_\" and dot \".\".";
-"global.host.title_input.placeholder" = "My profile";
-"global.email_not_configured" = "No e-mail account is configured.";
-
-"global.cells.enabled" = "Enabled";
-"global.cells.disabled" = "Disabled";
-"global.cells.none" = "None";
-"global.cells.automatic" = "Automatic";
-"global.cells.manual" = "Manual";
-
-"reddit.title" = "Reddit";
-"reddit.message" = "Did you know that Passepartout has a subreddit? Subscribe for updates or to discuss issues, features, new platforms or whatever you like.\n\nIt's also a great way to show you care about this project.";
-"reddit.buttons.subscribe" = "Subscribe now!";
-"reddit.buttons.remind" = "Remind me later";
-"reddit.buttons.never" = "Don't ask again";
-
-"organizer.sections.providers.header" = "Providers";
-"organizer.sections.providers.footer" = "Here you find a few providers with preset configuration profiles.";
-"organizer.sections.hosts.header" = "Hosts";
-"organizer.sections.hosts.footer" = "Import hosts from raw .ovpn configuration files.";
-"organizer.sections.siri.header" = "Siri";
-"organizer.sections.siri.footer" = "Get help from Siri to speed up your most common interactions with the app.";
-"organizer.sections.support.header" = "Support";
-"organizer.sections.feedback.header" = "Feedback";
-"organizer.cells.profile.value.current" = "In use";
-"organizer.cells.add_provider.caption" = "Add new provider";
-"organizer.cells.add_host.caption" = "Add new host";
-"organizer.cells.siri_shortcuts.caption" = "Manage shortcuts";
-"organizer.cells.join_community.caption" = "Join community";
-"organizer.cells.write_review.caption" = "Write a review";
-"organizer.cells.donate.caption" = "Make a donation";
-"organizer.cells.patreon.caption" = "Support me on Patreon";
-"organizer.cells.translate.caption" = "Offer to translate";
-"organizer.cells.about.caption" = "About %@";
-"organizer.cells.uninstall.caption" = "Remove VPN configuration";
-"organizer.alerts.exhausted_providers.message" = "You have created profiles for any available provider.";
-"organizer.alerts.add_host.message" = "Open an URL to an .ovpn configuration file from Safari, Mail or another app to set up a host profile.\n\nYou can also import an .ovpn with iTunes File Sharing.";
-"organizer.alerts.cannot_donate.message" = "There is no payment method configured on this device.";
-"organizer.alerts.delete_vpn_profile.message" = "Do you really want to erase the VPN configuration from your device settings? This may fix some broken VPN states and will not affect your provider and host profiles.";
-
-"wizards.host.cells.title_input.caption" = "Title";
-"wizards.host.sections.existing.header" = "Existing profiles";
-"wizards.host.alerts.existing.message" = "A host profile with the same title already exists. Replace it?";
-
-"parsed_file.alerts.malformed.message" = "The configuration file contains a malformed option (%@).";
-"parsed_file.alerts.missing.message" = "The configuration file lacks a required option (%@).";
-"parsed_file.alerts.unsupported.message" = "The configuration file contains an unsupported option (%@).";
-"parsed_file.alerts.potentially_unsupported.message" = "The configuration file is correct but contains a potentially unsupported option (%@).\n\nConnectivity may break depending on server settings.";
-"parsed_file.alerts.encryption_passphrase.message" = "Please enter the encryption passphrase.";
-"parsed_file.alerts.decryption.message" = "The configuration contains an encrypted private key and it could not be decrypted. Double check your entered passphrase.";
-"parsed_file.alerts.parsing.message" = "Unable to parse the provided configuration file (%@).";
-"parsed_file.alerts.buttons.report" = "Report an issue";
-
-"imported_hosts.title" = "Imported hosts";
-
-"service.welcome.message" = "Welcome to Passepartout!\n\nUse the organizer to add a new profile.";
-"service.sections.general.header" = "General";
-"service.sections.vpn.header" = "VPN";
-"service.sections.vpn.footer" = "The connection will be established whenever necessary.";
-"service.sections.status.header" = "Connection";
-"service.sections.configuration.header" = "Configuration";
-"service.sections.provider_infrastructure.footer" = "Last updated on %@.";
-"service.sections.vpn_survives_sleep.footer" = "Disable to improve battery usage, at the expense of occasional slowdowns due to wake-up reconnections.";
-"service.sections.vpn_resolves_hostname.footer" = "Preferred in most networks and required in some IPv6 networks. Disable where DNS is blocked, or to speed up negotiation when DNS is slow to respond.";
-//"service.sections.vpn_prefers_udp.footer" = "UDP is faster than TCP, but may not work in some networks. Disable in networks where UDP might be blocked.";
-"service.sections.trusted.header" = "Trusted networks";
-"service.sections.trusted.footer" = "When entering a trusted network, the VPN is normally shut down and kept disconnected. Disable this option to not enforce such behavior.";
-"service.sections.diagnostics.header" = "Diagnostics";
-"service.sections.diagnostics.footer" = "Masking status will be effective after reconnecting. Network data are hostnames, IP addresses, routing, SSID. Credentials and private keys are not logged regardless.";
-//"service.sections.destruction.footer" = "Delete configuration from device settings.";
-
-"service.cells.use_profile.caption" = "Use this profile";
-"service.cells.vpn_service.caption" = "Enabled";
-"service.cells.connection_status.caption" = "Status";
-"service.cells.reconnect.caption" = "Reconnect";
-"service.cells.account.caption" = "Account";
-"service.cells.account.none" = "None configured";
-"service.cells.endpoint.caption" = "Endpoint";
-"service.cells.provider.pool.caption" = "Location";
-"service.cells.provider.preset.caption" = "Preset";
-"service.cells.provider.refresh.caption" = "Refresh infrastructure";
-"service.cells.host.parameters.caption" = "Parameters";
-"service.cells.network_settings.caption" = "Network settings";
-"service.cells.vpn_survives_sleep.caption" = "Keep alive on sleep";
-"service.cells.vpn_resolves_hostname.caption" = "Resolve server hostname";
-//"service.cells.vpn_prefers_udp.caption" = "Prefer UDP socket";
-"service.cells.trusted_mobile.caption" = "Cellular network";
-"service.cells.trusted_add_wifi.caption" = "Add current Wi-Fi";
-"service.cells.trusted_policy.caption" = "Trust disables VPN";
-"service.cells.test_connectivity.caption" = "Test connectivity";
-"service.cells.data_count.caption" = "Exchanged data";
-"service.cells.data_count.none" = "Unavailable";
-"service.cells.debug_log.caption" = "Debug log";
-"service.cells.masks_private_data.caption" = "Mask network data";
-"service.cells.report_issue.caption" = "Report connectivity issue";
-
-"service.alerts.rename.title" = "Rename profile";
-"service.alerts.credentials_needed.message" = "You need to enter account credentials first.";
-"service.alerts.reconnect_vpn.message" = "Do you want to reconnect to the VPN?";
-"service.alerts.trusted.no_network.message" = "You are not connected to any Wi-Fi network.";
-"service.alerts.trusted.will_disconnect_trusted.message" = "By trusting this network, the VPN may be disconnected. Continue?";
-"service.alerts.trusted.will_disconnect_policy.message" = "By changing the trust policy, the VPN may be disconnected. Continue?";
-"service.alerts.test_connectivity.title" = "Connectivity";
-"service.alerts.test_connectivity.messages.success" = "Your device is connected to the Internet!";
-"service.alerts.test_connectivity.messages.failure" = "Your device has no Internet connectivity, please review your profile parameters.";
-"service.alerts.masks_private_data.messages.must_reconnect" = "In order to safely reset the current debug log and apply the new masking preference, you must reconnect to the VPN now.";
-"service.alerts.buttons.reconnect" = "Reconnect";
-"service.alerts.download.title" = "Download required";
-"service.alerts.download.message" = "%@ requires the download of additional configuration files.\n\nConfirm to start the download.";
-"service.alerts.download.failed" = "Failed to download configuration files. %@";
-"service.alerts.download.hud.extracting" = "Extracting files, please be patient...";
-
-"account.sections.credentials.header" = "Credentials";
-"account.sections.guidance.footer.infrastructure.mullvad" = "Use your %@ website credentials. Your username is usually numeric.";
-"account.sections.guidance.footer.infrastructure.nordvpn" = "Use your %@ website credentials. Your username is usually your e-mail.";
-"account.sections.guidance.footer.infrastructure.pia" = "Use your %@ website credentials. Your username is usually numeric with a \"p\" prefix.";
-"account.sections.guidance.footer.infrastructure.protonvpn" = "Find your %@ credentials in the \"Account > OpenVPN / IKEv2 Username\" section of the website.";
-"account.sections.guidance.footer.infrastructure.tunnelbear" = "Use your %@ website credentials. Your username is usually your e-mail.";
-"account.sections.guidance.footer.infrastructure.vyprvpn" = "Use your %@ website credentials. Your username is usually your e-mail.";
-"account.sections.guidance.footer.infrastructure.windscribe" = "Find your %@ credentials in the OpenVPN Config Generator on the website.";
-"account.sections.registration.footer" = "Go get an account on the %@ website.";
-"account.cells.username.caption" = "Username";
-"account.cells.username.placeholder" = "username";
-"account.cells.password.caption" = "Password";
-"account.cells.password.placeholder" = "secret";
-//"account.cells.password_confirm.caption" = "Confirm";
-//"account.cells.password_confirm.mismatch" = "Passwords don't match!";
-"account.cells.open_guide.caption" = "See your credentials";
-"account.cells.signup.caption" = "Register with %@";
-
-"endpoint.sections.location_addresses.header" = "Addresses";
-"endpoint.sections.location_protocols.header" = "Protocols";
-"endpoint.cells.any_address.caption" = "Automatic";
-"endpoint.cells.any_protocol.caption" = "Automatic";
-
-"provider.preset.cells.tech_details.caption" = "Technical details";
-//"provider.preset.sections.main.footer" = "Tap info button to disclose technical details.";
-
-"configuration.sections.communication.header" = "Communication";
-"configuration.sections.reset.footer" = "If you ended up with broken connectivity after changing the communication parameters, tap to revert to the original configuration.";
-"configuration.sections.tls.header" = "TLS";
-"configuration.sections.compression.header" = "Compression";
-"configuration.sections.network.header" = "Network";
-"configuration.sections.other.header" = "Other";
-"configuration.cells.cipher.caption" = "Cipher";
-"configuration.cells.digest.caption" = "Authentication";
-"configuration.cells.digest.value.embedded" = "Embedded";
-"configuration.cells.reset_original.caption" = "Reset configuration";
-"configuration.cells.client.caption" = "Client certificate";
-"configuration.cells.client.value.enabled" = "Verified";
-"configuration.cells.client.value.disabled" = "Not verified";
-"configuration.cells.tls_wrapping.caption" = "Wrapping";
-"configuration.cells.tls_wrapping.value.auth" = "Authentication";
-"configuration.cells.tls_wrapping.value.crypt" = "Encryption";
-"configuration.cells.eku.caption" = "Extended verification";
-"configuration.cells.default_gateway.caption" = "Default gateway";
-"configuration.cells.dns_server.caption" = "DNS";
-"configuration.cells.dns_domain.caption" = "Domain";
-"configuration.cells.proxy_http.caption" = "Proxy";
-"configuration.cells.proxy_https.caption" = "Proxy (HTTPS)";
-"configuration.cells.compression_framing.caption" = "Framing";
-"configuration.cells.compression_framing.value.lzo" = "--comp-lzo";
-"configuration.cells.compression_framing.value.compress" = "--compress";
-"configuration.cells.compression_algorithm.caption" = "Algorithm";
-"configuration.cells.compression_algorithm.value.lzo" = "LZO";
-"configuration.cells.compression_algorithm.value.other" = "Unsupported";
-"configuration.cells.keep_alive.caption" = "Keep-alive";
-"configuration.cells.keep_alive.value.seconds" = "%d seconds";
-"configuration.cells.renegotiation_seconds.caption" = "Renegotiation";
-"configuration.cells.renegotiation_seconds.value.after" = "after %@";
-"configuration.cells.random_endpoint.caption" = "Randomize endpoint";
-
-"network_settings.cells.choice.client" = "Read .ovpn";
-"network_settings.cells.choice.server" = "Pull from server";
-"network_settings.cells.address.caption" = "Address";
-"network_settings.cells.port.caption" = "Port";
-"network_settings.cells.add_dns_server.caption" = "Add address";
-"network_settings.cells.proxy_bypass.caption" = "Bypass domain";
-"network_settings.cells.add_proxy_bypass.caption" = "Add bypass domain";
-
-"debug_log.buttons.previous" = "Previous";
-"debug_log.buttons.next" = "Next";
-"debug_log.alerts.empty_log.message" = "The debug log is empty.";
-
-"vpn.connecting" = "Connecting";
-"vpn.active" = "Active";
-"vpn.disconnecting" = "Disconnecting";
-"vpn.inactive" = "Inactive";
-"vpn.disabled" = "Disabled";
-
-"vpn.errors.timeout" = "Timeout";
-"vpn.errors.dns" = "DNS failed";
-"vpn.errors.auth" = "Auth failed";
-"vpn.errors.tls" = "TLS failed";
-"vpn.errors.encryption" = "Encryption failed";
-"vpn.errors.compression" = "Compression unsupported";
-"vpn.errors.network" = "Network changed";
-"vpn.errors.routing" = "Missing routing";
-"vpn.errors.gateway" = "No gateway";
-
-"issue_reporter.title" = "Report issue";
-"issue_reporter.message" = "The debug log of your latest connections is crucial to resolve your connectivity issues and is completely anonymous.\n\nThe .ovpn configuration file, if any, is attached stripped of any sensitive data.\n\nPlease double check the e-mail attachments if unsure.";
-"issue_reporter.buttons.accept" = "I understand";
-
-"translations.title" = "Translations";
-
-"shortcuts.add.title" = "Add shortcut";
-"shortcuts.add.sections.vpn.header" = "VPN";
-"shortcuts.add.sections.wifi.header" = "Wi-Fi";
-"shortcuts.add.sections.cellular.header" = "Cellular";
-"shortcuts.add.cells.connect.caption" = "Connect to";
-"shortcuts.add.cells.enable_vpn.caption" = "Enable VPN";
-"shortcuts.add.cells.disable_vpn.caption" = "Disable VPN";
-"shortcuts.add.cells.trust_current_wifi.caption" = "Trust current Wi-Fi";
-"shortcuts.add.cells.untrust_current_wifi.caption" = "Untrust current Wi-Fi";
-"shortcuts.add.cells.trust_cellular.caption" = "Trust cellular network";
-"shortcuts.add.cells.untrust_cellular.caption" = "Untrust cellular network";
-"shortcuts.add.alerts.no_profiles.message" = "There is no profile to connect to.";
-
-"shortcuts.edit.title" = "Manage shortcuts";
-"shortcuts.edit.sections.all.header" = "Existing shortcuts";
-"shortcuts.edit.cells.add_shortcut.caption" = "Add shortcut";
-
-"about.title" = "About";
-"about.sections.web.header" = "Web";
-"about.sections.share.header" = "Share";
-"about.cells.credits.caption" = "Credits";
-"about.cells.website.caption" = "Home page";
-"about.cells.faq.caption" = "FAQ";
-"about.cells.disclaimer.caption" = "Disclaimer";
-"about.cells.privacy_policy.caption" = "Privacy policy";
-"about.cells.share_twitter.caption" = "Tweet about it!";
-"about.cells.share_generic.caption" = "Invite a friend";
-
-"donation.title" = "Donate";
-"donation.sections.one_time.header" = "One time";
-"donation.sections.one_time.footer" = "If you want to display gratitude for my free work, here are a couple amounts you can donate instantly.\n\nYou will only be charged once per donation, and you can donate multiple times.";
-"donation.cells.loading.caption" = "Loading donations";
-"donation.cells.purchasing.caption" = "Performing donation";
-"donation.alerts.purchase.success.title" = "Thank you";
-"donation.alerts.purchase.success.message" = "This means a lot to me and I really hope you keep using and promoting this app.";
-"donation.alerts.purchase.failure.message" = "Unable to perform the donation. %@";
-
-"share.message" = "Passepartout is an user-friendly, open source OpenVPN client for iOS and macOS";
-
-"version.title" = "Version";
-"version.labels.intro" = "Passepartout and TunnelKit are written and maintained by Davide De Rosa (keeshux).\n\nSource code for Passepartout and TunnelKit is publicly available on GitHub under the GPLv3, you can find links in the home page.\n\nPassepartout is a non-official client and is in no way affiliated with OpenVPN Inc.";
-
-"credits.title" = "Credits";
-"credits.sections.licenses.header" = "Licenses";
-"credits.sections.notices.header" = "Notices";
-"credits.sections.translations.header" = "Translations";
-
-"label.license.error" = "Unable to download full license content.";
diff --git a/Passepartout/Resources/fr.lproj/Intents.strings b/Passepartout/Resources/fr.lproj/Intents.strings
deleted file mode 100755
index 4e461f9a..00000000
--- a/Passepartout/Resources/fr.lproj/Intents.strings
+++ /dev/null
@@ -1,39 +0,0 @@
-"0jRWn5" = "Supprime le réseau cellulaire des réseaux de confiance";
-
-"1ZRTCZ" = "Désactive VPN";
-
-"66bZBE" = "Avec ${providerId} fournisseur";
-
-"7eoAss" = "Supprime le présent réseaux Wi-Fi des réseaux de confiance ";
-
-"9GpJt5" = "Ajoutes le réseau cellulaire aux réseaux de confiance";
-
-"BKxs8X" = "Ajoutes le présent réseau Wi-Fi aux réseaux de confiance";
-
-"H4taev" = "Faire confiance au réseau cellulaire";
-
-"KjkCfU" = "Connecter à une localization spécifique d'un profile de fournisseur";
-
-"LA99yM" = "Se connecter au VPN";
-
-"U6o81V" = "Se connecter à ${profileId}";
-
-"WnTPFg" = "Se connecter à ${poolName}";
-
-"eQ1yzr" = "Désactives le service VPN";
-
-"eXXb2z" = "Connectes à un profile hôte";
-
-"lQ6ziK" = "Activer VPN";
-
-"m2E7SI" = "Faire confiance au présent réseau Wi-Fi";
-
-"qo3Szz" = "Se connecter à la localisation du fournisseur";
-
-"rd1T8p" = "Ne plus faire confiance au présent réseau Wi-Fi";
-
-"wB1iYX" = "Faire confiance au présent réseau cellulaire";
-
-"xY97Vu" = "Activer le service VPN avec le profile présentement utilisé";
-
-"NCoK9B" = "Avec le profile utilisé";
diff --git a/Passepartout/Resources/fr.lproj/Localizable.strings b/Passepartout/Resources/fr.lproj/Localizable.strings
deleted file mode 100755
index 3b60920a..00000000
--- a/Passepartout/Resources/fr.lproj/Localizable.strings
+++ /dev/null
@@ -1,283 +0,0 @@
-//
-// Localizable.strings
-// Passepartout
-//
-// Created by Davide De Rosa on 6/13/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-"global.ok" = "OK";
-"global.cancel" = "Annuler";
-"global.next" = "Suivant";
-"global.close" = "Fermer";
-"global.host.title_input.message" = "Caractères acceptables sont alphanumériques et tiret \"-\", barre de soulignement \"_\" et point \".\".";
-"global.host.title_input.placeholder" = "Mon profile";
-"global.email_not_configured" = "Aucun compte courriel n'est configuré.";
-
-"global.cells.enabled" = "Activer";
-"global.cells.disabled" = "Désactiver";
-"global.cells.none" = "Aucun";
-"global.cells.automatic" = "Automatique";
-"global.cells.manual" = "Manuel";
-
-"reddit.title" = "Reddit";
-"reddit.message" = "Saviez-vous que Passepartout a un subreddit? Souscrivez pour les mises à jour ou discuter des problèmes, caractéristiques, nouvelles plateformes ou quoi que ce soit.\n\nC'est aussi une très bonne façon de démontrer votre enthousiasme envers le projet.";
-"reddit.buttons.subscribe" = "Souscrivez maintenant!";
-"reddit.buttons.remind" = "Me rappeler plus tard";
-"reddit.buttons.never" = "Ne pas me redemander";
-
-"organizer.sections.providers.header" = "Fournisseurs";
-"organizer.sections.providers.footer" = "Ici vous pouvez trousers certains fournisseurs avec des profiles déjà configurés.";
-"organizer.sections.hosts.header" = "Hôtes";
-"organizer.sections.hosts.footer" = "Importer des hôtes d'un fichier de configuration .ovpn.";
-"organizer.sections.siri.header" = "Siri";
-"organizer.sections.siri.footer" = "Obtenez de l'aide de Siri pour accélérer vos intéractions les plus courantes avec l'app.";
-"organizer.sections.support.header" = "Support";
-"organizer.sections.feedback.header" = "Commentaires";
-"organizer.cells.profile.value.current" = "En utilisation";
-"organizer.cells.add_provider.caption" = "Ajouter un nouveau fournisseur";
-"organizer.cells.add_host.caption" = "Ajouter un nouvel hôte";
-"organizer.cells.siri_shortcuts.caption" = "Gérer les raccourcis";
-"organizer.cells.join_community.caption" = "Joindre la communauté";
-"organizer.cells.write_review.caption" = "Écrire un avis";
-"organizer.cells.donate.caption" = "Faire un don";
-"organizer.cells.patreon.caption" = "Me supporter sur Patreon";
-"organizer.cells.translate.caption" = "Offrir de traduire";
-"organizer.cells.about.caption" = "À propos %@";
-"organizer.cells.uninstall.caption" = "Supprimer la configuration VPN";
-"organizer.alerts.exhausted_providers.message" = "Vous avez créé un profile pour un fournisseur existant.";
-"organizer.alerts.add_host.message" = "Ouvrir un URL vers un fichier de configuration .ovpn depuis Safari, Courriels ou un autre app pour installer un profile hôte.\n\nVous pouvez importer une configuration .ovpn avec le transfert de fichiers iTunes.";
-"organizer.alerts.cannot_donate.message" = "Il n'y a aucune méthode de paiement configuré sur cet appareil.";
-"organizer.alerts.delete_vpn_profile.message" = "Voulez-vous vraiment effacer la configuration VPN de vos paramètres? Ceci peux fixer certains VPN en arrêt et n'affectera pas vos profiles de fournisseurs et hôtes.";
-
-"wizards.host.cells.title_input.caption" = "Titre";
-"wizards.host.sections.existing.header" = "Profiles existants";
-"wizards.host.alerts.existing.message" = "Un profile hôte avec ce même nom existe déjà. Le remplacer?";
-
-"parsed_file.alerts.malformed.message" = "Le fichier de configuration contient une mauvaise option.(%@).";
-"parsed_file.alerts.missing.message" = "Le fichier de configuration ne contient pas une option requise. (%@).";
-"parsed_file.alerts.unsupported.message" = "Le fichier de configuration contient une option non supportée (%@).";
-"parsed_file.alerts.potentially_unsupported.message" = "Le fichier de configuration est adéquat, mais contient une option potentiellement non supportée. (%@).\n\nLa connection peut être perdue selon les paramètres du serveur.";
-"parsed_file.alerts.encryption_passphrase.message" = "Veuillez entrer le mot de passe d'encryption.";
-"parsed_file.alerts.decryption.message" = "Le fichier de configuration contient une clé privée encryptée et n'a pas été décryptée. Veuillez revérifier votre mot de passe.";
-"parsed_file.alerts.parsing.message" = "Incapable d'analyser le fichier de configuration fournis. (%@).";
-"parsed_file.alerts.buttons.report" = "Rapporter un problème";
-
-"imported_hosts.title" = "Hôtes importés";
-
-"service.welcome.message" = "Bienvenue à Passepartout!\n\nUtilisez l'organiseur pour ajouter un nouveau profile.";
-"service.sections.general.header" = "Général";
-"service.sections.vpn.header" = "VPN";
-"service.sections.vpn.footer" = "La connection sera établie lorsque nécessaire.";
-"service.sections.status.header" = "Connection";
-"service.sections.configuration.header" = "Configuration";
-"service.sections.provider_infrastructure.footer" = "Mis à jour : %@.";
-"service.sections.vpn_survives_sleep.footer" = "Désactiver pour augmenter l'autonomie de la batterie, au dépends de la rapidité au réveil pour la reconnection.";
-"service.sections.vpn_resolves_hostname.footer" = "Préféré dans la plus part des réseaux et requis dans certains réseaux IPv6. Désactiver lorsque le DNS est bloqué ou pour augmenter la rapidité des négociations lorsque le DNS est lent à répondre.";
-//"service.sections.vpn_prefers_udp.footer" = "UDP est plus rapide que le TCP, mais peut ne pas fonctionner sur certains réseaux. Désactiver dans les réseaux où UDP peut être bloqué.";
-"service.sections.trusted.header" = "Réseaux de confiance";
-"service.sections.trusted.footer" = "Lors d'une connection à un réseau de confiance, le VPN est normalement fermé. Désactivez cette option pour ne pas autoriser ce comportement.";
-"service.sections.diagnostics.header" = "Diagnostiques";
-"service.sections.diagnostics.footer" = "Camouflage du status sera effectif après la reconnection. Les données réseaux sont les noms d'hôtes, adresses IP, routage, SSID. Les identifiants et clés privés ne sont pas enregistrés.";
-//"service.sections.destruction.footer" = "Supprimer la configuration des réglages de l'appareil.";
-
-"service.cells.use_profile.caption" = "Utiliser ce profile";
-"service.cells.vpn_service.caption" = "Activer";
-"service.cells.connection_status.caption" = "Status";
-"service.cells.reconnect.caption" = "Reconnecter";
-"service.cells.account.caption" = "Compte";
-"service.cells.account.none" = "Aucun configuré";
-"service.cells.endpoint.caption" = "Extrémité";
-"service.cells.provider.pool.caption" = "Locallisation";
-"service.cells.provider.preset.caption" = "Préréglage";
-"service.cells.provider.refresh.caption" = "Rafraîchir l'infrastructure";
-"service.cells.host.parameters.caption" = "Paramètres";
-"service.cells.network_settings.caption" = "Paramètres réseaux";
-"service.cells.vpn_survives_sleep.caption" = "Garder actif lors de la veille";
-"service.cells.vpn_resolves_hostname.caption" = "Résoudre le nom d'hôte du serveur";
-//"service.cells.vpn_prefers_udp.caption" = "Préférer connection UDP";
-"service.cells.trusted_mobile.caption" = "Réseau cellulaire";
-"service.cells.trusted_add_wifi.caption" = "Ajouter le présent Wi-Fi";
-"service.cells.trusted_policy.caption" = "La confiance désactive le VPN";
-"service.cells.test_connectivity.caption" = "Tester la connection";
-"service.cells.data_count.caption" = "Échanger les données";
-"service.cells.data_count.none" = "Indisponible";
-"service.cells.debug_log.caption" = "Journal de débogage";
-"service.cells.masks_private_data.caption" = "Masquer les données de réseau";
-"service.cells.report_issue.caption" = "Rapporter un problème de connection";
-
-"service.alerts.rename.title" = "Renommer le profile";
-"service.alerts.credentials_needed.message" = "Vous devez entrer les identifiants de compte premièrement.";
-"service.alerts.reconnect_vpn.message" = "Voulez-vous reconnecter le VPN?";
-"service.alerts.trusted.no_network.message" = "Vous n'êtes pas connectés à aucun réseau Wi-Fi.";
-"service.alerts.trusted.will_disconnect_trusted.message" = "En faisant confiance à ce réseau, le VPN pourrait être déconnecté. Continuer?";
-"service.alerts.trusted.will_disconnect_policy.message" = "En changeant la stratégie de confiance, le VPN pourrait être déconnecté. Continuer?";
-"service.alerts.test_connectivity.title" = "Connections";
-"service.alerts.test_connectivity.messages.success" = "Votre appareil est connecté à Internet!";
-"service.alerts.test_connectivity.messages.failure" = "Votre appareil n'a aucune connection Invernet, veuillez vérifier vos paramètres de profile.";
-"service.alerts.masks_private_data.messages.must_reconnect" = "Pour bien réinitialiser le registre de diagnostique et appliquer les préférences de camouflage, vous devez vous reconnecter au VPN maintenant.";
-"service.alerts.buttons.reconnect" = "Reconnecter";
-"service.alerts.download.title" = "Téléchargement requis";
-"service.alerts.download.message" = "%@ requiert le téléchargement de fichiers de configuration supplémentaires.\n\nConfirmer le début du téléchargement.";
-"service.alerts.download.failed" = "Échec de téléchargement des fichiers de configuration. %@";
-"service.alerts.download.hud.extracting" = "Extraction des fichiers, veuillez patienter...";
-
-"account.sections.credentials.header" = "Indetifiants";
-"account.sections.guidance.footer.infrastructure.mullvad" = "Utilisez votre identifiants web de %@. Votre nom d'utilisateur est normalement numérique.";
-"account.sections.guidance.footer.infrastructure.nordvpn" = "Utilisez votre identifiants web de %@. Votre nom d'utilisateur est normalement votre courriel.";
-"account.sections.guidance.footer.infrastructure.pia" = "Utilisez votre identifiants web de %@. Votre nom d'utilisateur est normalement numérique avec le préfixe \"p\" ";
-"account.sections.guidance.footer.infrastructure.protonvpn" = "Trouvez votre identifiant web %@ dans la section du site web \"Account > OpenVPN / IKEv2 nom d'utilisateur\" ";
-"account.sections.guidance.footer.infrastructure.tunnelbear" = "Utilisez votre identifiants web de %@. Votre nom d'utilisateur est normalement votre courriel.";
-"account.sections.guidance.footer.infrastructure.vyprvpn" = "Utilisez votre identifiants web de %@. Votre nom d'utilisateur est normalement votre courriel.";
-"account.sections.guidance.footer.infrastructure.windscribe" = "Trouver votre identifiant %@ dans la section web Générateur de configuration OpenVPN.";
-"account.sections.registration.footer" = "Allez créer un compte sur le site %@.";
-"account.cells.username.caption" = "Nom d'utilisateur";
-"account.cells.username.placeholder" = "nom d'utilisateur";
-"account.cells.password.caption" = "Mot de passe";
-"account.cells.password.placeholder" = "secret";
-//"account.cells.password_confirm.caption" = "Confirmer";
-//"account.cells.password_confirm.mismatch" = "Les mots de passe ne correspondent pas!";
-"account.cells.open_guide.caption" = "Voir vos identifiants";
-"account.cells.signup.caption" = "S'inscrire avec %@";
-
-"endpoint.sections.location_addresses.header" = "Adresses";
-"endpoint.sections.location_protocols.header" = "Protocols";
-"endpoint.cells.any_address.caption" = "Automatique";
-"endpoint.cells.any_protocol.caption" = "Automatique";
-
-"provider.preset.cells.tech_details.caption" = "Détails techniques";
-//"provider.preset.sections.main.footer" = "Tapotez le bouton info pour voir les détails techniques.";
-
-"configuration.sections.communication.header" = "Communications";
-"configuration.sections.reset.footer" = "Si vous obtenez une connection erronnée après le changement des parameters de communication, tapotez pour revenir à la configuration initiale.";
-"configuration.sections.tls.header" = "TLS";
-"configuration.sections.compression.header" = "Compression";
-"configuration.sections.network.header" = "Réseau";
-"configuration.sections.other.header" = "Autre";
-"configuration.cells.cipher.caption" = "Cryptogramme";
-"configuration.cells.digest.caption" = "Authentification";
-"configuration.cells.digest.value.embedded" = "Intégré";
-"configuration.cells.reset_original.caption" = "Réinitialiser la configuration";
-"configuration.cells.client.caption" = "Certificat du client";
-"configuration.cells.client.value.enabled" = "Verifié";
-"configuration.cells.client.value.disabled" = "Non vérifié";
-"configuration.cells.tls_wrapping.caption" = "Wrapping";
-"configuration.cells.tls_wrapping.value.auth" = "Authentification";
-"configuration.cells.tls_wrapping.value.crypt" = "Cryptage";
-"configuration.cells.eku.caption" = "Vérification étendue";
-"configuration.cells.default_gateway.caption" = "Passerelle par défaut";
-"configuration.cells.dns_server.caption" = "DNS";
-"configuration.cells.dns_domain.caption" = "Domaine";
-"configuration.cells.proxy_http.caption" = "Proxy";
-"configuration.cells.proxy_https.caption" = "Proxy (HTTPS)";
-"configuration.cells.compression_framing.caption" = "Framing";
-"configuration.cells.compression_framing.value.lzo" = "--comp-lzo";
-"configuration.cells.compression_framing.value.compress" = "--compress";
-"configuration.cells.compression_algorithm.caption" = "Algorithme";
-"configuration.cells.compression_algorithm.value.lzo" = "LZO";
-"configuration.cells.compression_algorithm.value.other" = "Non supporté";
-"configuration.cells.keep_alive.caption" = "Garder actif";
-"configuration.cells.keep_alive.value.seconds" = "%d secondes";
-"configuration.cells.renegotiation_seconds.caption" = "Renégociation";
-"configuration.cells.renegotiation_seconds.value.after" = "aprè %@";
-"configuration.cells.random_endpoint.caption" = "Extrémité aléatoire";
-
-"network_settings.cells.choice.client" = "Lire .ovpn";
-"network_settings.cells.choice.server" = "Récupérer depuis le serveur";
-"network_settings.cells.address.caption" = "Adresse";
-"network_settings.cells.port.caption" = "Port";
-"network_settings.cells.add_dns_server.caption" = "Ajouter une adresse";
-"network_settings.cells.proxy_bypass.caption" = "Outrepasser le domaine";
-"network_settings.cells.add_proxy_bypass.caption" = "Ajouter outrepasser le domaine";
-
-"debug_log.buttons.previous" = "Précédent";
-"debug_log.buttons.next" = "Suivant";
-"debug_log.alerts.empty_log.message" = "Le journal de débogage est vide. ";
-
-"vpn.connecting" = "Connection...";
-"vpn.active" = "Actif";
-"vpn.disconnecting" = "Déconnection...";
-"vpn.inactive" = "Inactid";
-"vpn.disabled" = "Désactivé";
-
-"vpn.errors.timeout" = "Délais dépassé";
-"vpn.errors.dns" = "Échec DNS";
-"vpn.errors.auth" = "Échec Auth";
-"vpn.errors.tls" = "Échec TLS";
-"vpn.errors.encryption" = "Échec du cryptage";
-"vpn.errors.compression" = "Compression non supportée";
-"vpn.errors.network" = "Réseau modifié";
-"vpn.errors.routing" = "Routage manquant";
-"vpn.errors.gateway" = "Aucune passerelle";
-
-"issue_reporter.title" = "Rapporter un problème";
-"issue_reporter.message" = "Le journal débogage de votre dernière connection est crucial pour résoudre vos problèmes de connection et est entièrement anonyme.\n\nLe fichier de configuration .ovpn, si disponible, est attaché et supprimé de toute information confidentielle.\n\nVeuillez contre-vérifier les fichiers attachés au courriel si incertain.";
-"issue_reporter.buttons.accept" = "Je comprends";
-
-"translations.title" = "Traductions";
-
-"shortcuts.add.title" = "Ajouter un raccourcis";
-"shortcuts.add.sections.vpn.header" = "VPN";
-"shortcuts.add.sections.wifi.header" = "Wi-Fi";
-"shortcuts.add.sections.cellular.header" = "Cellulaire";
-"shortcuts.add.cells.connect.caption" = "Connecter à";
-"shortcuts.add.cells.enable_vpn.caption" = "Activer VPN";
-"shortcuts.add.cells.disable_vpn.caption" = "Désactiver VPN";
-"shortcuts.add.cells.trust_current_wifi.caption" = "Faire confiance au présent réseau Wi-Fi";
-"shortcuts.add.cells.untrust_current_wifi.caption" = "Retirer le présent réseau Wi-Fi des réseaux de confiance.";
-"shortcuts.add.cells.trust_cellular.caption" = "Faire confiance au présent réseau cellulaire";
-"shortcuts.add.cells.untrust_cellular.caption" = "Retirer le présent réseau cellulaire des réseaux de confiance.";
-"shortcuts.add.alerts.no_profiles.message" = "Il n'y a aucun profile pour se connecter.";
-
-"shortcuts.edit.title" = "Gérer les raccourcis";
-"shortcuts.edit.sections.all.header" = "Raccourcis existants";
-"shortcuts.edit.cells.add_shortcut.caption" = "Ajouter un raccourcis";
-
-"about.title" = "À propos";
-"about.sections.web.header" = "Web";
-"about.sections.share.header" = "Partager";
-"about.cells.credits.caption" = "Crédits";
-"about.cells.website.caption" = "Page d'accueil";
-"about.cells.faq.caption" = "FAQ";
-"about.cells.disclaimer.caption" = "Avis de non-responsabilité";
-"about.cells.privacy_policy.caption" = "Politique de la vie privée";
-"about.cells.share_twitter.caption" = "Tweetez!";
-"about.cells.share_generic.caption" = "Inviter un amis";
-
-"donation.title" = "Faire un don";
-"donation.sections.one_time.header" = "Une seule fois";
-"donation.sections.one_time.footer" = "Si vous voulez manifester votre gratitude envers mon travail bénévole, voici certains montants pour faire un don instantanément.\n\n Vous n'allez être chargé qu'une seule fois par don et vous pouvez faire un don plus d'une fois.";
-"donation.cells.loading.caption" = "Chargement des dons";
-"donation.cells.purchasing.caption" = "Don en cours";
-"donation.alerts.purchase.success.title" = "Merci";
-"donation.alerts.purchase.success.message" = "Ceci signifie beaucoup pour moi et j'espère sincèrement que vous continuerez d'utiliser et de promouvoir cette app.";
-"donation.alerts.purchase.failure.message" = "Impossible de faire le don. %@";
-
-"share.message" = "Passepartout est un client OpenVPN simple d'utilisation et open source pour iOs et macOS";
-
-"version.title" = "Version";
-"version.labels.intro" = "Passepartout et TunnelKit sont codés et maintenu par Davide De Rosa (keeshux).\n\nLe code source de Passepartout et TunnelKit est publiquement disponible sur GitHub sous license GPLv3, vous pouvez trouver les liens sur la page d'accueil.\n\nPassepartout est un client non-officiel et n'est aucunement affilié avec OpenVPN Inc.";
-
-"credits.title" = "Crédits";
-"credits.sections.licenses.header" = "Licenses";
-"credits.sections.notices.header" = "Préavis";
-"credits.sections.translations.header" = "Traductions";
-
-"label.license.error" = "Impossible de télécharger le contenu complet de la license.";
diff --git a/Passepartout/Resources/it.lproj/Intents.strings b/Passepartout/Resources/it.lproj/Intents.strings
deleted file mode 100644
index 41325f6e..00000000
--- a/Passepartout/Resources/it.lproj/Intents.strings
+++ /dev/null
@@ -1,39 +0,0 @@
-"0jRWn5" = "Rimuove la rete mobile dalle reti sicure";
-
-"1ZRTCZ" = "Disabilita VPN";
-
-"66bZBE" = "Con il provider ${providerId}";
-
-"7eoAss" = "Rimuove la Wi-Fi corrente dalle reti sicure";
-
-"9GpJt5" = "Aggiunge la rete mobile alle reti sicure";
-
-"BKxs8X" = "Aggiunge la Wi-Fi corrente alle reti sicure";
-
-"H4taev" = "Aggiungi rete mobile sicura";
-
-"KjkCfU" = "Avvia una connessione ad una regione specifica di un provider";
-
-"LA99yM" = "Connetti alla VPN";
-
-"U6o81V" = "Connettiti a ${profileId}";
-
-"WnTPFg" = "Connettiti in ${poolName}";
-
-"eQ1yzr" = "Disabilita il servizio VPN";
-
-"eXXb2z" = "Avvia la connessione ad un host";
-
-"lQ6ziK" = "Abilita VPN";
-
-"m2E7SI" = "Aggiungi Wi-Fi sicura";
-
-"qo3Szz" = "Connettiti a una regione del provider";
-
-"rd1T8p" = "Rimuovi Wi-Fi sicura";
-
-"wB1iYX" = "Rimuovi rete mobile sicura";
-
-"xY97Vu" = "Abilita il servizio VPN con il profilo attualmente in uso";
-
-"NCoK9B" = "Con il profilo in uso";
diff --git a/Passepartout/Resources/it.lproj/Localizable.strings b/Passepartout/Resources/it.lproj/Localizable.strings
deleted file mode 100644
index e122ab3d..00000000
--- a/Passepartout/Resources/it.lproj/Localizable.strings
+++ /dev/null
@@ -1,283 +0,0 @@
-//
-// Localizable.strings
-// Passepartout
-//
-// Created by Davide De Rosa on 6/13/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-"global.ok" = "OK";
-"global.cancel" = "Annulla";
-"global.next" = "Avanti";
-"global.close" = "Chiudi";
-"global.host.title_input.message" = "I caratteri ammessi sono gli alfanumerici e il trattino breve \"-\", il trattino basso \"_\" ed il punto \".\".";
-"global.host.title_input.placeholder" = "Il mio profilo";
-"global.email_not_configured" = "Nessun account e-mail configurato.";
-
-"global.cells.enabled" = "Abilitato";
-"global.cells.disabled" = "Disabilitato";
-"global.cells.none" = "Nessuno";
-"global.cells.automatic" = "Automatico";
-"global.cells.manual" = "Manuale";
-
-"reddit.title" = "Reddit";
-"reddit.message" = "Sapevi che Passepartout ha un subreddit? Iscriviti per aggiornamenti o per discutere problemi, aggiunte, nuove piattaforme o qualunque cosa tu voglia.\n\nÈ anche un ottimo modo per dimostrare che hai a cuore questo progetto.";
-"reddit.buttons.subscribe" = "Iscriviti ora!";
-"reddit.buttons.remind" = "Ricordami più tardi";
-"reddit.buttons.never" = "Non chiedere più";
-
-"organizer.sections.providers.header" = "Provider";
-"organizer.sections.providers.footer" = "Qui trovi alcuni provider con configurazioni precompilate.";
-"organizer.sections.hosts.header" = "Host";
-"organizer.sections.hosts.footer" = "Importa un host da un file di configurazione .ovpn.";
-"organizer.sections.siri.header" = "Siri";
-"organizer.sections.siri.footer" = "Chiedi aiuto a Siri per velocizzare le tue interazioni più frequenti con l'app.";
-"organizer.sections.support.header" = "Supporto";
-"organizer.sections.feedback.header" = "Feedback";
-"organizer.cells.profile.value.current" = "In uso";
-"organizer.cells.add_provider.caption" = "Aggiungi provider";
-"organizer.cells.add_host.caption" = "Aggiungi host";
-"organizer.cells.siri_shortcuts.caption" = "Gestisci comandi rapidi";
-"organizer.cells.join_community.caption" = "Entra nella community";
-"organizer.cells.write_review.caption" = "Scrivi una recensione";
-"organizer.cells.donate.caption" = "Fai una donazione";
-"organizer.cells.patreon.caption" = "Supportami su Patreon";
-"organizer.cells.translate.caption" = "Offri una traduzione";
-"organizer.cells.about.caption" = "Informazioni su %@";
-"organizer.cells.uninstall.caption" = "Rimuovi configurazione VPN";
-"organizer.alerts.exhausted_providers.message" = "Hai creato profili per tutti i provider disponibili.";
-"organizer.alerts.add_host.message" = "Apri l'URL di un file di configurazione .ovpn da Safari, Mail o da un'altra app per configurare un host.\n\nPuoi anche importare un file .ovpn con iTunes File Sharing.";
-"organizer.alerts.cannot_donate.message" = "Nessun metodo di pagamento configurato su questo dispositivo.";
-"organizer.alerts.delete_vpn_profile.message" = "Vuoi veramente cancellare la configurazione VPN dalle impostazioni del tuo dispositivo? Quest'azione potrebbe risolvere alcuni stati erronei della VPN e non altererà i tuoi provider e i tuoi host.";
-
-"wizards.host.cells.title_input.caption" = "Titolo";
-"wizards.host.sections.existing.header" = "Profili esistenti";
-"wizards.host.alerts.existing.message" = "Esiste già un host con lo stesso titolo. Sostituire?";
-
-"parsed_file.alerts.malformed.message" = "La configurazione contiene un'opzione malformata (%@).";
-"parsed_file.alerts.missing.message" = "La configurazione non contiene un'opzione obbligatoria (%@).";
-"parsed_file.alerts.unsupported.message" = "La configurazione contiene un'opzione non supportata (%@).";
-"parsed_file.alerts.potentially_unsupported.message" = "La configurazione è corretto ma contiene un'opzione potenzialmente non supportata (%@).\n\nLa connettività potrebbe fallire a seconda delle impostazioni del server.";
-"parsed_file.alerts.encryption_passphrase.message" = "Per favore inserisci la passphrase di criptazione.";
-"parsed_file.alerts.decryption.message" = "La configurazione contiene una chiave privata criptata e non è stato possibile decriptarla. Controlla la tua passphrase.";
-"parsed_file.alerts.parsing.message" = "Impossibile processare il file di configurazione specificato (%@).";
-"parsed_file.alerts.buttons.report" = "Segnala un problema";
-
-"imported_hosts.title" = "Host importati";
-
-"service.welcome.message" = "Benvenuto in Passepartout!\n\nUsa il menu per aggiungere un nuovo profilo.";
-"service.sections.general.header" = "Generale";
-"service.sections.vpn.header" = "VPN";
-"service.sections.vpn.footer" = "La connessione sarà stabilita ogni volta che è necessario.";
-"service.sections.status.header" = "Connessione";
-"service.sections.configuration.header" = "Configurazione";
-"service.sections.provider_infrastructure.footer" = "Ultimo aggiornamento: %@.";
-"service.sections.vpn_survives_sleep.footer" = "Disabilita per migliorare il consumo della batteria, a discapito di rallentamenti occasionali causati dalle riconnessioni.";
-"service.sections.vpn_resolves_hostname.footer" = "Preferibile nella maggior parte delle reti e necessario in alcune reti IPv6. Disabilita dove il DNS è bloccato, o per velocizzare la negoziazione quando il DNS tarda a rispondere.";
-//"service.sections.vpn_prefers_udp.footer" = "UDP is faster than TCP, but may not work in some networks. Disable in networks where UDP might be blocked.";
-"service.sections.trusted.header" = "Reti sicure";
-"service.sections.trusted.footer" = "Entrando in una rete sicura, normalmente la VPN viene spenta e mantenuta disconnessa. Disabilita quest'opzione per non imporre questo comportamento.";
-"service.sections.diagnostics.header" = "Diagnostica";
-"service.sections.diagnostics.footer" = "Il mascheramento sarà effettivo dopo una riconnessione. I dati di rete sono hostname, indirizzi IP, routing, SSID. Credenziali e chiavi private non sono registrati in ogni caso.";
-//"service.sections.destruction.footer" = "Delete configuration from device settings.";
-
-"service.cells.use_profile.caption" = "Usa questo profilo";
-"service.cells.vpn_service.caption" = "Abilitato";
-"service.cells.connection_status.caption" = "Stato";
-"service.cells.reconnect.caption" = "Riconnetti";
-"service.cells.account.caption" = "Account";
-"service.cells.account.none" = "Non configurato";
-"service.cells.endpoint.caption" = "Endpoint";
-"service.cells.provider.pool.caption" = "Regione";
-"service.cells.provider.preset.caption" = "Preset";
-"service.cells.provider.refresh.caption" = "Aggiorna infrastruttura";
-"service.cells.host.parameters.caption" = "Parametri";
-"service.cells.network_settings.caption" = "Impostazioni di rete";
-"service.cells.vpn_survives_sleep.caption" = "Mantieni attivo in sleep";
-"service.cells.vpn_resolves_hostname.caption" = "Risolvi hostname del server";
-//"service.cells.vpn_prefers_udp.caption" = "Prefer UDP socket";
-"service.cells.trusted_mobile.caption" = "Rete cellulare";
-"service.cells.trusted_add_wifi.caption" = "Aggiungi Wi-Fi corrente";
-"service.cells.trusted_policy.caption" = "Spegni VPN in rete sicura";
-"service.cells.test_connectivity.caption" = "Verifica connettività";
-"service.cells.data_count.caption" = "Dati scambiati";
-"service.cells.data_count.none" = "Non disponibile";
-"service.cells.debug_log.caption" = "Debug log";
-"service.cells.masks_private_data.caption" = "Maschera dati rete";
-"service.cells.report_issue.caption" = "Segnala problema connettività";
-
-"service.alerts.rename.title" = "Rinomina profilo";
-"service.alerts.credentials_needed.message" = "Devi prima inserire le tue credenziali.";
-"service.alerts.reconnect_vpn.message" = "Vuoi riconnetterti alla VPN?";
-"service.alerts.trusted.no_network.message" = "Non sei connesso/a a nessuna rete Wi-Fi.";
-"service.alerts.trusted.will_disconnect_trusted.message" = "Rendendo questa rete sicura, la VPN potrebbe essere disconnessa. Continuare?";
-"service.alerts.trusted.will_disconnect_policy.message" = "Cambiando la politica delle reti sicure, la VPN potrebbe essere disconnessa. Continuare?";
-"service.alerts.test_connectivity.title" = "Connettività";
-"service.alerts.test_connectivity.messages.success" = "Il tuo dispositivo è connesso a Internet!";
-"service.alerts.test_connectivity.messages.failure" = "Il tuo dispositivo non è connesso a Internet, per favore controlla i parametri del tuo profilo.";
-"service.alerts.masks_private_data.messages.must_reconnect" = "Per azzerare il debug log ed applicare la nuova preferenza di mascheramento, devi riconnetterti alla VPN.";
-"service.alerts.buttons.reconnect" = "Riconnetti";
-"service.alerts.download.title" = "Download necessario";
-"service.alerts.download.message" = "%@ richiede lo scaricamento di file di configurazione aggiuntivi.\n\nConferma per avviare lo scaricamento.";
-"service.alerts.download.failed" = "Impossibile scaricare i file di configurazione. %@";
-"service.alerts.download.hud.extracting" = "Estraendo i file, un attimo di pazienza...";
-
-"account.sections.credentials.header" = "Credenziali";
-"account.sections.guidance.footer.infrastructure.mullvad" = "Usa le credenziali del sito di %@. Il tuo username è generalmente numerico.";
-"account.sections.guidance.footer.infrastructure.nordvpn" = "Usa le credenziali del sito di %@. Il tuo username è generalmente la tua e-mail.";
-"account.sections.guidance.footer.infrastructure.pia" = "Usa le credenziali del sito di %@. Il tuo username è generalmente numerico con un prefisso \"p\".";
-"account.sections.guidance.footer.infrastructure.protonvpn" = "Trova le tue credenziali nella sezione \"Account > OpenVPN / IKEv2 Username\" del sito di %@.";
-"account.sections.guidance.footer.infrastructure.tunnelbear" = "Usa le credenziali del sito di %@. Il tuo username è generalmente la tua e-mail.";
-"account.sections.guidance.footer.infrastructure.vyprvpn" = "Usa le credenziali del sito di %@. Il tuo username è generalmente la tua e-mail.";
-"account.sections.guidance.footer.infrastructure.windscribe" = "Trova le tue credenziali nell'OpenVPN Config Generator sul sito di %@.";
-"account.sections.registration.footer" = "Registra un account sul sito di %@.";
-"account.cells.username.caption" = "Username";
-"account.cells.username.placeholder" = "username";
-"account.cells.password.caption" = "Password";
-"account.cells.password.placeholder" = "segreto";
-//"account.cells.password_confirm.caption" = "Confirm";
-//"account.cells.password_confirm.mismatch" = "Passwords don't match!";
-"account.cells.open_guide.caption" = "Vedi le tue credenziali";
-"account.cells.signup.caption" = "Registrati con %@";
-
-"endpoint.sections.location_addresses.header" = "Indirizzi";
-"endpoint.sections.location_protocols.header" = "Protocolli";
-"endpoint.cells.any_address.caption" = "Automatico";
-"endpoint.cells.any_protocol.caption" = "Automatico";
-
-"provider.preset.cells.tech_details.caption" = "Dettagli tecnici";
-//"provider.preset.sections.main.footer" = "Tap info button to disclose technical details.";
-
-"configuration.sections.communication.header" = "Comunicazione";
-"configuration.sections.reset.footer" = "Se ti trovi con una connettività compromessa dopo aver cambiato i parametri di comunicazione, tocca per tornare alla configurazione originale.";
-"configuration.sections.tls.header" = "TLS";
-"configuration.sections.compression.header" = "Compressione";
-"configuration.sections.network.header" = "Rete";
-"configuration.sections.other.header" = "Altro";
-"configuration.cells.cipher.caption" = "Cifratura";
-"configuration.cells.digest.caption" = "Autenticazione";
-"configuration.cells.digest.value.embedded" = "Incorporata";
-"configuration.cells.reset_original.caption" = "Ripristina configurazione";
-"configuration.cells.client.caption" = "Certificato client";
-"configuration.cells.client.value.enabled" = "Verificato";
-"configuration.cells.client.value.disabled" = "Non verificato";
-"configuration.cells.tls_wrapping.caption" = "Wrapping";
-"configuration.cells.tls_wrapping.value.auth" = "Autenticazione";
-"configuration.cells.tls_wrapping.value.crypt" = "Criptazione";
-"configuration.cells.eku.caption" = "Verifica estesa";
-"configuration.cells.default_gateway.caption" = "Gateway predefinito";
-"configuration.cells.dns_server.caption" = "Indirizzo";
-"configuration.cells.dns_domain.caption" = "Dominio";
-"configuration.cells.proxy_http.caption" = "Proxy";
-"configuration.cells.proxy_https.caption" = "Proxy (HTTPS)";
-"configuration.cells.compression_framing.caption" = "Framing";
-"configuration.cells.compression_framing.value.lzo" = "--comp-lzo";
-"configuration.cells.compression_framing.value.compress" = "--compress";
-"configuration.cells.compression_algorithm.caption" = "Algoritmo";
-"configuration.cells.compression_algorithm.value.lzo" = "LZO";
-"configuration.cells.compression_algorithm.value.other" = "Non supportato";
-"configuration.cells.keep_alive.caption" = "Keep-alive";
-"configuration.cells.keep_alive.value.seconds" = "%d secondi";
-"configuration.cells.renegotiation_seconds.caption" = "Rinegoziazione";
-"configuration.cells.renegotiation_seconds.value.after" = "dopo %@";
-"configuration.cells.random_endpoint.caption" = "Endpoint casuale";
-
-"network_settings.cells.choice.client" = "Leggi .ovpn";
-"network_settings.cells.choice.server" = "Ottieni dal server";
-"network_settings.cells.address.caption" = "Indirizzo";
-"network_settings.cells.port.caption" = "Porta";
-"network_settings.cells.add_dns_server.caption" = "Aggiungi indirizzo";
-"network_settings.cells.proxy_bypass.caption" = "Dominio ignorato";
-"network_settings.cells.add_proxy_bypass.caption" = "Aggiungi dominio ignorato";
-
-"debug_log.buttons.previous" = "Precedente";
-"debug_log.buttons.next" = "Successivo";
-"debug_log.alerts.empty_log.message" = "Il debug log è vuoto.";
-
-"vpn.connecting" = "Connettendo";
-"vpn.active" = "Attiva";
-"vpn.disconnecting" = "Disconnettendo";
-"vpn.inactive" = "Inattiva";
-"vpn.disabled" = "Disabilitata";
-
-"vpn.errors.timeout" = "Timeout";
-"vpn.errors.dns" = "DNS fallito";
-"vpn.errors.auth" = "Autenticazione fallita";
-"vpn.errors.tls" = "TLS fallito";
-"vpn.errors.encryption" = "Crittografia fallita";
-"vpn.errors.compression" = "Compressione non supportata";
-"vpn.errors.network" = "Rete cambiata";
-"vpn.errors.routing" = "Routing mancante";
-"vpn.errors.gateway" = "Nessun gateway";
-
-"issue_reporter.title" = "Segnala problema";
-"issue_reporter.message" = "Il debug log delle tue ultime connessioni è cruciale per risolvere i tuoi problemi di connettività ed è completamente anonimo.\n\nIl file di configurazione .ovpn, se presente, è allegato privato di ogni dato sensibile.\n\nPer favore controlla gli allegati dell'e-mail se non sei sicuro/a.";
-"issue_reporter.buttons.accept" = "Ho capito";
-
-"translations.title" = "Traduzioni";
-
-"shortcuts.add.title" = "Aggiungi comando rapido";
-"shortcuts.add.sections.vpn.header" = "VPN";
-"shortcuts.add.sections.wifi.header" = "Wi-Fi";
-"shortcuts.add.sections.cellular.header" = "Cellulare";
-"shortcuts.add.cells.connect.caption" = "Connetti a";
-"shortcuts.add.cells.enable_vpn.caption" = "Abilita VPN";
-"shortcuts.add.cells.disable_vpn.caption" = "Disabilita VPN";
-"shortcuts.add.cells.trust_current_wifi.caption" = "Aggiungi Wi-Fi sicura";
-"shortcuts.add.cells.untrust_current_wifi.caption" = "Rimuovi Wi-Fi sicura";
-"shortcuts.add.cells.trust_cellular.caption" = "Aggiungi rete mobile sicura";
-"shortcuts.add.cells.untrust_cellular.caption" = "Rimuovi rete mobile sicura";
-"shortcuts.add.alerts.no_profiles.message" = "Non c'è nessun profilo a cui connettersi.";
-
-"shortcuts.edit.title" = "Gestisci comandi rapidi";
-"shortcuts.edit.sections.all.header" = "Comandi esistenti";
-"shortcuts.edit.cells.add_shortcut.caption" = "Aggiungi comando rapido";
-
-"about.title" = "Informazioni su";
-"about.sections.web.header" = "Web";
-"about.sections.share.header" = "Condividi";
-"about.cells.credits.caption" = "Credits";
-"about.cells.website.caption" = "Home page";
-"about.cells.faq.caption" = "FAQ";
-"about.cells.disclaimer.caption" = "Disclaimer";
-"about.cells.privacy_policy.caption" = "Privacy policy";
-"about.cells.share_twitter.caption" = "Manda un Tweet!";
-"about.cells.share_generic.caption" = "Invita un amico";
-
-"donation.title" = "Donazione";
-"donation.sections.one_time.header" = "Unica";
-"donation.sections.one_time.footer" = "Se vuoi mostrare gratitudine per il mio lavoro a titolo gratuito, qui trovi varie somme da donare all'istante.\n\nLa donazione ti sarà addebitata solo una volta, e puoi effettuare più donazioni.";
-"donation.cells.loading.caption" = "Caricando donazioni";
-"donation.cells.purchasing.caption" = "Effettuando donazione";
-"donation.alerts.purchase.success.title" = "Grazie";
-"donation.alerts.purchase.success.message" = "Questo significa molto per me e spero vivamente che tu continui ad usare e promuovere quest'applicazione.";
-"donation.alerts.purchase.failure.message" = "Impossibile effettuare la donazione. %@";
-
-"share.message" = "Passepartout è un client OpenVPN user-friendly ed open source per iOS e macOS";
-
-"version.title" = "Versione";
-"version.labels.intro" = "Passepartout e TunnelKit sono scritti e mantenuti da Davide De Rosa (keeshux).\n\nIl codice sorgente di Passepartout e TunnelKit è pubblicamente disponibile su GitHub in accordo con la GPLv3, puoi trovare i link nella home page.\n\nPassepartout è un client non ufficiale e non è affiliato ad OpenVPN Inc. in alcuna maniera.";
-
-"credits.title" = "Credits";
-"credits.sections.licenses.header" = "Licenze";
-"credits.sections.notices.header" = "Notice";
-"credits.sections.translations.header" = "Traduzioni";
-
-"label.license.error" = "Impossibile scaricare il contenuto completo della licenza.";
diff --git a/Passepartout/Resources/nl.lproj/Intents.strings b/Passepartout/Resources/nl.lproj/Intents.strings
deleted file mode 100644
index 0db55251..00000000
--- a/Passepartout/Resources/nl.lproj/Intents.strings
+++ /dev/null
@@ -1,39 +0,0 @@
-"0jRWn5" = "Verwijder Mobielnetwerk van vertrouwde netwerken";
-
-"1ZRTCZ" = "Disable VPN";
-
-"66bZBE" = "Met ${providerId} aanbieder";
-
-"7eoAss" = "Verwijder huidige Wi-Fi van vertrouwde netwerken";
-
-"9GpJt5" = "Voeg Mobielnetwerk to aan vertrouwde netwerken";
-
-"BKxs8X" = "Voeg huidig Wi-Fi toe aan vertrouwde netwerken";
-
-"H4taev" = "Vertrouw mobiel netwerk";
-
-"KjkCfU" = "Maak verbinding met een specifieke lokatie van een aanbieder profiel";
-
-"LA99yM" = "Verbind VPN";
-
-"U6o81V" = "Verbind met ${profileId}";
-
-"WnTPFg" = "Verbind met ${poolName}";
-
-"eQ1yzr" = "Schakel VPN service uit";
-
-"eXXb2z" = "Verbind met een host profiel";
-
-"lQ6ziK" = "Schakel VPN in";
-
-"m2E7SI" = "Vertrouw huidig Wi-Fi netwerk";
-
-"qo3Szz" = "Maak verbinding met de locatie van de aanbieder";
-
-"rd1T8p" = "Wantrouw huidig Wi-Fi netwerk";
-
-"wB1iYX" = "Wantrouw modbiel netwerk";
-
-"xY97Vu" = "Schakel de VPN-service in met het profiel dat momenteel in gebruik is";
-
-"NCoK9B" = "Met het profiel dat momenteel in gebruik is";
diff --git a/Passepartout/Resources/nl.lproj/Localizable.strings b/Passepartout/Resources/nl.lproj/Localizable.strings
deleted file mode 100644
index 19fd43b4..00000000
--- a/Passepartout/Resources/nl.lproj/Localizable.strings
+++ /dev/null
@@ -1,283 +0,0 @@
-//
-// Localizable.strings
-// Passepartout
-//
-// Created by Davide De Rosa on 6/13/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-"global.ok" = "OK";
-"global.cancel" = "Afbreken";
-"global.next" = "Volgende";
-"global.close" = "Afsluiten";
-"global.host.title_input.message" = "Toegestane karakters zijn: alfanumerieke en streepjes \"-\", onderliggend streepje \"_\" en punten \".\".";
-"global.host.title_input.placeholder" = "Mijn Profiel";
-"global.email_not_configured" = "Er is geen email adres geconfigureerd.";
-
-"global.cells.enabled" = "Ingeschakeld";
-"global.cells.disabled" = "Uitgeschakeld";
-"global.cells.none" = "Geen";
-"global.cells.automatic" = "Automatisch";
-"global.cells.manual" = "Handmatig";
-
-"reddit.title" = "Reddit";
-"reddit.message" = "Wist je dat Passepartout een eigen subreddit heeft? Schrijf je in voor updates, of discussiëren over problemen, (nieuwe) mogelijkheden, nieuwe platformen of wat je maar wil.\n\nHet is ook een goede manier om te laten zien dat je om dit project geeft.";
-"reddit.buttons.subscribe" = "Schfijf je nu in!";
-"reddit.buttons.remind" = "Herinner me later";
-"reddit.buttons.never" = "Vraag dit niet meer";
-
-"organizer.sections.providers.header" = "Aanbieders";
-"organizer.sections.providers.footer" = "Hier vind je aan aantal aanbieders met configuratie profielen.";
-"organizer.sections.hosts.header" = "Hosts";
-"organizer.sections.hosts.footer" = "Importeer hosts met raw .ovpn configuratie bestanden.";
-"organizer.sections.siri.header" = "Siri";
-"organizer.sections.siri.footer" = "Krijg hulp van Siri en versnel de meest gebruikte interacties binnen de app.";
-"organizer.sections.support.header" = "Ondersteuning";
-"organizer.sections.feedback.header" = "Terugkoppeling";
-"organizer.cells.profile.value.current" = "In gebruik";
-"organizer.cells.add_provider.caption" = "Voeg nieuwe aanbieder toe";
-"organizer.cells.add_host.caption" = "Voeg nieuwe host toe";
-"organizer.cells.siri_shortcuts.caption" = "Beheer snelkoppelingen";
-"organizer.cells.join_community.caption" = "Word lid van de gemeenschap";
-"organizer.cells.write_review.caption" = "Schrijf een beoordeling";
-"organizer.cells.donate.caption" = "Doneer een gift";
-"organizer.cells.patreon.caption" = "Steun me op Patreon";
-"organizer.cells.translate.caption" = "Help met vertalen";
-"organizer.cells.about.caption" = "Over %@";
-"organizer.cells.uninstall.caption" = "Verwijder VPN configuratie";
-"organizer.alerts.exhausted_providers.message" = "Er zijn profielen gemaakt voor elke beschikbare aanbieder.";
-"organizer.alerts.add_host.message" = "Open een URL naar een .ovpn configuratie bestand met Safari, Mail of een andere app om een host profile te configureren.\n\nJe kan ook een .ovpn importeren met behulp van iTunes bestandsdeling.";
-"organizer.alerts.cannot_donate.message" = "Er is geen betaalmethode geconfigureerd op dit apparaat.";
-"organizer.alerts.delete_vpn_profile.message" = "Wilt u de VPN-configuratie van uw apparaatinstellingen verwijderen? Dit kan enkele problemen met VPN oplossen en heeft geen invloed op uw provider- en hostprofielen.";
-
-"wizards.host.cells.title_input.caption" = "Titel";
-"wizards.host.sections.existing.header" = "Bestaande profielen";
-"wizards.host.alerts.existing.message" = "Er bestaat al een host profiel met deze titel, wil je hem vervangen?";
-
-"parsed_file.alerts.malformed.message" = "Het configuratie betand bevat ongeldige optie(s) (%@).";
-"parsed_file.alerts.missing.message" = "Het configuratiebestand mist een vereiste optie (%@).";
-"parsed_file.alerts.unsupported.message" = "Het configuratiebestand bevat een niet-ondersteunde optie (%@).";
-"parsed_file.alerts.potentially_unsupported.message" = "Het configuratiebestand is correct maar bevat mogelijk een niet-ondersteunde optie (%@).\n\nConnectiviteit kan hier door niet werken, afhankelijk van de serverinstellingen.";
-"parsed_file.alerts.encryption_passphrase.message" = "Voer een coderingswachtwoord in";
-"parsed_file.alerts.decryption.message" = "De configuratie bevat een gecodeerde privésleutel en deze kan niet worden gedecodeerd. Controleer de ingevoerde wachtwoordzin nogmaals.";
-"parsed_file.alerts.parsing.message" = "Kan het opgegeven configuratiebestand niet verwerken (%@).";
-"parsed_file.alerts.buttons.report" = "Een probleem melden";
-
-"imported_hosts.title" = "Geïmporteerde hosts";
-
-"service.welcome.message" = "Welkom bij Passepartout!\n\nGebruik de organizer om een nieuw profiel toe te voegen.";
-"service.sections.general.header" = "Algemeen";
-"service.sections.vpn.header" = "VPN";
-"service.sections.vpn.footer" = "De verbinding zal worden gestart wanneer nodig.";
-"service.sections.status.header" = "Verbinding";
-"service.sections.configuration.header" = "Configuratie";
-"service.sections.provider_infrastructure.footer" = "Laatste update was op %@.";
-"service.sections.vpn_survives_sleep.footer" = "Uitschakelen om het batterijverbruik te verbeteren, ten koste van incidentele vertragingen als gevolg van het opnieuw opstarten na wake-up.";
-"service.sections.vpn_resolves_hostname.footer" = "Voorkeur om dit aan te zetten voor de meeste netwerken en vereist in sommige IPv6-netwerken. Uitschakelen waar DNS wordt geblokkeerd, of om de onderhandelingen te versnellen wanneer DNS traag reageert.";
-//"service.sections.vpn_prefers_udp.footer" = "UDP is sneller dan TCP, maar werkt mogelijk niet met sommige netwerken. Uitschakelen in netwerken waar UDP geblokkeerd is.";
-"service.sections.trusted.header" = "Vertrouwde netwerken";
-"service.sections.trusted.footer" = "Bij het invoeren van een vertrouwd netwerk wordt de VPN uitgeschakeld en niet verbonden gehouden. Schakel deze optie uit om dergelijk gedrag niet af te dwingen.";
-"service.sections.diagnostics.header" = "Diagnose";
-"service.sections.diagnostics.footer" = "De maskeerstatus is effectief na opnieuw verbinden. Netwerkgegevens zijn hostnamen, IP-adressen, routing, SSID's. Inloggegevens en privésleutels worden niet geregistreerd.";
-//"service.sections.destruction.footer" = "Configuratie uit apparaatinstellingen verwijderen.";
-
-"service.cells.use_profile.caption" = "Gebruik dit profiel";
-"service.cells.vpn_service.caption" = "Ingeschakeld";
-"service.cells.connection_status.caption" = "Status";
-"service.cells.reconnect.caption" = "Opnieuw verbinden";
-"service.cells.account.caption" = "Account";
-"service.cells.account.none" = "Niets geconfigureerd";
-"service.cells.endpoint.caption" = "Endpoint";
-"service.cells.provider.pool.caption" = "Locatie";
-"service.cells.provider.preset.caption" = "Voorkeur";
-"service.cells.provider.refresh.caption" = "Vernieuw de infrastructuur";
-"service.cells.host.parameters.caption" = "Parameters";
-"service.cells.network_settings.caption" = "Netwerk instellingen";
-"service.cells.vpn_survives_sleep.caption" = "Actief tijdens slaapstand";
-"service.cells.vpn_resolves_hostname.caption" = "Haal de naam van de host op";
-//"service.cells.vpn_prefers_udp.caption" = "Voorkeur voor UDP socket";
-"service.cells.trusted_mobile.caption" = "Mobiel netwerk";
-"service.cells.trusted_add_wifi.caption" = "Voeg huidige WiFi toe";
-"service.cells.trusted_policy.caption" = "Trust disables VPN";
-"service.cells.test_connectivity.caption" = "Test connectiviteit";
-"service.cells.data_count.caption" = "Gegegevens uitgewisseld";
-"service.cells.data_count.none" = "Niet beschikbaar";
-"service.cells.debug_log.caption" = "Foutopsporingslogboek";
-"service.cells.masks_private_data.caption" = "Netwerkgegevens maskeren";
-"service.cells.report_issue.caption" = "Probleem met connectiviteit melden";
-
-"service.alerts.rename.title" = "Profiel hernoemen";
-"service.alerts.credentials_needed.message" = "Voer eerst de accountgegevens in.";
-"service.alerts.reconnect_vpn.message" = "Opnieuw verbinding maken met de VPN?";
-"service.alerts.trusted.no_network.message" = "U bent niet verbonden met een Wi-Fi-netwerk.";
-"service.alerts.trusted.will_disconnect_trusted.message" = "Door dit netwerk te vertrouwen, kan de verbinding met de VPN mogelijk worden verbroken. Doorgaan?";
-"service.alerts.trusted.will_disconnect_policy.message" = "Door het vertrouwensbeleid te wijzigen, kan de verbinding met de VPN mogelijk worden verbroken. Doorgaan?";
-"service.alerts.test_connectivity.title" = "Connectiviteit";
-"service.alerts.test_connectivity.messages.success" = "Apparaat is verbonden met internet!";
-"service.alerts.test_connectivity.messages.failure" = "Uw apparaat heeft geen internetverbinding. Controleer uw profielparameters.";
-"service.alerts.masks_private_data.messages.must_reconnect" = "Om het huidige foutopsporingslogboek veilig opnieuw in te stellen en de nieuwe maskeervoorkeur toe te passen, moet u nu opnieuw verbinding maken met VPN.";
-"service.alerts.buttons.reconnect" = "Opnieuw verbinden";
-"service.alerts.download.title" = "Download vereist";
-"service.alerts.download.message" = "%@ vereist het downloaden van extra configuratiebestanden.\n\nBevestig om het downloaden te starten.";
-"service.alerts.download.failed" = "Downloaden van configuratiebestanden is mislukt. %@";
-"service.alerts.download.hud.extracting" = "Bestanden uitpakken, even geduld...";
-
-"account.sections.credentials.header" = "Inloggegevens";
-"account.sections.guidance.footer.infrastructure.mullvad" = "Gebruik de inloggegevens van %@. Uw gebruikersnaam is meestal numeriek.";
-"account.sections.guidance.footer.infrastructure.nordvpn" = "Gebruik de inloggegevens van %@. Uw gebruikersnaam is meestal uw e-mailadres.";
-"account.sections.guidance.footer.infrastructure.pia" = "Gebruik de inloggegevens van %@. Uw gebruikersnaam is meestal numeriek met \"p\" als voorvoegsel.";
-"account.sections.guidance.footer.infrastructure.protonvpn" = "Vind de inloggegevens van %@ in \"Account > OpenVPN / IKEv2 Username\" onderdeel van de website.";
-"account.sections.guidance.footer.infrastructure.tunnelbear" = "Gebruik de inloggegevens van %@. Uw gebruikersnaam is meestal uw e-mailadres.";
-"account.sections.guidance.footer.infrastructure.vyprvpn" = "Gebruik de inloggegevens van %@ Uw gebruikersnaam is meestal uw e-mailadres.";
-"account.sections.guidance.footer.infrastructure.windscribe" = "Vind de inloggegevens van %@ in de OpenVPN Config Generator op de website.";
-"account.sections.registration.footer" = "Registreer voor een %@ account op de website.";
-"account.cells.username.caption" = "Gebruikersnaam";
-"account.cells.username.placeholder" = "gebruikersnaam";
-"account.cells.password.caption" = "Wachtwoord";
-"account.cells.password.placeholder" = "geheim";
-//"account.cells.password_confirm.caption" = "Bevestig";
-//"account.cells.password_confirm.mismatch" = "Wachtwoorden verschillen!";
-"account.cells.open_guide.caption" = "Bekijk de inloggegevens";
-"account.cells.signup.caption" = "Registreer bij %@";
-
-"endpoint.sections.location_addresses.header" = "Adressen";
-"endpoint.sections.location_protocols.header" = "Protocollen";
-"endpoint.cells.any_address.caption" = "Automatisch";
-"endpoint.cells.any_protocol.caption" = "Automatisch";
-
-"provider.preset.cells.tech_details.caption" = "Technische details";
-//"provider.preset.sections.main.footer" = "Tik op de info knop voor technische details.";
-
-"configuration.sections.communication.header" = "Communicatie";
-"configuration.sections.reset.footer" = "Tik hier als de connectiviteit niet meer werkt na het aanpassen van instellingen, om terug te gaan naar de originele configuratie.";
-"configuration.sections.tls.header" = "TLS";
-"configuration.sections.compression.header" = "Compressie";
-"configuration.sections.network.header" = "Netwerk";
-"configuration.sections.other.header" = "Ander";
-"configuration.cells.cipher.caption" = "Cipher";
-"configuration.cells.digest.caption" = "Authenticatie";
-"configuration.cells.digest.value.embedded" = "Embedded";
-"configuration.cells.reset_original.caption" = "Reset configuratie";
-"configuration.cells.client.caption" = "Client certificaat";
-"configuration.cells.client.value.enabled" = "Geverifieerd";
-"configuration.cells.client.value.disabled" = "Niet geverifieerd";
-"configuration.cells.tls_wrapping.caption" = "Wrapping";
-"configuration.cells.tls_wrapping.value.auth" = "Authenticatie";
-"configuration.cells.tls_wrapping.value.crypt" = "Versleuteling";
-"configuration.cells.eku.caption" = "Uitgebreide verificatie";
-"configuration.cells.default_gateway.caption" = "Standaard gateway";
-"configuration.cells.dns_server.caption" = "DNS";
-"configuration.cells.dns_domain.caption" = "Domein";
-"configuration.cells.proxy_http.caption" = "Proxy";
-"configuration.cells.proxy_https.caption" = "Proxy (HTTPS)";
-"configuration.cells.compression_framing.caption" = "Framing";
-"configuration.cells.compression_framing.value.lzo" = "--comp-lzo";
-"configuration.cells.compression_framing.value.compress" = "--compress";
-"configuration.cells.compression_algorithm.caption" = "Algoritme";
-"configuration.cells.compression_algorithm.value.lzo" = "LZO";
-"configuration.cells.compression_algorithm.value.other" = "Niet ondersteund";
-"configuration.cells.keep_alive.caption" = "Keep-alive";
-"configuration.cells.keep_alive.value.seconds" = "%d seconden";
-"configuration.cells.renegotiation_seconds.caption" = "Renegotiation";
-"configuration.cells.renegotiation_seconds.value.after" = "na %@";
-"configuration.cells.random_endpoint.caption" = "Willekeurig eindpunt";
-
-"network_settings.cells.choice.client" = "Gebruik .ovpn";
-"network_settings.cells.choice.server" = "Haal op van server";
-"network_settings.cells.address.caption" = "Adress";
-"network_settings.cells.port.caption" = "Port";
-"network_settings.cells.add_dns_server.caption" = "Voeg adress toe";
-"network_settings.cells.proxy_bypass.caption" = "Omzeil domein";
-"network_settings.cells.add_proxy_bypass.caption" = "Voeg omzeil optie voor domein toe";
-
-"debug_log.buttons.previous" = "Vorige";
-"debug_log.buttons.next" = "Volgende";
-"debug_log.alerts.empty_log.message" = "Het logboek voor foutopsporing is leeg.";
-
-"vpn.connecting" = "Verbinden";
-"vpn.active" = "Actief";
-"vpn.disconnecting" = "Verbinding verbreken";
-"vpn.inactive" = "Inactief";
-"vpn.disabled" = "Uitgeschakeld";
-
-"vpn.errors.timeout" = "Time-out";
-"vpn.errors.dns" = "DNS niet gelukt";
-"vpn.errors.auth" = "Auth niet gelukt";
-"vpn.errors.tls" = "TLS niet gelukt";
-"vpn.errors.encryption" = "Versleuteling mislukt";
-"vpn.errors.compression" = "Compressie wordt niet ondersteund";
-"vpn.errors.network" = "Netwerk veranderd";
-"vpn.errors.routing" = "Ontbrekende routering";
-"vpn.errors.gateway" = "Geen gateway";
-
-"issue_reporter.title" = "Meld een probleem";
-"issue_reporter.message" = "Het foutopsporingslogboek van uw laatste verbindingen is cruciaal om uw verbindingsproblemen op te lossen en is volledig geanonimiseerd.\n\nHet .ovpn configuratiebestand, indien aanwezig, is ontdaan van alle gevoelige gegevens.\n\nControleer de e-mailbijlagen als je niet zeker bent dat alles verwijderd is.";
-"issue_reporter.buttons.accept" = "Ik ga akkoord";
-
-"translations.title" = "Vertalingen";
-
-"shortcuts.add.title" = "Voeg snelkoppeling toe";
-"shortcuts.add.sections.vpn.header" = "VPN";
-"shortcuts.add.sections.wifi.header" = "Wi-Fi";
-"shortcuts.add.sections.cellular.header" = "Mobiel";
-"shortcuts.add.cells.connect.caption" = "Verbind met";
-"shortcuts.add.cells.enable_vpn.caption" = "Activeer VPN";
-"shortcuts.add.cells.disable_vpn.caption" = "Deactiveer VPN";
-"shortcuts.add.cells.trust_current_wifi.caption" = "Vertrouw huidig Wi-Fi netwerk";
-"shortcuts.add.cells.untrust_current_wifi.caption" = "Untrust current Wi-Fi";
-"shortcuts.add.cells.trust_cellular.caption" = "Vertouw mobiel netwerk";
-"shortcuts.add.cells.untrust_cellular.caption" = "Untrust mobiel netwerk";
-"shortcuts.add.alerts.no_profiles.message" = "Er is geen profiel om verbinding mee te maken.";
-
-"shortcuts.edit.title" = "Beheer snelkoppelingen";
-"shortcuts.edit.sections.all.header" = "Bestaande snelkoppelingen";
-"shortcuts.edit.cells.add_shortcut.caption" = "Voeg snelkoppeling toe";
-
-"about.title" = "Over";
-"about.sections.web.header" = "Web";
-"about.sections.share.header" = "Delen";
-"about.cells.credits.caption" = "Credits";
-"about.cells.website.caption" = "Home page";
-"about.cells.faq.caption" = "FAQ";
-"about.cells.disclaimer.caption" = "Vrijwaring";
-"about.cells.privacy_policy.caption" = "Privacybeleid";
-"about.cells.share_twitter.caption" = "Tweet about it!";
-"about.cells.share_generic.caption" = "Nodig een vriend uit";
-
-"donation.title" = "Donatie";
-"donation.sections.one_time.header" = "Eenmalig";
-"donation.sections.one_time.footer" = "Als je dankbaarheid wilt tonen voor mijn gratis werk, zijn hier een paar bedragen die je direct kunt doneren.\n\nHet bedrag wordt slechts één keer per donatie in rekening gebracht en u kunt meerdere keren doneren.";
-"donation.cells.loading.caption" = "Ophalen donaties";
-"donation.cells.purchasing.caption" = "Doneren";
-"donation.alerts.purchase.success.title" = "Hartelijk dank";
-"donation.alerts.purchase.success.message" = "Dit betekent veel voor mij en ik hoop echt dat je deze app blijft gebruiken en promoten.";
-"donation.alerts.purchase.failure.message" = "Donatie mislukt. %@";
-
-"share.message" = "Passepartout is een gebruiksvriendelijke open source OpenVPN-client voor iOS en macOS";
-
-"version.title" = "Versie";
-"version.labels.intro" = "Passepartout en TunnelKit zijn geschreven en worden onderhouden door Davide De Rosa (keeshux).\n\nDe broncode voor Passepartout en TunnelKit is openbaar beschikbaar op GitHub onder de GPLv3, je kunt links op de startpagina vinden.\n\nPassepartout is een niet-officiële client en is op geen enkele manier verbonden aan OpenVPN Inc.";
-
-"credits.title" = "Credits";
-"credits.sections.licenses.header" = "Licenties";
-"credits.sections.notices.header" = "Mededelingen";
-"credits.sections.translations.header" = "Vertalingen";
-
-"label.license.error" = "Kan volledige licentie-inhoud niet downloaden.";
diff --git a/Passepartout/Resources/pt-br.lproj/Intents.strings b/Passepartout/Resources/pt-br.lproj/Intents.strings
deleted file mode 100644
index 99a90645..00000000
--- a/Passepartout/Resources/pt-br.lproj/Intents.strings
+++ /dev/null
@@ -1,39 +0,0 @@
-"0jRWn5" = "Remover celular de conexões seguras";
-
-"1ZRTCZ" = "Desativar VPN";
-
-"66bZBE" = "Com o provedor ${providerId}";
-
-"7eoAss" = "Remover Wi-Fi atual de conexões seguras";
-
-"9GpJt5" = "Adicionar celular em conexões seguras";
-
-"BKxs8X" = "Adicionar Wi-Fi atual em conexões seguras";
-
-"H4taev" = "Confiar em rede celular";
-
-"KjkCfU" = "Conectar em uma localização específica de um provedor";
-
-"LA99yM" = "Conectar VPN";
-
-"U6o81V" = "Conectar ${profileId}";
-
-"WnTPFg" = "Conectar ${poolName}";
-
-"eQ1yzr" = "Desabilitar serviço de VPN";
-
-"eXXb2z" = "Conectar em um host";
-
-"lQ6ziK" = "Ativar VPN";
-
-"m2E7SI" = "Confiar na Wi-Fi atual";
-
-"qo3Szz" = "Conectar em uma região do provedor";
-
-"rd1T8p" = "Não confiar na Wi-Fi atual";
-
-"wB1iYX" = "Não confiar na conexão celular";
-
-"xY97Vu" = "Ativar o serviço VPN no perfil em uso";
-
-"NCoK9B" = "Com o perfil em uso";
diff --git a/Passepartout/Resources/pt-br.lproj/Localizable.strings b/Passepartout/Resources/pt-br.lproj/Localizable.strings
deleted file mode 100644
index c1fbdf32..00000000
--- a/Passepartout/Resources/pt-br.lproj/Localizable.strings
+++ /dev/null
@@ -1,283 +0,0 @@
-//
-// Localizable.strings
-// Passepartout
-//
-// Created by Davide De Rosa on 6/13/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-"global.ok" = "OK";
-"global.cancel" = "Cancelar";
-"global.next" = "Próximo";
-"global.close" = "Fechar";
-"global.host.title_input.message" = "Caracteres aceitos são alfanuméricos, mais traço \"-\", underline \"_\" e ponto \".\".";
-"global.host.title_input.placeholder" = "Meu perfil";
-"global.email_not_configured" = "Nenhuma conta de email configurada.";
-
-"global.cells.enabled" = "Ativado";
-"global.cells.disabled" = "Desativado";
-"global.cells.none" = "Nenhum";
-"global.cells.automatic" = "Automático";
-"global.cells.manual" = "Manual";
-
-"reddit.title" = "Reddit";
-"reddit.message" = "Você sabia que Passepartout tem um subreddit? Siga-nos para atualizações ou para discutir problemas, novas funcionalidades, ou qualquer outro tópico.\n\nÉ uma boa maneira de mostrar seu interesse pelo projeto.";
-"reddit.buttons.subscribe" = "Seguir!";
-"reddit.buttons.remind" = "Lembrar-me depois";
-"reddit.buttons.never" = "Não perguntar novamente";
-
-"organizer.sections.providers.header" = "Provedores";
-"organizer.sections.providers.footer" = "Aqui você encontra um provedor com o perfil pré-configurado.";
-"organizer.sections.hosts.header" = "Hosts";
-"organizer.sections.hosts.footer" = "Importar hosts de um arquivo de configuração .ovpn.";
-"organizer.sections.siri.header" = "Siri";
-"organizer.sections.siri.footer" = "Peça ajuda para Siri para agilar tarefas comum do aplicativo.";
-"organizer.sections.support.header" = "Suporte";
-"organizer.sections.feedback.header" = "Feedback";
-"organizer.cells.profile.value.current" = "Ativo";
-"organizer.cells.add_provider.caption" = "Adicionar novo perfil";
-"organizer.cells.add_host.caption" = "Adicionar novo host";
-"organizer.cells.siri_shortcuts.caption" = "Gerenciar atalhos";
-"organizer.cells.join_community.caption" = "Participar da comunidade";
-"organizer.cells.write_review.caption" = "Escrever avaliação";
-"organizer.cells.donate.caption" = "Fazer doação";
-"organizer.cells.patreon.caption" = "Contribuir no Patreon";
-"organizer.cells.translate.caption" = "Ajudar-nos na tradução";
-"organizer.cells.about.caption" = "Sobre %@";
-"organizer.cells.uninstall.caption" = "Remover configuração VPN";
-"organizer.alerts.exhausted_providers.message" = "Você criou um perfil para qualquer provedor disponível.";
-"organizer.alerts.add_host.message" = "Abre uma URL para um arquivo de configuração .ovpn no Safari, Mail ou outro aplicativo.\n\nVocê pode também importar um .ovpn com o compartilhamento de arquivos do iTunes.";
-"organizer.alerts.cannot_donate.message" = "Nenhum meio de pagamento configurado nesse dispositivo.";
-"organizer.alerts.delete_vpn_profile.message" = "Tem certeza que deseja remover as configurações de VPN do seu dispositivo? Isso poderá corrigir problemas com o estado atual, sem afetar seu provedor e perfis do host.";
-
-"wizards.host.cells.title_input.caption" = "Título";
-"wizards.host.sections.existing.header" = "Perfis existentes";
-"wizards.host.alerts.existing.message" = "Já existe um perfil com esse nome, deseja substituí-lo?";
-
-"parsed_file.alerts.malformed.message" = "O arquivo de configuração possui uma opção não formatada corretamente (%@).";
-"parsed_file.alerts.missing.message" = "O arquivo não possui todas configurações requeridas (%@).";
-"parsed_file.alerts.unsupported.message" = "O arquivo de configuração possui uma opção não suportada (%@).";
-"parsed_file.alerts.potentially_unsupported.message" = "O arquivo de configuração está correto, mas provavelmente possui uma opção não suportada (%@).\n\nSua conexão poderá ser instável dependendo as configurações do servidor.";
-"parsed_file.alerts.encryption_passphrase.message" = "Por favor, digite sua senha de criptografia.";
-"parsed_file.alerts.decryption.message" = "Sua configiração possui uma chave privada criptografada que talvez não possa ser descriptografada. Verifique novamente sua senha de criptografia.";
-"parsed_file.alerts.parsing.message" = "Não foi possível processar as configurações do arquivo (%@).";
-"parsed_file.alerts.buttons.report" = "Reportar problema";
-
-"imported_hosts.title" = "Hosts importados";
-
-"service.welcome.message" = "Bem-vindo ao Passepartout!\n\nUse o organizador para adicionar um novo perfil.";
-"service.sections.general.header" = "Geral";
-"service.sections.vpn.header" = "VPN";
-"service.sections.vpn.footer" = "A conexão será estabeleciada assim que necessária.";
-"service.sections.status.header" = "Conexão";
-"service.sections.configuration.header" = "Configuração";
-"service.sections.provider_infrastructure.footer" = "Última atualização em %@.";
-"service.sections.vpn_survives_sleep.footer" = "Desative para melhorar o consumo de bateria, o que poderá ocasionar queda de performance quando o restabelecimento de conexão for realizado.";
-"service.sections.vpn_resolves_hostname.footer" = "Recomendado para maioria das redes e requirido em algumas redes IPv6. Desative se o DNS estiver bloqueado, ou para acelerar o DNS quando o mesmo está devagar.";
-//"service.sections.vpn_prefers_udp.footer" = "UDP é mais rápido que TCP, mas pode não funcionar em algumas redes. Desative em redes onde UDP possa estar bloqueado.";
-"service.sections.trusted.header" = "Redes seguras";
-"service.sections.trusted.footer" = "Ao entrar em uma rede segura, a VPN é normalmente é desconectada e mantido inativa. Desative essa opção para não forçar esse comportamento.";
-"service.sections.diagnostics.header" = "Diagnóstico";
-"service.sections.diagnostics.footer" = "O status será escondido após reconectado. Os dados da rede são hostnames, endereços de IP, rotas, SSID. Credenciais e chaves privadas não será logadas em nenhum dos casos.";
-//"service.sections.destruction.footer" = "Deletar configuração das preferências do dispositivo.";
-
-"service.cells.use_profile.caption" = "Usar esse perfil";
-"service.cells.vpn_service.caption" = "Ativado";
-"service.cells.connection_status.caption" = "Status";
-"service.cells.reconnect.caption" = "Reconectar";
-"service.cells.account.caption" = "Conta";
-"service.cells.account.none" = "Nenhum configurado";
-"service.cells.endpoint.caption" = "Endereço";
-"service.cells.provider.pool.caption" = "Localização";
-"service.cells.provider.preset.caption" = "Pré-definição";
-"service.cells.provider.refresh.caption" = "Atualizar infraestrutura";
-"service.cells.host.parameters.caption" = "Parâmetros";
-"service.cells.network_settings.caption" = "Configurações de rede";
-"service.cells.vpn_survives_sleep.caption" = "Manter ativo em modo descanço";
-"service.cells.vpn_resolves_hostname.caption" = "Resolver hostname do servidor";
-//"service.cells.vpn_prefers_udp.caption" = "Preferir socket UDP";
-"service.cells.trusted_mobile.caption" = "Rede celular";
-"service.cells.trusted_add_wifi.caption" = "Adicionar Wi-Fi atual";
-"service.cells.trusted_policy.caption" = "Trust disables VPN";
-"service.cells.test_connectivity.caption" = "Testar conexão";
-"service.cells.data_count.caption" = "Dados transferidos";
-"service.cells.data_count.none" = "Indisponível";
-"service.cells.debug_log.caption" = "Log de Debug";
-"service.cells.masks_private_data.caption" = "Esconder dados da rede";
-"service.cells.report_issue.caption" = "Reportar problemas de conexão";
-
-"service.alerts.rename.title" = "Renomear perfil";
-"service.alerts.credentials_needed.message" = "Primeiramente você precisa preencher suas credenciais.";
-"service.alerts.reconnect_vpn.message" = "Deseja reconectar à VPN?";
-"service.alerts.trusted.no_network.message" = "Você não está conectado em nenhuma rede Wi-Fi.";
-"service.alerts.trusted.will_disconnect_trusted.message" = "Ao confiar nessa rede, sua VPN provavelmente será desconectada. Deseja continuar?";
-"service.alerts.trusted.will_disconnect_policy.message" = "Ao alterar a política de segurança, sua VPN provavelmente será desconectada. Deseja continuar?";
-"service.alerts.test_connectivity.title" = "Conectividade";
-"service.alerts.test_connectivity.messages.success" = "Seu dispositivo está conectado à Internet!";
-"service.alerts.test_connectivity.messages.failure" = "Seu dispositivo não está conectado à Internet, por favor, verifique sua configurações.";
-"service.alerts.masks_private_data.messages.must_reconnect" = "Para garantir uma restauração segura do seu log de debug, você precisa reconectar à VPN.";
-"service.alerts.buttons.reconnect" = "Reconectar";
-"service.alerts.download.title" = "Download requirido";
-"service.alerts.download.message" = "%@ requer o download de arquivos de configuração adicionais.\n\nConfirme para iniciar.";
-"service.alerts.download.failed" = "Erro no download do arquivo de configuração. %@";
-"service.alerts.download.hud.extracting" = "Extraindo arquivos, seja paciente...";
-
-"account.sections.credentials.header" = "Credenciais";
-"account.sections.guidance.footer.infrastructure.mullvad" = "Utilize %@ credenciais do site. Seu usuário é normalmente numérico.";
-"account.sections.guidance.footer.infrastructure.nordvpn" = "Utilize %@ credenciais do site. Seu usuário é normalmente o seu email.";
-"account.sections.guidance.footer.infrastructure.pia" = "Utilize %@ credenciais do site. Seu usuário é normalmente numérico com prefixo \"p\".";
-"account.sections.guidance.footer.infrastructure.protonvpn" = "Encontre %@ credenciais na sessão \"Account > OpenVPN / IKEv2 Username\" do site.";
-"account.sections.guidance.footer.infrastructure.tunnelbear" = "Utilize %@ credenciais do site. Seu usuário é normalmente o seu email.";
-"account.sections.guidance.footer.infrastructure.vyprvpn" = "Utilize %@ credenciais do site. Seu usuário é normalmente o seu email.";
-"account.sections.guidance.footer.infrastructure.windscribe" = "Encontre %@ credenciais no gerador de configuração OpenVPN do site.";
-"account.sections.registration.footer" = "Registrar em %@ website.";
-"account.cells.username.caption" = "Usuário";
-"account.cells.username.placeholder" = "usuário";
-"account.cells.password.caption" = "Senha";
-"account.cells.password.placeholder" = "senha secreta";
-//"account.cells.password_confirm.caption" = "Confirmar";
-//"account.cells.password_confirm.mismatch" = "Senhas não conferem!";
-"account.cells.open_guide.caption" = "Ver sua credenciais";
-"account.cells.signup.caption" = "Registrar com %@";
-
-"endpoint.sections.location_addresses.header" = "Endereços";
-"endpoint.sections.location_protocols.header" = "Protocolos";
-"endpoint.cells.any_address.caption" = "Automático";
-"endpoint.cells.any_protocol.caption" = "Automático";
-
-"provider.preset.cells.tech_details.caption" = "Detalhes técnicos";
-//"provider.preset.sections.main.footer" = "Toque no botão \"Informação.\" para mostrar detalhes técnicos.";
-
-"configuration.sections.communication.header" = "Comunicação";
-"configuration.sections.reset.footer" = "Se você foi desconectado após mudar parâmetros de comunicação, toque para restaurar a configuração original.";
-"configuration.sections.tls.header" = "TLS";
-"configuration.sections.compression.header" = "Compressão";
-"configuration.sections.network.header" = "Rede";
-"configuration.sections.other.header" = "Outro";
-"configuration.cells.cipher.caption" = "Criptografada";
-"configuration.cells.digest.caption" = "Autenticação";
-"configuration.cells.digest.value.embedded" = "Agregado";
-"configuration.cells.reset_original.caption" = "Restaurar configuração";
-"configuration.cells.client.caption" = "Certificado do cliente";
-"configuration.cells.client.value.enabled" = "Verificado";
-"configuration.cells.client.value.disabled" = "Não verificado";
-"configuration.cells.tls_wrapping.caption" = "Wrapping";
-"configuration.cells.tls_wrapping.value.auth" = "Autenticação";
-"configuration.cells.tls_wrapping.value.crypt" = "Criptografia";
-"configuration.cells.eku.caption" = "Verificação extendida";
-"configuration.cells.default_gateway.caption" = "Gateway padrão";
-"configuration.cells.dns_server.caption" = "DNS";
-"configuration.cells.dns_domain.caption" = "Domínio";
-"configuration.cells.proxy_http.caption" = "Proxy";
-"configuration.cells.proxy_https.caption" = "Proxy (HTTPS)";
-"configuration.cells.compression_framing.caption" = "Framing";
-"configuration.cells.compression_framing.value.lzo" = "--comp-lzo";
-"configuration.cells.compression_framing.value.compress" = "--compress";
-"configuration.cells.compression_algorithm.caption" = "Algorítimo";
-"configuration.cells.compression_algorithm.value.lzo" = "LZO";
-"configuration.cells.compression_algorithm.value.other" = "Não suportado";
-"configuration.cells.keep_alive.caption" = "Manter ativo";
-"configuration.cells.keep_alive.value.seconds" = "%d segundos";
-"configuration.cells.renegotiation_seconds.caption" = "Renegociando";
-"configuration.cells.renegotiation_seconds.value.after" = "depois de %@";
-"configuration.cells.random_endpoint.caption" = "Destino randômico";
-
-"network_settings.cells.choice.client" = "Ler .ovpn";
-"network_settings.cells.choice.server" = "Puxar do servidor";
-"network_settings.cells.address.caption" = "Endereço";
-"network_settings.cells.port.caption" = "Porta";
-"network_settings.cells.add_dns_server.caption" = "Adicionar endereço";
-"network_settings.cells.proxy_bypass.caption" = "Domínio ignorado";
-"network_settings.cells.add_proxy_bypass.caption" = "Adicionar domínio ignorado";
-
-"debug_log.buttons.previous" = "Anterior";
-"debug_log.buttons.next" = "Próximo";
-"debug_log.alerts.empty_log.message" = "O log está vazio.";
-
-"vpn.connecting" = "Conectando";
-"vpn.active" = "Ativa";
-"vpn.disconnecting" = "Desconectando";
-"vpn.inactive" = "Inativo";
-"vpn.disabled" = "Desativado";
-
-"vpn.errors.timeout" = "Timeout";
-"vpn.errors.dns" = "Falha no DNS";
-"vpn.errors.auth" = "Falha na autenticação";
-"vpn.errors.tls" = "Falha no TLS";
-"vpn.errors.encryption" = "Falha na criptografia";
-"vpn.errors.compression" = "Compressão não suportada";
-"vpn.errors.network" = "Rede alterada";
-"vpn.errors.routing" = "Rota necessária";
-"vpn.errors.gateway" = "Sem gateway";
-
-"issue_reporter.title" = "Reportar problema";
-"issue_reporter.message" = "O log de suas últimas conexões é crucial para resolver problemas de conectividade e é completamemnte anônimo.\n\nO arquivo de conexão .ovpn, se existente, é anexado sem nenhum dado sensitivo.\n\nPor favor, verique o anexos de email se necessário.";
-"issue_reporter.buttons.accept" = "Eu concordo";
-
-"translations.title" = "Traduções";
-
-"shortcuts.add.title" = "Adicionar atalho";
-"shortcuts.add.sections.vpn.header" = "VPN";
-"shortcuts.add.sections.wifi.header" = "Wi-Fi";
-"shortcuts.add.sections.cellular.header" = "Celular";
-"shortcuts.add.cells.connect.caption" = "Conectar à";
-"shortcuts.add.cells.enable_vpn.caption" = "Ativar VPN";
-"shortcuts.add.cells.disable_vpn.caption" = "Desativar VPN";
-"shortcuts.add.cells.trust_current_wifi.caption" = "Confiar na Wi-Fi atual";
-"shortcuts.add.cells.untrust_current_wifi.caption" = "Não confiar na Wi-Fi atual";
-"shortcuts.add.cells.trust_cellular.caption" = "Confiar em rede celular";
-"shortcuts.add.cells.untrust_cellular.caption" = "Não confiar em rede celular";
-"shortcuts.add.alerts.no_profiles.message" = "Ainda não existe nenhum perfil para se conectar.";
-
-"shortcuts.edit.title" = "Configuração de atalhos";
-"shortcuts.edit.sections.all.header" = "Atalhos existentes";
-"shortcuts.edit.cells.add_shortcut.caption" = "Adicionar atalho";
-
-"about.title" = "Sobre";
-"about.sections.web.header" = "Web";
-"about.sections.share.header" = "Compartilhar";
-"about.cells.credits.caption" = "Créditos";
-"about.cells.website.caption" = "Home page";
-"about.cells.faq.caption" = "FAQ";
-"about.cells.disclaimer.caption" = "Disclaimer";
-"about.cells.privacy_policy.caption" = "Política de privacidade";
-"about.cells.share_twitter.caption" = "Tweet sobre isso!";
-"about.cells.share_generic.caption" = "Convide um amigo";
-
-"donation.title" = "Doar";
-"donation.sections.one_time.header" = "Uma vez";
-"donation.sections.one_time.footer" = "Se você deseja mostrar gratidão pelo meu trabalho, aqui estão alguns valores do qual você pode contribuir.\n\nVocé só será cobrado uma única vez, ou doar mais vezes caso desejar.";
-"donation.cells.loading.caption" = "Carregando doações";
-"donation.cells.purchasing.caption" = "Efetuando doação";
-"donation.alerts.purchase.success.title" = "Obrigado";
-"donation.alerts.purchase.success.message" = "Isso significa muito para mim! Espero que você continue usando e promovendo esse aplicativo.";
-"donation.alerts.purchase.failure.message" = "Não foi possível realizar doação. %@";
-
-"share.message" = "Passepartout é um cliente OpenVPN fácil e open-source para iOS e macOS";
-
-"version.title" = "Versão";
-"version.labels.intro" = "Passepartout e TunnelKit são desenvolvidos e mantidos por Davide De Rosa (keeshux).\n\nO código de fonte está disponível no GitHub sobre a licença GPLv3, você pode encontrar links na home page.\n\nPassepartout não é um cliente oficial e não possui nenhuma ligação com a OpenVPN Inc.";
-
-"credits.title" = "Créditos";
-"credits.sections.licenses.header" = "Licenças";
-"credits.sections.notices.header" = "Notices";
-"credits.sections.translations.header" = "Traduções";
-
-"label.license.error" = "Não foi possível realizar o download da licença.";
diff --git a/Passepartout/Resources/ru.lproj/Intents.strings b/Passepartout/Resources/ru.lproj/Intents.strings
deleted file mode 100644
index 717096ad..00000000
--- a/Passepartout/Resources/ru.lproj/Intents.strings
+++ /dev/null
@@ -1,39 +0,0 @@
-"0jRWn5" = "Удаляет мобильную сеть из доверенных подключений";
-
-"1ZRTCZ" = "Отключить VPN";
-
-"66bZBE" = "С ${providerId} провайдером";
-
-"7eoAss" = "Удаляет текущий Wi-Fi из доверенных подключений";
-
-"9GpJt5" = "Добавляет мобильную сеть в доверенные подключения";
-
-"BKxs8X" = "Добавляет текущий Wi-Fi в доверенные подключения";
-
-"H4taev" = "Доверять мобильной сети";
-
-"KjkCfU" = "Подключиться к конкретному местоположению провайдера";
-
-"LA99yM" = "Подключиться к VPN";
-
-"U6o81V" = "Подключиться к ${profileId}";
-
-"WnTPFg" = "Подключиться к ${poolName}";
-
-"eQ1yzr" = "Отключить этот VPN сервис";
-
-"eXXb2z" = "Подключается к хост профилю";
-
-"lQ6ziK" = "Включить VPN";
-
-"m2E7SI" = "Доверять текущему Wi-Fi";
-
-"qo3Szz" = "Подключиться к местоположению провайдера";
-
-"rd1T8p" = "Не доверять текущему Wi-Fi";
-
-"wB1iYX" = "Не доверять мобильной сети";
-
-"xY97Vu" = "Включает VPN с используемым профилем";
-
-"NCoK9B" = "С используемым профилем";
diff --git a/Passepartout/Resources/ru.lproj/Localizable.strings b/Passepartout/Resources/ru.lproj/Localizable.strings
deleted file mode 100644
index d8a53ad2..00000000
--- a/Passepartout/Resources/ru.lproj/Localizable.strings
+++ /dev/null
@@ -1,283 +0,0 @@
-//
-// Localizable.strings
-// Passepartout
-//
-// Created by Davide De Rosa on 4/23/19.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-"global.ok" = "Ок";
-"global.cancel" = "Отменить";
-"global.next" = "Далее";
-"global.close" = "Закрыть";
-"global.host.title_input.message" = "Разрешены буквы латиницы, дэш \"-\", нижнее подчеркивание \"_\" и точка \".\".";
-"global.host.title_input.placeholder" = "Мой профиль";
-"global.email_not_configured" = "E-mail аккаунт не создан.";
-
-"global.cells.enabled" = "Включен";
-"global.cells.disabled" = "Выключен";
-"global.cells.none" = "Нет";
-"global.cells.automatic" = "Автоматически";
-"global.cells.manual" = "Вручную";
-
-"reddit.title" = "Reddit";
-"reddit.message" = "А Вы знали, что Passepartout имеет свой сабреддит? Подписывайтесь для получения обновлений, обсуждения проблем, функций, новых платформ или чего угодно.\n\nЭто также отличный способ показать поддержку проекта.";
-"reddit.buttons.subscribe" = "Подписаться сейчас!";
-"reddit.buttons.remind" = "Напомнить позже";
-"reddit.buttons.never" = "Больше не спрашивать";
-
-"organizer.sections.providers.header" = "Провайдеры";
-"organizer.sections.providers.footer" = "Здесь Вы найдёте несколько провайдеров с уже созданными профилями.";
-"organizer.sections.hosts.header" = "Хосты|Hosts";
-"organizer.sections.hosts.footer" = "Импорт хостов из .ovpn файлов";
-"organizer.sections.siri.header" = "Сири";
-"organizer.sections.siri.footer" = "Получить помощь Сири, чтобы ускорить частые действия с приложением.";
-"organizer.sections.support.header" = "Поддержка";
-"organizer.sections.feedback.header" = "Отзыв";
-"organizer.cells.profile.value.current" = "Используется";
-"organizer.cells.add_provider.caption" = "Добавить нового провайдера";
-"organizer.cells.add_host.caption" = "Добавить новый хост";
-"organizer.cells.siri_shortcuts.caption" = "Управлять коммандами";
-"organizer.cells.join_community.caption" = "Вступить в сообщество";
-"organizer.cells.write_review.caption" = "Написать отзыв";
-"organizer.cells.donate.caption" = "Сделать пожертвование";
-"organizer.cells.patreon.caption" = "Поддержите меня на Patreon";
-"organizer.cells.translate.caption" = "Помощь с переводом";
-"organizer.cells.about.caption" = "Об %@";
-"organizer.cells.uninstall.caption" = "Удалить VPN конфигурацию";
-"organizer.alerts.exhausted_providers.message" = "Вы создали профили для всех доступных провайдеров.";
-"organizer.alerts.add_host.message" = "Откройте ссылку на .ovpn файл конфигурации через Safari, Почту или другое приложение для добавление хост профиля.\n\nВы также можете импортировать .ovpn файл через общие файлы iTunes.";
-"organizer.alerts.cannot_donate.message" = "На этом усторйстве не выбран способ платежа.";
-"organizer.alerts.delete_vpn_profile.message" = "Вы действительно хотите убрать VPN конфигурацию из настроек устройства? Это может исправить несколько VPN ошибок, но не изменит установки приложения.";
-
-"wizards.host.cells.title_input.caption" = "Название";
-"wizards.host.sections.existing.header" = "Существующие профили";
-"wizards.host.alerts.existing.message" = "Хост профиль с этим названием уже существует. Заменить?";
-
-"parsed_file.alerts.malformed.message" = "Файл конфигурации содержит неверную опцию (%@).";
-"parsed_file.alerts.missing.message" = "Файл конфигурации не содержит необходимую опцию (%@).";
-"parsed_file.alerts.unsupported.message" = "Файл конфигурации содержит неподдерживаемую опцию (%@).";
-"parsed_file.alerts.potentially_unsupported.message" = "Файл конфигурации верный, но возможно содержит неподдерживаемую опцию (%@).\n\nСоединение может прерваться - зависит от настроек сервера.";
-"parsed_file.alerts.encryption_passphrase.message" = "Пожалуйста, введите кодовую фразу шифрования";
-"parsed_file.alerts.decryption.message" = "Конфигурация содержит зашифрованный приватный ключ, он не может быть расшифрован. Перепроверьте кодовую фразу.";
-"parsed_file.alerts.parsing.message" = "Не получается разобрать предоставленный файл конфигурации (%@).";
-"parsed_file.alerts.buttons.report" = "Сообщить о проблеме";
-
-"imported_hosts.title" = "Импортированные хост профили";
-
-"service.welcome.message" = "Добро пожаловать в Passepartout!\n\nИспользуйте организатор для добавления нового профиля.";
-"service.sections.general.header" = "Основное";
-"service.sections.vpn.header" = "VPN";
-"service.sections.vpn.footer" = "Соединение будет установлено при необходимости.";
-"service.sections.status.header" = "Соединение";
-"service.sections.configuration.header" = "Конфигурация";
-"service.sections.provider_infrastructure.footer" = "Последнее обновление %@.";
-"service.sections.vpn_survives_sleep.footer" = "Отключите для уменьшения расхода заряда аккумулятора, может привести к временным замедлениям в связи с повторным подключением после \"пробуждения\".";
-"service.sections.vpn_resolves_hostname.footer" = "Предпочтительно в большинстве сетей и необходимо в некоторых IPv6 сетях. Отключите если DNS заблокирован, или для увеличения скорости в случае медленных ответов DNS.";
-//"service.sections.vpn_prefers_udp.footer" = "UDP быстрее TCP, но может не работать в некоторых сетях. Отключите в случае блокировки UDP в Вашей сети.";
-"service.sections.trusted.header" = "Доверенные сети";
-"service.sections.trusted.footer" = "При подключении к доверенным сетям VPN обычно выключается, и остаётся отключенным. Отключите эту опцию чтобы оставлять VPN подключенным.";
-"service.sections.diagnostics.header" = "Диагностика";
-"service.sections.diagnostics.footer" = "Маскировка включится после повторного подключения. Информация о сети - это названия хост профилей, IP адрес, маршрутизация и SSID. Данные для входа и приватные ключи не собираются.";
-//"service.sections.destruction.footer" = "Удалить конфигурацию из настроек устройства.";
-
-"service.cells.use_profile.caption" = "Использовать это профиль.";
-"service.cells.vpn_service.caption" = "Включен";
-"service.cells.connection_status.caption" = "Статус";
-"service.cells.reconnect.caption" = "Переподключиться";
-"service.cells.account.caption" = "Аккаунт";
-"service.cells.account.none" = "Ничего не создано";
-"service.cells.endpoint.caption" = "Конечная точка";
-"service.cells.provider.pool.caption" = "Местоположение";
-"service.cells.provider.preset.caption" = "Пресет";
-"service.cells.provider.refresh.caption" = "Обновить инфраструктуру";
-"service.cells.host.parameters.caption" = "Параметры";
-"service.cells.network_settings.caption" = "Сетевые настройки";
-"service.cells.vpn_survives_sleep.caption" = "Оставлять включенным во время сна";
-"service.cells.vpn_resolves_hostname.caption" = "Разрешить имя хоста сервера";
-//"service.cells.vpn_prefers_udp.caption" = "Предпочитать UDP подключение";
-"service.cells.trusted_mobile.caption" = "Мобильная сеть";
-"service.cells.trusted_add_wifi.caption" = "Добавить текущий Wi-Fi";
-"service.cells.trusted_policy.caption" = "Дов. сеть отключает VPN";
-"service.cells.test_connectivity.caption" = "Проверить подключение";
-"service.cells.data_count.caption" = "Переданная информация";
-"service.cells.data_count.none" = "Недоступно";
-"service.cells.debug_log.caption" = "Журнал отладки";
-"service.cells.masks_private_data.caption" = "Маскировать информацию сети";
-"service.cells.report_issue.caption" = "Сообщить о проблеме подкл.";
-
-"service.alerts.rename.title" = "Переименовать профиль";
-"service.alerts.credentials_needed.message" = "Сначала нужно ввести данные аккаунта.";
-"service.alerts.reconnect_vpn.message" = "Хотите заново подключиться к VPN?";
-"service.alerts.trusted.no_network.message" = "Вы не подключены к Wi-Fi.";
-"service.alerts.trusted.will_disconnect_trusted.message" = "При доверии этой сети VPN может быть отключен. Продолжить?";
-"service.alerts.trusted.will_disconnect_policy.message" = "При изменении установок доверия VPN может быть отключен. Продолжить?";
-"service.alerts.test_connectivity.title" = "Связь";
-"service.alerts.test_connectivity.messages.success" = "Ваше устройство подключено к интернету!";
-"service.alerts.test_connectivity.messages.failure" = "Ваше устройство не подключено к интернету, пожалйста проверьте установки Вашего профиля.";
-"service.alerts.masks_private_data.messages.must_reconnect" = "Для безопасного сброса журнала отладки и изменения маскировки информации сети Вы должны заново подключиться к VPN.";
-"service.alerts.buttons.reconnect" = "Переподключить";
-"service.alerts.download.title" = "Необходимо скачивание";
-"service.alerts.download.message" = "%@ необходимы дополнительные файлы конфигурации.\n\nПодтвердите для скачивания.";
-"service.alerts.download.failed" = "Не удалось скачать файлы конфигурации.%@";
-"service.alerts.download.hud.extracting" = "Извлечение файлов, пожалуста подождите...";
-
-"account.sections.credentials.header" = "Данные для входа";
-"account.sections.guidance.footer.infrastructure.mullvad" = "Используйте Ваши данные для входа с веб-сайта %@. Ваш логин обычно числовой с.";
-"account.sections.guidance.footer.infrastructure.nordvpn" = "Используйте данные для входа на %@ веб-сайт. Ваш логин обычно Ваш e-mail.";
-"account.sections.guidance.footer.infrastructure.pia" = "Используйте Ваши данные для входа с веб-сайта %@. Ваш логин обычно числовой с приставкой \"p\".";
-"account.sections.guidance.footer.infrastructure.protonvpn" = "Найдите Ваши данные для входа %@ \"Account > OpenVPN / IKEv2 Username\" секции веб-сайта.";
-"account.sections.guidance.footer.infrastructure.tunnelbear" = "Используйте данные для входа на %@ веб-сайт. Ваш логин обычно Ваш e-mail.";
-"account.sections.guidance.footer.infrastructure.vyprvpn" = "Используйте данные для входа на %@ веб-сайт. Ваш логин обычно Ваш e-mail.";
-"account.sections.guidance.footer.infrastructure.windscribe" = "Найдите Ваши данные для входа %@ в OpenVPN Config Generator на веб-сайте.";
-"account.sections.registration.footer" = "Создайте аккаунт на %@ веб-сайте.";
-"account.cells.username.caption" = "Логин";
-"account.cells.username.placeholder" = "логин";
-"account.cells.password.caption" = "Пароль";
-"account.cells.password.placeholder" = "пароль";
-//"account.cells.password_confirm.caption" = "Подтвердить";
-//"account.cells.password_confirm.mismatch" = "Пароли не совпадают!";
-"account.cells.open_guide.caption" = "Проверьте Ваши данные";
-"account.cells.signup.caption" = "Зарегистрируйтесь с %@";
-
-"endpoint.sections.location_addresses.header" = "Адреса";
-"endpoint.sections.location_protocols.header" = "Протоколы";
-"endpoint.cells.any_address.caption" = "Автоматически";
-"endpoint.cells.any_protocol.caption" = "Автоматически";
-
-"provider.preset.cells.tech_details.caption" = "Техническая информация";
-//"provider.preset.sections.main.footer" = "Нажмите i для раскрытия технической информации.";
-
-"configuration.sections.communication.header" = "Связь";
-"configuration.sections.reset.footer" = "Если после изменения параметров связи у Вас разорвалось соединение, нажмите, чтобы вернуться к исходной конфигурации.";
-"configuration.sections.tls.header" = "TLS";
-"configuration.sections.compression.header" = "Компресия";
-"configuration.sections.network.header" = "Сеть";
-"configuration.sections.other.header" = "Другое";
-"configuration.cells.cipher.caption" = "Шифруем";
-"configuration.cells.digest.caption" = "Аутентификация";
-"configuration.cells.digest.value.embedded" = "Внедрена";
-"configuration.cells.reset_original.caption" = "Сброс конфигурации";
-"configuration.cells.client.caption" = "Сертификат клиента";
-"configuration.cells.client.value.enabled" = "Проверено";
-"configuration.cells.client.value.disabled" = "Не проверено";
-"configuration.cells.tls_wrapping.caption" = "Упаковываем";
-"configuration.cells.tls_wrapping.value.auth" = "Аутентификация";
-"configuration.cells.tls_wrapping.value.crypt" = "Шифрование";
-"configuration.cells.eku.caption" = "Расширенная проверка";
-"configuration.cells.default_gateway.caption" = "Шлюз по умолчанию";
-"configuration.cells.dns_server.caption" = "DNS";
-"configuration.cells.dns_domain.caption" = "Домен";
-"configuration.cells.proxy_http.caption" = "Прокси";
-"configuration.cells.proxy_https.caption" = "Прокси (HTTPS)";
-"configuration.cells.compression_framing.caption" = "Фрейминг";
-"configuration.cells.compression_framing.value.lzo" = "--comp-lzo";
-"configuration.cells.compression_framing.value.compress" = "--compress";
-"configuration.cells.compression_algorithm.caption" = "Алгоритм";
-"configuration.cells.compression_algorithm.value.lzo" = "LZO";
-"configuration.cells.compression_algorithm.value.other" = "Неподдерживаемое";
-"configuration.cells.keep_alive.caption" = "Поддерживаем";
-"configuration.cells.keep_alive.value.seconds" = "%d секунд";
-"configuration.cells.renegotiation_seconds.caption" = "Перезаключение";
-"configuration.cells.renegotiation_seconds.value.after" = "после %@";
-"configuration.cells.random_endpoint.caption" = "Рандомная конечная точка";
-
-"network_settings.cells.choice.client" = "Читать .ovpn";
-"network_settings.cells.choice.server" = "Вытащить с сервера";
-"network_settings.cells.address.caption" = "Адрес";
-"network_settings.cells.port.caption" = "порт";
-"network_settings.cells.add_dns_server.caption" = "Добавить адрес";
-"network_settings.cells.proxy_bypass.caption" = "Обход домена";
-"network_settings.cells.add_proxy_bypass.caption" = "Добавить обходной домен";
-
-"debug_log.buttons.previous" = "Предыдущий";
-"debug_log.buttons.next" = "Следующий";
-"debug_log.alerts.empty_log.message" = "Журнал отладки пуст.";
-
-"vpn.connecting" = "Подключается";
-"vpn.active" = "Активен";
-"vpn.disconnecting" = "Отключается";
-"vpn.inactive" = "Не активен";
-"vpn.disabled" = "Отключен";
-
-"vpn.errors.timeout" = "Тайм-аут";
-"vpn.errors.dns" = "Ошибка DNS";
-"vpn.errors.auth" = "Ошибка аутентификации";
-"vpn.errors.tls" = "Ошибка TSL";
-"vpn.errors.encryption" = "Ошибка расшифровки";
-"vpn.errors.compression" = "Сжатие не поддерживается";
-"vpn.errors.network" = "Изменение сети";
-"vpn.errors.routing" = "Отсутствует маршрутизация";
-"vpn.errors.gateway" = "Нет шлюза";
-
-"issue_reporter.title" = "Сообщить о проблеме";
-"issue_reporter.message" = "Журнал отладки Вашего последнего соединения необходим для разрешения проблем подключения, и является полностью анонимным.\n\n .ovpn файл, если есть, прикреплён без каких-либо конфиденциальных данных .\n\nПожалуйста, перепроверьте прикреплённые файлы, если не уверены.";
-"issue_reporter.buttons.accept" = "Я понимаю";
-
-"translations.title" = "Переводы";
-
-"shortcuts.add.title" = "Создать команду";
-"shortcuts.add.sections.vpn.header" = "VPN";
-"shortcuts.add.sections.wifi.header" = "Wi-Fi";
-"shortcuts.add.sections.cellular.header" = "Мобильная сеть";
-"shortcuts.add.cells.connect.caption" = "Подключиться к";
-"shortcuts.add.cells.enable_vpn.caption" = "Включи VPN";
-"shortcuts.add.cells.disable_vpn.caption" = "Выключи VPN";
-"shortcuts.add.cells.trust_current_wifi.caption" = "Доверять текущему Wi-Fi";
-"shortcuts.add.cells.untrust_current_wifi.caption" = "Не доверять текущему Wi-Fi";
-"shortcuts.add.cells.trust_cellular.caption" = "Доверять мобильной сети";
-"shortcuts.add.cells.untrust_cellular.caption" = "Не доверять мобильной сети";
-"shortcuts.add.alerts.no_profiles.message" = "Нет профиля для подключения.";
-
-"shortcuts.edit.title" = "Управлять командами";
-"shortcuts.edit.sections.all.header" = "Существующие команды";
-"shortcuts.edit.cells.add_shortcut.caption" = "Создать команду";
-
-"about.title" = "О нас";
-"about.sections.web.header" = "Веб";
-"about.sections.share.header" = "Поделиться";
-"about.cells.credits.caption" = "Благодарности";
-"about.cells.website.caption" = "Домашняя страница";
-"about.cells.faq.caption" = "FAQ";
-"about.cells.disclaimer.caption" = "Предупреждение";
-"about.cells.privacy_policy.caption" = "Политика конфиденциальности";
-"about.cells.share_twitter.caption" = "Твитнуть о нас!";
-"about.cells.share_generic.caption" = "Пригласить друга";
-
-"donation.title" = "Пожертвовать";
-"donation.sections.one_time.header" = "Один раз";
-"donation.sections.one_time.footer" = "Если Вы хотите поблагодарить мою бесплатную работу, здесь есть несколько сумм, которые Вы можете пожертвовать прямо сейчас.\n\nСумма будет списана только один раз, а Вы можете пожертвовать несколько раз.";
-"donation.cells.loading.caption" = "Загружаем пожертвования";
-"donation.cells.purchasing.caption" = "Исполняется";
-"donation.alerts.purchase.success.title" = "Спасибо";
-"donation.alerts.purchase.success.message" = "Это значит многое для меня, и, я надеюсь, Вы продолжить использовать и рассказывать об этом приложении.";
-"donation.alerts.purchase.failure.message" = "Не получается совершить пожертвование. %@";
-
-"share.message" = "Passepartout - это простой в использовании OpenVPN клиент для iOS и macOS, с открытым исходным кодом";
-
-"version.title" = "Версия";
-"version.labels.intro" = "Passepartout и TunnelKit написаны и установлены Davide De Rosa (keeshux).\n\nИсходные коды для Passepartout и TunnelKit публично доступны на GitHub под GPLv3, вы можете найти ссылки на домашней странице.\n\nPassepartout является неофициальным клиентом, и никаким образом не связан с OpenVPN Inc.";
-
-"credits.title" = "Благодарность";
-"credits.sections.licenses.header" = "Лицензии";
-"credits.sections.notices.header" = "Упоминания";
-"credits.sections.translations.header" = "Переводы";
-
-"label.license.error" = "Не получается загрузить полную лицензию.";
diff --git a/Passepartout/Resources/sv.lproj/Intents.strings b/Passepartout/Resources/sv.lproj/Intents.strings
deleted file mode 100644
index a3a2e812..00000000
--- a/Passepartout/Resources/sv.lproj/Intents.strings
+++ /dev/null
@@ -1,39 +0,0 @@
-"0jRWn5" = "Tar bort cellular från betrodda nätverk";
-
-"1ZRTCZ" = "Avstäng VPN";
-
-"66bZBE" = "Med ${providerId} leverantör";
-
-"7eoAss" = "Tar bort nuvarande Wi-Fi från betrodda nätverk";
-
-"9GpJt5" = "Tillsätter cellular till lita betrodda nätverk";
-
-"BKxs8X" = "Tillsätter nuvarande Wi-Fi till betrodda nätverk";
-
-"H4taev" = "Lita på cellular nätverk";
-
-"KjkCfU" = "Koppla till en specifik plats från en leverantör profil";
-
-"LA99yM" = "Koppla till VPN";
-
-"U6o81V" = "Koppla till ${profileId}";
-
-"WnTPFg" = "Koppla till ${poolName}";
-
-"eQ1yzr" = "Avstäng VPN service";
-
-"eXXb2z" = "Koppla till en host profil";
-
-"lQ6ziK" = "Avstäng VPN";
-
-"m2E7SI" = "lita på närvarande Wi-Fi";
-
-"qo3Szz" = "Koppla till provider plats";
-
-"rd1T8p" = "Untrust närvarande Wi-Fi";
-
-"wB1iYX" = "Untrust cellular nätverk";
-
-"xY97Vu" = "På-sätter VPN service med närvarande profil";
-
-"NCoK9B" = "Med profil i andvänding";
diff --git a/Passepartout/Resources/sv.lproj/Localizable.strings b/Passepartout/Resources/sv.lproj/Localizable.strings
deleted file mode 100644
index 788f528c..00000000
--- a/Passepartout/Resources/sv.lproj/Localizable.strings
+++ /dev/null
@@ -1,283 +0,0 @@
-//
-// Localizable.strings
-// Passepartout
-//
-// Created by Davide De Rosa on 6/13/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-"global.ok" = "OK";
-"global.cancel" = "Annullera";
-"global.next" = "Nästa";
-"global.close" = "Stäng";
-"global.host.title_input.message" = "Godtagbara tecken är alfanumeriska plus bindestreck \" - \", understrykning \" _ \"och punkt \". \".";
-"global.host.title_input.placeholder" = "Min profil";
-"global.email_not_configured" = "Inget e-postkonto är konfigurerat.";
-
-"global.cells.enabled" = "Aktiverad";
-"global.cells.disabled" = "Inaktiverad";
-"global.cells.none" = "Ingen";
-"global.cells.automatic" = "Automatiskt";
-"global.cells.manual" = "Manuellt";
-
-"reddit.title" = "Reddit";
-"reddit.message" = "Visste du att Passepartout har en subreddit? Prenumerera på uppdateringar eller diskutera problem, funktioner, nya plattformar eller vad du vill. \n\nDet är också ett bra sätt att visa dig bryr dig om detta projekt." ;
-"reddit.buttons.subscribe" = "Prenumerera nu!";
-"reddit.buttons.remind" = "Påminn mig senare";
-"reddit.buttons.never" = "Fråga inte igen";
-
-"organizer.sections.providers.header" = "Providers";
-"organizer.sections.providers.footer" = "Här hittar du några leverantörer med förinställda konfigurationsprofiler.";
-"organizer.sections.hosts.header" = "Värdar";
-"organizer.sections.hosts.footer" = "Importera värdar från .ovpn konfigurationsfiler.";
-"organizer.sections.siri.header" = "Siri";
-"organizer.sections.siri.footer" = "Få hjälp från Siri för att påskynda dina vanligaste interaktioner med appen.";
-"organizer.sections.support.header" = "Support";
-"organizer.sections.feedback.header" = "Feedback";
-"organizer.cells.profile.value.current" = "Under användning";
-"organizer.cells.add_provider.caption" = "Lägg till ny leverantör";
-"organizer.cells.add_host.caption" = "Lägg till ny värd";
-"organizer.cells.siri_shortcuts.caption" = "Hantera genvägar";
-"organizer.cells.join_community.caption" = "Gå med i samhället";
-"organizer.cells.write_review.caption" = "Skriv en recension";
-"organizer.cells.donate.caption" = "Gör en donation";
-"organizer.cells.patreon.caption" = "Stötta mig på Patreon";
-"organizer.cells.translate.caption" = "Erbjuda att översätta";
-"organizer.cells.about.caption" = "Om %@";
-"organizer.cells.uninstall.caption" = "Ta bort VPN-konfiguration";
-"organizer.alerts.exhausted_providers.message" = "Du har skapat profiler för alla tillgängliga leverantörer.";
-"organizer.alerts.add_host.message" = "Öppna en URL till en .ovpn konfigurationsfil från Safari, Mail eller en annan app för att skapa en värdprofil. \n\nDu kan också importera en .ovpn med iTunes Fildelning." ;
-"organizer.alerts.cannot_donate.message" = "Det finns ingen betalningsmetod konfigurerad på den här enheten.";
-"organizer.alerts.delete_vpn_profile.message" = "Vill du verkligen radera VPN-konfigurationen från enhetens inställningar? Detta kan fixas med några brutna VPN-stater och påverkar inte dina leverantörs- och värdprofiler.";
-
-"wizards.host.cells.title_input.caption" = "Namn";
-"wizards.host.sections.existing.header" = "Befintliga profiler";
-"wizards.host.alerts.existing.message" = "En värdprofil med samma namn finns redan. Byt ut det?";
-
-"parsed_file.alerts.malformed.message" = "Konfigurationsfilen innehåller ett felaktigt val (%@).";
-"parsed_file.alerts.missing.message" = "Konfigurationsfilen saknar ett obligatoriskt val (%@).";
-"parsed_file.alerts.unsupported.message" = "Konfigurationsfilen innehåller ett stöd som inte stöds (%@).";
-"parsed_file.alerts.potentially_unsupported.message" = "Konfigurationsfilen är korrekt men innehåller ett eventuellt stöd som inte stöds (%@). \n\nConnectivity kan bryta beroende på serverinställningar.";
-"parsed_file.alerts.encryption_passphrase.message" = "Var god ange krypterings lösenordsfrasen.";
-"parsed_file.alerts.decryption.message" = "Konfigurationen innehåller en krypterad privat nyckel och den kan inte dekrypteras. Dubbelkontrollera ditt inmatade lösenfras.";
-"parsed_file.alerts.parsing.message" = "Det gick inte att analysera den angivna konfigurationsfilen (%@).";
-"parsed_file.alerts.buttons.report" = "Rapportera ett problem";
-
-"imported_hosts.title" = "Importerade värdar";
-
-"service.welcome.message" = "Välkommen till Passepartout! \n\nAnvänd arrangören för att lägga till en ny profil.";
-"service.sections.general.header" = "Allmän";
-"service.sections.vpn.header" = "VPN";
-"service.sections.vpn.footer" = "Anslutningen kommer att upprättas vid behov.";
-"service.sections.status.header" = "Koppling";
-"service.sections.configuration.header" = "Konfiguration";
-"service.sections.provider_infrastructure.footer" = "Senast uppdaterad på %@.";
-"service.sections.vpn_survives_sleep.footer" = "Inaktivera för att förbättra batterianvändningen, på bekostnad av tillfälliga avmattningar på grund av återuppkoppling.";
-"service.sections.vpn_resolves_hostname.footer" = "Föredragna i de flesta nätverk och krävs i vissa IPv6-nätverk. Inaktivera var DNS blockeras eller för att påskynda förhandlingar när DNS är långsamt att svara.";
-//"service.sections.vpn_prefers_udp.footer "=" UDP är snabbare än TCP, men fungerar kanske inte i vissa nätverk. Inaktivera i nätverk där UDP kan blockeras. ";
-"service.sections.trusted.header" = "Trusted networks";
-"service.sections.trusted.footer" = "När du advänder ett betrodat nätverk, VPNet stängs normalt och hålls bortkopplat. Avaktivera detta alternativet för att inte genomdriva sådant beteende.";
-"service.sections.diagnostics.header" = "Diagnostics";
-"service.sections.diagnostics.footer" = "Masking status kommer att fungera efter återanslutning. Nätverksdata är värdnamn, IP-adresser, routing, SSID. Referenser och privata nycklar loggas inte oavsett.";
-//"service.sections.destruction.footer "=" Radera konfiguration från enhetsinställningar. ";
-
-"service.cells.use_profile.caption" = "Använd den här profilen";
-"service.cells.vpn_service.caption" = "Aktiverad";
-"service.cells.connection_status.caption" = "Status";
-"service.cells.reconnect.caption" = "Återanslut";
-"service.cells.account.caption" = "Konto";
-"service.cells.account.none" = "Ingen konfigurerad";
-"service.cells.endpoint.caption" = "Slutpunkt";
-"service.cells.provider.pool.caption" = "Plats";
-"service.cells.provider.preset.caption" = "Förinställt";
-"service.cells.provider.refresh.caption" = "Uppdatera infrastruktur";
-"service.cells.host.parameters.caption" = "Parametrar";
-"service.cells.network_settings.caption" = "Nätverksinställningar";
-"service.cells.vpn_survives_sleep.caption" = "Håll dig levande i sömnen";
-"service.cells.vpn_resolves_hostname.caption" = "Lösa server värdnamn";
-//"service.cells.vpn_prefers_udp.caption "=" Välj UDP-uttag ";
-"service.cells.trusted_mobile.caption" = "Mobilt nätverk";
-"service.cells.trusted_add_wifi.caption" = "Lägg till nuvarande Wi-Fi";
-"service.cells.trusted_policy.caption" = "Förtroende inaktiverar VPN";
-"service.cells.test_connectivity.caption" = "Testanslutning";
-"service.cells.data_count.caption" = "Utbyttad data";
-"service.cells.data_count.none" = "Otillgänglig";
-"service.cells.debug_log.caption" = "Debug log";
-"service.cells.masks_private_data.caption" = "Mask nätverksdata";
-"service.cells.report_issue.caption" = "Rapportera anslutningsproblem";
-
-"service.alerts.rename.title" = "Byt namn på profil";
-"service.alerts.credentials_needed.message" = "Du måste ange kontouppgifterna först.";
-"service.alerts.reconnect_vpn.message" = "Vill du återansluta till VPN?";
-"service.alerts.trusted.no_network.message" = "Du är inte ansluten till något Wi-Fi-nätverk.";
-"service.alerts.trusted.will_disconnect_trusted.message" = "Genom att lita på detta nätverk kan VPN kopplas bort. Fortsätt?";
-"service.alerts.trusted.will_disconnect_policy.message" = "Genom att byta tillitspolicy kan VPN kopplas bort. Fortsätt?";
-"service.alerts.test_connectivity.title" = "Anslutningar";
-"service.alerts.test_connectivity.messages.success" = "Din enhet är ansluten till Internet!";
-"service.alerts.test_connectivity.messages.failure" = "Din enhet har ingen Internetanslutning, var god granska dina profilparametrar.";
-"service.alerts.masks_private_data.messages.must_reconnect" = "För att säkert återställa den aktuella felsökningsloggen och tillämpa den nya maskeringspreferensen måste du återansluta till VPN nu.";
-"service.alerts.buttons.reconnect" = "Reconnect";
-"service.alerts.download.title" = "Ladda ner krävs";
-"service.alerts.download.message" = "%@ kräver nedladdning av ytterligare konfigurationsfiler. \n\nKontrollera för att starta nedladdningen.";
-"service.alerts.download.failed" = "Misslyckades med att ladda ner konfigurationsfiler. %@";
-"service.alerts.download.hud.extracting" = "Extraherar filer, var så tålmodig ...";
-
-"account.sections.credentials.header" = "Referenser";
-"account.sections.guidance.footer.infrastructure.mullvad" = "Använd dina %@ webbplatsuppgifter. Ditt användarnamn är vanligtvis numeriskt.";
-"account.sections.guidance.footer.infrastructure.nordvpn" = "Använd dina %@ webbplatsuppgifter. Ditt användarnamn är vanligtvis ditt e-postmeddelande.";
-"account.sections.guidance.footer.infrastructure.pia" = "Använd dina %@ webbplatsuppgifter. Ditt användarnamn är vanligtvis numeriskt med ett prefix för \" p \".";
-"account.sections.guidance.footer.infrastructure.protonvpn" = "Hitta dina %@ credentials i avsnittet \" Konto> OpenVPN / IKEv2 Användarnamn \"på webbplatsen.";
-"account.sections.guidance.footer.infrastructure.tunnelbear" = "Använd dina %@ webbplatsuppgifter. Ditt användarnamn är vanligtvis ditt e-postmeddelande.";
-"account.sections.guidance.footer.infrastructure.vyprvpn" = "Använd dina %@ webbplatsuppgifter. Ditt användarnamn är vanligtvis ditt e-postmeddelande.";
-"account.sections.guidance.footer.infrastructure.windscribe" = "Hitta din %@ credentials i OpenVPN Config Generator på webbplatsen.";
-"account.sections.registration.footer" = "Hämta ett konto på %@ webbplatsen.";
-"account.cells.username.caption" = "Användarnamn";
-"account.cells.username.placeholder" = "användarnamn";
-"account.cells.password.caption" = "Lösenord";
-"account.cells.password.placeholder" = "hemlighet";
-//"account.cells.password_confirm.caption "=" Bekräfta ";
-//"account.cells.password_confirm.mismatch "=" Lösenorden matchar inte! ";
-"account.cells.open_guide.caption" = "Visa dina uppgifter";
-"account.cells.signup.caption" = "Registrera med %@";
-
-"endpoint.sections.location_addresses.header" = "Adresser";
-"endpoint.sections.location_protocols.header" = "Protokoll";
-"endpoint.cells.any_address.caption" = "Automatiskt";
-"endpoint.cells.any_protocol.caption" = "Automatiskt";
-
-"provider.preset.cells.tech_details.caption" = "Tekniska detaljer";
-//"provider.preset.sections.main.footer "=" Tryck på info-knappen för att avslöja tekniska detaljer. ";
-
-"configuration.sections.communication.header" = "Communication";
-"configuration.sections.reset.footer" = "Om du slutade med bruten anslutning efter att ha ändrat kommunikationsparametrarna trycker du på för att återgå till den ursprungliga konfigurationen.";
-"configuration.sections.tls.header" = "TLS";
-"configuration.sections.compression.header" = "Kompression";
-"configuration.sections.network.header" = "Nätverk";
-"configuration.sections.other.header" = "Other";
-"configuration.cells.cipher.caption" = "Cipher";
-"configuration.cells.digest.caption" = "Autentisering";
-"configuration.cells.digest.value.embedded" = "Inbäddad";
-"configuration.cells.reset_original.caption" = "Återställ konfiguration";
-"configuration.cells.client.caption" = "Klientcertifikat";
-"configuration.cells.client.value.enabled" = "Verified";
-"configuration.cells.client.value.disabled" = "Ej verifierad";
-"configuration.cells.tls_wrapping.caption" = "Omslagning";
-"configuration.cells.tls_wrapping.value.auth" = "Autentisering";
-"configuration.cells.tls_wrapping.value.crypt" = "Kryptering";
-"configuration.cells.eku.caption" = "Förlängd verifering";
-"configuration.cells.default_gateway.caption" = "Normal gateway";
-"configuration.cells.dns_server.caption" = "DNS";
-"configuration.cells.dns_domain.caption" = "Domain";
-"configuration.cells.proxy_http.caption" = "Proxy";
-"configuration.cells.proxy_https.caption" = "Proxy (HTTPS)";
-"configuration.cells.compression_framing.caption" = "Inramning";
-"configuration.cells.compression_framing.value.lzo" = "--comp-lzo";
-"configuration.cells.compression_framing.value.compress" = "--compress";
-"configuration.cells.compression_algorithm.caption" = "Algoritm";
-"configuration.cells.compression_algorithm.value.lzo" = "LZO";
-"configuration.cells.compression_algorithm.value.other" = "Utan stöd";
-"configuration.cells.keep_alive.caption" = "hål-vid-liv";
-"configuration.cells.keep_alive.value.seconds" = "%d seconds";
-"configuration.cells.renegotiation_seconds.caption" = "Omförhandling";
-"configuration.cells.renegotiation_seconds.value.after" = "efter %@";
-"configuration.cells.random_endpoint.caption" = "Omställ slutpunkt pa slumpmässigt sätt";
-
-"network_settings.cells.choice.client" = "Läs .ovpn";
-"network_settings.cells.choice.server" = "Dra från server";
-"network_settings.cells.address.caption" = "Adress";
-"network_settings.cells.port.caption" = "Port";
-"network_settings.cells.add_dns_server.caption" = "Lägg till adress";
-"network_settings.cells.proxy_bypass.caption" = "Bypass-domän";
-"network_settings.cells.add_proxy_bypass.caption" = "Add bypass domain";
-
-"debug_log.buttons.previous" = "Previous";
-"debug_log.buttons.next" = "Next";
-"debug_log.alerts.empty_log.message" = "Felsökningsloggen är tom.";
-
-"vpn.connecting" = "Anslutning";
-"vpn.active" = "Activ";
-"vpn.disconnecting" = "Koppla bort";
-"vpn.inactive" = "Inaktiv";
-"vpn.disabled" = "Inaktiverad";
-
-"vpn.errors.timeout" = "Timeout";
-"vpn.errors.dns" = "DNS misslyckades";
-"vpn.errors.auth" = "Auth failed";
-"vpn.errors.tls" = "TLS misslyckades";
-"vpn.errors.encryption" = "Kryptering misslyckades";
-"vpn.errors.compression" = "Komprimering utan stöd";
-"vpn.errors.network" = "Nätverk ändrat";
-"vpn.errors.routing" = "Saknad routing";
-"vpn.errors.gateway" = "Ingen gateway";
-
-"issue_reporter.title" = "Rapportera problem";
-"issue_reporter.message" = "Felsökningsloggen för dina senaste anslutningar är avgörande för att lösa dina anslutningsproblem och är helt anonym. \n\nHanteringsfilen .ovpn är eventuellt bifogad av någon känslig data. \n\nPresentera dubbelkolla e-postbilagorna om du är osäker. ";
-"issue_reporter.buttons.accept" = "Jag förstår";
-
-"translations.title" = "Översättningar";
-
-"shortcuts.add.title" = "Lägg till genväg";
-"shortcuts.add.sections.vpn.header" = "VPN";
-"shortcuts.add.sections.wifi.header" = "Wi-Fi";
-"shortcuts.add.sections.cellular.header" = "Cellular";
-"shortcuts.add.cells.connect.caption" = "Anslut till";
-"shortcuts.add.cells.enable_vpn.caption" = "Aktivera VPN";
-"shortcuts.add.cells.disable_vpn.caption" = "Inaktivera VPN";
-"shortcuts.add.cells.trust_current_wifi.caption" = "Lita på nuvarande Wi-Fi";
-"shortcuts.add.cells.untrust_current_wifi.caption" = "Avaktivera nuvarande Wi-Fi";
-"shortcuts.add.cells.trust_cellular.caption" = "Lita på mobilnätverk";
-"shortcuts.add.cells.untrust_cellular.caption" = "Untrust cellular network";
-"shortcuts.add.alerts.no_profiles.message" = "Det finns ingen profil att ansluta till.";
-
-"shortcuts.edit.title" = "Hantera genvägar";
-"shortcuts.edit.sections.all.header" = "Befintliga genvägar";
-"shortcuts.edit.cells.add_shortcut.caption" = "Lägg till genväg";
-
-"about.title" = "About";
-"about.sections.web.header" = "Web";
-"about.sections.share.header" = "Dela";
-"about.cells.credits.caption" = "Credits";
-"about.cells.website.caption" = "Hemsida";
-"about.cells.faq.caption" = "FAQ";
-"about.cells.disclaimer.caption" = "Disclaimer";
-"about.cells.privacy_policy.caption" = "Sekretesspolicy";
-"about.cells.share_twitter.caption" = "Tweet om det!";
-"about.cells.share_generic.caption" = "Bjud in en vän";
-
-"donation.title" = "Donera";
-"donation.sections.one_time.header" = "En gång";
-"donation.sections.one_time.footer" = "Om du vill visa tacksamhet för mitt fria arbete, här är några belopp du kan donera direkt. \n\nDu betalas endast en gång per donation, och du kan donera flera gånger. ";
-"donation.cells.loading.caption" = "Laddar donationer";
-"donation.cells.purchasing.caption" = "Performing donation";
-"donation.alerts.purchase.success.title" = "Tack";
-"donation.alerts.purchase.success.message" = "Detta betyder mycket för mig och jag hoppas verkligen att du fortsätter att använda och marknadsföra denna app.";
-"donation.alerts.purchase.failure.message" = "Kan inte göra donationen. %@";
-
-"share.message" = "Passepartout är en användarvänlig öppen källkod OpenVPN-klient för iOS och macOS";
-
-"version.title" = "Version";
-"version.labels.intro" = "Passepartout och TunnelKit skrivs och underhålls av Davide De Rosa (keeshux). \n\nKällkod för Passepartout och TunnelKit är offentligt tillgänglig på GitHub under GPLv3, du kan hitta länkar på hemsidan. \n\nPassepartout är en icke-officiell klient och är inte på något sätt ansluten till OpenVPN Inc. ";
-
-"credits.title" = "Credits";
-"credits.sections.licenses.header" = "Licenses";
-"credits.sections.notices.header" = "Meddelanden";
-"credits.sections.translations.header" = "Translations";
-
-"label.license.error" = "Kan inte ladda ner fullständigt licensinnehåll.";
diff --git a/Passepartout/Sources/AppConstants.swift b/Passepartout/Sources/AppConstants.swift
deleted file mode 100644
index 628d3a4f..00000000
--- a/Passepartout/Sources/AppConstants.swift
+++ /dev/null
@@ -1,344 +0,0 @@
-//
-// AppConstants.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 9/15/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import TunnelKit
-import SwiftyBeaver
-
-public class AppConstants {
- public class App {
- public static let appStoreId: String = {
- guard let identifier = GroupConstants.App.config["appstore_id"] as? String else {
- fatalError("Missing appstore_id from Info.plist config")
- }
- return identifier
- }()
-
- public static let tunnelBundleId: String = {
- guard let identifier = Bundle.main.infoDictionary?[kCFBundleIdentifierKey as String] as? String else {
- fatalError("Missing kCFBundleIdentifierKey from Info.plist")
- }
- return "\(identifier).Tunnel"
- }()
- }
-
- public class Flags {
- public static let isBeta = false
- }
-
- public class Domain {
- public static let name = "passepartoutvpn.app"
- }
-
- public class Store {
- public static let serviceFilename = "ConnectionService.json"
-
- public static let webCacheDirectory = "Web"
-
- public static let providersDirectory = "Providers"
-
- public static let hostsDirectory = "Hosts"
- }
-
- public class Web {
- private static let version = "v2"
-
- private static let baseURL = Repos.api.appendingPathComponent(version)
-
- public static func url(path: String) -> URL {
- return baseURL.appendingPathComponent(path)
- }
-
- public static let timeout: TimeInterval = 3.0
-
- public static let minimumUpdateInterval: TimeInterval = 600.0 // 10 minutes
-
- private static let connectivityStrings: [String] = [
- "https://www.amazon.com",
- "https://www.google.com",
- "https://www.twitter.com",
- "https://www.facebook.com",
- "https://www.instagram.com"
- ]
-
- public static let connectivityURL = URL(string: connectivityStrings.customRandomElement())!
-
- public static let connectivityTimeout: TimeInterval = 10.0
- }
-
- public class Log {
- public static let level: SwiftyBeaver.Level = .debug
-
- public static let debugFormat = "$DHH:mm:ss$d - $M"
-
- public static var debugSnapshot: () -> String = { TransientStore.shared.service.vpnLog }
-
- public static let viewerRefreshInterval: TimeInterval = 3.0
-
- private static let fileName = "Debug.log"
-
- public static var fileURL: URL {
- return GroupConstants.App.cachesURL.appendingPathComponent(fileName)
- }
-
- private static let console: ConsoleDestination = {
- let dest = ConsoleDestination()
- dest.minLevel = level
- dest.useNSLog = true
- return dest
- }()
-
- private static let file: FileDestination = {
- let dest = FileDestination()
- dest.minLevel = level
- dest.logFileURL = fileURL
- _ = dest.deleteLogFile()
- return dest
- }()
-
- public static func configure() {
- SwiftyBeaver.addDestination(console)
- SwiftyBeaver.addDestination(file)
- }
- }
-
- public class IssueReporter {
- public class Email {
- public static let recipient = "issues@\(Domain.name)"
-
- public static let subject = "\(GroupConstants.App.name) - Report issue"
-
- public static func body(_ description: String, _ metadata: String) -> String {
- return "Hi,\n\n\(description)\n\n\(metadata)\n\nRegards"
- }
-
- public static let template = "description of the issue: "
- }
-
- public class Filenames {
- public static var debugLog: String {
- let fmt = DateFormatter()
- fmt.dateFormat = "yyyyMMdd-HHmmss"
- let iso = fmt.string(from: Date())
- return "debug-\(iso).txt"
- }
-
- public static let configuration = "profile.ovpn"
-// public static let configuration = "profile.ovpn.txt"
- }
-
- public class MIME {
- public static let debugLog = "text/plain"
-
-// public static let configuration = "application/x-openvpn-profile"
- public static let configuration = "text/plain"
- }
- }
-
- public class Translations {
- public class Email {
- public static let recipient = "translate@\(Domain.name)"
-
- public static let subject = "\(GroupConstants.App.name) - Translations"
-
- public static func body(_ description: String) -> String {
- return "Hi,\n\n\(description)\n\nRegards"
- }
-
- public static let template = "I offer to translate to: "
- }
-
- public static let authorByLanguage: [String: String] = [
- "de": "Christian Lederer",
- "el": "Konstantinos Koukoulakis",
- "es": "Davide De Rosa, Elena Vivó",
- "fr-FR": "Julien Laniel",
- "it": "Davide De Rosa",
- "nl": "Norbert de Vreede",
- "pt-BR": "Helder Santana",
- "ru": "Alexander Korobynikov",
- "sv": "Henry Gross-Hellsen"
- ]
- }
-
- public class URLs {
- public static let website = URL(string: "https://\(Domain.name)")!
-
- public static let faq = website.appendingPathComponent("faq")
-
- public static let disclaimer = website.appendingPathComponent("disclaimer")
-
- public static let privacyPolicy = website.appendingPathComponent("privacy")
-
- public static let readme = Repos.ios.appendingPathComponent("blob/master/README.md")
-
- public static let changelog = Repos.ios.appendingPathComponent("blob/master/CHANGELOG.md")
-
- public static let subreddit = URL(string: "https://www.reddit.com/r/passepartout")!
-
- public static let patreon = URL(string: "https://www.patreon.com/keeshux")!
-
- private static let twitterHashtags = ["OpenVPN", "iOS", "macOS"]
-
- public static var twitterIntent: URL {
- var text = L10n.Share.message
- for ht in twitterHashtags {
- text = text.replacingOccurrences(of: ht, with: "#\(ht)")
- }
- var comps = URLComponents(string: "https://twitter.com/intent/tweet")!
- comps.queryItems = [
- URLQueryItem(name: "url", value: website.absoluteString),
- URLQueryItem(name: "via", value: "keeshux"),
- URLQueryItem(name: "text", value: text)
- ]
- return comps.url!
- }
-
- public static func review(withId id: String) -> URL {
- return URL(string: "https://itunes.apple.com/app/id\(id)?action=write-review")!
- }
-
- public static let guidances: [Infrastructure.Name: String] = [
- .protonVPN: "https://account.protonvpn.com/settings",
- .windscribe: "https://windscribe.com/getconfig/openvpn"
- ]
-
- public static let referrals: [Infrastructure.Name: String] = [
- .mullvad: "https://mullvad.net/en/account/create/",
- .nordVPN: "https://go.nordvpn.net/SH21Z",
- .pia: "https://www.privateinternetaccess.com/pages/buy-vpn/",
- .protonVPN: "https://protonvpn.net/?aid=keeshux",
- .tunnelBear: "https://click.tunnelbear.com/SHb8",
- .vyprVPN: "https://www.vyprvpn.com/",
- .windscribe: "https://secure.link/kCsD0prd"
- ]
-
- public static let externalResources: [Infrastructure.Name: String] = [
- .nordVPN: "https://downloads.nordcdn.com/configs/archives/certificates/servers.zip" // 9MB
- ]
- }
-
- public class Repos {
- private static let githubRoot = URL(string: "https://github.com/passepartoutvpn/")!
-
- private static let githubRawRoot = URL(string: "https://\(Domain.name)/")!
-
- private static func github(repo: String) -> URL {
- return githubRoot.appendingPathComponent(repo)
- }
-
- private static func githubRaw(repo: String) -> URL {
- return githubRawRoot.appendingPathComponent(repo)
- }
-
- public static let ios = github(repo: "passepartout-ios")
-
- public static let api = githubRaw(repo: "api")
- }
-
- public struct License {
- public let name: String
-
- public let type: String
-
- public let url: URL
-
- public init(_ name: String, _ type: String, _ urlString: String) {
- self.name = name
- self.type = type
- url = URL(string: urlString)!
- }
-
- public static let all: [License] = [
- License(
- "lzo",
- "GPLv2",
- "https://www.gnu.org/licenses/gpl-2.0.txt"
- ),
- License(
- "MBProgressHUD",
- "MIT",
- "https://raw.githubusercontent.com/jdg/MBProgressHUD/master/LICENSE"
- ),
- License(
- "OpenSSL",
- "OpenSSL",
- "https://www.openssl.org/source/license.txt"
- ),
- License(
- "PIATunnel",
- "MIT",
- "https://raw.githubusercontent.com/pia-foss/tunnel-apple/master/LICENSE"
- ),
- License(
- "SSZipArchive",
- "MIT",
- "https://raw.githubusercontent.com/samsoffes/ssziparchive/master/LICENSE"
- ),
- License(
- "SwiftGen",
- "MIT",
- "https://raw.githubusercontent.com/SwiftGen/SwiftGen/master/LICENCE"
- ),
- License(
- "SwiftyBeaver",
- "MIT",
- "https://raw.githubusercontent.com/SwiftyBeaver/SwiftyBeaver/master/LICENSE"
- )
- ]
-
- public static var cachedContent: [String: String] = [:]
- }
-
- public struct Notice {
- public let name: String
-
- public let statement: String
-
- public init(_ name: String, _ statement: String) {
- self.name = name
- self.statement = statement
- }
-
- public static let all: [Notice] = [
- Notice(
- "Circle Icons",
- "The logo is taken from the awesome Circle Icons set by Nick Roach."
- ),
- Notice(
- "Country flags",
- "The country flags are taken from: https://github.com/lipis/flag-icon-css/"
- ),
- Notice(
- "OpenVPN",
- "© 2002-2018 OpenVPN Inc. - OpenVPN is a registered trademark of OpenVPN Inc."
- )
- ]
- }
-
- public struct Rating {
- public static let eventCount = 3
- }
-}
diff --git a/Passepartout/Sources/ApplicationError.swift b/Passepartout/Sources/ApplicationError.swift
deleted file mode 100644
index 93b33889..00000000
--- a/Passepartout/Sources/ApplicationError.swift
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// ApplicationError.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 6/12/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-
-public enum ApplicationError: String, Error {
- case missingProfile
-
- case missingCredentials
-
- case migration
-
- case inactiveProfile
-
- case externalResources
-}
diff --git a/Passepartout/Sources/GroupConstants.swift b/Passepartout/Sources/GroupConstants.swift
deleted file mode 100644
index 4061ce1a..00000000
--- a/Passepartout/Sources/GroupConstants.swift
+++ /dev/null
@@ -1,87 +0,0 @@
-//
-// GroupConstants.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 6/7/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-
-public class GroupConstants {
- public class App {
- public static let name = "Passepartout"
-
- public static let tunnelKitName = "TunnelKit"
-
- public static let title = name
-// public static let title = "\u{1F511}"
-
- public static let versionNumber = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String
-
- public static let buildNumber = Int(Bundle.main.infoDictionary![kCFBundleVersionKey as String] as! String)!
-
- public static let versionString = "\(versionNumber) (\(buildNumber))"
-
- public static let config: [String: Any] = {
- guard let cfg = Bundle.main.infoDictionary?["com.algoritmico.Passepartout.config"] as? [String: Any] else {
- fatalError("Missing app config from Info.plist")
- }
- return cfg
- }()
-
- public static let groupId: String = {
- guard let identifier = config["group_id"] as? String else {
- fatalError("Missing group_id from Info.plist config")
- }
- return identifier
- }()
-
- private static var containerURL: URL {
- guard let url = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: groupId) else {
- print("Unable to access App Group container")
- return FileManager.default.userURL(for: .documentDirectory, appending: nil)
- }
- return url
- }
-
- public static let documentsURL: URL = {
- let url = containerURL.appendingPathComponent("Documents", isDirectory: true)
- try? FileManager.default.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil)
- return url
- }()
-
- public static let cachesURL: URL = {
- let url = containerURL.appendingPathComponent("Library/Caches", isDirectory: true)
- try? FileManager.default.createDirectory(at: url, withIntermediateDirectories: true, attributes: nil)
- return url
- }()
-
- public static let externalURL = cachesURL.appendingPathComponent("External")
- }
-
- public class VPN {
- public static let dnsTimeout = 5000
-
- public static let sessionMarker = "--- EOF ---"
-
- public static let dataCountInterval = 5000
- }
-}
diff --git a/Passepartout/Sources/Intents/IntentDispatcher.swift b/Passepartout/Sources/Intents/IntentDispatcher.swift
deleted file mode 100644
index f3c8d3c6..00000000
--- a/Passepartout/Sources/Intents/IntentDispatcher.swift
+++ /dev/null
@@ -1,318 +0,0 @@
-//
-// IntentDispatcher.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 3/8/19.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import Intents
-import SwiftyBeaver
-
-private let log = SwiftyBeaver.self
-
-public extension Notification.Name {
- static let IntentDidUpdateService = Notification.Name("IntentDidUpdateService")
-}
-
-@available(iOS 12, *)
-public class IntentDispatcher {
- private class Groups {
- static let vpn = "VPN"
-
- static let trust = "Trust"
- }
-
- // MARK: Intents
-
- public static func intentConnect(profile: ConnectionProfile) -> ConnectVPNIntent {
- let intent = ConnectVPNIntent()
- intent.context = profile.context.rawValue
- intent.profileId = profile.id
- return intent
- }
-
- public static func intentMoveTo(profile: ProviderConnectionProfile, pool: Pool) -> MoveToLocationIntent {
- let intent = MoveToLocationIntent()
- intent.providerId = profile.id
- intent.poolId = pool.id
- intent.poolName = pool.localizedId
- return intent
- }
-
- public static func intentEnable() -> EnableVPNIntent {
- return EnableVPNIntent()
- }
-
- public static func intentDisable() -> DisableVPNIntent {
- return DisableVPNIntent()
- }
-
- public static func intentTrustWiFi() -> TrustCurrentNetworkIntent {
- return TrustCurrentNetworkIntent()
- }
-
- public static func intentUntrustWiFi() -> UntrustCurrentNetworkIntent {
- return UntrustCurrentNetworkIntent()
- }
-
- public static func intentTrustCellular() -> TrustCellularNetworkIntent {
- return TrustCellularNetworkIntent()
- }
-
- public static func intentUntrustCellular() -> UntrustCellularNetworkIntent {
- return UntrustCellularNetworkIntent()
- }
-
- // MARK: Donations
-
- public static func donateConnection(with profile: ConnectionProfile) {
- let genericIntent: INIntent
- if let provider = profile as? ProviderConnectionProfile, let pool = provider.pool {
- genericIntent = intentMoveTo(profile: provider, pool: pool)
- } else {
- genericIntent = intentConnect(profile: profile)
- }
-
- let interaction = INInteraction(intent: genericIntent, response: nil)
- interaction.groupIdentifier = ProfileKey(profile).rawValue
- interaction.donateAndLog()
- }
-
- public static func donateEnableVPN() {
- let interaction = INInteraction(intent: intentEnable(), response: nil)
- interaction.groupIdentifier = Groups.vpn
- interaction.donateAndLog()
- }
-
- public static func donateDisableVPN() {
- let interaction = INInteraction(intent: intentDisable(), response: nil)
- interaction.groupIdentifier = Groups.vpn
- interaction.donateAndLog()
- }
-
- public static func donateTrustCurrentNetwork() {
- let interaction = INInteraction(intent: intentTrustWiFi(), response: nil)
- interaction.groupIdentifier = Groups.trust
- interaction.donateAndLog()
- }
-
- public static func donateUntrustCurrentNetwork() {
- let interaction = INInteraction(intent: intentUntrustWiFi(), response: nil)
- interaction.groupIdentifier = Groups.trust
- interaction.donateAndLog()
- }
-
- public static func donateTrustCellularNetwork() {
- let interaction = INInteraction(intent: intentTrustCellular(), response: nil)
- interaction.groupIdentifier = Groups.trust
- interaction.donateAndLog()
- }
-
- public static func donateUntrustCellularNetwork() {
- let interaction = INInteraction(intent: intentUntrustCellular(), response: nil)
- interaction.groupIdentifier = Groups.trust
- interaction.donateAndLog()
- }
-
- //
-
- public static func handleInteraction(_ interaction: INInteraction, completionHandler: ((Error?) -> Void)?) {
- handleIntent(interaction.intent, interaction: interaction, completionHandler: completionHandler)
- }
-
- public static func handleIntent(_ intent: INIntent, interaction: INInteraction?, completionHandler: ((Error?) -> Void)?) {
- if let custom = intent as? ConnectVPNIntent {
- handleConnectVPN(custom, interaction: interaction, completionHandler: completionHandler)
- } else if let custom = intent as? EnableVPNIntent {
- handleEnableVPN(custom, interaction: interaction, completionHandler: completionHandler)
- } else if let custom = intent as? DisableVPNIntent {
- handleDisableVPN(custom, interaction: interaction, completionHandler: completionHandler)
- } else if let custom = intent as? MoveToLocationIntent {
- handleMoveToLocation(custom, interaction: interaction, completionHandler: completionHandler)
- } else if let _ = intent as? TrustCurrentNetworkIntent {
- handleCurrentNetwork(trust: true, interaction: interaction, completionHandler: completionHandler)
- } else if let _ = intent as? UntrustCurrentNetworkIntent {
- handleCurrentNetwork(trust: false, interaction: interaction, completionHandler: completionHandler)
- } else if let _ = intent as? TrustCellularNetworkIntent {
- handleCellularNetwork(trust: true, interaction: interaction, completionHandler: completionHandler)
- } else if let _ = intent as? UntrustCellularNetworkIntent {
- handleCellularNetwork(trust: false, interaction: interaction, completionHandler: completionHandler)
- }
- }
-
- public static func handleConnectVPN(_ intent: ConnectVPNIntent, interaction: INInteraction?, completionHandler: ((Error?) -> Void)?) {
- guard let contextValue = intent.context, let context = Context(rawValue: contextValue), let id = intent.profileId else {
- if let interactionIdentifier = interaction?.identifier {
- INInteraction.delete(with: [interactionIdentifier], completion: nil)
- }
- // FIXME: error = missing data, programming error
- completionHandler?(nil)
- return
- }
- let profileKey = ProfileKey(context, id)
- log.info("Connect to profile: \(profileKey)")
-
- let service = TransientStore.shared.service
- let vpn = VPN.shared
- guard !(service.isActiveProfile(profileKey) && (vpn.status == .connected)) else {
- log.info("Profile is already active and connected")
- completionHandler?(nil)
- return
- }
-
- guard let profile = service.profile(withContext: context, id: id) else {
- // FIXME: error = no profile
- completionHandler?(nil)
- return
- }
- service.activateProfile(profile)
- refreshVPN(service: service, doReconnect: true, completionHandler: completionHandler)
- }
-
- public static func handleMoveToLocation(_ intent: MoveToLocationIntent, interaction: INInteraction?, completionHandler: ((Error?) -> Void)?) {
- guard let providerId = intent.providerId, let poolId = intent.poolId else {
- // FIXME: error = no provider/pool
- completionHandler?(nil)
- return
- }
- let service = TransientStore.shared.service
- guard let providerProfile = service.profile(withContext: .provider, id: providerId) as? ProviderConnectionProfile else {
- // FIXME: error = no provider
- completionHandler?(nil)
- return
- }
- log.info("Connect to provider location: \(providerId) @ [\(poolId)]")
-
- let vpn = VPN.shared
- guard !(service.isActiveProfile(providerProfile) && (providerProfile.poolId == poolId) && (vpn.status == .connected)) else {
- log.info("Profile is already active and connected to \(poolId)")
- completionHandler?(nil)
- return
- }
-
- providerProfile.poolId = poolId
- service.activateProfile(providerProfile)
- refreshVPN(service: service, doReconnect: true, completionHandler: completionHandler)
- }
-
- public static func handleEnableVPN(_ intent: EnableVPNIntent, interaction: INInteraction?, completionHandler: ((Error?) -> Void)?) {
- let service = TransientStore.shared.service
- log.info("Enabling VPN...")
- refreshVPN(service: service, doReconnect: true, completionHandler: completionHandler)
- }
-
- public static func handleDisableVPN(_ intent: DisableVPNIntent, interaction: INInteraction?, completionHandler: ((Error?) -> Void)?) {
- log.info("Disabling VPN...")
-
- let vpn = VPN.shared
- vpn.prepare {
- vpn.disconnect { (error) in
- notifyServiceUpdate()
- completionHandler?(error)
- }
- }
- }
-
- public static func handleCurrentNetwork(trust: Bool, interaction: INInteraction?, completionHandler: ((Error?) -> Void)?) {
- guard let currentWifi = Utils.currentWifiNetworkName() else {
- // FIXME: error = not connected to wifi
- completionHandler?(nil)
- return
- }
- let service = TransientStore.shared.service
- service.preferences.trustedWifis[currentWifi] = trust
- TransientStore.shared.serialize(withProfiles: false)
-
- log.info("\(trust ? "Trusted" : "Untrusted") Wi-Fi: \(currentWifi)")
- refreshVPN(service: service, doReconnect: false, completionHandler: completionHandler)
- }
-
- public static func handleCellularNetwork(trust: Bool, interaction: INInteraction?, completionHandler: ((Error?) -> Void)?) {
- guard Utils.hasCellularData() else {
- // FIXME: error = has no mobile data
- completionHandler?(nil)
- return
- }
- let service = TransientStore.shared.service
- service.preferences.trustsMobileNetwork = trust
- TransientStore.shared.serialize(withProfiles: false)
-
- log.info("\(trust ? "Trusted" : "Untrusted") cellular network")
- refreshVPN(service: service, doReconnect: false, completionHandler: completionHandler)
- }
-
- private static func refreshVPN(service: ConnectionService, doReconnect: Bool, completionHandler: ((Error?) -> Void)?) {
- let configuration: VPNConfiguration
- do {
- configuration = try service.vpnConfiguration()
- } catch let e {
- log.error("Unable to build VPN configuration: \(e)")
- notifyServiceUpdate()
- completionHandler?(e)
- return
- }
-
- let vpn = VPN.shared
- if doReconnect {
- log.info("Reconnecting VPN: \(configuration)")
- vpn.reconnect(configuration: configuration) { (error) in
- notifyServiceUpdate()
- completionHandler?(error)
- }
- } else {
- log.info("Reinstalling VPN: \(configuration)")
- vpn.install(configuration: configuration) { (error) in
- notifyServiceUpdate()
- completionHandler?(error)
- }
- }
- }
-
- //
-
- public static func forgetProfile(withKey profileKey: ProfileKey) {
- INInteraction.delete(with: profileKey.rawValue) { (error) in
- if let error = error {
- log.error("Unable to forget interactions: \(error)")
- return
- }
- log.debug("Removed profile \(profileKey) interactions")
- }
- }
-
- //
-
- private static func notifyServiceUpdate() {
- NotificationCenter.default.post(name: .IntentDidUpdateService, object: nil)
- }
-}
-
-private extension INInteraction {
- func donateAndLog() {
- donate { (error) in
- if let error = error {
- log.error("Unable to donate interaction: \(error)")
- }
- log.debug("Donated \(self.intent)")
- }
- }
-}
diff --git a/Passepartout/Sources/Model/ConnectionProfile.swift b/Passepartout/Sources/Model/ConnectionProfile.swift
deleted file mode 100644
index 04d7364c..00000000
--- a/Passepartout/Sources/Model/ConnectionProfile.swift
+++ /dev/null
@@ -1,92 +0,0 @@
-//
-// ConnectionProfile.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 9/2/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import TunnelKit
-import NetworkExtension
-
-public enum Context: String, Codable {
- case provider
-
- case host
-}
-
-public protocol ConnectionProfile: class, EndpointDataSource, CustomStringConvertible {
- var context: Context { get }
-
- var id: String { get }
-
- var username: String? { get set }
-
- var requiresCredentials: Bool { get }
-
- var networkChoices: ProfileNetworkChoices? { get set }
-
- var manualNetworkSettings: ProfileNetworkSettings? { get set }
-
- func generate(from configuration: OpenVPNTunnelProvider.Configuration, preferences: Preferences) throws -> OpenVPNTunnelProvider.Configuration
-
- func with(newId: String) -> ConnectionProfile
-}
-
-public extension ConnectionProfile {
- var passwordKey: String? {
- guard let username = username else {
- return nil
- }
- return "\(Bundle.main.bundleIdentifier!).\(context.rawValue).\(id).\(username)"
- }
-
- func password(in keychain: Keychain) -> String? {
- guard let key = passwordKey else {
- return nil
- }
- return try? keychain.password(for: key)
- }
-
- func setPassword(_ password: String?, in keychain: Keychain) throws {
- guard let key = passwordKey else {
- return
- }
- guard let password = password else {
- keychain.removePassword(for: key)
- return
- }
- try keychain.set(password: password, for: key, label: key)
- }
-
- func removePassword(in keychain: Keychain) {
- guard let key = passwordKey else {
- return
- }
- keychain.removePassword(for: key)
- }
-}
-
-public extension ConnectionProfile {
- var description: String {
- return "(\(context):\(id))"
- }
-}
diff --git a/Passepartout/Sources/Model/ConnectionService+Configurations.swift b/Passepartout/Sources/Model/ConnectionService+Configurations.swift
deleted file mode 100644
index e3404e43..00000000
--- a/Passepartout/Sources/Model/ConnectionService+Configurations.swift
+++ /dev/null
@@ -1,69 +0,0 @@
-//
-// ConnectionService+Configurations.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 10/22/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import SwiftyBeaver
-
-private let log = SwiftyBeaver.self
-
-public extension ConnectionService {
- func save(configurationURL: URL, for key: ProfileKey) throws -> URL {
- let destinationURL = targetConfigurationURL(for: key)
- let fm = FileManager.default
- try? fm.removeItem(at: destinationURL)
- try fm.copyItem(at: configurationURL, to: destinationURL)
- return destinationURL
- }
-
- func save(configurationURL: URL, for profile: ConnectionProfile) throws -> URL {
- return try save(configurationURL: configurationURL, for: ProfileKey(profile))
- }
-
- func configurationURL(for key: ProfileKey) -> URL? {
- let url = targetConfigurationURL(for: key)
- guard FileManager.default.fileExists(atPath: url.path) else {
- return nil
- }
- return url
- }
-
- func configurationURL(for profile: ConnectionProfile) -> URL? {
- return configurationURL(for: ProfileKey(profile))
- }
-
- func targetConfigurationURL(for key: ProfileKey) -> URL {
- return contextURL(key).appendingPathComponent(key.id).appendingPathExtension("ovpn")
- }
-
- func pendingConfigurationURLs() -> [URL] {
- do {
- let list = try FileManager.default.contentsOfDirectory(at: rootURL, includingPropertiesForKeys: nil, options: [])
- return list.filter { $0.pathExtension == "ovpn" }
- } catch let e {
- log.error("Could not list imported configurations: \(e)")
- return []
- }
- }
-}
diff --git a/Passepartout/Sources/Model/ConnectionService+Migration.swift b/Passepartout/Sources/Model/ConnectionService+Migration.swift
deleted file mode 100644
index 86225b78..00000000
--- a/Passepartout/Sources/Model/ConnectionService+Migration.swift
+++ /dev/null
@@ -1,53 +0,0 @@
-//
-// ConnectionService+Migration.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 10/25/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import SwiftyBeaver
-
-private let log = SwiftyBeaver.self
-
-public extension ConnectionService {
- static func migrateJSON(from: URL, to: URL) {
- do {
- let newData = try migrateJSON(at: from)
-// log.verbose(String(data: newData, encoding: .utf8)!)
- try newData.write(to: to)
- } catch let e {
- log.error("Could not migrate service: \(e)")
- }
- }
-
- static func migrateJSON(at url: URL) throws -> Data {
- let data = try Data(contentsOf: url)
- guard var json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
- throw ApplicationError.migration
- }
-
- // put migration logic here
- let _ = json["build"] as? Int ?? 0
-
- return try JSONSerialization.data(withJSONObject: json, options: [])
- }
-}
diff --git a/Passepartout/Sources/Model/ConnectionService.swift b/Passepartout/Sources/Model/ConnectionService.swift
deleted file mode 100644
index c1c52761..00000000
--- a/Passepartout/Sources/Model/ConnectionService.swift
+++ /dev/null
@@ -1,616 +0,0 @@
-//
-// ConnectionService.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 9/3/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import TunnelKit
-import NetworkExtension
-import SwiftyBeaver
-
-private let log = SwiftyBeaver.self
-
-public protocol ConnectionServiceDelegate: class {
- func connectionService(didAdd profile: ConnectionProfile)
-
- func connectionService(didRename oldProfile: ConnectionProfile, to newProfile: ConnectionProfile)
-
- func connectionService(didRemoveProfileWithKey key: ProfileKey)
-
- func connectionService(willDeactivate profile: ConnectionProfile)
-
- func connectionService(didActivate profile: ConnectionProfile)
-}
-
-public extension Notification.Name {
- static let ConnectionServiceDidUpdateDataCount = Notification.Name("ConnectionServiceDidUpdateDataCount")
-}
-
-public class ConnectionService: Codable {
- public enum CodingKeys: String, CodingKey {
- case build
-
- case appGroup
-
- case baseConfiguration
-
- case activeProfileKey
-
- case preferences
- }
-
- public struct NotificationKeys {
- public static let dataCount = "DataCount"
- }
-
- public var directory: String? = nil
-
- public var rootURL: URL {
- var url = GroupConstants.App.documentsURL
- if let directory = directory {
- url.appendPathComponent(directory)
- }
- return url
- }
-
- private var providersURL: URL {
- return rootURL.appendingPathComponent(AppConstants.Store.providersDirectory)
- }
-
- private var hostsURL: URL {
- return rootURL.appendingPathComponent(AppConstants.Store.hostsDirectory)
- }
-
- private var build: Int
-
- private let appGroup: String
-
- private let defaults: UserDefaults
-
- private let keychain: Keychain
-
- public var baseConfiguration: OpenVPNTunnelProvider.Configuration
-
- private var cache: [ProfileKey: ConnectionProfile]
-
- private var dataCountObserver: Timer?
-
- public private(set) var activeProfileKey: ProfileKey? {
- willSet {
- if let oldProfile = activeProfile {
- delegate?.connectionService(willDeactivate: oldProfile)
- }
- }
- didSet {
- if let newProfile = activeProfile {
- delegate?.connectionService(didActivate: newProfile)
- }
- }
- }
-
- public var activeProfile: ConnectionProfile? {
- guard let id = activeProfileKey else {
- return nil
- }
- var hit = cache[id]
- if let placeholder = hit as? PlaceholderConnectionProfile {
- hit = profile(withContext: placeholder.context, id: placeholder.id)
- cache[id] = hit
- }
- return hit
- }
-
- public let preferences: EditablePreferences
-
- public weak var delegate: ConnectionServiceDelegate?
-
- public init(withAppGroup appGroup: String, baseConfiguration: OpenVPNTunnelProvider.Configuration) {
- guard let defaults = UserDefaults(suiteName: appGroup) else {
- fatalError("No entitlements for group '\(appGroup)'")
- }
- build = GroupConstants.App.buildNumber
- self.appGroup = appGroup
- self.defaults = defaults
- keychain = Keychain(group: appGroup)
-
- self.baseConfiguration = baseConfiguration
- activeProfileKey = nil
- preferences = EditablePreferences()
-
- cache = [:]
- }
-
- deinit {
- dataCountObserver?.invalidate()
- }
-
- // MARK: Codable
-
- public required init(from decoder: Decoder) throws {
- let container = try decoder.container(keyedBy: CodingKeys.self)
- let appGroup = try container.decode(String.self, forKey: .appGroup)
- guard let defaults = UserDefaults(suiteName: appGroup) else {
- fatalError("No entitlements for group '\(appGroup)'")
- }
- build = try container.decode(Int.self, forKey: .build)
- self.appGroup = appGroup
- self.defaults = defaults
- keychain = Keychain(group: appGroup)
-
- baseConfiguration = try container.decode(OpenVPNTunnelProvider.Configuration.self, forKey: .baseConfiguration)
- activeProfileKey = try container.decodeIfPresent(ProfileKey.self, forKey: .activeProfileKey)
- preferences = try container.decode(EditablePreferences.self, forKey: .preferences)
-
- cache = [:]
- }
-
- public func encode(to encoder: Encoder) throws {
- build = GroupConstants.App.buildNumber
-
- var container = encoder.container(keyedBy: CodingKeys.self)
- try container.encode(build, forKey: .build)
- try container.encode(appGroup, forKey: .appGroup)
- try container.encode(baseConfiguration, forKey: .baseConfiguration)
- try container.encodeIfPresent(activeProfileKey, forKey: .activeProfileKey)
- try container.encode(preferences, forKey: .preferences)
- }
-
- // MARK: Serialization
-
- public func loadProfiles() {
- let fm = FileManager.default
- try? fm.createDirectory(at: providersURL, withIntermediateDirectories: false, attributes: nil)
- try? fm.createDirectory(at: hostsURL, withIntermediateDirectories: false, attributes: nil)
-
- do {
- let files = try fm.contentsOfDirectory(at: providersURL, includingPropertiesForKeys: nil, options: [])
-// log.debug("Found \(files.count) provider files: \(files)")
- for entry in files {
- guard let id = ConnectionService.profileId(fromURL: entry) else {
- continue
- }
- let key = ProfileKey(.provider, id)
- cache[key] = PlaceholderConnectionProfile(key)
- }
- } catch let e {
- log.warning("Could not list provider contents: \(e) (\(providersURL))")
- }
- do {
- let files = try fm.contentsOfDirectory(at: hostsURL, includingPropertiesForKeys: nil, options: [])
-// log.debug("Found \(files.count) host files: \(files)")
- for entry in files {
- guard let id = ConnectionService.profileId(fromURL: entry) else {
- continue
- }
- let key = ProfileKey(.host, id)
- cache[key] = PlaceholderConnectionProfile(key)
- }
- } catch let e {
- log.warning("Could not list host contents: \(e) (\(hostsURL))")
- }
- }
-
- public func saveProfiles() {
- let encoder = JSONEncoder()
- ensureDirectoriesExistence()
-
- for profile in cache.values {
- saveProfile(profile, withEncoder: encoder, checkDirectories: false)
- }
- }
-
- private func ensureDirectoriesExistence() {
- let fm = FileManager.default
- try? fm.createDirectory(at: providersURL, withIntermediateDirectories: false, attributes: nil)
- try? fm.createDirectory(at: hostsURL, withIntermediateDirectories: false, attributes: nil)
- }
-
- private func saveProfile(_ profile: ConnectionProfile, withEncoder encoder: JSONEncoder, checkDirectories: Bool) {
- if checkDirectories {
- ensureDirectoriesExistence()
- }
- do {
- let url = profileURL(ProfileKey(profile))
- var optData: Data?
- if let providerProfile = profile as? ProviderConnectionProfile {
- optData = try encoder.encode(providerProfile)
- } else if let hostProfile = profile as? HostConnectionProfile {
- optData = try encoder.encode(hostProfile)
- } else if let placeholder = profile as? PlaceholderConnectionProfile {
- log.debug("Skipped placeholder \(placeholder)")
- } else {
- fatalError("Attempting to add an unhandled profile type: \(type(of: profile))")
- }
- guard let data = optData else {
- return
- }
- try data.write(to: url)
- log.debug("Serialized profile \(profile)")
- } catch let e {
- log.warning("Could not serialize profile \(profile): \(e)")
- }
- }
-
- public func profile(withContext context: Context, id: String) -> ConnectionProfile? {
- return profile(withKey: ProfileKey(context, id))
- }
-
- public func profile(withKey key: ProfileKey) -> ConnectionProfile? {
- var profile = cache[key]
- if let _ = profile as? PlaceholderConnectionProfile {
- let decoder = JSONDecoder()
- do {
- let data = try profileData(key)
- switch key.context {
- case .provider:
- let providerProfile = try decoder.decode(ProviderConnectionProfile.self, from: data)
-
- // XXX: fix renamed presets, fall back to default
- if providerProfile.preset == nil {
- providerProfile.presetId = providerProfile.infrastructure.defaults.preset
- }
-
- // XXX: fix renamed pool, fall back to default
- if providerProfile.pool == nil, let fallbackPool = providerProfile.infrastructure.defaultPool() {
- providerProfile.poolId = fallbackPool.id
- }
-
- // XXX: fix unsupported preset
- providerProfile.setSupportedPreset()
-
- profile = providerProfile
-
- case .host:
-// let hostProfile = try decoder.decode(HostConnectionProfile.self, from: data)
-//
-// profile = hostProfile
- break
- }
- cache[key] = profile
- } catch let e {
- log.error("Could not decode profile JSON: \(e)")
- return nil
- }
- }
-
- return profile
- }
-
- public func ids(forContext context: Context) -> [String] {
- return cache.keys.filter { $0.context == context }.map { $0.id }
- }
-
- public func contextURL(_ key: ProfileKey) -> URL {
- switch key.context {
- case .provider:
- return providersURL
-
- case .host:
- return hostsURL
- }
- }
-
- public func profileURL(_ key: ProfileKey) -> URL {
- return contextURL(key).appendingPathComponent(key.id).appendingPathExtension("json")
- }
-
- public func profileData(_ key: ProfileKey) throws -> Data {
- return try Data(contentsOf: profileURL(key))
- }
-
- private static func profileId(fromURL url: URL) -> String? {
- guard url.pathExtension == "json" else {
- return nil
- }
- return url.deletingPathExtension().lastPathComponent
- }
-
- func reloadHostProfilesFromConfigurationFiles() -> Bool {
- var anyReloaded = false
- for entry in cache {
- guard entry.value.context == .host else {
- continue
- }
- guard let host = profile(withKey: entry.key) as? HostConnectionProfile else {
- log.warning("Host context but not a HostConnectionProfile?")
- continue
- }
- guard let url = configurationURL(for: entry.key) else {
- continue
- }
-
- // can fail due to passphrase (migration is non-interactive)
- if let result = try? OpenVPN.ConfigurationParser.parsed(fromURL: url) {
- host.parameters = OpenVPNTunnelProvider.ConfigurationBuilder(sessionConfiguration: result.configuration).build()
- } else {
-
- // fall back to the safer option
- var builder = host.parameters.builder()
- var sessionBuilder = builder.sessionConfiguration.builder()
- sessionBuilder.routingPolicies = [.IPv4]
- builder.sessionConfiguration = sessionBuilder.build()
- host.parameters = builder.build()
- }
- cache[entry.key] = host
-
- anyReloaded = true
- }
- return anyReloaded
- }
-
- // MARK: Profiles
-
- public func hasProfiles() -> Bool {
- return !cache.isEmpty
- }
-
- public func addProfile(_ profile: ConnectionProfile, credentials: Credentials?) -> Bool {
- guard cache.index(forKey: ProfileKey(profile)) == nil else {
- return false
- }
- addOrReplaceProfile(profile, credentials: credentials)
- return true
- }
-
- public func addOrReplaceProfile(_ profile: ConnectionProfile, credentials: Credentials?) {
- let key = ProfileKey(profile)
- cache[key] = profile
- try? setCredentials(credentials, for: profile)
- if cache.count == 1 {
- activeProfileKey = key
- }
- delegate?.connectionService(didAdd: profile)
-
- // serialization (can fail)
- saveProfile(profile, withEncoder: JSONEncoder(), checkDirectories: true)
- }
-
- @discardableResult
- public func renameProfile(_ key: ProfileKey, to newId: String) -> ConnectionProfile? {
- precondition(newId != key.id)
-
- // WARNING: can be a placeholder
- guard let oldProfile = cache[key] else {
- return nil
- }
-
- let fm = FileManager.default
- let temporaryDelegate = delegate
- delegate = nil
-
- // 1. add renamed profile
- let newProfile = oldProfile.with(newId: newId)
- let newKey = ProfileKey(newProfile)
- let sameCredentials = credentials(for: oldProfile)
- addOrReplaceProfile(newProfile, credentials: sameCredentials)
-
- // 2. rename .ovpn (if present)
- if let cfgFrom = configurationURL(for: key) {
- let cfgTo = targetConfigurationURL(for: newKey)
- try? fm.removeItem(at: cfgTo)
- try? fm.moveItem(at: cfgFrom, to: cfgTo)
- }
-
- // 3. remove old entry
- removeProfile(key)
-
- // 4. replace active key (if active)
- if key == activeProfileKey {
- activeProfileKey = newKey
- }
-
- delegate = temporaryDelegate
- delegate?.connectionService(didRename: oldProfile, to: newProfile)
-
- return newProfile
- }
-
- @discardableResult
- public func renameProfile(_ profile: ConnectionProfile, to id: String) -> ConnectionProfile? {
- return renameProfile(ProfileKey(profile), to: id)
- }
-
- public func removeProfile(_ key: ProfileKey) {
- guard let profile = cache[key] else {
- return
- }
-
- cache.removeValue(forKey: key)
- removeCredentials(for: profile)
- if cache.isEmpty {
- activeProfileKey = nil
- }
-
- delegate?.connectionService(didRemoveProfileWithKey: key)
-
- // serialization (can fail)
- do {
- let fm = FileManager.default
- if let cfg = configurationURL(for: key) {
- try? fm.removeItem(at: cfg)
- }
- let url = profileURL(key)
- try fm.removeItem(at: url)
- log.debug("Deleted removed profile '\(profile.id)'")
- } catch let e {
- log.warning("Could not delete profile '\(profile.id)': \(e)")
- }
- }
-
- public func containsProfile(_ key: ProfileKey) -> Bool {
- return cache.index(forKey: key) != nil
- }
-
- public func containsProfile(_ profile: ConnectionProfile) -> Bool {
- return containsProfile(ProfileKey(profile))
- }
-
- public func hasActiveProfile() -> Bool {
- return activeProfileKey != nil
- }
-
- public func isActiveProfile(_ key: ProfileKey) -> Bool {
- return key == activeProfileKey
- }
-
- public func isActiveProfile(_ profile: ConnectionProfile) -> Bool {
- return isActiveProfile(ProfileKey(profile))
- }
-
- public func activateProfile(_ profile: ConnectionProfile) {
- activeProfileKey = ProfileKey(profile)
- }
-
- // MARK: Credentials
-
- public func needsCredentials(for profile: ConnectionProfile) -> Bool {
- guard profile.requiresCredentials else {
- return false
- }
- guard let creds = credentials(for: profile) else {
- return true
- }
- return creds.isEmpty
- }
-
- public func credentials(for profile: ConnectionProfile) -> Credentials? {
- guard let username = profile.username, let key = profile.passwordKey else {
- return nil
- }
- guard let password = try? keychain.password(for: key) else {
- return nil
- }
- return Credentials(username, password)
- }
-
- public func setCredentials(_ credentials: Credentials?, for profile: ConnectionProfile) throws {
- profile.username = credentials?.username
- try profile.setPassword(credentials?.password, in: keychain)
- }
-
- public func removeCredentials(for profile: ConnectionProfile) {
- profile.removePassword(in: keychain)
- }
-
- // MARK: VPN
-
- public func vpnConfiguration() throws -> NetworkExtensionVPNConfiguration {
- guard let profile = activeProfile else {
- throw ApplicationError.missingProfile
- }
- let creds = credentials(for: profile)
- if profile.requiresCredentials {
- guard creds != nil else {
- throw ApplicationError.missingCredentials
- }
- }
-
- var cfg = try profile.generate(from: baseConfiguration, preferences: preferences)
-
- // override network settings
- if let choices = profile.networkChoices, let settings = profile.manualNetworkSettings {
- var builder = cfg.builder()
- var sessionBuilder = builder.sessionConfiguration.builder()
- sessionBuilder.applyGateway(from: choices, settings: settings)
- sessionBuilder.applyDNS(from: choices, settings: settings)
- sessionBuilder.applyProxy(from: choices, settings: settings)
- builder.sessionConfiguration = sessionBuilder.build()
- cfg = builder.build()
- }
-
- let protocolConfiguration = try cfg.generatedTunnelProtocol(
- withBundleIdentifier: AppConstants.App.tunnelBundleId,
- appGroup: appGroup,
- credentials: creds
- )
- protocolConfiguration.disconnectOnSleep = preferences.disconnectsOnSleep
-
- log.verbose("Configuration:")
- log.verbose(protocolConfiguration)
-
- var rules: [NEOnDemandRule] = []
- #if os(iOS)
- if preferences.trustsMobileNetwork {
- let rule = policyRule()
- rule.interfaceTypeMatch = .cellular
- rules.append(rule)
- }
- #endif
- let reallyTrustedWifis = Array(preferences.trustedWifis.filter { $1 }.keys)
- if !reallyTrustedWifis.isEmpty {
- let rule = policyRule()
- rule.interfaceTypeMatch = .wiFi
- rule.ssidMatch = reallyTrustedWifis
- rules.append(rule)
- }
- let connection = NEOnDemandRuleConnect()
- connection.interfaceTypeMatch = .any
- rules.append(connection)
-
- return NetworkExtensionVPNConfiguration(protocolConfiguration: protocolConfiguration, onDemandRules: rules)
- }
-
- private func policyRule() -> NEOnDemandRule {
- switch preferences.trustPolicy {
- case .ignore:
- return NEOnDemandRuleIgnore()
-
- case .disconnect:
- return NEOnDemandRuleDisconnect()
- }
- }
-
- public var vpnLog: String {
- return baseConfiguration.existingLog(in: appGroup) ?? ""
- }
-
- public func eraseVpnLog() {
- log.info("Erasing VPN log...")
- guard let url = baseConfiguration.urlForLog(in: appGroup) else {
- return
- }
- try? FileManager.default.removeItem(at: url)
- }
-
- public var vpnLastError: OpenVPNTunnelProvider.ProviderError? {
- return baseConfiguration.lastError(in: appGroup)
- }
-
- public func clearVpnLastError() {
- baseConfiguration.clearLastError(in: appGroup)
- }
-
- public func observeVPNDataCount(interval: TimeInterval) {
- dataCountObserver?.invalidate()
- dataCountObserver = Timer.scheduledTimer(withTimeInterval: interval, repeats: true, block: { [weak self] (_) in
- guard let dataCount = self?.vpnDataCount else {
- return
- }
- NotificationCenter.default.post(name: .ConnectionServiceDidUpdateDataCount, object: nil, userInfo: [NotificationKeys.dataCount: dataCount])
- })
- }
-
- public var vpnDataCount: (Int, Int)? {
- return baseConfiguration.dataCount(in: appGroup)
- }
-}
diff --git a/Passepartout/Sources/Model/Credentials.swift b/Passepartout/Sources/Model/Credentials.swift
deleted file mode 100644
index 9735fdf5..00000000
--- a/Passepartout/Sources/Model/Credentials.swift
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// Credentials.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 6/7/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import TunnelKit
-
-public typealias Credentials = OpenVPN.Credentials
-
-public extension Credentials {
- var isEmpty: Bool {
- return username.isEmpty || password.isEmpty
- }
-
- func trimmed() -> Credentials {
- let trimmedUsername = username.trimmingCharacters(in: .whitespacesAndNewlines)
- let trimmedPassword = password.trimmingCharacters(in: .whitespacesAndNewlines)
- return Credentials(trimmedUsername, trimmedPassword)
- }
-}
diff --git a/Passepartout/Sources/Model/DataUnit.swift b/Passepartout/Sources/Model/DataUnit.swift
deleted file mode 100644
index e93e2215..00000000
--- a/Passepartout/Sources/Model/DataUnit.swift
+++ /dev/null
@@ -1,93 +0,0 @@
-//
-// DataUnit.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 3/30/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-
-public enum DataUnit: Int, CustomStringConvertible {
- case byte = 1
-
- case kilobyte = 1024
-
- case megabyte = 1048576
-
- case gigabyte = 1073741824
-
- fileprivate var showsDecimals: Bool {
- switch self {
- case .byte, .kilobyte:
- return false
-
- case .megabyte, .gigabyte:
- return true
- }
- }
-
- fileprivate var boundary: Int {
- return Int(0.1 * Double(rawValue))
- }
-
- // MARK: CustomStringConvertible
-
- public var description: String {
- switch self {
- case .byte:
- return "B"
-
- case .kilobyte:
- return "kB"
-
- case .megabyte:
- return "MB"
-
- case .gigabyte:
- return "GB"
- }
- }
-}
-
-public extension Int {
- private static let allUnits: [DataUnit] = [
- .gigabyte,
- .megabyte,
- .kilobyte,
- .byte
- ]
-
- var dataUnitDescription: String {
- if self == 0 {
- return "0B"
- }
- for u in Int.allUnits {
- if self >= u.boundary {
- if !u.showsDecimals {
- return "\(self / u.rawValue)\(u)"
- }
- let count = Double(self) / Double(u.rawValue)
- return String(format: "%.2f%@", count, u.description)
- }
- }
- fatalError("Number is negative")
- }
-}
diff --git a/Passepartout/Sources/Model/DebugLog.swift b/Passepartout/Sources/Model/DebugLog.swift
deleted file mode 100644
index 3a873531..00000000
--- a/Passepartout/Sources/Model/DebugLog.swift
+++ /dev/null
@@ -1,84 +0,0 @@
-//
-// DebugLog.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 6/26/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-#if os(iOS)
-import UIKit
-#else
-import Cocoa
-#endif
-
-public struct DebugLog {
- private let raw: String
-
- public init(raw: String) {
- self.raw = raw
- }
-
- public func string() -> String {
- return raw
- }
-
- public func data() -> Data? {
- return raw.data(using: .utf8)
- }
-
- public func decoratedString() -> String {
- let appName = GroupConstants.App.name
- let appVersion = GroupConstants.App.versionString
-
- var metadata: [String] = []
- let osVersion: String
- let deviceType: String?
-
- #if os(iOS)
- let device = UIDevice.current
- osVersion = "\(device.systemName) \(device.systemVersion)"
- deviceType = device.model
- #else
- let os = ProcessInfo().operatingSystemVersion
- osVersion = "macOS \(os.majorVersion).\(os.minorVersion).\(os.patchVersion)"
- deviceType = nil
- #endif
-
- metadata.append("App: \(appName) \(appVersion)")
- metadata.append("OS: \(osVersion)")
- if let deviceType = deviceType {
- metadata.append("Device: \(deviceType)")
- }
-
- var fullText = metadata.joined(separator: "\n")
- fullText += "\n\n"
- fullText += raw
- return fullText
- }
-
- public func decoratedData() -> Data {
- guard let data = decoratedString().data(using: .utf8) else {
- fatalError("Could not encode log metadata to UTF8?")
- }
- return data
- }
-}
diff --git a/Passepartout/Sources/Model/EndpointDataSource.swift b/Passepartout/Sources/Model/EndpointDataSource.swift
deleted file mode 100644
index eef438f3..00000000
--- a/Passepartout/Sources/Model/EndpointDataSource.swift
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// EndpointDataSource.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 9/5/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import TunnelKit
-
-public protocol EndpointDataSource {
- var mainAddress: String? { get }
-
- var addresses: [String] { get }
-
- var protocols: [EndpointProtocol] { get }
-
- var canCustomizeEndpoint: Bool { get }
-
- var customAddress: String? { get }
-
- var customProtocol: EndpointProtocol? { get }
-}
diff --git a/Passepartout/Sources/Model/Preferences.swift b/Passepartout/Sources/Model/Preferences.swift
deleted file mode 100644
index 114a6b93..00000000
--- a/Passepartout/Sources/Model/Preferences.swift
+++ /dev/null
@@ -1,54 +0,0 @@
-//
-// Preferences.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 9/4/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-
-public protocol Preferences {
- var resolvesHostname: Bool { get }
-
- var disconnectsOnSleep: Bool { get }
-
- #if os(iOS)
- var trustsMobileNetwork: Bool { get }
- #endif
-
- var trustedWifis: [String: Bool] { get }
-
- var trustPolicy: TrustPolicy { get }
-}
-
-public class EditablePreferences: Preferences, Codable {
- public var resolvesHostname: Bool = true
-
- public var disconnectsOnSleep: Bool = false
-
- #if os(iOS)
- public var trustsMobileNetwork: Bool = false
- #endif
-
- public var trustedWifis: [String: Bool] = [:]
-
- public var trustPolicy: TrustPolicy = .disconnect
-}
diff --git a/Passepartout/Sources/Model/ProfileNetworkSettings.swift b/Passepartout/Sources/Model/ProfileNetworkSettings.swift
deleted file mode 100644
index 2d643bfb..00000000
--- a/Passepartout/Sources/Model/ProfileNetworkSettings.swift
+++ /dev/null
@@ -1,168 +0,0 @@
-//
-// ProfileNetworkSettings.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 04/28/19.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import TunnelKit
-
-public enum NetworkChoice: String, Codable {
- case client
-
- case server // erase client settings
-
- case manual
-}
-
-public class ProfileNetworkChoices: Codable {
- public var gateway: NetworkChoice
-
- public var dns: NetworkChoice
-
- public var proxy: NetworkChoice
-
- public init(choice: NetworkChoice) {
- gateway = choice
- dns = choice
- proxy = choice
- }
-}
-
-public class ProfileNetworkSettings: Codable, CustomStringConvertible {
- public var gatewayPolicies: [OpenVPN.RoutingPolicy]?
-
- public var dnsServers: [String]?
-
- public var dnsDomainName: String?
-
- public var proxyAddress: String?
-
- public var proxyPort: UInt16?
-
- public var proxyServer: Proxy? {
- guard let address = proxyAddress, let port = proxyPort, !address.isEmpty, port > 0 else {
- return nil
- }
- return Proxy(address, port)
- }
-
- public var proxyBypassDomains: [String]?
-
- public init() {
- gatewayPolicies = [.IPv4, .IPv6]
- }
-
- public init(from configuration: OpenVPN.Configuration) {
- gatewayPolicies = configuration.routingPolicies
- dnsDomainName = configuration.searchDomain
- dnsServers = configuration.dnsServers
- proxyAddress = configuration.httpProxy?.address
- proxyPort = configuration.httpProxy?.port
- proxyBypassDomains = configuration.proxyBypassDomains
- }
-
- public func copy(from settings: ProfileNetworkSettings) {
- copyGateway(from: settings)
- copyDNS(from: settings)
- copyProxy(from: settings)
- }
-
- public func copyGateway(from settings: ProfileNetworkSettings) {
- gatewayPolicies = settings.gatewayPolicies
- }
-
- public func copyDNS(from settings: ProfileNetworkSettings) {
- dnsDomainName = settings.dnsDomainName
- dnsServers = settings.dnsServers?.filter { !$0.isEmpty }
- }
-
- public func copyProxy(from settings: ProfileNetworkSettings) {
- proxyAddress = settings.proxyAddress
- proxyPort = settings.proxyPort
- proxyBypassDomains = settings.proxyBypassDomains?.filter { !$0.isEmpty }
- }
-
- // MARK: CustomStringConvertible
-
- public var description: String {
- let comps: [String] = [
- "gw: \(gatewayPolicies?.description ?? "")",
- "dns: {domain: \(dnsDomainName ?? ""), servers: \(dnsServers?.description ?? "[]")}",
- "proxy: {address: \(proxyAddress ?? ""), port: \(proxyPort?.description ?? ""), bypass: \(proxyBypassDomains?.description ?? "[]")}"
- ]
- return "{\(comps.joined(separator: ", "))}"
- }
-}
-
-extension OpenVPN.ConfigurationBuilder {
- public mutating func applyGateway(from choices: ProfileNetworkChoices, settings: ProfileNetworkSettings) {
- switch choices.gateway {
- case .client:
- break
-
- case .server:
- routingPolicies = nil
-
- case .manual:
- routingPolicies = settings.gatewayPolicies
- }
- }
-
- public mutating func applyDNS(from choices: ProfileNetworkChoices, settings: ProfileNetworkSettings) {
- switch choices.dns {
- case .client:
- break
-
- case .server:
- dnsServers = nil
- searchDomain = nil
-
- case .manual:
- dnsServers = settings.dnsServers?.filter { !$0.isEmpty }
- searchDomain = settings.dnsDomainName
- }
- }
-
- public mutating func applyProxy(from choices: ProfileNetworkChoices, settings: ProfileNetworkSettings) {
- switch choices.proxy {
- case .client:
- break
-
- case .server:
- httpProxy = nil
- httpsProxy = nil
- proxyBypassDomains = nil
-
- case .manual:
- if let proxyServer = settings.proxyServer {
- httpProxy = proxyServer
- httpsProxy = proxyServer
- proxyBypassDomains = settings.proxyBypassDomains?.filter { !$0.isEmpty }
- } else {
- httpProxy = nil
- httpsProxy = nil
- proxyBypassDomains = nil
- }
- }
- }
-}
diff --git a/Passepartout/Sources/Model/Profiles/HostConnectionProfile.swift b/Passepartout/Sources/Model/Profiles/HostConnectionProfile.swift
deleted file mode 100644
index 1b3bebcf..00000000
--- a/Passepartout/Sources/Model/Profiles/HostConnectionProfile.swift
+++ /dev/null
@@ -1,120 +0,0 @@
-//
-// HostConnectionProfile.m
-// Passepartout
-//
-// Created by Davide De Rosa on 9/2/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import TunnelKit
-
-public class HostConnectionProfile: ConnectionProfile, Codable, Equatable {
- public var title: String
-
- public let hostname: String
-
- public var parameters: OpenVPNTunnelProvider.Configuration
-
- public init(title: String, hostname: String) {
- self.title = title
- self.hostname = hostname
- let sessionConfiguration = OpenVPN.ConfigurationBuilder().build()
- parameters = OpenVPNTunnelProvider.ConfigurationBuilder(sessionConfiguration: sessionConfiguration).build()
- }
-
- // MARK: ConnectionProfile
-
- public let context: Context = .host
-
- public var id: String {
- return title
- }
-
- public var username: String?
-
- public var requiresCredentials: Bool {
- return false
- }
-
- public var networkChoices: ProfileNetworkChoices?
-
- public var manualNetworkSettings: ProfileNetworkSettings?
-
- public func generate(from configuration: OpenVPNTunnelProvider.Configuration, preferences: Preferences) throws -> OpenVPNTunnelProvider.Configuration {
- guard let endpointProtocols = parameters.sessionConfiguration.endpointProtocols, !endpointProtocols.isEmpty else {
- preconditionFailure("No endpointProtocols")
- }
-
- // XXX: copy paste, error prone
- var builder = parameters.builder()
- builder.mtu = configuration.mtu
- builder.shouldDebug = configuration.shouldDebug
- builder.debugLogFormat = configuration.debugLogFormat
- builder.masksPrivateData = configuration.masksPrivateData
-
- // forcibly override hostname with profile hostname (never nil)
- var sessionBuilder = builder.sessionConfiguration.builder()
- sessionBuilder.hostname = hostname
- sessionBuilder.tlsSecurityLevel = 0 // lowest, tolerate widest range of certificates
- builder.sessionConfiguration = sessionBuilder.build()
-
- return builder.build()
- }
-
- public func with(newId: String) -> ConnectionProfile {
- let profile = HostConnectionProfile(title: newId, hostname: hostname)
- profile.username = username
- profile.parameters = parameters
- return profile
- }
-}
-
-public extension HostConnectionProfile {
- static func ==(lhs: HostConnectionProfile, rhs: HostConnectionProfile) -> Bool {
- return lhs.id == rhs.id
- }
-}
-
-public extension HostConnectionProfile {
- var mainAddress: String? {
- return hostname
- }
-
- var addresses: [String] {
- return [hostname]
- }
-
- var protocols: [EndpointProtocol] {
- return parameters.sessionConfiguration.endpointProtocols ?? []
- }
-
- var canCustomizeEndpoint: Bool {
- return false
- }
-
- var customAddress: String? {
- return nil
- }
-
- var customProtocol: EndpointProtocol? {
- return nil
- }
-}
diff --git a/Passepartout/Sources/Model/Profiles/PlaceholderConnectionProfile.swift b/Passepartout/Sources/Model/Profiles/PlaceholderConnectionProfile.swift
deleted file mode 100644
index 5bd833bf..00000000
--- a/Passepartout/Sources/Model/Profiles/PlaceholderConnectionProfile.swift
+++ /dev/null
@@ -1,71 +0,0 @@
-//
-// PlaceholderConnectionProfile.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 11/6/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import TunnelKit
-
-public class PlaceholderConnectionProfile: ConnectionProfile {
- public let context: Context
-
- public let id: String
-
- public var username: String? = nil
-
- public var requiresCredentials: Bool = false
-
- public var networkChoices: ProfileNetworkChoices?
-
- public var manualNetworkSettings: ProfileNetworkSettings?
-
- public func generate(from configuration: OpenVPNTunnelProvider.Configuration, preferences: Preferences) throws -> OpenVPNTunnelProvider.Configuration {
- fatalError("Generating configuration from a PlaceholderConnectionProfile")
- }
-
- public func with(newId: String) -> ConnectionProfile {
- return PlaceholderConnectionProfile(context, newId)
- }
-
- public var mainAddress: String? = nil
-
- public var addresses: [String] = []
-
- public var protocols: [EndpointProtocol] = []
-
- public var canCustomizeEndpoint: Bool = false
-
- public var customAddress: String?
-
- public var customProtocol: EndpointProtocol?
-
- public init(_ context: Context, _ id: String) {
- self.context = context
- self.id = id
- }
-
- public init(_ key: ProfileKey) {
- context = key.context
- id = key.id
- }
-}
diff --git a/Passepartout/Sources/Model/Profiles/PoolCategory.swift b/Passepartout/Sources/Model/Profiles/PoolCategory.swift
deleted file mode 100644
index 4f937fa9..00000000
--- a/Passepartout/Sources/Model/Profiles/PoolCategory.swift
+++ /dev/null
@@ -1,34 +0,0 @@
-//
-// PoolCategory.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 4/11/19.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-
-public struct PoolCategory: Codable {
- public let name: String
-
- public let groups: [PoolGroup]
-
- public let presets: [String]?
-}
diff --git a/Passepartout/Sources/Model/Profiles/ProfileKey.swift b/Passepartout/Sources/Model/Profiles/ProfileKey.swift
deleted file mode 100644
index ac3af59e..00000000
--- a/Passepartout/Sources/Model/Profiles/ProfileKey.swift
+++ /dev/null
@@ -1,72 +0,0 @@
-//
-// ProfileKey.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 11/6/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-
-public struct ProfileKey: RawRepresentable, Hashable, Codable, CustomStringConvertible {
- private static let separator: Character = "."
-
- public let context: Context
-
- public let id: String
-
- public init(_ context: Context, _ id: String) {
- self.context = context
- self.id = id
- }
-
- public init(_ profile: ConnectionProfile) {
- context = profile.context
- id = profile.id
- }
-
- // MARK: RawRepresentable
-
- public var rawValue: String {
- return "\(context)\(ProfileKey.separator)\(id)"
- }
-
- public init?(rawValue: String) {
- guard let separatorIndex = rawValue.firstIndex(of: ProfileKey.separator) else {
- return nil
- }
-
- let contextValue = rawValue[rawValue.startIndex...
-//
-
-import Foundation
-import TunnelKit
-
-public class ProviderConnectionProfile: ConnectionProfile, Codable, Equatable {
- public let name: Infrastructure.Name
-
- public var infrastructure: Infrastructure {
- return InfrastructureFactory.shared.get(name)
- }
-
- public var poolId: String {
- didSet {
- validateEndpoint()
- }
- }
-
- public var pool: Pool? {
- return infrastructure.pool(for: poolId)
- }
-
- public var presetId: String {
- didSet {
- validateEndpoint()
- }
- }
-
- public var preset: InfrastructurePreset? {
- return infrastructure.preset(for: presetId)
- }
-
- public var manualAddress: String?
-
- public var manualProtocol: EndpointProtocol?
-
- public var networkChoices: ProfileNetworkChoices?
-
- public var manualNetworkSettings: ProfileNetworkSettings?
-
- public var usesProviderEndpoint: Bool {
- return (manualAddress != nil) || (manualProtocol != nil)
- }
-
- public init(name: Infrastructure.Name) {
- self.name = name
- poolId = ""
- presetId = ""
-
- username = nil
-
- poolId = infrastructure.defaultPool()?.id ?? infrastructure.defaults.pool
- presetId = infrastructure.defaults.preset
- }
-
- public func setSupportedPreset() {
- guard let pool = pool else {
- return
- }
- let supported = pool.supportedPresetIds(in: infrastructure)
- if let current = preset?.id, !supported.contains(current), let fallback = supported.first {
- presetId = fallback
- }
- }
-
- private func validateEndpoint() {
- guard let pool = pool, let preset = preset else {
- manualAddress = nil
- manualProtocol = nil
- return
- }
- if let address = manualAddress, !pool.hasAddress(address) {
- manualAddress = nil
- }
- if let proto = manualProtocol, !preset.hasProtocol(proto) {
- manualProtocol = nil
- }
- }
-
- // MARK: ConnectionProfile
-
- public let context: Context = .provider
-
- public var id: String {
- return name.rawValue
- }
-
- public var username: String?
-
- public var requiresCredentials: Bool {
- return true
- }
-
- public func generate(from configuration: OpenVPNTunnelProvider.Configuration, preferences: Preferences) throws -> OpenVPNTunnelProvider.Configuration {
- guard let pool = pool else {
- preconditionFailure("Nil pool?")
- }
- guard let preset = preset else {
- preconditionFailure("Nil preset?")
- }
-
-// assert(!pool.numericAddresses.isEmpty)
-
- // XXX: copy paste, error prone
- var builder = preset.configuration.builder()
- builder.mtu = configuration.mtu
- builder.shouldDebug = configuration.shouldDebug
- builder.debugLogFormat = configuration.debugLogFormat
- builder.masksPrivateData = configuration.masksPrivateData
-
- do {
- try preset.injectExternalConfiguration(&builder, with: name, pool: pool)
- } catch {
- throw ApplicationError.externalResources
- }
-
- if let address = manualAddress {
- builder.prefersResolvedAddresses = true
- builder.resolvedAddresses = [address]
- } else if builder.sessionConfiguration.hostname == nil {
- builder.prefersResolvedAddresses = true
- builder.resolvedAddresses = pool.addresses()
- } else {
- builder.prefersResolvedAddresses = !preferences.resolvesHostname
- builder.resolvedAddresses = pool.addresses()
- }
-
- var sessionBuilder = builder.sessionConfiguration.builder()
- if let proto = manualProtocol {
- sessionBuilder.endpointProtocols = [proto]
- } else {
-
- // restrict "Any" protocol to UDP, unless there are no UDP endpoints
- let allEndpoints = builder.sessionConfiguration.endpointProtocols
- var endpoints = allEndpoints?.filter { $0.socketType == .udp }
- if endpoints?.isEmpty ?? true {
- endpoints = allEndpoints
- }
-
- sessionBuilder.endpointProtocols = endpoints
-// sessionBuilder.endpointProtocols = [
-// EndpointProtocol(.udp, 8080),
-// EndpointProtocol(.tcp, 443)
-// ]
- }
- builder.sessionConfiguration = sessionBuilder.build()
-
- return builder.build()
- }
-
- public func with(newId: String) -> ConnectionProfile {
- fatalError("Cannot rename a ProviderConnectionProfile")
- }
-}
-
-public extension ProviderConnectionProfile {
- static func ==(lhs: ProviderConnectionProfile, rhs: ProviderConnectionProfile) -> Bool {
- return lhs.id == rhs.id
- }
-}
-
-public extension ProviderConnectionProfile {
- var mainAddress: String? {
- guard let pool = pool else {
- assertionFailure("Getting provider main address but no pool set")
- return nil
- }
- return pool.hostname
- }
-
- var addresses: [String] {
- var addrs = pool?.addresses() ?? []
- if let pool = pool, pool.hostname == nil, !(pool.isResolved ?? false), let externalHostname = try? preset?.externalConfiguration(forKey: .hostname, infrastructureName: infrastructure.name, pool: pool) as? String {
- addrs.insert(externalHostname, at: 0)
- }
- return addrs
- }
-
- var protocols: [EndpointProtocol] {
- return preset?.configuration.sessionConfiguration.endpointProtocols ?? []
- }
-
- var canCustomizeEndpoint: Bool {
- return true
- }
-
- var customAddress: String? {
- return manualAddress
- }
-
- var customProtocol: EndpointProtocol? {
- return manualProtocol
- }
-}
diff --git a/Passepartout/Sources/Model/SessionProxy+Communication.swift b/Passepartout/Sources/Model/SessionProxy+Communication.swift
deleted file mode 100644
index 8e9a3e63..00000000
--- a/Passepartout/Sources/Model/SessionProxy+Communication.swift
+++ /dev/null
@@ -1,42 +0,0 @@
-//
-// SessionProxy+Communication.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 9/4/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import TunnelKit
-
-public extension OpenVPN.ConfigurationBuilder {
-// mutating func copyCommunication(from other: OpenVPN.ConfigurationBuilder) {
-// cipher = other.cipher
-// digest = other.digest
-// compressionFraming = other.compressionFraming
-// }
-
- func canCommunicate(with other: OpenVPN.Configuration) -> Bool {
- return
- (cipher == other.cipher) &&
- ((digest == other.digest) || fallbackCipher.embedsDigest) &&
- (compressionFraming == other.compressionFraming)
- }
-}
diff --git a/Passepartout/Sources/Model/TransientStore.swift b/Passepartout/Sources/Model/TransientStore.swift
deleted file mode 100644
index afda9a0e..00000000
--- a/Passepartout/Sources/Model/TransientStore.swift
+++ /dev/null
@@ -1,171 +0,0 @@
-//
-// TransientStore.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 7/16/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import TunnelKit
-import SwiftyBeaver
-
-private let log = SwiftyBeaver.self
-
-public class TransientStore {
- private struct Keys {
- static let didHandleSubreddit = "DidHandleSubreddit"
-
- static let masksPrivateData = "MasksPrivateData"
-
- // migrations
-
- static let didMigrateHostsRoutingPolicies = "DidMigrateHostsRoutingPolicies"
- }
-
- public static let shared = TransientStore()
-
- private static var serviceURL: URL {
- return GroupConstants.App.documentsURL.appendingPathComponent(AppConstants.Store.serviceFilename)
- }
-
- public let service: ConnectionService
-
- public static var didHandleSubreddit: Bool {
- get {
- return UserDefaults.standard.bool(forKey: Keys.didHandleSubreddit)
- }
- set {
- UserDefaults.standard.set(newValue, forKey: Keys.didHandleSubreddit)
- }
- }
-
- public static var masksPrivateData: Bool {
- get {
- return UserDefaults.standard.bool(forKey: Keys.masksPrivateData)
- }
- set {
- UserDefaults.standard.set(newValue, forKey: Keys.masksPrivateData)
- }
- }
-
- public static var didMigrateHostsRoutingPolicies: Bool {
- get {
- return UserDefaults.standard.bool(forKey: Keys.didMigrateHostsRoutingPolicies)
- }
- set {
- UserDefaults.standard.set(newValue, forKey: Keys.didMigrateHostsRoutingPolicies)
- }
- }
-
- public static var baseVPNConfiguration: OpenVPNTunnelProvider.ConfigurationBuilder {
- let sessionBuilder = OpenVPN.ConfigurationBuilder()
- var builder = OpenVPNTunnelProvider.ConfigurationBuilder(sessionConfiguration: sessionBuilder.build())
- builder.mtu = 1250
- builder.shouldDebug = true
-// builder.debugLogFormat = "$Dyyyy-MM-dd HH:mm:ss.SSS$d $L $N.$F:$l - $M"
-// builder.debugLogFormat = "$DHH:mm:ss$d $N.$F:$l - $M"
- builder.debugLogFormat = AppConstants.Log.debugFormat
- builder.masksPrivateData = masksPrivateData
- return builder
- }
-
- private init() {
- UserDefaults.standard.register(defaults: [
- Keys.didHandleSubreddit: false,
- Keys.masksPrivateData: true
- ])
-
- TransientStore.migrateDocumentsToAppGroup()
-
- // this must be graceful
- ConnectionService.migrateJSON(from: TransientStore.serviceURL, to: TransientStore.serviceURL)
-
- let cfg = TransientStore.baseVPNConfiguration.build()
- do {
- let data = try Data(contentsOf: TransientStore.serviceURL)
- if let content = String(data: data, encoding: .utf8) {
- log.verbose("Service JSON:")
- log.verbose(content)
- }
- service = try JSONDecoder().decode(ConnectionService.self, from: data)
- service.baseConfiguration = cfg
- service.loadProfiles()
-
- // do migrations
- if !TransientStore.didMigrateHostsRoutingPolicies {
- if service.reloadHostProfilesFromConfigurationFiles() {
- service.saveProfiles()
- }
- TransientStore.didMigrateHostsRoutingPolicies = true
- }
- } catch let e {
- log.error("Could not decode service: \(e)")
- service = ConnectionService(
- withAppGroup: GroupConstants.App.groupId,
- baseConfiguration: cfg
- )
-
-// // hardcoded loading
-// _ = service.addProfile(ProviderConnectionProfile(name: .pia), credentials: nil)
-// _ = service.addProfile(HostConnectionProfile(title: "vps"), credentials: Credentials(username: "foo", password: "bar"))
-// service.activateProfile(service.profiles.first!)
- }
- service.observeVPNDataCount(interval: TimeInterval(GroupConstants.VPN.dataCountInterval) / 1000.0)
- }
-
- public func serialize(withProfiles: Bool) {
- try? JSONEncoder().encode(service).write(to: TransientStore.serviceURL)
- if withProfiles {
- service.saveProfiles()
- }
- }
-
- //
-
- private static func migrateDocumentsToAppGroup() {
- var hasMigrated = false
- let oldDocumentsURL = FileManager.default.userURL(for: .documentDirectory, appending: nil)
- let newDocumentsURL = GroupConstants.App.documentsURL
- log.debug("App documentsURL: \(oldDocumentsURL)")
- log.debug("Group documentsURL: \(newDocumentsURL)")
- let fm = FileManager.default
- do {
- for c in try fm.contentsOfDirectory(atPath: oldDocumentsURL.path) {
- guard c != "Inbox" else {
- continue
- }
- let old = oldDocumentsURL.appendingPathComponent(c)
- let new = newDocumentsURL.appendingPathComponent(c)
- log.verbose("Move:")
- log.verbose("\tFROM: \(old)")
- log.verbose("\tTO: \(new)")
- try fm.moveItem(at: old, to: new)
- hasMigrated = true
- }
- } catch let e {
- hasMigrated = false
- log.error("Could not migrate documents to App Group: \(e)")
- }
- if hasMigrated {
- log.debug("Documents migrated to App Group")
- }
- }
-}
diff --git a/Passepartout/Sources/Model/TrustPolicy.swift b/Passepartout/Sources/Model/TrustPolicy.swift
deleted file mode 100644
index cb955486..00000000
--- a/Passepartout/Sources/Model/TrustPolicy.swift
+++ /dev/null
@@ -1,32 +0,0 @@
-//
-// TrustPolicy.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 9/2/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-
-public enum TrustPolicy: String, Codable {
- case ignore
-
- case disconnect
-}
diff --git a/Passepartout/Sources/Model/TrustedNetworks.swift b/Passepartout/Sources/Model/TrustedNetworks.swift
deleted file mode 100644
index baecf4e0..00000000
--- a/Passepartout/Sources/Model/TrustedNetworks.swift
+++ /dev/null
@@ -1,219 +0,0 @@
-//
-// TrustedNetworks.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 6/21/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-
-public protocol TrustedNetworksModelDelegate: class {
- func trustedNetworksCouldDisconnect(_: TrustedNetworksModel) -> Bool
-
- func trustedNetworksShouldConfirmDisconnection(_: TrustedNetworksModel, triggeredAt rowIndex: Int, completionHandler: @escaping () -> Void)
-
- func trustedNetworks(_: TrustedNetworksModel, shouldInsertWifiAt rowIndex: Int)
-
- func trustedNetworks(_: TrustedNetworksModel, shouldReloadWifiAt rowIndex: Int, isTrusted: Bool)
-
- func trustedNetworks(_: TrustedNetworksModel, shouldDeleteWifiAt rowIndex: Int)
-
- func trustedNetworksShouldReinstall(_: TrustedNetworksModel)
-}
-
-public class TrustedNetworksModel {
- public enum RowType {
- case trustsMobile
-
- case trustedWiFi
-
- case addCurrentWiFi
- }
-
- public private(set) var trustedWifis: [String: Bool]
-
- public private(set) var sortedWifis: [String]
-
- #if os(iOS)
- private let hasMobileNetwork: Bool
-
- public private(set) var trustsMobileNetwork: Bool
-
- public private(set) var rows: [RowType]
- #endif
-
- public weak var delegate: TrustedNetworksModelDelegate?
-
- public init() {
- trustedWifis = [:]
- sortedWifis = []
-
- #if os(iOS)
- hasMobileNetwork = Utils.hasCellularData()
- trustsMobileNetwork = false
- rows = []
- #endif
- }
-
- public func load(from preferences: Preferences) {
- trustedWifis = preferences.trustedWifis
- sortedWifis = trustedWifis.keys.sorted()
-
- #if os(iOS)
- trustsMobileNetwork = preferences.trustsMobileNetwork
- rows.removeAll()
- if hasMobileNetwork {
- rows.append(.trustsMobile)
- }
- for _ in sortedWifis {
- rows.append(.trustedWiFi)
- }
- rows.append(.addCurrentWiFi)
- #endif
- }
-
- #if os(iOS)
- public func setMobile(_ isTrusted: Bool) {
- let completionHandler: () -> Void = {
- self.trustsMobileNetwork = isTrusted
- self.delegate?.trustedNetworksShouldReinstall(self)
- }
- guard !(isTrusted && mightDisconnect()) else {
- delegate?.trustedNetworksShouldConfirmDisconnection(self, triggeredAt: 0, completionHandler: completionHandler)
- return
- }
- completionHandler()
- }
- #endif
-
- public func wifi(at rowIndex: Int) -> (String, Bool) {
- let index = indexForWifi(at: rowIndex)
- let wifiName = sortedWifis[index]
- let isTrusted = trustedWifis[wifiName] ?? false
- return (wifiName, isTrusted)
- }
-
- public func addCurrentWifi() -> Bool {
- guard let currentWifi = Utils.currentWifiNetworkName() else {
- return false
- }
- addWifi(currentWifi)
- return true
- }
-
- public func addWifi(_ wifiToAdd: String) {
- var index = 0
- var isDuplicate = false
- for wifi in sortedWifis {
- guard wifiToAdd != wifi else {
- isDuplicate = true
- break
- }
- guard wifiToAdd > wifi else {
- break
- }
- index += 1
- }
-
- guard !(trustedWifis[wifiToAdd] ?? false) else {
- return
- }
-
- let isTrusted = false
- let rowIndex = rowIndexForWifi(at: index)
- trustedWifis[wifiToAdd] = isTrusted
-
- if !isDuplicate {
- sortedWifis.insert(wifiToAdd, at: index)
- #if os(iOS)
- rows.insert(.trustedWiFi, at: rowIndex)
- #endif
- delegate?.trustedNetworks(self, shouldInsertWifiAt: rowIndex)
- } else {
- delegate?.trustedNetworks(self, shouldReloadWifiAt: rowIndex, isTrusted: isTrusted)
- }
-
- delegate?.trustedNetworksShouldReinstall(self)
- }
-
- public func removeWifi(at rowIndex: Int) {
- let index = indexForWifi(at: rowIndex)
- let removedWifi = sortedWifis.remove(at: index)
- trustedWifis.removeValue(forKey: removedWifi)
- #if os(iOS)
- rows.remove(at: rowIndex)
- #endif
-
- delegate?.trustedNetworks(self, shouldDeleteWifiAt: rowIndex)
- delegate?.trustedNetworksShouldReinstall(self)
- }
-
- public func enableWifi(at rowIndex: Int) {
- let index = indexForWifi(at: rowIndex)
- let wifi = sortedWifis[index]
-
- let completionHandler: () -> Void = {
- self.trustedWifis[wifi] = true
-
- self.delegate?.trustedNetworks(self, shouldReloadWifiAt: rowIndex, isTrusted: true)
- self.delegate?.trustedNetworksShouldReinstall(self)
- }
- guard !mightDisconnect() else {
- delegate?.trustedNetworksShouldConfirmDisconnection(self, triggeredAt: rowIndex, completionHandler: completionHandler)
- return
- }
- completionHandler()
- }
-
- public func disableWifi(at rowIndex: Int) {
- let index = indexForWifi(at: rowIndex)
- let wifi = sortedWifis[index]
-
- trustedWifis[wifi] = false
-
- delegate?.trustedNetworks(self, shouldReloadWifiAt: rowIndex, isTrusted: false)
- delegate?.trustedNetworksShouldReinstall(self)
- }
-
- public func isTrusted(wifi: String) -> Bool {
- return trustedWifis[wifi] ?? false
- }
-
- private func indexForWifi(at rowIndex: Int) -> Int {
- #if os(iOS)
- return hasMobileNetwork ? (rowIndex - 1) : rowIndex
- #else
- return rowIndex
- #endif
- }
-
- private func rowIndexForWifi(at index: Int) -> Int {
- #if os(iOS)
- return index + (hasMobileNetwork ? 1 : 0)
- #else
- return index
- #endif
- }
-
- private func mightDisconnect() -> Bool {
- return delegate?.trustedNetworksCouldDisconnect(self) ?? false
- }
-}
diff --git a/Passepartout/Sources/Reviewer.swift b/Passepartout/Sources/Reviewer.swift
deleted file mode 100644
index 0bd311fc..00000000
--- a/Passepartout/Sources/Reviewer.swift
+++ /dev/null
@@ -1,75 +0,0 @@
-//
-// Reviewer.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 12/10/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import StoreKit
-import SwiftyBeaver
-
-private let log = SwiftyBeaver.self
-
-public class Reviewer {
- private struct Keys {
- static let eventCount = "ReviewerEventCount"
-
- static let lastVersion = "ReviewerLastVersion"
- }
-
- public static let shared = Reviewer()
-
- private let defaults: UserDefaults
-
- public var eventCountBeforeRating = 3
-
- private init() {
- defaults = .standard
- }
-
- public func reportEvent() {
- let currentVersion = GroupConstants.App.buildNumber
- let lastVersion = defaults.integer(forKey: Keys.lastVersion)
- if lastVersion > 0 {
- log.debug("App last reviewed for version \(lastVersion)")
- } else {
- log.debug("App was never reviewed")
- }
- guard currentVersion != lastVersion else {
- log.debug("App already reviewed for version \(currentVersion)")
- return
- }
-
- var count = defaults.integer(forKey: Keys.eventCount)
- count += 1
- defaults.set(count, forKey: Keys.eventCount)
- log.debug("Event reported for version \(currentVersion) (count: \(count), prompt: \(eventCountBeforeRating))")
-
- guard count >= eventCountBeforeRating else {
- return
- }
- log.debug("Prompting for review...")
-
- SKStoreReviewController.requestReview()
- defaults.removeObject(forKey: Keys.eventCount)
- defaults.set(currentVersion, forKey: Keys.lastVersion)
- }
-}
diff --git a/Passepartout/Sources/Services/Infrastructure.swift b/Passepartout/Sources/Services/Infrastructure.swift
deleted file mode 100644
index c9122b96..00000000
--- a/Passepartout/Sources/Services/Infrastructure.swift
+++ /dev/null
@@ -1,140 +0,0 @@
-//
-// Infrastructure.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 6/11/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import SSZipArchive
-
-public struct Infrastructure: Codable {
- public enum Name: String, Codable, Comparable {
- case mullvad = "Mullvad"
-
- case nordVPN = "NordVPN"
-
- case pia = "PIA"
-
- case protonVPN = "ProtonVPN"
-
- case tunnelBear = "TunnelBear"
-
- case vyprVPN = "VyprVPN"
-
- case windscribe = "Windscribe"
- }
-
- public struct Defaults: Codable {
- public let username: String?
-
- public let pool: String
-
- public let preset: String
- }
-
- public let build: Int
-
- public let name: Name
-
- public let categories: [PoolCategory]
-
- public let presets: [InfrastructurePreset]
-
- public let defaults: Defaults
-
- public static func loaded(from url: URL) throws -> Infrastructure {
- let json = try Data(contentsOf: url)
- return try JSONDecoder().decode(Infrastructure.self, from: json)
- }
-
- public func defaultPool() -> Pool? {
- return pool(withPrefix: defaults.pool)
- }
-
- public func pool(for identifier: String) -> Pool? {
- for cat in categories {
- for group in cat.groups {
- guard let found = group.pools.first(where: { $0.id == identifier }) else {
- continue
- }
- return found
- }
- }
- return nil
- }
-
- public func pool(withPrefix prefix: String) -> Pool? {
- for cat in categories {
- for group in cat.groups {
- guard let found = group.pools.first(where: { $0.id.hasPrefix(prefix) }) else {
- continue
- }
- return found
- }
- }
- return nil
- }
-
- public func preset(for identifier: String) -> InfrastructurePreset? {
- return presets.first { $0.id == identifier }
- }
-}
-
-extension Infrastructure.Name {
- public var webName: String {
- return rawValue.lowercased()
- }
-
- public static func <(lhs: Infrastructure.Name, rhs: Infrastructure.Name) -> Bool {
- return lhs.webName < rhs.webName
- }
-}
-
-extension Infrastructure.Name {
- public var externalURL: URL {
- return GroupConstants.App.externalURL.appendingPathComponent(webName)
- }
-
- public func importExternalResources(from url: URL, completionHandler: @escaping () -> Void) {
- var task: () -> Void
- switch self {
- case .nordVPN:
- task = {
- SSZipArchive.unzipFile(atPath: url.path, toDestination: self.externalURL.path)
- }
-
- default:
- task = {}
- }
- execute(task: task, completionHandler: completionHandler)
- }
-
- private func execute(task: @escaping () -> Void, completionHandler: @escaping () -> Void) {
- let queue: DispatchQueue = .global(qos: .background)
- queue.async {
- task()
- DispatchQueue.main.async {
- completionHandler()
- }
- }
- }
-}
diff --git a/Passepartout/Sources/Services/InfrastructureFactory.swift b/Passepartout/Sources/Services/InfrastructureFactory.swift
deleted file mode 100644
index de1f2281..00000000
--- a/Passepartout/Sources/Services/InfrastructureFactory.swift
+++ /dev/null
@@ -1,272 +0,0 @@
-//
-// InfrastructureFactory.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 9/2/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import SwiftyBeaver
-
-private let log = SwiftyBeaver.self
-
-// TODO: retain max N infrastructures at a time (LRU)
-
-public class InfrastructureFactory {
- private static func embedded(withName name: Infrastructure.Name) -> Infrastructure {
- guard let url = name.bundleURL else {
- fatalError("Cannot find JSON for infrastructure '\(name)'")
- }
- do {
- return try Infrastructure.loaded(from: url)
- } catch let e {
- fatalError("Cannot parse JSON for infrastructure '\(name)': \(e)")
- }
- }
-
- private static func isNewer(cachedEntry: URL, thanBundleWithName name: Infrastructure.Name) -> Bool {
- guard let cacheDate = FileManager.default.modificationDate(of: cachedEntry.path) else {
- return false
- }
- guard let bundleURL = name.bundleURL else {
- return true
- }
- guard let bundleDate = FileManager.default.modificationDate(of: bundleURL.path) else {
- return true
- }
- return cacheDate > bundleDate
- }
-
- public static let shared = InfrastructureFactory()
-
- // manually pre-sorted
- public let allNames: [Infrastructure.Name] = [
- .mullvad,
- .nordVPN,
- .pia,
- .protonVPN,
- .tunnelBear,
- .vyprVPN,
- .windscribe
- ]
-
- private let bundle: [Infrastructure.Name: Infrastructure]
-
- private let cachePath: URL
-
- private var cache: [Infrastructure.Name: Infrastructure]
-
- private var lastUpdate: [Infrastructure.Name: Date]
-
- private init() {
- var bundle: [Infrastructure.Name: Infrastructure] = [:]
- allNames.forEach {
- bundle[$0] = InfrastructureFactory.embedded(withName: $0)
- }
- self.bundle = bundle
-
- cachePath = GroupConstants.App.cachesURL
- cache = [:]
- lastUpdate = [:]
- }
-
- public func loadCache() {
- let cacheEntries: [URL]
- let netPath = "\(AppConstants.Store.webCacheDirectory)/\(WebServices.Group.network.rawValue)"
- do {
- cacheEntries = try FileManager.default.contentsOfDirectory(
- at: cachePath.appendingPathComponent(netPath),
- includingPropertiesForKeys: nil
- )
- } catch let e {
- log.verbose("Error loading cache: \(e)")
- return
- }
-
- let decoder = JSONDecoder()
- for entry in cacheEntries {
- guard let data = try? Data(contentsOf: entry) else {
- continue
- }
- let infra: Infrastructure
- do {
- infra = try decoder.decode(Infrastructure.self, from: data)
- } catch let e {
- log.warning("Unable to load infrastructure \(entry.lastPathComponent): \(e)")
- if let json = String(data: data, encoding: .utf8) {
- log.warning(json)
- }
- continue
- }
-
- // supersede if older than embedded
- guard InfrastructureFactory.isNewer(cachedEntry: entry, thanBundleWithName: infra.name) else {
- log.warning("Bundle is newer than cache, superseding cache for \(infra.name)")
- cache[infra.name] = bundle[infra.name]
- continue
- }
-
- cache[infra.name] = infra
- log.debug("Loading cache for \(infra.name)")
- }
- }
-
- public func get(_ name: Infrastructure.Name) -> Infrastructure {
- guard let infra = cache[name] ?? bundle[name] else {
- fatalError("No infrastructure embedded nor cached for '\(name)'")
- }
- return infra
- }
-
- public func update(_ name: Infrastructure.Name, notBeforeInterval minInterval: TimeInterval?, completionHandler: @escaping ((Infrastructure, Date)?, Error?) -> Void) -> Bool {
- let ifModifiedSince = modificationDate(for: name)
-
- if let lastInfrastructureUpdate = lastUpdate[name] {
- log.debug("Last update for \(name): \(lastUpdate)")
-
- if let minInterval = minInterval {
- let elapsed = -lastInfrastructureUpdate.timeIntervalSinceNow
- guard elapsed >= minInterval else {
- log.warning("Skipping update, only \(elapsed) seconds elapsed (< \(minInterval))")
- return false
- }
- }
- }
-
- WebServices.shared.network(with: name, ifModifiedSince: ifModifiedSince) { (response, error) in
- if error == nil {
- self.lastUpdate[name] = Date()
- }
-
- guard let response = response else {
- log.error("No response from web service")
- DispatchQueue.main.async {
- completionHandler(nil, error)
- }
- return
- }
- if response.isCached {
- log.debug("Cache is up to date")
- DispatchQueue.main.async {
- completionHandler(nil, error)
- }
- return
- }
- guard let infra = response.value, let lastModified = response.lastModified else {
- log.error("No response from web service or missing Last-Modified")
- DispatchQueue.main.async {
- completionHandler(nil, error)
- }
- return
- }
- let appBuild = GroupConstants.App.buildNumber
- guard appBuild >= infra.build else {
- log.error("Response requires app build >= \(infra.build) (found \(appBuild))")
- DispatchQueue.main.async {
- completionHandler(nil, error)
- }
- return
- }
-
- var isNewer = true
- if let bundleDate = self.bundleModificationDate(for: name) {
- log.verbose("Bundle date: \(bundleDate)")
- log.verbose("Web date: \(lastModified)")
-
- isNewer = lastModified > bundleDate
- }
- guard isNewer else {
- log.warning("Web service infrastructure is older than bundle, discarding")
- DispatchQueue.main.async {
- completionHandler(nil, error)
- }
- return
- }
-
- self.save(name, with: infra, lastModified: lastModified)
-
- DispatchQueue.main.async {
- completionHandler((infra, lastModified), nil)
- }
- }
- return true
- }
-
- public func modificationDate(for name: Infrastructure.Name) -> Date? {
- let optBundleDate = bundleModificationDate(for: name)
- guard let cacheDate = cacheModificationDate(for: name) else {
- return optBundleDate
- }
- guard let bundleDate = optBundleDate else {
- return cacheDate
- }
- return max(cacheDate, bundleDate)
- }
-
- private func save(_ name: Infrastructure.Name, with infrastructure: Infrastructure, lastModified: Date) {
- cache[name] = infrastructure
-
- let fm = FileManager.default
- let url = cacheURL(for: name)
- do {
- let parent = url.deletingLastPathComponent()
- try fm.createDirectory(at: parent, withIntermediateDirectories: true, attributes: nil)
- let data = try JSONEncoder().encode(infrastructure)
- try data.write(to: url)
- try fm.setAttributes([.modificationDate: lastModified], ofItemAtPath: url.path)
- } catch let e {
- log.error("Error saving cache: \(e)")
- }
- }
-
- private func cacheURL(for name: Infrastructure.Name) -> URL {
- return cachePath.appendingPathComponent(name.bundleRelativePath)
- }
-
- private func cacheModificationDate(for name: Infrastructure.Name) -> Date? {
- let url = cacheURL(for: name)
- return FileManager.default.modificationDate(of: url.path)
- }
-
- private func bundleModificationDate(for name: Infrastructure.Name) -> Date? {
- guard let url = name.bundleURL else {
- return nil
- }
- return FileManager.default.modificationDate(of: url.path)
- }
-}
-
-private extension Infrastructure.Name {
- var bundleRelativePath: String {
- let endpoint = WebServices.Endpoint.network(self)
-
- // e.g. "Web", PIA="net/pia" -> "Web/net/pia.json"
- return "\(AppConstants.Store.webCacheDirectory)/\(endpoint.path).json"
- }
-
- var bundleURL: URL? {
- let bundle = Bundle(for: InfrastructureFactory.self)
- let endpoint = WebServices.Endpoint.network(self)
-
- // e.g. "Web", PIA="net/pia" -> "[Bundle]:Web/net/pia.json"
- return bundle.url(forResource: "\(AppConstants.Store.webCacheDirectory)/\(endpoint.path)", withExtension: "json")
- }
-}
diff --git a/Passepartout/Sources/Services/InfrastructurePreset.swift b/Passepartout/Sources/Services/InfrastructurePreset.swift
deleted file mode 100644
index 0cb8caf3..00000000
--- a/Passepartout/Sources/Services/InfrastructurePreset.swift
+++ /dev/null
@@ -1,232 +0,0 @@
-//
-// InfrastructurePreset.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 8/30/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import TunnelKit
-
-// supports a subset of OpenVPNTunnelProvider.Configuration
-// ignores new JSON keys
-
-public struct InfrastructurePreset: Codable {
- public enum ExternalKey: String, Codable {
- case ca
-
- case client
-
- case key
-
- case wrapKeyData = "wrap.key.data"
-
- case hostname
- }
-
- public enum PresetKeys: String, CodingKey {
- case id
-
- case name
-
- case comment
-
- case configuration = "cfg"
-
- case external
- }
-
- public enum ConfigurationKeys: String, CodingKey {
- case endpointProtocols = "ep"
-
- case cipher
-
- case digest = "auth"
-
- case ca
-
- case clientCertificate = "client"
-
- case clientKey = "key"
-
- case compressionFraming = "frame"
-
- case compressionAlgorithm = "compression"
-
- case keepAliveSeconds = "ping"
-
- case renegotiatesAfterSeconds = "reneg"
-
- case tlsWrap = "wrap"
-
- case checksEKU = "eku"
-
- case randomizeEndpoint = "random"
-
- case usesPIAPatches = "pia"
- }
-
- public let id: String
-
- public let name: String
-
- public let comment: String
-
- public let configuration: OpenVPNTunnelProvider.Configuration
-
- public let external: [ExternalKey: String]?
-
- public func hasProtocol(_ proto: EndpointProtocol) -> Bool {
- return configuration.sessionConfiguration.endpointProtocols?.firstIndex(of: proto) != nil
- }
-
- public func externalConfiguration(forKey key: ExternalKey, infrastructureName: Infrastructure.Name, pool: Pool) throws -> Any? {
- guard let pattern = external?[key] else {
- return nil
- }
- let baseURL = infrastructureName.externalURL
- switch key {
- case .ca:
- let filename = pattern.replacingOccurrences(of: "${id}", with: pool.id)
- let caURL = baseURL.appendingPathComponent(filename)
- return OpenVPN.CryptoContainer(pem: try String(contentsOf: caURL))
-
- case .wrapKeyData:
- let filename = pattern.replacingOccurrences(of: "${id}", with: pool.id)
- let tlsKeyURL = baseURL.appendingPathComponent(filename)
- let file = try String(contentsOf: tlsKeyURL)
- return OpenVPN.StaticKey(file: file, direction: .client)
-
- case .hostname:
- return pattern.replacingOccurrences(of: "${id}", with: pool.id)
-
- default:
- break
- }
- return nil
- }
-
- public func injectExternalConfiguration(_ configuration: inout OpenVPNTunnelProvider.ConfigurationBuilder, with infrastructureName: Infrastructure.Name, pool: Pool) throws {
- guard let external = external, !external.isEmpty else {
- return
- }
-
- var sessionBuilder = configuration.sessionConfiguration.builder()
- if let _ = external[.ca] {
- sessionBuilder.ca = try externalConfiguration(forKey: .ca, infrastructureName: infrastructureName, pool: pool) as? OpenVPN.CryptoContainer
- }
- if let _ = external[.wrapKeyData] {
- if let dummyWrap = sessionBuilder.tlsWrap {
- if let staticKey = try externalConfiguration(forKey: .wrapKeyData, infrastructureName: infrastructureName, pool: pool) as? OpenVPN.StaticKey {
- sessionBuilder.tlsWrap = OpenVPN.TLSWrap(strategy: dummyWrap.strategy, key: staticKey)
- }
- }
- }
- if let _ = external[.hostname] {
- sessionBuilder.hostname = try externalConfiguration(forKey: .hostname, infrastructureName: infrastructureName, pool: pool) as? String
- }
- configuration.sessionConfiguration = sessionBuilder.build()
- }
-
- // MARK: Codable
-
- public init(from decoder: Decoder) throws {
- let container = try decoder.container(keyedBy: PresetKeys.self)
- id = try container.decode(String.self, forKey: .id)
- name = try container.decode(String.self, forKey: .name)
- comment = try container.decode(String.self, forKey: .comment)
- if let rawExternal = try container.decodeIfPresent([String: String].self, forKey: .external) {
- var remapped: [ExternalKey: String] = [:]
- for entry in rawExternal {
- guard let key = ExternalKey(rawValue: entry.key) else {
- continue
- }
- remapped[key] = entry.value
- }
- external = remapped
- } else {
- external = nil
- }
-
- let cfgContainer = try container.nestedContainer(keyedBy: ConfigurationKeys.self, forKey: .configuration)
-
- var sessionBuilder = OpenVPN.ConfigurationBuilder()
- sessionBuilder.cipher = try cfgContainer.decode(OpenVPN.Cipher.self, forKey: .cipher)
- if let digest = try cfgContainer.decodeIfPresent(OpenVPN.Digest.self, forKey: .digest) {
- sessionBuilder.digest = digest
- }
- sessionBuilder.compressionFraming = try cfgContainer.decode(OpenVPN.CompressionFraming.self, forKey: .compressionFraming)
- sessionBuilder.compressionAlgorithm = try cfgContainer.decodeIfPresent(OpenVPN.CompressionAlgorithm.self, forKey: .compressionAlgorithm) ?? .disabled
- sessionBuilder.ca = try cfgContainer.decodeIfPresent(OpenVPN.CryptoContainer.self, forKey: .ca)
- sessionBuilder.clientCertificate = try cfgContainer.decodeIfPresent(OpenVPN.CryptoContainer.self, forKey: .clientCertificate)
- sessionBuilder.clientKey = try cfgContainer.decodeIfPresent(OpenVPN.CryptoContainer.self, forKey: .clientKey)
- sessionBuilder.tlsWrap = try cfgContainer.decodeIfPresent(OpenVPN.TLSWrap.self, forKey: .tlsWrap)
- sessionBuilder.keepAliveInterval = try cfgContainer.decodeIfPresent(TimeInterval.self, forKey: .keepAliveSeconds)
- sessionBuilder.renegotiatesAfter = try cfgContainer.decodeIfPresent(TimeInterval.self, forKey: .renegotiatesAfterSeconds)
- sessionBuilder.endpointProtocols = try cfgContainer.decode([EndpointProtocol].self, forKey: .endpointProtocols)
- sessionBuilder.checksEKU = try cfgContainer.decodeIfPresent(Bool.self, forKey: .checksEKU) ?? false
- sessionBuilder.randomizeEndpoint = try cfgContainer.decodeIfPresent(Bool.self, forKey: .randomizeEndpoint) ?? false
- sessionBuilder.usesPIAPatches = try cfgContainer.decodeIfPresent(Bool.self, forKey: .usesPIAPatches) ?? false
-
- // default to server settings
- sessionBuilder.routingPolicies = nil
-
- let builder = OpenVPNTunnelProvider.ConfigurationBuilder(sessionConfiguration: sessionBuilder.build())
- configuration = builder.build()
- }
-
- public func encode(to encoder: Encoder) throws {
- guard let ca = configuration.sessionConfiguration.ca else {
- fatalError("Could not encode nil ca")
- }
- guard let endpointProtocols = configuration.sessionConfiguration.endpointProtocols else {
- fatalError("Could not encode nil endpointProtocols")
- }
-
- var container = encoder.container(keyedBy: PresetKeys.self)
- try container.encode(id, forKey: .id)
- try container.encode(name, forKey: .name)
- try container.encode(comment, forKey: .comment)
- if let external = external {
- var rawExternal: [String: String] = [:]
- for entry in external {
- rawExternal[entry.key.rawValue] = entry.value
- }
- try container.encode(rawExternal, forKey: .external)
- }
-
- var cfgContainer = container.nestedContainer(keyedBy: ConfigurationKeys.self, forKey: .configuration)
- try cfgContainer.encode(configuration.sessionConfiguration.cipher, forKey: .cipher)
- try cfgContainer.encode(configuration.sessionConfiguration.digest, forKey: .digest)
- try cfgContainer.encode(configuration.sessionConfiguration.compressionFraming, forKey: .compressionFraming)
- try cfgContainer.encodeIfPresent(configuration.sessionConfiguration.compressionAlgorithm, forKey: .compressionAlgorithm)
- try cfgContainer.encodeIfPresent(ca, forKey: .ca)
- try cfgContainer.encodeIfPresent(configuration.sessionConfiguration.clientCertificate, forKey: .clientCertificate)
- try cfgContainer.encodeIfPresent(configuration.sessionConfiguration.clientKey, forKey: .clientKey)
- try cfgContainer.encodeIfPresent(configuration.sessionConfiguration.tlsWrap, forKey: .tlsWrap)
- try cfgContainer.encodeIfPresent(configuration.sessionConfiguration.keepAliveInterval, forKey: .keepAliveSeconds)
- try cfgContainer.encodeIfPresent(configuration.sessionConfiguration.renegotiatesAfter, forKey: .renegotiatesAfterSeconds)
- try cfgContainer.encode(endpointProtocols, forKey: .endpointProtocols)
- try cfgContainer.encodeIfPresent(configuration.sessionConfiguration.checksEKU, forKey: .checksEKU)
- try cfgContainer.encodeIfPresent(configuration.sessionConfiguration.randomizeEndpoint, forKey: .randomizeEndpoint)
- try cfgContainer.encodeIfPresent(configuration.sessionConfiguration.usesPIAPatches, forKey: .usesPIAPatches)
- }
-}
diff --git a/Passepartout/Sources/Services/Pool.swift b/Passepartout/Sources/Services/Pool.swift
deleted file mode 100644
index d23e21c3..00000000
--- a/Passepartout/Sources/Services/Pool.swift
+++ /dev/null
@@ -1,161 +0,0 @@
-//
-// Pool.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 6/11/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import TunnelKit
-
-public struct Pool: Codable, Hashable {
- public enum CodingKeys: String, CodingKey {
- case id
-
- case country
-
- case extraCountries = "extra_countries"
-
- case area
-
- case num
-
- case tags
-
-// case location
-
- case hostname
-
- case isResolved = "resolved"
-
- case numericAddresses = "addrs"
- }
-
- public let id: String
-
- public let country: String
-
- public let extraCountries: [String]?
-
- public let area: String?
-
- public let num: Int?
-
- public let tags: [String]?
-
-// public let location: (Double, Double)
-
- public let hostname: String?
-
- public let isResolved: Bool?
-
- public let numericAddresses: [UInt32]?
-
- // XXX: inefficient but convenient field (not serialized)
- public func category(in infrastructure: Infrastructure) -> PoolCategory? {
- for category in infrastructure.categories {
- for group in category.groups {
- for pool in group.pools {
- if pool.id == id {
- return category
- }
- }
- }
- }
- return nil
- }
-
- public func supportedPresetIds(in infrastructure: Infrastructure) -> [String] {
- let poolCategory = category(in: infrastructure)
- return poolCategory?.presets ?? infrastructure.presets.map { $0.id }
- }
-
- public func hasAddress(_ address: String) -> Bool {
- guard let numericAddresses = numericAddresses else {
- return false
- }
- guard let ipv4 = DNSResolver.ipv4(fromString: address) else {
- return false
- }
- return numericAddresses.contains(ipv4)
- }
-
- // XXX: inefficient, can't easily use lazy on struct
- public func addresses() -> [String] {
- var addrs = numericAddresses?.map { DNSResolver.string(fromIPv4: $0) } ?? []
- if let hostname = hostname {
- addrs.insert(hostname, at: 0)
- }
- return addrs
- }
-
- // MARK: Equatable
-
- public static func == (lhs: Pool, rhs: Pool) -> Bool {
- return lhs.id == rhs.id
- }
-
- // MARK: Hashable
-
- public func hash(into hasher: inout Hasher) {
- id.hash(into: &hasher)
- }
-}
-
-extension Pool {
- public var localizedCountry: String {
- return Utils.localizedCountry(country)
- }
-
- public var localizedId: String {
- var comps: [String] = [localizedCountry]
- if let secondaryId = optionalSecondaryId {
- comps.append(secondaryId)
- }
- return comps.joined(separator: " - ")
- }
-
- public var secondaryId: String {
- return optionalSecondaryId ?? ""
- }
-
- private var optionalSecondaryId: String? {
- var comps: [String] = []
- if let extraCountries = extraCountries {
- comps.append(contentsOf: extraCountries.map { Utils.localizedCountry($0) })
- }
- if let area = area {
- comps.append(area.uppercased())
- }
- if let num = num {
- comps.append("#\(num)")
- }
- guard !comps.isEmpty else {
- return nil
- }
- var str = comps.joined(separator: " ")
- if let tags = tags {
- let suffix = tags.map { $0.uppercased() }.joined(separator: ",")
- str = "\(str) (\(suffix))"
- }
- return str
- }
-}
diff --git a/Passepartout/Sources/Services/PoolGroup.swift b/Passepartout/Sources/Services/PoolGroup.swift
deleted file mode 100644
index 2c4615f0..00000000
--- a/Passepartout/Sources/Services/PoolGroup.swift
+++ /dev/null
@@ -1,74 +0,0 @@
-//
-// PoolGroup.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 4/6/19.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-
-public struct PoolGroup: Codable, Hashable, Comparable, CustomStringConvertible {
- public let country: String
-
- public let area: String?
-
- public let pools: [Pool]
-
- private var id: String {
- var id = country
- if let area = area {
- id += area
- }
- return id
- }
-
- private var localizedId: String {
- var localizedId = Utils.localizedCountry(country)
- if let area = area {
- localizedId += area
- }
- return localizedId
- }
-
- // MARK: Hashable
-
- public func hash(into hasher: inout Hasher) {
- id.hash(into: &hasher)
- }
-
- // MARK: Comparable
-
- public static func <(lhs: PoolGroup, rhs: PoolGroup) -> Bool {
- return lhs.localizedId < rhs.localizedId
- }
-
- // MARK: CustomStringConvertible
-
- public var description: String {
- return "{\(country), \(area ?? "--")}"
- }
-}
-
-extension PoolGroup {
- public var localizedCountry: String {
- return Utils.localizedCountry(country)
- }
-}
diff --git a/Passepartout/Sources/Services/WebServices.swift b/Passepartout/Sources/Services/WebServices.swift
deleted file mode 100644
index 4033d2bd..00000000
--- a/Passepartout/Sources/Services/WebServices.swift
+++ /dev/null
@@ -1,130 +0,0 @@
-//
-// WebServices.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 9/14/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import SwiftyBeaver
-
-private let log = SwiftyBeaver.self
-
-public class WebServices {
- public enum Group: String {
- case network = "net"
- }
-
- public enum Endpoint {
- case network(Infrastructure.Name)
-
- var path: String {
- switch self {
- case .network(let name):
- return "\(Group.network.rawValue)/\(name.webName)"
- }
- }
- }
-
- public struct Response {
- public let value: T?
-
- public let lastModifiedString: String?
-
- public var lastModified: Date? {
- guard let string = lastModifiedString else {
- return nil
- }
- return lmFormatter.date(from: string)
- }
-
- public let isCached: Bool
- }
-
- public static let shared = WebServices()
-
- private static let lmFormatter: DateFormatter = {
- let fmt = DateFormatter()
- fmt.timeZone = TimeZone(abbreviation: "GMT")
- fmt.dateFormat = "EEE, dd LLL yyyy HH:mm:ss zzz"
- return fmt
- }()
-
- public func network(with name: Infrastructure.Name, ifModifiedSince lastModified: Date?, completionHandler: @escaping (Response?, Error?) -> Void) {
- var request = get(.network(name))
- if let lastModified = lastModified {
- request.addValue(WebServices.lmFormatter.string(from: lastModified), forHTTPHeaderField: "If-Modified-Since")
- }
- parse(Infrastructure.self, request: request, completionHandler: completionHandler)
- }
-
- private func get(_ endpoint: Endpoint) -> URLRequest {
- let url = AppConstants.Web.url(path: "\(endpoint.path).json")
- return URLRequest(url: url, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: AppConstants.Web.timeout)
- }
-
- private func parse(_ type: T.Type, request: URLRequest, completionHandler: @escaping (Response?, Error?) -> Void) {
- log.debug("GET \(request.url!)")
- log.debug("Request headers: \(request.allHTTPHeaderFields?.description ?? "")")
-
- let session = URLSession(configuration: .default)
- session.dataTask(with: request) { (data, response, error) in
- guard let httpResponse = response as? HTTPURLResponse else {
- log.error("Error (response): \(error?.localizedDescription ?? "nil")")
- completionHandler(nil, error)
- return
- }
-
- let statusCode = httpResponse.statusCode
- log.debug("Response status: \(statusCode)")
- if let responseHeaders = httpResponse.allHeaderFields as? [String: String] {
- log.debug("Response headers: \(responseHeaders)")
- }
-
- // 304: cache hit
- if statusCode == 304 {
- log.debug("Response is cached")
- completionHandler(Response(value: nil, lastModifiedString: nil, isCached: true), nil)
- return
- }
-
- // 200: cache miss
- let value: T
- let lastModifiedString: String?
- guard statusCode == 200, let data = data else {
- log.error("Error (network): \(error?.localizedDescription ?? "nil")")
- completionHandler(nil, error)
- return
- }
- do {
- value = try JSONDecoder().decode(type, from: data)
- } catch let e {
- log.error("Error (parsing): \(e)")
- completionHandler(nil, error)
- return
- }
- lastModifiedString = httpResponse.allHeaderFields["Last-Modified"] as? String
-
- let response = Response(value: value, lastModifiedString: lastModifiedString, isCached: false)
- completionHandler(response, nil)
- }.resume()
- }
-}
diff --git a/Passepartout/Sources/SwiftGen+Strings.swift b/Passepartout/Sources/SwiftGen+Strings.swift
deleted file mode 100644
index 96dd4b5d..00000000
--- a/Passepartout/Sources/SwiftGen+Strings.swift
+++ /dev/null
@@ -1,995 +0,0 @@
-// swiftlint:disable all
-// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
-
-import Foundation
-
-// swiftlint:disable superfluous_disable_command
-// swiftlint:disable file_length
-
-// MARK: - Strings
-
-// swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length
-// swiftlint:disable nesting type_body_length type_name
-public enum L10n {
-
- public enum About {
- /// About
- public static let title = L10n.tr("Localizable", "about.title")
- public enum Cells {
- public enum Credits {
- /// Credits
- public static let caption = L10n.tr("Localizable", "about.cells.credits.caption")
- }
- public enum Disclaimer {
- /// Disclaimer
- public static let caption = L10n.tr("Localizable", "about.cells.disclaimer.caption")
- }
- public enum Faq {
- /// FAQ
- public static let caption = L10n.tr("Localizable", "about.cells.faq.caption")
- }
- public enum PrivacyPolicy {
- /// Privacy policy
- public static let caption = L10n.tr("Localizable", "about.cells.privacy_policy.caption")
- }
- public enum ShareGeneric {
- /// Invite a friend
- public static let caption = L10n.tr("Localizable", "about.cells.share_generic.caption")
- }
- public enum ShareTwitter {
- /// Tweet about it!
- public static let caption = L10n.tr("Localizable", "about.cells.share_twitter.caption")
- }
- public enum Website {
- /// Home page
- public static let caption = L10n.tr("Localizable", "about.cells.website.caption")
- }
- }
- public enum Sections {
- public enum Share {
- /// Share
- public static let header = L10n.tr("Localizable", "about.sections.share.header")
- }
- public enum Web {
- /// Web
- public static let header = L10n.tr("Localizable", "about.sections.web.header")
- }
- }
- }
-
- public enum Account {
- public enum Cells {
- public enum OpenGuide {
- /// See your credentials
- public static let caption = L10n.tr("Localizable", "account.cells.open_guide.caption")
- }
- public enum Password {
- /// Password
- public static let caption = L10n.tr("Localizable", "account.cells.password.caption")
- /// secret
- public static let placeholder = L10n.tr("Localizable", "account.cells.password.placeholder")
- }
- public enum Signup {
- /// Register with %@
- public static func caption(_ p1: String) -> String {
- return L10n.tr("Localizable", "account.cells.signup.caption", p1)
- }
- }
- public enum Username {
- /// Username
- public static let caption = L10n.tr("Localizable", "account.cells.username.caption")
- /// username
- public static let placeholder = L10n.tr("Localizable", "account.cells.username.placeholder")
- }
- }
- public enum Sections {
- public enum Credentials {
- /// Credentials
- public static let header = L10n.tr("Localizable", "account.sections.credentials.header")
- }
- public enum Guidance {
- public enum Footer {
- public enum Infrastructure {
- /// Use your %@ website credentials. Your username is usually numeric.
- public static func mullvad(_ p1: String) -> String {
- return L10n.tr("Localizable", "account.sections.guidance.footer.infrastructure.mullvad", p1)
- }
- /// Use your %@ website credentials. Your username is usually your e-mail.
- public static func nordvpn(_ p1: String) -> String {
- return L10n.tr("Localizable", "account.sections.guidance.footer.infrastructure.nordvpn", p1)
- }
- /// Use your %@ website credentials. Your username is usually numeric with a "p" prefix.
- public static func pia(_ p1: String) -> String {
- return L10n.tr("Localizable", "account.sections.guidance.footer.infrastructure.pia", p1)
- }
- /// Find your %@ credentials in the "Account > OpenVPN / IKEv2 Username" section of the website.
- public static func protonvpn(_ p1: String) -> String {
- return L10n.tr("Localizable", "account.sections.guidance.footer.infrastructure.protonvpn", p1)
- }
- /// Use your %@ website credentials. Your username is usually your e-mail.
- public static func tunnelbear(_ p1: String) -> String {
- return L10n.tr("Localizable", "account.sections.guidance.footer.infrastructure.tunnelbear", p1)
- }
- /// Use your %@ website credentials. Your username is usually your e-mail.
- public static func vyprvpn(_ p1: String) -> String {
- return L10n.tr("Localizable", "account.sections.guidance.footer.infrastructure.vyprvpn", p1)
- }
- /// Find your %@ credentials in the OpenVPN Config Generator on the website.
- public static func windscribe(_ p1: String) -> String {
- return L10n.tr("Localizable", "account.sections.guidance.footer.infrastructure.windscribe", p1)
- }
- }
- }
- }
- public enum Registration {
- /// Go get an account on the %@ website.
- public static func footer(_ p1: String) -> String {
- return L10n.tr("Localizable", "account.sections.registration.footer", p1)
- }
- }
- }
- }
-
- public enum Configuration {
- public enum Cells {
- public enum Cipher {
- /// Cipher
- public static let caption = L10n.tr("Localizable", "configuration.cells.cipher.caption")
- }
- public enum Client {
- /// Client certificate
- public static let caption = L10n.tr("Localizable", "configuration.cells.client.caption")
- public enum Value {
- /// Not verified
- public static let disabled = L10n.tr("Localizable", "configuration.cells.client.value.disabled")
- /// Verified
- public static let enabled = L10n.tr("Localizable", "configuration.cells.client.value.enabled")
- }
- }
- public enum CompressionAlgorithm {
- /// Algorithm
- public static let caption = L10n.tr("Localizable", "configuration.cells.compression_algorithm.caption")
- public enum Value {
- /// LZO
- public static let lzo = L10n.tr("Localizable", "configuration.cells.compression_algorithm.value.lzo")
- /// Unsupported
- public static let other = L10n.tr("Localizable", "configuration.cells.compression_algorithm.value.other")
- }
- }
- public enum CompressionFraming {
- /// Framing
- public static let caption = L10n.tr("Localizable", "configuration.cells.compression_framing.caption")
- public enum Value {
- /// --compress
- public static let compress = L10n.tr("Localizable", "configuration.cells.compression_framing.value.compress")
- /// --comp-lzo
- public static let lzo = L10n.tr("Localizable", "configuration.cells.compression_framing.value.lzo")
- }
- }
- public enum DefaultGateway {
- /// Default gateway
- public static let caption = L10n.tr("Localizable", "configuration.cells.default_gateway.caption")
- }
- public enum Digest {
- /// Authentication
- public static let caption = L10n.tr("Localizable", "configuration.cells.digest.caption")
- public enum Value {
- /// Embedded
- public static let embedded = L10n.tr("Localizable", "configuration.cells.digest.value.embedded")
- }
- }
- public enum DnsDomain {
- /// Domain
- public static let caption = L10n.tr("Localizable", "configuration.cells.dns_domain.caption")
- }
- public enum DnsServer {
- /// DNS
- public static let caption = L10n.tr("Localizable", "configuration.cells.dns_server.caption")
- }
- public enum Eku {
- /// Extended verification
- public static let caption = L10n.tr("Localizable", "configuration.cells.eku.caption")
- }
- public enum KeepAlive {
- /// Keep-alive
- public static let caption = L10n.tr("Localizable", "configuration.cells.keep_alive.caption")
- public enum Value {
- /// %d seconds
- public static func seconds(_ p1: Int) -> String {
- return L10n.tr("Localizable", "configuration.cells.keep_alive.value.seconds", p1)
- }
- }
- }
- public enum ProxyHttp {
- /// Proxy
- public static let caption = L10n.tr("Localizable", "configuration.cells.proxy_http.caption")
- }
- public enum ProxyHttps {
- /// Proxy (HTTPS)
- public static let caption = L10n.tr("Localizable", "configuration.cells.proxy_https.caption")
- }
- public enum RandomEndpoint {
- /// Randomize endpoint
- public static let caption = L10n.tr("Localizable", "configuration.cells.random_endpoint.caption")
- }
- public enum RenegotiationSeconds {
- /// Renegotiation
- public static let caption = L10n.tr("Localizable", "configuration.cells.renegotiation_seconds.caption")
- public enum Value {
- /// after %@
- public static func after(_ p1: String) -> String {
- return L10n.tr("Localizable", "configuration.cells.renegotiation_seconds.value.after", p1)
- }
- }
- }
- public enum ResetOriginal {
- /// Reset configuration
- public static let caption = L10n.tr("Localizable", "configuration.cells.reset_original.caption")
- }
- public enum TlsWrapping {
- /// Wrapping
- public static let caption = L10n.tr("Localizable", "configuration.cells.tls_wrapping.caption")
- public enum Value {
- /// Authentication
- public static let auth = L10n.tr("Localizable", "configuration.cells.tls_wrapping.value.auth")
- /// Encryption
- public static let crypt = L10n.tr("Localizable", "configuration.cells.tls_wrapping.value.crypt")
- }
- }
- }
- public enum Sections {
- public enum Communication {
- /// Communication
- public static let header = L10n.tr("Localizable", "configuration.sections.communication.header")
- }
- public enum Compression {
- /// Compression
- public static let header = L10n.tr("Localizable", "configuration.sections.compression.header")
- }
- public enum Network {
- /// Network
- public static let header = L10n.tr("Localizable", "configuration.sections.network.header")
- }
- public enum Other {
- /// Other
- public static let header = L10n.tr("Localizable", "configuration.sections.other.header")
- }
- public enum Reset {
- /// If you ended up with broken connectivity after changing the communication parameters, tap to revert to the original configuration.
- public static let footer = L10n.tr("Localizable", "configuration.sections.reset.footer")
- }
- public enum Tls {
- /// TLS
- public static let header = L10n.tr("Localizable", "configuration.sections.tls.header")
- }
- }
- }
-
- public enum Credits {
- /// Credits
- public static let title = L10n.tr("Localizable", "credits.title")
- public enum Sections {
- public enum Licenses {
- /// Licenses
- public static let header = L10n.tr("Localizable", "credits.sections.licenses.header")
- }
- public enum Notices {
- /// Notices
- public static let header = L10n.tr("Localizable", "credits.sections.notices.header")
- }
- public enum Translations {
- /// Translations
- public static let header = L10n.tr("Localizable", "credits.sections.translations.header")
- }
- }
- }
-
- public enum DebugLog {
- public enum Alerts {
- public enum EmptyLog {
- /// The debug log is empty.
- public static let message = L10n.tr("Localizable", "debug_log.alerts.empty_log.message")
- }
- }
- public enum Buttons {
- /// Next
- public static let next = L10n.tr("Localizable", "debug_log.buttons.next")
- /// Previous
- public static let previous = L10n.tr("Localizable", "debug_log.buttons.previous")
- }
- }
-
- public enum Donation {
- /// Donate
- public static let title = L10n.tr("Localizable", "donation.title")
- public enum Alerts {
- public enum Purchase {
- public enum Failure {
- /// Unable to perform the donation. %@
- public static func message(_ p1: String) -> String {
- return L10n.tr("Localizable", "donation.alerts.purchase.failure.message", p1)
- }
- }
- public enum Success {
- /// This means a lot to me and I really hope you keep using and promoting this app.
- public static let message = L10n.tr("Localizable", "donation.alerts.purchase.success.message")
- /// Thank you
- public static let title = L10n.tr("Localizable", "donation.alerts.purchase.success.title")
- }
- }
- }
- public enum Cells {
- public enum Loading {
- /// Loading donations
- public static let caption = L10n.tr("Localizable", "donation.cells.loading.caption")
- }
- public enum Purchasing {
- /// Performing donation
- public static let caption = L10n.tr("Localizable", "donation.cells.purchasing.caption")
- }
- }
- public enum Sections {
- public enum OneTime {
- /// If you want to display gratitude for my free work, here are a couple amounts you can donate instantly.\n\nYou will only be charged once per donation, and you can donate multiple times.
- public static let footer = L10n.tr("Localizable", "donation.sections.one_time.footer")
- /// One time
- public static let header = L10n.tr("Localizable", "donation.sections.one_time.header")
- }
- }
- }
-
- public enum Endpoint {
- public enum Cells {
- public enum AnyAddress {
- /// Automatic
- public static let caption = L10n.tr("Localizable", "endpoint.cells.any_address.caption")
- }
- public enum AnyProtocol {
- /// Automatic
- public static let caption = L10n.tr("Localizable", "endpoint.cells.any_protocol.caption")
- }
- }
- public enum Sections {
- public enum LocationAddresses {
- /// Addresses
- public static let header = L10n.tr("Localizable", "endpoint.sections.location_addresses.header")
- }
- public enum LocationProtocols {
- /// Protocols
- public static let header = L10n.tr("Localizable", "endpoint.sections.location_protocols.header")
- }
- }
- }
-
- public enum Global {
- /// Cancel
- public static let cancel = L10n.tr("Localizable", "global.cancel")
- /// Close
- public static let close = L10n.tr("Localizable", "global.close")
- /// No e-mail account is configured.
- public static let emailNotConfigured = L10n.tr("Localizable", "global.email_not_configured")
- /// Next
- public static let next = L10n.tr("Localizable", "global.next")
- /// OK
- public static let ok = L10n.tr("Localizable", "global.ok")
- public enum Cells {
- /// Automatic
- public static let automatic = L10n.tr("Localizable", "global.cells.automatic")
- /// Disabled
- public static let disabled = L10n.tr("Localizable", "global.cells.disabled")
- /// Enabled
- public static let enabled = L10n.tr("Localizable", "global.cells.enabled")
- /// Manual
- public static let manual = L10n.tr("Localizable", "global.cells.manual")
- /// None
- public static let `none` = L10n.tr("Localizable", "global.cells.none")
- }
- public enum Host {
- public enum TitleInput {
- /// Acceptable characters are alphanumerics plus dash "-", underscore "_" and dot ".".
- public static let message = L10n.tr("Localizable", "global.host.title_input.message")
- /// My profile
- public static let placeholder = L10n.tr("Localizable", "global.host.title_input.placeholder")
- }
- }
- }
-
- public enum ImportedHosts {
- /// Imported hosts
- public static let title = L10n.tr("Localizable", "imported_hosts.title")
- }
-
- public enum IssueReporter {
- /// The debug log of your latest connections is crucial to resolve your connectivity issues and is completely anonymous.\n\nThe .ovpn configuration file, if any, is attached stripped of any sensitive data.\n\nPlease double check the e-mail attachments if unsure.
- public static let message = L10n.tr("Localizable", "issue_reporter.message")
- /// Report issue
- public static let title = L10n.tr("Localizable", "issue_reporter.title")
- public enum Buttons {
- /// I understand
- public static let accept = L10n.tr("Localizable", "issue_reporter.buttons.accept")
- }
- }
-
- public enum Label {
- public enum License {
- /// Unable to download full license content.
- public static let error = L10n.tr("Localizable", "label.license.error")
- }
- }
-
- public enum NetworkSettings {
- public enum Cells {
- public enum AddDnsServer {
- /// Add address
- public static let caption = L10n.tr("Localizable", "network_settings.cells.add_dns_server.caption")
- }
- public enum AddProxyBypass {
- /// Add bypass domain
- public static let caption = L10n.tr("Localizable", "network_settings.cells.add_proxy_bypass.caption")
- }
- public enum Address {
- /// Address
- public static let caption = L10n.tr("Localizable", "network_settings.cells.address.caption")
- }
- public enum Choice {
- /// Read .ovpn
- public static let client = L10n.tr("Localizable", "network_settings.cells.choice.client")
- /// Pull from server
- public static let server = L10n.tr("Localizable", "network_settings.cells.choice.server")
- }
- public enum Port {
- /// Port
- public static let caption = L10n.tr("Localizable", "network_settings.cells.port.caption")
- }
- public enum ProxyBypass {
- /// Bypass domain
- public static let caption = L10n.tr("Localizable", "network_settings.cells.proxy_bypass.caption")
- }
- }
- }
-
- public enum Organizer {
- public enum Alerts {
- public enum AddHost {
- /// Open an URL to an .ovpn configuration file from Safari, Mail or another app to set up a host profile.\n\nYou can also import an .ovpn with iTunes File Sharing.
- public static let message = L10n.tr("Localizable", "organizer.alerts.add_host.message")
- }
- public enum CannotDonate {
- /// There is no payment method configured on this device.
- public static let message = L10n.tr("Localizable", "organizer.alerts.cannot_donate.message")
- }
- public enum DeleteVpnProfile {
- /// Do you really want to erase the VPN configuration from your device settings? This may fix some broken VPN states and will not affect your provider and host profiles.
- public static let message = L10n.tr("Localizable", "organizer.alerts.delete_vpn_profile.message")
- }
- public enum ExhaustedProviders {
- /// You have created profiles for any available provider.
- public static let message = L10n.tr("Localizable", "organizer.alerts.exhausted_providers.message")
- }
- }
- public enum Cells {
- public enum About {
- /// About %@
- public static func caption(_ p1: String) -> String {
- return L10n.tr("Localizable", "organizer.cells.about.caption", p1)
- }
- }
- public enum AddHost {
- /// Add new host
- public static let caption = L10n.tr("Localizable", "organizer.cells.add_host.caption")
- }
- public enum AddProvider {
- /// Add new provider
- public static let caption = L10n.tr("Localizable", "organizer.cells.add_provider.caption")
- }
- public enum Donate {
- /// Make a donation
- public static let caption = L10n.tr("Localizable", "organizer.cells.donate.caption")
- }
- public enum JoinCommunity {
- /// Join community
- public static let caption = L10n.tr("Localizable", "organizer.cells.join_community.caption")
- }
- public enum Patreon {
- /// Support me on Patreon
- public static let caption = L10n.tr("Localizable", "organizer.cells.patreon.caption")
- }
- public enum Profile {
- public enum Value {
- /// In use
- public static let current = L10n.tr("Localizable", "organizer.cells.profile.value.current")
- }
- }
- public enum SiriShortcuts {
- /// Manage shortcuts
- public static let caption = L10n.tr("Localizable", "organizer.cells.siri_shortcuts.caption")
- }
- public enum Translate {
- /// Offer to translate
- public static let caption = L10n.tr("Localizable", "organizer.cells.translate.caption")
- }
- public enum Uninstall {
- /// Remove VPN configuration
- public static let caption = L10n.tr("Localizable", "organizer.cells.uninstall.caption")
- }
- public enum WriteReview {
- /// Write a review
- public static let caption = L10n.tr("Localizable", "organizer.cells.write_review.caption")
- }
- }
- public enum Sections {
- public enum Feedback {
- /// Feedback
- public static let header = L10n.tr("Localizable", "organizer.sections.feedback.header")
- }
- public enum Hosts {
- /// Import hosts from raw .ovpn configuration files.
- public static let footer = L10n.tr("Localizable", "organizer.sections.hosts.footer")
- /// Hosts
- public static let header = L10n.tr("Localizable", "organizer.sections.hosts.header")
- }
- public enum Providers {
- /// Here you find a few providers with preset configuration profiles.
- public static let footer = L10n.tr("Localizable", "organizer.sections.providers.footer")
- /// Providers
- public static let header = L10n.tr("Localizable", "organizer.sections.providers.header")
- }
- public enum Siri {
- /// Get help from Siri to speed up your most common interactions with the app.
- public static let footer = L10n.tr("Localizable", "organizer.sections.siri.footer")
- /// Siri
- public static let header = L10n.tr("Localizable", "organizer.sections.siri.header")
- }
- public enum Support {
- /// Support
- public static let header = L10n.tr("Localizable", "organizer.sections.support.header")
- }
- }
- }
-
- public enum ParsedFile {
- public enum Alerts {
- public enum Buttons {
- /// Report an issue
- public static let report = L10n.tr("Localizable", "parsed_file.alerts.buttons.report")
- }
- public enum Decryption {
- /// The configuration contains an encrypted private key and it could not be decrypted. Double check your entered passphrase.
- public static let message = L10n.tr("Localizable", "parsed_file.alerts.decryption.message")
- }
- public enum EncryptionPassphrase {
- /// Please enter the encryption passphrase.
- public static let message = L10n.tr("Localizable", "parsed_file.alerts.encryption_passphrase.message")
- }
- public enum Malformed {
- /// The configuration file contains a malformed option (%@).
- public static func message(_ p1: String) -> String {
- return L10n.tr("Localizable", "parsed_file.alerts.malformed.message", p1)
- }
- }
- public enum Missing {
- /// The configuration file lacks a required option (%@).
- public static func message(_ p1: String) -> String {
- return L10n.tr("Localizable", "parsed_file.alerts.missing.message", p1)
- }
- }
- public enum Parsing {
- /// Unable to parse the provided configuration file (%@).
- public static func message(_ p1: String) -> String {
- return L10n.tr("Localizable", "parsed_file.alerts.parsing.message", p1)
- }
- }
- public enum PotentiallyUnsupported {
- /// The configuration file is correct but contains a potentially unsupported option (%@).\n\nConnectivity may break depending on server settings.
- public static func message(_ p1: String) -> String {
- return L10n.tr("Localizable", "parsed_file.alerts.potentially_unsupported.message", p1)
- }
- }
- public enum Unsupported {
- /// The configuration file contains an unsupported option (%@).
- public static func message(_ p1: String) -> String {
- return L10n.tr("Localizable", "parsed_file.alerts.unsupported.message", p1)
- }
- }
- }
- }
-
- public enum Provider {
- public enum Preset {
- public enum Cells {
- public enum TechDetails {
- /// Technical details
- public static let caption = L10n.tr("Localizable", "provider.preset.cells.tech_details.caption")
- }
- }
- }
- }
-
- public enum Reddit {
- /// Did you know that Passepartout has a subreddit? Subscribe for updates or to discuss issues, features, new platforms or whatever you like.\n\nIt's also a great way to show you care about this project.
- public static let message = L10n.tr("Localizable", "reddit.message")
- /// Reddit
- public static let title = L10n.tr("Localizable", "reddit.title")
- public enum Buttons {
- /// Don't ask again
- public static let never = L10n.tr("Localizable", "reddit.buttons.never")
- /// Remind me later
- public static let remind = L10n.tr("Localizable", "reddit.buttons.remind")
- /// Subscribe now!
- public static let subscribe = L10n.tr("Localizable", "reddit.buttons.subscribe")
- }
- }
-
- public enum Service {
- public enum Alerts {
- public enum Buttons {
- /// Reconnect
- public static let reconnect = L10n.tr("Localizable", "service.alerts.buttons.reconnect")
- }
- public enum CredentialsNeeded {
- /// You need to enter account credentials first.
- public static let message = L10n.tr("Localizable", "service.alerts.credentials_needed.message")
- }
- public enum Download {
- /// Failed to download configuration files. %@
- public static func failed(_ p1: String) -> String {
- return L10n.tr("Localizable", "service.alerts.download.failed", p1)
- }
- /// %@ requires the download of additional configuration files.\n\nConfirm to start the download.
- public static func message(_ p1: String) -> String {
- return L10n.tr("Localizable", "service.alerts.download.message", p1)
- }
- /// Download required
- public static let title = L10n.tr("Localizable", "service.alerts.download.title")
- public enum Hud {
- /// Extracting files, please be patient...
- public static let extracting = L10n.tr("Localizable", "service.alerts.download.hud.extracting")
- }
- }
- public enum MasksPrivateData {
- public enum Messages {
- /// In order to safely reset the current debug log and apply the new masking preference, you must reconnect to the VPN now.
- public static let mustReconnect = L10n.tr("Localizable", "service.alerts.masks_private_data.messages.must_reconnect")
- }
- }
- public enum ReconnectVpn {
- /// Do you want to reconnect to the VPN?
- public static let message = L10n.tr("Localizable", "service.alerts.reconnect_vpn.message")
- }
- public enum Rename {
- /// Rename profile
- public static let title = L10n.tr("Localizable", "service.alerts.rename.title")
- }
- public enum TestConnectivity {
- /// Connectivity
- public static let title = L10n.tr("Localizable", "service.alerts.test_connectivity.title")
- public enum Messages {
- /// Your device has no Internet connectivity, please review your profile parameters.
- public static let failure = L10n.tr("Localizable", "service.alerts.test_connectivity.messages.failure")
- /// Your device is connected to the Internet!
- public static let success = L10n.tr("Localizable", "service.alerts.test_connectivity.messages.success")
- }
- }
- public enum Trusted {
- public enum NoNetwork {
- /// You are not connected to any Wi-Fi network.
- public static let message = L10n.tr("Localizable", "service.alerts.trusted.no_network.message")
- }
- public enum WillDisconnectPolicy {
- /// By changing the trust policy, the VPN may be disconnected. Continue?
- public static let message = L10n.tr("Localizable", "service.alerts.trusted.will_disconnect_policy.message")
- }
- public enum WillDisconnectTrusted {
- /// By trusting this network, the VPN may be disconnected. Continue?
- public static let message = L10n.tr("Localizable", "service.alerts.trusted.will_disconnect_trusted.message")
- }
- }
- }
- public enum Cells {
- public enum Account {
- /// Account
- public static let caption = L10n.tr("Localizable", "service.cells.account.caption")
- /// None configured
- public static let `none` = L10n.tr("Localizable", "service.cells.account.none")
- }
- public enum ConnectionStatus {
- /// Status
- public static let caption = L10n.tr("Localizable", "service.cells.connection_status.caption")
- }
- public enum DataCount {
- /// Exchanged data
- public static let caption = L10n.tr("Localizable", "service.cells.data_count.caption")
- /// Unavailable
- public static let `none` = L10n.tr("Localizable", "service.cells.data_count.none")
- }
- public enum DebugLog {
- /// Debug log
- public static let caption = L10n.tr("Localizable", "service.cells.debug_log.caption")
- }
- public enum Endpoint {
- /// Endpoint
- public static let caption = L10n.tr("Localizable", "service.cells.endpoint.caption")
- }
- public enum Host {
- public enum Parameters {
- /// Parameters
- public static let caption = L10n.tr("Localizable", "service.cells.host.parameters.caption")
- }
- }
- public enum MasksPrivateData {
- /// Mask network data
- public static let caption = L10n.tr("Localizable", "service.cells.masks_private_data.caption")
- }
- public enum NetworkSettings {
- /// Network settings
- public static let caption = L10n.tr("Localizable", "service.cells.network_settings.caption")
- }
- public enum Provider {
- public enum Pool {
- /// Location
- public static let caption = L10n.tr("Localizable", "service.cells.provider.pool.caption")
- }
- public enum Preset {
- /// Preset
- public static let caption = L10n.tr("Localizable", "service.cells.provider.preset.caption")
- }
- public enum Refresh {
- /// Refresh infrastructure
- public static let caption = L10n.tr("Localizable", "service.cells.provider.refresh.caption")
- }
- }
- public enum Reconnect {
- /// Reconnect
- public static let caption = L10n.tr("Localizable", "service.cells.reconnect.caption")
- }
- public enum ReportIssue {
- /// Report connectivity issue
- public static let caption = L10n.tr("Localizable", "service.cells.report_issue.caption")
- }
- public enum TestConnectivity {
- /// Test connectivity
- public static let caption = L10n.tr("Localizable", "service.cells.test_connectivity.caption")
- }
- public enum TrustedAddWifi {
- /// Add current Wi-Fi
- public static let caption = L10n.tr("Localizable", "service.cells.trusted_add_wifi.caption")
- }
- public enum TrustedMobile {
- /// Cellular network
- public static let caption = L10n.tr("Localizable", "service.cells.trusted_mobile.caption")
- }
- public enum TrustedPolicy {
- /// Trust disables VPN
- public static let caption = L10n.tr("Localizable", "service.cells.trusted_policy.caption")
- }
- public enum UseProfile {
- /// Use this profile
- public static let caption = L10n.tr("Localizable", "service.cells.use_profile.caption")
- }
- public enum VpnResolvesHostname {
- /// Resolve server hostname
- public static let caption = L10n.tr("Localizable", "service.cells.vpn_resolves_hostname.caption")
- }
- public enum VpnService {
- /// Enabled
- public static let caption = L10n.tr("Localizable", "service.cells.vpn_service.caption")
- }
- public enum VpnSurvivesSleep {
- /// Keep alive on sleep
- public static let caption = L10n.tr("Localizable", "service.cells.vpn_survives_sleep.caption")
- }
- }
- public enum Sections {
- public enum Configuration {
- /// Configuration
- public static let header = L10n.tr("Localizable", "service.sections.configuration.header")
- }
- public enum Diagnostics {
- /// Masking status will be effective after reconnecting. Network data are hostnames, IP addresses, routing, SSID. Credentials and private keys are not logged regardless.
- public static let footer = L10n.tr("Localizable", "service.sections.diagnostics.footer")
- /// Diagnostics
- public static let header = L10n.tr("Localizable", "service.sections.diagnostics.header")
- }
- public enum General {
- /// General
- public static let header = L10n.tr("Localizable", "service.sections.general.header")
- }
- public enum ProviderInfrastructure {
- /// Last updated on %@.
- public static func footer(_ p1: String) -> String {
- return L10n.tr("Localizable", "service.sections.provider_infrastructure.footer", p1)
- }
- }
- public enum Status {
- /// Connection
- public static let header = L10n.tr("Localizable", "service.sections.status.header")
- }
- public enum Trusted {
- /// When entering a trusted network, the VPN is normally shut down and kept disconnected. Disable this option to not enforce such behavior.
- public static let footer = L10n.tr("Localizable", "service.sections.trusted.footer")
- /// Trusted networks
- public static let header = L10n.tr("Localizable", "service.sections.trusted.header")
- }
- public enum Vpn {
- /// The connection will be established whenever necessary.
- public static let footer = L10n.tr("Localizable", "service.sections.vpn.footer")
- /// VPN
- public static let header = L10n.tr("Localizable", "service.sections.vpn.header")
- }
- public enum VpnResolvesHostname {
- /// Preferred in most networks and required in some IPv6 networks. Disable where DNS is blocked, or to speed up negotiation when DNS is slow to respond.
- public static let footer = L10n.tr("Localizable", "service.sections.vpn_resolves_hostname.footer")
- }
- public enum VpnSurvivesSleep {
- /// Disable to improve battery usage, at the expense of occasional slowdowns due to wake-up reconnections.
- public static let footer = L10n.tr("Localizable", "service.sections.vpn_survives_sleep.footer")
- }
- }
- public enum Welcome {
- /// Welcome to Passepartout!\n\nUse the organizer to add a new profile.
- public static let message = L10n.tr("Localizable", "service.welcome.message")
- }
- }
-
- public enum Share {
- /// Passepartout is an user-friendly, open source OpenVPN client for iOS and macOS
- public static let message = L10n.tr("Localizable", "share.message")
- }
-
- public enum Shortcuts {
- public enum Add {
- /// Add shortcut
- public static let title = L10n.tr("Localizable", "shortcuts.add.title")
- public enum Alerts {
- public enum NoProfiles {
- /// There is no profile to connect to.
- public static let message = L10n.tr("Localizable", "shortcuts.add.alerts.no_profiles.message")
- }
- }
- public enum Cells {
- public enum Connect {
- /// Connect to
- public static let caption = L10n.tr("Localizable", "shortcuts.add.cells.connect.caption")
- }
- public enum DisableVpn {
- /// Disable VPN
- public static let caption = L10n.tr("Localizable", "shortcuts.add.cells.disable_vpn.caption")
- }
- public enum EnableVpn {
- /// Enable VPN
- public static let caption = L10n.tr("Localizable", "shortcuts.add.cells.enable_vpn.caption")
- }
- public enum TrustCellular {
- /// Trust cellular network
- public static let caption = L10n.tr("Localizable", "shortcuts.add.cells.trust_cellular.caption")
- }
- public enum TrustCurrentWifi {
- /// Trust current Wi-Fi
- public static let caption = L10n.tr("Localizable", "shortcuts.add.cells.trust_current_wifi.caption")
- }
- public enum UntrustCellular {
- /// Untrust cellular network
- public static let caption = L10n.tr("Localizable", "shortcuts.add.cells.untrust_cellular.caption")
- }
- public enum UntrustCurrentWifi {
- /// Untrust current Wi-Fi
- public static let caption = L10n.tr("Localizable", "shortcuts.add.cells.untrust_current_wifi.caption")
- }
- }
- public enum Sections {
- public enum Cellular {
- /// Cellular
- public static let header = L10n.tr("Localizable", "shortcuts.add.sections.cellular.header")
- }
- public enum Vpn {
- /// VPN
- public static let header = L10n.tr("Localizable", "shortcuts.add.sections.vpn.header")
- }
- public enum Wifi {
- /// Wi-Fi
- public static let header = L10n.tr("Localizable", "shortcuts.add.sections.wifi.header")
- }
- }
- }
- public enum Edit {
- /// Manage shortcuts
- public static let title = L10n.tr("Localizable", "shortcuts.edit.title")
- public enum Cells {
- public enum AddShortcut {
- /// Add shortcut
- public static let caption = L10n.tr("Localizable", "shortcuts.edit.cells.add_shortcut.caption")
- }
- }
- public enum Sections {
- public enum All {
- /// Existing shortcuts
- public static let header = L10n.tr("Localizable", "shortcuts.edit.sections.all.header")
- }
- }
- }
- }
-
- public enum Translations {
- /// Translations
- public static let title = L10n.tr("Localizable", "translations.title")
- }
-
- public enum Version {
- /// Version
- public static let title = L10n.tr("Localizable", "version.title")
- public enum Labels {
- /// Passepartout and TunnelKit are written and maintained by Davide De Rosa (keeshux).\n\nSource code for Passepartout and TunnelKit is publicly available on GitHub under the GPLv3, you can find links in the home page.\n\nPassepartout is a non-official client and is in no way affiliated with OpenVPN Inc.
- public static let intro = L10n.tr("Localizable", "version.labels.intro")
- }
- }
-
- public enum Vpn {
- /// Active
- public static let active = L10n.tr("Localizable", "vpn.active")
- /// Connecting
- public static let connecting = L10n.tr("Localizable", "vpn.connecting")
- /// Disabled
- public static let disabled = L10n.tr("Localizable", "vpn.disabled")
- /// Disconnecting
- public static let disconnecting = L10n.tr("Localizable", "vpn.disconnecting")
- /// Inactive
- public static let inactive = L10n.tr("Localizable", "vpn.inactive")
- public enum Errors {
- /// Auth failed
- public static let auth = L10n.tr("Localizable", "vpn.errors.auth")
- /// Compression unsupported
- public static let compression = L10n.tr("Localizable", "vpn.errors.compression")
- /// DNS failed
- public static let dns = L10n.tr("Localizable", "vpn.errors.dns")
- /// Encryption failed
- public static let encryption = L10n.tr("Localizable", "vpn.errors.encryption")
- /// No gateway
- public static let gateway = L10n.tr("Localizable", "vpn.errors.gateway")
- /// Network changed
- public static let network = L10n.tr("Localizable", "vpn.errors.network")
- /// Missing routing
- public static let routing = L10n.tr("Localizable", "vpn.errors.routing")
- /// Timeout
- public static let timeout = L10n.tr("Localizable", "vpn.errors.timeout")
- /// TLS failed
- public static let tls = L10n.tr("Localizable", "vpn.errors.tls")
- }
- }
-
- public enum Wizards {
- public enum Host {
- public enum Alerts {
- public enum Existing {
- /// A host profile with the same title already exists. Replace it?
- public static let message = L10n.tr("Localizable", "wizards.host.alerts.existing.message")
- }
- }
- public enum Cells {
- public enum TitleInput {
- /// Title
- public static let caption = L10n.tr("Localizable", "wizards.host.cells.title_input.caption")
- }
- }
- public enum Sections {
- public enum Existing {
- /// Existing profiles
- public static let header = L10n.tr("Localizable", "wizards.host.sections.existing.header")
- }
- }
- }
- }
-}
-// swiftlint:enable explicit_type_interface function_parameter_count identifier_name line_length
-// swiftlint:enable nesting type_body_length type_name
-
-// MARK: - Implementation Details
-
-extension L10n {
- private static func tr(_ table: String, _ key: String, _ args: CVarArg...) -> String {
- // swiftlint:disable:next nslocalizedstring_key
- let format = NSLocalizedString(key, tableName: table, bundle: Bundle(for: BundleToken.self), comment: "")
- return String(format: format, locale: Locale.current, arguments: args)
- }
-}
-
-private final class BundleToken {}
diff --git a/Passepartout/Sources/Utils.swift b/Passepartout/Sources/Utils.swift
deleted file mode 100644
index f964e688..00000000
--- a/Passepartout/Sources/Utils.swift
+++ /dev/null
@@ -1,242 +0,0 @@
-//
-// Utils.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 6/16/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-#if os(iOS)
-import SystemConfiguration.CaptiveNetwork
-#else
-import CoreWLAN
-#endif
-import SwiftyBeaver
-
-private let log = SwiftyBeaver.self
-
-public class Utils {
- fileprivate static let timestampFormatter: DateFormatter = {
- let fmt = DateFormatter()
- fmt.dateStyle = .medium
- fmt.timeStyle = .medium
- return fmt
- }()
-
- fileprivate static let componentsFormatter: DateComponentsFormatter = {
- let fmt = DateComponentsFormatter()
- fmt.unitsStyle = .full
- return fmt
- }()
-
- public static func versionString() -> String {
- let info = Bundle.main.infoDictionary
- guard let version = info?["CFBundleShortVersionString"] else {
- fatalError("No bundle version?")
- }
- guard let build = info?["CFBundleVersion"] else {
- fatalError("No bundle build number?")
- }
- return "\(version) (\(build))"
- }
-
- #if targetEnvironment(simulator)
- public static func hasCellularData() -> Bool {
- return true
- }
- #else
- public static func hasCellularData() -> Bool {
- var addrs: UnsafeMutablePointer?
- guard getifaddrs(&addrs) == 0 else {
- return false
- }
- var isFound = false
- var cursor = addrs?.pointee
- while let ifa = cursor {
- let name = String(cString: ifa.ifa_name)
- if name == "pdp_ip0" {
- isFound = true
- break
- }
- cursor = ifa.ifa_next?.pointee
- }
- freeifaddrs(addrs)
- return isFound
- }
- #endif
-
- #if targetEnvironment(simulator)
- public static func currentWifiNetworkName() -> String? {
-// return nil
- return ["FOO", "BAR", "WIFI"].customRandomElement()
- }
- #else
- public static func currentWifiNetworkName() -> String? {
- #if os(iOS)
- guard let interfaceNames = CNCopySupportedInterfaces() as? [CFString] else {
- return nil
- }
- for name in interfaceNames {
- guard let iface = CNCopyCurrentNetworkInfo(name) as? [String: Any] else {
- continue
- }
- if let ssid = iface["SSID"] as? String {
- return ssid
- }
- }
- return nil
- #else
- return CWWiFiClient.shared().interface()?.ssid()
- #endif
- }
- #endif
-
- public static func regex(_ pattern: String) -> NSRegularExpression {
- return try! NSRegularExpression(pattern: pattern, options: [])
- }
-
- public static func checkConnectivityURL(_ url: URL, timeout: TimeInterval, completionHandler: @escaping (Bool) -> Void) {
- let session = URLSession(configuration: .ephemeral)
- let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: timeout)
-
- log.info("Check connectivity via \(url)")
- session.dataTask(with: request) { (_, response, error) in
- if let response = response as? HTTPURLResponse {
- log.debug("Response code: \(response.statusCode)")
- }
- if let error = error {
- log.error("Connectivity failed: \(error)")
- } else {
- log.info("Connectivity succeeded!")
- }
- DispatchQueue.main.async {
- completionHandler(error == nil)
- }
- }.resume()
- }
-
- public static func localizedCountry(_ code: String) -> String {
- return Locale.current.localizedString(forRegionCode: code) ?? code
- }
-
- public static func localizedLanguage(_ code: String) -> String {
- return Locale.current.localizedString(forLanguageCode: code)?.capitalized ?? code
- }
-
- private init() {
- }
-}
-
-public extension FileManager {
- func userURL(for searchPath: SearchPathDirectory, appending: String?) -> URL {
- let paths = urls(for: .documentDirectory, in: .userDomainMask)
- var directory = paths[0]
- if let appending = appending {
- directory.appendPathComponent(appending)
- }
- return directory
- }
-
- func modificationDate(of path: String) -> Date? {
- guard let attrs = try? attributesOfItem(atPath: path) else {
- return nil
- }
- return attrs[.modificationDate] as? Date
- }
-}
-
-public extension Date {
- var timestamp: String {
- return Utils.timestampFormatter.string(from: self)
- }
-}
-
-public extension TimeInterval {
- var localized: String {
- guard let str = Utils.componentsFormatter.string(from: self) else {
- fatalError("Could not format a TimeInterval?")
- }
- return str
- }
-}
-
-public extension Sequence {
- func stableSorted(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> [Element] {
- return try enumerated().sorted {
- return try areInIncreasingOrder($0.element, $1.element) ||
- ($0.offset < $1.offset && !areInIncreasingOrder($1.element, $0.element))
- }.map { $0.element }
- }
-}
-
-public extension Array {
- func customRandomElement() -> Element {
- let i = Int(arc4random() % UInt32(count))
- return self[i]
- }
-}
-
-public extension StringProtocol where Index == String.Index {
- func nsRange(from range: Range) -> NSRange {
- return NSRange(range, in: self)
- }
-}
-
-public extension CharacterSet {
- static let filename: CharacterSet = {
- var chars: CharacterSet = .decimalDigits
- let english = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- let symbols = "-_."
- chars.formUnion(CharacterSet(charactersIn: english))
- chars.formUnion(CharacterSet(charactersIn: english.lowercased()))
- chars.formUnion(CharacterSet(charactersIn: symbols))
- return chars
- }()
-}
-
-public extension URL {
- private static let illegalCharacterFallback = "_"
-
- var normalizedFilename: String {
- let filename = deletingPathExtension().lastPathComponent
- return filename.components(separatedBy: CharacterSet.filename.inverted).joined(separator: URL.illegalCharacterFallback)
- }
-}
-
-public extension Array where Element: CustomStringConvertible {
- func sortedCaseInsensitive() -> [Element] {
- return sorted { $0.description.lowercased() < $1.description.lowercased() }
- }
-}
-
-public extension UITableView {
- func scrollToRowAsync(at indexPath: IndexPath) {
- DispatchQueue.main.async { [weak self] in
- self?.scrollToRow(at: indexPath, at: .middle, animated: false)
- }
- }
-
- func selectRowAsync(at indexPath: IndexPath) {
- DispatchQueue.main.async { [weak self] in
- self?.selectRow(at: indexPath, animated: false, scrollPosition: .middle)
- }
- }
-}
diff --git a/Passepartout/Sources/VPN/GracefulVPN.swift b/Passepartout/Sources/VPN/GracefulVPN.swift
deleted file mode 100644
index e8dc8258..00000000
--- a/Passepartout/Sources/VPN/GracefulVPN.swift
+++ /dev/null
@@ -1,139 +0,0 @@
-//
-// GracefulVPN.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 9/18/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import SwiftyBeaver
-
-private let log = SwiftyBeaver.self
-
-public class GracefulVPN {
- private let service: ConnectionService
-
- public var profile: ConnectionProfile?
-
- private var vpn: VPNProvider? {
- guard let profile = profile else {
- return nil
- }
- guard service.isActiveProfile(profile) else {
- return nil
- }
- return VPN.shared
- }
-
- public var isEnabled: Bool {
- return vpn?.isEnabled ?? false
- }
-
- public var status: VPNStatus? {
- return vpn?.status
- }
-
- public init(service: ConnectionService) {
- self.service = service
- }
-
- public func prepare(completionHandler: (() -> Void)?) {
- service.clearVpnLastError()
- guard let vpn = vpn else {
- completionHandler?()
- return
- }
- log.info("Preparing...")
- vpn.prepare(completionHandler: completionHandler)
- }
-
- public func reconnect(completionHandler: ((Error?) -> Void)?) {
- service.clearVpnLastError()
- guard let vpn = vpn else {
- completionHandler?(ApplicationError.inactiveProfile)
- return
- }
- do {
- log.info("Reconnecting...")
- try vpn.reconnect(configuration: service.vpnConfiguration(), completionHandler: completionHandler)
- } catch let e {
- guard e as? ApplicationError != .externalResources else {
- completionHandler?(e)
- return
- }
- log.error("Could not reconnect: \(e)")
- }
- }
-
- public func reinstall(completionHandler: ((Error?) -> Void)?) {
- service.clearVpnLastError()
- guard let vpn = vpn else {
- completionHandler?(ApplicationError.inactiveProfile)
- return
- }
- do {
- log.info("Reinstalling...")
- try vpn.install(configuration: service.vpnConfiguration(), completionHandler: completionHandler)
- } catch let e {
- guard e as? ApplicationError != .externalResources else {
- completionHandler?(e)
- return
- }
- log.error("Could not reinstall: \(e)")
- }
- }
-
- public func reinstallIfEnabled() {
- guard isEnabled else {
- log.warning("Not reinstalling (VPN is disabled)")
- return
- }
- if status != .disconnected {
- reconnect(completionHandler: nil)
- } else {
- reinstall(completionHandler: nil)
- }
- }
-
- public func disconnect(completionHandler: ((Error?) -> Void)?) {
- guard let vpn = vpn else {
- completionHandler?(ApplicationError.inactiveProfile)
- return
- }
- vpn.disconnect(completionHandler: completionHandler)
- }
-
- public func uninstall(completionHandler: (() -> Void)?) {
- guard let vpn = vpn else {
- completionHandler?()
- return
- }
- vpn.uninstall(completionHandler: completionHandler)
- }
-
- public func requestBytesCount(completionHandler: @escaping ((UInt, UInt)?) -> Void) {
- guard let vpn = vpn else {
- completionHandler(nil)
- return
- }
- vpn.requestBytesCount(completionHandler: completionHandler)
- }
-}
diff --git a/Passepartout/Sources/VPN/MockVPNProvider.swift b/Passepartout/Sources/VPN/MockVPNProvider.swift
deleted file mode 100644
index f264da3f..00000000
--- a/Passepartout/Sources/VPN/MockVPNProvider.swift
+++ /dev/null
@@ -1,81 +0,0 @@
-//
-// MockVPNProvider.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 6/15/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-
-public class MockVPNProvider: VPNProvider {
- public let isPrepared: Bool = true
-
- public private(set) var isEnabled: Bool = false
-
- public private(set) var status: VPNStatus = .disconnected
-
- public func prepare(completionHandler: (() -> Void)?) {
- NotificationCenter.default.post(name: .VPNDidPrepare, object: nil)
- completionHandler?()
- }
-
- public func install(configuration: VPNConfiguration, completionHandler: ((Error?) -> Void)?) {
- isEnabled = true
- completionHandler?(nil)
- }
-
- public func connect(completionHandler: ((Error?) -> Void)?) {
- isEnabled = true
- status = .connected
- NotificationCenter.default.post(name: .VPNDidChangeStatus, object: self)
- completionHandler?(nil)
- }
-
- public func disconnect(completionHandler: ((Error?) -> Void)?) {
- isEnabled = false
- status = .disconnected
- NotificationCenter.default.post(name: .VPNDidChangeStatus, object: self)
- completionHandler?(nil)
- }
-
- public func reconnect(configuration: VPNConfiguration, completionHandler: ((Error?) -> Void)?) {
- isEnabled = true
- status = .connected
- NotificationCenter.default.post(name: .VPNDidChangeStatus, object: self)
- completionHandler?(nil)
- }
-
- public func uninstall(completionHandler: (() -> Void)?) {
- isEnabled = false
- status = .disconnected
- NotificationCenter.default.post(name: .VPNDidChangeStatus, object: self)
- completionHandler?()
- }
-
- public func requestDebugLog(fallback: (() -> String)?, completionHandler: @escaping (String) -> Void) {
- let log = [String](repeating: "lorem ipsum", count: 1000).joined(separator: " ")
- completionHandler(log)
- }
-
- public func requestBytesCount(completionHandler: @escaping ((UInt, UInt)?) -> Void) {
- completionHandler((0, 0))
- }
-}
diff --git a/Passepartout/Sources/VPN/StandardVPNProvider.swift b/Passepartout/Sources/VPN/StandardVPNProvider.swift
deleted file mode 100644
index 746e1a90..00000000
--- a/Passepartout/Sources/VPN/StandardVPNProvider.swift
+++ /dev/null
@@ -1,288 +0,0 @@
-//
-// StandardVPNProvider.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 6/15/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import NetworkExtension
-import TunnelKit
-
-public class StandardVPNProvider: VPNProvider {
- private let bundleIdentifier: String
-
- private var manager: NETunnelProviderManager?
-
- private var lastNotifiedStatus: VPNStatus?
-
- public init(bundleIdentifier: String) {
- self.bundleIdentifier = bundleIdentifier
-
- let nc = NotificationCenter.default
- nc.addObserver(self, selector: #selector(vpnDidUpdate(_:)), name: .NEVPNStatusDidChange, object: nil)
- nc.addObserver(self, selector: #selector(vpnDidReinstall(_:)), name: .NEVPNConfigurationChange, object: nil)
- }
-
- deinit {
- NotificationCenter.default.removeObserver(self)
- }
-
- // MARK: VPNProvider
-
- public var isPrepared: Bool {
- return manager != nil
- }
-
- public var isEnabled: Bool {
- guard let manager = manager else {
- return false
- }
- return manager.isEnabled && manager.isOnDemandEnabled
- }
-
- public var status: VPNStatus {
- guard let neStatus = manager?.connection.status else {
- return .disconnected
- }
- switch neStatus {
- case .connected:
- return .connected
-
- case .connecting, .reasserting:
- return .connecting
-
- case .disconnecting:
- return .disconnecting
-
- case .disconnected, .invalid:
- return .disconnected
-
- @unknown default:
- return .disconnected
- }
- }
-
- public func prepare(completionHandler: (() -> Void)?) {
- find(with: bundleIdentifier) {
- self.manager = $0
- NotificationCenter.default.post(name: .VPNDidPrepare, object: nil)
- completionHandler?()
- }
- }
-
- public func install(configuration: VPNConfiguration, completionHandler: ((Error?) -> Void)?) {
- guard let configuration = configuration as? NetworkExtensionVPNConfiguration else {
- fatalError("Not a NetworkExtensionVPNConfiguration")
- }
- find(with: bundleIdentifier) {
- guard let manager = $0 else {
- completionHandler?(nil)
- return
- }
- self.manager = manager
- manager.protocolConfiguration = configuration.protocolConfiguration
- manager.onDemandRules = configuration.onDemandRules
- manager.isOnDemandEnabled = true
- manager.isEnabled = true
- manager.saveToPreferences { (error) in
- guard error == nil else {
- manager.isOnDemandEnabled = false
- manager.isEnabled = false
- completionHandler?(error)
- return
- }
- manager.loadFromPreferences { (error) in
- completionHandler?(error)
- }
- }
- }
- }
-
- public func connect(completionHandler: ((Error?) -> Void)?) {
- do {
- try manager?.connection.startVPNTunnel()
- completionHandler?(nil)
- } catch let e {
- completionHandler?(e)
- }
- }
-
- public func disconnect(completionHandler: ((Error?) -> Void)?) {
- guard let manager = manager else {
- completionHandler?(nil)
- return
- }
- manager.connection.stopVPNTunnel()
- manager.isOnDemandEnabled = false
- manager.isEnabled = false
- manager.saveToPreferences(completionHandler: completionHandler)
- }
-
- public func reconnect(configuration: VPNConfiguration, completionHandler: ((Error?) -> Void)?) {
- guard let configuration = configuration as? NetworkExtensionVPNConfiguration else {
- fatalError("Not a NetworkExtensionVPNConfiguration")
- }
- install(configuration: configuration) { (error) in
- guard error == nil else {
- completionHandler?(nil)
- return
- }
- let connectBlock = {
- self.connect(completionHandler: completionHandler)
- }
- if self.status != .disconnected {
- self.manager?.connection.stopVPNTunnel()
- DispatchQueue.main.asyncAfter(deadline: .now() + 2.0, execute: connectBlock)
- } else {
- connectBlock()
- }
- }
- }
-
- public func uninstall(completionHandler: (() -> Void)?) {
- find(with: bundleIdentifier) { (manager) in
- guard let manager = manager else {
- completionHandler?()
- return
- }
- manager.connection.stopVPNTunnel()
- manager.removeFromPreferences { (error) in
- self.manager = nil
- completionHandler?()
- }
- }
- }
-
- public func requestDebugLog(fallback: (() -> String)?, completionHandler: @escaping (String) -> Void) {
- guard status != .disconnected else {
- completionHandler(fallback?() ?? "")
- return
- }
- findAndRequestDebugLog { (recent) in
- DispatchQueue.main.async {
- guard let recent = recent else {
- completionHandler(fallback?() ?? "")
- return
- }
- completionHandler(recent)
- }
- }
- }
-
- public func requestBytesCount(completionHandler: @escaping ((UInt, UInt)?) -> Void) {
- find(with: bundleIdentifier) {
- self.manager = $0
- guard let session = self.manager?.connection as? NETunnelProviderSession else {
- DispatchQueue.main.async {
- completionHandler(nil)
- }
- return
- }
- do {
- try session.sendProviderMessage(OpenVPNTunnelProvider.Message.dataCount.data) { (data) in
- guard let data = data, data.count == 16 else {
- DispatchQueue.main.async {
- completionHandler(nil)
- }
- return
- }
- let bytesIn: UInt = data.subdata(in: 0..<8).withUnsafeBytes { $0.load(as: UInt.self) }
- let bytesOut: UInt = data.subdata(in: 8..<16).withUnsafeBytes { $0.load(as: UInt.self) }
- DispatchQueue.main.async {
- completionHandler((bytesIn, bytesOut))
- }
- }
- } catch {
- DispatchQueue.main.async {
- completionHandler(nil)
- }
- }
- }
- }
-
- // MARK: Helpers
-
- private func find(with bundleIdentifier: String, completionHandler: @escaping (NETunnelProviderManager?) -> Void) {
- NETunnelProviderManager.loadAllFromPreferences { (managers, error) in
- guard error == nil else {
- completionHandler(nil)
- return
- }
- let manager = managers?.first {
- guard let ptm = $0.protocolConfiguration as? NETunnelProviderProtocol else {
- return false
- }
- return (ptm.providerBundleIdentifier == bundleIdentifier)
- }
- completionHandler(manager ?? NETunnelProviderManager())
- }
- }
-
- private func findAndRequestDebugLog(completionHandler: @escaping (String?) -> Void) {
- find(with: bundleIdentifier) {
- self.manager = $0
- guard let session = self.manager?.connection as? NETunnelProviderSession else {
- completionHandler(nil)
- return
- }
- StandardVPNProvider.requestDebugLog(session: session, completionHandler: completionHandler)
- }
- }
-
- private static func requestDebugLog(session: NETunnelProviderSession, completionHandler: @escaping (String?) -> Void) {
- do {
- try session.sendProviderMessage(OpenVPNTunnelProvider.Message.requestLog.data) { (data) in
- guard let data = data, !data.isEmpty else {
- completionHandler(nil)
- return
- }
- let newestLog = String(data: data, encoding: .utf8)
- completionHandler(newestLog)
- }
- } catch {
- completionHandler(nil)
- }
- }
-
- // MARK: Notifications
-
- @objc private func vpnDidUpdate(_ notification: Notification) {
-// guard let connection = notification.object as? NETunnelProviderSession else {
-// return
-// }
-// log.debug("VPN status did change: \(connection.status.rawValue)")
-
- let status = self.status
- if let last = lastNotifiedStatus {
- guard status != last else {
- return
- }
- }
- lastNotifiedStatus = status
-
- NotificationCenter.default.post(name: .VPNDidChangeStatus, object: self)
- }
-
- @objc private func vpnDidReinstall(_ notification: Notification) {
- NotificationCenter.default.post(name: .VPNDidReinstall, object: self)
- }
-}
diff --git a/Passepartout/Sources/VPN/VPN.swift b/Passepartout/Sources/VPN/VPN.swift
deleted file mode 100644
index 443494c2..00000000
--- a/Passepartout/Sources/VPN/VPN.swift
+++ /dev/null
@@ -1,34 +0,0 @@
-//
-// VPN.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 6/12/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-
-public class VPN {
- #if targetEnvironment(simulator)
- public static let shared = MockVPNProvider()
- #else
- public static let shared = StandardVPNProvider(bundleIdentifier: AppConstants.App.tunnelBundleId)
- #endif
-}
diff --git a/Passepartout/Sources/VPN/VPNConfiguration.swift b/Passepartout/Sources/VPN/VPNConfiguration.swift
deleted file mode 100644
index b261cf26..00000000
--- a/Passepartout/Sources/VPN/VPNConfiguration.swift
+++ /dev/null
@@ -1,36 +0,0 @@
-//
-// VPNConfiguration.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 9/18/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-import NetworkExtension
-
-public protocol VPNConfiguration {
-}
-
-public struct NetworkExtensionVPNConfiguration: VPNConfiguration {
- public let protocolConfiguration: NETunnelProviderProtocol
-
- public let onDemandRules: [NEOnDemandRule]
-}
diff --git a/Passepartout/Sources/VPN/VPNProvider.swift b/Passepartout/Sources/VPN/VPNProvider.swift
deleted file mode 100644
index d138adf7..00000000
--- a/Passepartout/Sources/VPN/VPNProvider.swift
+++ /dev/null
@@ -1,58 +0,0 @@
-//
-// VPNProvider.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 9/6/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-
-public protocol VPNProvider: class {
- var isPrepared: Bool { get }
-
- var isEnabled: Bool { get }
-
- var status: VPNStatus { get }
-
- func prepare(completionHandler: (() -> Void)?)
-
- func install(configuration: VPNConfiguration, completionHandler: ((Error?) -> Void)?)
-
- func connect(completionHandler: ((Error?) -> Void)?)
-
- func disconnect(completionHandler: ((Error?) -> Void)?)
-
- func reconnect(configuration: VPNConfiguration, completionHandler: ((Error?) -> Void)?)
-
- func uninstall(completionHandler: (() -> Void)?)
-
- func requestDebugLog(fallback: (() -> String)?, completionHandler: @escaping (String) -> Void)
-
- func requestBytesCount(completionHandler: @escaping ((UInt, UInt)?) -> Void)
-}
-
-public extension Notification.Name {
- static let VPNDidPrepare = Notification.Name("VPNDidPrepare")
-
- static let VPNDidChangeStatus = Notification.Name("VPNDidChangeStatus")
-
- static let VPNDidReinstall = Notification.Name("VPNDidReinstall")
-}
diff --git a/Passepartout/Sources/VPN/VPNStatus.swift b/Passepartout/Sources/VPN/VPNStatus.swift
deleted file mode 100644
index 39371a7d..00000000
--- a/Passepartout/Sources/VPN/VPNStatus.swift
+++ /dev/null
@@ -1,36 +0,0 @@
-//
-// VPNStatus.swift
-// Passepartout
-//
-// Created by Davide De Rosa on 9/18/18.
-// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
-// https://github.com/passepartoutvpn
-//
-// This file is part of Passepartout.
-//
-// Passepartout is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// Passepartout is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with Passepartout. If not, see .
-//
-
-import Foundation
-
-public enum VPNStatus {
- case connected
-
- case connecting
-
- case disconnected
-
- case disconnecting
-}
diff --git a/Passepartout-Core/Info.plist b/PassepartoutCore-iOS/Info.plist
similarity index 96%
rename from Passepartout-Core/Info.plist
rename to PassepartoutCore-iOS/Info.plist
index c0fcf6c3..cc06ea29 100644
--- a/Passepartout-Core/Info.plist
+++ b/PassepartoutCore-iOS/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 1.6.1
+ 1.7.0
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
diff --git a/Passepartout-Core/Passepartout_Core.h b/PassepartoutCore-iOS/PassepartoutCore.h
similarity index 70%
rename from Passepartout-Core/Passepartout_Core.h
rename to PassepartoutCore-iOS/PassepartoutCore.h
index 8808e6df..f448127a 100644
--- a/Passepartout-Core/Passepartout_Core.h
+++ b/PassepartoutCore-iOS/PassepartoutCore.h
@@ -1,10 +1,10 @@
//
-// Passepartout_Core.h
-// Passepartout-Core
+// PassepartoutCore.h
+// PassepartoutCore
//
// Created by Davide De Rosa on 3/18/19.
// Copyright (c) 2019 Davide De Rosa. All rights reserved.
-//
+
// https://github.com/passepartoutvpn
//
// This file is part of Passepartout.
@@ -23,14 +23,14 @@
// along with Passepartout. If not, see .
//
-#import
+#import
-//! Project version number for Passepartout_Core.
-FOUNDATION_EXPORT double Passepartout_CoreVersionNumber;
+//! Project version number for PassepartoutCore.
+FOUNDATION_EXPORT double PassepartoutCoreVersionNumber;
-//! Project version string for Passepartout_Core.
-FOUNDATION_EXPORT const unsigned char Passepartout_CoreVersionString[];
+//! Project version string for PassepartoutCore.
+FOUNDATION_EXPORT const unsigned char PassepartoutCoreVersionString[];
-// In this header, you should import all the public headers of your framework using statements like #import
+// In this header, you should import all the public headers of your framework using statements like #import
diff --git a/Passepartout-CoreTests/Info.plist b/PassepartoutCoreTests-iOS/Info.plist
similarity index 96%
rename from Passepartout-CoreTests/Info.plist
rename to PassepartoutCoreTests-iOS/Info.plist
index 120b91dd..19b78785 100644
--- a/Passepartout-CoreTests/Info.plist
+++ b/PassepartoutCoreTests-iOS/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
BNDL
CFBundleShortVersionString
- 1.6.1
+ 1.7.0
CFBundleVersion
1
diff --git a/Podfile b/Podfile
index b5830bff..3bf05f42 100644
--- a/Podfile
+++ b/Podfile
@@ -14,10 +14,10 @@ def shared_pods
pod 'SSZipArchive'
end
-target 'Passepartout-Core' do
+target 'PassepartoutCore-iOS' do
shared_pods
end
-target 'Passepartout-CoreTests' do
+target 'PassepartoutCoreTests-iOS' do
shared_pods
end
diff --git a/Podfile.lock b/Podfile.lock
index 6a47fa6b..7ee9d213 100644
--- a/Podfile.lock
+++ b/Podfile.lock
@@ -44,6 +44,6 @@ SPEC CHECKSUMS:
SwiftyBeaver: 4cc0080d2e23f980652e28978db11a5c9da39165
TunnelKit: 821c15bb87aafae69eb8c63e4cc46d883fff8797
-PODFILE CHECKSUM: b45e8f98f20b6c63f2735d1f038fb2e415601fbd
+PODFILE CHECKSUM: 7c6100ea5c0ecfaf8b85d0c7978502f9979cb057
COCOAPODS: 1.6.1
diff --git a/README.md b/README.md
index 38838734..a6a9e393 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
# [Passepartout][about-website]
![iOS 11+](https://img.shields.io/badge/ios-11+-green.svg)
-[![TunnelKit 1.7.x](https://img.shields.io/badge/tunnelkit-1.7-d69c68.svg)][dep-tunnelkit]
+[![TunnelKit 2.0.x](https://img.shields.io/badge/tunnelkit-2.0-d69c68.svg)][dep-tunnelkit]
[![License GPLv3](https://img.shields.io/badge/license-GPLv3-lightgray.svg)](LICENSE)
[![Join Reddit](https://img.shields.io/badge/discuss-Reddit-orange.svg)][about-reddit]
[![Join Telegram](https://img.shields.io/badge/chat-Telegram-blue.svg)][about-telegram]
@@ -95,12 +95,15 @@ Download the app codebase locally:
$ git clone https://github.com/passepartoutvpn/passepartout-ios.git
+Enter the directory and clone the submodules:
+
+ $ git submodule init
+ $ git submodule update
+
Assuming you have a [working CocoaPods environment][dep-cocoapods], setting up the app workspace only requires installing the pod dependencies:
$ pod install
-After that, open `Passepartout.xcworkspace` in Xcode and run the `Passepartout-iOS` target.
-
For the VPN to work properly, the app requires:
- _App Groups_ and _Keychain Sharing_ capabilities
@@ -113,7 +116,9 @@ Make sure to update `Passepartout-iOS/Config.xcconfig` according to your develop
CFG_TEAM_ID = A1B2C3D4E5
CFG_APP_ID = com.example.ios.MyApp
CFG_GROUP_ID = com.example.MyAppGroup // omit the "group." prefix
- CFG_APPSTORE_ID = 1234567890
+ CFG_APPSTORE_ID = 1234567890 // optional for development, can be bogus
+
+After that, open `Passepartout.xcworkspace` in Xcode and run the `Passepartout-iOS` target.
## License
@@ -168,8 +173,8 @@ Website: [passepartoutvpn.app][about-website]
[app-net-mullvad]: https://mullvad.net/en/account/create/
[app-net-nordvpn]: https://go.nordvpn.net/SH21Z
[app-net-pia]: https://www.privateinternetaccess.com/pages/buy-vpn/
-[app-net-protonvpn]: https://protonvpn.net/?aid=keeshux
-[app-net-tunnelbear]: https://click.tunnelbear.com/SHb8
+[app-net-protonvpn]: https://proton.go2cloud.org/SHZ
+[app-net-tunnelbear]: https://www.tunnelbear.com/
[app-net-vyprvpn]: https://www.vyprvpn.com/
[app-net-windscribe]: https://secure.link/kCsD0prd
diff --git a/Submodules/API b/Submodules/API
new file mode 160000
index 00000000..08a23ab1
--- /dev/null
+++ b/Submodules/API
@@ -0,0 +1 @@
+Subproject commit 08a23ab1772d0dd8ed39ef91300530745b26e25d
diff --git a/Submodules/Core b/Submodules/Core
new file mode 160000
index 00000000..27b161b3
--- /dev/null
+++ b/Submodules/Core
@@ -0,0 +1 @@
+Subproject commit 27b161b3a3dc616bb68dfb988583e4b0c2ba9e6a