From 803f8273db9d6922f09b64a2ca7994f34b33c80a Mon Sep 17 00:00:00 2001 From: Federico Cappelli Date: Wed, 10 Jan 2024 16:26:04 +0100 Subject: [PATCH 1/9] broken site model removed --- DuckDuckGo.xcodeproj/project.pbxproj | 4 +- .../xcshareddata/swiftpm/Package.resolved | 12 +- .../PrivacyDashboard/BrokenSiteInfo.swift | 248 +++++++++--------- .../PrivacyDashboardViewController.swift | 38 ++- 4 files changed, 162 insertions(+), 140 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 1b4eebbf57..5f715aff62 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -9220,8 +9220,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/DuckDuckGo/BrowserServicesKit"; requirement = { - kind = exactVersion; - version = 95.0.0; + branch = fcappelli/breakage_improvement_mac; + kind = branch; }; }; C14882EB27F211A000D59F0C /* XCRemoteSwiftPackageReference "SwiftSoup" */ = { diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 4c2e238aea..dd1bdbfd6f 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -14,8 +14,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/DuckDuckGo/BrowserServicesKit", "state" : { - "revision" : "ae9e9180f74d92c83fc3cc1d2fc23f4855fb361c", - "version" : "95.0.0" + "branch" : "fcappelli/breakage_improvement_mac", + "revision" : "7dd2e929883e02915f554167341b4500339a01d1" } }, { @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/content-scope-scripts", "state" : { - "revision" : "b7ad9843e70cede0c2ca9c4260d970f62cb28156", - "version" : "4.52.0" + "revision" : "bb027f14bec7fbb1a85d308139e7a66686da160e", + "version" : "4.59.0" } }, { @@ -104,8 +104,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/privacy-dashboard", "state" : { - "revision" : "38336a574e13090764ba09a6b877d15ee514e371", - "version" : "3.1.1" + "branch" : "12-14-feat_macos_allow_direct_navigation_to_breakage_form", + "revision" : "24b6260043a888827998124bc12104f4779e010f" } }, { diff --git a/DuckDuckGo/PrivacyDashboard/BrokenSiteInfo.swift b/DuckDuckGo/PrivacyDashboard/BrokenSiteInfo.swift index a6395d695d..2b9cab0ce6 100644 --- a/DuckDuckGo/PrivacyDashboard/BrokenSiteInfo.swift +++ b/DuckDuckGo/PrivacyDashboard/BrokenSiteInfo.swift @@ -1,130 +1,130 @@ +//// +//// BrokenSiteInfo.swift +//// DuckDuckGo +//// +//// Copyright © 2020 DuckDuckGo. All rights reserved. +//// +//// Licensed under the Apache License, Version 2.0 (the "License"); +//// you may not use this file except in compliance with the License. +//// You may obtain a copy of the License at +//// +//// http://www.apache.org/licenses/LICENSE-2.0 +//// +//// Unless required by applicable law or agreed to in writing, software +//// distributed under the License is distributed on an "AS IS" BASIS, +//// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +//// See the License for the specific language governing permissions and +//// limitations under the License. +//// // -// BrokenSiteInfo.swift -// DuckDuckGo +// import Foundation +// import Core // -// Copyright © 2020 DuckDuckGo. All rights reserved. +// public struct BrokenSiteInfo { // -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at +// static let allowedQueryReservedCharacters = CharacterSet(charactersIn: ",") // -// http://www.apache.org/licenses/LICENSE-2.0 +// private struct Keys { +// static let url = "siteUrl" +// static let category = "category" +// static let reportFlow = "reportFlow" +// static let description = "description" +// static let upgradedHttps = "upgradedHttps" +// static let tds = "tds" +// static let blockedTrackers = "blockedTrackers" +// static let surrogates = "surrogates" +// static let atb = "atb" //MISSING +// static let os = "os" +// static let manufacturer = "manufacturer" +// static let model = "model" //MISSING +// static let siteType = "siteType" //MISSING +// static let gpc = "gpc" +// static let ampUrl = "ampUrl" +// static let urlParametersRemoved = "urlParametersRemoved" +// static let protectionsState = "protectionsState" +// } +// +// public enum Source: String { +// case appMenu = "menu" +// case dashboard +// } +// +// private let url: URL? +// private let httpsUpgrade: Bool +// private let blockedTrackerDomains: [String] +// private let installedSurrogates: [String] +// private let isDesktop: Bool +// private let tdsETag: String? +// private let ampUrl: String? +// private let urlParametersRemoved: Bool +// private let model: String +// private let manufacturer: String +// private let systemVersion: String +// private let gpc: Bool +// private let protectionsState: Bool // -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +// public init(url: URL?, httpsUpgrade: Bool, +// blockedTrackerDomains: [String], +// installedSurrogates: [String], +// isDesktop: Bool, +// tdsETag: String?, +// ampUrl: String?, +// urlParametersRemoved: Bool, +// protectionsState: Bool, +// model: String = UIDevice.current.model, +// manufacturer: String = "Apple", +// systemVersion: String = UIDevice.current.systemVersion, +// gpc: Bool? = nil) { +// self.url = url +// self.httpsUpgrade = httpsUpgrade +// self.blockedTrackerDomains = blockedTrackerDomains +// self.installedSurrogates = installedSurrogates +// self.isDesktop = isDesktop +// self.tdsETag = tdsETag +// self.ampUrl = ampUrl +// self.urlParametersRemoved = urlParametersRemoved // - -import Foundation -import Core - -public struct BrokenSiteInfo { - - static let allowedQueryReservedCharacters = CharacterSet(charactersIn: ",") - - private struct Keys { - static let url = "siteUrl" - static let category = "category" - static let reportFlow = "reportFlow" - static let description = "description" - static let upgradedHttps = "upgradedHttps" - static let tds = "tds" - static let blockedTrackers = "blockedTrackers" - static let surrogates = "surrogates" - static let atb = "atb" - static let os = "os" - static let manufacturer = "manufacturer" - static let model = "model" - static let siteType = "siteType" - static let gpc = "gpc" - static let ampUrl = "ampUrl" - static let urlParametersRemoved = "urlParametersRemoved" - static let protectionsState = "protectionsState" - } - - public enum Source: String { - case appMenu = "menu" - case dashboard - } - - private let url: URL? - private let httpsUpgrade: Bool - private let blockedTrackerDomains: [String] - private let installedSurrogates: [String] - private let isDesktop: Bool - private let tdsETag: String? - private let ampUrl: String? - private let urlParametersRemoved: Bool - private let model: String - private let manufacturer: String - private let systemVersion: String - private let gpc: Bool - private let protectionsState: Bool - - public init(url: URL?, httpsUpgrade: Bool, - blockedTrackerDomains: [String], - installedSurrogates: [String], - isDesktop: Bool, - tdsETag: String?, - ampUrl: String?, - urlParametersRemoved: Bool, - protectionsState: Bool, - model: String = UIDevice.current.model, - manufacturer: String = "Apple", - systemVersion: String = UIDevice.current.systemVersion, - gpc: Bool? = nil) { - self.url = url - self.httpsUpgrade = httpsUpgrade - self.blockedTrackerDomains = blockedTrackerDomains - self.installedSurrogates = installedSurrogates - self.isDesktop = isDesktop - self.tdsETag = tdsETag - self.ampUrl = ampUrl - self.urlParametersRemoved = urlParametersRemoved - - self.model = model - self.manufacturer = manufacturer - self.systemVersion = systemVersion - self.protectionsState = protectionsState - - if let gpcParam = gpc { - self.gpc = gpcParam - } else { - self.gpc = AppDependencyProvider.shared.appSettings.sendDoNotSell - } - } - - func send(with category: String?, description: String, source: Source) { - - let parameters: [String: String] = [ - Keys.url: normalize(url), - Keys.category: category ?? "", - Keys.description: description, - Keys.reportFlow: source.rawValue, - Keys.upgradedHttps: httpsUpgrade ? "true" : "false", - Keys.siteType: isDesktop ? "desktop" : "mobile", - Keys.tds: tdsETag?.trimmingCharacters(in: CharacterSet(charactersIn: "\"")) ?? "", - Keys.blockedTrackers: blockedTrackerDomains.joined(separator: ","), - Keys.surrogates: installedSurrogates.joined(separator: ","), - Keys.atb: StatisticsUserDefaults().atb ?? "", - Keys.os: systemVersion, - Keys.manufacturer: manufacturer, - Keys.model: model, - Keys.gpc: gpc ? "true" : "false", - Keys.ampUrl: ampUrl ?? "", - Keys.urlParametersRemoved: urlParametersRemoved ? "true" : "false", - Keys.protectionsState: protectionsState ? "true" : "false" - ] - - Pixel.fire(pixel: .brokenSiteReport, - withAdditionalParameters: parameters, - allowedQueryReservedCharacters: BrokenSiteInfo.allowedQueryReservedCharacters) - } - - private func normalize(_ url: URL?) -> String { - return url?.normalized()?.absoluteString ?? "" - } - -} +// self.model = model +// self.manufacturer = manufacturer +// self.systemVersion = systemVersion +// self.protectionsState = protectionsState +// +// if let gpcParam = gpc { +// self.gpc = gpcParam +// } else { +// self.gpc = AppDependencyProvider.shared.appSettings.sendDoNotSell +// } +// } +// +// func send(with category: String?, description: String, source: Source) { +// +// let parameters: [String: String] = [ +// Keys.url: normalize(url), +// Keys.category: category ?? "", +// Keys.description: description, +// Keys.reportFlow: source.rawValue, +// Keys.upgradedHttps: httpsUpgrade ? "true" : "false", +// Keys.siteType: isDesktop ? "desktop" : "mobile", +// Keys.tds: tdsETag?.trimmingCharacters(in: CharacterSet(charactersIn: "\"")) ?? "", +// Keys.blockedTrackers: blockedTrackerDomains.joined(separator: ","), +// Keys.surrogates: installedSurrogates.joined(separator: ","), +// Keys.atb: StatisticsUserDefaults().atb ?? "", +// Keys.os: systemVersion, +// Keys.manufacturer: manufacturer, +// Keys.model: model, +// Keys.gpc: gpc ? "true" : "false", +// Keys.ampUrl: ampUrl ?? "", +// Keys.urlParametersRemoved: urlParametersRemoved ? "true" : "false", +// Keys.protectionsState: protectionsState ? "true" : "false" +// ] +// +// Pixel.fire(pixel: .brokenSiteReport, +// withAdditionalParameters: parameters, +// allowedQueryReservedCharacters: BrokenSiteInfo.allowedQueryReservedCharacters) +// } +// +// private func normalize(_ url: URL?) -> String { +// return url?.normalized()?.absoluteString ?? "" +// } +// +// } diff --git a/DuckDuckGo/PrivacyDashboard/PrivacyDashboardViewController.swift b/DuckDuckGo/PrivacyDashboard/PrivacyDashboardViewController.swift index c4a2e67877..f448510e65 100644 --- a/DuckDuckGo/PrivacyDashboard/PrivacyDashboardViewController.swift +++ b/DuckDuckGo/PrivacyDashboard/PrivacyDashboardViewController.swift @@ -23,6 +23,7 @@ import Combine import Core import BrowserServicesKit import PrivacyDashboard +import Common /// View controller used for `Privacy Dasboard` or `Report broken site`, the web content is chosen at init time setting the correct `initMode` class PrivacyDashboardViewController: UIViewController { @@ -39,12 +40,20 @@ class PrivacyDashboardViewController: UIViewController { private let privacyDashboardController: PrivacyDashboardController private let privacyConfigurationManager: PrivacyConfigurationManaging private let contentBlockingManager: ContentBlockerRulesManager - public var brokenSiteInfo: BrokenSiteInfo? + public var breakageReport: WebsiteBreakage? - var source: BrokenSiteInfo.Source { + var source: WebsiteBreakage.Source { initMode == .reportBrokenSite ? .appMenu : .dashboard } + private let websiteBreakageReporter: WebsiteBreakageReporter = { + WebsiteBreakageReporter(pixelHandler: { parameters in + Pixel.fire(pixel: .brokenSiteReport, + withAdditionalParameters: parameters, + allowedQueryReservedCharacters: WebsiteBreakage.allowedQueryReservedCharacters) + }, keyValueStoring: UserDefaults.standard) + }() + init?(coder: NSCoder, privacyInfo: PrivacyInfo?, privacyConfigurationManager: PrivacyConfigurationManaging, @@ -126,6 +135,8 @@ extension PrivacyDashboardViewController: Themable { } } +// MARK: - PrivacyDashboardControllerDelegate + extension PrivacyDashboardViewController: PrivacyDashboardControllerDelegate { func privacyDashboardController(_ privacyDashboardController: PrivacyDashboardController, didChangeProtectionSwitch protectionState: ProtectionState) { @@ -159,6 +170,8 @@ extension PrivacyDashboardViewController: PrivacyDashboardControllerDelegate { } } +// MARK: - PrivacyDashboardNavigationDelegate + extension PrivacyDashboardViewController: PrivacyDashboardNavigationDelegate { func privacyDashboardController(_ privacyDashboardController: PrivacyDashboard.PrivacyDashboardController, didSetHeight height: Int) { @@ -171,20 +184,29 @@ extension PrivacyDashboardViewController: PrivacyDashboardNavigationDelegate { } } +// MARK: - PrivacyDashboardReportBrokenSiteDelegate + extension PrivacyDashboardViewController: PrivacyDashboardReportBrokenSiteDelegate { - - func privacyDashboardController(_ privacyDashboardController: PrivacyDashboardController, reportBrokenSiteDidChangeProtectionSwitch protectionState: ProtectionState) { + + func privacyDashboardController(_ privacyDashboardController: PrivacyDashboardController, + reportBrokenSiteDidChangeProtectionSwitch protectionState: ProtectionState) { privacyDashboardProtectionSwitchChangeHandler(state: protectionState) } - func privacyDashboardController(_ privacyDashboardController: PrivacyDashboard.PrivacyDashboardController, didRequestSubmitBrokenSiteReportWithCategory category: String, description: String) { + func privacyDashboardController(_ privacyDashboardController: PrivacyDashboard.PrivacyDashboardController, + didRequestSubmitBrokenSiteReportWithCategory category: String, description: String) { - guard let brokenSiteInfo = brokenSiteInfo else { - assertionFailure("brokenSiteInfo not initialised") + guard let breakageReport = breakageReport else { + assertionFailure("WebsiteBreakage not initialised") return } - brokenSiteInfo.send(with: category, description: description, source: source) + do { + try websiteBreakageReporter.report(breakage: breakageReport) + } catch { + os_log("Failed to generate or send the website breakage report: %@", type: .error, error.localizedDescription) + } + ActionMessageView.present(message: UserText.feedbackSumbittedConfirmation) privacyDashboardCloseHandler() } From b7ad7d13dcfe009ee9e152ed483b7595aad50510 Mon Sep 17 00:00:00 2001 From: Federico Cappelli Date: Wed, 10 Jan 2024 18:56:39 +0100 Subject: [PATCH 2/9] Report broken site unit tests fixed --- .gitignore | 2 + DuckDuckGo.xcodeproj/project.pbxproj | 8 ++ .../xcshareddata/swiftpm/Package.resolved | 2 +- .../xcschemes/DuckDuckGo.xcscheme | 2 +- .../PrivacyDashboardViewController.swift | 5 +- .../BrokenSiteReportingTests.swift | 90 +++++++----------- ...000170c180>{number = 1, name = main}.plist | Bin 106 -> 0 bytes 7 files changed, 52 insertions(+), 57 deletions(-) delete mode 100644 DuckDuckGoTests/NetworkProtectionVPNLocationViewModelTests.swift<_NSMainThread: 0x60000170c180>{number = 1, name = main}.plist diff --git a/.gitignore b/.gitignore index 07ebc5f934..d460333497 100644 --- a/.gitignore +++ b/.gitignore @@ -74,3 +74,5 @@ fastlane/test_output Configuration/ExternalDeveloper.xcconfig scripts/assets + +DuckDuckGoTests/NetworkProtectionVPNLocationViewModelTests.swift*.plist diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index d3cfe88cc2..547633e84b 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -862,6 +862,7 @@ F1134ED21F40EF3A00B73467 /* JsonTestDataLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1134ECF1F40EBE200B73467 /* JsonTestDataLoader.swift */; }; F1134ED61F40F29F00B73467 /* StatisticsUserDefaultsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1134ED41F40F15800B73467 /* StatisticsUserDefaultsTests.swift */; }; F114C55B1E66EB020018F95F /* NibLoading.swift in Sources */ = {isa = PBXBuildFile; fileRef = F114C55A1E66EB020018F95F /* NibLoading.swift */; }; + F115ED9C2B4EFC8E001A0453 /* TestUtils in Frameworks */ = {isa = PBXBuildFile; productRef = F115ED9B2B4EFC8E001A0453 /* TestUtils */; }; F130D73A1E5776C500C45811 /* OmniBarDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F130D7391E5776C500C45811 /* OmniBarDelegate.swift */; }; F1386BA41E6846C40062FC3C /* TabDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1386BA31E6846C40062FC3C /* TabDelegate.swift */; }; F13B4BC01F180D8A00814661 /* TabsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F13B4BBF1F180D8A00814661 /* TabsModel.swift */; }; @@ -2677,6 +2678,7 @@ files = ( F486D3362506A037002D07D7 /* OHHTTPStubs in Frameworks */, F486D3382506A225002D07D7 /* OHHTTPStubsSwift in Frameworks */, + F115ED9C2B4EFC8E001A0453 /* TestUtils in Frameworks */, EEFAB4672A73C230008A38E4 /* NetworkProtectionTestUtils in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -5695,6 +5697,7 @@ F486D3352506A037002D07D7 /* OHHTTPStubs */, F486D3372506A225002D07D7 /* OHHTTPStubsSwift */, EEFAB4662A73C230008A38E4 /* NetworkProtectionTestUtils */, + F115ED9B2B4EFC8E001A0453 /* TestUtils */, ); productName = DuckDuckGoTests; productReference = 84E341A61E2F7EFB00BDBA6F /* UnitTests.xctest */; @@ -10120,6 +10123,11 @@ package = 98A16C2928A11BDE00A6C003 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = NetworkProtectionTestUtils; }; + F115ED9B2B4EFC8E001A0453 /* TestUtils */ = { + isa = XCSwiftPackageProductDependency; + package = 98A16C2928A11BDE00A6C003 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = TestUtils; + }; F42D541C29DCA40B004C4FF1 /* DesignResourcesKit */ = { isa = XCSwiftPackageProductDependency; package = F42D541B29DCA40B004C4FF1 /* XCRemoteSwiftPackageReference "DesignResourcesKit" */; diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index dd1bdbfd6f..161328585f 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -15,7 +15,7 @@ "location" : "https://github.com/DuckDuckGo/BrowserServicesKit", "state" : { "branch" : "fcappelli/breakage_improvement_mac", - "revision" : "7dd2e929883e02915f554167341b4500339a01d1" + "revision" : "690024ca0c4dffd1ef72799eb2cbd1962fc5adef" } }, { diff --git a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGo.xcscheme b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGo.xcscheme index 7c553f4089..e564636928 100644 --- a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGo.xcscheme +++ b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGo.xcscheme @@ -1,7 +1,7 @@ + version = "1.7"> diff --git a/DuckDuckGo/PrivacyDashboard/PrivacyDashboardViewController.swift b/DuckDuckGo/PrivacyDashboard/PrivacyDashboardViewController.swift index 1de29842f9..2d4f924437 100644 --- a/DuckDuckGo/PrivacyDashboard/PrivacyDashboardViewController.swift +++ b/DuckDuckGo/PrivacyDashboard/PrivacyDashboardViewController.swift @@ -235,16 +235,17 @@ extension PrivacyDashboardViewController { let blockedTrackerDomains = privacyInfo.trackerInfo.trackersBlocked.compactMap { $0.domain } let configuration = ContentBlocking.shared.privacyConfigurationManager.privacyConfig let protectionsState = configuration.isFeature(.contentBlocking, enabledForDomain: breakageAdditionalInfo.currentURL.host) - + return WebsiteBreakage(siteUrl: breakageAdditionalInfo.currentURL, category: category, description: description, osVersion: "\(ProcessInfo.processInfo.operatingSystemVersion)", + manufacturer: "Apple", upgradedHttps: breakageAdditionalInfo.httpsForced, tdsETag: ContentBlocking.shared.contentBlockingManager.currentMainRules?.etag ?? "", blockedTrackerDomains: blockedTrackerDomains, installedSurrogates: privacyInfo.trackerInfo.installedSurrogates.map { $0 }, - isGPCEnabled: false, + isGPCEnabled: AppDependencyProvider.shared.appSettings.sendDoNotSell, ampURL: breakageAdditionalInfo.ampURLString, urlParametersRemoved: breakageAdditionalInfo.urlParametersRemoved, protectionsState: protectionsState, diff --git a/DuckDuckGoTests/BrokenSiteReportingTests.swift b/DuckDuckGoTests/BrokenSiteReportingTests.swift index 3959b8cbf3..40c578f113 100644 --- a/DuckDuckGoTests/BrokenSiteReportingTests.swift +++ b/DuckDuckGoTests/BrokenSiteReportingTests.swift @@ -23,8 +23,9 @@ import BrowserServicesKit import OHHTTPStubs import OHHTTPStubsSwift @testable import Core - +import PrivacyDashboard @testable import DuckDuckGo +import TestUtils final class BrokenSiteReportingTests: XCTestCase { private let data = JsonTestDataLoader() @@ -52,7 +53,6 @@ final class BrokenSiteReportingTests: XCTestCase { func testBrokenSiteReporting() throws { let testJSON = data.fromJsonFile(Resource.tests) - let testString = String(data: testJSON, encoding: .utf8) let testData = try JSONDecoder().decode(BrokenSiteReportingTestData.self, from: testJSON) referenceTests = testData.reportURL.tests.filter { @@ -61,13 +61,12 @@ final class BrokenSiteReportingTests: XCTestCase { let testsExecuted = expectation(description: "tests executed") testsExecuted.expectedFulfillmentCount = referenceTests.count - - runReferenceTests(onTestExecuted: testsExecuted) - waitForExpectations(timeout: 30, handler: nil) - + + try runReferenceTests(onTestExecuted: testsExecuted) + waitForExpectations(timeout: 10, handler: nil) } - private func runReferenceTests(onTestExecuted: XCTestExpectation) { + private func runReferenceTests(onTestExecuted: XCTestExpectation) throws { guard let test = referenceTests.popLast() else { return @@ -75,56 +74,41 @@ final class BrokenSiteReportingTests: XCTestCase { os_log("Testing [%s]", type: .info, test.name) - let brokenSiteInfo = BrokenSiteInfo(url: URL(string: test.siteURL), - httpsUpgrade: test.wasUpgraded, - blockedTrackerDomains: test.blockedTrackers, - installedSurrogates: test.surrogates, - isDesktop: true, - tdsETag: test.blocklistVersion, - ampUrl: nil, - urlParametersRemoved: false, - protectionsState: test.protectionsEnabled, - model: test.model ?? "", - manufacturer: test.manufacturer ?? "", - systemVersion: test.os ?? "", - gpc: test.gpcEnabled) + let websiteBreakage = WebsiteBreakage(siteUrl: URL(string: test.siteURL)!, + category: test.category, + description: "", + osVersion: test.os ?? "", + manufacturer: test.manufacturer ?? "", + upgradedHttps: test.wasUpgraded, + tdsETag: test.blocklistVersion, + blockedTrackerDomains: test.blockedTrackers, + installedSurrogates: test.surrogates, + isGPCEnabled: test.gpcEnabled ?? false, + ampURL: "", + urlParametersRemoved: false, + protectionsState: test.protectionsEnabled, + reportFlow: .dashboard, + siteType: .mobile, + atb: "", + model: test.model ?? "") - stub(condition: isHost(host)) { request -> HTTPStubsResponse in + let reporter = WebsiteBreakageReporter(pixelHandler: { params in - guard let requestURL = request.url else { - XCTFail("Couldn't create request URL") - return HTTPStubsResponse(data: Data(), statusCode: 200, headers: nil) - } - - let absoluteURL = requestURL.absoluteString - .replacingOccurrences(of: "%20", with: " ") - - if test.expectReportURLPrefix.count > 0 { - XCTAssertTrue(requestURL.absoluteString.contains(test.expectReportURLPrefix), "Prefix [\(test.expectReportURLPrefix)] not found") - } - - for param in test.expectReportURLParams { - let pattern = "[?&]\(param.name)=\(param.value)[&$]?" - - guard let regex = try? NSRegularExpression(pattern: pattern, - options: []) else { - XCTFail("Couldn't create regex") - return HTTPStubsResponse(data: Data(), statusCode: 200, headers: nil) + for expectedParam in test.expectReportURLParams { + + if let actualValue = params[expectedParam.name], + let expectedCleanValue = expectedParam.value.removingPercentEncoding { + if actualValue != expectedCleanValue { + XCTFail("Mismatching param: \(expectedParam.name) => \(expectedCleanValue) != \(actualValue)") + } + } else { + XCTFail("Missing param: \(expectedParam.name)") } - - let match = regex.matches(in: absoluteURL, range: NSRange(location: 0, length: absoluteURL.count)) - XCTAssertEqual(match.count, 1, "Param [\(param.name)] with value [\(param.value)] not found in [\(absoluteURL)]") - } - - DispatchQueue.main.async { - onTestExecuted.fulfill() - self.runReferenceTests(onTestExecuted: onTestExecuted) } - - return HTTPStubsResponse(data: Data(), statusCode: 200, headers: nil) - } - - brokenSiteInfo.send(with: test.category, description: "", source: .dashboard) + onTestExecuted.fulfill() + try? self.runReferenceTests(onTestExecuted: onTestExecuted) + }, keyValueStoring: MockKeyValueStore()) + try reporter.report(breakage: websiteBreakage) } } diff --git a/DuckDuckGoTests/NetworkProtectionVPNLocationViewModelTests.swift<_NSMainThread: 0x60000170c180>{number = 1, name = main}.plist b/DuckDuckGoTests/NetworkProtectionVPNLocationViewModelTests.swift<_NSMainThread: 0x60000170c180>{number = 1, name = main}.plist deleted file mode 100644 index 4c375cd9b45468c03975f4da9db70030d6a2cd4a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 106 zcmYc)$jK}&F)+Bu$P_PNl9yUio?nz5P?TSinp~2ZpBJ23Qj(dM9-Nv3SB lg-h~_64O(|5_3vZUGhqEayYo17{Gv$5kfOCLunZ04gj8997zBG From eea04685dc640ff49c8383141f1f30a814db72dc Mon Sep 17 00:00:00 2001 From: Federico Cappelli Date: Thu, 11 Jan 2024 10:27:10 +0100 Subject: [PATCH 3/9] os detection improved --- .../PrivacyDashboard/PrivacyDashboardViewController.swift | 2 +- Gemfile.lock | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/DuckDuckGo/PrivacyDashboard/PrivacyDashboardViewController.swift b/DuckDuckGo/PrivacyDashboard/PrivacyDashboardViewController.swift index 2d4f924437..01b4729e9a 100644 --- a/DuckDuckGo/PrivacyDashboard/PrivacyDashboardViewController.swift +++ b/DuckDuckGo/PrivacyDashboard/PrivacyDashboardViewController.swift @@ -239,7 +239,7 @@ extension PrivacyDashboardViewController { return WebsiteBreakage(siteUrl: breakageAdditionalInfo.currentURL, category: category, description: description, - osVersion: "\(ProcessInfo.processInfo.operatingSystemVersion)", + osVersion: "\(ProcessInfo().operatingSystemVersion.majorVersion)", manufacturer: "Apple", upgradedHttps: breakageAdditionalInfo.httpsForced, tdsETag: ContentBlocking.shared.contentBlockingManager.currentMainRules?.etag ?? "", diff --git a/Gemfile.lock b/Gemfile.lock index d857156940..41d2cd26f5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -32,7 +32,8 @@ GEM declarative (0.0.20) digest-crc (0.6.5) rake (>= 12.0.0, < 14.0.0) - domain_name (0.6.20231109) + domain_name (0.5.20190701) + unf (>= 0.0.5, < 1.0.0) dotenv (2.8.1) emoji_regex (3.2.3) excon (0.104.0) @@ -188,6 +189,9 @@ GEM tty-spinner (0.9.3) tty-cursor (~> 0.7) uber (0.1.0) + unf (0.1.4) + unf_ext + unf_ext (0.0.9.1) unicode-display_width (2.5.0) webrick (1.8.1) word_wrap (1.0.0) From f1c7e56244956863ac132da9d191af975465a22b Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Thu, 11 Jan 2024 18:14:43 +0600 Subject: [PATCH 4/9] add xcargs: -skipPackagePluginValidation arg to build_app --- fastlane/Fastfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 5713dc41c2..841515862f 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -77,7 +77,8 @@ lane :adhoc do |options| export_method: "ad-hoc", scheme: "DuckDuckGo", export_options: "adhocExportOptions.plist", - derived_data_path: "DerivedData" + derived_data_path: "DerivedData", + xcargs: "-skipPackagePluginValidation" ) if is_ci From 924da96dfb011f34782620abfae79e013053bfbd Mon Sep 17 00:00:00 2001 From: Federico Cappelli Date: Thu, 11 Jan 2024 13:18:12 +0100 Subject: [PATCH 5/9] bsk updated --- .../xcshareddata/swiftpm/Package.resolved | 2 +- .../SyncUI/Resources/en.lproj/Localizable.strings | 11 ++++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 161328585f..01186f4ff8 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -15,7 +15,7 @@ "location" : "https://github.com/DuckDuckGo/BrowserServicesKit", "state" : { "branch" : "fcappelli/breakage_improvement_mac", - "revision" : "690024ca0c4dffd1ef72799eb2cbd1962fc5adef" + "revision" : "d10308aa31ab81149bc8773140de3b08ba9707dd" } }, { diff --git a/LocalPackages/SyncUI/Sources/SyncUI/Resources/en.lproj/Localizable.strings b/LocalPackages/SyncUI/Sources/SyncUI/Resources/en.lproj/Localizable.strings index 0b3210a0b6..4b864482a4 100644 --- a/LocalPackages/SyncUI/Sources/SyncUI/Resources/en.lproj/Localizable.strings +++ b/LocalPackages/SyncUI/Sources/SyncUI/Resources/en.lproj/Localizable.strings @@ -26,7 +26,7 @@ "cancel.button" = "Cancel"; /* Connect With Server Sheet - Button */ -"connect.with.server.sheet.button" = "Turn on Sync & Backup"; +"connect.with.server.sheet.button" = "Turn On Sync & Back Up"; /* Connect With Server Sheet - Description Part 1 */ "connect.with.server.sheet.description.part1" = "This creates an encrypted backup of your bookmarks and passwords on DuckDuckGo’s secure server, which can be synced with your other devices."; @@ -50,7 +50,7 @@ "delete.server.data" = "Turn Off and Delete Server Data..."; /* Device SyncedSheet - Title */ -"device.synced.sheet.title" = "Your Data is Synced!"; +"device.synced.sheet.title" = "Your data is synced!"; /* Standard Buttons - Done Button */ "done.button" = "Done"; @@ -184,9 +184,6 @@ /* Scan or See Code View - Instruction with syncMenuPath */ "scan.or.see.code.instruction.attributed" = "Go to %@ in the DuckDuckGo Browser on another device and select ”Sync with Another Device.”."; -/* Scan or See Code View - Instruction Part 3 */ -"scan.or.see.code.instruction.part3" = "in the DuckDuckGo Browser on another device and select ”Sync with Another Device.”"; - /* Scan or See Code View - Manually Enter Code Link */ "scan.or.see.code.manually.enter.code.link" = "Manually Enter Code"; @@ -227,7 +224,7 @@ "sync.warning.sync.unavailable" = "Sync & Backup is Unavailable"; /* Button label for syncing with another device */ -"sync.with.another.device.button" = "Sync with Another Device"; +"sync.with.another.device.button" = "Sync With Another Device"; /* Footer message for syncing with another device */ "sync.with.another.device.footer" = "Your data is end-to-end encrypted, and DuckDuckGo does not have access to the encryption key."; @@ -257,7 +254,7 @@ "unified.favorites.instruction" = "Use the same favorite bookmarks on all your devices. Leave off to keep mobile and desktop favorites separate."; /* Options - Unify Favorites Title */ -"unified.favorites.title" = "Unify Favorites"; +"unified.favorites.title" = "Unify Favorites Across Devices"; /* View Text Code menu item */ "view.text.code.menu.item" = "View Text Code"; From f08738f65b7f3ac65b3f1bb1b38f94c521751dd7 Mon Sep 17 00:00:00 2001 From: Federico Cappelli Date: Thu, 11 Jan 2024 13:37:46 +0100 Subject: [PATCH 6/9] pkg fix --- .../project.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index a344a8e46b..01186f4ff8 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -156,7 +156,7 @@ { "identity" : "trackerradarkit", "kind" : "remoteSourceControl", - "location" : "https://github.com/duckduckgo/TrackerRadarKit.git", + "location" : "https://github.com/duckduckgo/TrackerRadarKit", "state" : { "revision" : "a6b7ba151d9dc6684484f3785293875ec01cc1ff", "version" : "1.2.2" From f5442a483e5c83ba1c1eff661b5405bb146699a7 Mon Sep 17 00:00:00 2001 From: Federico Cappelli Date: Fri, 12 Jan 2024 13:24:25 +0100 Subject: [PATCH 7/9] commented out code removed --- DuckDuckGo/TabViewController.swift | 31 ------------------------------ 1 file changed, 31 deletions(-) diff --git a/DuckDuckGo/TabViewController.swift b/DuckDuckGo/TabViewController.swift index 8592ef3ca7..e24722716f 100644 --- a/DuckDuckGo/TabViewController.swift +++ b/DuckDuckGo/TabViewController.swift @@ -712,7 +712,6 @@ class TabViewController: UIViewController { controller.popoverPresentationController?.sourceRect = iconView.bounds } privacyDashboard = controller -// privacyDashboard?.breakageAdditionalInfo = } if let controller = segue.destination as? FullscreenDaxDialogViewController { @@ -916,36 +915,6 @@ class TabViewController: UIViewController { isDesktop: tabModel.isDesktop) } -// public func getCurrentWebsiteInfo() -> WebsiteBreakage? { -// -// guard let privacyInfo = privacyInfo, -// let currentURL = url else { -// return nil -// } -// -// let blockedTrackerDomains = privacyInfo.trackerInfo.trackersBlocked.compactMap { $0.domain } -// let configuration = ContentBlocking.shared.privacyConfigurationManager.privacyConfig -// let protectionsState = configuration.isFeature(.contentBlocking, enabledForDomain: currentURL.host) -// -// return WebsiteBreakage(siteUrl: currentURL, -// category: <#T##String#>, -// description: <#T##String?#>, -// osVersion: "\(ProcessInfo.processInfo.operatingSystemVersion)", -// upgradedHttps: httpsForced, -// tdsETag: ContentBlocking.shared.contentBlockingManager.currentMainRules?.etag ?? "", -// blockedTrackerDomains: blockedTrackerDomains, -// installedSurrogates: privacyInfo.trackerInfo.installedSurrogates.map { $0 }, -// isGPCEnabled: false, -// ampURL: linkProtection.lastAMPURLString ?? "", -// urlParametersRemoved: linkProtection.urlParametersRemoved, -// protectionsState: protectionsState, -// reportFlow: <#T##WebsiteBreakage.Source#>, -// siteType: tabModel.isDesktop ? .desktop : .mobile, -// atb: StatisticsUserDefaults().atb ?? "", -// model: UIDevice.current.model) -// -// } - public func print() { let printFormatter = webView.viewPrintFormatter() From 80b5d1ffaedb3fbe495bb1e78007ca2a83d23237 Mon Sep 17 00:00:00 2001 From: Federico Cappelli Date: Thu, 25 Jan 2024 10:15:48 +0000 Subject: [PATCH 8/9] typo fixed --- DuckDuckGo/MainViewController+Segues.swift | 2 +- .../PrivacyDashboard/PrivacyDashboardViewController.swift | 6 +++--- DuckDuckGo/TabViewController.swift | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/DuckDuckGo/MainViewController+Segues.swift b/DuckDuckGo/MainViewController+Segues.swift index d8be360658..0d994f5699 100644 --- a/DuckDuckGo/MainViewController+Segues.swift +++ b/DuckDuckGo/MainViewController+Segues.swift @@ -137,7 +137,7 @@ extension MainViewController { privacyConfigurationManager: ContentBlocking.shared.privacyConfigurationManager, contentBlockingManager: ContentBlocking.shared.contentBlockingManager, initMode: .reportBrokenSite, - breakageAdditionalInfo: self.currentTab?.makeBreakageAdditionaInfo()) + breakageAdditionalInfo: self.currentTab?.makeBreakageAdditionalInfo()) } guard let controller = controller else { diff --git a/DuckDuckGo/PrivacyDashboard/PrivacyDashboardViewController.swift b/DuckDuckGo/PrivacyDashboard/PrivacyDashboardViewController.swift index 01b4729e9a..48a5b0d6e0 100644 --- a/DuckDuckGo/PrivacyDashboard/PrivacyDashboardViewController.swift +++ b/DuckDuckGo/PrivacyDashboard/PrivacyDashboardViewController.swift @@ -40,7 +40,7 @@ class PrivacyDashboardViewController: UIViewController { private let privacyDashboardController: PrivacyDashboardController private let privacyConfigurationManager: PrivacyConfigurationManaging private let contentBlockingManager: ContentBlockerRulesManager - public var breakageAdditionalInfo: BreakageAdditionaInfo? + public var breakageAdditionalInfo: BreakageAdditionalInfo? var source: WebsiteBreakage.Source { initMode == .reportBrokenSite ? .appMenu : .dashboard @@ -59,7 +59,7 @@ class PrivacyDashboardViewController: UIViewController { privacyConfigurationManager: PrivacyConfigurationManaging, contentBlockingManager: ContentBlockerRulesManager, initMode: Mode, - breakageAdditionalInfo: BreakageAdditionaInfo?) { + breakageAdditionalInfo: BreakageAdditionalInfo?) { self.privacyDashboardController = PrivacyDashboardController(privacyInfo: privacyInfo) self.privacyConfigurationManager = privacyConfigurationManager self.contentBlockingManager = contentBlockingManager @@ -213,7 +213,7 @@ extension PrivacyDashboardViewController: UIPopoverPresentationControllerDelegat extension PrivacyDashboardViewController { - struct BreakageAdditionaInfo { + struct BreakageAdditionalInfo { let currentURL: URL let httpsForced: Bool let ampURLString: String diff --git a/DuckDuckGo/TabViewController.swift b/DuckDuckGo/TabViewController.swift index e750b15075..840bd0b648 100644 --- a/DuckDuckGo/TabViewController.swift +++ b/DuckDuckGo/TabViewController.swift @@ -749,7 +749,7 @@ class TabViewController: UIViewController { privacyConfigurationManager: ContentBlocking.shared.privacyConfigurationManager, contentBlockingManager: ContentBlocking.shared.contentBlockingManager, initMode: .privacyDashboard, - breakageAdditionalInfo: makeBreakageAdditionaInfo()) + breakageAdditionalInfo: makeBreakageAdditionalInfo()) } private func addTextSizeObserver() { @@ -913,12 +913,12 @@ class TabViewController: UIViewController { webView.removeObserver(self, forKeyPath: #keyPath(WKWebView.title)) } - public func makeBreakageAdditionaInfo() -> PrivacyDashboardViewController.BreakageAdditionaInfo? { + public func makeBreakageAdditionalInfo() -> PrivacyDashboardViewController.BreakageAdditionalInfo? { guard let currentURL = url else { return nil } - return PrivacyDashboardViewController.BreakageAdditionaInfo(currentURL: currentURL, + return PrivacyDashboardViewController.BreakageAdditionalInfo(currentURL: currentURL, httpsForced: httpsForced, ampURLString: linkProtection.lastAMPURLString ?? "", urlParametersRemoved: linkProtection.urlParametersRemoved, From bf5cd4fc8204994d0850a4cca08f2d34cc279065 Mon Sep 17 00:00:00 2001 From: Federico Cappelli Date: Mon, 29 Jan 2024 11:05:05 +0000 Subject: [PATCH 9/9] BSK 103.0.0 --- DuckDuckGo.xcodeproj/project.pbxproj | 4 +- .../xcshareddata/swiftpm/Package.resolved | 8 +- DuckDuckGo/en.lproj/Localizable.strings | 2392 ----------------- LocalPackages/DuckUI/Package.swift | 2 +- LocalPackages/SyncUI/Package.swift | 2 +- .../Resources/en.lproj/Localizable.strings | 258 -- LocalPackages/Waitlist/Package.swift | 2 +- .../en.lproj/Localizable.strings | 15 - Widgets/en.lproj/Localizable.strings | 51 - 9 files changed, 9 insertions(+), 2725 deletions(-) diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 12b8341185..4fbd26a8ab 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -9976,8 +9976,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/DuckDuckGo/BrowserServicesKit"; requirement = { - branch = fcappelli/breakage_improvement_mac; - kind = branch; + kind = exactVersion; + version = 103.0.0; }; }; C14882EB27F211A000D59F0C /* XCRemoteSwiftPackageReference "SwiftSoup" */ = { diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index a418b794f4..1ccd2c196c 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -14,8 +14,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/DuckDuckGo/BrowserServicesKit", "state" : { - "branch" : "fcappelli/breakage_improvement_mac", - "revision" : "ce5701ccb7f5868d364fce5978729014f2d53c7a" + "revision" : "5af8fbcff0913aa543ba3eea60cc24e706a3a4e5", + "version" : "103.0.0" } }, { @@ -104,8 +104,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/privacy-dashboard", "state" : { - "branch" : "12-14-feat_macos_allow_direct_navigation_to_breakage_form", - "revision" : "24b6260043a888827998124bc12104f4779e010f" + "revision" : "c67d268bf234760f49034a0fe7a6137a1b216b05", + "version" : "3.2.0" } }, { diff --git a/DuckDuckGo/en.lproj/Localizable.strings b/DuckDuckGo/en.lproj/Localizable.strings index f50749e44b..e69de29bb2 100644 --- a/DuckDuckGo/en.lproj/Localizable.strings +++ b/DuckDuckGo/en.lproj/Localizable.strings @@ -1,2392 +0,0 @@ -/* Buton label for Edit action */ -"action.generic.edit" = "Edit"; - -/* Button label for a generic show action */ -"action.generic.show" = "Show"; - -/* Button label for Undo action */ -"action.generic.undo" = "Undo"; - -/* Button label for managing favorites */ -"action.manage.favorites" = "Manage"; - -/* Button label for OK action */ -"action.ok" = "OK"; - -/* Add action - button shown in alert */ -"action.title.add" = "Add"; - -/* Autofill Logins menu item opening the login list */ -"action.title.autofill.logins" = "Passwords"; - -/* Confirmation of Add to Bookmarks action in Add All Open Tabs to Bookmarks alert */ -"action.title.bookmark" = "Bookmark"; - -/* Button: Open bookmarks list */ -"action.title.bookmarks" = "Bookmarks"; - -/* Cancel action - button shown in alert */ -"action.title.cancel" = "Cancel"; - -/* Copy action */ -"action.title.copy" = "Copy"; - -/* Floating message indicating URL has been copied */ -"action.title.copy.message" = "URL copied"; - -/* Delete action - button shown in alert */ -"action.title.delete" = "Delete"; - -/* Disable protection action */ -"action.title.disable.protection" = "Disable Privacy Protection"; - -/* Downloads menu item opening the downlods list */ -"action.title.downloads" = "Downloads"; - -/* Edit Bookmark action */ -"action.title.edit.bookmark" = "Edit Bookmark"; - -/* Enable protection action */ -"action.title.enable.protection" = "Enable Privacy Protection"; - -/* No comment provided by engineer. */ -"action.title.forgetAll" = "Close Tabs and Clear Data"; - -/* Confirmation message */ -"action.title.forgetAllDone" = "Tabs and data cleared"; - -/* Open in New Background Tab action */ -"action.title.newBackgroundTabForUrl" = "Open in Background"; - -/* Create New Tab action */ -"action.title.newTabAction" = "New"; - -/* Open in New Tab action */ -"action.title.newTabForUrl" = "Open in New Tab"; - -/* Open action */ -"action.title.open" = "Open"; - -/* Paste and Go action */ -"action.title.pasteAndGo" = "Paste & Go"; - -/* Print action */ -"action.title.print" = "Print"; - -/* Refresh action - button shown in alert */ -"action.title.refresh" = "Refresh"; - -/* Remove Favorite action */ -"action.title.remove.favorite" = "Remove Favorite"; - -/* Report broken site action */ -"action.title.reportBrokenSite" = "Report Broken Site"; - -/* Action to reload current page in desktop mode */ -"action.title.request.desktop.site" = "Desktop Site"; - -/* Action to reload current page in mobile mode */ -"action.title.request.mobile.site" = "Mobile Site"; - -/* Save action - button shown in alert */ -"action.title.save" = "Save"; - -/* Add to Bookmarks action */ -"action.title.save.bookmark" = "Add Bookmark"; - -/* Add to Favorites action */ -"action.title.save.favorite" = "Add Favorite"; - -/* Settings action */ -"action.title.settings" = "Settings"; - -/* Share action */ -"action.title.share" = "Share"; - -/* Settings label for bottom position for the address bar */ -"address.bar.bottom" = "Bottom"; - -/* Settings label for top position for the address bar */ -"address.bar.top" = "Top"; - -/* No comment provided by engineer. */ -"addWidget.button" = "Add Widget"; - -/* No comment provided by engineer. */ -"addWidget.description" = "Get quick access to private search and the sites you love."; - -/* No comment provided by engineer. */ -"addWidget.settings.firstParagraph" = "Long-press on the home screen to enter jiggle mode."; - -/* Replacement string is a plus button icon. */ -"addWidget.settings.secondParagraph.%@" = "Tap the plus %@ button."; - -/* No comment provided by engineer. */ -"addWidget.settings.title" = "Find and select DuckDuckGo. Then choose a widget."; - -/* No comment provided by engineer. */ -"addWidget.title" = "One tap to your favorite sites."; - -/* No comment provided by engineer. */ -"alert.message.bookmarkAll" = "Existing bookmarks will not be duplicated."; - -/* Description for alert shown when sync bookmarks paused for too many items */ -"alert.sync-bookmarks-paused-description" = "You have exceeded the bookmarks sync limit. Try deleting some bookmarks. Until this is resolved your bookmarks will not be backed up."; - -/* Title for alert shown when sync bookmarks paused for too many items */ -"alert.sync-bookmarks-paused-title" = "Bookmarks Sync is Paused"; - -/* Description for alert shown when sync credentials paused for too many items */ -"alert.sync-credentials-paused-description" = "You have exceeded the passwords sync limit. Try deleting some passwords. Until this is resolved your passwords will not be backed up."; - -/* Title for alert shown when sync credentials paused for too many items */ -"alert.sync-credentials-paused-title" = "Passwords Sync is Paused"; - -/* Title for sync error alert */ -"alert.sync-error" = "Sync & Backup Error"; - -/* Learn more button in alert */ -"alert.sync-paused-alert-learn-more-button" = "Learn More"; - -/* Confirmation button in alert */ -"alert.sync-paused-alert-ok-button" = "OK"; - -/* Question from confirmation dialog */ -"alert.title.bookmarkAll" = "Bookmark All Tabs?"; - -/* Disable protection alert */ -"alert.title.disable.protection" = "Add to Unprotected Sites"; - -/* Disable potection alert placeholder - leave as it is */ -"alert.title.disable.protection.placeholder" = "www.example.com"; - -/* Save Bookmark action */ -"alert.title.save.bookmark" = "Save Bookmark"; - -/* Save Favorite action */ -"alert.title.save.favorite" = "Save Favorite"; - -/* Description for unable to create recovery pdf error */ -"alert.unable-to-create-recovery-pdf-description" = "Unable to create the recovery PDF."; - -/* Description for unable to delete data error */ -"alert.unable-to-delete-data-description" = "Unable to delete data on the server."; - -/* Description for unable to merge two accounts error */ -"alert.unable-to-merge-two-accounts-description" = "To pair these devices, turn off Sync & Backup on one device then tap \"Sync With Another Device\" on the other device."; - -/* Description for unable to remove device error */ -"alert.unable-to-remove-device-description" = "Unable to remove this device from Sync & Backup."; - -/* Description for unable to sync to server error */ -"alert.unable-to-sync-to-server-description" = "Unable to connect to the server."; - -/* Description for unable to sync with another device error */ -"alert.unable-to-sync-with-other-device-description" = "Unable to Sync with another device."; - -/* Description for unable to turn sync off error */ -"alert.unable-to-turn-sync-off-description" = "Unable to turn Sync & Backup off."; - -/* Description for unable to update device name error */ -"alert.unable-to-update-device-name-description" = "Unable to update the device name."; - -/* Shown on authentication screen */ -"app.authentication.unlock" = "Unlock DuckDuckGo."; - -/* First part of about page content (note the trailing space) */ -"appTP.about.content1" = "You’ve probably heard about companies like Google and Facebook tracking you behind the scenes on third-party websites. But did you know they also track your personal information through apps on your device?\n\nIn 2022, DuckDuckGo found that "; - -/* Second part of about page content (note the trailing space) */ -"appTP.about.content2" = "over 85% of free iOS apps tested contained hidden trackers from other companies."; - -/* Third part of about page content (note the leading space) */ -"appTP.about.content3" = " Of the 395 apps tested, 60% sent data to Google. This happens even while you’re not using your device.\n\nTrackers in apps may have access to a lot more information than their website tracker cousins, such as your location down to which floor of a building you're on, how often you play games while at work, and when and how long you sleep each day. Even if you haven’t given apps explicit permission to collect data, they can still take it without your knowledge.\n\nTracking networks like Facebook and Google use these little pieces of information to build a digital profile about you. With it, tracking networks can manipulate what you see online and allow advertisers to bid on access to you based on your data.\n\nTrackers in apps is a BIG problem for privacy. But DuckDuckGo has a solution that can help.\n\nWhen enabled in the DuckDuckGo Privacy Browser app, App Tracking Protection blocks many trackers in other apps, not just the trackers we find on websites when you browse. These dual layers of protection reduce what companies know about you overall, so you can use your apps with more peace of mind, knowing you’re more protected."; - -/* Navigation Title for AppTP about page */ -"appTP.about.navTitle" = "About App Trackers"; - -/* Title for AppTP about page */ -"appTP.about.title" = "What Are App Trackers?"; - -/* Title for 'Report an Issue' button in the activity view. */ -"appTP.activityView.reportIssue" = "Report Issue"; - -/* Text label for switch that turns blocking on or off for a tracker */ -"appTP.blockTrackerText" = "Block this Tracker"; - -/* Detail string describing what AppTP is */ -"appTP.cell.detail" = "Block app trackers on your device"; - -/* String indicating AppTP is disabled when viewed from the settings screen */ -"appTP.cell.disabled" = "Disabled"; - -/* String indicating AppTP is enabled when viewed from the settings screen */ -"appTP.cell.enabled" = "Enabled"; - -/* Info string informing the user what App Tracking Protection does. */ -"appTP.empty.disabled.info" = "Enable App Tracking Protection so we can block pesky trackers in other apps."; - -/* Info string informing the user we're looking for trackers in other apps. */ -"appTP.empty.enabled.heading" = "We’re blocking hidden trackers"; - -/* Info string informing the user we're looking for trackers in other apps. */ -"appTP.empty.enabled.info" = "Come back soon to see a list of all the app trackers we’ve blocked."; - -/* First answer for AppTP FAQ page */ -"appTP.faq.answer1" = "App Tracking Protection blocks app trackers from other companies, like when Facebook tries to track you in a banking app. Companies may still track you in apps they own."; - -/* Second answer for AppTP FAQ page */ -"appTP.faq.answer2" = "Yes! App Tracking Protection works across all apps on your device to block the most common hidden trackers we find trying to collect your personal info."; - -/* Third answer for AppTP FAQ page */ -"appTP.faq.answer3" = "We currently only block the most common trackers that we find on iOS. This helps us to comprehensively test App Tracking Protection and lower frequency of app breakage, while blocking up to 70% of all tracking requests."; - -/* Fourth answer for AppTP FAQ page */ -"appTP.faq.answer4" = "You’ll be asked to set up a virtual private network (VPN) connection, but you don't need to install a VPN app for App Tracking Protection to work.\n\nThis permission, which works only on your device, allows App Tracking Protection to monitor network traffic so that it can block known trackers."; - -/* Fifth answer for AppTP FAQ page */ -"appTP.faq.answer5" = "You can use App Tracking Protection at the same time as using an IKEv2 protocol VPN app on an iOS device. You won’t be able to use App Tracking Protection on an iOS device if you’re using a VPN app that uses a different type of protocol, like WireGuard or OpenVPN type VPNs."; - -/* Sixth answer for AppTP FAQ page */ -"appTP.faq.answer6" = "A VPN sends your data from the device to its own server, where it secures and anonymizes your data from prying eyes. However, this allows the VPN company to see your network traffic.\n\nApp Tracking Protection is different. Instead of sending your data to a VPN server, App Tracking Protection works only on your device, sitting between your apps and the servers they talk to.\n\nWhenever App Tracking Protection recognizes a known tracker, it blocks the tracker from sending personal information (such as your IP address, activity, and device details) off your device. All other traffic reaches its destination, so your apps work normally."; - -/* Seventh answer for AppTP FAQ page */ -"appTP.faq.answer7" = "App Tracking Protection works only on your device and doesn’t send your data off your device to DuckDuckGo. We don’t collect or store any data from your apps."; - -/* First question for AppTP FAQ page */ -"appTP.faq.question1" = "How does App Tracking Protection work?"; - -/* Second question for AppTP FAQ page */ -"appTP.faq.question2" = "Does App Tracking Protection block trackers in all apps on my device?"; - -/* Third question for AppTP FAQ page */ -"appTP.faq.question3" = "Does App Tracking Protection block all app trackers?"; - -/* Fourth question for AppTP FAQ page */ -"appTP.faq.question4" = "Why does App Tracking Protection use a VPN connection?"; - -/* Fifth question for AppTP FAQ page */ -"appTP.faq.question5" = "Will App Tracking Protection work if I also use a VPN app?"; - -/* Sixth question for AppTP FAQ page */ -"appTP.faq.question6" = "How is App Tracking Protection different from a VPN?"; - -/* Seventh question for AppTP FAQ page */ -"appTP.faq.question7" = "Is my data private?"; - -/* Title for AppTP FAQ page */ -"appTP.faq.title" = "App Tracking Protection FAQ"; - -/* Do not translate. StringsDict entry -- Count part of string 'App Tracking Protection blocked x tracking attempts today' */ -"appTP.home.blockedCount" = "appTP.home.blockedCount"; - -/* Prefix of string 'App Tracking Protection blocked x tracking attempts today' (note the trailing space) */ -"appTP.home.blockedPrefix" = "App Tracking Protection blocked "; - -/* Prefix of string 'App Tracking Protection blocked x tracking attempts today' (note the leading space) */ -"appTP.home.blockedSuffix" = " in your apps today."; - -/* Prefix of string 'App Tracking Protection disabled. Tap to re-enable.' (note the trailing space) */ -"appTP.home.disabledPrefix" = "App Tracking Protection disabled. "; - -/* Suffix of string 'App Tracking Protection disabled. Tap to re-enable.' */ -"appTP.home.disabledSuffix" = "Tap to continue blocking tracking attempts across your apps."; - -/* Text indicating the tracking event occured 'just now'. Example: Last attempt 'just now' */ -"appTP.justNow" = "just now"; - -/* View to manage trackers for AppTP. Allows the user to turn trackers on or off. */ -"appTP.manageTrackers" = "Manage Trackers"; - -/* Button title for AppTP onboarding */ -"appTP.onboarding.continueButton" = "Continue"; - -/* Button title for AppTP onboarding to enable AppTP */ -"appTP.onboarding.enableeButton" = "Enable App Tracking Protection"; - -/* Button title for AppTP onboarding to learn more about AppTP */ -"appTP.onboarding.learnMoreButton" = "Learn More"; - -/* First part of info on the first AppTP onboarding page */ -"appTP.onboarding.page1Info1" = "Over 85% of free iOS apps"; - -/* Second part of info on the first AppTP onboarding page (note the leading space) */ -"appTP.onboarding.page1Info2" = " we’ve tested allow other companies to track your personal information, even when you’re sleeping."; - -/* Third part of info on the first AppTP onboarding page */ -"appTP.onboarding.page1Info3" = "See who we catch trying to track you in your apps and take back control."; - -/* First part of info on the second AppTP onboarding page (note the trailing space) */ -"appTP.onboarding.page2Info1" = "App Tracking Protection "; - -/* Second part of info on the second AppTP onboarding page */ -"appTP.onboarding.page2Info2" = "detects and blocks app trackers from other companies,"; - -/* Third part of info on the second AppTP onboarding page (note the leading space) */ -"appTP.onboarding.page2Info3" = " like when Google attempts to track you in a health app."; - -/* Fourth part of info on the second AppTP onboarding page */ -"appTP.onboarding.page2Info4" = "It’s free,"; - -/* Fifth part of info on the second AppTP onboarding page (note the leading and trailing space) */ -"appTP.onboarding.page2Info5" = " and you can enjoy your apps as you normally would. Working in the background, it helps "; - -/* Sixth part of info on the second AppTP onboarding page */ -"appTP.onboarding.page2Info6" = "protect you night and day."; - -/* First part of info on the third AppTP onboarding page */ -"appTP.onboarding.page3Info1" = "App Tracking Protection is not a VPN."; - -/* Second part of info on the third AppTP onboarding page (note the leading space) */ -"appTP.onboarding.page3Info2" = " However, your device will recognize it as one. This is because it uses a local VPN connection to work."; - -/* Third part of info on the third AppTP onboarding page (note the trailing space) */ -"appTP.onboarding.page3Info3" = "App Tracking Protection is different. "; - -/* Fourth part of info on the third AppTP onboarding page */ -"appTP.onboarding.page3Info4" = "It never routes app data through an external server."; - -/* Title for first AppTP onboarding page */ -"appTP.onboarding.title1" = "One easy step for better app privacy!"; - -/* Title for second AppTP onboarding page */ -"appTP.onboarding.title2" = "How does it work?"; - -/* Title for third AppTP onboarding page */ -"appTP.onboarding.title3" = "Who sees your data?"; - -/* Breakage report app name label */ -"appTP.report.appLabel" = "Which app is having issues?"; - -/* Breakage report app name placeholder */ -"appTP.report.appPlaceholder" = "App name"; - -/* Breakage report category label */ -"appTP.report.categoryLabel" = "What’s happening?"; - -/* Breakage report comment label */ -"appTP.report.commentLabel" = "Comments"; - -/* Breakage report comment placeholder */ -"appTP.report.commentPlaceholder" = "Add additional details"; - -/* Breakage report footer explaining what is collected in the breakage report */ -"appTP.report.footer" = "In addition to the details entered into this form, your app issue report will contain: -• A list of trackers blocked in the last 10 min -• Whether App Tracking Protection is enabled -• Aggregate DuckDuckGo app diagnostics"; - -/* Breakage report submit button */ -"appTP.report.submit" = "Submit"; - -/* Breakage report form title */ -"appTP.report.title" = "Report Issue"; - -/* Breakage report succcess message */ -"appTP.report.toast" = "Thank you! Feedback submitted."; - -/* Cancel button for 'Report an Issue' alert. */ -"appTP.reportAlert.cancel" = "Not Now"; - -/* Confirm button for 'Report an Issue' alert. */ -"appTP.reportAlert.confirm" = "Report Issue"; - -/* Message for 'Report an Issue' alert. */ -"appTP.reportAlert.message" = "Let us know if you disabled App Tracking Protection for this specific tracker because it caused app issues. Your feedback helps us improve!"; - -/* Title for 'Report an Issue' alert. */ -"appTP.reportAlert.title" = "Report Issue?"; - -/* Toast notification diplayed after restoring the blocklist to default settings */ -"appTP.restoreDefaultsToast" = "Default settings restored"; - -/* Button to restore the blocklist to its default state. */ -"appTP.restoreDefualts" = "Restore Defaults"; - -/* Title for the App Tracking Protection feature */ -"appTP.title" = "App Tracking Protection"; - -/* Text indicating when the tracker was last allowed. Example: Last attempt allowed (timeString) */ -"appTP.trackerAllowedTimestamp" = "Last attempt allowed %@"; - -/* Text indicating when the tracker was last blocked. Example: Last attempt blocked (timeString) */ -"appTP.trackerBlockedTimestamp" = "Last attempt blocked %@"; - -/* Do not translate. StringsDict entry -- Subtitle for tracking attempts in App Tracking Protection Activity View. Example: (count) tracking attempts */ -"appTP.trackingattempts" = "appTP.trackingattempts"; - -/* Authentication Alert Sign In Button */ -"auth.alert.login.button" = "Sign In"; - -/* Authentication Alert - populated with a domain name */ -"auth.alert.message.encrypted" = "Sign in to %@. Your login information will be sent securely."; - -/* Authentication Alert - populated with a domain name */ -"auth.alert.message.plain" = "Log in to %@. Your password will be sent insecurely because the connection is unencrypted."; - -/* Authentication Password field placeholder */ -"auth.alert.password.placeholder" = "Password"; - -/* Authentication Alert Title */ -"auth.alert.title" = "Authentication Required"; - -/* Authentication User name field placeholder */ -"auth.alert.username.placeholder" = "Username"; - -/* No comment provided by engineer. */ -"autoclear.off" = "Off"; - -/* No comment provided by engineer. */ -"autoclear.on" = "On"; - -/* Autoconsent for Cookie Management Setting state */ -"autoconsent.disabled" = "Disabled"; - -/* Autoconsent for Cookie Management Setting state */ -"autoconsent.enabled" = "Enabled"; - -/* No comment provided by engineer. */ -"autoconsent.info.header" = "When DuckDuckGo detects cookie consent pop-ups on sites you visit, we can try to automatically set your cookie preferences to minimize cookies and maximize privacy, then close the pop-ups. Some sites don't provide an option to manage cookie preferences, so we can only hide pop-ups like these."; - -/* Text link to email protection website */ -"autofill.enable.email.protection" = "Enable Email Protection"; - -/* Accessibility title for a Hide Password button replacing displayed password with ***** */ -"autofill.hide-password" = "Hide Password"; - -/* Disable action for alert when asking the user if they want to keep using autofill */ -"autofill.keep-enabled.alert.disable" = "Disable"; - -/* Confirm action for alert when asking the user if they want to keep using autofill */ -"autofill.keep-enabled.alert.keep-using" = "Keep Saving"; - -/* Message for alert when asking the user if they want to keep using autofill */ -"autofill.keep-enabled.alert.message" = "You can disable this at any time in Settings."; - -/* Title for alert when asking the user if they want to keep using autofill */ -"autofill.keep-enabled.alert.title" = "Do you want to keep saving passwords?"; - -/* Button displayed after saving/updating an autofill login that takes the user to the saved login */ -"autofill.login-save-action-button.toast" = "View"; - -/* Message displayed after saving an autofill login */ -"autofill.login-saved.toast" = "Password saved"; - -/* Message displayed after updating an autofill login */ -"autofill.login-updated.toast" = "Password updated"; - -/* Menu item text for copying autofill login details */ -"autofill.logins.copy-prompt" = "Copy %@"; - -/* Title for toast when copying address */ -"autofill.logins.copy-toast.address-copied" = "Address copied"; - -/* Title for toast when copying notes */ -"autofill.logins.copy-toast.notes-copied" = "Notes copied"; - -/* Title for toast when copying password */ -"autofill.logins.copy-toast.password-copied" = "Password copied"; - -/* Title for toast when copying username */ -"autofill.logins.copy-toast.username-copied" = "Username copied"; - -/* Address label for login details on autofill */ -"autofill.logins.details.address" = "Website URL"; - -/* Title for autofill login details */ -"autofill.logins.details.default-title" = "Password"; - -/* Delete button when deleting an autofill login */ -"autofill.logins.details.delete" = "Delete Password"; - -/* Autofill alert button confirming delete autofill login */ -"autofill.logins.details.delete-confirmation.button" = "Delete Password"; - -/* Title of confirmation alert when deleting an autofill login */ -"autofill.logins.details.delete-confirmation.title" = "Are you sure you want to delete this password?"; - -/* Title when editing autofill login details */ -"autofill.logins.details.edit-title" = "Edit Password"; - -/* Placeholder for password field on autofill login details */ -"autofill.logins.details.edit.password-placeholder" = "Password"; - -/* Placeholder for title field on autofill login details */ -"autofill.logins.details.edit.title-placeholder" = "Title"; - -/* Placeholder for url field on autofill login details */ -"autofill.logins.details.edit.url-placeholder" = "example.com"; - -/* Placeholder for userbane field on autofill login details */ -"autofill.logins.details.edit.username-placeholder" = "username@example.com"; - -/* Message displaying when the login was last updated */ -"autofill.logins.details.last-updated" = "Last updated %@"; - -/* Login name label for login details on autofill */ -"autofill.logins.details.login-name" = "Title"; - -/* Title when adding new autofill login */ -"autofill.logins.details.new-title" = "Add password"; - -/* Notes label for login details on autofill */ -"autofill.logins.details.notes" = "Notes"; - -/* Menu item title for option to open website from selected url */ -"autofill.logins.details.open-website-prompt.title" = "Open Website"; - -/* Password label for login details on autofill */ -"autofill.logins.details.password" = "Password"; - -/* Action text for alert when attempting to save a duplicate login */ -"autofill.logins.details.save-duplicate-alert.action" = "OK"; - -/* Message for alert when attempting to save a duplicate login */ -"autofill.logins.details.save-duplicate-alert.message" = "You already have a password saved for this username and website."; - -/* Title for alert when attempting to save a duplicate login */ -"autofill.logins.details.save-duplicate-alert.title" = "Duplicate Password"; - -/* Username label for login details on autofill */ -"autofill.logins.details.username" = "Username"; - -/* Subtitle for view displayed when autofill has no items */ -"autofill.logins.empty-view.subtitle" = "Passwords are stored securely on your device."; - -/* Title for view displayed when autofill has no items */ -"autofill.logins.empty-view.title" = "No passwords saved yet"; - -/* Cancel button for auth when opening login list */ -"autofill.logins.list.auth.cancel" = "Cancel"; - -/* Reason for auth when opening login list */ -"autofill.logins.list.auth.reason" = "Unlock device to access passwords"; - -/* Title for close navigation button */ -"autofill.logins.list.close-title" = "Close"; - -/* Title for a toggle that enables autofill */ -"autofill.logins.list.enable" = "Save and autofill passwords"; - -/* Toast message when a login item is deleted */ -"autofill.logins.list.login-deleted-message" = "Password for %@ deleted"; - -/* Toast message when a login item without a title is deleted */ -"autofill.logins.list.login-deleted-message-no-title" = "Password deleted"; - -/* Title for a button that allows a user to reset their list of never saved sites */ -"autofill.logins.list.never.saved" = "Reset Excluded Sites"; - -/* Cancel button for resetting list of never saved sites */ -"autofill.logins.list.never.saved.reset.action.cancel" = "Cancel"; - -/* Confirm button to reset list of never saved sites */ -"autofill.logins.list.never.saved.reset.action.confirm" = "Reset Excluded Sites"; - -/* Alert title */ -"autofill.logins.list.never.saved.reset.action.title" = "If you reset excluded sites, you will be prompted to save your password next time you sign in to any of these sites."; - -/* Placeholder for search field on autofill login listing */ -"autofill.logins.list.search-placeholder" = "Search passwords"; - -/* Section title for group of suggested saved logins */ -"autofill.logins.list.suggested" = "Suggested"; - -/* Title for screen listing autofill logins */ -"autofill.logins.list.title" = "Passwords"; - -/* Title for view displayed when autofill is locked on devices where a passcode has not been set */ -"autofill.logins.no-auth.subtitle" = "A passcode is required to protect your passwords."; - -/* Title for view displayed when autofill is locked on devices where a passcode has not been set */ -"autofill.logins.no-auth.title" = "Secure your device to save passwords"; - -/* Cancel button for auth during login prompt */ -"autofill.logins.prompt.auth.cancel" = "Cancel"; - -/* Reason for auth during login prompt */ -"autofill.logins.prompt.auth.reason" = "Unlock to use saved password"; - -/* Title for section of autofill logins that are an exact match to the current website */ -"autofill.logins.prompt.exact.match.title" = "From this website"; - -/* Button title for autofill login prompt if more options are available */ -"autofill.logins.prompt.more-options" = "More Options"; - -/* Title for section of autofill logins that are an approximate match to the current website */ -"autofill.logins.prompt.partial.match.title" = "From %@"; - -/* Title of button for autofill login prompt to use a saved password for a website */ -"autofill.logins.prompt.password.button.title" = "Password for %@"; - -/* Title for autofill login prompt */ -"autofill.logins.prompt.title" = "Use a saved password?"; - -/* Subtitle displayed when there are no results on Autofill search, example : No Result (Title) for Duck (Subtitle) */ -"autofill.logins.search.no-results.subtitle" = "for '%@'"; - -/* Title displayed when there are no results on Autofill search */ -"autofill.logins.search.no-results.title" = "No Results"; - -/* Subtitle for prompt to use suggested strong password for creating a login */ -"autofill.password-generation-prompt.subtitle" = "Passwords are stored securely on your device."; - -/* Title for prompt to use suggested strong password for creating a login */ -"autofill.password-generation-prompt.title" = "Use a strong password from DuckDuckGo?"; - -/* Button title choosing to use the suggested generated password for creating a login */ -"autofill.password-generation-prompt.use-generated-password.cta" = "Use Strong Password"; - -/* Button title choosing to use own password for creating a login */ -"autofill.password-generation-prompt.use-own-password.cta" = "Create My Own"; - -/* Text for the confirmation message displayed when a user tries activate a Private Email Address */ -"autofill.private.email.mesage.activate.confirm.content" = "Emails sent to %@ will again be forwarded to your inbox."; - -/* Title for the confirmation message displayed when a user tries activate a Private Email Address */ -"autofill.private.email.mesage.activate.confirm.title" = "Reactivate Private Duck Address?"; - -/* Mesasage displayed when a private email address is active */ -"autofill.private.email.mesage.active" = "Active"; - -/* Text for the confirmation message displayed when a user tries deactivate a Private Email Address */ -"autofill.private.email.mesage.deactivate.confirm.content" = "Emails sent to %@ will no longer be forwarded to your inbox."; - -/* Title for the confirmation message displayed when a user tries deactivate a Private Email Address */ -"autofill.private.email.mesage.deactivate.confirm.title" = "Deactivate Private Duck Address?"; - -/* Mesasage displayed when a user tries to manage a private email address but the service is not available, returns an error or network is down */ -"autofill.private.email.mesage.error" = "Management of this address is temporarily unavailable"; - -/* Mesasage displayed when a private email address is inactive */ -"autofill.private.email.mesage.inactive" = "Deactivated"; - -/* Button text for the alert dialog telling the user an updated username is no longer a private email address */ -"autofill.removed.duck.address.button" = "Got it"; - -/* Content for the alert dialog telling the user an updated username is no longer a private email address */ -"autofill.removed.duck.address.content" = "You can still manage this Duck Address from emails received from it in your personal inbox."; - -/* Title for the alert dialog telling the user an updated username is no longer a private email address */ -"autofill.removed.duck.address.title" = "Private Duck Address username was removed"; - -/* CTA displayed on modal asking if the user never wants to be prompted to save a login for this website agin */ -"autofill.save-login.never-prompt.CTA" = "Never Ask for This Site"; - -/* Message displayed on modal asking for the user to save the login for the first time */ -"autofill.save-login.new-user.message" = "Passwords are stored securely on your device."; - -/* Title displayed on modal asking for the user to save the login for the first time */ -"autofill.save-login.new-user.title" = "Do you want DuckDuckGo to save your password?"; - -/* Cancel CTA displayed on modal asking for the user to save the login */ -"autofill.save-login.not-now.CTA" = "Don’t Save"; - -/* Title displayed on modal asking for the user to save the login */ -"autofill.save-login.title" = "Save Password?"; - -/* Confirm CTA displayed on modal asking for the user to save the password */ -"autofill.save-password.save.CTA" = "Save Password"; - -/* Accessibility title for a Show Password button displaying actial password instead of ***** */ -"autofill.show-password" = "Show Password"; - -/* Message displayed to the user when they are logged out of Email protection. */ -"autofill.signin.to.manage" = "%@ to manage your Duck Addresses on this device."; - -/* Message displayed on modal asking for the user to update the password */ -"autofill.update-password.message" = "DuckDuckGo will update this stored password on your device."; - -/* Confirm CTA displayed on modal asking for the user to update the password */ -"autofill.update-password.save.CTA" = "Update Password"; - -/* Title displayed on modal asking for the user to update the password */ -"autofill.update-password.title" = "Update password for\n%@?"; - -/* Confirm CTA displayed on modal asking for the user to update the login */ -"autofill.update-username.save.CTA" = "Update Username"; - -/* Title displayed on modal asking for the user to update the username */ -"autofill.update-usernamr.title" = "Update username?"; - -/* Add bookmark screen title */ -"bookmark.addBookmark.title" = "Add Bookmark"; - -/* Add favorite screen title */ -"bookmark.addFavorite.title" = "Add Favorite"; - -/* Add folder screen title */ -"bookmark.addFolder.title" = "Add Folder"; - -/* Add bookmark folder button text */ -"bookmark.addFolderButton" = "Add Folder"; - -/* Placeholder in the add bookmark form */ -"bookmark.address.placeholder" = "www.example.com"; - -/* Delete bookmark alert message */ -"bookmark.delete.alert.message" = "This will delete your bookmark for \"%@\""; - -/* Delete bookmark alert title */ -"bookmark.delete.alert.title" = "Delete?"; - -/* The message shown after a bookmark has been deleted */ -"bookmark.deleted.toast" = "Bookmark deleted"; - -/* Delete bookmark folder alert delete button */ -"bookmark.deleteFolderAlert.deleteButton" = "Delete"; - -/* Do not translate - stringsdict entry */ -"bookmark.deleteFolderAlert.message" = "bookmark.deleteFolderAlert.message"; - -/* Delete bookmark folder alert title */ -"bookmark.deleteFolderAlert.title" = "Delete %@?"; - -/* Edit bookmark screen title */ -"bookmark.editBookmark.title" = "Edit Bookmark"; - -/* Edit favorite screen title */ -"bookmark.editFavorite.title" = "Edit Favorite"; - -/* Edit folder screen title */ -"bookmark.editFolder.title" = "Edit Folder"; - -/* Header for folder selection for bookmarks */ -"bookmark.folderSelect.title" = "Location"; - -/* More options button text */ -"bookmark.moreButton" = "More"; - -/* Placeholder in the add bookmark form */ -"bookmark.title.placeholder" = "Website title"; - -/* Top level bookmarks folder title */ -"bookmark.topLevelFolder.title" = "Bookmarks"; - -/* Info message after selecting Bookmark All button */ -"bookmarkAll.tabs.failed" = "Added new bookmarks for all tabs"; - -/* Confirmation message after selecting Bookmark All button */ -"bookmarkAll.tabs.saved" = "All tabs bookmarked"; - -/* No comment provided by engineer. */ -"bookmarks.button.hint" = "Bookmarks"; - -/* Failure message when bookmarks failed to export */ -"bookmarks.export.failed.message" = "We couldn’t export your bookmarks, please try again."; - -/* Confirmation message that bookmarks have been exported to the file system */ -"bookmarks.export.files.success.message" = "Your bookmarks have been exported."; - -/* Confirmation message that bookmarks have been shared successfully to another app */ -"bookmarks.export.share.success.message" = "Your bookmarks have been shared."; - -/* Title of option to export HTML */ -"bookmarks.exportAction.title" = "Export HTML File"; - -/* Failure message when bookmarks failed to import */ -"bookmarks.import.failed.message" = "Sorry, we aren’t able to import this file."; - -/* Confirmation message that bookmarks have been imported */ -"bookmarks.import.success.message" = "Your bookmarks have been imported."; - -/* Title of option to import HTML */ -"bookmarks.importAction.title" = "Import HTML File"; - -/* Import bookmark file button text */ -"bookmarks.importExport.footer.button.title" = "Import bookmark file from another browser"; - -/* Title of prompt for users where they can choose to import or export an HTML file containing webpage bookmarks */ -"bookmarks.importExport.title" = "Import an HTML file of bookmarks from another browser, or export your existing bookmarks."; - -/* Title for a section containing only items from past month */ -"date.range.past-month" = "Past month"; - -/* Title for a section containing only items from past week */ -"date.range.past-week" = "Past week"; - -/* Title for a section containing only items from today */ -"date.range.today" = "Today"; - -/* Title for a section containing only items from yesterday */ -"date.range.yesterday" = "Yesterday"; - -/* Button title accepting to enable feature to automatically manage cookie popups */ -"dax.cookie-consent.button.accept" = "Manage Cookie Pop-ups"; - -/* Button title rejecting to enable feature to automatically manage cookie popups */ -"dax.cookie-consent.button.reject" = "No Thanks"; - -/* First part of text displayed on Dax dialog for enabling Autoconsent for Cookie Management feature */ -"dax.cookie-consent.first" = "Looks like this site has a cookie consent pop-up👇"; - -/* Second part of text displayed on Dax dialog for enabling Autoconsent for Cookie Management feature */ -"dax.cookie-consent.second" = "Want me to handle these for you? I can try to minimize cookies, maximize privacy, and hide pop-ups like these."; - -/* No comment provided by engineer. */ -"dax.hide.button" = "Hide Tips Forever"; - -/* No comment provided by engineer. */ -"dax.hide.cancel" = "Cancel"; - -/* Subtitle in Hide Dax dialog */ -"dax.hide.message" = "There are only a few, and we tried to make them informative."; - -/* Title in Hide Dax dialog */ -"dax.hide.title" = "Hide remaining tips?"; - -/* No comment provided by engineer. */ -"dax.onboarding.browsing.after.search" = "Your DuckDuckGo searches are anonymous. Always. 🙌"; - -/* No comment provided by engineer. */ -"dax.onboarding.browsing.after.search.cta" = "Phew!"; - -/* First parameter is a count of additional trackers, second and third are names of the tracker networks (strings) */ -"dax.onboarding.browsing.multiple.trackers" = "dax.onboarding.browsing.multiple.trackers"; - -/* No comment provided by engineer. */ -"dax.onboarding.browsing.multiple.trackers.cta" = "High Five!"; - -/* Parameter is domain name (string) */ -"dax.onboarding.browsing.one.tracker" = "*%1$@* was trying to track you here.\n\nI blocked them!\n\n☝️ You can check the address bar to see who is trying to track you when you visit a new site."; - -/* No comment provided by engineer. */ -"dax.onboarding.browsing.one.tracker.cta" = "High Five!"; - -/* First paramter is a string - network name, 2nd parameter is a string - domain name */ -"dax.onboarding.browsing.site.is.major.tracker" = "Heads up! I can’t stop %1$@ from seeing your activity on %2$@.\n\nBut browse with me, and I can reduce what %1$@ knows about you overall by blocking their trackers on lots of other sites."; - -/* No comment provided by engineer. */ -"dax.onboarding.browsing.site.is.major.tracker.cta" = "Got It"; - -/* Parameters are domain names (strings) */ -"dax.onboarding.browsing.site.owned.by.major.tracker" = "Heads up! Since %2$@ owns %1$@, I can’t stop them from seeing your activity here.\n\nBut browse with me, and I can reduce what %2$@ knows about you overall by blocking their trackers on lots of other sites."; - -/* Got It */ -"dax.onboarding.browsing.site.owned.by.major.tracker.cta" = "Got It"; - -/* No comment provided by engineer. */ -"dax.onboarding.browsing.without.trackers" = "As you tap and scroll, I’ll block pesky trackers.\n\nGo ahead - keep browsing!"; - -/* No comment provided by engineer. */ -"dax.onboarding.browsing.without.trackers.cta" = "Got It"; - -/* Encourage user to try clearing data with the fire button */ -"dax.onboarding.fire.button" = "Personal data can build up in your browser. Yuck. Use the Fire Button to burn it all away. Give it a try now! 👇"; - -/* Cancel action */ -"dax.onboarding.fire.button.cancelAction" = "Cancel"; - -/* Encourage user to try clearing data with the fire button */ -"dax.onboarding.fire.button.confirmAction" = "Close Tabs and Clear Data"; - -/* Encourage user to add favorite site using the browsing menu. */ -"dax.onboarding.home.add.favorite" = "Visit your favorite sites in a flash!\n\nGo to a site you love. Then tap the \"⋯\" icon and select *Add to Favorites*."; - -/* Accessible version of dax.onboarding.home.add.favorite */ -"dax.onboarding.home.add.favorite.accessible" = "Visit your favorite sites in a flash! Visit one of your favorite sites. Then tap the open menu button and select Add to Favorites."; - -/* No comment provided by engineer. */ -"dax.onboarding.home.initial" = "Next, try visiting one of your favorite sites!\n\nI’ll block trackers so they can’t spy on you. I’ll also upgrade the security of your connection if possible. 🔒"; - -/* ad = advertisment */ -"dax.onboarding.home.subsequent" = "You’ve got this!\n\nRemember: Every time you browse with me, a creepy ad loses its wings. 👍"; - -/* No comment provided by engineer. */ -"dax.onboarding.message" = "The Internet can be kinda creepy.\n\nNot to worry! Searching and browsing privately is easier than you think."; - -/* GPC Setting state */ -"donotsell.disabled" = "Disabled"; - -/* No comment provided by engineer. */ -"donotsell.disclaimer.learnmore" = "Learn More"; - -/* GPC Setting state */ -"donotsell.enabled" = "Enabled"; - -/* No comment provided by engineer. */ -"donotsell.info.headertext" = "DuckDuckGo automatically blocks many trackers. With Global Privacy Control (GPC), you can also ask participating websites to restrict selling or sharing your personal data with other companies."; - -/* Alert action for starting a file dowload */ -"downloads.alert.action.save-to-downloads" = "Save to Downloads"; - -/* Cancel download action for alert when trying to cancel the file download */ -"downloads.cancel-download.alert.cancel" = "Cancel"; - -/* Message for alert when trying to cancel the file download */ -"downloads.cancel-download.alert.message" = "Are you sure you want to cancel this download?"; - -/* Resume download action for alert when trying to cancel the file download */ -"downloads.cancel-download.alert.resume" = "Resume"; - -/* Title for alert when trying to cancel the file download */ -"downloads.cancel-download.alert.title" = "Cancel download?"; - -/* Button for deleting all items on downloads list */ -"downloads.downloads-list.delete-all" = "Delete All"; - -/* Empty downloads list placholder */ -"downloads.downloads-list.empty" = "No files downloaded yet"; - -/* Label displaying file download progress. Both parameters are formatted data size measurements e.g. 5MB. First parameter is data size currently downloaded. Second parameter is total expected data size of the file. */ -"downloads.downloads-list.row.downloading" = "Downloading - %1$@ of %2$@"; - -/* Label displaying file download progress. The parameter is formatted data size measurements currently downloaded e.g. 5MB. */ -"downloads.downloads-list.row.downloadingUnknownTotalSize" = "Downloading - %@"; - -/* Downloads list screen title */ -"downloads.downloads-list.title" = "Downloads"; - -/* Additional alert message shown when there are active downloads when using the fire button */ -"downloads.fire-button.alert.message" = "This will also cancel downloads in progress"; - -/* Message confirming that all files on the downloads list have been deleted */ -"downloads.message.all-files-deleted" = "All files deleted"; - -/* Message confirming that the download process has completed. Parameter is downloaded file's filename */ -"downloads.message.download-complete" = "Download complete for %@"; - -/* Message confirming the file was deleted. Parameter is file's filename */ -"downloads.message.download-deleted" = "Deleted %@"; - -/* Message informing that the download has failed due to connection issues */ -"downloads.message.download-failed" = "Failed to download. Check internet connection."; - -/* Message confirming that the download process has started. Parameter is downloaded file's filename */ -"downloads.message.download-started" = "Download started for %@"; - -/* Email protection service offered by DuckDuckGo */ -"email-protection" = "Email Protection"; - -/* Cancel option for the email alias alert */ -"email.aliasAlert.decline" = "Cancel"; - -/* Option for generating a private email address */ -"email.aliasAlert.generatePrivateAddress" = "Generate Private Duck Address"; - -/* Option for generating a private email address */ -"email.aliasAlert.prompt.generatePrivateAddress" = "Generate Private Duck Address"; - -/* Subtitle for generating a private email address */ -"email.aliasAlert.prompt.generatePrivateAddress.subtitle" = "Block email trackers & hide address"; - -/* Title for the email alias selection prompt */ -"email.aliasAlert.prompt.title" = "Select email address"; - -/* Subtitle for choosing primary user email address */ -"email.aliasAlert.prompt.useUserAddress.subtitle" = "Block email trackers"; - -/* Title for the email alias selection alert */ -"email.aliasAlert.title" = "Block email trackers with a Duck Address"; - -/* Parameter is an email address (string) */ -"email.aliasAlert.useUserAddress" = "Use %@"; - -/* Title for the email copy browsing menu alert */ -"email.browsingMenu.alert" = "New address copied to your clipboard"; - -/* Email option title in the browsing menu */ -"email.browsingMenu.useNewDuckAddress" = "Generate Private Duck Address"; - -/* Signed in state for the email feature */ -"email.settings.enabled" = "Enabled"; - -/* Footer text for the email feature */ -"email.settings.footer" = "Removing Email Protection from this device removes the option to fill in your Personal Duck Address or a newly generated Private Duck Address into email fields as you browse the web.\n\nTo delete your Duck Addresses entirely, or for any other questions or feedback, reach out to us at support@duck.com."; - -/* Signed out state for the email feature */ -"email.settings.off" = "Off"; - -/* Subtitle for the email settings cell */ -"email.settings.subtitle" = "Block email trackers and hide your address"; - -/* Option to continue the Email Protection signup */ -"email.signup-prompt.alert.continue" = "Continue Setup"; - -/* Option to exit the Email Protection signup */ -"email.signup-prompt.alert.exit" = "Exit Setup"; - -/* Title for exiting the Email Protection signup early alert */ -"email.signup-prompt.alert.title" = "If you exit now, your Duck Address will not be saved!"; - -/* Button title choosing not to sign up for email protection and not to be prompted again */ -"email.signup-prompt.do-not-signup-button.cta" = "Don’t Show Again"; - -/* Button title choosing to sign up for email protection */ -"email.signup-prompt.signup-button.cta" = "Protect My Email"; - -/* Subtitle for prompt to sign up for email protection */ -"email.signup-prompt.subtitle" = "Create a unique, random address that also removes hidden trackers and forwards email to your inbox."; - -/* Title for prompt to sign up for email protection */ -"email.signup-prompt.title" = "Hide Your Email and\nBlock Trackers"; - -/* Empty list state placholder */ -"empty.bookmarks" = "No bookmarks added yet"; - -/* Empty search placeholder on bookmarks search */ -"empty.search" = "No matches found"; - -/* Button title to Sign In */ -"error.email-protection-sign-in.action" = "Sign In"; - -/* Alert message */ -"error.email-protection-sign-in.body" = "Sorry, please sign in again to re-enable Email Protection features on this browser."; - -/* Alert title */ -"error.email-protection-sign-in.title" = "Email Protection Error"; - -/* Button title to open device settings */ -"error.insufficient-disk-space.action" = "Open Settings"; - -/* Alert message */ -"error.insufficient-disk-space.body" = "Looks like your device has run out of storage space. Please free up space to continue."; - -/* Alert title */ -"error.insufficient-disk-space.title" = "Not enough storage"; - -/* Button title that is shutting down the app */ -"error.preemptive-crash.action" = "Close App"; - -/* Alert message */ -"error.preemptive-crash.body" = "Looks like there's an issue with the app and it needs to close. Please reopen to continue."; - -/* Alert title */ -"error.preemptive-crash.title" = "App issue detected"; - -/* Generic error message on a dialog for when the cause is not known. */ -"error.unknown.try.again" = "An unknown error has occurred"; - -/* No comment provided by engineer. */ -"favorite" = "Favorite"; - -/* No comment provided by engineer. */ -"favorite.menu.edit" = "Edit"; - -/* No comment provided by engineer. */ -"favorite.menu.remove" = "Remove"; - -/* Display Mode for favorites */ -"favorites.settings.all-devices" = "All Device Favorites"; - -/* Footer of the favorites settings table */ -"favorites.settings.footer" = "Choose which favorites to display on a new tab based on their origin."; - -/* Header of the favorites settings table */ -"favorites.settings.header" = "Display Preferences"; - -/* Display Mode for favorites */ -"favorites.settings.mobile-only" = "Mobile Favorites Only"; - -/* No comment provided by engineer. */ -"feedback.browserFeatures.ads" = "Ad and pop-up blocking"; - -/* No comment provided by engineer. */ -"feedback.browserFeatures.bookmarks" = "Creating and managing bookmarks"; - -/* No comment provided by engineer. */ -"feedback.browserFeatures.caption" = "Which browsing feature can we add or improve?"; - -/* No comment provided by engineer. */ -"feedback.browserFeatures.description" = "Browser Feature Issues"; - -/* No comment provided by engineer. */ -"feedback.browserFeatures.entry" = "Browsing features are missing or frustrating"; - -/* No comment provided by engineer. */ -"feedback.browserFeatures.images" = "Interacting with images"; - -/* No comment provided by engineer. */ -"feedback.browserFeatures.navigation" = "Navigating forward, backward, and/or refreshing"; - -/* No comment provided by engineer. */ -"feedback.browserFeatures.other" = "None of these"; - -/* No comment provided by engineer. */ -"feedback.browserFeatures.tabs" = "Creating and managing tabs"; - -/* No comment provided by engineer. */ -"feedback.browserFeatures.videos" = "Watching videos"; - -/* No comment provided by engineer. */ -"feedback.customization.bookmarks" = "How bookmarks are displayed"; - -/* No comment provided by engineer. */ -"feedback.customization.caption" = "Which customization option can we add or improve?"; - -/* No comment provided by engineer. */ -"feedback.customization.description" = "Customization Issues"; - -/* No comment provided by engineer. */ -"feedback.customization.entry" = "There aren’t enough ways to customize the app"; - -/* No comment provided by engineer. */ -"feedback.customization.homeScreen" = "The home screen configuration"; - -/* No comment provided by engineer. */ -"feedback.customization.other" = "None of these"; - -/* No comment provided by engineer. */ -"feedback.customization.tabs" = "How tabs are displayed"; - -/* No comment provided by engineer. */ -"feedback.customization.ui" = "How the app looks"; - -/* No comment provided by engineer. */ -"feedback.customization.whatIsCleared" = "Which data is cleared"; - -/* No comment provided by engineer. */ -"feedback.customization.whenIsCleared" = "When data is cleared"; - -/* No comment provided by engineer. */ -"feedback.ddgSearch.autocomplete" = "Better autocomplete"; - -/* No comment provided by engineer. */ -"feedback.ddgSearch.caption" = "Which search feature can we add or improve?"; - -/* No comment provided by engineer. */ -"feedback.ddgSearch.description" = "DuckDuckGo Search Issues"; - -/* No comment provided by engineer. */ -"feedback.ddgSearch.entry" = "DuckDuckGo search isn’t good enough"; - -/* No comment provided by engineer. */ -"feedback.ddgSearch.languageOrRegion" = "Searching in a specific language or region"; - -/* No comment provided by engineer. */ -"feedback.ddgSearch.layout" = "The layout should be more like Google"; - -/* No comment provided by engineer. */ -"feedback.ddgSearch.loadTime" = "Faster load time"; - -/* No comment provided by engineer. */ -"feedback.ddgSearch.other" = "None of these"; - -/* No comment provided by engineer. */ -"feedback.ddgSearch.technical" = "Programming/technical search"; - -/* No comment provided by engineer. */ -"feedback.form.caption" = "Please tell us what we can improve"; - -/* Confirmation button */ -"feedback.form.submit" = "Submit"; - -/* No comment provided by engineer. */ -"feedback.negative.form.genericPlaceholder" = "Please be as specific as possible"; - -/* No comment provided by engineer. */ -"feedback.negative.form.placeholder" = "Are there any specifics you’d like to include?"; - -/* No comment provided by engineer. */ -"feedback.negative.header" = "We’re Sorry to Hear That"; - -/* No comment provided by engineer. */ -"feedback.negative.supplementary" = "What is your frustration most related to?"; - -/* No comment provided by engineer. */ -"feedback.other.description" = "Other Issues"; - -/* No comment provided by engineer. */ -"feedback.other.entry" = "None of these"; - -/* No comment provided by engineer. */ -"feedback.performance.caption" = "Which issue are you experiencing?"; - -/* No comment provided by engineer. */ -"feedback.performance.crashes" = "The app crashes or freezes"; - -/* No comment provided by engineer. */ -"feedback.performance.description" = "Performance Issues"; - -/* No comment provided by engineer. */ -"feedback.performance.entry" = "The app is slow, buggy, or crashes"; - -/* No comment provided by engineer. */ -"feedback.performance.other" = "None of these"; - -/* No comment provided by engineer. */ -"feedback.performance.playback" = "Video or media playback bugs"; - -/* No comment provided by engineer. */ -"feedback.performance.slowLoading" = "Web pages or search results load slowly"; - -/* Header above input field */ -"feedback.positive.form.header" = "Share Details"; - -/* No comment provided by engineer. */ -"feedback.positive.form.placeholder" = "What have you been enjoying?"; - -/* No comment provided by engineer. */ -"feedback.positive.form.supplementary" = "Are there any details you’d like to share with the team?"; - -/* No comment provided by engineer. */ -"feedback.positive.header" = "Awesome to Hear!"; - -/* No comment provided by engineer. */ -"feedback.positive.noThanks" = "No Thanks! I’m Done"; - -/* Button encouraging uses to share details aboout their feedback */ -"feedback.positive.submit" = "Share Details"; - -/* No comment provided by engineer. */ -"feedback.start.footer" = "Your anonymous feedback is important to us."; - -/* No comment provided by engineer. */ -"feedback.start.header" = "Let’s Get Started!"; - -/* No comment provided by engineer. */ -"feedback.start.supplementary" = "How would you categorize your feedback?"; - -/* No comment provided by engineer. */ -"feedback.submitted.confirmation" = "Thank You! Feedback submitted."; - -/* No comment provided by engineer. */ -"feedback.websiteLoading.description" = "Website Loading Issues"; - -/* No comment provided by engineer. */ -"feedback.websiteLoading.entry" = "Certain websites don’t load correctly"; - -/* No comment provided by engineer. */ -"feedback.websiteLoading.form.placeholder" = "What content seems to be affected?"; - -/* No comment provided by engineer. */ -"feedback.websiteLoading.form.supplementary" = "Where are you seeing these issues?"; - -/* No comment provided by engineer. */ -"feedback.websiteLoading.form.urlPlaceholder" = "Which website has issues?"; - -/* Used to indicate number of entries found and position of the currently viewed one: e.g. 1 of 10 */ -"findinpage.count" = "%1$d of %2$d"; - -/* No comment provided by engineer. */ -"findinpage.title" = "Find in Page"; - -/* No comment provided by engineer. */ -"fireButtonAnimation.airstream.name" = "Airstream"; - -/* No comment provided by engineer. */ -"fireButtonAnimation.fireRising.name" = "Inferno"; - -/* No comment provided by engineer. */ -"fireButtonAnimation.none.name" = "None"; - -/* No comment provided by engineer. */ -"fireButtonAnimation.waterSwirl.name" = "Whirlpool"; - -/* No comment provided by engineer. */ -"home.row.onboarding.header" = "Add DuckDuckGo to your home screen!"; - -/* No comment provided by engineer. */ -"home.row.reminder.message" = "Add DuckDuckGo to your dock for easy access!"; - -/* Home is this context is the bottom home row (dock) */ -"home.row.reminder.title" = "Take DuckDuckGo home"; - -/* This describes empty tab */ -"homeTab.searchAndFavorites" = "Search or enter address"; - -/* Home tab title */ -"homeTab.title" = "Home"; - -/* OK title for invite screen alert dismissal button */ -"invite.alert.ok.button" = "OK"; - -/* Continue button on an invite dialog */ -"invite.dialog.continue.button" = "Continue"; - -/* Get Started button on an invite dialog */ -"invite.dialog.get.started.button" = "Get Started"; - -/* Message to show after user enters an unrecognized invite code */ -"invite.dialog.unrecognized.code.message" = "We didn’t recognize this Invite Code."; - -/* No comment provided by engineer. */ -"keyCommandAddBookmark" = "Add Bookmark"; - -/* No comment provided by engineer. */ -"keyCommandAddFavorite" = "Add Favorite"; - -/* No comment provided by engineer. */ -"keyCommandBrowserBack" = "Browse Back"; - -/* No comment provided by engineer. */ -"keyCommandBrowserForward" = "Browse Forward"; - -/* No comment provided by engineer. */ -"keyCommandClose" = "Close"; - -/* No comment provided by engineer. */ -"keyCommandCloseTab" = "Close Tab"; - -/* No comment provided by engineer. */ -"keyCommandFind" = "Find in Page"; - -/* No comment provided by engineer. */ -"keyCommandFindNext" = "Find Next"; - -/* No comment provided by engineer. */ -"keyCommandFindPrevious" = "Find Previous"; - -/* No comment provided by engineer. */ -"keyCommandFire" = "Clear All Tabs and Data"; - -/* No comment provided by engineer. */ -"keyCommandLocation" = "Search or Enter Address"; - -/* No comment provided by engineer. */ -"keyCommandNewTab" = "New Tab"; - -/* No comment provided by engineer. */ -"keyCommandNextTab" = "Next Tab"; - -/* No comment provided by engineer. */ -"keyCommandOpenInNewBackgroundTab" = "Open Link in Background"; - -/* No comment provided by engineer. */ -"keyCommandOpenInNewTab" = "Open Link in New Tab"; - -/* No comment provided by engineer. */ -"keyCommandPreviousTab" = "Previous Tab"; - -/* No comment provided by engineer. */ -"keyCommandPrint" = "Print"; - -/* No comment provided by engineer. */ -"keyCommandReload" = "Reload"; - -/* No comment provided by engineer. */ -"keyCommandSelect" = "Select"; - -/* No comment provided by engineer. */ -"keyCommandShowAllTabs" = "Show All Tabs"; - -/* Please preserve newline character */ -"launchscreenWelcomeMessage" = "Welcome to\nDuckDuckGo!"; - -/* Summary text for the macOS browser waitlist */ -"mac-browser.waitlist.summary" = "DuckDuckGo for Mac has the speed you need, the browsing features you expect, and comes packed with our best-in-class privacy essentials."; - -/* Title for the macOS waitlist notification */ -"mac-waitlist.available.notification.title" = "DuckDuckGo for Mac is ready!"; - -/* Title for the copy action */ -"mac-waitlist.copy" = "Copy"; - -/* Description text above the Share Link button */ -"mac-waitlist.join-waitlist-screen.on-your-computer-go-to" = "On your Windows computer, go to:"; - -/* Description text above the Share Link button */ -"mac-waitlist.join-waitlist-screen.on-your-mac-go-to" = "On your Mac, go to:"; - -/* Title for the Share Link button */ -"mac-waitlist.join-waitlist-screen.share-link" = "Share Link"; - -/* Title for the Join Waitlist screen */ -"mac-waitlist.join-waitlist-screen.try-duckduckgo-for-mac" = "Get DuckDuckGo for Mac!"; - -/* Disclaimer for the Join Waitlist screen */ -"mac-waitlist.join-waitlist-screen.windows" = "Windows coming soon!"; - -/* Title for the macOS waitlist button redirecting to Windows waitlist */ -"mac-waitlist.join-waitlist-screen.windows-waitlist" = "Looking for the Windows version?"; - -/* Title for the settings subtitle */ -"mac-waitlist.settings.browse-privately" = "Browse privately with our app for Mac"; - -/* Message used when sharing to iMessage */ -"mac-waitlist.share-sheet.message" = "Ready to start browsing privately on Mac? - -Visit this URL on your Mac to download: -https://duckduckgo.com/mac"; - -/* Title for the share sheet entry */ -"mac-waitlist.share-sheet.title" = "DuckDuckGo for Mac"; - -/* Title for the Mac Waitlist feature */ -"mac-waitlist.title" = "DuckDuckGo App for Mac"; - -/* No comment provided by engineer. */ -"menu.button.hint" = "Browsing Menu"; - -/* Title for back button in navigation bar */ -"navbar.back-button.title" = "Back"; - -/* Title for next button in navigation bar to progress forward */ -"navbar.next-button.title" = "Next"; - -/* Finish editing bookmarks button */ -"navigation.title.done" = "Done"; - -/* Edit button */ -"navigation.title.edit" = "Edit"; - -/* String indicating NetP is connected when viewed from the settings screen */ -"netP.cell.connected" = "Connected"; - -/* String indicating NetP is disconnected when viewed from the settings screen */ -"netP.cell.disconnected" = "Not connected"; - -/* Title for the Network Protection feature */ -"netP.title" = "Network Protection"; - -/* Privacy Policy title for Network Protection */ -"network-protection.privacy-policy.title" = "Privacy Policy"; - -/* Title text for the Network Protection terms and conditions accept button */ -"network-protection.waitlist.agree-and-continue" = "Agree and Continue"; - -/* Availability disclaimer for Network Protection join waitlist screen */ -"network-protection.waitlist.availability-disclaimer" = "Network Protection is free to use during early access."; - -/* Agree and Continue button for Network Protection join waitlist screen */ -"network-protection.waitlist.button.agree-and-continue" = "Agree and Continue"; - -/* Enable Notifications button for Network Protection joined waitlist screen */ -"network-protection.waitlist.button.enable-notifications" = "Enable Notifications"; - -/* Button title for users who already have an invite code */ -"network-protection.waitlist.button.existing-invite-code" = "I Have an Invite Code"; - -/* Join Waitlist button for Network Protection join waitlist screen */ -"network-protection.waitlist.button.join-waitlist" = "Join the Waitlist"; - -/* Button title text for the Network Protection waitlist confirmation prompt */ -"network-protection.waitlist.get-started" = "Get Started"; - -/* Subtitle for section 1 of the Network Protection invited screen */ -"network-protection.waitlist.invited.section-1.subtitle" = "Encrypt online traffic across your browsers and apps."; - -/* Title for section 1 of the Network Protection invited screen */ -"network-protection.waitlist.invited.section-1.title" = "Full-device coverage"; - -/* Subtitle for section 2 of the Network Protection invited screen */ -"network-protection.waitlist.invited.section-2.subtitle" = "No need for a separate app. Connect in one click and see your connection status at a glance."; - -/* Title for section 2 of the Network Protection invited screen */ -"network-protection.waitlist.invited.section-2.title" = "Fast, reliable, and easy to use"; - -/* Subtitle for section 3 of the Network Protection invited screen */ -"network-protection.waitlist.invited.section-3.subtitle" = "We do not log or save any data that can connect you to your online activity."; - -/* Title for section 3 of the Network Protection invited screen */ -"network-protection.waitlist.invited.section-3.title" = "Strict no-logging policy"; - -/* Subtitle for Network Protection invited screen */ -"network-protection.waitlist.invited.subtitle" = "Get an extra layer of protection online with the VPN built for speed and simplicity. Encrypt your internet connection across your entire device and hide your location and IP address from sites you visit."; - -/* Title for Network Protection invited screen */ -"network-protection.waitlist.invited.title" = "You’re invited to try\nNetwork Protection early access!"; - -/* First subtitle for Network Protection join waitlist screen */ -"network-protection.waitlist.join.subtitle.1" = "Secure your connection anytime, anywhere with Network Protection, the VPN from DuckDuckGo."; - -/* Second subtitle for Network Protection join waitlist screen */ -"network-protection.waitlist.join.subtitle.2" = "Join the waitlist, and we’ll notify you when it’s your turn."; - -/* Title for Network Protection join waitlist screen */ -"network-protection.waitlist.join.title" = "Network Protection Early Access"; - -/* Title for Network Protection joined waitlist screen */ -"network-protection.waitlist.joined.title" = "You’re on the list!"; - -/* Subtitle 1 for Network Protection joined waitlist screen when notifications are enabled */ -"network-protection.waitlist.joined.with-notifications.subtitle.1" = "New invites are sent every few days, on a first come, first served basis."; - -/* Subtitle 2 for Network Protection joined waitlist screen when notifications are enabled */ -"network-protection.waitlist.joined.with-notifications.subtitle.2" = "We’ll notify you when your invite is ready."; - -/* Body text for the alert to enable notifications */ -"network-protection.waitlist.notification-alert.description" = "We’ll send you a notification when your invite to test Network Protection is ready."; - -/* Subtitle for the alert to confirm enabling notifications */ -"network-protection.waitlist.notification-prompt-description" = "Get a notification when your copy of Network Protection early access is ready."; - -/* Title for the alert to confirm enabling notifications */ -"network-protection.waitlist.notification-prompt-title" = "Know the instant you're invited"; - -/* Title for Network Protection waitlist notification */ -"network-protection.waitlist.notification.text" = "Open your invite"; - -/* Title for Network Protection waitlist notification */ -"network-protection.waitlist.notification.title" = "Network Protection is ready!"; - -/* Subtitle text for the Network Protection settings row */ -"network-protection.waitlist.settings-subtitle.joined-and-invited" = "Your invite is ready!"; - -/* Subtitle text for the Network Protection settings row */ -"network-protection.waitlist.settings-subtitle.joined-but-not-invited" = "You’re on the list!"; - -/* Subtitle text for the Network Protection settings row */ -"network-protection.waitlist.settings-subtitle.waitlist-not-joined" = "Join the private waitlist"; - -/* Message for the network protection invite dialog */ -"network.protection.invite.dialog.message" = "Enter your invite code to get started."; - -/* Title for the network protection invite screen */ -"network.protection.invite.dialog.title" = "You’re invited to try Network Protection"; - -/* Prompt for the network protection invite code text field */ -"network.protection.invite.field.prompt" = "Invite Code"; - -/* Message for the network protection invite success view */ -"network.protection.invite.success.message" = "Hide your location from websites and conceal your online activity from Internet providers and others on your network."; - -/* Title for the network protection invite success view */ -"network.protection.invite.success.title" = "Success! You’re in."; - -/* Title text for an iOS quick action that opens VPN settings */ -"network.protection.quick-action.open-vpn" = "Open VPN"; - -/* The label for when NetP VPN is connected plus the length of time connected as a formatter HH:MM:SS string */ -"network.protection.status.connected.format" = "Connected - %@"; - -/* The label for the NetP VPN when connecting */ -"network.protection.status.connecting" = "Connecting..."; - -/* The label for the NetP VPN when disconnected */ -"network.protection.status.disconnected" = "Not connected"; - -/* The label for the NetP VPN when disconnecting */ -"network.protection.status.disconnecting" = "Disconnecting..."; - -/* Message label text for the netP status view */ -"network.protection.status.header.message" = "DuckDuckGo's VPN secures all of your device's Internet traffic anytime, anywhere."; - -/* Header title label text for the status view when netP is disconnected */ -"network.protection.status.header.title.off" = "Network Protection is Off"; - -/* Header title label text for the status view when netP is connected */ -"network.protection.status.header.title.on" = "Network Protection is On"; - -/* The status view 'Share Feedback' button which is shown inline on the status view after the temporary free use footer text */ -"network.protection.status.menu.share.feedback" = "Share Feedback"; - -/* Connection details label shown in NetworkProtection's status view. */ -"network.protection.status.view.connection.details" = "Connection Details"; - -/* Generic connection failed error message shown in NetworkProtection's status view. */ -"network.protection.status.view.error.connection.failed.message" = "Please try again later."; - -/* Generic connection failed error title shown in NetworkProtection's status view. */ -"network.protection.status.view.error.connection.failed.title" = "Failed to Connect."; - -/* IP Address label shown in NetworkProtection's status view. */ -"network.protection.status.view.ip.address" = "IP Address"; - -/* Location label shown in NetworkProtection's status view. */ -"network.protection.status.view.location" = "Location"; - -/* Label shown on the title of the settings section in NetworkProtection's status view. */ -"network.protection.status.view.settings.section.title" = "Manage"; - -/* Title label text for the status view when netP is disconnected */ -"network.protection.status.view.title" = "Network Protection"; - -/* Title for the button to link to the iOS app settings and enable notifications app-wide. */ -"network.protection.turn.on.notifications.button.title" = "Turn On Notifications"; - -/* Footer text under the button to link to the iOS app settings and enable notifications app-wide. */ -"network.protection.turn.on.notifications.section.footer" = "Allow DuckDuckGo to notify you if your connection drops or VPN status changes."; - -/* List section footer for the toggle for VPN alerts. */ -"network.protection.vpn.alerts.toggle.section.footer" = "Get notified if your connection drops or VPN status changes."; - -/* Title for the toggle for VPN alerts. */ -"network.protection.vpn.alerts.toggle.title" = "VPN Alerts"; - -/* Footer text for the Exclude Local Networks setting item. */ -"network.protection.vpn.exclude.local.networks.setting.footer" = "Let local traffic bypass the VPN and connect to devices on your local network, like a printer."; - -/* Title for the Exclude Local Networks setting item. */ -"network.protection.vpn.exclude.local.networks.setting.title" = "Exclude Local Networks"; - -/* Title for the VPN Location screen's All Countries section. */ -"network.protection.vpn.location.all.countries.section.title" = "All Countries"; - -/* Subtitle of countries item when there are multiple cities, example : */ -"network.protection.vpn.location.country.item.formatted.cities.count" = "%d cities"; - -/* Title for the VPN Location screen's Nearest Available selection item. */ -"network.protection.vpn.location.nearest.available.item.title" = "Nearest Available"; - -/* Footer describing the VPN Location screen's Recommended section which just has Nearest Available. */ -"network.protection.vpn.location.recommended.section.footer" = "Automatically connect to the nearest server we can find."; - -/* Title for the VPN Location screen's Recommended section. */ -"network.protection.vpn.location.recommended.section.title" = "Recommended"; - -/* Subtitle for the preferred location item that formats a city and country. E.g Chicago, United States */ -"network.protection.vpn.location.subtitle.formatted.city.and.country" = "%1$@, %2$@"; - -/* Title for the VPN Location screen. */ -"network.protection.vpn.location.title" = "VPN Location"; - -/* Title for the VPN Notifications management screen. */ -"network.protection.vpn.notifications.title" = "VPN Notifications"; - -/* Label for the Preferred Location VPN Settings item when the nearest available location is selected. */ -"network.protection.vpn.preferred.location.nearest" = "Nearest Available"; - -/* Title for the Preferred Location VPN Settings item. */ -"network.protection.vpn.preferred.location.title" = "Preferred Location"; - -/* Footer text for the Always on VPN setting item. */ -"network.protection.vpn.secure.dns.setting.footer" = "Our VPN uses Secure DNS to keep your online activity private, so that your Internet provider can't see what websites you visit."; - -/* Title for the VPN Settings screen. */ -"network.protection.vpn.settings.title" = "VPN Settings"; - -/* Do not translate - stringsdict entry */ -"number.of.tabs" = "number.of.tabs"; - -/* Text displayed on notification appearing in the address bar when the browser dismissed the cookie popup automatically rejecting it */ -"omnibar.notification.cookies-managed" = "Cookies Managed"; - -/* Text displayed on notification appearing in the address bar when the browser hides a cookie popup */ -"omnibar.notification.popup-hidden" = "Pop-up Hidden"; - -/* No comment provided by engineer. */ -"onboarding.widgets.continueButton" = "Add Widget"; - -/* No comment provided by engineer. */ -"onboarding.widgets.header" = "Using DuckDuckGo just got easier."; - -/* No comment provided by engineer. */ -"onboarding.widgets.skipButton" = "Maybe Later"; - -/* No comment provided by engineer. */ -"onboardingContinue" = "Continue"; - -/* No comment provided by engineer. */ -"onboardingDefaultBrowserMaybeLater" = "Maybe Later"; - -/* No comment provided by engineer. */ -"onboardingDefaultBrowserTitle" = "Make DuckDuckGo your default browser."; - -/* No comment provided by engineer. */ -"onboardingSetAsDefaultBrowser" = "Set as Default Browser"; - -/* No comment provided by engineer. */ -"onboardingSkip" = "Skip"; - -/* This is on a button presented on the last of the onboarding screens. */ -"onboardingStartBrowsing" = "Start Browsing"; - -/* No comment provided by engineer. */ -"onboardingWelcomeHeader" = "Welcome to DuckDuckGo!"; - -/* ’Link’ is link on a website */ -"open.externally.failed" = "The app required to open that link can’t be found"; - -/* Activate button */ -"pm.activate" = "Reactivate"; - -/* Cancel button */ -"pm.cancel" = "Cancel"; - -/* Deactivate button */ -"pm.deactivate" = "Deactivate"; - -/* No comment provided by engineer. */ -"preserveLogins.domain.list.footer" = "Websites rely on cookies to keep you signed in. When you Fireproof a site, cookies won’t be erased and you’ll stay signed in, even after using the Fire Button. We still block third-party trackers found on Fireproof websites."; - -/* Section header above Fireproofed websites list */ -"preserveLogins.domain.list.title" = "Fireproof Sites"; - -/* Alert message explaining to users that the benefit of fireproofing a site is that they will be kept signed in */ -"preserveLogins.fireproof.message" = "Fireproofing this site will keep you signed in after using the Fire Button."; - -/* Parameter is a string - domain name. Alert title prompting user to fireproof a site so they can stay signed in */ -"preserveLogins.fireproof.title" = "Fireproof %@ to stay signed in?"; - -/* Confirm fireproofing action */ -"preserveLogins.menu.confirm" = "Fireproof"; - -/* Parameter is a website URL. Messege confirms that given website has been fireproofed. */ -"preserveLogins.menu.confirm.message" = "%@ is now Fireproof"; - -/* Deny fireproofing action */ -"preserveLogins.menu.defer" = "Not Now"; - -/* Disable fireproofing for site */ -"preserveLogins.menu.disable" = "Remove Fireproofing"; - -/* Enable fireproofing for site */ -"preserveLogins.menu.enable" = "Fireproof This Site"; - -/* Messege confirms that website is no longer fireproofed. */ -"preserveLogins.menu.removal.message" = "Fireproofing removed"; - -/* Alert title */ -"preserveLogins.remove.all" = "Remove All"; - -/* Confirmation button in alert */ -"preserveLogins.remove.all.ok" = "OK"; - -/* Privacy Icon accessibility title */ -"privacy.icon.dax" = "DuckDuckGo logo"; - -/* Privacy Icon accessibility hint */ -"privacy.icon.hint" = "Tap to open Privacy Dashboard screen"; - -/* Privacy Icon accessibility title */ -"privacy.icon.shield" = "Privacy Icon"; - -/* Deny action */ -"prompt.custom.url.scheme.dontopen" = "Cancel"; - -/* Confirm action */ -"prompt.custom.url.scheme.open" = "Open"; - -/* No comment provided by engineer. */ -"prompt.custom.url.scheme.prompt" = "Would you like to leave DuckDuckGo to view this content?"; - -/* Alert title */ -"prompt.custom.url.scheme.title" = "Open in Another App?"; - -/* No comment provided by engineer. */ -"search.hint.duckduckgo" = "Search or enter address"; - -/* No comment provided by engineer. */ -"section.title.bookmarks" = "Bookmarks"; - -/* No comment provided by engineer. */ -"section.title.favorites" = "Favorites"; - -/* Settings cell for About DDG */ -"settings.about.ddg" = "About DuckDuckGo"; - -/* Settings section title for About DuckDuckGo */ -"settings.about.section" = "About"; - -/* about page */ -"settings.about.text" = "DuckDuckGo is the independent Internet privacy company founded in 2008 for anyone who’s tired of being tracked online and wants an easy solution. We’re proof you can get real privacy protection online without tradeoffs. - -The DuckDuckGo browser comes with the features you expect from a go-to browser, like bookmarks, tabs, passwords, and more, plus over [a dozen powerful privacy protections](ddgQuickLink://duckduckgo.com/duckduckgo-help-pages/privacy/web-tracking-protections/) not offered in most popular browsers by default. This uniquely comprehensive set of privacy protections helps protect your online activities, from searching to browsing, emailing, and more. - -Our privacy protections work without having to know anything about the technical details or deal with complicated settings. All you have to do is switch your browser to DuckDuckGo across all your devices and you get privacy by default. - -But if you *do* want a peek under the hood, you can find more information about how DuckDuckGo privacy protections work on our [help pages](ddgQuickLink://duckduckgo.com/duckduckgo-help-pages/)."; - -/* Settings screen cell text for adding the app to the dock */ -"settings.add.to.dock" = "Add App to Your Dock"; - -/* Settings screen cell text for add widget to the home screen */ -"settings.add.widget" = "Add Widget to Home Screen"; - -/* Settings screen cell text for addess bar position */ -"settings.address.bar" = "Address Bar Position"; - -/* Settings screen appearance section title */ -"settings.appearance" = "Appearance"; - -/* Settings screen cell for opening links in associated apps */ -"settings.associated.apps" = "Open Links in Associated Apps"; - -/* Description for associated apps description */ -"settings.associated.apps.description" = "Disable to prevent links from automatically opening in other installed apps."; - -/* Settings screen cell for autocomplete */ -"settings.autocomplete" = "Autocomplete Suggestions"; - -/* Settings screen cell text for Application Lock */ -"settings.autolock" = "Application Lock"; - -/* Section footer Autolock description */ -"settings.autolock.description" = "If Touch ID, Face ID or a system passcode is set, you’ll be requested to unlock the app when opening."; - -/* Settings screen cell text for Automatically Clearing Data */ -"settings.clear.data" = "Automatically Clear Data"; - -/* Settings screen cell text for Cookie popups */ -"settings.cookie.popups" = "Manage Cookie Pop-ups"; - -/* Settings title for the customize section */ -"settings.customize" = "Customize"; - -/* Settings screen cell text for setting the app as default browser */ -"settings.default.browser" = "Set as Default Browser"; - -/* Settings cell for Email Protection */ -"settings.emailProtection" = "Email Protection"; - -/* Settings cell for Email Protection */ -"settings.emailProtection.description" = "Block email trackers and hide your address"; - -/* Settings cell for Feedback */ -"settings.feedback" = "Share Feedback"; - -/* Settings screen cell text for fire button animation */ -"settings.firebutton" = "Fire Button Animation"; - -/* Settings screen cell text for Fireproof Sites */ -"settings.fireproof.sites" = "Fireproof Sites"; - -/* Settings screen cell text for GPC */ -"settings.gpc" = "Global Privacy Control (GPC)"; - -/* Settings screen cell text for app icon selection */ -"settings.icon" = "App Icon"; - -/* Settings screen cell for Keyboard */ -"settings.keyboard" = "Keyboard"; - -/* Settings screen cell text for passwords */ -"settings.logins" = "Passwords"; - -/* Settings title for the 'More' section */ -"settings.more" = "More from DuckDuckGo"; - -/* Product name for the subscription bundle */ -"settings.ppro" = "Privacy Pro"; - -/* Settings screen cell for long press previews */ -"settings.previews" = "Long-Press Previews"; - -/* Settings title for the privacy section */ -"settings.privacy" = "Privacy"; - -/* Data Broker protection cell subtitle for privacy pro */ -"settings.subscription.DBP.subtitle" = "Remove your info from sites that sell it"; - -/* Data Broker protection cell title for privacy pro */ -"settings.subscription.DBP.title" = "Personal Information Removal"; - -/* Privacy pro description subtext */ -"settings.subscription.description" = "More seamless privacy with three new protections, including:"; - -/* Privacy pro features list */ -"settings.subscription.features" = " • VPN (Virtual Private Network) - • Personal Information Removal - • Identity Theft Restoration"; - -/* Identity theft restoration cell subtitle for privacy pro */ -"settings.subscription.ITR.subtitle" = "If your identity is stolen, we'll help restore it"; - -/* Identity theft restoration cell title for privacy pro */ -"settings.subscription.ITR.title" = "Identity Theft Restoration"; - -/* Learn more button text for privacy pro */ -"settings.subscription.learn.more" = "Learn More"; - -/* Subscription Settings button text for privacy pro */ -"settings.subscription.manage" = "Subscription Settings"; - -/* Call to action title for Privacy Pro */ -"settings.subscription.subscribe" = "Subscribe to Privacy Pro"; - -/* VPN cell title for privacy pro */ -"settings.subscription.VPN.title" = "VPN"; - -/* Settings screen cell text for sync and backup */ -"settings.sync" = "Sync & Backup"; - -/* Settings screen cell text for text size */ -"settings.text.size" = "Text Size"; - -/* Settings screen cell text for theme */ -"settings.theme" = "Theme"; - -/* Title for the Settings View */ -"settings.title" = "Settings"; - -/* Settings screen cell text for Unprotected Sites */ -"settings.unprotected.sites" = "Unprotected Sites"; - -/* Settings cell for Version */ -"settings.version" = "Version"; - -/* Settings screen cell for voice search */ -"settings.voice.search" = "Private Voice Search"; - -/* Report a Broken Site screen confirmation button */ -"siteFeedback.buttonText" = "Submit Report"; - -/* Domain is an URL address */ -"siteFeedback.domainInfo" = "Domain of Broken Site:"; - -/* No comment provided by engineer. */ -"siteFeedback.messagePlaceholder" = "Which content or functionality is breaking?"; - -/* No comment provided by engineer. */ -"siteFeedback.subtitle" = "Broken site reporting is completely anonymous and helps us to improve the app!"; - -/* This is a form title */ -"siteFeedback.title" = "Report a Broken Site"; - -/* No comment provided by engineer. */ -"siteFeedback.urlPlaceholder" = "Which website is broken?"; - -/* Subscription Activation Window Title */ -"subscription.activate" = "Activate Subscription"; - -/* Apple ID option for activation */ -"subscription.activate.appleid" = "Apple ID"; - -/* Button text for restoring purchase via Apple ID */ -"subscription.activate.appleid.button" = "Restore Purchase"; - -/* Description for Apple ID activation */ -"subscription.activate.appleid.description" = "Restore your purchase to activate your subscription on this device."; - -/* Subscription Activation Info */ -"subscription.activate.description" = "Access your Privacy Pro subscription on this device via Apple ID or an email address."; - -/* Email option for activation */ -"subscription.activate.email" = "Email"; - -/* Description for Email activation */ -"subscription.activate.email.description" = "Use your email to activate your subscription on this device."; - -/* Restore button title for Managing Email */ -"subscription.activate.manage.email.button" = "Manage"; - -/* Button title for cancelling email deletion */ -"subscription.activate.manage.email.cancel" = "Cancel"; - -/* Button title for confirming email deletion */ -"subscription.activate.manage.email.OK" = "OK"; - -/* View Title for managing your email account */ -"subscription.activate.manage.email.title" = "Manage Email"; - -/* Restore button title for AppleID */ -"subscription.activate.restore.apple" = "Restore"; - -/* Restore button title for Email */ -"subscription.activate.restore.email" = "Enter Email"; - -/* Subscription Activation Title */ -"subscription.activate.title" = "Activate your subscription on this device"; - -/* Add to another device button */ -"subscription.add.device.button" = "Add to Another Device"; - -/* Subscription Add device Info */ -"subscription.add.device.description" = "Access your Privacy Pro subscription on any of your devices via Apple ID or by adding an email address."; - -/* Add subscription to other device title */ -"subscription.add.device.header.title" = "Use your subscription on all your devices"; - -/* Resend activation instructions button */ -"subscription.add.device.resend.instructions" = "Resend Instructions"; - -/* Add to another device view title */ -"subscription.add.device.title" = "Add Device"; - -/* Add email to an existing subscription */ -"subscription.add.email" = "Add an email address to activate your subscription on your other devices. We’ll only use this address to verify your subscription."; - -/* Button title for adding email to subscription */ -"subscription.add.email.button" = "Add Email"; - -/* View title for adding email to subscription */ -"subscription.add.email.title" = "Add Email"; - -/* Subscription availability message on Apple devices */ -"subscription.available.apple" = "Privacy Pro is available on any device signed in to the same Apple ID."; - -/* Change plan or billing title */ -"subscription.change.plan" = "Change Plan Or Billing"; - -/* FAQ Button */ -"subscription.faq" = "Privacy Pro FAQ"; - -/* FAQ Description */ -"subscription.faq.description" = "Visit our Privacy Pro help pages for answers to frequently asked questions"; - -/* Cancel action for the existing subscription dialog */ -"subscription.found.cancel" = "Cancel"; - -/* Restore action for the existing subscription dialog */ -"subscription.found.restore" = "Restore"; - -/* Message for the existing subscription dialog */ -"subscription.found.text" = "We found a subscription associated with this Apple ID."; - -/* Title for the existing subscription dialog */ -"subscription.found.title" = "Subscription Found"; - -/* Help and support Section header */ -"subscription.help" = "Help and support"; - -/* Header for the device management section */ -"subscription.manage.devices" = "Manage Devices"; - -/* Description for Email Management options */ -"subscription.manage.email.description" = "You can use this email to activate your subscription on your other devices."; - -/* Manage Plan header */ -"subscription.manage.plan" = "Manage Plan"; - -/* Alert content for not found subscription */ -"subscription.notFound.alert.message" = "The subscription associated with this Apple ID is no longer active."; - -/* Alert title for not found subscription */ -"subscription.notFound.alert.title" = "Subscription Not Found"; - -/* View plans button text */ -"subscription.notFound.view.plans" = "View Plans"; - -/* Progress view title when completing the purchase */ -"subscription.progress.view.completing.purchase" = "Completing purchase..."; - -/* Progress view title when starting the purchase */ -"subscription.progress.view.purchasing.subscription" = "Purchase in progress..."; - -/* Progress view title when restoring past subscription purchase */ -"subscription.progress.view.restoring.subscription" = "Restoring subscription..."; - -/* Remove from this device button */ -"subscription.remove.from.device.button" = "Remove From This Device"; - -/* Remove from device confirmation dialog text */ -"subscription.remove.from.device.text" = "You will no longer be able to access your Privacy Pro subscription on this device. This will not cancel your subscription, and it will remain active on your other devices."; - -/* Remove from device confirmation dialog title */ -"subscription.remove.from.device.title" = "Remove From This Device?"; - -/* Remove subscription button text */ -"subscription.remove.subscription" = "Remove Subscription"; - -/* Remove subscription cancel button text */ -"subscription.remove.subscription.cancel" = "Cancel"; - -/* Alert button text for restored purchase alert */ -"subscription.restore.success.alert.button" = "OK"; - -/* Alert message for restored purchase */ -"subscription.restore.success.alert.message" = "Your purchases have been restored."; - -/* Alert title for restored purchase */ -"subscription.restore.success.alert.title" = "You’re all set."; - -/* Subscription Expiration Data */ -"subscription.subscription.active.caption" = "Your Privacy Pro subscription renews on %@"; - -/* Message confirming that recovery code was copied to clipboard */ -"sync.code.copied" = "Recovery code copied to clipboard"; - -/* Caption for a button to delete Sync server data */ -"sync.delete.all.confirm.action" = "Delete Server Data"; - -/* Message for the dialog to confirm deleting Sync server data */ -"sync.delete.all.confirm.message" = "All devices will be disconnected and your synced data will be deleted from the server."; - -/* Title of the dialog to confirm deleting Sync server data */ -"sync.delete.all.confirm.title" = "Delete Server Data?"; - -/* Caption for a button to remove device from Sync */ -"sync.remove-device.action" = "Remove"; - -/* No comment provided by engineer. */ -"sync.remove-device.message" = "\"%@\" will no longer be able to access your synced data."; - -/* Title of the dialog to remove device from Sync */ -"sync.remove-device.title" = "Remove Device?"; - -/* Caption for a button to remove current device from Sync */ -"sync.turn.off.confirm.action" = "Remove"; - -/* Message for the dialog to confirm turning off Sync */ -"sync.turn.off.confirm.message" = "This Device will no longer be able to access your synced data."; - -/* Title of the dialog to confirm turning off Sync */ -"sync.turn.off.confirm.title" = "Turn Off Sync?"; - -/* Data syncing unavailable warning message */ -"sync.warning.data.syncing.disabled" = "Sorry, but Sync & Backup is currently unavailable. Please try again later."; - -/* Data syncing unavailable warning message */ -"sync.warning.data.syncing.disabled.upgrade.required" = "Sorry, but Sync & Backup is no longer available in this app version. Please update DuckDuckGo to the latest version to continue."; - -/* Title of the warning message */ -"sync.warning.sync.paused" = "Sync & Backup is Paused"; - -/* Accessibility label on remove button */ -"tab.close.home" = "Close home tab"; - -/* Accesibility label: first string is website title, second is address */ -"tab.close.with.title.and.address" = "Close \"%1$@\" at %2$@"; - -/* Accessibility label on tab cell */ -"tab.open.home" = "Open home tab"; - -/* Accesibility label: first string is website title, second is address */ -"tab.open.with.title.and.address" = "Open \"%1$@\" at %2$@"; - -/* Tab Switcher Accessibility Label */ -"tab.switcher.accessibility.label" = "Tab Switcher"; - -/* Description text for the text size adjustment setting */ -"textSize.description" = "Choose your preferred text size. Websites you view in DuckDuckGo will adjust to it."; - -/* Replacement string is a current percent value e.g. '120%' */ -"textSize.footer" = "Text Size - %@"; - -/* Dark Theme entry */ -"theme.acc.dark" = "Dark"; - -/* Short entry for Default System theme */ -"theme.acc.default" = "System"; - -/* Light Theme entry */ -"theme.acc.light" = "Light"; - -/* Dark Theme entry */ -"theme.name.dark" = "Dark"; - -/* Entry for Default System theme */ -"theme.name.default" = "System Default"; - -/* Light Theme entry */ -"theme.name.light" = "Light"; - -/* Confirmation of an action - populated with a domain name */ -"toast.protection.disabled" = "Privacy Protection disabled for %@"; - -/* Confirmation of an action - populated with a domain name */ -"toast.protection.enabled" = "Privacy Protection enabled for %@"; - -/* Autocomplete selected suggestion into the Address Bar button accessibility label */ -"voiceover.action.suggestion.autocomplete" = "Autocomplete suggestion"; - -/* Voice-over title for a Bookmark suggestion. Noun */ -"voiceover.suggestion.type.bookmark" = "Bookmark"; - -/* Search for suggestion action accessibility title */ -"voiceover.suggestion.type.search" = "Search at DuckDuckGo"; - -/* Open suggested website action accessibility title */ -"voiceover.suggestion.type.website" = "Open website"; - -/* No microphone permission alert action button to open the settings app */ -"voiceSearch.alert.no-permission.action.settings" = "Settings"; - -/* Message for alert warning the user about missing microphone permission */ -"voiceSearch.alert.no-permission.message" = "Please allow Microphone access in iOS System Settings for DuckDuckGo to use voice features."; - -/* OK button alert warning the user about missing microphone permission */ -"voiceSearch.alert.no-permission.ok" = "OK"; - -/* Title for alert warning the user about missing microphone permission */ -"voiceSearch.alert.no-permission.title" = "Microphone Access Required"; - -/* Cancel button for voice search */ -"voiceSearch.cancel" = "Cancel"; - -/* Voice-search footer note with on-device privacy warning */ -"voiceSearch.footer.note" = "Audio is processed on-device. It's not stored or shared with anyone, including DuckDuckGo."; - -/* Title for the Cancel button of the VPN feedback form */ -"vpn.feedback-form.button.cancel" = "Cancel"; - -/* Title for the Done button of the VPN feedback form */ -"vpn.feedback-form.button.done" = "Done"; - -/* Title for the Submit button of the VPN feedback form */ -"vpn.feedback-form.button.submit" = "Submit"; - -/* Title for the Submitting state of the VPN feedback form */ -"vpn.feedback-form.button.submitting" = "Submitting…"; - -/* Title for the browser crash/freeze category of the VPN feedback form */ -"vpn.feedback-form.category.browser-crash-or-freeze" = "VPN causes browser to crash or freeze"; - -/* Title for the 'VPN fails to connect' category of the VPN feedback form */ -"vpn.feedback-form.category.fails-to-connect" = "VPN fails to connect"; - -/* Title for the 'VPN feature request' category of the VPN feedback form */ -"vpn.feedback-form.category.feature-request" = "VPN feature request"; - -/* Title for the category 'VPN causes issues with other apps or websites' category of the VPN feedback form */ -"vpn.feedback-form.category.issues-with-apps" = "VPN causes issues with other apps or websites"; - -/* Title for the local device connectivity category of the VPN feedback form */ -"vpn.feedback-form.category.local-device-connectivity" = "VPN won't let me connect to local device"; - -/* Title for the 'other VPN feedback' category of the VPN feedback form */ -"vpn.feedback-form.category.other" = "Other VPN feedback"; - -/* Title for the category selection state of the VPN feedback form */ -"vpn.feedback-form.category.select-category" = "Select a category"; - -/* Title for the 'VPN is too slow' category of the VPN feedback form */ -"vpn.feedback-form.category.too-slow" = "VPN connection is too slow"; - -/* Title for the 'unable to install' category of the VPN feedback form */ -"vpn.feedback-form.category.unable-to-install" = "Unable to install VPN"; - -/* Action title for the alert when the VPN feedback form can't be submitted */ -"vpn.feedback-form.error.action" = "OK"; - -/* Message for the alert when the VPN feedback form can't be submitted */ -"vpn.feedback-form.error.message" = "Failed to share your feedback. Please try again."; - -/* Title for the alert when the VPN feedback form can't be submitted */ -"vpn.feedback-form.error.title" = "Error"; - -/* Title for the feedback sent view description of the VPN feedback form */ -"vpn.feedback-form.sending-confirmation.description" = "Your feedback will help us improve the\nDuckDuckGo VPN."; - -/* Title for the feedback sending error text of the VPN feedback form */ -"vpn.feedback-form.sending-confirmation.error" = "We couldn't send your feedback right now, please try again."; - -/* Title for the feedback sent view title of the VPN feedback form */ -"vpn.feedback-form.sending-confirmation.title" = "Thank you!"; - -/* Toast message when the VPN feedback form is submitted successfully */ -"vpn.feedback-form.submitted.message" = "Thank You! Feedback submitted."; - -/* Text for the body of the VPN feedback form */ -"vpn.feedback-form.text-1" = "Please describe what's happening, what you expected to happen, and the steps that led to the issue:"; - -/* Text for the body of the VPN feedback form */ -"vpn.feedback-form.text-2" = "In addition to the details entered into this form, your app issue report will contain:"; - -/* Bullet text for the body of the VPN feedback form */ -"vpn.feedback-form.text-3" = "• Whether specific DuckDuckGo features are enabled"; - -/* Bullet text for the body of the VPN feedback form */ -"vpn.feedback-form.text-4" = "• Aggregate DuckDuckGo app diagnostics"; - -/* Text for the body of the VPN feedback form */ -"vpn.feedback-form.text-5" = "By tapping \"Submit\" I agree that DuckDuckGo may use the information in this report for purposes of improving the app's features."; - -/* Title for each screen of the VPN feedback form */ -"vpn.feedback-form.title" = "Help Improve the DuckDuckGo VPN"; - -/* Title for the button to enable push notifications in system settings */ -"waitlist.allow-notifications" = "Allow Notifications"; - -/* Body text for the waitlist notification */ -"waitlist.available.notification.body" = "Open your invite"; - -/* Title for the copy action */ -"waitlist.copy" = "Copy"; - -/* Label text for the invite code */ -"waitlist.invite-code" = "Invite Code"; - -/* Step title on the invite screen */ -"waitlist.invite-screen.step.title" = "Step %d"; - -/* Title for the invite code screen */ -"waitlist.invite-screen.youre-invited" = "You’re Invited!"; - -/* Title for the Join Waitlist screen */ -"waitlist.join-waitlist-screen.join" = "Join the Private Waitlist"; - -/* Temporary status text for the Join Waitlist screen */ -"waitlist.join-waitlist-screen.joining" = "Joining Waitlist..."; - -/* Title for the Share Link button */ -"waitlist.join-waitlist-screen.share-link" = "Share Link"; - -/* Notification text for the waitlist */ -"waitlist.joined.no-notification.get-notification" = "Notify Me"; - -/* Title for the alert to confirm enabling notifications */ -"waitlist.joined.no-notification.get-notification-confirmation-title" = "Get a notification when it’s your turn?"; - -/* Cancel button in the alert to confirm enabling notifications */ -"waitlist.joined.no-notification.no-thanks" = "No Thanks"; - -/* Text used for the Notifications Disabled state */ -"waitlist.notification.disabled" = "We can notify you when it’s your turn, but notifications are currently disabled for DuckDuckGo."; - -/* Privacy disclaimer for the Waitlist feature */ -"waitlist.privacy-disclaimer" = "You won’t need to share any personal information to join the waitlist. You’ll secure your place in line with a timestamp that exists solely on your device so we can notify you when it’s your turn."; - -/* Title for the queue screen */ -"waitlist.queue-screen.on-the-list" = "You’re on the list!"; - -/* Title for the settings subtitle */ -"waitlist.settings.download-available" = "Download available"; - -/* Title for the share sheet entry */ -"waitlist.share-sheet.title" = "You’re Invited!"; - -/* Confirmation message */ -"web.url.remove.favorite.done" = "Favorite removed"; - -/* Confirmation message */ -"web.url.save.bookmark.done" = "Bookmark added"; - -/* Floating Info message */ -"web.url.save.bookmark.exists" = "Bookmark already saved"; - -/* Floating message indicating failure */ -"web.url.save.bookmark.none" = "No webpage to bookmark"; - -/* Confirmation message */ -"web.url.save.favorite.done" = "Favorite added"; - -/* Cancel button for JavaScript alerts */ -"webJSAlert.cancel.button" = "Cancel"; - -/* OK button for JavaScript alerts */ -"webJSAlert.OK.button" = "OK"; - -/* Alert title explaining the message is shown by a website */ -"webJSAlert.website-message.format" = "A message from %@:"; - -/* Title for the Windows waitlist notification */ -"windows-waitlist.available.notification.title" = "Try DuckDuckGo for Windows!"; - -/* Description on the invite screen */ -"windows-waitlist.invite-screen.step-1.description" = "Visit this URL on your Windows device to download:"; - -/* Description on the invite screen */ -"windows-waitlist.invite-screen.step-2.description" = "Open DuckDuckGo Installer in Downloads, select Install, then enter your invite code."; - -/* Subtitle for the Windows Waitlist Invite screen */ -"windows-waitlist.invite-screen.subtitle" = "Ready to use DuckDuckGo on Windows?"; - -/* Title for the Windows waitlist button redirecting to Mac waitlist */ -"windows-waitlist.join-waitlist-screen.mac-waitlist" = "Looking for the Mac version?"; - -/* Title for the Join Windows Waitlist screen */ -"windows-waitlist.join-waitlist-screen.try-duckduckgo-for-windows" = "Get early access to try DuckDuckGo for Windows!"; - -/* Message for the alert to confirm enabling notifications */ -"windows-waitlist.joined.no-notification.get-notification-confirmation-message" = "We’ll send you a notification when your copy of DuckDuckGo for Windows is ready for download. "; - -/* Label text for the Joined Waitlist state with notifications declined */ -"windows-waitlist.joined.notifications-declined" = "Your invite to try DuckDuckGo for Windows will arrive here. Check back soon, or we can send you a notification when it’s your turn."; - -/* Label text for the Joined Waitlist state with notifications enabled */ -"windows-waitlist.joined.notifications-enabled" = "We’ll send you a notification when your copy of DuckDuckGo for Windows is ready for download."; - -/* Title for the settings subtitle */ -"windows-waitlist.settings.browse-privately" = "Browse privately with our app for Windows"; - -/* Message used when sharing to iMessage. Parameter is an eight digit invite code. */ -"windows-waitlist.share-sheet.invite-code-message" = "You’re invited! - -Ready to use DuckDuckGo on Windows? - -Step 1 -Visit this URL on your Windows device to download: -https://duckduckgo.com/windows - -Step 2 -Open DuckDuckGo Installer in Downloads, select Install, then enter your invite code. - -Invite code: %@"; - -/* Message used when sharing to iMessage */ -"windows-waitlist.share-sheet.message" = "Ready to start browsing privately on Windows? - -Visit this URL on your Computer to download: -https://duckduckgo.com/windows"; - -/* Summary text for the Windows browser waitlist */ -"windows-waitlist.summary" = "DuckDuckGo for Windows has what you need to browse with more privacy — private search, tracker blocking, forced encryption, and cookie pop-up blocking, plus more best-in-class protections on the way."; - -/* Title for the Windows Waitlist feature */ -"windows-waitlist.title" = "DuckDuckGo App for Windows"; - -/* Title for the Windows browser download link page */ -"windows-waitlist.waitlist-download-screen.try-duckduckgo-for-windows" = "Get DuckDuckGo for Windows!"; - diff --git a/LocalPackages/DuckUI/Package.swift b/LocalPackages/DuckUI/Package.swift index 74c51b6864..cf31671f45 100644 --- a/LocalPackages/DuckUI/Package.swift +++ b/LocalPackages/DuckUI/Package.swift @@ -31,7 +31,7 @@ let package = Package( targets: ["DuckUI"]) ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "101.2.2"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "103.0.0"), ], targets: [ .target( diff --git a/LocalPackages/SyncUI/Package.swift b/LocalPackages/SyncUI/Package.swift index b7c6f13b13..6543b2f149 100644 --- a/LocalPackages/SyncUI/Package.swift +++ b/LocalPackages/SyncUI/Package.swift @@ -33,7 +33,7 @@ let package = Package( ], dependencies: [ .package(path: "../DuckUI"), - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "101.2.2"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "103.0.0"), .package(url: "https://github.com/duckduckgo/DesignResourcesKit", exact: "2.0.0") ], targets: [ diff --git a/LocalPackages/SyncUI/Sources/SyncUI/Resources/en.lproj/Localizable.strings b/LocalPackages/SyncUI/Sources/SyncUI/Resources/en.lproj/Localizable.strings index 68f7f7409b..e69de29bb2 100644 --- a/LocalPackages/SyncUI/Sources/SyncUI/Resources/en.lproj/Localizable.strings +++ b/LocalPackages/SyncUI/Sources/SyncUI/Resources/en.lproj/Localizable.strings @@ -1,258 +0,0 @@ -/* Standard Buttons - Back Button */ -"back.button" = "Back"; - -/* Sync Paused Errors - Bookmarks Limit Exceeded Action */ -"bookmarks.limit.exceeded.action" = "Manage Bookmarks"; - -/* Sync Paused Errors - Bookmarks Limit Exceeded Description */ -"bookmarks.limit.exceeded.description" = "Bookmark limit exceeded. Delete some to resume syncing."; - -/* Camera View - Go to Settings Button */ -"camera.go.to.settings.button" = "Go to Settings"; - -/* Camera View - Unavailable Title */ -"camera.is.unavailable.title" = "Camera is Unavailable"; - -/* Camera View - Permission Instructions */ -"camera.permission.instructions" = "Please go to your device's settings and grant permission for this app to access your camera."; - -/* Camera View - Permission Required */ -"camera.permission.required" = "Camera Permission is Required"; - -/* Camera View - Point Camera Indication */ -"camera.point.camera.indication" = "Point camera at QR code to sync"; - -/* Standard Buttons - Cancel Button */ -"cancel.button" = "Cancel"; - -/* Connect With Server Sheet - Button */ -"connect.with.server.sheet.button" = "Turn On Sync & Back Up"; - -/* Connect With Server Sheet - Description Part 1 */ -"connect.with.server.sheet.description.part1" = "This creates an encrypted backup of your bookmarks and passwords on DuckDuckGo’s secure server, which can be synced with your other devices."; - -/* Connect With Server Sheet - Description Part 2 */ -"connect.with.server.sheet.description.part2" = "The encryption key is only stored on your device, DuckDuckGo cannot access it."; - -/* Connect With Server Sheet - Footer */ -"connect.with.server.sheet.footer" = "You can sync with your other devices later."; - -/* Connect With Server Sheet - Title */ -"connect.with.server.sheet.title" = "Sync and Back Up This Device"; - -/* Sync Paused Errors - Credentials Limit Exceeded Action */ -"credentials.limit.exceeded.action" = "Manage Logins"; - -/* Sync Paused Errors - Credentials Limit Exceeded Description */ -"credentials.limit.exceeded.description" = "Logins limit exceeded. Delete some to resume syncing."; - -/* Delete Server Data - Button */ -"delete.server.data" = "Turn Off and Delete Server Data..."; - -/* Device SyncedSheet - Title */ -"device.synced.sheet.title" = "Your data is synced!"; - -/* Standard Buttons - Done Button */ -"done.button" = "Done"; - -/* Edit Device View - Header */ -"edit.device.header" = "Device Name"; - -/* Edit Device View - Title */ -"edit.device.title" = "Edit %@"; - -/* Fetch Favicons Onboarding - Button Title */ -"fetch.favicons.onboarding.button.title" = "Keep Bookmarks Icons Updated"; - -/* Fetch Favicons Onboarding - Message */ -"fetch.favicons.onboarding.message" = "Do you want this device to automatically download icons for any new bookmarks synced from your other devices? This will expose the download to your network any time a bookmark is synced."; - -/* Fetch Favicons Onboarding - Title */ -"fetch.favicons.onboarding.title" = "Download Missing Icons?"; - -/* Options - Fetch Favicons Description */ -"fetch.favicons.option.caption" = "Automatically download icons for your synced bookmarks. Icon downloads are exposed to your network."; - -/* Options - Fetch Favicons Title */ -"fetch.favicons.option.title" = "Auto-Download Icons"; - -/* Manually Enter Code View - Instruction with sync menu path and view text code menu item inserted */ -"manually.enter.code.instruction.attributed" = "Go to %1$@ and select %2$@ in the DuckDuckGo App on another synced device and paste the code here to sync this device."; - -/* Manually Enter Code View - Title */ -"manually.enter.code.title" = "Manually Enter Code"; - -/* Manually Enter Code View - Validating Code Action */ -"manually.enter.code.validating.code.action" = "Validating code"; - -/* Manually Enter Code View - Validating Code Failed Action */ -"manually.enter.code.validating.code.failed.action" = "Invalid code."; - -/* Standard Buttons - Next Button */ -"next.button" = "Next"; - -/* Standard Buttons - Not Now Button */ -"not.now.button" = "Not Now"; - -/* Options - Section Header */ -"options.section.header" = "Options"; - -/* Section header for other syncing options */ -"other.options.section.header" = "Other Options"; - -/* Standard Buttons - Paste Button */ -"paste.button" = "Paste"; - -/* Description of rollout banner */ -"preferences.sync.rollout-banner.description" = "Sync & Backup is rolling out gradually and may not be available yet within DuckDuckGo on your other devices."; - -/* Preparing To Sync Sheet - Description */ -"preparing.to.sync.sheet.description" = "Your bookmarks and passwords are being prepared to sync. This should only take a moment."; - -/* Preparing To Sync Sheet - Footer */ -"preparing.to.sync.sheet.footer" = "Connecting…"; - -/* Preparing To Sync Sheet - Title */ -"preparing.to.sync.sheet.title" = "Setting Up Sync and Backup"; - -/* Link label for recovering synced data */ -"recover.synced.data.link" = "Recover Synced Data"; - -/* Recover Synced Data Sheet - Button */ -"recover.synced.data.sheet.button" = "Get Started"; - -/* Recover Synced Data Sheet - Description */ -"recover.synced.data.sheet.description" = "To restore your synced data, you'll need the Recovery Code you saved when you first set up Sync. This code may have been saved as a PDF on the device you originally used to set up Sync."; - -/* Recover Synced Data Sheet - Title */ -"recover.synced.data.sheet.title" = "Recover Synced Data"; - -/* Remove Device View - Button */ -"remove.device.button" = "Remove Device"; - -/* Remove Device View - Message */ -"remove.device.message" = "\"%@\" will no longer be able to access your synced data."; - -/* Remove Device View - Title */ -"remove.device.title" = "Remove Device?"; - -/* Save Recovery Code Sheet - Copy Code Toast */ -"save.recovery.code.code.copied.button" = "Recovery code copied to clipboard"; - -/* Save Recovery Code Sheet - Copy Code Button */ -"save.recovery.code.copy.code.button" = "Copy Code"; - -/* Save Recovery Code Sheet - Save as PDF Button */ -"save.recovery.code.save.as.pdf.button" = "Save as PDF"; - -/* Save Recovery Code Sheet - Description */ -"save.recovery.code.sheet.description" = "If you lose access to your devices, you will need this code to recover your synced data."; - -/* Save Recovery Code Sheet - Footer */ -"save.recovery.code.sheet.footer" = "Anyone with access to this code can access your synced data, so please keep it in a safe place."; - -/* Save Recovery Code Sheet - Title */ -"save.recovery.code.sheet.title" = "Save Recovery Code"; - -/* Save RecoveryPDF - Button */ -"save.recovery.pdf.button" = "Save Recovery PDF"; - -/* Save RecoveryPDF - Footer */ -"save.recovery.pdf.footer" = "If you lose your device, you will need this recovery code to restore your synced data."; - -/* Scan Or Enter Code To Recover Synced Data View - Enter Code Link */ -"scan.code.to.recover.synced.data.enter.code.link" = "Enter Text Code Manually"; - -/* Scan Or Enter Code To Recover Synced Data View - Explanation */ -"scan.code.to.recover.synced.data.explanation" = "Scan the QR code on your Recovery PDF, or another synced device, to recover your data."; - -/* Scan Or Enter Code To Recover Synced Data View - Footer */ -"scan.code.to.recover.synced.data.footer" = "Can’t Scan?"; - -/* Scan Or Enter Code To Recover Synced Data View - Title */ -"scan.code.to.recover.synced.data.title" = "Recover Synced Data"; - -/* Scan or See Code View - Footer */ -"scan.or.see.code.footer" = "Can’t Scan?"; - -/* Scan or See Code View - Instruction */ -"scan.or.see.code.instruction" = "Go to Settings › Sync & Backup in the DuckDuckGo Browser on another device and select ”Sync With Another Device.”"; - -/* Scan or See Code View - Instruction with syncMenuPath */ -"scan.or.see.code.instruction.attributed" = "Go to %@ in the DuckDuckGo Browser on another device and select ”Sync With Another Device.”."; - -/* Scan or See Code View - Manually Enter Code Link */ -"scan.or.see.code.manually.enter.code.link" = "Manually Enter Code"; - -/* Scan or See Code View - Scan Code Instructions Body */ -"scan.or.see.code.scan.code.instructions.body" = "Scan this code with another device to sync."; - -/* Scan or See Code View - Scan Code Instructions Title */ -"scan.or.see.code.scan.code.instructions.title" = "Mobile-to-Mobile?"; - -/* Scan or See Code View - Share Code Link */ -"scan.or.see.code.share.code.link" = "Share Text Code"; - -/* Scan or See Code View - Title */ -"scan.or.see.code.title" = "Scan QR Code"; - -/* Link label for syncing and backing up the device */ -"sync.and.backup.this.device.link" = "Sync and Back Up This Device"; - -/* Sync Paused Errors - Title */ -"sync.limit.exceeded.title" = "Sync Paused"; - -/* Sync Menu Path */ -"sync.menu.path" = "Settings > Sync & Backup > Sync With Another Device"; - -/* Sync & Backup Title */ -"sync.title" = "Sync & Backup"; - -/* Data syncing unavailable warning message */ -"sync.warning.data.syncing.disabled" = "Sorry, but Sync & Backup is currently unavailable. Please try again later."; - -/* Data syncing unavailable warning message */ -"sync.warning.data.syncing.disabled.upgrade.required" = "Sorry, but Sync & Backup is no longer available in this app version. Please update DuckDuckGo to the latest version to continue."; - -/* Title of the warning message */ -"sync.warning.sync.paused" = "Sync & Backup is Paused"; - -/* Title of the warning message */ -"sync.warning.sync.unavailable" = "Sync & Backup is Unavailable"; - -/* Button label for syncing with another device */ -"sync.with.another.device.button" = "Sync With Another Device"; - -/* Footer message for syncing with another device */ -"sync.with.another.device.footer" = "Your data is end-to-end encrypted, and DuckDuckGo does not have access to the encryption key."; - -/* Message for syncing with another device */ -"sync.with.another.device.message" = "Securely sync bookmarks and passwords between your devices."; - -/* Title for syncing with another device */ -"sync.with.another.device.title" = "Begin Syncing"; - -/* Synced Devices - Section Header */ -"synced.devices.section.header" = "Synced Devices"; - -/* Synced Devices - Sync with Another Device Label */ -"synced.devices.sync.with.another.device.label" = "Sync With Another Device"; - -/* Synced Devices - This Device Label */ -"synced.devices.this.device.label" = "This Device"; - -/* Turn Sync Off - Button */ -"turn.sync.off" = "Turn Off Sync & Backup..."; - -/* Turn Sync Off - Section Header */ -"turn.sync.off.section.header" = "Sync Enabled"; - -/* Options - Unify Favorites Instruction */ -"unified.favorites.instruction" = "Use the same favorite bookmarks on all your devices. Leave off to keep mobile and desktop favorites separate."; - -/* Options - Unify Favorites Title */ -"unified.favorites.title" = "Unify Favorites Across Devices"; - -/* View Text Code menu item */ -"view.text.code.menu.item" = "View Text Code"; - diff --git a/LocalPackages/Waitlist/Package.swift b/LocalPackages/Waitlist/Package.swift index 3988db42e0..598bd55103 100644 --- a/LocalPackages/Waitlist/Package.swift +++ b/LocalPackages/Waitlist/Package.swift @@ -15,7 +15,7 @@ let package = Package( targets: ["Waitlist", "WaitlistMocks"]) ], dependencies: [ - .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "101.2.2"), + .package(url: "https://github.com/duckduckgo/BrowserServicesKit", exact: "103.0.0"), .package(url: "https://github.com/duckduckgo/DesignResourcesKit", exact: "2.0.0") ], targets: [ diff --git a/PacketTunnelProvider/en.lproj/Localizable.strings b/PacketTunnelProvider/en.lproj/Localizable.strings index 1a6d5fe4de..e69de29bb2 100644 --- a/PacketTunnelProvider/en.lproj/Localizable.strings +++ b/PacketTunnelProvider/en.lproj/Localizable.strings @@ -1,15 +0,0 @@ -/* The body of the notification shown when Network Protection fails to reconnect */ -"network.protection.failure.notification.body" = "Network Protection failed to connect. Please try again later."; - -/* The body of the notification shown when Network Protection's connection is interrupted */ -"network.protection.interrupted.notification.body" = "Network Protection was interrupted. Attempting to reconnect now..."; - -/* The title of the notifications shown from Network Protection */ -"network.protection.notification.title" = "DuckDuckGo"; - -/* The body of the notification shown when Network Protection reconnects successfully */ -"network.protection.success.notification.body" = "Network Protection is On. Your location and online activity are protected."; - -/* The body of the notification shown when Network Protection connects successfully with the city + state/country as formatted parameter */ -"network.protection.success.notification.subtitle.including.serverLocation" = "Routing device traffic through %@."; - diff --git a/Widgets/en.lproj/Localizable.strings b/Widgets/en.lproj/Localizable.strings index 31e12dbf16..e69de29bb2 100644 --- a/Widgets/en.lproj/Localizable.strings +++ b/Widgets/en.lproj/Localizable.strings @@ -1,51 +0,0 @@ -/* Description shown to the user when adding the Email Protection lock screen widget */ -"lock.screen.widget.email.description" = "Instantly generate a new private Duck Address."; - -/* Title shown to the user when adding the Email Protection lock screen widget */ -"lock.screen.widget.email.title" = "Email Protection"; - -/* Description shown to the user when adding the Search lock screen widget */ -"lock.screen.widget.favorites.description" = "Quickly open your favorite websites with a tap."; - -/* Title shown to the user when adding the favorites lock screen widget */ -"lock.screen.widget.favorites.title" = "Favorites"; - -/* Description shown to the user when adding the Fire Button lock screen widget */ -"lock.screen.widget.fire.description" = "Instantly delete your browsing history and start a new private search in DuckDuckGo."; - -/* Title shown to the user when adding the Fire Button lock screen widget */ -"lock.screen.widget.fire.title" = "Fire Button"; - -/* Description shown to the user when adding the Search lock screen widget */ -"lock.screen.widget.search.description" = "Instantly start a private search in DuckDuckGo."; - -/* Title shown to the user when adding the Search lock screen widget */ -"lock.screen.widget.search.title" = "Private Search"; - -/* Description shown to the user when adding the Voice Search lock screen widget */ -"lock.screen.widget.voice.description" = "Instantly start a new private voice search in DuckDuckGo."; - -/* Title shown to the user when adding the Voice Search lock screen widget */ -"lock.screen.widget.voice.title" = "Voice Search"; - -/* Description of search and favorites widget in widget gallery */ -"widget.gallery.search.and.favorites.description" = "Search or visit your favorite sites privately with just one tap."; - -/* Display name for search and favorites widget in widget gallery */ -"widget.gallery.search.and.favorites.display.name" = "Search and Favorites"; - -/* Description of search only widget in widget gallery */ -"widget.gallery.search.description" = "Quickly launch a private search in DuckDuckGo."; - -/* Display name for search only widget in widget gallery */ -"widget.gallery.search.display.name" = "Search"; - -/* CTA shown in the favorites widget empty state. */ -"widget.no.favorites.cta" = "Add Favorites"; - -/* Message shown in the favorites widget empty state. */ -"widget.no.favorites.message" = "Quickly visit your favorite sites."; - -/* Placeholder text in search field on the search and favorites widget */ -"widget.search.duckduckgo" = "Search DuckDuckGo"; -