diff --git a/Passepartout-iOS/Global/ConfigurationParserResult+Alerts.swift b/Passepartout-iOS/Global/ConfigurationParserResult+Alerts.swift
index 8077bbe5..39deb886 100644
--- a/Passepartout-iOS/Global/ConfigurationParserResult+Alerts.swift
+++ b/Passepartout-iOS/Global/ConfigurationParserResult+Alerts.swift
@@ -44,17 +44,17 @@ extension OpenVPN.ConfigurationParser.Result {
} catch let e as ConfigurationError {
switch e {
case .encryptionPassphrase, .unableToDecrypt(_):
- let alert = Macros.alert(url.normalizedFilename, L10n.ParsedFile.Alerts.EncryptionPassphrase.message)
+ let alert = Macros.alert(url.normalizedFilename, L10n.Core.ParsedFile.Alerts.EncryptionPassphrase.message)
alert.addTextField { (field) in
field.isSecureTextEntry = true
}
- alert.addDefaultAction(L10n.Global.ok) {
+ alert.addDefaultAction(L10n.Core.Global.ok) {
guard let passphrase = alert.textFields?.first?.text else {
return
}
passphraseBlock(passphrase)
}
- alert.addCancelAction(L10n.Global.cancel) {
+ alert.addCancelAction(L10n.Core.Global.cancel) {
passphraseCancelBlock?()
}
viewController.present(alert, animated: true, completion: nil)
@@ -76,22 +76,22 @@ extension OpenVPN.ConfigurationParser.Result {
private static func alertImportError(url: URL, in vc: UIViewController, withMessage message: String) {
let alert = Macros.alert(url.normalizedFilename, message)
-// alert.addDefaultAction(L10n.ParsedFile.Alerts.Buttons.report) {
+// alert.addDefaultAction(L10n.Core.ParsedFile.Alerts.Buttons.report) {
// var attach = IssueReporter.Attachments(debugLog: false, configurationURL: url)
// attach.description = message
// IssueReporter.shared.present(in: vc, withAttachments: attach)
// }
- alert.addCancelAction(L10n.Global.ok)
+ alert.addCancelAction(L10n.Core.Global.ok)
vc.present(alert, animated: true, completion: nil)
}
static func alertImportWarning(url: URL, in vc: UIViewController, withWarning warning: ConfigurationError, completionHandler: @escaping (Bool) -> Void) {
let message = details(forWarning: warning)
- let alert = Macros.alert(url.normalizedFilename, L10n.ParsedFile.Alerts.PotentiallyUnsupported.message(message))
- alert.addDefaultAction(L10n.Global.ok) {
+ let alert = Macros.alert(url.normalizedFilename, L10n.Core.ParsedFile.Alerts.PotentiallyUnsupported.message(message))
+ alert.addDefaultAction(L10n.Core.Global.ok) {
completionHandler(true)
}
- alert.addCancelAction(L10n.Global.cancel) {
+ alert.addCancelAction(L10n.Core.Global.cancel) {
completionHandler(false)
}
vc.present(alert, animated: true, completion: nil)
@@ -102,22 +102,22 @@ extension OpenVPN.ConfigurationParser.Result {
switch appError {
case .malformed(let option):
log.error("Could not parse configuration URL: malformed option, \(option)")
- return L10n.ParsedFile.Alerts.Malformed.message(option)
+ return L10n.Core.ParsedFile.Alerts.Malformed.message(option)
case .missingConfiguration(let option):
log.error("Could not parse configuration URL: missing configuration, \(option)")
- return L10n.ParsedFile.Alerts.Missing.message(option)
+ return L10n.Core.ParsedFile.Alerts.Missing.message(option)
case .unsupportedConfiguration(let option):
log.error("Could not parse configuration URL: unsupported configuration, \(option)")
- return L10n.ParsedFile.Alerts.Unsupported.message(option)
+ return L10n.Core.ParsedFile.Alerts.Unsupported.message(option)
default:
break
}
}
log.error("Could not parse configuration URL: \(error)")
- return L10n.ParsedFile.Alerts.Parsing.message(error.localizedDescription)
+ return L10n.Core.ParsedFile.Alerts.Parsing.message(error.localizedDescription)
}
private static func details(forWarning warning: ConfigurationError) -> String {
diff --git a/Passepartout-iOS/Global/IssueReporter.swift b/Passepartout-iOS/Global/IssueReporter.swift
index c638ba6a..ab34f4a0 100644
--- a/Passepartout-iOS/Global/IssueReporter.swift
+++ b/Passepartout-iOS/Global/IssueReporter.swift
@@ -57,8 +57,8 @@ class IssueReporter: NSObject {
func present(in viewController: UIViewController, withAttachments attachments: Attachments) {
guard MFMailComposeViewController.canSendMail() else {
- let alert = Macros.alert(L10n.IssueReporter.title, L10n.Global.emailNotConfigured)
- alert.addCancelAction(L10n.Global.ok)
+ let alert = Macros.alert(L10n.Core.IssueReporter.title, L10n.Core.Global.emailNotConfigured)
+ alert.addCancelAction(L10n.Core.Global.ok)
viewController.present(alert, animated: true, completion: nil)
return
}
@@ -66,13 +66,13 @@ class IssueReporter: NSObject {
self.viewController = viewController
if attachments.debugLog {
- let alert = Macros.alert(L10n.IssueReporter.title, L10n.IssueReporter.message)
- alert.addDefaultAction(L10n.IssueReporter.Buttons.accept) {
+ let alert = Macros.alert(L10n.Core.IssueReporter.title, L10n.Core.IssueReporter.message)
+ alert.addDefaultAction(L10n.Core.IssueReporter.Buttons.accept) {
VPN.shared.requestDebugLog(fallback: AppConstants.Log.debugSnapshot) {
self.composeEmail(withDebugLog: $0, configurationURL: attachments.configurationURL, description: attachments.description)
}
}
- alert.addCancelAction(L10n.Global.cancel)
+ alert.addCancelAction(L10n.Core.Global.cancel)
viewController.present(alert, animated: true, completion: nil)
} else {
composeEmail(withDebugLog: nil, configurationURL: attachments.configurationURL, description: attachments.description)
diff --git a/Passepartout-iOS/Global/SwiftGen+Strings.swift b/Passepartout-iOS/Global/SwiftGen+Strings.swift
new file mode 100644
index 00000000..9cf81c3a
--- /dev/null
+++ b/Passepartout-iOS/Global/SwiftGen+Strings.swift
@@ -0,0 +1,992 @@
+// 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
+internal enum L10n {
+ internal enum App {
+ internal enum Account {
+ internal enum Sections {
+ internal enum Credentials {
+ /// Credentials
+ internal static let header = L10n.tr("App", "account.sections.credentials.header")
+ }
+ }
+ }
+ internal enum Endpoint {
+ internal enum Sections {
+ internal enum LocationAddresses {
+ /// Addresses
+ internal static let header = L10n.tr("App", "endpoint.sections.location_addresses.header")
+ }
+ internal enum LocationProtocols {
+ /// Protocols
+ internal static let header = L10n.tr("App", "endpoint.sections.location_protocols.header")
+ }
+ }
+ }
+ internal enum ImportedHosts {
+ /// Imported hosts
+ internal static let title = L10n.tr("App", "imported_hosts.title")
+ }
+ internal enum NetworkSettings {
+ internal enum Cells {
+ internal enum AddDnsServer {
+ /// Add address
+ internal static let caption = L10n.tr("App", "network_settings.cells.add_dns_server.caption")
+ }
+ internal enum AddProxyBypass {
+ /// Add bypass domain
+ internal static let caption = L10n.tr("App", "network_settings.cells.add_proxy_bypass.caption")
+ }
+ internal enum ProxyBypass {
+ /// Bypass domain
+ internal static let caption = L10n.tr("App", "network_settings.cells.proxy_bypass.caption")
+ }
+ }
+ }
+ internal enum Organizer {
+ internal enum Cells {
+ internal enum AddHost {
+ /// Add new host
+ internal static let caption = L10n.tr("App", "organizer.cells.add_host.caption")
+ }
+ internal enum AddProvider {
+ /// Add new provider
+ internal static let caption = L10n.tr("App", "organizer.cells.add_provider.caption")
+ }
+ internal enum Profile {
+ internal enum Value {
+ /// In use
+ internal static let current = L10n.tr("App", "organizer.cells.profile.value.current")
+ }
+ }
+ }
+ }
+ internal enum Provider {
+ internal enum Preset {
+ internal enum Cells {
+ internal enum TechDetails {
+ /// Technical details
+ internal static let caption = L10n.tr("App", "provider.preset.cells.tech_details.caption")
+ }
+ }
+ }
+ }
+ internal enum Service {
+ internal enum Cells {
+ internal enum Host {
+ internal enum Parameters {
+ /// Parameters
+ internal static let caption = L10n.tr("App", "service.cells.host.parameters.caption")
+ }
+ }
+ internal enum Provider {
+ internal enum Refresh {
+ /// Refresh infrastructure
+ internal static let caption = L10n.tr("App", "service.cells.provider.refresh.caption")
+ }
+ }
+ internal enum Reconnect {
+ /// Reconnect
+ internal static let caption = L10n.tr("App", "service.cells.reconnect.caption")
+ }
+ internal enum TrustedAddWifi {
+ /// Add current Wi-Fi
+ internal static let caption = L10n.tr("App", "service.cells.trusted_add_wifi.caption")
+ }
+ internal enum UseProfile {
+ /// Use this profile
+ internal static let caption = L10n.tr("App", "service.cells.use_profile.caption")
+ }
+ internal enum VpnService {
+ /// Enabled
+ internal static let caption = L10n.tr("App", "service.cells.vpn_service.caption")
+ }
+ }
+ internal enum Sections {
+ internal enum Configuration {
+ /// Configuration
+ internal static let header = L10n.tr("App", "service.sections.configuration.header")
+ }
+ internal enum Status {
+ /// Connection
+ internal static let header = L10n.tr("App", "service.sections.status.header")
+ }
+ internal enum Vpn {
+ /// VPN
+ internal static let header = L10n.tr("App", "service.sections.vpn.header")
+ }
+ }
+ internal enum Welcome {
+ /// Welcome to Passepartout!\n\nUse the organizer to add a new profile.
+ internal static let message = L10n.tr("App", "service.welcome.message")
+ }
+ }
+ internal enum Shortcuts {
+ internal enum Add {
+ /// Add shortcut
+ internal static let title = L10n.tr("App", "shortcuts.add.title")
+ }
+ internal enum Edit {
+ /// Manage shortcuts
+ internal static let title = L10n.tr("App", "shortcuts.edit.title")
+ internal enum Cells {
+ internal enum AddShortcut {
+ /// Add shortcut
+ internal static let caption = L10n.tr("App", "shortcuts.edit.cells.add_shortcut.caption")
+ }
+ }
+ }
+ }
+ internal enum Wizards {
+ internal enum Host {
+ internal enum Cells {
+ internal enum TitleInput {
+ /// Title
+ internal static let caption = L10n.tr("App", "wizards.host.cells.title_input.caption")
+ }
+ }
+ internal enum Sections {
+ internal enum Existing {
+ /// Existing profiles
+ internal static let header = L10n.tr("App", "wizards.host.sections.existing.header")
+ }
+ }
+ }
+ }
+ }
+ internal enum Core {
+ internal enum About {
+ /// About
+ internal static let title = L10n.tr("Core", "about.title")
+ internal enum Cells {
+ internal enum Credits {
+ /// Credits
+ internal static let caption = L10n.tr("Core", "about.cells.credits.caption")
+ }
+ internal enum Disclaimer {
+ /// Disclaimer
+ internal static let caption = L10n.tr("Core", "about.cells.disclaimer.caption")
+ }
+ internal enum Faq {
+ /// FAQ
+ internal static let caption = L10n.tr("Core", "about.cells.faq.caption")
+ }
+ internal enum PrivacyPolicy {
+ /// Privacy policy
+ internal static let caption = L10n.tr("Core", "about.cells.privacy_policy.caption")
+ }
+ internal enum ShareGeneric {
+ /// Invite a friend
+ internal static let caption = L10n.tr("Core", "about.cells.share_generic.caption")
+ }
+ internal enum ShareTwitter {
+ /// Tweet about it!
+ internal static let caption = L10n.tr("Core", "about.cells.share_twitter.caption")
+ }
+ internal enum Website {
+ /// Home page
+ internal static let caption = L10n.tr("Core", "about.cells.website.caption")
+ }
+ }
+ internal enum Sections {
+ internal enum Share {
+ /// Share
+ internal static let header = L10n.tr("Core", "about.sections.share.header")
+ }
+ internal enum Web {
+ /// Web
+ internal static let header = L10n.tr("Core", "about.sections.web.header")
+ }
+ }
+ }
+ internal enum Account {
+ /// Account
+ internal static let title = L10n.tr("Core", "account.title")
+ internal enum Cells {
+ internal enum OpenGuide {
+ /// See your credentials
+ internal static let caption = L10n.tr("Core", "account.cells.open_guide.caption")
+ }
+ internal enum Password {
+ /// Password
+ internal static let caption = L10n.tr("Core", "account.cells.password.caption")
+ /// secret
+ internal static let placeholder = L10n.tr("Core", "account.cells.password.placeholder")
+ }
+ internal enum Signup {
+ /// Register with %@
+ internal static func caption(_ p1: String) -> String {
+ return L10n.tr("Core", "account.cells.signup.caption", p1)
+ }
+ }
+ internal enum Username {
+ /// Username
+ internal static let caption = L10n.tr("Core", "account.cells.username.caption")
+ /// username
+ internal static let placeholder = L10n.tr("Core", "account.cells.username.placeholder")
+ }
+ }
+ internal enum Sections {
+ internal enum Guidance {
+ internal enum Footer {
+ internal enum Infrastructure {
+ /// Use your %@ website credentials. Your username is usually numeric.
+ internal static func mullvad(_ p1: String) -> String {
+ return L10n.tr("Core", "account.sections.guidance.footer.infrastructure.mullvad", p1)
+ }
+ /// Use your %@ website credentials. Your username is usually your e-mail.
+ internal static func nordvpn(_ p1: String) -> String {
+ return L10n.tr("Core", "account.sections.guidance.footer.infrastructure.nordvpn", p1)
+ }
+ /// Use your %@ website credentials. Your username is usually numeric with a "p" prefix.
+ internal static func pia(_ p1: String) -> String {
+ return L10n.tr("Core", "account.sections.guidance.footer.infrastructure.pia", p1)
+ }
+ /// Find your %@ credentials in the "Account > OpenVPN / IKEv2 Username" section of the website.
+ internal static func protonvpn(_ p1: String) -> String {
+ return L10n.tr("Core", "account.sections.guidance.footer.infrastructure.protonvpn", p1)
+ }
+ /// Use your %@ website credentials. Your username is usually your e-mail.
+ internal static func tunnelbear(_ p1: String) -> String {
+ return L10n.tr("Core", "account.sections.guidance.footer.infrastructure.tunnelbear", p1)
+ }
+ /// Use your %@ website credentials. Your username is usually your e-mail.
+ internal static func vyprvpn(_ p1: String) -> String {
+ return L10n.tr("Core", "account.sections.guidance.footer.infrastructure.vyprvpn", p1)
+ }
+ /// Find your %@ credentials in the OpenVPN Config Generator on the website.
+ internal static func windscribe(_ p1: String) -> String {
+ return L10n.tr("Core", "account.sections.guidance.footer.infrastructure.windscribe", p1)
+ }
+ }
+ }
+ }
+ internal enum Registration {
+ /// Go get an account on the %@ website.
+ internal static func footer(_ p1: String) -> String {
+ return L10n.tr("Core", "account.sections.registration.footer", p1)
+ }
+ }
+ }
+ }
+ internal enum Configuration {
+ internal enum Cells {
+ internal enum Cipher {
+ /// Cipher
+ internal static let caption = L10n.tr("Core", "configuration.cells.cipher.caption")
+ }
+ internal enum Client {
+ /// Client certificate
+ internal static let caption = L10n.tr("Core", "configuration.cells.client.caption")
+ internal enum Value {
+ /// Not verified
+ internal static let disabled = L10n.tr("Core", "configuration.cells.client.value.disabled")
+ /// Verified
+ internal static let enabled = L10n.tr("Core", "configuration.cells.client.value.enabled")
+ }
+ }
+ internal enum CompressionAlgorithm {
+ /// Algorithm
+ internal static let caption = L10n.tr("Core", "configuration.cells.compression_algorithm.caption")
+ internal enum Value {
+ /// LZO
+ internal static let lzo = L10n.tr("Core", "configuration.cells.compression_algorithm.value.lzo")
+ /// Unsupported
+ internal static let other = L10n.tr("Core", "configuration.cells.compression_algorithm.value.other")
+ }
+ }
+ internal enum CompressionFraming {
+ /// Framing
+ internal static let caption = L10n.tr("Core", "configuration.cells.compression_framing.caption")
+ internal enum Value {
+ /// --compress
+ internal static let compress = L10n.tr("Core", "configuration.cells.compression_framing.value.compress")
+ /// --comp-lzo
+ internal static let lzo = L10n.tr("Core", "configuration.cells.compression_framing.value.lzo")
+ }
+ }
+ internal enum Digest {
+ /// Authentication
+ internal static let caption = L10n.tr("Core", "configuration.cells.digest.caption")
+ internal enum Value {
+ /// Embedded
+ internal static let embedded = L10n.tr("Core", "configuration.cells.digest.value.embedded")
+ }
+ }
+ internal enum Eku {
+ /// Extended verification
+ internal static let caption = L10n.tr("Core", "configuration.cells.eku.caption")
+ }
+ internal enum KeepAlive {
+ /// Keep-alive
+ internal static let caption = L10n.tr("Core", "configuration.cells.keep_alive.caption")
+ internal enum Value {
+ /// %d seconds
+ internal static func seconds(_ p1: Int) -> String {
+ return L10n.tr("Core", "configuration.cells.keep_alive.value.seconds", p1)
+ }
+ }
+ }
+ internal enum RandomEndpoint {
+ /// Randomize endpoint
+ internal static let caption = L10n.tr("Core", "configuration.cells.random_endpoint.caption")
+ }
+ internal enum RenegotiationSeconds {
+ /// Renegotiation
+ internal static let caption = L10n.tr("Core", "configuration.cells.renegotiation_seconds.caption")
+ internal enum Value {
+ /// after %@
+ internal static func after(_ p1: String) -> String {
+ return L10n.tr("Core", "configuration.cells.renegotiation_seconds.value.after", p1)
+ }
+ }
+ }
+ internal enum ResetOriginal {
+ /// Reset configuration
+ internal static let caption = L10n.tr("Core", "configuration.cells.reset_original.caption")
+ }
+ internal enum TlsWrapping {
+ /// Wrapping
+ internal static let caption = L10n.tr("Core", "configuration.cells.tls_wrapping.caption")
+ internal enum Value {
+ /// Authentication
+ internal static let auth = L10n.tr("Core", "configuration.cells.tls_wrapping.value.auth")
+ /// Encryption
+ internal static let crypt = L10n.tr("Core", "configuration.cells.tls_wrapping.value.crypt")
+ }
+ }
+ }
+ internal enum Sections {
+ internal enum Communication {
+ /// Communication
+ internal static let header = L10n.tr("Core", "configuration.sections.communication.header")
+ }
+ internal enum Compression {
+ /// Compression
+ internal static let header = L10n.tr("Core", "configuration.sections.compression.header")
+ }
+ internal enum Network {
+ /// Network
+ internal static let header = L10n.tr("Core", "configuration.sections.network.header")
+ }
+ internal enum Other {
+ /// Other
+ internal static let header = L10n.tr("Core", "configuration.sections.other.header")
+ }
+ internal enum Reset {
+ /// If you ended up with broken connectivity after changing the communication parameters, tap to revert to the original configuration.
+ internal static let footer = L10n.tr("Core", "configuration.sections.reset.footer")
+ }
+ internal enum Tls {
+ /// TLS
+ internal static let header = L10n.tr("Core", "configuration.sections.tls.header")
+ }
+ }
+ }
+ internal enum Credits {
+ /// Credits
+ internal static let title = L10n.tr("Core", "credits.title")
+ internal enum Sections {
+ internal enum Licenses {
+ /// Licenses
+ internal static let header = L10n.tr("Core", "credits.sections.licenses.header")
+ }
+ internal enum Notices {
+ /// Notices
+ internal static let header = L10n.tr("Core", "credits.sections.notices.header")
+ }
+ internal enum Translations {
+ /// Translations
+ internal static let header = L10n.tr("Core", "credits.sections.translations.header")
+ }
+ }
+ }
+ internal enum DebugLog {
+ internal enum Alerts {
+ internal enum EmptyLog {
+ /// The debug log is empty.
+ internal static let message = L10n.tr("Core", "debug_log.alerts.empty_log.message")
+ }
+ }
+ internal enum Buttons {
+ /// Next
+ internal static let next = L10n.tr("Core", "debug_log.buttons.next")
+ /// Previous
+ internal static let previous = L10n.tr("Core", "debug_log.buttons.previous")
+ }
+ }
+ internal enum Donation {
+ /// Donate
+ internal static let title = L10n.tr("Core", "donation.title")
+ internal enum Alerts {
+ internal enum Purchase {
+ internal enum Failure {
+ /// Unable to perform the donation. %@
+ internal static func message(_ p1: String) -> String {
+ return L10n.tr("Core", "donation.alerts.purchase.failure.message", p1)
+ }
+ }
+ internal enum Success {
+ /// This means a lot to me and I really hope you keep using and promoting this app.
+ internal static let message = L10n.tr("Core", "donation.alerts.purchase.success.message")
+ /// Thank you
+ internal static let title = L10n.tr("Core", "donation.alerts.purchase.success.title")
+ }
+ }
+ }
+ internal enum Cells {
+ internal enum Loading {
+ /// Loading donations
+ internal static let caption = L10n.tr("Core", "donation.cells.loading.caption")
+ }
+ internal enum Purchasing {
+ /// Performing donation
+ internal static let caption = L10n.tr("Core", "donation.cells.purchasing.caption")
+ }
+ }
+ internal enum Sections {
+ internal 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.
+ internal static let footer = L10n.tr("Core", "donation.sections.one_time.footer")
+ /// One time
+ internal static let header = L10n.tr("Core", "donation.sections.one_time.header")
+ }
+ }
+ }
+ internal enum Endpoint {
+ /// Endpoint
+ internal static let title = L10n.tr("Core", "endpoint.title")
+ internal enum Cells {
+ internal enum AnyAddress {
+ /// Automatic
+ internal static let caption = L10n.tr("Core", "endpoint.cells.any_address.caption")
+ }
+ internal enum AnyProtocol {
+ /// Automatic
+ internal static let caption = L10n.tr("Core", "endpoint.cells.any_protocol.caption")
+ }
+ }
+ }
+ internal enum Global {
+ /// Cancel
+ internal static let cancel = L10n.tr("Core", "global.cancel")
+ /// Close
+ internal static let close = L10n.tr("Core", "global.close")
+ /// No e-mail account is configured.
+ internal static let emailNotConfigured = L10n.tr("Core", "global.email_not_configured")
+ /// Next
+ internal static let next = L10n.tr("Core", "global.next")
+ /// OK
+ internal static let ok = L10n.tr("Core", "global.ok")
+ internal enum Captions {
+ /// Address
+ internal static let address = L10n.tr("Core", "global.captions.address")
+ /// Port
+ internal static let port = L10n.tr("Core", "global.captions.port")
+ }
+ internal enum Host {
+ internal enum TitleInput {
+ /// Acceptable characters are alphanumerics plus dash "-", underscore "_" and dot ".".
+ internal static let message = L10n.tr("Core", "global.host.title_input.message")
+ /// My profile
+ internal static let placeholder = L10n.tr("Core", "global.host.title_input.placeholder")
+ }
+ }
+ internal enum Values {
+ /// Automatic
+ internal static let automatic = L10n.tr("Core", "global.values.automatic")
+ /// Disabled
+ internal static let disabled = L10n.tr("Core", "global.values.disabled")
+ /// Enabled
+ internal static let enabled = L10n.tr("Core", "global.values.enabled")
+ /// Manual
+ internal static let manual = L10n.tr("Core", "global.values.manual")
+ /// None
+ internal static let `none` = L10n.tr("Core", "global.values.none")
+ }
+ }
+ internal 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.
+ internal static let message = L10n.tr("Core", "issue_reporter.message")
+ /// Report issue
+ internal static let title = L10n.tr("Core", "issue_reporter.title")
+ internal enum Buttons {
+ /// I understand
+ internal static let accept = L10n.tr("Core", "issue_reporter.buttons.accept")
+ }
+ }
+ internal enum Label {
+ internal enum License {
+ /// Unable to download full license content.
+ internal static let error = L10n.tr("Core", "label.license.error")
+ }
+ }
+ internal enum NetworkChoice {
+ /// Read .ovpn
+ internal static let client = L10n.tr("Core", "network_choice.client")
+ /// Pull from server
+ internal static let server = L10n.tr("Core", "network_choice.server")
+ }
+ internal enum NetworkSettings {
+ /// Network settings
+ internal static let title = L10n.tr("Core", "network_settings.title")
+ internal enum Dns {
+ /// DNS
+ internal static let title = L10n.tr("Core", "network_settings.dns.title")
+ internal enum Cells {
+ internal enum Domain {
+ /// Domain
+ internal static let caption = L10n.tr("Core", "network_settings.dns.cells.domain.caption")
+ }
+ }
+ }
+ internal enum Gateway {
+ /// Default gateway
+ internal static let title = L10n.tr("Core", "network_settings.gateway.title")
+ }
+ internal enum Proxy {
+ /// Proxy
+ internal static let title = L10n.tr("Core", "network_settings.proxy.title")
+ }
+ }
+ internal enum Organizer {
+ internal enum Alerts {
+ internal 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.
+ internal static let message = L10n.tr("Core", "organizer.alerts.add_host.message")
+ }
+ internal enum CannotDonate {
+ /// There is no payment method configured on this device.
+ internal static let message = L10n.tr("Core", "organizer.alerts.cannot_donate.message")
+ }
+ internal 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.
+ internal static let message = L10n.tr("Core", "organizer.alerts.delete_vpn_profile.message")
+ }
+ internal enum ExhaustedProviders {
+ /// You have created profiles for any available provider.
+ internal static let message = L10n.tr("Core", "organizer.alerts.exhausted_providers.message")
+ }
+ }
+ internal enum Cells {
+ internal enum About {
+ /// About %@
+ internal static func caption(_ p1: String) -> String {
+ return L10n.tr("Core", "organizer.cells.about.caption", p1)
+ }
+ }
+ internal enum Donate {
+ /// Make a donation
+ internal static let caption = L10n.tr("Core", "organizer.cells.donate.caption")
+ }
+ internal enum JoinCommunity {
+ /// Join community
+ internal static let caption = L10n.tr("Core", "organizer.cells.join_community.caption")
+ }
+ internal enum Patreon {
+ /// Support me on Patreon
+ internal static let caption = L10n.tr("Core", "organizer.cells.patreon.caption")
+ }
+ internal enum SiriShortcuts {
+ /// Manage shortcuts
+ internal static let caption = L10n.tr("Core", "organizer.cells.siri_shortcuts.caption")
+ }
+ internal enum Translate {
+ /// Offer to translate
+ internal static let caption = L10n.tr("Core", "organizer.cells.translate.caption")
+ }
+ internal enum Uninstall {
+ /// Remove VPN configuration
+ internal static let caption = L10n.tr("Core", "organizer.cells.uninstall.caption")
+ }
+ internal enum WriteReview {
+ /// Write a review
+ internal static let caption = L10n.tr("Core", "organizer.cells.write_review.caption")
+ }
+ }
+ internal enum Sections {
+ internal enum Feedback {
+ /// Feedback
+ internal static let header = L10n.tr("Core", "organizer.sections.feedback.header")
+ }
+ internal enum Hosts {
+ /// Import hosts from raw .ovpn configuration files.
+ internal static let footer = L10n.tr("Core", "organizer.sections.hosts.footer")
+ /// Hosts
+ internal static let header = L10n.tr("Core", "organizer.sections.hosts.header")
+ }
+ internal enum Providers {
+ /// Here you find a few providers with preset configuration profiles.
+ internal static let footer = L10n.tr("Core", "organizer.sections.providers.footer")
+ /// Providers
+ internal static let header = L10n.tr("Core", "organizer.sections.providers.header")
+ }
+ internal enum Siri {
+ /// Get help from Siri to speed up your most common interactions with the app.
+ internal static let footer = L10n.tr("Core", "organizer.sections.siri.footer")
+ /// Siri
+ internal static let header = L10n.tr("Core", "organizer.sections.siri.header")
+ }
+ internal enum Support {
+ /// Support
+ internal static let header = L10n.tr("Core", "organizer.sections.support.header")
+ }
+ }
+ }
+ internal enum ParsedFile {
+ internal enum Alerts {
+ internal enum Buttons {
+ /// Report an issue
+ internal static let report = L10n.tr("Core", "parsed_file.alerts.buttons.report")
+ }
+ internal enum Decryption {
+ /// The configuration contains an encrypted private key and it could not be decrypted. Double check your entered passphrase.
+ internal static let message = L10n.tr("Core", "parsed_file.alerts.decryption.message")
+ }
+ internal enum EncryptionPassphrase {
+ /// Please enter the encryption passphrase.
+ internal static let message = L10n.tr("Core", "parsed_file.alerts.encryption_passphrase.message")
+ }
+ internal enum Malformed {
+ /// The configuration file contains a malformed option (%@).
+ internal static func message(_ p1: String) -> String {
+ return L10n.tr("Core", "parsed_file.alerts.malformed.message", p1)
+ }
+ }
+ internal enum Missing {
+ /// The configuration file lacks a required option (%@).
+ internal static func message(_ p1: String) -> String {
+ return L10n.tr("Core", "parsed_file.alerts.missing.message", p1)
+ }
+ }
+ internal enum Parsing {
+ /// Unable to parse the provided configuration file (%@).
+ internal static func message(_ p1: String) -> String {
+ return L10n.tr("Core", "parsed_file.alerts.parsing.message", p1)
+ }
+ }
+ internal enum PotentiallyUnsupported {
+ /// The configuration file is correct but contains a potentially unsupported option (%@).\n\nConnectivity may break depending on server settings.
+ internal static func message(_ p1: String) -> String {
+ return L10n.tr("Core", "parsed_file.alerts.potentially_unsupported.message", p1)
+ }
+ }
+ internal enum Unsupported {
+ /// The configuration file contains an unsupported option (%@).
+ internal static func message(_ p1: String) -> String {
+ return L10n.tr("Core", "parsed_file.alerts.unsupported.message", p1)
+ }
+ }
+ }
+ }
+ internal 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.
+ internal static let message = L10n.tr("Core", "reddit.message")
+ /// Reddit
+ internal static let title = L10n.tr("Core", "reddit.title")
+ internal enum Buttons {
+ /// Don't ask again
+ internal static let never = L10n.tr("Core", "reddit.buttons.never")
+ /// Remind me later
+ internal static let remind = L10n.tr("Core", "reddit.buttons.remind")
+ /// Subscribe now!
+ internal static let subscribe = L10n.tr("Core", "reddit.buttons.subscribe")
+ }
+ }
+ internal enum Service {
+ internal enum Alerts {
+ internal enum Buttons {
+ /// Reconnect
+ internal static let reconnect = L10n.tr("Core", "service.alerts.buttons.reconnect")
+ }
+ internal enum CredentialsNeeded {
+ /// You need to enter account credentials first.
+ internal static let message = L10n.tr("Core", "service.alerts.credentials_needed.message")
+ }
+ internal enum Download {
+ /// Failed to download configuration files. %@
+ internal static func failed(_ p1: String) -> String {
+ return L10n.tr("Core", "service.alerts.download.failed", p1)
+ }
+ /// %@ requires the download of additional configuration files.\n\nConfirm to start the download.
+ internal static func message(_ p1: String) -> String {
+ return L10n.tr("Core", "service.alerts.download.message", p1)
+ }
+ /// Download required
+ internal static let title = L10n.tr("Core", "service.alerts.download.title")
+ internal enum Hud {
+ /// Extracting files, please be patient...
+ internal static let extracting = L10n.tr("Core", "service.alerts.download.hud.extracting")
+ }
+ }
+ internal enum MasksPrivateData {
+ internal enum Messages {
+ /// In order to safely reset the current debug log and apply the new masking preference, you must reconnect to the VPN now.
+ internal static let mustReconnect = L10n.tr("Core", "service.alerts.masks_private_data.messages.must_reconnect")
+ }
+ }
+ internal enum ReconnectVpn {
+ /// Do you want to reconnect to the VPN?
+ internal static let message = L10n.tr("Core", "service.alerts.reconnect_vpn.message")
+ }
+ internal enum Rename {
+ /// Rename profile
+ internal static let title = L10n.tr("Core", "service.alerts.rename.title")
+ }
+ internal enum TestConnectivity {
+ /// Connectivity
+ internal static let title = L10n.tr("Core", "service.alerts.test_connectivity.title")
+ internal enum Messages {
+ /// Your device has no Internet connectivity, please review your profile parameters.
+ internal static let failure = L10n.tr("Core", "service.alerts.test_connectivity.messages.failure")
+ /// Your device is connected to the Internet!
+ internal static let success = L10n.tr("Core", "service.alerts.test_connectivity.messages.success")
+ }
+ }
+ internal enum Trusted {
+ internal enum NoNetwork {
+ /// You are not connected to any Wi-Fi network.
+ internal static let message = L10n.tr("Core", "service.alerts.trusted.no_network.message")
+ }
+ internal enum WillDisconnectPolicy {
+ /// By changing the trust policy, the VPN may be disconnected. Continue?
+ internal static let message = L10n.tr("Core", "service.alerts.trusted.will_disconnect_policy.message")
+ }
+ internal enum WillDisconnectTrusted {
+ /// By trusting this network, the VPN may be disconnected. Continue?
+ internal static let message = L10n.tr("Core", "service.alerts.trusted.will_disconnect_trusted.message")
+ }
+ }
+ }
+ internal enum Cells {
+ internal enum ConnectionStatus {
+ /// Status
+ internal static let caption = L10n.tr("Core", "service.cells.connection_status.caption")
+ }
+ internal enum DataCount {
+ /// Exchanged data
+ internal static let caption = L10n.tr("Core", "service.cells.data_count.caption")
+ /// Unavailable
+ internal static let `none` = L10n.tr("Core", "service.cells.data_count.none")
+ }
+ internal enum DebugLog {
+ /// Debug log
+ internal static let caption = L10n.tr("Core", "service.cells.debug_log.caption")
+ }
+ internal enum MasksPrivateData {
+ /// Mask network data
+ internal static let caption = L10n.tr("Core", "service.cells.masks_private_data.caption")
+ }
+ internal enum Provider {
+ internal enum Pool {
+ /// Location
+ internal static let caption = L10n.tr("Core", "service.cells.provider.pool.caption")
+ }
+ internal enum Preset {
+ /// Preset
+ internal static let caption = L10n.tr("Core", "service.cells.provider.preset.caption")
+ }
+ }
+ internal enum ReportIssue {
+ /// Report connectivity issue
+ internal static let caption = L10n.tr("Core", "service.cells.report_issue.caption")
+ }
+ internal enum TestConnectivity {
+ /// Test connectivity
+ internal static let caption = L10n.tr("Core", "service.cells.test_connectivity.caption")
+ }
+ internal enum TrustedMobile {
+ /// Cellular network
+ internal static let caption = L10n.tr("Core", "service.cells.trusted_mobile.caption")
+ }
+ internal enum TrustedPolicy {
+ /// Trust disables VPN
+ internal static let caption = L10n.tr("Core", "service.cells.trusted_policy.caption")
+ }
+ internal enum VpnResolvesHostname {
+ /// Resolve server hostname
+ internal static let caption = L10n.tr("Core", "service.cells.vpn_resolves_hostname.caption")
+ }
+ internal enum VpnSurvivesSleep {
+ /// Keep alive on sleep
+ internal static let caption = L10n.tr("Core", "service.cells.vpn_survives_sleep.caption")
+ }
+ }
+ internal enum Sections {
+ internal 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.
+ internal static let footer = L10n.tr("Core", "service.sections.diagnostics.footer")
+ /// Diagnostics
+ internal static let header = L10n.tr("Core", "service.sections.diagnostics.header")
+ }
+ internal enum ProviderInfrastructure {
+ /// Last updated on %@.
+ internal static func footer(_ p1: String) -> String {
+ return L10n.tr("Core", "service.sections.provider_infrastructure.footer", p1)
+ }
+ }
+ internal enum Trusted {
+ /// When entering a trusted network, the VPN is normally shut down and kept disconnected. Disable this option to not enforce such behavior.
+ internal static let footer = L10n.tr("Core", "service.sections.trusted.footer")
+ /// Trusted networks
+ internal static let header = L10n.tr("Core", "service.sections.trusted.header")
+ }
+ internal enum Vpn {
+ /// The connection will be established whenever necessary.
+ internal static let footer = L10n.tr("Core", "service.sections.vpn.footer")
+ }
+ internal 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.
+ internal static let footer = L10n.tr("Core", "service.sections.vpn_resolves_hostname.footer")
+ }
+ internal enum VpnSurvivesSleep {
+ /// Disable to improve battery usage, at the expense of occasional slowdowns due to wake-up reconnections.
+ internal static let footer = L10n.tr("Core", "service.sections.vpn_survives_sleep.footer")
+ }
+ }
+ }
+ internal enum Share {
+ /// Passepartout is an user-friendly, open source OpenVPN client for iOS and macOS
+ internal static let message = L10n.tr("Core", "share.message")
+ }
+ internal enum Shortcuts {
+ internal enum Add {
+ internal enum Alerts {
+ internal enum NoProfiles {
+ /// There is no profile to connect to.
+ internal static let message = L10n.tr("Core", "shortcuts.add.alerts.no_profiles.message")
+ }
+ }
+ internal enum Cells {
+ internal enum Connect {
+ /// Connect to
+ internal static let caption = L10n.tr("Core", "shortcuts.add.cells.connect.caption")
+ }
+ internal enum DisableVpn {
+ /// Disable VPN
+ internal static let caption = L10n.tr("Core", "shortcuts.add.cells.disable_vpn.caption")
+ }
+ internal enum EnableVpn {
+ /// Enable VPN
+ internal static let caption = L10n.tr("Core", "shortcuts.add.cells.enable_vpn.caption")
+ }
+ internal enum TrustCellular {
+ /// Trust cellular network
+ internal static let caption = L10n.tr("Core", "shortcuts.add.cells.trust_cellular.caption")
+ }
+ internal enum TrustCurrentWifi {
+ /// Trust current Wi-Fi
+ internal static let caption = L10n.tr("Core", "shortcuts.add.cells.trust_current_wifi.caption")
+ }
+ internal enum UntrustCellular {
+ /// Untrust cellular network
+ internal static let caption = L10n.tr("Core", "shortcuts.add.cells.untrust_cellular.caption")
+ }
+ internal enum UntrustCurrentWifi {
+ /// Untrust current Wi-Fi
+ internal static let caption = L10n.tr("Core", "shortcuts.add.cells.untrust_current_wifi.caption")
+ }
+ }
+ internal enum Sections {
+ internal enum Cellular {
+ /// Cellular
+ internal static let header = L10n.tr("Core", "shortcuts.add.sections.cellular.header")
+ }
+ internal enum Vpn {
+ /// VPN
+ internal static let header = L10n.tr("Core", "shortcuts.add.sections.vpn.header")
+ }
+ internal enum Wifi {
+ /// Wi-Fi
+ internal static let header = L10n.tr("Core", "shortcuts.add.sections.wifi.header")
+ }
+ }
+ }
+ internal enum Edit {
+ internal enum Sections {
+ internal enum All {
+ /// Existing shortcuts
+ internal static let header = L10n.tr("Core", "shortcuts.edit.sections.all.header")
+ }
+ }
+ }
+ }
+ internal enum Translations {
+ /// Translations
+ internal static let title = L10n.tr("Core", "translations.title")
+ }
+ internal enum Version {
+ /// Version
+ internal static let title = L10n.tr("Core", "version.title")
+ internal 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.
+ internal static let intro = L10n.tr("Core", "version.labels.intro")
+ }
+ }
+ internal enum Vpn {
+ /// Active
+ internal static let active = L10n.tr("Core", "vpn.active")
+ /// Connecting
+ internal static let connecting = L10n.tr("Core", "vpn.connecting")
+ /// Disabled
+ internal static let disabled = L10n.tr("Core", "vpn.disabled")
+ /// Disconnecting
+ internal static let disconnecting = L10n.tr("Core", "vpn.disconnecting")
+ /// Inactive
+ internal static let inactive = L10n.tr("Core", "vpn.inactive")
+ internal enum Errors {
+ /// Auth failed
+ internal static let auth = L10n.tr("Core", "vpn.errors.auth")
+ /// Compression unsupported
+ internal static let compression = L10n.tr("Core", "vpn.errors.compression")
+ /// DNS failed
+ internal static let dns = L10n.tr("Core", "vpn.errors.dns")
+ /// Encryption failed
+ internal static let encryption = L10n.tr("Core", "vpn.errors.encryption")
+ /// No gateway
+ internal static let gateway = L10n.tr("Core", "vpn.errors.gateway")
+ /// Network changed
+ internal static let network = L10n.tr("Core", "vpn.errors.network")
+ /// Missing routing
+ internal static let routing = L10n.tr("Core", "vpn.errors.routing")
+ /// Timeout
+ internal static let timeout = L10n.tr("Core", "vpn.errors.timeout")
+ /// TLS failed
+ internal static let tls = L10n.tr("Core", "vpn.errors.tls")
+ }
+ }
+ internal enum Wizards {
+ internal enum Host {
+ internal enum Alerts {
+ internal enum Existing {
+ /// A host profile with the same title already exists. Replace it?
+ internal static let message = L10n.tr("Core", "wizards.host.alerts.existing.message")
+ }
+ }
+ }
+ }
+ }
+}
+// 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-iOS/Global/Theme+Cells.swift b/Passepartout-iOS/Global/Theme+Cells.swift
index ef0e3d0f..f883803f 100644
--- a/Passepartout-iOS/Global/Theme+Cells.swift
+++ b/Passepartout-iOS/Global/Theme+Cells.swift
@@ -78,18 +78,18 @@ extension SettingTableViewCell {
func applyVPN(_ theme: Theme, with vpnStatus: VPNStatus?, error: OpenVPNTunnelProvider.ProviderError?) {
leftTextColor = theme.palette.primaryText
guard let vpnStatus = vpnStatus else {
- rightText = L10n.Vpn.disabled
+ rightText = L10n.Core.Vpn.disabled
rightTextColor = theme.palette.secondaryText
return
}
switch vpnStatus {
case .connecting:
- rightText = L10n.Vpn.connecting
+ rightText = L10n.Core.Vpn.connecting
rightTextColor = theme.palette.indeterminate
case .connected:
- rightText = L10n.Vpn.active
+ rightText = L10n.Core.Vpn.active
rightTextColor = theme.palette.on
case .disconnecting, .disconnected:
@@ -97,31 +97,31 @@ extension SettingTableViewCell {
if let error = error {
switch error {
case .socketActivity, .timeout:
- disconnectionReason = L10n.Vpn.Errors.timeout
+ disconnectionReason = L10n.Core.Vpn.Errors.timeout
case .dnsFailure:
- disconnectionReason = L10n.Vpn.Errors.dns
+ disconnectionReason = L10n.Core.Vpn.Errors.dns
case .tlsInitialization, .tlsServerVerification, .tlsHandshake:
- disconnectionReason = L10n.Vpn.Errors.tls
+ disconnectionReason = L10n.Core.Vpn.Errors.tls
case .authentication:
- disconnectionReason = L10n.Vpn.Errors.auth
+ disconnectionReason = L10n.Core.Vpn.Errors.auth
case .encryptionInitialization, .encryptionData:
- disconnectionReason = L10n.Vpn.Errors.encryption
+ disconnectionReason = L10n.Core.Vpn.Errors.encryption
case .serverCompression:
- disconnectionReason = L10n.Vpn.Errors.compression
+ disconnectionReason = L10n.Core.Vpn.Errors.compression
case .networkChanged:
- disconnectionReason = L10n.Vpn.Errors.network
+ disconnectionReason = L10n.Core.Vpn.Errors.network
case .routing:
- disconnectionReason = L10n.Vpn.Errors.routing
+ disconnectionReason = L10n.Core.Vpn.Errors.routing
case .gatewayUnattainable:
- disconnectionReason = L10n.Vpn.Errors.gateway
+ disconnectionReason = L10n.Core.Vpn.Errors.gateway
default:
break
@@ -129,11 +129,11 @@ extension SettingTableViewCell {
}
switch vpnStatus {
case .disconnecting:
- rightText = disconnectionReason ?? L10n.Vpn.disconnecting
+ rightText = disconnectionReason ?? L10n.Core.Vpn.disconnecting
rightTextColor = theme.palette.indeterminate
case .disconnected:
- rightText = disconnectionReason ?? L10n.Vpn.inactive
+ rightText = disconnectionReason ?? L10n.Core.Vpn.inactive
rightTextColor = theme.palette.off
default:
diff --git a/Passepartout-iOS/Global/Theme.swift b/Passepartout-iOS/Global/Theme.swift
index c6fa2826..4d647c45 100644
--- a/Passepartout-iOS/Global/Theme.swift
+++ b/Passepartout-iOS/Global/Theme.swift
@@ -135,7 +135,7 @@ extension UIButton {
extension UITextField {
func applyProfileId(_ theme: Theme) {
- placeholder = L10n.Global.Host.TitleInput.placeholder
+ placeholder = L10n.Core.Global.Host.TitleInput.placeholder
clearButtonMode = .always
keyboardType = .asciiCapable
returnKeyType = .done
diff --git a/Passepartout-iOS/Global/de.lproj/App.strings b/Passepartout-iOS/Global/de.lproj/App.strings
new file mode 100644
index 00000000..02cbbea7
--- /dev/null
+++ b/Passepartout-iOS/Global/de.lproj/App.strings
@@ -0,0 +1,61 @@
+//
+// App.strings
+// Passepartout-iOS
+//
+// 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 .
+//
+
+"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";
+
+"wizards.host.cells.title_input.caption" = "Titel";
+"wizards.host.sections.existing.header" = "Bestehende Profile";
+
+"imported_hosts.title" = "Importierte Hosts";
+
+"service.welcome.message" = "Willkommen bei Passepartout!\n\nBenutze den Organizer um ein neues Profil hinzuzufügen.";
+"service.sections.vpn.header" = "VPN";
+"service.sections.status.header" = "Verbindung";
+"service.sections.configuration.header" = "Konfiguration";
+
+"service.cells.use_profile.caption" = "Dieses Profil verwenden";
+"service.cells.vpn_service.caption" = "Aktiviert";
+"service.cells.reconnect.caption" = "Erneut verbinden";
+"service.cells.provider.refresh.caption" = "Infrastruktur neu laden";
+"service.cells.host.parameters.caption" = "Parameter";
+"service.cells.trusted_add_wifi.caption" = "Aktuelles WLAN hinzufügen";
+
+"account.sections.credentials.header" = "Zugangsdaten";
+
+"endpoint.sections.location_addresses.header" = "Adressen";
+"endpoint.sections.location_protocols.header" = "Protokolle";
+
+"provider.preset.cells.tech_details.caption" = "Technische Details";
+
+"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";
+
+"shortcuts.add.title" = "Füge Kurzbefehl hinzu";
+
+"shortcuts.edit.title" = "Kurzbefehle bearbeiten";
+"shortcuts.edit.cells.add_shortcut.caption" = "Kurzbefehl hinzufügen";
diff --git a/Passepartout-iOS/Global/el.lproj/App.strings b/Passepartout-iOS/Global/el.lproj/App.strings
new file mode 100644
index 00000000..0dd8e0c8
--- /dev/null
+++ b/Passepartout-iOS/Global/el.lproj/App.strings
@@ -0,0 +1,61 @@
+//
+// App.strings
+// Passepartout-iOS
+//
+// 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 .
+//
+
+"organizer.cells.profile.value.current" = "Σε χρήση";
+"organizer.cells.add_provider.caption" = "Προσθήκη νέου παρόχου";
+"organizer.cells.add_host.caption" = "Προσθήκη νέου διακομιστή";
+
+"wizards.host.cells.title_input.caption" = "Τίτλος";
+"wizards.host.sections.existing.header" = "Υπάρχον Προφίλ";
+
+"imported_hosts.title" = "Εισαγόμενοι διακομιστές";
+
+"service.welcome.message" = "Καλώς Ήλθατε στο Passepartout!\n\nΧρησιμοποιήστε τον διοργανωτή για να προσθέσετε ένα νέο προφίλ.";
+"service.sections.vpn.header" = "VPN";
+"service.sections.status.header" = "Σύνδεση";
+"service.sections.configuration.header" = "Ρύθμιση";
+
+"service.cells.use_profile.caption" = "Χρησιμοποιήστε αυτό το προφίλ";
+"service.cells.vpn_service.caption" = "Ενεργοποιήθηκε";
+"service.cells.reconnect.caption" = "Επανασύνδεση";
+"service.cells.provider.refresh.caption" = "Ανανέωση της υποδομής";
+"service.cells.host.parameters.caption" = "Παράμετροι";
+"service.cells.trusted_add_wifi.caption" = "Προσθέστε το τρέχον Wi-Fi";
+
+"account.sections.credentials.header" = "Διαπιστευτήρια";
+
+"endpoint.sections.location_addresses.header" = "Διεθύνσεις";
+"endpoint.sections.location_protocols.header" = "Πρωτόκολλα";
+
+"provider.preset.cells.tech_details.caption" = "Τεχνικές Λεπτομέρειες";
+
+"network_settings.cells.add_dns_server.caption" = "Προσθήκη Διεύθυνσης";
+"network_settings.cells.proxy_bypass.caption" = "Παράκαμψη Τομέα";
+"network_settings.cells.add_proxy_bypass.caption" = "Προσθήκη τομέα παράκαμψης";
+
+"shortcuts.add.title" = "Προσθήκη Συντόμευσης";
+
+"shortcuts.edit.title" = "Διαχείριση συντομεύσεων";
+"shortcuts.edit.cells.add_shortcut.caption" = "Προσθήκη Συντόμευσης";
diff --git a/Passepartout-iOS/Global/en.lproj/App.strings b/Passepartout-iOS/Global/en.lproj/App.strings
new file mode 100644
index 00000000..c693fa02
--- /dev/null
+++ b/Passepartout-iOS/Global/en.lproj/App.strings
@@ -0,0 +1,61 @@
+//
+// App.strings
+// Passepartout-iOS
+//
+// Created by Davide De Rosa on 6/21/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 .
+//
+
+"organizer.cells.profile.value.current" = "In use";
+"organizer.cells.add_provider.caption" = "Add new provider";
+"organizer.cells.add_host.caption" = "Add new host";
+
+"wizards.host.cells.title_input.caption" = "Title";
+"wizards.host.sections.existing.header" = "Existing profiles";
+
+"imported_hosts.title" = "Imported hosts";
+
+"service.welcome.message" = "Welcome to Passepartout!\n\nUse the organizer to add a new profile.";
+"service.sections.vpn.header" = "VPN";
+"service.sections.status.header" = "Connection";
+"service.sections.configuration.header" = "Configuration";
+
+"service.cells.use_profile.caption" = "Use this profile";
+"service.cells.vpn_service.caption" = "Enabled";
+"service.cells.reconnect.caption" = "Reconnect";
+"service.cells.provider.refresh.caption" = "Refresh infrastructure";
+"service.cells.host.parameters.caption" = "Parameters";
+"service.cells.trusted_add_wifi.caption" = "Add current Wi-Fi";
+
+"account.sections.credentials.header" = "Credentials";
+
+"endpoint.sections.location_addresses.header" = "Addresses";
+"endpoint.sections.location_protocols.header" = "Protocols";
+
+"provider.preset.cells.tech_details.caption" = "Technical details";
+
+"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";
+
+"shortcuts.add.title" = "Add shortcut";
+
+"shortcuts.edit.title" = "Manage shortcuts";
+"shortcuts.edit.cells.add_shortcut.caption" = "Add shortcut";
diff --git a/Passepartout-iOS/Global/es.lproj/App.strings b/Passepartout-iOS/Global/es.lproj/App.strings
new file mode 100644
index 00000000..ee8b59cc
--- /dev/null
+++ b/Passepartout-iOS/Global/es.lproj/App.strings
@@ -0,0 +1,61 @@
+//
+// App.strings
+// Passepartout-iOS
+//
+// 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 .
+//
+
+"organizer.cells.profile.value.current" = "En uso";
+"organizer.cells.add_provider.caption" = "Añadir proveedor";
+"organizer.cells.add_host.caption" = "Añadir host";
+
+"wizards.host.cells.title_input.caption" = "Título";
+"wizards.host.sections.existing.header" = "Perfiles existentes";
+
+"imported_hosts.title" = "Hosts importados";
+
+"service.welcome.message" = "Bienvenid@ a Passepartout!\n\nUsa el organizador para añadir un nuevo perfil.";
+"service.sections.vpn.header" = "VPN";
+"service.sections.status.header" = "Conexión";
+"service.sections.configuration.header" = "Configuración";
+
+"service.cells.use_profile.caption" = "Usar este perfil";
+"service.cells.vpn_service.caption" = "Habilitado";
+"service.cells.reconnect.caption" = "Reconectar";
+"service.cells.provider.refresh.caption" = "Refrescar infraestructura";
+"service.cells.host.parameters.caption" = "Parámetros";
+"service.cells.trusted_add_wifi.caption" = "Añadir Wi-Fi en uso";
+
+"account.sections.credentials.header" = "Credenciales";
+
+"endpoint.sections.location_addresses.header" = "Direcciones";
+"endpoint.sections.location_protocols.header" = "Protocolos";
+
+"provider.preset.cells.tech_details.caption" = "Detalles técnicos";
+
+"network_settings.cells.add_dns_server.caption" = "Añadir dirección";
+"network_settings.cells.proxy_bypass.caption" = "Dominio ignorado";
+"network_settings.cells.add_proxy_bypass.caption" = "Añadir dominio ignorado";
+
+"shortcuts.add.title" = "Añadir atajo";
+
+"shortcuts.edit.title" = "Gestionar atajos";
+"shortcuts.edit.cells.add_shortcut.caption" = "Añadir atajo";
diff --git a/Passepartout-iOS/Global/fr.lproj/App.strings b/Passepartout-iOS/Global/fr.lproj/App.strings
new file mode 100644
index 00000000..06555b83
--- /dev/null
+++ b/Passepartout-iOS/Global/fr.lproj/App.strings
@@ -0,0 +1,61 @@
+//
+// App.strings
+// Passepartout-iOS
+//
+// 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 .
+//
+
+"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";
+
+"wizards.host.cells.title_input.caption" = "Titre";
+"wizards.host.sections.existing.header" = "Profiles existants";
+
+"imported_hosts.title" = "Hôtes importés";
+
+"service.welcome.message" = "Bienvenue à Passepartout!\n\nUtilisez l'organiseur pour ajouter un nouveau profile.";
+"service.sections.vpn.header" = "VPN";
+"service.sections.status.header" = "Connection";
+"service.sections.configuration.header" = "Configuration";
+
+"service.cells.use_profile.caption" = "Utiliser ce profile";
+"service.cells.vpn_service.caption" = "Activer";
+"service.cells.reconnect.caption" = "Reconnecter";
+"service.cells.provider.refresh.caption" = "Rafraîchir l'infrastructure";
+"service.cells.host.parameters.caption" = "Paramètres";
+"service.cells.trusted_add_wifi.caption" = "Ajouter le présent Wi-Fi";
+
+"account.sections.credentials.header" = "Indetifiants";
+
+"endpoint.sections.location_addresses.header" = "Adresses";
+"endpoint.sections.location_protocols.header" = "Protocols";
+
+"provider.preset.cells.tech_details.caption" = "Détails techniques";
+
+"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";
+
+"shortcuts.add.title" = "Ajouter un raccourcis";
+
+"shortcuts.edit.title" = "Gérer les raccourcis";
+"shortcuts.edit.cells.add_shortcut.caption" = "Ajouter un raccourcis";
diff --git a/Passepartout-iOS/Global/it.lproj/App.strings b/Passepartout-iOS/Global/it.lproj/App.strings
new file mode 100644
index 00000000..b8ed51dd
--- /dev/null
+++ b/Passepartout-iOS/Global/it.lproj/App.strings
@@ -0,0 +1,61 @@
+//
+// App.strings
+// Passepartout-iOS
+//
+// 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 .
+//
+
+"organizer.cells.profile.value.current" = "In uso";
+"organizer.cells.add_provider.caption" = "Aggiungi provider";
+"organizer.cells.add_host.caption" = "Aggiungi host";
+
+"wizards.host.cells.title_input.caption" = "Titolo";
+"wizards.host.sections.existing.header" = "Profili esistenti";
+
+"imported_hosts.title" = "Host importati";
+
+"service.welcome.message" = "Benvenuto in Passepartout!\n\nUsa il menu per aggiungere un nuovo profilo.";
+"service.sections.vpn.header" = "VPN";
+"service.sections.status.header" = "Connessione";
+"service.sections.configuration.header" = "Configurazione";
+
+"service.cells.use_profile.caption" = "Usa questo profilo";
+"service.cells.vpn_service.caption" = "Abilitato";
+"service.cells.reconnect.caption" = "Riconnetti";
+"service.cells.provider.refresh.caption" = "Aggiorna infrastruttura";
+"service.cells.host.parameters.caption" = "Parametri";
+"service.cells.trusted_add_wifi.caption" = "Aggiungi Wi-Fi corrente";
+
+"account.sections.credentials.header" = "Credenziali";
+
+"endpoint.sections.location_addresses.header" = "Indirizzi";
+"endpoint.sections.location_protocols.header" = "Protocolli";
+
+"provider.preset.cells.tech_details.caption" = "Dettagli tecnici";
+
+"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";
+
+"shortcuts.add.title" = "Aggiungi comando rapido";
+
+"shortcuts.edit.title" = "Gestisci comandi rapidi";
+"shortcuts.edit.cells.add_shortcut.caption" = "Aggiungi comando rapido";
diff --git a/Passepartout-iOS/Global/nl.lproj/App.strings b/Passepartout-iOS/Global/nl.lproj/App.strings
new file mode 100644
index 00000000..ddaa02ff
--- /dev/null
+++ b/Passepartout-iOS/Global/nl.lproj/App.strings
@@ -0,0 +1,61 @@
+//
+// App.strings
+// Passepartout-iOS
+//
+// 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 .
+//
+
+"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";
+
+"wizards.host.cells.title_input.caption" = "Titel";
+"wizards.host.sections.existing.header" = "Bestaande profielen";
+
+"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.vpn.header" = "VPN";
+"service.sections.status.header" = "Verbinding";
+"service.sections.configuration.header" = "Configuratie";
+
+"service.cells.use_profile.caption" = "Gebruik dit profiel";
+"service.cells.vpn_service.caption" = "Ingeschakeld";
+"service.cells.reconnect.caption" = "Opnieuw verbinden";
+"service.cells.provider.refresh.caption" = "Vernieuw de infrastructuur";
+"service.cells.host.parameters.caption" = "Parameters";
+"service.cells.trusted_add_wifi.caption" = "Voeg huidige WiFi toe";
+
+"account.sections.credentials.header" = "Inloggegevens";
+
+"endpoint.sections.location_addresses.header" = "Adressen";
+"endpoint.sections.location_protocols.header" = "Protocollen";
+
+"provider.preset.cells.tech_details.caption" = "Technische details";
+
+"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";
+
+"shortcuts.add.title" = "Voeg snelkoppeling toe";
+
+"shortcuts.edit.title" = "Beheer snelkoppelingen";
+"shortcuts.edit.cells.add_shortcut.caption" = "Voeg snelkoppeling toe";
diff --git a/Passepartout-iOS/Global/pt.lproj/App.strings b/Passepartout-iOS/Global/pt.lproj/App.strings
new file mode 100644
index 00000000..637581dd
--- /dev/null
+++ b/Passepartout-iOS/Global/pt.lproj/App.strings
@@ -0,0 +1,61 @@
+//
+// App.strings
+// Passepartout-iOS
+//
+// 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 .
+//
+
+"organizer.cells.profile.value.current" = "Ativo";
+"organizer.cells.add_provider.caption" = "Adicionar novo perfil";
+"organizer.cells.add_host.caption" = "Adicionar novo host";
+
+"wizards.host.cells.title_input.caption" = "Título";
+"wizards.host.sections.existing.header" = "Perfis existentes";
+
+"imported_hosts.title" = "Hosts importados";
+
+"service.welcome.message" = "Bem-vindo ao Passepartout!\n\nUse o organizador para adicionar um novo perfil.";
+"service.sections.vpn.header" = "VPN";
+"service.sections.status.header" = "Conexão";
+"service.sections.configuration.header" = "Configuração";
+
+"service.cells.use_profile.caption" = "Usar esse perfil";
+"service.cells.vpn_service.caption" = "Ativado";
+"service.cells.reconnect.caption" = "Reconectar";
+"service.cells.provider.refresh.caption" = "Atualizar infraestrutura";
+"service.cells.host.parameters.caption" = "Parâmetros";
+"service.cells.trusted_add_wifi.caption" = "Adicionar Wi-Fi atual";
+
+"account.sections.credentials.header" = "Credenciais";
+
+"endpoint.sections.location_addresses.header" = "Endereços";
+"endpoint.sections.location_protocols.header" = "Protocolos";
+
+"provider.preset.cells.tech_details.caption" = "Detalhes técnicos";
+
+"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";
+
+"shortcuts.add.title" = "Adicionar atalho";
+
+"shortcuts.edit.title" = "Configuração de atalhos";
+"shortcuts.edit.cells.add_shortcut.caption" = "Adicionar atalho";
diff --git a/Passepartout-iOS/Global/ru.lproj/App.strings b/Passepartout-iOS/Global/ru.lproj/App.strings
new file mode 100644
index 00000000..6d999ac3
--- /dev/null
+++ b/Passepartout-iOS/Global/ru.lproj/App.strings
@@ -0,0 +1,61 @@
+//
+// App.strings
+// Passepartout-iOS
+//
+// 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 .
+//
+
+"organizer.cells.profile.value.current" = "Используется";
+"organizer.cells.add_provider.caption" = "Добавить нового провайдера";
+"organizer.cells.add_host.caption" = "Добавить новый хост";
+
+"wizards.host.cells.title_input.caption" = "Название";
+"wizards.host.sections.existing.header" = "Существующие профили";
+
+"imported_hosts.title" = "Импортированные хост профили";
+
+"service.welcome.message" = "Добро пожаловать в Passepartout!\n\nИспользуйте организатор для добавления нового профиля.";
+"service.sections.vpn.header" = "VPN";
+"service.sections.status.header" = "Соединение";
+"service.sections.configuration.header" = "Конфигурация";
+
+"service.cells.use_profile.caption" = "Использовать это профиль.";
+"service.cells.vpn_service.caption" = "Включен";
+"service.cells.reconnect.caption" = "Переподключиться";
+"service.cells.provider.refresh.caption" = "Обновить инфраструктуру";
+"service.cells.host.parameters.caption" = "Параметры";
+"service.cells.trusted_add_wifi.caption" = "Добавить текущий Wi-Fi";
+
+"account.sections.credentials.header" = "Данные для входа";
+
+"endpoint.sections.location_addresses.header" = "Адреса";
+"endpoint.sections.location_protocols.header" = "Протоколы";
+
+"provider.preset.cells.tech_details.caption" = "Техническая информация";
+
+"network_settings.cells.add_dns_server.caption" = "Добавить адрес";
+"network_settings.cells.proxy_bypass.caption" = "Обход домена";
+"network_settings.cells.add_proxy_bypass.caption" = "Добавить обходной домен";
+
+"shortcuts.add.title" = "Создать команду";
+
+"shortcuts.edit.title" = "Управлять командами";
+"shortcuts.edit.cells.add_shortcut.caption" = "Создать команду";
diff --git a/Passepartout-iOS/Global/sv.lproj/App.strings b/Passepartout-iOS/Global/sv.lproj/App.strings
new file mode 100644
index 00000000..bd348eff
--- /dev/null
+++ b/Passepartout-iOS/Global/sv.lproj/App.strings
@@ -0,0 +1,61 @@
+//
+// App.strings
+// Passepartout-iOS
+//
+// 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 .
+//
+
+"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";
+
+"wizards.host.cells.title_input.caption" = "Namn";
+"wizards.host.sections.existing.header" = "Befintliga profiler";
+
+"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.vpn.header" = "VPN";
+"service.sections.status.header" = "Koppling";
+"service.sections.configuration.header" = "Konfiguration";
+
+"service.cells.use_profile.caption" = "Använd den här profilen";
+"service.cells.vpn_service.caption" = "Aktiverad";
+"service.cells.reconnect.caption" = "Återanslut";
+"service.cells.provider.refresh.caption" = "Uppdatera infrastruktur";
+"service.cells.host.parameters.caption" = "Parametrar";
+"service.cells.trusted_add_wifi.caption" = "Lägg till nuvarande Wi-Fi";
+
+"account.sections.credentials.header" = "Referenser";
+
+"endpoint.sections.location_addresses.header" = "Adresser";
+"endpoint.sections.location_protocols.header" = "Protokoll";
+
+"provider.preset.cells.tech_details.caption" = "Tekniska detaljer";
+
+"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";
+
+"shortcuts.add.title" = "Lägg till genväg";
+
+"shortcuts.edit.title" = "Hantera genvägar";
+"shortcuts.edit.cells.add_shortcut.caption" = "Lägg till genväg";
diff --git a/Passepartout-iOS/Scenes/About/AboutViewController.swift b/Passepartout-iOS/Scenes/About/AboutViewController.swift
index 48951ffb..fff6ee47 100644
--- a/Passepartout-iOS/Scenes/About/AboutViewController.swift
+++ b/Passepartout-iOS/Scenes/About/AboutViewController.swift
@@ -38,8 +38,8 @@ class AboutViewController: UITableViewController, TableModelHost {
model.add(.share)
model.setHeader("", for: .info)
model.setHeader("GitHub", for: .github)
- model.setHeader(L10n.About.Sections.Web.header, for: .web)
- model.setHeader(L10n.About.Sections.Share.header, for: .share)
+ model.setHeader(L10n.Core.About.Sections.Web.header, for: .web)
+ model.setHeader(L10n.Core.About.Sections.Share.header, for: .share)
model.set([.version, .credits], in: .info)
model.set([.readme, .changelog], in: .github)
model.set([.website, .faq, .disclaimer, .privacyPolicy], in: .web)
@@ -61,7 +61,7 @@ class AboutViewController: UITableViewController, TableModelHost {
override func viewDidLoad() {
super.viewDidLoad()
- title = L10n.About.title
+ title = L10n.Core.About.title
}
// MARK: Actions
@@ -79,7 +79,7 @@ class AboutViewController: UITableViewController, TableModelHost {
}
private func inviteFriend(sender: UITableViewCell?) {
- let message = "\(L10n.Share.message) \(AppConstants.URLs.website)"
+ let message = "\(L10n.Core.Share.message) \(AppConstants.URLs.website)"
let vc = UIActivityViewController(activityItems: [message], applicationActivities: nil)
vc.popoverPresentationController?.sourceView = sender
present(vc, animated: true, completion: nil)
@@ -153,11 +153,11 @@ extension AboutViewController {
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
switch model.row(at: indexPath) {
case .version:
- cell.leftText = L10n.Version.title
+ cell.leftText = L10n.Core.Version.title
cell.rightText = Utils.versionString()
case .credits:
- cell.leftText = L10n.About.Cells.Credits.caption
+ cell.leftText = L10n.Core.About.Cells.Credits.caption
case .readme:
cell.leftText = "README"
@@ -166,22 +166,22 @@ extension AboutViewController {
cell.leftText = "CHANGELOG"
case .website:
- cell.leftText = L10n.About.Cells.Website.caption
+ cell.leftText = L10n.Core.About.Cells.Website.caption
case .faq:
- cell.leftText = L10n.About.Cells.Faq.caption
+ cell.leftText = L10n.Core.About.Cells.Faq.caption
case .disclaimer:
- cell.leftText = L10n.About.Cells.Disclaimer.caption
+ cell.leftText = L10n.Core.About.Cells.Disclaimer.caption
case .privacyPolicy:
- cell.leftText = L10n.About.Cells.PrivacyPolicy.caption
+ cell.leftText = L10n.Core.About.Cells.PrivacyPolicy.caption
case .shareTwitter:
- cell.leftText = L10n.About.Cells.ShareTwitter.caption
+ cell.leftText = L10n.Core.About.Cells.ShareTwitter.caption
case .shareGeneric:
- cell.leftText = L10n.About.Cells.ShareGeneric.caption
+ cell.leftText = L10n.Core.About.Cells.ShareGeneric.caption
}
return cell
}
@@ -213,7 +213,7 @@ extension AboutViewController {
visit(AppConstants.URLs.privacyPolicy)
case .shareTwitter:
- visit(AppConstants.URLs.twitterIntent)
+ visit(AppConstants.URLs.twitterIntent(withMessage: L10n.Core.Share.message))
case .shareGeneric:
inviteFriend(sender: tableView.cellForRow(at: indexPath))
diff --git a/Passepartout-iOS/Scenes/About/CreditsViewController.swift b/Passepartout-iOS/Scenes/About/CreditsViewController.swift
index cd76ece6..bcee7c0f 100644
--- a/Passepartout-iOS/Scenes/About/CreditsViewController.swift
+++ b/Passepartout-iOS/Scenes/About/CreditsViewController.swift
@@ -44,9 +44,9 @@ class CreditsViewController: UITableViewController, TableModelHost {
model.add(.notices)
model.add(.translations)
- model.setHeader(L10n.Credits.Sections.Licenses.header, for: .licenses)
- model.setHeader(L10n.Credits.Sections.Notices.header, for: .notices)
- model.setHeader(L10n.Credits.Sections.Translations.header, for: .translations)
+ model.setHeader(L10n.Core.Credits.Sections.Licenses.header, for: .licenses)
+ model.setHeader(L10n.Core.Credits.Sections.Notices.header, for: .notices)
+ model.setHeader(L10n.Core.Credits.Sections.Translations.header, for: .translations)
model.set(.license, count: licenses.count, in: .licenses)
model.set(.notice, count: notices.count, in: .notices)
@@ -58,7 +58,7 @@ class CreditsViewController: UITableViewController, TableModelHost {
override func viewDidLoad() {
super.viewDidLoad()
- title = L10n.Credits.title
+ title = L10n.Core.Credits.title
reloadModel()
}
diff --git a/Passepartout-iOS/Scenes/About/LabelViewController.swift b/Passepartout-iOS/Scenes/About/LabelViewController.swift
index 22d62a0a..44863f7e 100644
--- a/Passepartout-iOS/Scenes/About/LabelViewController.swift
+++ b/Passepartout-iOS/Scenes/About/LabelViewController.swift
@@ -69,7 +69,7 @@ class LabelViewController: UIViewController {
content = try String(contentsOf: license.url)
couldFetch = true
} catch {
- content = L10n.Label.License.error
+ content = L10n.Core.Label.License.error
couldFetch = false
}
DispatchQueue.main.async {
diff --git a/Passepartout-iOS/Scenes/About/VersionViewController.swift b/Passepartout-iOS/Scenes/About/VersionViewController.swift
index f6d35cf9..3adf3b1e 100644
--- a/Passepartout-iOS/Scenes/About/VersionViewController.swift
+++ b/Passepartout-iOS/Scenes/About/VersionViewController.swift
@@ -44,10 +44,10 @@ class VersionViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
- title = L10n.Version.title
+ title = L10n.Core.Version.title
labelTitle?.text = GroupConstants.App.name
labelVersion?.text = Utils.versionString()
- labelIntro?.text = L10n.Version.Labels.intro
+ labelIntro?.text = L10n.Core.Version.Labels.intro
scrollView?.applyPrimaryBackground(Theme.current)
for label in [labelTitle, labelVersion, labelIntro] {
diff --git a/Passepartout-iOS/Scenes/AccountViewController.swift b/Passepartout-iOS/Scenes/AccountViewController.swift
index d3fffded..8b6f0130 100644
--- a/Passepartout-iOS/Scenes/AccountViewController.swift
+++ b/Passepartout-iOS/Scenes/AccountViewController.swift
@@ -60,7 +60,7 @@ class AccountViewController: UIViewController, TableModelHost {
guard let name = infrastructureName else {
return nil
}
- let V = L10n.Account.Sections.Guidance.Footer.Infrastructure.self
+ let V = L10n.Core.Account.Sections.Guidance.Footer.Infrastructure.self
switch name {
case .mullvad:
return V.mullvad(name.rawValue)
@@ -109,7 +109,7 @@ class AccountViewController: UIViewController, TableModelHost {
model.clear()
model.add(.credentials)
- model.setHeader(L10n.Account.Sections.Credentials.header, for: .credentials)
+ model.setHeader(L10n.App.Account.Sections.Credentials.header, for: .credentials)
model.set([.username, .password], in: .credentials)
if let name = infrastructureName {
@@ -125,7 +125,7 @@ class AccountViewController: UIViewController, TableModelHost {
}
if let _ = referralURL {
model.add(.registration)
- model.setFooter(L10n.Account.Sections.Registration.footer(name.rawValue), for: .registration)
+ model.setFooter(L10n.Core.Account.Sections.Registration.footer(name.rawValue), for: .registration)
model.set([.signUp], in: .registration)
}
}
@@ -142,7 +142,7 @@ class AccountViewController: UIViewController, TableModelHost {
override func viewDidLoad() {
super.viewDidLoad()
- title = L10n.Service.Cells.Account.caption
+ title = L10n.Core.Account.title
cellUsername?.field.text = currentCredentials?.username
cellPassword?.field.text = currentCredentials?.password
@@ -234,8 +234,8 @@ extension AccountViewController: UITableViewDataSource, UITableViewDelegate, Fie
case .username:
let cell = Cells.field.dequeue(from: tableView, for: indexPath)
cellUsername = cell
- cell.caption = L10n.Account.Cells.Username.caption
- cell.field.placeholder = usernamePlaceholder ?? L10n.Account.Cells.Username.placeholder
+ cell.caption = L10n.Core.Account.Cells.Username.caption
+ cell.field.placeholder = usernamePlaceholder ?? L10n.Core.Account.Cells.Username.placeholder
cell.field.clearButtonMode = .always
cell.field.isSecureTextEntry = false
cell.field.text = currentCredentials?.username
@@ -249,8 +249,8 @@ extension AccountViewController: UITableViewDataSource, UITableViewDelegate, Fie
case .password:
let cell = Cells.field.dequeue(from: tableView, for: indexPath)
cellPassword = cell
- cell.caption = L10n.Account.Cells.Password.caption
- cell.field.placeholder = L10n.Account.Cells.Password.placeholder
+ cell.caption = L10n.Core.Account.Cells.Password.caption
+ cell.field.placeholder = L10n.Core.Account.Cells.Password.placeholder
cell.field.clearButtonMode = .always
cell.field.isSecureTextEntry = true
cell.field.text = currentCredentials?.password
@@ -262,7 +262,7 @@ extension AccountViewController: UITableViewDataSource, UITableViewDelegate, Fie
case .openGuide:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Account.Cells.OpenGuide.caption
+ cell.leftText = L10n.Core.Account.Cells.OpenGuide.caption
cell.applyAction(Theme.current)
return cell
@@ -271,7 +271,7 @@ extension AccountViewController: UITableViewDataSource, UITableViewDelegate, Fie
fatalError("Sign-up shown when not a provider profile")
}
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Account.Cells.Signup.caption(name.rawValue)
+ cell.leftText = L10n.Core.Account.Cells.Signup.caption(name.rawValue)
cell.applyAction(Theme.current)
return cell
}
diff --git a/Passepartout-iOS/Scenes/ConfigurationViewController.swift b/Passepartout-iOS/Scenes/ConfigurationViewController.swift
index aa793f2a..5559b4b4 100644
--- a/Passepartout-iOS/Scenes/ConfigurationViewController.swift
+++ b/Passepartout-iOS/Scenes/ConfigurationViewController.swift
@@ -59,19 +59,17 @@ class ConfigurationViewController: UIViewController, TableModelHost {
model.add(.reset)
}
model.add(.tls)
-// model.add(.network)
model.add(.other)
// headers
- model.setHeader(L10n.Configuration.Sections.Communication.header, for: .communication)
- model.setHeader(L10n.Configuration.Sections.Tls.header, for: .tls)
- model.setHeader(L10n.Configuration.Sections.Compression.header, for: .compression)
- model.setHeader(L10n.Configuration.Sections.Network.header, for: .network)
- model.setHeader(L10n.Configuration.Sections.Other.header, for: .other)
+ model.setHeader(L10n.Core.Configuration.Sections.Communication.header, for: .communication)
+ model.setHeader(L10n.Core.Configuration.Sections.Tls.header, for: .tls)
+ model.setHeader(L10n.Core.Configuration.Sections.Compression.header, for: .compression)
+ model.setHeader(L10n.Core.Configuration.Sections.Other.header, for: .other)
// footers
if isEditable {
- model.setFooter(L10n.Configuration.Sections.Reset.footer, for: .reset)
+ model.setFooter(L10n.Core.Configuration.Sections.Reset.footer, for: .reset)
}
// rows
@@ -81,17 +79,6 @@ class ConfigurationViewController: UIViewController, TableModelHost {
}
model.set([.client, .tlsWrapping, .eku], in: .tls)
model.set([.compressionFraming, .compressionAlgorithm], in: .compression)
- var networkRows: [RowType]
- if let dnsServers = configuration.dnsServers {
- networkRows = [RowType](repeating: .dnsServer, count: dnsServers.count)
- } else {
- networkRows = []
- }
- networkRows.insert(.defaultGateway, at: 0)
- networkRows.append(.dnsDomain)
- networkRows.append(.httpProxy)
- networkRows.append(.httpsProxy)
- model.set(networkRows, in: .network)
model.set([.keepAlive, .renegSeconds, .randomEndpoint], in: .other)
return model
@@ -198,16 +185,6 @@ extension ConfigurationViewController: UITableViewDataSource, UITableViewDelegat
case compressionAlgorithm
- case defaultGateway
-
- case dnsServer
-
- case dnsDomain
-
- case httpProxy
-
- case httpsProxy
-
case keepAlive
case renegSeconds
@@ -237,7 +214,7 @@ extension ConfigurationViewController: UITableViewDataSource, UITableViewDelegat
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let row = model.row(at: indexPath)
- let V = L10n.Configuration.Cells.self
+ let V = L10n.Core.Configuration.Cells.self
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
if !isEditable {
@@ -246,38 +223,38 @@ extension ConfigurationViewController: UITableViewDataSource, UITableViewDelegat
cell.isTappable = isEditable
switch row {
case .cipher:
- cell.leftText = L10n.Configuration.Cells.Cipher.caption
+ cell.leftText = V.Cipher.caption
cell.rightText = configuration.fallbackCipher.description
case .digest:
- cell.leftText = L10n.Configuration.Cells.Digest.caption
+ cell.leftText = V.Digest.caption
cell.rightText = configuration.fallbackDigest.description
case .compressionFraming:
- cell.leftText = L10n.Configuration.Cells.CompressionFraming.caption
+ cell.leftText = V.CompressionFraming.caption
cell.rightText = configuration.fallbackCompressionFraming.cellDescription
case .compressionAlgorithm:
- cell.leftText = L10n.Configuration.Cells.CompressionAlgorithm.caption
+ cell.leftText = V.CompressionAlgorithm.caption
if let compressionAlgorithm = configuration.compressionAlgorithm {
cell.rightText = compressionAlgorithm.cellDescription
} else {
- cell.rightText = L10n.Global.Cells.disabled
+ cell.rightText = L10n.Core.Global.Values.disabled
}
cell.isTappable = (configuration.compressionFraming != .disabled)
case .resetOriginal:
- cell.leftText = L10n.Configuration.Cells.ResetOriginal.caption
+ cell.leftText = V.ResetOriginal.caption
cell.applyAction(Theme.current)
case .client:
- cell.leftText = L10n.Configuration.Cells.Client.caption
- cell.rightText = (configuration.clientCertificate != nil) ? L10n.Configuration.Cells.Client.Value.enabled : L10n.Configuration.Cells.Client.Value.disabled
+ cell.leftText = V.Client.caption
+ cell.rightText = (configuration.clientCertificate != nil) ? V.Client.Value.enabled : V.Client.Value.disabled
cell.accessoryType = .none
cell.isTappable = false
case .tlsWrapping:
- cell.leftText = L10n.Configuration.Cells.TlsWrapping.caption
+ cell.leftText = V.TlsWrapping.caption
if let strategy = configuration.tlsWrap?.strategy {
switch strategy {
case .auth:
@@ -287,77 +264,40 @@ extension ConfigurationViewController: UITableViewDataSource, UITableViewDelegat
cell.rightText = V.TlsWrapping.Value.crypt
}
} else {
- cell.rightText = L10n.Global.Cells.disabled
+ cell.rightText = L10n.Core.Global.Values.disabled
}
cell.accessoryType = .none
cell.isTappable = false
case .eku:
cell.leftText = V.Eku.caption
- cell.rightText = (configuration.checksEKU ?? false) ? L10n.Global.Cells.enabled : L10n.Global.Cells.disabled
+ cell.rightText = (configuration.checksEKU ?? false) ? L10n.Core.Global.Values.enabled : L10n.Core.Global.Values.disabled
cell.accessoryType = .none
cell.isTappable = false
- case .defaultGateway:
- cell.leftText = L10n.Configuration.Cells.DefaultGateway.caption
- if let policies = configuration.routingPolicies {
- cell.rightText = policies.map { $0.rawValue }.joined(separator: " / ")
- } else {
- cell.rightText = L10n.Global.Cells.none
- }
- cell.accessoryType = .none
- cell.isTappable = false
-
- case .dnsServer:
- guard let dnsServers = configuration.dnsServers else {
- fatalError("Showing DNS section without any custom server")
- }
- cell.leftText = L10n.Configuration.Cells.DnsServer.caption
- cell.rightText = dnsServers[indexPath.row - 1]
- cell.accessoryType = .none
- cell.isTappable = false
-
- case .dnsDomain:
- cell.leftText = L10n.Configuration.Cells.DnsDomain.caption
- cell.rightText = configuration.searchDomain ?? L10n.Global.Cells.none
- cell.accessoryType = .none
- cell.isTappable = false
-
- case .httpProxy:
- cell.leftText = L10n.Configuration.Cells.ProxyHttp.caption
- cell.rightText = configuration.httpProxy?.description ?? L10n.Global.Cells.none
- cell.accessoryType = .none
- cell.isTappable = false
-
- case .httpsProxy:
- cell.leftText = L10n.Configuration.Cells.ProxyHttps.caption
- cell.rightText = configuration.httpsProxy?.description ?? L10n.Global.Cells.none
- cell.accessoryType = .none
- cell.isTappable = false
-
case .keepAlive:
- cell.leftText = L10n.Configuration.Cells.KeepAlive.caption
+ cell.leftText = V.KeepAlive.caption
if let keepAlive = configuration.keepAliveInterval, keepAlive > 0 {
cell.rightText = V.KeepAlive.Value.seconds(Int(keepAlive))
} else {
- cell.rightText = L10n.Global.Cells.disabled
+ cell.rightText = L10n.Core.Global.Values.disabled
}
cell.accessoryType = .none
cell.isTappable = false
case .renegSeconds:
- cell.leftText = L10n.Configuration.Cells.RenegotiationSeconds.caption
+ cell.leftText = V.RenegotiationSeconds.caption
if let reneg = configuration.renegotiatesAfter, reneg > 0 {
cell.rightText = V.RenegotiationSeconds.Value.after(TimeInterval(reneg).localized)
} else {
- cell.rightText = L10n.Global.Cells.disabled
+ cell.rightText = L10n.Core.Global.Values.disabled
}
cell.accessoryType = .none
cell.isTappable = false
case .randomEndpoint:
cell.leftText = V.RandomEndpoint.caption
- cell.rightText = (configuration.randomizeEndpoint ?? false) ? L10n.Global.Cells.enabled : L10n.Global.Cells.disabled
+ cell.rightText = (configuration.randomizeEndpoint ?? false) ? L10n.Core.Global.Values.enabled : L10n.Core.Global.Values.disabled
cell.accessoryType = .none
cell.isTappable = false
}
@@ -451,10 +391,10 @@ extension ConfigurationViewController: UITableViewDataSource, UITableViewDelegat
private extension OpenVPN.CompressionFraming {
var cellDescription: String {
- let V = L10n.Configuration.Cells.self
+ let V = L10n.Core.Configuration.Cells.self
switch self {
case .disabled:
- return L10n.Global.Cells.disabled
+ return L10n.Core.Global.Values.disabled
case .compLZO:
return V.CompressionFraming.Value.lzo
@@ -467,10 +407,10 @@ private extension OpenVPN.CompressionFraming {
private extension OpenVPN.CompressionAlgorithm {
var cellDescription: String {
- let V = L10n.Configuration.Cells.self
+ let V = L10n.Core.Configuration.Cells.self
switch self {
case .disabled:
- return L10n.Global.Cells.disabled
+ return L10n.Core.Global.Values.disabled
case .LZO:
return V.CompressionAlgorithm.Value.lzo
diff --git a/Passepartout-iOS/Scenes/DebugLogViewController.swift b/Passepartout-iOS/Scenes/DebugLogViewController.swift
index 40441cf6..35c76cca 100644
--- a/Passepartout-iOS/Scenes/DebugLogViewController.swift
+++ b/Passepartout-iOS/Scenes/DebugLogViewController.swift
@@ -49,7 +49,7 @@ class DebugLogViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
- title = L10n.Service.Cells.DebugLog.caption
+ title = L10n.Core.Service.Cells.DebugLog.caption
textLog?.contentInsetAdjustmentBehavior = .never
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(toggleBars))
@@ -84,8 +84,8 @@ class DebugLogViewController: UIViewController {
@IBAction private func share(_ sender: Any?) {
guard let raw = textLog?.text, !raw.isEmpty else {
- let alert = Macros.alert(title, L10n.DebugLog.Alerts.EmptyLog.message)
- alert.addCancelAction(L10n.Global.ok)
+ let alert = Macros.alert(title, L10n.Core.DebugLog.Alerts.EmptyLog.message)
+ alert.addCancelAction(L10n.Core.Global.ok)
present(alert, animated: true, completion: nil)
return
}
diff --git a/Passepartout-iOS/Scenes/EndpointViewController.swift b/Passepartout-iOS/Scenes/EndpointViewController.swift
index 9ada92b9..e0fb8727 100644
--- a/Passepartout-iOS/Scenes/EndpointViewController.swift
+++ b/Passepartout-iOS/Scenes/EndpointViewController.swift
@@ -66,8 +66,8 @@ class EndpointViewController: UIViewController, TableModelHost {
model.add(.locationAddresses)
model.add(.locationProtocols)
- model.setHeader(L10n.Endpoint.Sections.LocationAddresses.header, for: .locationAddresses)
- model.setHeader(L10n.Endpoint.Sections.LocationProtocols.header, for: .locationProtocols)
+ model.setHeader(L10n.App.Endpoint.Sections.LocationAddresses.header, for: .locationAddresses)
+ model.setHeader(L10n.App.Endpoint.Sections.LocationProtocols.header, for: .locationProtocols)
if dataSource.canCustomizeEndpoint {
var addressRows: [RowType] = Array(repeating: .availableAddress, count: dataSource.addresses.count)
@@ -99,7 +99,7 @@ class EndpointViewController: UIViewController, TableModelHost {
override func viewDidLoad() {
super.viewDidLoad()
- title = L10n.Service.Cells.Endpoint.caption
+ title = L10n.Core.Endpoint.title
guard let _ = dataSource else {
fatalError("Data source not set")
}
@@ -208,7 +208,7 @@ extension EndpointViewController: UITableViewDataSource, UITableViewDelegate {
switch row {
case .anyAddress:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Endpoint.Cells.AnyAddress.caption
+ cell.leftText = L10n.Core.Endpoint.Cells.AnyAddress.caption
cell.accessoryType = .none
cell.isTappable = true
if let _ = currentAddress {
@@ -235,7 +235,7 @@ extension EndpointViewController: UITableViewDataSource, UITableViewDelegate {
case .anyProtocol:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Endpoint.Cells.AnyProtocol.caption
+ cell.leftText = L10n.Core.Endpoint.Cells.AnyProtocol.caption
cell.accessoryType = .none
cell.isTappable = true
if let _ = currentProtocol {
diff --git a/Passepartout-iOS/Scenes/NetworkSettingsViewController.swift b/Passepartout-iOS/Scenes/NetworkSettingsViewController.swift
index 27a0542e..15961bce 100644
--- a/Passepartout-iOS/Scenes/NetworkSettingsViewController.swift
+++ b/Passepartout-iOS/Scenes/NetworkSettingsViewController.swift
@@ -101,12 +101,12 @@ class NetworkSettingsViewController: UITableViewController {
// headers
model.setHeader("", for: .choices)
- model.setHeader(L10n.Configuration.Cells.DefaultGateway.caption, for: .manualGateway)
- model.setHeader(L10n.Configuration.Cells.DnsServer.caption, for: .manualDNS)
- model.setHeader(L10n.Configuration.Cells.ProxyHttp.caption, for: .manualProxy)
+ model.setHeader(L10n.Core.NetworkSettings.Gateway.title, for: .manualGateway)
+ model.setHeader(L10n.Core.NetworkSettings.Dns.title, for: .manualDNS)
+ model.setHeader(L10n.Core.NetworkSettings.Proxy.title, for: .manualProxy)
// footers
-// model.setFooter(L10n.Configuration.Sections.Reset.footer, for: .reset)
+// model.setFooter(L10n.Core.Configuration.Sections.Reset.footer, for: .reset)
// rows
model.set([.gateway, .dns, .proxy], in: .choices)
@@ -342,9 +342,9 @@ extension NetworkSettingsViewController {
case .dnsDomain:
let cell = Cells.field.dequeue(from: tableView, for: indexPath)
- cell.caption = L10n.Configuration.Cells.DnsDomain.caption
+ cell.caption = L10n.Core.NetworkSettings.Dns.Cells.Domain.caption
cell.field.tag = FieldTag.dnsDomain.rawValue
- cell.field.placeholder = L10n.Global.Cells.none
+ cell.field.placeholder = L10n.Core.Global.Values.none
cell.field.text = networkSettings.dnsDomainName
cell.field.clearButtonMode = .always
cell.field.keyboardType = .asciiCapable
@@ -357,9 +357,9 @@ extension NetworkSettingsViewController {
let i = indexPath.row - Offsets.dnsAddress
let cell = Cells.field.dequeue(from: tableView, for: indexPath)
- cell.caption = L10n.NetworkSettings.Cells.Address.caption
+ cell.caption = L10n.Core.Global.Captions.address
cell.field.tag = FieldTag.dnsAddress.rawValue + i
- cell.field.placeholder = L10n.Global.Cells.none
+ cell.field.placeholder = L10n.Core.Global.Values.none
cell.field.text = networkSettings.dnsServers?[i]
cell.field.clearButtonMode = .always
cell.field.keyboardType = .decimalPad
@@ -371,14 +371,14 @@ extension NetworkSettingsViewController {
case .dnsAddAddress:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
cell.applyAction(Theme.current)
- cell.leftText = L10n.NetworkSettings.Cells.AddDnsServer.caption
+ cell.leftText = L10n.App.NetworkSettings.Cells.AddDnsServer.caption
return cell
case .proxyAddress:
let cell = Cells.field.dequeue(from: tableView, for: indexPath)
- cell.caption = L10n.NetworkSettings.Cells.Address.caption
+ cell.caption = L10n.Core.Global.Captions.address
cell.field.tag = FieldTag.proxyAddress.rawValue
- cell.field.placeholder = L10n.Global.Cells.none
+ cell.field.placeholder = L10n.Core.Global.Values.none
cell.field.text = networkSettings.proxyAddress
cell.field.clearButtonMode = .always
cell.field.keyboardType = .decimalPad
@@ -389,9 +389,9 @@ extension NetworkSettingsViewController {
case .proxyPort:
let cell = Cells.field.dequeue(from: tableView, for: indexPath)
- cell.caption = L10n.NetworkSettings.Cells.Port.caption
+ cell.caption = L10n.Core.Global.Captions.port
cell.field.tag = FieldTag.proxyPort.rawValue
- cell.field.placeholder = L10n.Global.Cells.none
+ cell.field.placeholder = L10n.Core.Global.Values.none
cell.field.text = networkSettings.proxyPort?.description
cell.field.clearButtonMode = .always
cell.field.keyboardType = .numberPad
@@ -404,9 +404,9 @@ extension NetworkSettingsViewController {
let i = indexPath.row - Offsets.proxyBypass
let cell = Cells.field.dequeue(from: tableView, for: indexPath)
- cell.caption = L10n.NetworkSettings.Cells.ProxyBypass.caption
+ cell.caption = L10n.App.NetworkSettings.Cells.ProxyBypass.caption
cell.field.tag = FieldTag.proxyBypass.rawValue + i
- cell.field.placeholder = L10n.Global.Cells.none
+ cell.field.placeholder = L10n.Core.Global.Values.none
cell.field.text = networkSettings.proxyBypassDomains?[i]
cell.field.clearButtonMode = .always
cell.field.keyboardType = .asciiCapable
@@ -418,7 +418,7 @@ extension NetworkSettingsViewController {
case .proxyAddBypass:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
cell.applyAction(Theme.current)
- cell.leftText = L10n.NetworkSettings.Cells.AddProxyBypass.caption
+ cell.leftText = L10n.App.NetworkSettings.Cells.AddProxyBypass.caption
return cell
}
}
@@ -573,13 +573,13 @@ extension NetworkChoice: CustomStringConvertible {
public var description: String {
switch self {
case .client:
- return L10n.NetworkSettings.Cells.Choice.client
+ return L10n.Core.NetworkChoice.client
case .server:
- return L10n.NetworkSettings.Cells.Choice.server
+ return L10n.Core.NetworkChoice.server
case .manual:
- return L10n.Global.Cells.manual
+ return L10n.Core.Global.Values.manual
}
}
}
diff --git a/Passepartout-iOS/Scenes/Organizer/DonationViewController.swift b/Passepartout-iOS/Scenes/Organizer/DonationViewController.swift
index 35cca335..16658d1d 100644
--- a/Passepartout-iOS/Scenes/Organizer/DonationViewController.swift
+++ b/Passepartout-iOS/Scenes/Organizer/DonationViewController.swift
@@ -53,8 +53,8 @@ class DonationViewController: UITableViewController, TableModelHost {
model.clear()
model.add(.oneTime)
- model.setHeader(L10n.Donation.Sections.OneTime.header, for: .oneTime)
- model.setFooter(L10n.Donation.Sections.OneTime.footer, for: .oneTime)
+ model.setHeader(L10n.Core.Donation.Sections.OneTime.header, for: .oneTime)
+ model.setFooter(L10n.Core.Donation.Sections.OneTime.footer, for: .oneTime)
guard !isLoading else {
model.set([.loading], in: .oneTime)
@@ -81,7 +81,7 @@ class DonationViewController: UITableViewController, TableModelHost {
override func viewDidLoad() {
super.viewDidLoad()
- title = L10n.Donation.title
+ title = L10n.Core.Donation.title
reloadModel()
let inApp = InAppHelper.shared
@@ -122,12 +122,12 @@ class DonationViewController: UITableViewController, TableModelHost {
switch model.row(at: indexPath) {
case .loading:
let cell = Cells.activity.dequeue(from: tableView, for: indexPath)
- cell.textLabel?.text = L10n.Donation.Cells.Loading.caption
+ cell.textLabel?.text = L10n.Core.Donation.Cells.Loading.caption
return cell
case .purchasing:
let cell = Cells.activity.dequeue(from: tableView, for: indexPath)
- cell.textLabel?.text = L10n.Donation.Cells.Purchasing.caption
+ cell.textLabel?.text = L10n.Core.Donation.Cells.Purchasing.caption
return cell
case .donation:
@@ -178,12 +178,12 @@ class DonationViewController: UITableViewController, TableModelHost {
return
case .success:
- alert = Macros.alert(L10n.Donation.Alerts.Purchase.Success.title, L10n.Donation.Alerts.Purchase.Success.message)
+ alert = Macros.alert(L10n.Core.Donation.Alerts.Purchase.Success.title, L10n.Core.Donation.Alerts.Purchase.Success.message)
case .failure:
- alert = Macros.alert(title, L10n.Donation.Alerts.Purchase.Failure.message(error?.localizedDescription ?? ""))
+ alert = Macros.alert(title, L10n.Core.Donation.Alerts.Purchase.Failure.message(error?.localizedDescription ?? ""))
}
- alert.addCancelAction(L10n.Global.ok) {
+ alert.addCancelAction(L10n.Core.Global.ok) {
self.isPurchasing = false
self.reloadModel()
self.tableView.reloadData()
diff --git a/Passepartout-iOS/Scenes/Organizer/ImportedHostsViewController.swift b/Passepartout-iOS/Scenes/Organizer/ImportedHostsViewController.swift
index ed913d2d..8629e53a 100644
--- a/Passepartout-iOS/Scenes/Organizer/ImportedHostsViewController.swift
+++ b/Passepartout-iOS/Scenes/Organizer/ImportedHostsViewController.swift
@@ -38,7 +38,7 @@ class ImportedHostsViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
- title = L10n.ImportedHosts.title
+ title = L10n.App.ImportedHosts.title
}
override func viewWillAppear(_ animated: Bool) {
@@ -53,9 +53,9 @@ class ImportedHostsViewController: UITableViewController {
guard !pendingConfigurationURLs.isEmpty else {
let alert = Macros.alert(
title,
- L10n.Organizer.Alerts.AddHost.message
+ L10n.Core.Organizer.Alerts.AddHost.message
)
- alert.addCancelAction(L10n.Global.ok) {
+ alert.addCancelAction(L10n.Core.Global.ok) {
self.close()
}
present(alert, animated: true, completion: nil)
diff --git a/Passepartout-iOS/Scenes/Organizer/OrganizerViewController.swift b/Passepartout-iOS/Scenes/Organizer/OrganizerViewController.swift
index 3f332e98..c227512c 100644
--- a/Passepartout-iOS/Scenes/Organizer/OrganizerViewController.swift
+++ b/Passepartout-iOS/Scenes/Organizer/OrganizerViewController.swift
@@ -55,18 +55,18 @@ class OrganizerViewController: UITableViewController, TableModelHost {
model.add(.feedback)
model.add(.about)
model.add(.destruction)
- model.setHeader(L10n.Service.Sections.Vpn.header, for: .vpn)
- model.setHeader(L10n.Organizer.Sections.Providers.header, for: .providers)
- model.setHeader(L10n.Organizer.Sections.Hosts.header, for: .hosts)
- model.setFooter(L10n.Organizer.Sections.Providers.footer, for: .providers)
- model.setFooter(L10n.Organizer.Sections.Hosts.footer, for: .hosts)
+ model.setHeader(L10n.App.Service.Sections.Vpn.header, for: .vpn)
+ model.setHeader(L10n.Core.Organizer.Sections.Providers.header, for: .providers)
+ model.setHeader(L10n.Core.Organizer.Sections.Hosts.header, for: .hosts)
+ model.setFooter(L10n.Core.Organizer.Sections.Providers.footer, for: .providers)
+ model.setFooter(L10n.Core.Organizer.Sections.Hosts.footer, for: .hosts)
if #available(iOS 12, *) {
- model.setHeader(L10n.Organizer.Sections.Siri.header, for: .siri)
- model.setFooter(L10n.Organizer.Sections.Siri.footer, for: .siri)
+ model.setHeader(L10n.Core.Organizer.Sections.Siri.header, for: .siri)
+ model.setFooter(L10n.Core.Organizer.Sections.Siri.footer, for: .siri)
model.set([.siriShortcuts], in: .siri)
}
- model.setHeader(L10n.Organizer.Sections.Support.header, for: .support)
- model.setHeader(L10n.Organizer.Sections.Feedback.header, for: .feedback)
+ model.setHeader(L10n.Core.Organizer.Sections.Support.header, for: .support)
+ model.setHeader(L10n.Core.Organizer.Sections.Feedback.header, for: .feedback)
model.set([.connectionStatus], in: .vpn)
model.set([.donate, .patreon, .translate], in: .support)
model.set([.joinCommunity, .writeReview], in: .feedback)
@@ -125,15 +125,15 @@ class OrganizerViewController: UITableViewController, TableModelHost {
if !didShowSubreddit && !TransientStore.didHandleSubreddit {
didShowSubreddit = true
- let alert = Macros.alert(L10n.Reddit.title, L10n.Reddit.message)
- alert.addDefaultAction(L10n.Reddit.Buttons.subscribe) {
+ let alert = Macros.alert(L10n.Core.Reddit.title, L10n.Core.Reddit.message)
+ alert.addDefaultAction(L10n.Core.Reddit.Buttons.subscribe) {
TransientStore.didHandleSubreddit = true
self.subscribeSubreddit()
}
- alert.addAction(L10n.Reddit.Buttons.never) {
+ alert.addAction(L10n.Core.Reddit.Buttons.never) {
TransientStore.didHandleSubreddit = true
}
- alert.addCancelAction(L10n.Reddit.Buttons.remind)
+ alert.addCancelAction(L10n.Core.Reddit.Buttons.remind)
present(alert, animated: true, completion: nil)
}
}
@@ -195,10 +195,10 @@ class OrganizerViewController: UITableViewController, TableModelHost {
guard !names.isEmpty else {
let alert = Macros.alert(
- L10n.Organizer.Sections.Providers.header,
- L10n.Organizer.Alerts.ExhaustedProviders.message
+ L10n.Core.Organizer.Sections.Providers.header,
+ L10n.Core.Organizer.Alerts.ExhaustedProviders.message
)
- alert.addCancelAction(L10n.Global.ok)
+ alert.addCancelAction(L10n.Core.Global.ok)
present(alert, animated: true, completion: nil)
return
}
@@ -218,10 +218,10 @@ class OrganizerViewController: UITableViewController, TableModelHost {
private func donateToDeveloper() {
guard SKPaymentQueue.canMakePayments() else {
let alert = Macros.alert(
- L10n.Organizer.Cells.Donate.caption,
- L10n.Organizer.Alerts.CannotDonate.message
+ L10n.Core.Organizer.Cells.Donate.caption,
+ L10n.Core.Organizer.Alerts.CannotDonate.message
)
- alert.addCancelAction(L10n.Global.ok)
+ alert.addCancelAction(L10n.Core.Global.ok)
present(alert, animated: true, completion: nil)
return
}
@@ -234,8 +234,8 @@ class OrganizerViewController: UITableViewController, TableModelHost {
private func offerTranslation() {
guard MFMailComposeViewController.canSendMail() else {
- let alert = Macros.alert(L10n.IssueReporter.title, L10n.Global.emailNotConfigured)
- alert.addCancelAction(L10n.Global.ok)
+ let alert = Macros.alert(L10n.Core.IssueReporter.title, L10n.Core.Global.emailNotConfigured)
+ alert.addCancelAction(L10n.Core.Global.ok)
present(alert, animated: true, completion: nil)
return
}
@@ -304,13 +304,13 @@ class OrganizerViewController: UITableViewController, TableModelHost {
private func confirmVpnProfileDeletion() {
let alert = Macros.alert(
- L10n.Organizer.Cells.Uninstall.caption,
- L10n.Organizer.Alerts.DeleteVpnProfile.message
+ L10n.Core.Organizer.Cells.Uninstall.caption,
+ L10n.Core.Organizer.Alerts.DeleteVpnProfile.message
)
- alert.addDefaultAction(L10n.Global.ok) {
+ alert.addDefaultAction(L10n.Core.Global.ok) {
VPN.shared.uninstall(completionHandler: nil)
}
- alert.addCancelAction(L10n.Global.cancel)
+ alert.addCancelAction(L10n.Core.Global.cancel)
present(alert, animated: true, completion: nil)
}
@@ -330,7 +330,7 @@ class OrganizerViewController: UITableViewController, TableModelHost {
return
}
let alert = Macros.alert("Debug log", log)
- alert.addCancelAction(L10n.Global.ok)
+ alert.addCancelAction(L10n.Core.Global.ok)
present(alert, animated: true, completion: nil)
}
@@ -419,7 +419,7 @@ extension OrganizerViewController {
case .connectionStatus:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
cell.applyVPN(Theme.current, with: VPN.shared.isEnabled ? VPN.shared.status : nil, error: nil)
- cell.leftText = L10n.Service.Cells.ConnectionStatus.caption
+ cell.leftText = L10n.Core.Service.Cells.ConnectionStatus.caption
return cell
case .profile:
@@ -431,61 +431,61 @@ extension OrganizerViewController {
cell.imageView?.image = nil
}
cell.leftText = rowProfile.id
- cell.rightText = service.isActiveProfile(rowProfile) ? L10n.Organizer.Cells.Profile.Value.current : nil
+ cell.rightText = service.isActiveProfile(rowProfile) ? L10n.App.Organizer.Cells.Profile.Value.current : nil
return cell
case .addProvider:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
cell.applyAction(Theme.current)
- cell.leftText = L10n.Organizer.Cells.AddProvider.caption
+ cell.leftText = L10n.App.Organizer.Cells.AddProvider.caption
return cell
case .addHost:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
cell.applyAction(Theme.current)
- cell.leftText = L10n.Organizer.Cells.AddHost.caption
+ cell.leftText = L10n.App.Organizer.Cells.AddHost.caption
return cell
case .siriShortcuts:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
cell.applyAction(Theme.current)
- cell.leftText = L10n.Organizer.Cells.SiriShortcuts.caption
+ cell.leftText = L10n.Core.Organizer.Cells.SiriShortcuts.caption
return cell
case .donate:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Organizer.Cells.Donate.caption
+ cell.leftText = L10n.Core.Organizer.Cells.Donate.caption
return cell
case .patreon:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Organizer.Cells.Patreon.caption
+ cell.leftText = L10n.Core.Organizer.Cells.Patreon.caption
return cell
case .translate:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Organizer.Cells.Translate.caption
+ cell.leftText = L10n.Core.Organizer.Cells.Translate.caption
return cell
case .joinCommunity:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Organizer.Cells.JoinCommunity.caption
+ cell.leftText = L10n.Core.Organizer.Cells.JoinCommunity.caption
return cell
case .writeReview:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Organizer.Cells.WriteReview.caption
+ cell.leftText = L10n.Core.Organizer.Cells.WriteReview.caption
return cell
case .openAbout:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Organizer.Cells.About.caption(GroupConstants.App.name)
+ cell.leftText = L10n.Core.Organizer.Cells.About.caption(GroupConstants.App.name)
cell.rightText = Utils.versionString()
return cell
case .uninstall:
let cell = Cells.destructive.dequeue(from: tableView, for: indexPath)
- cell.caption = L10n.Organizer.Cells.Uninstall.caption
+ cell.caption = L10n.Core.Organizer.Cells.Uninstall.caption
return cell
case .testDisplayLog:
diff --git a/Passepartout-iOS/Scenes/Organizer/WizardHostViewController.swift b/Passepartout-iOS/Scenes/Organizer/WizardHostViewController.swift
index 19dfb0e8..53ce115d 100644
--- a/Passepartout-iOS/Scenes/Organizer/WizardHostViewController.swift
+++ b/Passepartout-iOS/Scenes/Organizer/WizardHostViewController.swift
@@ -52,10 +52,10 @@ class WizardHostViewController: UITableViewController, TableModelHost {
lazy var model: TableModel = {
let model: TableModel = TableModel()
model.add(.meta)
- model.setFooter(L10n.Global.Host.TitleInput.message, for: .meta)
+ model.setFooter(L10n.Core.Global.Host.TitleInput.message, for: .meta)
if !existingHosts.isEmpty {
model.add(.existing)
- model.setHeader(L10n.Wizards.Host.Sections.Existing.header, for: .existing)
+ model.setHeader(L10n.App.Wizards.Host.Sections.Existing.header, for: .existing)
}
model.set([.titleInput], in: .meta)
model.set(.existingHost, count: existingHosts.count, in: .existing)
@@ -70,8 +70,8 @@ class WizardHostViewController: UITableViewController, TableModelHost {
override func viewDidLoad() {
super.viewDidLoad()
- title = L10n.Organizer.Sections.Hosts.header
- itemNext.title = L10n.Global.next
+ title = L10n.Core.Organizer.Sections.Hosts.header
+ itemNext.title = L10n.Core.Global.next
}
override func viewWillAppear(_ animated: Bool) {
@@ -110,11 +110,11 @@ class WizardHostViewController: UITableViewController, TableModelHost {
let service = TransientStore.shared.service
guard !service.containsProfile(profile) else {
let replacedProfile = service.profile(withContext: profile.context, id: profile.id)
- let alert = Macros.alert(title, L10n.Wizards.Host.Alerts.Existing.message)
- alert.addDefaultAction(L10n.Global.ok) {
+ let alert = Macros.alert(title, L10n.Core.Wizards.Host.Alerts.Existing.message)
+ alert.addDefaultAction(L10n.Core.Global.ok) {
self.next(withProfile: profile, replacedProfile: replacedProfile)
}
- alert.addCancelAction(L10n.Global.cancel)
+ alert.addCancelAction(L10n.Core.Global.cancel)
present(alert, animated: true, completion: nil)
return
}
@@ -203,7 +203,7 @@ extension WizardHostViewController {
switch model.row(at: indexPath) {
case .titleInput:
let cell = Cells.field.dequeue(from: tableView, for: indexPath)
- cell.caption = L10n.Wizards.Host.Cells.TitleInput.caption
+ cell.caption = L10n.App.Wizards.Host.Cells.TitleInput.caption
cell.captionWidth = 100.0
cell.allowedCharset = .filename
cell.field.applyProfileId(Theme.current)
diff --git a/Passepartout-iOS/Scenes/Organizer/WizardProviderViewController.swift b/Passepartout-iOS/Scenes/Organizer/WizardProviderViewController.swift
index 1591e925..02553939 100644
--- a/Passepartout-iOS/Scenes/Organizer/WizardProviderViewController.swift
+++ b/Passepartout-iOS/Scenes/Organizer/WizardProviderViewController.swift
@@ -34,7 +34,7 @@ class WizardProviderViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
- title = L10n.Organizer.Sections.Providers.header
+ title = L10n.Core.Organizer.Sections.Providers.header
}
private func next(withName name: Infrastructure.Name) {
diff --git a/Passepartout-iOS/Scenes/ProviderPoolViewController.swift b/Passepartout-iOS/Scenes/ProviderPoolViewController.swift
index 7d8d9f4e..750a549f 100644
--- a/Passepartout-iOS/Scenes/ProviderPoolViewController.swift
+++ b/Passepartout-iOS/Scenes/ProviderPoolViewController.swift
@@ -72,7 +72,7 @@ class ProviderPoolViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
- title = L10n.Service.Cells.Provider.Pool.caption
+ title = L10n.Core.Service.Cells.Provider.Pool.caption
tableView.reloadData()
if let ip = selectedIndexPath {
tableView.selectRowAsync(at: ip)
diff --git a/Passepartout-iOS/Scenes/ProviderPresetViewController.swift b/Passepartout-iOS/Scenes/ProviderPresetViewController.swift
index d8901562..44654ecb 100644
--- a/Passepartout-iOS/Scenes/ProviderPresetViewController.swift
+++ b/Passepartout-iOS/Scenes/ProviderPresetViewController.swift
@@ -54,7 +54,7 @@ class ProviderPresetViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
- title = L10n.Service.Cells.Provider.Preset.caption
+ title = L10n.Core.Service.Cells.Provider.Preset.caption
tableView.reloadData()
if let ip = selectedIndexPath {
tableView.scrollToRowAsync(at: ip)
@@ -94,7 +94,7 @@ extension ProviderPresetViewController: UITableViewDataSource, UITableViewDelega
}
// func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
-// return L10n.Provider.Preset.Sections.Main.footer
+// return L10n.Core.Provider.Preset.Sections.Main.footer
// }
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
@@ -113,7 +113,7 @@ extension ProviderPresetViewController: UITableViewDataSource, UITableViewDelega
case .techDetails:
cell.applyAction(Theme.current)
- cell.leftText = L10n.Provider.Preset.Cells.TechDetails.caption
+ cell.leftText = L10n.App.Provider.Preset.Cells.TechDetails.caption
cell.accessoryType = .none
}
return cell
diff --git a/Passepartout-iOS/Scenes/ServiceViewController.swift b/Passepartout-iOS/Scenes/ServiceViewController.swift
index 249e7079..7db7521f 100644
--- a/Passepartout-iOS/Scenes/ServiceViewController.swift
+++ b/Passepartout-iOS/Scenes/ServiceViewController.swift
@@ -25,7 +25,6 @@
import UIKit
import NetworkExtension
-import CoreTelephony
import MBProgressHUD
import TunnelKit
import PassepartoutCore
@@ -98,7 +97,7 @@ class ServiceViewController: UIViewController, TableModelHost {
navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem
navigationItem.leftItemsSupplementBackButton = true
- labelWelcome.text = L10n.Service.Welcome.message
+ labelWelcome.text = L10n.App.Service.Welcome.message
labelWelcome.apply(Theme.current)
let nc = NotificationCenter.default
@@ -174,14 +173,14 @@ class ServiceViewController: UIViewController, TableModelHost {
case .hostParametersSegueIdentifier:
let vc = destination as? ConfigurationViewController
- vc?.title = L10n.Service.Cells.Host.Parameters.caption
+ vc?.title = L10n.App.Service.Cells.Host.Parameters.caption
vc?.initialConfiguration = uncheckedHostProfile.parameters.sessionConfiguration
vc?.originalConfigurationURL = service.configurationURL(for: uncheckedHostProfile)
vc?.delegate = self
case .networkSettingsSegueIdentifier:
let vc = destination as? NetworkSettingsViewController
- vc?.title = L10n.Service.Cells.NetworkSettings.caption
+ vc?.title = L10n.Core.NetworkSettings.title
vc?.profile = profile
case .debugLogSegueIdentifier:
@@ -218,19 +217,19 @@ class ServiceViewController: UIViewController, TableModelHost {
}
@IBAction private func renameProfile() {
- let alert = Macros.alert(L10n.Service.Alerts.Rename.title, L10n.Global.Host.TitleInput.message)
+ let alert = Macros.alert(L10n.Core.Service.Alerts.Rename.title, L10n.Core.Global.Host.TitleInput.message)
alert.addTextField { (field) in
field.text = self.profile?.id
field.applyProfileId(Theme.current)
field.delegate = self
}
- pendingRenameAction = alert.addDefaultAction(L10n.Global.ok) {
+ pendingRenameAction = alert.addDefaultAction(L10n.Core.Global.ok) {
guard let newId = alert.textFields?.first?.text else {
return
}
self.doRenameCurrentProfile(to: newId)
}
- alert.addCancelAction(L10n.Global.cancel)
+ alert.addCancelAction(L10n.Core.Global.cancel)
pendingRenameAction?.isEnabled = false
present(alert, animated: true, completion: nil)
}
@@ -247,10 +246,10 @@ class ServiceViewController: UIViewController, TableModelHost {
}
guard !service.needsCredentials(for: uncheckedProfile) else {
let alert = Macros.alert(
- L10n.Service.Sections.Vpn.header,
- L10n.Service.Alerts.CredentialsNeeded.message
+ L10n.App.Service.Sections.Vpn.header,
+ L10n.Core.Service.Alerts.CredentialsNeeded.message
)
- alert.addCancelAction(L10n.Global.ok) {
+ alert.addCancelAction(L10n.Core.Global.ok) {
cell.setOn(false, animated: true)
}
present(alert, animated: true, completion: nil)
@@ -285,13 +284,13 @@ class ServiceViewController: UIViewController, TableModelHost {
private func confirmVpnReconnection() {
guard vpn.status == .disconnected else {
let alert = Macros.alert(
- L10n.Service.Cells.ConnectionStatus.caption,
- L10n.Service.Alerts.ReconnectVpn.message
+ L10n.Core.Service.Cells.ConnectionStatus.caption,
+ L10n.Core.Service.Alerts.ReconnectVpn.message
)
- alert.addDefaultAction(L10n.Global.ok) {
+ alert.addDefaultAction(L10n.Core.Global.ok) {
self.vpn.reconnect(completionHandler: nil)
}
- alert.addCancelAction(L10n.Global.cancel)
+ alert.addCancelAction(L10n.Core.Global.cancel)
present(alert, animated: true, completion: nil)
return
}
@@ -349,13 +348,13 @@ class ServiceViewController: UIViewController, TableModelHost {
return
}
let alert = Macros.alert(
- L10n.Service.Sections.Trusted.header,
- L10n.Service.Alerts.Trusted.WillDisconnectPolicy.message
+ L10n.Core.Service.Sections.Trusted.header,
+ L10n.Core.Service.Alerts.Trusted.WillDisconnectPolicy.message
)
- alert.addDefaultAction(L10n.Global.ok) {
+ alert.addDefaultAction(L10n.Core.Global.ok) {
completionHandler()
}
- alert.addCancelAction(L10n.Global.cancel) {
+ alert.addCancelAction(L10n.Core.Global.cancel) {
sender.setOn(false, animated: true)
}
present(alert, animated: true, completion: nil)
@@ -363,13 +362,13 @@ class ServiceViewController: UIViewController, TableModelHost {
private func confirmPotentialTrustedDisconnection(at rowIndex: Int?, completionHandler: @escaping () -> Void) {
let alert = Macros.alert(
- L10n.Service.Sections.Trusted.header,
- L10n.Service.Alerts.Trusted.WillDisconnectTrusted.message
+ L10n.Core.Service.Sections.Trusted.header,
+ L10n.Core.Service.Alerts.Trusted.WillDisconnectTrusted.message
)
- alert.addDefaultAction(L10n.Global.ok) {
+ alert.addDefaultAction(L10n.Core.Global.ok) {
completionHandler()
}
- alert.addCancelAction(L10n.Global.cancel) {
+ alert.addCancelAction(L10n.Core.Global.cancel) {
guard let rowIndex = rowIndex else {
return
}
@@ -385,12 +384,12 @@ class ServiceViewController: UIViewController, TableModelHost {
Utils.checkConnectivityURL(AppConstants.Web.connectivityURL, timeout: AppConstants.Web.connectivityTimeout) {
hud.hide()
- let V = L10n.Service.Alerts.TestConnectivity.Messages.self
+ let V = L10n.Core.Service.Alerts.TestConnectivity.Messages.self
let alert = Macros.alert(
- L10n.Service.Alerts.TestConnectivity.title,
+ L10n.Core.Service.Alerts.TestConnectivity.title,
$0 ? V.success : V.failure
)
- alert.addCancelAction(L10n.Global.ok)
+ alert.addCancelAction(L10n.Core.Global.ok)
self.present(alert, animated: true, completion: nil)
}
}
@@ -398,10 +397,10 @@ class ServiceViewController: UIViewController, TableModelHost {
// private func displayDataCount() {
// guard vpn.isEnabled else {
// let alert = Macros.alert(
-// L10n.Service.Cells.DataCount.caption,
-// L10n.Service.Alerts.DataCount.Messages.notAvailable
+// L10n.Core.Service.Cells.DataCount.caption,
+// L10n.Core.Service.Alerts.DataCount.Messages.notAvailable
// )
-// alert.addCancelAction(L10n.Global.ok)
+// alert.addCancelAction(L10n.Core.Global.ok)
// present(alert, animated: true, completion: nil)
// return
// }
@@ -409,15 +408,15 @@ class ServiceViewController: UIViewController, TableModelHost {
// vpn.requestBytesCount {
// let message: String
// if let count = $0 {
-// message = L10n.Service.Alerts.DataCount.Messages.current(Int(count.0), Int(count.1))
+// message = L10n.Core.Service.Alerts.DataCount.Messages.current(Int(count.0), Int(count.1))
// } else {
-// message = L10n.Service.Alerts.DataCount.Messages.notAvailable
+// message = L10n.Core.Service.Alerts.DataCount.Messages.notAvailable
// }
// let alert = Macros.alert(
-// L10n.Service.Cells.DataCount.caption,
+// L10n.Core.Service.Cells.DataCount.caption,
// message
// )
-// alert.addCancelAction(L10n.Global.ok)
+// alert.addCancelAction(L10n.Core.Global.ok)
// self.present(alert, animated: true, completion: nil)
// }
// }
@@ -430,15 +429,15 @@ class ServiceViewController: UIViewController, TableModelHost {
guard vpn.status == .disconnected else {
let alert = Macros.alert(
- L10n.Service.Cells.MasksPrivateData.caption,
- L10n.Service.Alerts.MasksPrivateData.Messages.mustReconnect
+ L10n.Core.Service.Cells.MasksPrivateData.caption,
+ L10n.Core.Service.Alerts.MasksPrivateData.Messages.mustReconnect
)
- alert.addDestructiveAction(L10n.Service.Alerts.Buttons.reconnect) {
+ alert.addDestructiveAction(L10n.Core.Service.Alerts.Buttons.reconnect) {
handler()
self.shouldDeleteLogOnDisconnection = true
self.vpn.reconnect(completionHandler: nil)
}
- alert.addCancelAction(L10n.Global.cancel) {
+ alert.addCancelAction(L10n.Core.Global.cancel) {
cell.setOn(!cell.isOn, animated: true)
}
present(alert, animated: true, completion: nil)
@@ -464,11 +463,11 @@ class ServiceViewController: UIViewController, TableModelHost {
}
let alert = Macros.alert(
- L10n.Service.Alerts.Download.title,
- L10n.Service.Alerts.Download.message(providerProfile.name.rawValue)
+ L10n.Core.Service.Alerts.Download.title,
+ L10n.Core.Service.Alerts.Download.message(providerProfile.name.rawValue)
)
- alert.addCancelAction(L10n.Global.cancel)
- alert.addDefaultAction(L10n.Global.ok) {
+ alert.addCancelAction(L10n.Core.Global.cancel)
+ alert.addDefaultAction(L10n.Core.Global.ok) {
self.confirmDownload(URL(string: downloadURL)!)
}
present(alert, animated: true, completion: nil)
@@ -483,15 +482,15 @@ class ServiceViewController: UIViewController, TableModelHost {
private func handleDownloadedProviderResources(url: URL?, error: Error?) {
guard let url = url else {
let alert = Macros.alert(
- L10n.Service.Alerts.Download.title,
- L10n.Service.Alerts.Download.failed(error?.localizedDescription ?? "")
+ L10n.Core.Service.Alerts.Download.title,
+ L10n.Core.Service.Alerts.Download.failed(error?.localizedDescription ?? "")
)
- alert.addCancelAction(L10n.Global.ok)
+ alert.addCancelAction(L10n.Core.Global.ok)
present(alert, animated: true, completion: nil)
return
}
- let hud = HUD(label: L10n.Service.Alerts.Download.Hud.extracting)
+ let hud = HUD(label: L10n.Core.Service.Alerts.Download.Hud.extracting)
hud.show()
uncheckedProviderProfile.name.importExternalResources(from: url) {
hud.hide()
@@ -661,7 +660,7 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String? {
let rows = model.rows(for: section)
if rows.contains(.providerRefresh), let date = lastInfrastructureUpdate {
- return L10n.Service.Sections.ProviderInfrastructure.footer(date.timestamp)
+ return L10n.Core.Service.Sections.ProviderInfrastructure.footer(date.timestamp)
}
return model.footer(for: section)
}
@@ -680,7 +679,7 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
case .useProfile:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
cell.applyAction(Theme.current)
- cell.leftText = L10n.Service.Cells.UseProfile.caption
+ cell.leftText = L10n.App.Service.Cells.UseProfile.caption
return cell
case .vpnService:
@@ -689,7 +688,7 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
}
let cell = Cells.toggle.dequeue(from: tableView, for: indexPath, tag: row.rawValue, delegate: self)
- cell.caption = L10n.Service.Cells.VpnService.caption
+ cell.caption = L10n.App.Service.Cells.VpnService.caption
cell.isOn = vpn.isEnabled
return cell
@@ -700,7 +699,7 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
cell.applyVPN(Theme.current, with: vpn.isEnabled ? vpn.status : nil, error: service.vpnLastError)
- cell.leftText = L10n.Service.Cells.ConnectionStatus.caption
+ cell.leftText = L10n.Core.Service.Cells.ConnectionStatus.caption
cell.accessoryType = .none
cell.isTappable = false
return cell
@@ -708,7 +707,7 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
case .reconnect:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
cell.applyAction(Theme.current)
- cell.leftText = L10n.Service.Cells.Reconnect.caption
+ cell.leftText = L10n.App.Service.Cells.Reconnect.caption
cell.accessoryType = .none
cell.isTappable = !service.needsCredentials(for: uncheckedProfile) && vpn.isEnabled
return cell
@@ -717,15 +716,15 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
case .account:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Service.Cells.Account.caption
+ cell.leftText = L10n.Core.Account.title
cell.rightText = profile?.username
return cell
case .endpoint:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Service.Cells.Endpoint.caption
+ cell.leftText = L10n.Core.Endpoint.title
- let V = L10n.Global.Cells.self
+ let V = L10n.Core.Global.Values.self
if let provider = profile as? ProviderConnectionProfile {
cell.rightText = provider.usesProviderEndpoint ? V.manual : V.automatic
} else {
@@ -735,27 +734,27 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
case .networkSettings:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Service.Cells.NetworkSettings.caption
+ cell.leftText = L10n.Core.NetworkSettings.title
return cell
// provider cells
case .providerPool:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Service.Cells.Provider.Pool.caption
+ cell.leftText = L10n.Core.Service.Cells.Provider.Pool.caption
cell.rightText = uncheckedProviderProfile.pool?.localizedId
return cell
case .providerPreset:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Service.Cells.Provider.Preset.caption
+ cell.leftText = L10n.Core.Service.Cells.Provider.Preset.caption
cell.rightText = uncheckedProviderProfile.preset?.name // XXX: localize?
return cell
case .providerRefresh:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
cell.applyAction(Theme.current)
- cell.leftText = L10n.Service.Cells.Provider.Refresh.caption
+ cell.leftText = L10n.App.Service.Cells.Provider.Refresh.caption
return cell
// host cells
@@ -763,7 +762,7 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
case .hostParameters:
let parameters = uncheckedHostProfile.parameters
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Service.Cells.Host.Parameters.caption
+ cell.leftText = L10n.App.Service.Cells.Host.Parameters.caption
if !parameters.sessionConfiguration.fallbackCipher.embedsDigest {
cell.rightText = "\(parameters.sessionConfiguration.fallbackCipher.genericName) / \(parameters.sessionConfiguration.fallbackDigest.genericName)"
} else {
@@ -775,19 +774,19 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
case .vpnResolvesHostname:
let cell = Cells.toggle.dequeue(from: tableView, for: indexPath, tag: row.rawValue, delegate: self)
- cell.caption = L10n.Service.Cells.VpnResolvesHostname.caption
+ cell.caption = L10n.Core.Service.Cells.VpnResolvesHostname.caption
cell.isOn = service.preferences.resolvesHostname
return cell
case .vpnSurvivesSleep:
let cell = Cells.toggle.dequeue(from: tableView, for: indexPath, tag: row.rawValue, delegate: self)
- cell.caption = L10n.Service.Cells.VpnSurvivesSleep.caption
+ cell.caption = L10n.Core.Service.Cells.VpnSurvivesSleep.caption
cell.isOn = !service.preferences.disconnectsOnSleep
return cell
case .trustedMobile:
let cell = Cells.toggle.dequeue(from: tableView, for: indexPath, tag: row.rawValue, delegate: self)
- cell.caption = L10n.Service.Cells.TrustedMobile.caption
+ cell.caption = L10n.Core.Service.Cells.TrustedMobile.caption
cell.isOn = service.preferences.trustsMobileNetwork
return cell
@@ -801,12 +800,12 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
case .trustedAddCurrentWiFi:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
cell.applyAction(Theme.current)
- cell.leftText = L10n.Service.Cells.TrustedAddWifi.caption
+ cell.leftText = L10n.App.Service.Cells.TrustedAddWifi.caption
return cell
case .trustedPolicy:
let cell = Cells.toggle.dequeue(from: tableView, for: indexPath, tag: row.rawValue, delegate: self)
- cell.caption = L10n.Service.Cells.TrustedPolicy.caption
+ cell.caption = L10n.Core.Service.Cells.TrustedPolicy.caption
cell.isOn = (service.preferences.trustPolicy == .disconnect)
return cell
@@ -814,18 +813,18 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
case .testConnectivity:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Service.Cells.TestConnectivity.caption
+ cell.leftText = L10n.Core.Service.Cells.TestConnectivity.caption
return cell
case .dataCount:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Service.Cells.DataCount.caption
+ cell.leftText = L10n.Core.Service.Cells.DataCount.caption
if let count = currentDataCount, vpn.status == .connected {
let down = count.0.dataUnitDescription
let up = count.1.dataUnitDescription
cell.rightText = "↓\(down) / ↑\(up)"
} else {
- cell.rightText = L10n.Service.Cells.DataCount.none
+ cell.rightText = L10n.Core.Service.Cells.DataCount.none
}
cell.accessoryType = .none
cell.isTappable = false
@@ -833,12 +832,12 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
case .debugLog:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Service.Cells.DebugLog.caption
+ cell.leftText = L10n.Core.Service.Cells.DebugLog.caption
return cell
case .masksPrivateData:
let cell = Cells.toggle.dequeue(from: tableView, for: indexPath, tag: row.rawValue, delegate: self)
- cell.caption = L10n.Service.Cells.MasksPrivateData.caption
+ cell.caption = L10n.Core.Service.Cells.MasksPrivateData.caption
cell.isOn = TransientStore.masksPrivateData
return cell
@@ -846,7 +845,7 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
case .reportIssue:
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
- cell.leftText = L10n.Service.Cells.ReportIssue.caption
+ cell.leftText = L10n.Core.Service.Cells.ReportIssue.caption
return cell
}
}
@@ -933,10 +932,10 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
guard trustedNetworks.addCurrentWifi() else {
let alert = Macros.alert(
- L10n.Service.Sections.Trusted.header,
- L10n.Service.Alerts.Trusted.NoNetwork.message
+ L10n.Core.Service.Sections.Trusted.header,
+ L10n.Core.Service.Alerts.Trusted.NoNetwork.message
)
- alert.addCancelAction(L10n.Global.ok)
+ alert.addCancelAction(L10n.Core.Global.ok)
present(alert, animated: true, completion: nil)
return false
}
@@ -1034,31 +1033,31 @@ extension ServiceViewController: UITableViewDataSource, UITableViewDelegate, Tog
}
// headers
- model.setHeader(L10n.Service.Sections.Vpn.header, for: .vpn)
+ model.setHeader(L10n.App.Service.Sections.Vpn.header, for: .vpn)
if isProvider {
- model.setHeader(L10n.Service.Sections.Configuration.header, for: .authentication)
+ model.setHeader(L10n.App.Service.Sections.Configuration.header, for: .authentication)
} else {
- model.setHeader(L10n.Service.Sections.Configuration.header, for: .configuration)
+ model.setHeader(L10n.App.Service.Sections.Configuration.header, for: .configuration)
}
if isActiveProfile {
if isProvider {
model.setHeader("", for: .vpnResolvesHostname)
model.setHeader("", for: .vpnSurvivesSleep)
}
- model.setHeader(L10n.Service.Sections.Trusted.header, for: .trusted)
- model.setHeader(L10n.Service.Sections.Diagnostics.header, for: .diagnostics)
- model.setHeader(L10n.Organizer.Sections.Feedback.header, for: .feedback)
+ model.setHeader(L10n.Core.Service.Sections.Trusted.header, for: .trusted)
+ model.setHeader(L10n.Core.Service.Sections.Diagnostics.header, for: .diagnostics)
+ model.setHeader(L10n.Core.Organizer.Sections.Feedback.header, for: .feedback)
}
// footers
if isActiveProfile {
- model.setFooter(L10n.Service.Sections.Vpn.footer, for: .vpn)
+ model.setFooter(L10n.Core.Service.Sections.Vpn.footer, for: .vpn)
if isProvider {
- model.setFooter(L10n.Service.Sections.VpnResolvesHostname.footer, for: .vpnResolvesHostname)
+ model.setFooter(L10n.Core.Service.Sections.VpnResolvesHostname.footer, for: .vpnResolvesHostname)
}
- model.setFooter(L10n.Service.Sections.VpnSurvivesSleep.footer, for: .vpnSurvivesSleep)
- model.setFooter(L10n.Service.Sections.Trusted.footer, for: .trustedPolicy)
- model.setFooter(L10n.Service.Sections.Diagnostics.footer, for: .diagnostics)
+ model.setFooter(L10n.Core.Service.Sections.VpnSurvivesSleep.footer, for: .vpnSurvivesSleep)
+ model.setFooter(L10n.Core.Service.Sections.Trusted.footer, for: .trustedPolicy)
+ model.setFooter(L10n.Core.Service.Sections.Diagnostics.footer, for: .diagnostics)
}
// rows
diff --git a/Passepartout-iOS/Scenes/Shortcuts/ShortcutsAddViewController.swift b/Passepartout-iOS/Scenes/Shortcuts/ShortcutsAddViewController.swift
index ee6fc2c4..363bfd49 100644
--- a/Passepartout-iOS/Scenes/Shortcuts/ShortcutsAddViewController.swift
+++ b/Passepartout-iOS/Scenes/Shortcuts/ShortcutsAddViewController.swift
@@ -41,9 +41,9 @@ class ShortcutsAddViewController: UITableViewController, TableModelHost {
model.set([.connect, .enableVPN, .disableVPN], in: .vpn)
model.set([.trustCurrentWiFi, .untrustCurrentWiFi], in: .wifi)
model.set([.trustCellular, .untrustCellular], in: .cellular)
- model.setHeader(L10n.Shortcuts.Add.Sections.Vpn.header, for: .vpn)
- model.setHeader(L10n.Shortcuts.Add.Sections.Wifi.header, for: .wifi)
- model.setHeader(L10n.Shortcuts.Add.Sections.Cellular.header, for: .cellular)
+ model.setHeader(L10n.Core.Shortcuts.Add.Sections.Vpn.header, for: .vpn)
+ model.setHeader(L10n.Core.Shortcuts.Add.Sections.Wifi.header, for: .wifi)
+ model.setHeader(L10n.Core.Shortcuts.Add.Sections.Cellular.header, for: .cellular)
return model
}()
@@ -55,7 +55,7 @@ class ShortcutsAddViewController: UITableViewController, TableModelHost {
override func viewDidLoad() {
super.viewDidLoad()
- title = L10n.Shortcuts.Add.title
+ title = L10n.App.Shortcuts.Add.title
}
// MARK: UITableViewController
@@ -100,25 +100,25 @@ class ShortcutsAddViewController: UITableViewController, TableModelHost {
let cell = Cells.setting.dequeue(from: tableView, for: indexPath)
switch model.row(at: indexPath) {
case .connect:
- cell.leftText = L10n.Shortcuts.Add.Cells.Connect.caption
+ cell.leftText = L10n.Core.Shortcuts.Add.Cells.Connect.caption
case .enableVPN:
- cell.leftText = L10n.Shortcuts.Add.Cells.EnableVpn.caption
+ cell.leftText = L10n.Core.Shortcuts.Add.Cells.EnableVpn.caption
case .disableVPN:
- cell.leftText = L10n.Shortcuts.Add.Cells.DisableVpn.caption
+ cell.leftText = L10n.Core.Shortcuts.Add.Cells.DisableVpn.caption
case .trustCurrentWiFi:
- cell.leftText = L10n.Shortcuts.Add.Cells.TrustCurrentWifi.caption
+ cell.leftText = L10n.Core.Shortcuts.Add.Cells.TrustCurrentWifi.caption
case .untrustCurrentWiFi:
- cell.leftText = L10n.Shortcuts.Add.Cells.UntrustCurrentWifi.caption
+ cell.leftText = L10n.Core.Shortcuts.Add.Cells.UntrustCurrentWifi.caption
case .trustCellular:
- cell.leftText = L10n.Shortcuts.Add.Cells.TrustCellular.caption
+ cell.leftText = L10n.Core.Shortcuts.Add.Cells.TrustCellular.caption
case .untrustCellular:
- cell.leftText = L10n.Shortcuts.Add.Cells.UntrustCellular.caption
+ cell.leftText = L10n.Core.Shortcuts.Add.Cells.UntrustCellular.caption
}
return cell
}
@@ -159,10 +159,10 @@ class ShortcutsAddViewController: UITableViewController, TableModelHost {
private func addConnect() {
guard TransientStore.shared.service.hasProfiles() else {
let alert = Macros.alert(
- L10n.Shortcuts.Add.Cells.Connect.caption,
- L10n.Shortcuts.Add.Alerts.NoProfiles.message
+ L10n.Core.Shortcuts.Add.Cells.Connect.caption,
+ L10n.Core.Shortcuts.Add.Alerts.NoProfiles.message
)
- alert.addAction(L10n.Global.ok) {
+ alert.addAction(L10n.Core.Global.ok) {
if let ip = self.tableView.indexPathForSelectedRow {
self.tableView.deselectRow(at: ip, animated: true)
}
diff --git a/Passepartout-iOS/Scenes/Shortcuts/ShortcutsConnectToViewController.swift b/Passepartout-iOS/Scenes/Shortcuts/ShortcutsConnectToViewController.swift
index 02f7759f..865fcfe9 100644
--- a/Passepartout-iOS/Scenes/Shortcuts/ShortcutsConnectToViewController.swift
+++ b/Passepartout-iOS/Scenes/Shortcuts/ShortcutsConnectToViewController.swift
@@ -44,8 +44,8 @@ class ShortcutsConnectToViewController: UITableViewController, ProviderPoolViewC
let model: TableModel = {
let model: TableModel = TableModel()
- model.setHeader(L10n.Organizer.Sections.Providers.header, for: .providers)
- model.setHeader(L10n.Organizer.Sections.Hosts.header, for: .hosts)
+ model.setHeader(L10n.Core.Organizer.Sections.Providers.header, for: .providers)
+ model.setHeader(L10n.Core.Organizer.Sections.Hosts.header, for: .hosts)
return model
}()
@@ -68,7 +68,7 @@ class ShortcutsConnectToViewController: UITableViewController, ProviderPoolViewC
override func viewDidLoad() {
super.viewDidLoad()
- title = L10n.Shortcuts.Add.Cells.Connect.caption
+ title = L10n.Core.Shortcuts.Add.Cells.Connect.caption
reloadModel()
}
diff --git a/Passepartout-iOS/Scenes/Shortcuts/ShortcutsViewController.swift b/Passepartout-iOS/Scenes/Shortcuts/ShortcutsViewController.swift
index e655187d..0f3a4cac 100644
--- a/Passepartout-iOS/Scenes/Shortcuts/ShortcutsViewController.swift
+++ b/Passepartout-iOS/Scenes/Shortcuts/ShortcutsViewController.swift
@@ -75,7 +75,7 @@ class ShortcutsViewController: UITableViewController, INUIAddVoiceShortcutViewCo
let model: TableModel = {
let model: TableModel = TableModel()
model.add(.all)
- model.setHeader(L10n.Shortcuts.Edit.Sections.All.header, for: .all)
+ model.setHeader(L10n.Core.Shortcuts.Edit.Sections.All.header, for: .all)
model.set([], in: .all)
return model
}()
@@ -91,7 +91,7 @@ class ShortcutsViewController: UITableViewController, INUIAddVoiceShortcutViewCo
override func viewDidLoad() {
super.viewDidLoad()
- title = L10n.Organizer.Cells.SiriShortcuts.caption
+ title = L10n.Core.Organizer.Cells.SiriShortcuts.caption
INVoiceShortcutCenter.shared.getAllVoiceShortcuts { [weak self] (shortcuts, error) in
DispatchQueue.main.async {
@@ -121,9 +121,9 @@ class ShortcutsViewController: UITableViewController, INUIAddVoiceShortcutViewCo
// TODO: really show it?
// let alert = Macros.alert(
// title,
-// L10n.Shortcuts.Edit.message(error?.localizedDescription ?? "")
+// L10n.Core.Shortcuts.Edit.message(error?.localizedDescription ?? "")
// )
-// alert.addCancelAction(L10n.Global.ok) {
+// alert.addCancelAction(L10n.Core.Global.ok) {
// self.close()
// }
// present(alert, animated: true, completion: nil)
@@ -191,7 +191,7 @@ class ShortcutsViewController: UITableViewController, INUIAddVoiceShortcutViewCo
case .addShortcut:
cell.applyAction(Theme.current)
- cell.leftText = L10n.Shortcuts.Edit.Cells.AddShortcut.caption
+ cell.leftText = L10n.App.Shortcuts.Edit.Cells.AddShortcut.caption
cell.accessoryType = .none
cell.isTappable = true
}
diff --git a/Passepartout.xcodeproj/project.pbxproj b/Passepartout.xcodeproj/project.pbxproj
index 79f438cd..2bff6ba7 100644
--- a/Passepartout.xcodeproj/project.pbxproj
+++ b/Passepartout.xcodeproj/project.pbxproj
@@ -27,7 +27,6 @@
0E3152BC223FA03D00F61841 /* ApplicationError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E6BE13920CFB76800A6DD36 /* ApplicationError.swift */; };
0E3152BD223FA03D00F61841 /* GroupConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EDE8DED20C93E4C004C739C /* GroupConstants.swift */; };
0E3152BE223FA03D00F61841 /* Reviewer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E78179E21BE852200950C58 /* Reviewer.swift */; };
- 0E3152BF223FA03D00F61841 /* SwiftGen+Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E05C5E320D1993C006EE732 /* SwiftGen+Strings.swift */; };
0E3152C0223FA03D00F61841 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E4FD7ED20D539A0002221FF /* Utils.swift */; };
0E3152C1223FA04800F61841 /* GracefulVPN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E5E5DE421511C5F00E318A3 /* GracefulVPN.swift */; };
0E3152C2223FA04800F61841 /* MockVPNProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E4FD7E020D3E4C5002221FF /* MockVPNProvider.swift */; };
@@ -61,10 +60,12 @@
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 */; };
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 */; };
+ 0E45E6E022BD793800F19312 /* App.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0E45E6E222BD793800F19312 /* App.strings */; };
+ 0E45E6E422BD799700F19312 /* SwiftGen+Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E45E6E322BD799700F19312 /* SwiftGen+Strings.swift */; };
+ 0E45E6FA22BD8FC500F19312 /* Core.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0E3CAF98229AAE760008E5C8 /* Core.strings */; };
0E4C9CBB20DCF0D600A0C59C /* DestructiveTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E4C9CBA20DCF0D600A0C59C /* DestructiveTableViewCell.swift */; };
0E4FD7F120D58618002221FF /* Macros.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E4FD7F020D58618002221FF /* Macros.swift */; };
0E533B162258E03B00EF94FC /* PoolGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E533B152258E03B00EF94FC /* PoolGroup.swift */; };
@@ -160,7 +161,6 @@
/* Begin PBXFileReference section */
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 = ""; };
- 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 = ""; };
0E1066C820E0F84A004F98B7 /* Cells.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cells.swift; sourceTree = ""; };
0E158AD920E11B0B00C85A82 /* EndpointViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EndpointViewController.swift; sourceTree = ""; };
@@ -181,17 +181,28 @@
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 = ""; };
- 0E3CAF99229AAE760008E5C8 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; };
- 0E3CAF9C229AAE760008E5C8 /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/Localizable.strings; sourceTree = ""; };
- 0E3CAF9E229AAE760008E5C8 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; };
- 0E3CAFA0229AAE760008E5C8 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = ""; };
- 0E3CAFAB229AAE760008E5C8 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Localizable.strings; sourceTree = ""; };
+ 0E3CAF99229AAE760008E5C8 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Core.strings; sourceTree = ""; };
+ 0E3CAF9C229AAE760008E5C8 /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/Core.strings; sourceTree = ""; };
+ 0E3CAF9E229AAE760008E5C8 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Core.strings; sourceTree = ""; };
+ 0E3CAFA0229AAE760008E5C8 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Core.strings; sourceTree = ""; };
+ 0E3CAFAB229AAE760008E5C8 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Core.strings; sourceTree = ""; };
0E3CAFAE229AAE760008E5C8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; name = Base; path = Base.lproj/Intents.intentdefinition; sourceTree = ""; };
- 0E3CAFB1229AAE760008E5C8 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Localizable.strings; sourceTree = ""; };
- 0E3CAFB3229AAE760008E5C8 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = ""; };
- 0E3CAFB5229AAE760008E5C8 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Localizable.strings; sourceTree = ""; };
+ 0E3CAFB1229AAE760008E5C8 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Core.strings; sourceTree = ""; };
+ 0E3CAFB3229AAE760008E5C8 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Core.strings; sourceTree = ""; };
+ 0E3CAFB5229AAE760008E5C8 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Core.strings; sourceTree = ""; };
0E3CAFC3229AAF8E0008E5C8 /* API */ = {isa = PBXFileReference; lastKnownFileType = folder; path = API; sourceTree = ""; };
0E3DA370215CB5BF00B40FC9 /* VersionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionViewController.swift; sourceTree = ""; };
+ 0E45E6E122BD793800F19312 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/App.strings; sourceTree = ""; };
+ 0E45E6E322BD799700F19312 /* SwiftGen+Strings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "SwiftGen+Strings.swift"; sourceTree = ""; };
+ 0E45E6F122BD897E00F19312 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/App.strings; sourceTree = ""; };
+ 0E45E6F222BD898000F19312 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/App.strings; sourceTree = ""; };
+ 0E45E6F322BD898200F19312 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/App.strings; sourceTree = ""; };
+ 0E45E6F422BD898300F19312 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/App.strings; sourceTree = ""; };
+ 0E45E6F522BD898500F19312 /* el */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = el; path = el.lproj/App.strings; sourceTree = ""; };
+ 0E45E6F622BD898700F19312 /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/App.strings; sourceTree = ""; };
+ 0E45E6F722BD898800F19312 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/App.strings; sourceTree = ""; };
+ 0E45E6F822BD898A00F19312 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/App.strings; sourceTree = ""; };
+ 0E45E6F922BD898B00F19312 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/App.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 = ""; };
@@ -209,11 +220,11 @@
0E5E5DE421511C5F00E318A3 /* GracefulVPN.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GracefulVPN.swift; sourceTree = ""; };
0E66A26F225FE25800F9C779 /* PoolCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = PoolCategory.swift; path = ../Model/Profiles/PoolCategory.swift; sourceTree = ""; };
0E6ACB7722B1A57C001B3C99 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/Intents.strings; sourceTree = ""; };
- 0E6ACB7822B1A5BB001B3C99 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/Localizable.strings; sourceTree = ""; };
+ 0E6ACB7822B1A5BB001B3C99 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/Core.strings; sourceTree = ""; };
0E6BE13920CFB76800A6DD36 /* ApplicationError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationError.swift; sourceTree = ""; };
0E6BE13E20CFBAB300A6DD36 /* DebugLogViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DebugLogViewController.swift; sourceTree = ""; };
0E773BF7224BF37600CDDC8E /* ShortcutsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShortcutsViewController.swift; sourceTree = ""; };
- 0E776575229CF65D0023FA76 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; };
+ 0E776575229CF65D0023FA76 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Core.strings; sourceTree = ""; };
0E776637229D0D9E0023FA76 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Intents.strings; sourceTree = ""; };
0E776638229D0D9F0023FA76 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Intents.strings; sourceTree = ""; };
0E776639229D0DA00023FA76 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Intents.strings; sourceTree = ""; };
@@ -374,8 +385,8 @@
0E3CAF97229AAE760008E5C8 /* Resources */ = {
isa = PBXGroup;
children = (
+ 0E3CAF98229AAE760008E5C8 /* Core.strings */,
0E3CAFAD229AAE760008E5C8 /* Intents.intentdefinition */,
- 0E3CAF98229AAE760008E5C8 /* Localizable.strings */,
);
path = Resources;
sourceTree = "";
@@ -528,6 +539,7 @@
0EDE8DEC20C93E3B004C739C /* Global */ = {
isa = PBXGroup;
children = (
+ 0E45E6E222BD793800F19312 /* App.strings */,
0EA068F3218475F800C320AD /* ConfigurationParserResult+Alerts.swift */,
0EEB53B1225D525B00746300 /* Downloader.swift */,
0EF5CF242141CE58004FF1BD /* HUD.swift */,
@@ -538,6 +550,7 @@
0ECC60DD2256B6890020BEAC /* SwiftGen+Assets.swift */,
0EDE8DE320C89028004C739C /* SwiftGen+Scenes.swift */,
0EF56BBA2185AC8500B0C8AB /* SwiftGen+Segues.swift */,
+ 0E45E6E322BD799700F19312 /* SwiftGen+Strings.swift */,
0E05C61C20D27C82006EE732 /* Theme.swift */,
0ECEE44F20E1182E00A6BB43 /* Theme+Cells.swift */,
0E2B493F20FCFF990094784C /* Theme+Titles.swift */,
@@ -566,7 +579,6 @@
0E6BE13920CFB76800A6DD36 /* ApplicationError.swift */,
0EDE8DED20C93E4C004C739C /* GroupConstants.swift */,
0E78179E21BE852200950C58 /* Reviewer.swift */,
- 0E05C5E320D1993C006EE732 /* SwiftGen+Strings.swift */,
0E4FD7ED20D539A0002221FF /* Utils.swift */,
);
path = Sources;
@@ -791,7 +803,6 @@
buildActionMask = 2147483647;
files = (
0E3CAFC4229AAF8E0008E5C8 /* API in Resources */,
- 0E3CAFB7229AAE770008E5C8 /* Localizable.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -804,9 +815,11 @@
0E24273A225950450064A1A3 /* About.storyboard in Resources */,
0E57F64620C83FC7008323CF /* LaunchScreen.storyboard in Resources */,
0E57F64320C83FC7008323CF /* Assets.xcassets in Resources */,
+ 0E45E6FA22BD8FC500F19312 /* Core.strings in Resources */,
0E9CD7872257462800D033B4 /* Providers.xcassets in Resources */,
0E9CD789225746B300D033B4 /* Flags.xcassets in Resources */,
0E57F64120C83FC5008323CF /* Main.storyboard in Resources */,
+ 0E45E6E022BD793800F19312 /* App.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -941,7 +954,6 @@
0E3152C5223FA04800F61841 /* VPNConfiguration.swift in Sources */,
0E3152C8223FA04D00F61841 /* Infrastructure.swift in Sources */,
0E3152D8223FA05400F61841 /* TrustPolicy.swift in Sources */,
- 0E3152BF223FA03D00F61841 /* SwiftGen+Strings.swift in Sources */,
0E3152DC223FA05800F61841 /* ProviderConnectionProfile.swift in Sources */,
0E3152D9223FA05800F61841 /* HostConnectionProfile.swift in Sources */,
0E3152D6223FA05400F61841 /* TransientStore.swift in Sources */,
@@ -976,6 +988,7 @@
0EBE3A79213C4E5500BFA2F5 /* OrganizerViewController.swift in Sources */,
0E4FD7F120D58618002221FF /* Macros.swift in Sources */,
0EF5CF252141CE58004FF1BD /* HUD.swift in Sources */,
+ 0E45E6E422BD799700F19312 /* SwiftGen+Strings.swift in Sources */,
0E05C5D720D1645F006EE732 /* ToggleTableViewCell.swift in Sources */,
0EFB901A2276D7F1006405E4 /* NetworkSettingsViewController.swift in Sources */,
0E05C5D420D1645F006EE732 /* FieldTableViewCell.swift in Sources */,
@@ -1059,7 +1072,7 @@
name = Shortcuts.storyboard;
sourceTree = "";
};
- 0E3CAF98229AAE760008E5C8 /* Localizable.strings */ = {
+ 0E3CAF98229AAE760008E5C8 /* Core.strings */ = {
isa = PBXVariantGroup;
children = (
0E3CAF99229AAE760008E5C8 /* de */,
@@ -1073,7 +1086,7 @@
0E776575229CF65D0023FA76 /* es */,
0E6ACB7822B1A5BB001B3C99 /* pt */,
);
- name = Localizable.strings;
+ name = Core.strings;
sourceTree = "";
};
0E3CAFAD229AAE760008E5C8 /* Intents.intentdefinition */ = {
@@ -1094,6 +1107,23 @@
name = Intents.intentdefinition;
sourceTree = "";
};
+ 0E45E6E222BD793800F19312 /* App.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 0E45E6E122BD793800F19312 /* en */,
+ 0E45E6F122BD897E00F19312 /* it */,
+ 0E45E6F222BD898000F19312 /* de */,
+ 0E45E6F322BD898200F19312 /* ru */,
+ 0E45E6F422BD898300F19312 /* nl */,
+ 0E45E6F522BD898500F19312 /* el */,
+ 0E45E6F622BD898700F19312 /* sv */,
+ 0E45E6F722BD898800F19312 /* fr */,
+ 0E45E6F822BD898A00F19312 /* es */,
+ 0E45E6F922BD898B00F19312 /* pt */,
+ );
+ name = App.strings;
+ sourceTree = "";
+ };
0E57F63F20C83FC5008323CF /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
diff --git a/Submodules/Core b/Submodules/Core
index 766a328a..b58dbe71 160000
--- a/Submodules/Core
+++ b/Submodules/Core
@@ -1 +1 @@
-Subproject commit 766a328ac407b9c84aedf82268500c325930380a
+Subproject commit b58dbe713459f631220fd903bc17bd99748c750c
diff --git a/ci/list-untranslated.sh b/ci/list-untranslated.sh
index c252d235..74b609b2 100755
--- a/ci/list-untranslated.sh
+++ b/ci/list-untranslated.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-DIR="Passepartout/Resources"
-FILENAME="Localizable.strings"
+DIR="Passepartout-iOS/Global"
+FILENAME="App.strings"
LANG_BASE="en"
LANG_TARGET="$1"
STRINGS_BASE="$DIR/$LANG_BASE.lproj/$FILENAME"
diff --git a/swiftgen.yml b/swiftgen.yml
index 2de2c804..855481ab 100644
--- a/swiftgen.yml
+++ b/swiftgen.yml
@@ -1,3 +1,11 @@
+strings:
+ inputs:
+ - Submodules/Core/Passepartout/Resources/en.lproj/Core.strings
+ - Passepartout-iOS/Global/en.lproj/App.strings
+ outputs:
+ - templateName: structured-swift4
+ output: Passepartout-iOS/Global/SwiftGen+Strings.swift
+
ib:
inputs:
- Passepartout-iOS/Base.lproj/About.storyboard