diff --git a/.github/workflows/create_variant.yml b/.github/workflows/create_variant.yml index 502080b8e1..c51a9c0697 100644 --- a/.github/workflows/create_variant.yml +++ b/.github/workflows/create_variant.yml @@ -86,14 +86,28 @@ jobs: .github scripts + - name: Download DMG artifact + id: download-dmg-artifact + continue-on-error: true + uses: actions/download-artifact@v4 + with: + name: duckduckgo-dmg + path: ${{ github.workspace }} + - name: Download release app + # Download the release app only if download-dmg-artifact fails + if: ${{ steps.download-dmg-artifact.outcome == 'failure' }} run: | curl -fLSs "${{ vars.RELEASE_DMG_URL }}" --output duckduckgo.dmg - hdiutil attach duckduckgo.dmg -mountpoint vanilla - mkdir -p dmg - cp -R vanilla/DuckDuckGo.app dmg/DuckDuckGo.app - hdiutil detach vanilla - rm -f duckduckgo.dmg + + - name: Extract App from DMG + id: extract-app-from-dmg + run: | + hdiutil attach duckduckgo.dmg -mountpoint vanilla + mkdir -p dmg + cp -R vanilla/DuckDuckGo.app dmg/DuckDuckGo.app + hdiutil detach vanilla + rm -f duckduckgo.dmg - name: Install create-dmg run: brew install create-dmg @@ -120,7 +134,7 @@ jobs: run: | codesign -d --entitlements :- DuckDuckGo.app > entitlements.plist echo "${{ env.ATB_VARIANT_NAME }}" > "DuckDuckGo.app/Contents/Resources/variant.txt" - echo "${{ env.ORIGIN_VARIANT_NAME }}" > "DuckDuckGo.app/Contents/Resources/origin.txt" + echo "${{ env.ORIGIN_VARIANT_NAME }}" > "DuckDuckGo.app/Contents/Resources/Origin.txt" sign_identity="$(security find-certificate -a -c "Developer ID Application" -Z | grep ^SHA-1 | cut -d " " -f3 | uniq)" /usr/bin/codesign \ diff --git a/.github/workflows/create_variants.yml b/.github/workflows/create_variants.yml index ccddcecbb2..c48424a947 100644 --- a/.github/workflows/create_variants.yml +++ b/.github/workflows/create_variants.yml @@ -72,11 +72,29 @@ jobs: atb-asana-task-id: ${{ vars.DMG_VARIANTS_LIST_TASK_ID }} origin-asana-section-id: ${{ vars.DMG_VARIANTS_ORIGIN_SECTION_ID }} - + download-dmg-and-upload-artifact: + + name: Download Release App and upload artifact + + runs-on: macos-13 + timeout-minutes: 15 + + steps: + - name: Download release app + run: | + curl -fLSs "${{ vars.RELEASE_DMG_URL }}" --output duckduckgo.dmg + + - name: Upload DMG artifact + uses: actions/upload-artifact@v4 + with: + name: duckduckgo-dmg + path: ${{ github.workspace }}/duckduckgo.dmg + retention-days: 1 + create-variants: name: Create Variant - needs: set-up-variants + needs: [set-up-variants, download-dmg-and-upload-artifact] strategy: fail-fast: false diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index c6e30341ad..528b219281 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -256,10 +256,6 @@ jobs: # workflow_call is used by bump_internal_release and is followed by a proper release job if: github.actor != 'dependabot[bot]' && (github.event_name == 'push' || github.event_name == 'pull_request') - strategy: - matrix: - scheme: [ "DuckDuckGo Privacy Browser", "DuckDuckGo Privacy Pro" ] - runs-on: macos-13-xlarge timeout-minutes: 30 @@ -311,7 +307,7 @@ jobs: run: | export OS_ACTIVITY_MODE=debug set -o pipefail && xcodebuild \ - -scheme "${{ matrix.scheme }}" \ + -scheme "DuckDuckGo Privacy Browser" \ -derivedDataPath "DerivedData" \ -configuration "Release" \ -skipPackagePluginValidation -skipMacroValidation \ diff --git a/.github/workflows/stale_pr.yml b/.github/workflows/stale_pr.yml index a5590c9c63..a4a6e92c29 100644 --- a/.github/workflows/stale_pr.yml +++ b/.github/workflows/stale_pr.yml @@ -12,8 +12,8 @@ jobs: uses: actions/stale@v9 with: stale-pr-message: 'This PR has been inactive for more than 7 days and will be automatically closed 7 days from now.' - days-before-stale: 7 + days-before-pr-stale: 7 close-pr-message: 'This PR has been closed after 14 days of inactivity. Feel free to reopen it if you plan to continue working on it or have further discussions.' - days-before-close: 7 + days-before-pr-close: 7 stale-pr-label: stale exempt-draft-pr: true \ No newline at end of file diff --git a/Configuration/App/DuckDuckGo.xcconfig b/Configuration/App/DuckDuckGo.xcconfig index 778bc1e09d..36ec797d04 100644 --- a/Configuration/App/DuckDuckGo.xcconfig +++ b/Configuration/App/DuckDuckGo.xcconfig @@ -26,7 +26,7 @@ CODE_SIGN_IDENTITY[sdk=macosx*] = Developer ID Application CODE_SIGN_IDENTITY[config=Debug][sdk=macosx*] = Apple Development CODE_SIGN_IDENTITY[config=CI][sdk=macosx*] = -FEATURE_FLAGS = FEEDBACK SPARKLE DBP SUBSCRIPTION STRIPE +FEATURE_FLAGS = FEEDBACK SPARKLE DBP STRIPE PRODUCT_NAME_PREFIX = DuckDuckGo diff --git a/Configuration/App/NetworkProtection/DuckDuckGoVPN.xcconfig b/Configuration/App/NetworkProtection/DuckDuckGoVPN.xcconfig index 1840da7701..6280424f9c 100644 --- a/Configuration/App/NetworkProtection/DuckDuckGoVPN.xcconfig +++ b/Configuration/App/NetworkProtection/DuckDuckGoVPN.xcconfig @@ -49,10 +49,10 @@ PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*] = PROVISIONING_PROFILE_SPECIFIER[config=Review][sdk=macosx*] = macOS NetP VPN App - Review (XPC) PROVISIONING_PROFILE_SPECIFIER[config=Release][sdk=macosx*] = macOS NetP VPN App - Release (XPC) -FEATURE_FLAGS[arch=*][sdk=*] = NETP_SYSTEM_EXTENSION SUBSCRIPTION -FEATURE_FLAGS[config=CI][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION SUBSCRIPTION -FEATURE_FLAGS[config=Debug][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION SUBSCRIPTION -FEATURE_FLAGS[config=Review][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION SUBSCRIPTION +FEATURE_FLAGS[arch=*][sdk=*] = NETP_SYSTEM_EXTENSION +FEATURE_FLAGS[config=CI][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION +FEATURE_FLAGS[config=Debug][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION +FEATURE_FLAGS[config=Review][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION SWIFT_OBJC_BRIDGING_HEADER = SKIP_INSTALL = YES diff --git a/Configuration/App/NetworkProtection/DuckDuckGoVPNAppStore.xcconfig b/Configuration/App/NetworkProtection/DuckDuckGoVPNAppStore.xcconfig index 82c6a46644..d3e404d3ac 100644 --- a/Configuration/App/NetworkProtection/DuckDuckGoVPNAppStore.xcconfig +++ b/Configuration/App/NetworkProtection/DuckDuckGoVPNAppStore.xcconfig @@ -50,10 +50,10 @@ PROVISIONING_PROFILE_SPECIFIER[sdk=macosx*] = PROVISIONING_PROFILE_SPECIFIER[config=Release][sdk=macosx*] = match AppStore com.duckduckgo.mobile.ios.vpn.agent macos PROVISIONING_PROFILE_SPECIFIER[config=Review][sdk=macosx*] = match AppStore com.duckduckgo.mobile.ios.vpn.agent.review macos -FEATURE_FLAGS[arch=*][sdk=*] = SUBSCRIPTION -FEATURE_FLAGS[config=CI][arch=*][sdk=*] = SUBSCRIPTION -FEATURE_FLAGS[config=Debug][arch=*][sdk=*] = SUBSCRIPTION -FEATURE_FLAGS[config=Review][arch=*][sdk=*] = SUBSCRIPTION +FEATURE_FLAGS[arch=*][sdk=*] = +FEATURE_FLAGS[config=CI][arch=*][sdk=*] = +FEATURE_FLAGS[config=Debug][arch=*][sdk=*] = +FEATURE_FLAGS[config=Review][arch=*][sdk=*] = ENABLE_APP_SANDBOX = YES SWIFT_OBJC_BRIDGING_HEADER = diff --git a/Configuration/BuildNumber.xcconfig b/Configuration/BuildNumber.xcconfig index 3e6bef97fd..67b5d537a4 100644 --- a/Configuration/BuildNumber.xcconfig +++ b/Configuration/BuildNumber.xcconfig @@ -1 +1 @@ -CURRENT_PROJECT_VERSION = 161 +CURRENT_PROJECT_VERSION = 174 diff --git a/Configuration/Common.xcconfig b/Configuration/Common.xcconfig index 08829b84c0..04c51ab42e 100644 --- a/Configuration/Common.xcconfig +++ b/Configuration/Common.xcconfig @@ -21,7 +21,7 @@ COMBINE_HIDPI_IMAGES = YES DEVELOPMENT_TEAM = HKE973VLUW DEVELOPMENT_TEAM[config=CI][sdk=*] = -FEATURE_FLAGS = FEEDBACK DBP SUBSCRIPTION +FEATURE_FLAGS = FEEDBACK DBP GCC_PREPROCESSOR_DEFINITIONS[config=CI][arch=*][sdk=*] = DEBUG=1 CI=1 $(inherited) GCC_PREPROCESSOR_DEFINITIONS[config=Debug][arch=*][sdk=*] = DEBUG=1 $(inherited) diff --git a/Configuration/Extensions/NetworkProtection/NetworkProtectionSystemExtension.xcconfig b/Configuration/Extensions/NetworkProtection/NetworkProtectionSystemExtension.xcconfig index 25bbdee54d..f815d7c7de 100644 --- a/Configuration/Extensions/NetworkProtection/NetworkProtectionSystemExtension.xcconfig +++ b/Configuration/Extensions/NetworkProtection/NetworkProtectionSystemExtension.xcconfig @@ -31,10 +31,10 @@ INFOPLIST_FILE = NetworkProtectionSystemExtension/Info.plist INFOPLIST_KEY_NSHumanReadableCopyright = Copyright © 2023 DuckDuckGo. All rights reserved. INFOPLIST_KEY_NSSystemExtensionUsageDescription = DuckDuckGo VPN -FEATURE_FLAGS[arch=*][sdk=*] = NETP_SYSTEM_EXTENSION NETWORK_EXTENSION SUBSCRIPTION -FEATURE_FLAGS[config=CI][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION NETWORK_EXTENSION SUBSCRIPTION -FEATURE_FLAGS[config=Debug][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION NETWORK_EXTENSION SUBSCRIPTION -FEATURE_FLAGS[config=Review][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION NETWORK_EXTENSION SUBSCRIPTION +FEATURE_FLAGS[arch=*][sdk=*] = NETP_SYSTEM_EXTENSION NETWORK_EXTENSION +FEATURE_FLAGS[config=CI][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION NETWORK_EXTENSION +FEATURE_FLAGS[config=Debug][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION NETWORK_EXTENSION +FEATURE_FLAGS[config=Review][arch=*][sdk=*] = NETP_SYSTEM_EXTENSION NETWORK_EXTENSION PRODUCT_BUNDLE_IDENTIFIER[sdk=*] = $(SYSEX_BUNDLE_ID) PRODUCT_BUNDLE_IDENTIFIER[config=CI][sdk=*] = $(SYSEX_BUNDLE_ID) diff --git a/Configuration/Tests/UnitTests.xcconfig b/Configuration/Tests/UnitTests.xcconfig index a6e5d79a1d..1f7cfbaeaf 100644 --- a/Configuration/Tests/UnitTests.xcconfig +++ b/Configuration/Tests/UnitTests.xcconfig @@ -17,7 +17,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES -FEATURE_FLAGS = FEEDBACK DBP SUBSCRIPTION +FEATURE_FLAGS = FEEDBACK DBP INFOPLIST_FILE = UnitTests/Info.plist PRODUCT_BUNDLE_IDENTIFIER = com.duckduckgo.macos.browser.DuckDuckGoTests diff --git a/Configuration/Tests/UnitTestsAppStore.xcconfig b/Configuration/Tests/UnitTestsAppStore.xcconfig index 0f966ba610..e187624399 100644 --- a/Configuration/Tests/UnitTestsAppStore.xcconfig +++ b/Configuration/Tests/UnitTestsAppStore.xcconfig @@ -16,7 +16,7 @@ #include "UnitTests.xcconfig" #include "../AppStore.xcconfig" -FEATURE_FLAGS = FEEDBACK DBP SUBSCRIPTION +FEATURE_FLAGS = FEEDBACK DBP PRODUCT_BUNDLE_IDENTIFIER = com.duckduckgo.mobile.ios.DuckDuckGoTests diff --git a/Configuration/Version.xcconfig b/Configuration/Version.xcconfig index 71f4ed0cad..b517e1e1fb 100644 --- a/Configuration/Version.xcconfig +++ b/Configuration/Version.xcconfig @@ -1 +1 @@ -MARKETING_VERSION = 1.83.0 +MARKETING_VERSION = 1.85.0 diff --git a/DuckDuckGo.xcodeproj/project.pbxproj b/DuckDuckGo.xcodeproj/project.pbxproj index 55941a8752..cbb0e1aab6 100644 --- a/DuckDuckGo.xcodeproj/project.pbxproj +++ b/DuckDuckGo.xcodeproj/project.pbxproj @@ -19,13 +19,10 @@ 14D9B8FB24F7E089000D4D13 /* AddressBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14D9B8F924F7E089000D4D13 /* AddressBarViewController.swift */; }; 1D01A3D02B88CEC600FE8150 /* PreferencesAccessibilityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D01A3CF2B88CEC600FE8150 /* PreferencesAccessibilityView.swift */; }; 1D01A3D12B88CEC600FE8150 /* PreferencesAccessibilityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D01A3CF2B88CEC600FE8150 /* PreferencesAccessibilityView.swift */; }; - 1D01A3D22B88CEC600FE8150 /* PreferencesAccessibilityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D01A3CF2B88CEC600FE8150 /* PreferencesAccessibilityView.swift */; }; 1D01A3D42B88CF7700FE8150 /* AccessibilityPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D01A3D32B88CF7700FE8150 /* AccessibilityPreferences.swift */; }; 1D01A3D52B88CF7700FE8150 /* AccessibilityPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D01A3D32B88CF7700FE8150 /* AccessibilityPreferences.swift */; }; - 1D01A3D62B88CF7700FE8150 /* AccessibilityPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D01A3D32B88CF7700FE8150 /* AccessibilityPreferences.swift */; }; 1D01A3D82B88DF8B00FE8150 /* PreferencesSyncView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D01A3D72B88DF8B00FE8150 /* PreferencesSyncView.swift */; }; 1D01A3D92B88DF8B00FE8150 /* PreferencesSyncView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D01A3D72B88DF8B00FE8150 /* PreferencesSyncView.swift */; }; - 1D01A3DA2B88DF8B00FE8150 /* PreferencesSyncView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D01A3D72B88DF8B00FE8150 /* PreferencesSyncView.swift */; }; 1D02633628D8A9A9005CBB41 /* BWEncryption.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D02633528D8A9A9005CBB41 /* BWEncryption.m */; settings = {COMPILER_FLAGS = "-Wno-deprecated -Wno-strict-prototypes"; }; }; 1D074B272909A433006E4AC3 /* PasswordManagerCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D074B262909A433006E4AC3 /* PasswordManagerCoordinator.swift */; }; 1D12F2E2298BC660009A65FD /* InternalUserDeciderStoreMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D12F2E1298BC660009A65FD /* InternalUserDeciderStoreMock.swift */; }; @@ -37,16 +34,12 @@ 1D1C36E729FB019C001FA40C /* HistoryTabExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D1C36E529FB019C001FA40C /* HistoryTabExtensionTests.swift */; }; 1D220BF82B86192200F8BBC6 /* PreferencesEmailProtectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D220BF72B86192200F8BBC6 /* PreferencesEmailProtectionView.swift */; }; 1D220BF92B86192200F8BBC6 /* PreferencesEmailProtectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D220BF72B86192200F8BBC6 /* PreferencesEmailProtectionView.swift */; }; - 1D220BFA2B86192200F8BBC6 /* PreferencesEmailProtectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D220BF72B86192200F8BBC6 /* PreferencesEmailProtectionView.swift */; }; 1D220BFC2B87AACF00F8BBC6 /* PrivacyProtectionStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D220BFB2B87AACF00F8BBC6 /* PrivacyProtectionStatus.swift */; }; 1D220BFD2B87AACF00F8BBC6 /* PrivacyProtectionStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D220BFB2B87AACF00F8BBC6 /* PrivacyProtectionStatus.swift */; }; - 1D220BFE2B87AACF00F8BBC6 /* PrivacyProtectionStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D220BFB2B87AACF00F8BBC6 /* PrivacyProtectionStatus.swift */; }; 1D26EBAC2B74BECB0002A93F /* NSImageSendable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D26EBAB2B74BECB0002A93F /* NSImageSendable.swift */; }; 1D26EBAD2B74BECB0002A93F /* NSImageSendable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D26EBAB2B74BECB0002A93F /* NSImageSendable.swift */; }; - 1D26EBAE2B74BECB0002A93F /* NSImageSendable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D26EBAB2B74BECB0002A93F /* NSImageSendable.swift */; }; 1D26EBB02B74DB600002A93F /* TabSnapshotCleanupService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D26EBAF2B74DB600002A93F /* TabSnapshotCleanupService.swift */; }; 1D26EBB12B74DB600002A93F /* TabSnapshotCleanupService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D26EBAF2B74DB600002A93F /* TabSnapshotCleanupService.swift */; }; - 1D26EBB22B74DB600002A93F /* TabSnapshotCleanupService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D26EBAF2B74DB600002A93F /* TabSnapshotCleanupService.swift */; }; 1D2DC00629016798008083A1 /* BWCredential.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDF075C28F815AD00EDFBE3 /* BWCredential.swift */; }; 1D2DC0072901679C008083A1 /* BWError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDF076028F815AD00EDFBE3 /* BWError.swift */; }; 1D2DC0082901679E008083A1 /* BWResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDF076128F815AD00EDFBE3 /* BWResponse.swift */; }; @@ -90,7 +83,6 @@ 1D8C2FF12B70F751005E4BBD /* MockTabSnapshotStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D8C2FEF2B70F751005E4BBD /* MockTabSnapshotStore.swift */; }; 1D9A4E5A2B43213B00F449E2 /* TabSnapshotExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D9A4E592B43213B00F449E2 /* TabSnapshotExtension.swift */; }; 1D9A4E5B2B43213B00F449E2 /* TabSnapshotExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D9A4E592B43213B00F449E2 /* TabSnapshotExtension.swift */; }; - 1D9A4E5C2B43213B00F449E2 /* TabSnapshotExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D9A4E592B43213B00F449E2 /* TabSnapshotExtension.swift */; }; 1D9FDEB72B9B5D150040B78C /* SearchPreferencesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D9FDEB62B9B5D150040B78C /* SearchPreferencesTests.swift */; }; 1D9FDEB82B9B5D150040B78C /* SearchPreferencesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D9FDEB62B9B5D150040B78C /* SearchPreferencesTests.swift */; }; 1D9FDEBA2B9B5E090040B78C /* WebTrackingProtectionPreferencesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D9FDEB92B9B5E090040B78C /* WebTrackingProtectionPreferencesTests.swift */; }; @@ -109,40 +101,30 @@ 1DA6D1032A1FFA3B00540406 /* HTTPCookieTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DA6D0FF2A1FF9DC00540406 /* HTTPCookieTests.swift */; }; 1DB67F292B6FE4A6003DF243 /* WebViewSnapshotRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DB67F282B6FE4A6003DF243 /* WebViewSnapshotRenderer.swift */; }; 1DB67F2A2B6FEB17003DF243 /* WebViewSnapshotRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DB67F282B6FE4A6003DF243 /* WebViewSnapshotRenderer.swift */; }; - 1DB67F2B2B6FEB19003DF243 /* WebViewSnapshotRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DB67F282B6FE4A6003DF243 /* WebViewSnapshotRenderer.swift */; }; 1DB67F2D2B6FEFDB003DF243 /* ViewSnapshotRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DB67F2C2B6FEFDB003DF243 /* ViewSnapshotRenderer.swift */; }; 1DB67F2E2B6FEFDB003DF243 /* ViewSnapshotRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DB67F2C2B6FEFDB003DF243 /* ViewSnapshotRenderer.swift */; }; - 1DB67F2F2B6FEFDB003DF243 /* ViewSnapshotRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DB67F2C2B6FEFDB003DF243 /* ViewSnapshotRenderer.swift */; }; 1DB9617A29F1D06D00CF5568 /* InternalUserDeciderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DB9617929F1D06D00CF5568 /* InternalUserDeciderMock.swift */; }; 1DB9617B29F1D06D00CF5568 /* InternalUserDeciderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DB9617929F1D06D00CF5568 /* InternalUserDeciderMock.swift */; }; 1DB9618229F67F6100CF5568 /* FaviconNullStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DB9617F29F67F3E00CF5568 /* FaviconNullStore.swift */; }; 1DB9618329F67F6200CF5568 /* FaviconNullStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DB9617F29F67F3E00CF5568 /* FaviconNullStore.swift */; }; 1DC669702B6CF0D700AA0645 /* TabSnapshotStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DC6696F2B6CF0D700AA0645 /* TabSnapshotStore.swift */; }; 1DC669712B6CF0D700AA0645 /* TabSnapshotStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DC6696F2B6CF0D700AA0645 /* TabSnapshotStore.swift */; }; - 1DC669722B6CF0D700AA0645 /* TabSnapshotStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DC6696F2B6CF0D700AA0645 /* TabSnapshotStore.swift */; }; 1DCFBC8A29ADF32B00313531 /* BurnerHomePageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DCFBC8929ADF32B00313531 /* BurnerHomePageView.swift */; }; 1DCFBC8B29ADF32B00313531 /* BurnerHomePageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DCFBC8929ADF32B00313531 /* BurnerHomePageView.swift */; }; 1DDC84F72B83558F00670238 /* PreferencesPrivateSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDC84F62B83558F00670238 /* PreferencesPrivateSearchView.swift */; }; 1DDC84F82B83558F00670238 /* PreferencesPrivateSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDC84F62B83558F00670238 /* PreferencesPrivateSearchView.swift */; }; - 1DDC84F92B83558F00670238 /* PreferencesPrivateSearchView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDC84F62B83558F00670238 /* PreferencesPrivateSearchView.swift */; }; 1DDC84FB2B8356CE00670238 /* PreferencesDefaultBrowserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDC84FA2B8356CE00670238 /* PreferencesDefaultBrowserView.swift */; }; 1DDC84FC2B8356CE00670238 /* PreferencesDefaultBrowserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDC84FA2B8356CE00670238 /* PreferencesDefaultBrowserView.swift */; }; - 1DDC84FD2B8356CE00670238 /* PreferencesDefaultBrowserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDC84FA2B8356CE00670238 /* PreferencesDefaultBrowserView.swift */; }; 1DDC84FF2B835BC000670238 /* SearchPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDC84FE2B835BC000670238 /* SearchPreferences.swift */; }; 1DDC85002B835BC000670238 /* SearchPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDC84FE2B835BC000670238 /* SearchPreferences.swift */; }; - 1DDC85012B835BC000670238 /* SearchPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDC84FE2B835BC000670238 /* SearchPreferences.swift */; }; 1DDC85032B83903E00670238 /* PreferencesWebTrackingProtectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDC85022B83903E00670238 /* PreferencesWebTrackingProtectionView.swift */; }; 1DDC85042B83903E00670238 /* PreferencesWebTrackingProtectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDC85022B83903E00670238 /* PreferencesWebTrackingProtectionView.swift */; }; - 1DDC85052B83903E00670238 /* PreferencesWebTrackingProtectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDC85022B83903E00670238 /* PreferencesWebTrackingProtectionView.swift */; }; 1DDD3EBC2B84DCB9004CBF2B /* WebTrackingProtectionPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDD3EBB2B84DCB9004CBF2B /* WebTrackingProtectionPreferences.swift */; }; 1DDD3EBD2B84DCB9004CBF2B /* WebTrackingProtectionPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDD3EBB2B84DCB9004CBF2B /* WebTrackingProtectionPreferences.swift */; }; - 1DDD3EBE2B84DCB9004CBF2B /* WebTrackingProtectionPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDD3EBB2B84DCB9004CBF2B /* WebTrackingProtectionPreferences.swift */; }; 1DDD3EC02B84F5D5004CBF2B /* PreferencesCookiePopupProtectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDD3EBF2B84F5D5004CBF2B /* PreferencesCookiePopupProtectionView.swift */; }; 1DDD3EC12B84F5D5004CBF2B /* PreferencesCookiePopupProtectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDD3EBF2B84F5D5004CBF2B /* PreferencesCookiePopupProtectionView.swift */; }; - 1DDD3EC22B84F5D5004CBF2B /* PreferencesCookiePopupProtectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDD3EBF2B84F5D5004CBF2B /* PreferencesCookiePopupProtectionView.swift */; }; 1DDD3EC42B84F96B004CBF2B /* CookiePopupProtectionPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDD3EC32B84F96B004CBF2B /* CookiePopupProtectionPreferences.swift */; }; 1DDD3EC52B84F96B004CBF2B /* CookiePopupProtectionPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDD3EC32B84F96B004CBF2B /* CookiePopupProtectionPreferences.swift */; }; - 1DDD3EC62B84F96B004CBF2B /* CookiePopupProtectionPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDD3EC32B84F96B004CBF2B /* CookiePopupProtectionPreferences.swift */; }; 1DDF076328F815AD00EDFBE3 /* BWCommunicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDF075D28F815AD00EDFBE3 /* BWCommunicator.swift */; }; 1DDF076428F815AD00EDFBE3 /* BWManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDF075E28F815AD00EDFBE3 /* BWManager.swift */; }; 1DE03425298BC7F000CAB3D7 /* InternalUserDeciderStoreMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D12F2E1298BC660009A65FD /* InternalUserDeciderStoreMock.swift */; }; @@ -150,17 +132,10 @@ 1DFAB51E2A8982A600A0F7F6 /* SetExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DFAB51C2A8982A600A0F7F6 /* SetExtension.swift */; }; 1DFAB5222A8983DE00A0F7F6 /* SetExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DFAB51F2A89830D00A0F7F6 /* SetExtensionTests.swift */; }; 1DFAB5232A8983E100A0F7F6 /* SetExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DFAB51F2A89830D00A0F7F6 /* SetExtensionTests.swift */; }; - 1E0068AD2B1673BB00BBF43B /* SubscriptionUI in Frameworks */ = {isa = PBXBuildFile; productRef = 1E0068AC2B1673BB00BBF43B /* SubscriptionUI */; }; 1E0C72062ABC63BD00802009 /* SubscriptionPagesUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E0C72052ABC63BD00802009 /* SubscriptionPagesUserScript.swift */; }; 1E0C72072ABC63BD00802009 /* SubscriptionPagesUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E0C72052ABC63BD00802009 /* SubscriptionPagesUserScript.swift */; }; - 1E21F8E32B73E48600FB272E /* Subscription in Frameworks */ = {isa = PBXBuildFile; productRef = 1E21F8E22B73E48600FB272E /* Subscription */; }; - 1E2AE4C72ACB215900684E0A /* NetworkProtectionRemoteMessaging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BCF15D62ABB8A110083F6DF /* NetworkProtectionRemoteMessaging.swift */; }; - 1E2AE4C82ACB216B00684E0A /* HoverTrackingArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B140872ABDBCC1004F8E85 /* HoverTrackingArea.swift */; }; - 1E2AE4CA2ACB21A000684E0A /* NetworkProtectionRemoteMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BCF15D82ABB8A7F0083F6DF /* NetworkProtectionRemoteMessage.swift */; }; - 1E2AE4CB2ACB21C800684E0A /* HardwareModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9579202AC687170062CA31 /* HardwareModel.swift */; }; 1E559BB12BBCA9F1002B4AF6 /* RedirectNavigationResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E559BB02BBCA9F1002B4AF6 /* RedirectNavigationResponder.swift */; }; 1E559BB22BBCA9F1002B4AF6 /* RedirectNavigationResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E559BB02BBCA9F1002B4AF6 /* RedirectNavigationResponder.swift */; }; - 1E559BB32BBCA9F1002B4AF6 /* RedirectNavigationResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E559BB02BBCA9F1002B4AF6 /* RedirectNavigationResponder.swift */; }; 1E7E2E9029029A2A00C01B54 /* ContentBlockingRulesUpdateObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7E2E8F29029A2A00C01B54 /* ContentBlockingRulesUpdateObserver.swift */; }; 1E7E2E942902AC0E00C01B54 /* PrivacyDashboardPermissionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7E2E932902AC0E00C01B54 /* PrivacyDashboardPermissionHandler.swift */; }; 1E950E3F2912A10D0051A99B /* ContentBlocking in Frameworks */ = {isa = PBXBuildFile; productRef = 1E950E3E2912A10D0051A99B /* ContentBlocking */; }; @@ -170,37 +145,32 @@ 1EA7B8D52B7E078C000330A4 /* Subscription in Frameworks */ = {isa = PBXBuildFile; productRef = 1EA7B8D42B7E078C000330A4 /* Subscription */; }; 1ED910D52B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ED910D42B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift */; }; 1ED910D62B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ED910D42B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift */; }; - 1ED910D72B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1ED910D42B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift */; }; 310E79BF294A19A8007C49E8 /* FireproofingReferenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 310E79BE294A19A8007C49E8 /* FireproofingReferenceTests.swift */; }; 311B262728E73E0A00FD181A /* TabShadowConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 311B262628E73E0A00FD181A /* TabShadowConfig.swift */; }; 31267C692B640C4200FEF811 /* DataBrokerProtectionFeatureVisibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31C5FFB82AF64D120008A79F /* DataBrokerProtectionFeatureVisibility.swift */; }; 31267C6A2B640C4B00FEF811 /* DataBrokerProtectionFeatureDisabler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3199C6F82AF94F5B002A7BA1 /* DataBrokerProtectionFeatureDisabler.swift */; }; 31267C6B2B640C5200FEF811 /* DataBrokerProtectionAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3199C6FC2AF97367002A7BA1 /* DataBrokerProtectionAppEvents.swift */; }; 3129788A2B64131200B67619 /* DataBrokerProtection in Frameworks */ = {isa = PBXBuildFile; productRef = 312978892B64131200B67619 /* DataBrokerProtection */; }; - 3143C8792B0D1F3D00382627 /* DataBrokerProtection in Frameworks */ = {isa = PBXBuildFile; productRef = 3143C8782B0D1F3D00382627 /* DataBrokerProtection */; }; 3154FD1428E6011A00909769 /* TabShadowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3154FD1328E6011A00909769 /* TabShadowView.swift */; }; - 3158B1472B0BF72E00AF130C /* DBPHomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3192EC872A4DCF21001E97A5 /* DBPHomeViewController.swift */; }; 3158B1492B0BF73000AF130C /* DBPHomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3192EC872A4DCF21001E97A5 /* DBPHomeViewController.swift */; }; 3158B14A2B0BF74300AF130C /* DataBrokerProtectionDebugMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 316850712AF3AD58009A2828 /* DataBrokerProtectionDebugMenu.swift */; }; - 3158B14C2B0BF74500AF130C /* DataBrokerProtectionDebugMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 316850712AF3AD58009A2828 /* DataBrokerProtectionDebugMenu.swift */; }; 3158B14D2B0BF74D00AF130C /* DataBrokerProtectionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3139A1512AA4B3C000969C7D /* DataBrokerProtectionManager.swift */; }; - 3158B14F2B0BF74F00AF130C /* DataBrokerProtectionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3139A1512AA4B3C000969C7D /* DataBrokerProtectionManager.swift */; }; 3158B1502B0BF75200AF130C /* DataBrokerProtectionLoginItemScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B6D98662ADEB4B000CD35FE /* DataBrokerProtectionLoginItemScheduler.swift */; }; - 3158B1522B0BF75400AF130C /* DataBrokerProtectionLoginItemScheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B6D98662ADEB4B000CD35FE /* DataBrokerProtectionLoginItemScheduler.swift */; }; 3158B1532B0BF75700AF130C /* LoginItem+DataBrokerProtection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D8FA00B2AC5BDCE005DD0D0 /* LoginItem+DataBrokerProtection.swift */; }; - 3158B1552B0BF75900AF130C /* LoginItem+DataBrokerProtection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D8FA00B2AC5BDCE005DD0D0 /* LoginItem+DataBrokerProtection.swift */; }; 3158B1562B0BF75D00AF130C /* DataBrokerProtectionFeatureVisibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31C5FFB82AF64D120008A79F /* DataBrokerProtectionFeatureVisibility.swift */; }; - 3158B1582B0BF76000AF130C /* DataBrokerProtectionFeatureVisibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31C5FFB82AF64D120008A79F /* DataBrokerProtectionFeatureVisibility.swift */; }; 3158B1592B0BF76400AF130C /* DataBrokerProtectionFeatureDisabler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3199C6F82AF94F5B002A7BA1 /* DataBrokerProtectionFeatureDisabler.swift */; }; - 3158B15B2B0BF76700AF130C /* DataBrokerProtectionFeatureDisabler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3199C6F82AF94F5B002A7BA1 /* DataBrokerProtectionFeatureDisabler.swift */; }; 3158B15C2B0BF76D00AF130C /* DataBrokerProtectionAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3199C6FC2AF97367002A7BA1 /* DataBrokerProtectionAppEvents.swift */; }; - 3158B15E2B0BF76F00AF130C /* DataBrokerProtectionAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3199C6FC2AF97367002A7BA1 /* DataBrokerProtectionAppEvents.swift */; }; 315A023D2B64216B00BFA577 /* IPCServiceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD01C182AD8319C0088B32E /* IPCServiceManager.swift */; }; 315A023F2B6421AE00BFA577 /* Networking in Frameworks */ = {isa = PBXBuildFile; productRef = 315A023E2B6421AE00BFA577 /* Networking */; }; 315AA07028CA5CC800200030 /* YoutubePlayerNavigationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 315AA06F28CA5CC800200030 /* YoutubePlayerNavigationHandler.swift */; }; 3168506D2AF3AD1D009A2828 /* WaitlistViewControllerPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3168506C2AF3AD1C009A2828 /* WaitlistViewControllerPresenter.swift */; }; 3168506E2AF3AD1D009A2828 /* WaitlistViewControllerPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3168506C2AF3AD1C009A2828 /* WaitlistViewControllerPresenter.swift */; }; - 316850702AF3AD1D009A2828 /* WaitlistViewControllerPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3168506C2AF3AD1C009A2828 /* WaitlistViewControllerPresenter.swift */; }; + 316913232BD2B6250051B46D /* DataBrokerProtectionPixelsHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 316913222BD2B6250051B46D /* DataBrokerProtectionPixelsHandler.swift */; }; + 316913242BD2B6250051B46D /* DataBrokerProtectionPixelsHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 316913222BD2B6250051B46D /* DataBrokerProtectionPixelsHandler.swift */; }; + 316913262BD2B76F0051B46D /* DataBrokerPrerequisitesStatusVerifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 316913252BD2B76F0051B46D /* DataBrokerPrerequisitesStatusVerifier.swift */; }; + 316913272BD2B76F0051B46D /* DataBrokerPrerequisitesStatusVerifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 316913252BD2B76F0051B46D /* DataBrokerPrerequisitesStatusVerifier.swift */; }; + 316913292BD2C7570051B46D /* DataBrokerProtectionErrorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 316913282BD2C7570051B46D /* DataBrokerProtectionErrorViewController.swift */; }; + 3169132A2BD2C7570051B46D /* DataBrokerProtectionErrorViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 316913282BD2C7570051B46D /* DataBrokerProtectionErrorViewController.swift */; }; 3171D6B82889849F0068632A /* CookieManagedNotificationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3171D6B72889849F0068632A /* CookieManagedNotificationView.swift */; }; 3171D6BA288984D00068632A /* BadgeAnimationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3171D6B9288984D00068632A /* BadgeAnimationView.swift */; }; 3171D6DB2889B64D0068632A /* CookieManagedNotificationContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3171D6DA2889B64D0068632A /* CookieManagedNotificationContainerView.swift */; }; @@ -215,14 +185,14 @@ 31A3A4E32B0C115F0021063C /* DataBrokerProtection in Frameworks */ = {isa = PBXBuildFile; productRef = 31A3A4E22B0C115F0021063C /* DataBrokerProtection */; }; 31AA6B972B960B870025014E /* DataBrokerProtectionLoginItemPixels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31AA6B962B960B870025014E /* DataBrokerProtectionLoginItemPixels.swift */; }; 31AA6B982B960BA50025014E /* DataBrokerProtectionLoginItemPixels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31AA6B962B960B870025014E /* DataBrokerProtectionLoginItemPixels.swift */; }; - 31AA6B992B960BA60025014E /* DataBrokerProtectionLoginItemPixels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31AA6B962B960B870025014E /* DataBrokerProtectionLoginItemPixels.swift */; }; 31B4AF532901A4F20013585E /* NSEventExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31B4AF522901A4F20013585E /* NSEventExtension.swift */; }; 31C3CE0228EDC1E70002C24A /* CustomRoundedCornersShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31C3CE0128EDC1E70002C24A /* CustomRoundedCornersShape.swift */; }; 31C9ADE52AF0564500CEF57D /* WaitlistFeatureSetupHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31C9ADE42AF0564500CEF57D /* WaitlistFeatureSetupHandler.swift */; }; 31C9ADE62AF0564500CEF57D /* WaitlistFeatureSetupHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31C9ADE42AF0564500CEF57D /* WaitlistFeatureSetupHandler.swift */; }; - 31C9ADE82AF0564500CEF57D /* WaitlistFeatureSetupHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31C9ADE42AF0564500CEF57D /* WaitlistFeatureSetupHandler.swift */; }; 31CF3432288B0B1B0087244B /* NavigationBarBadgeAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31CF3431288B0B1B0087244B /* NavigationBarBadgeAnimator.swift */; }; 31D5375C291D944100407A95 /* PasswordManagementBitwardenItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31D5375B291D944100407A95 /* PasswordManagementBitwardenItemView.swift */; }; + 31DC2F222BD6DE6C001354EF /* DataBrokerPrerequisitesStatusVerifierTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31DC2F202BD6DE65001354EF /* DataBrokerPrerequisitesStatusVerifierTests.swift */; }; + 31DC2F232BD6E028001354EF /* DataBrokerPrerequisitesStatusVerifierTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31DC2F202BD6DE65001354EF /* DataBrokerPrerequisitesStatusVerifierTests.swift */; }; 31E163BA293A56F400963C10 /* BrokenSiteReportingReferenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31E163B9293A56F400963C10 /* BrokenSiteReportingReferenceTests.swift */; }; 31E163BD293A579E00963C10 /* PrivacyReferenceTestHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31E163BC293A579E00963C10 /* PrivacyReferenceTestHelper.swift */; }; 31E163C0293A581900963C10 /* privacy-reference-tests in Resources */ = {isa = PBXBuildFile; fileRef = 31E163BF293A581900963C10 /* privacy-reference-tests */; }; @@ -236,7 +206,6 @@ 31F28C5328C8EECA00119F70 /* DuckURLSchemeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31F28C5228C8EECA00119F70 /* DuckURLSchemeHandler.swift */; }; 31F2D1FF2AF026D800BF0144 /* WaitlistTermsAndConditionsActionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31F2D1FE2AF026D800BF0144 /* WaitlistTermsAndConditionsActionHandler.swift */; }; 31F2D2002AF026D800BF0144 /* WaitlistTermsAndConditionsActionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31F2D1FE2AF026D800BF0144 /* WaitlistTermsAndConditionsActionHandler.swift */; }; - 31F2D2022AF026D800BF0144 /* WaitlistTermsAndConditionsActionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31F2D1FE2AF026D800BF0144 /* WaitlistTermsAndConditionsActionHandler.swift */; }; 31F7F2A6288AD2CA001C0D64 /* NavigationBarBadgeAnimationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31F7F2A5288AD2CA001C0D64 /* NavigationBarBadgeAnimationView.swift */; }; 3701C9CE29BD040C00305B15 /* FirefoxBerkeleyDatabaseReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3701C9CD29BD040900305B15 /* FirefoxBerkeleyDatabaseReader.swift */; }; 3701C9CF29BD040C00305B15 /* FirefoxBerkeleyDatabaseReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3701C9CD29BD040900305B15 /* FirefoxBerkeleyDatabaseReader.swift */; }; @@ -288,7 +257,6 @@ 3706FAB2293F65D500E42796 /* TabInstrumentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB88B4F25B7BA2B006F6B06 /* TabInstrumentation.swift */; }; 3706FAB5293F65D500E42796 /* ConfigurationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85D33F1125C82EB3002B91A6 /* ConfigurationManager.swift */; }; 3706FAB6293F65D500E42796 /* YoutubePlayerUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31F28C4C28C8EEC500119F70 /* YoutubePlayerUserScript.swift */; }; - 3706FAB7293F65D500E42796 /* PixelParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A9E48326146AAB0067D1B9 /* PixelParameters.swift */; }; 3706FAB8293F65D500E42796 /* FaviconImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA5FA696275F90C400DCE9C9 /* FaviconImageCache.swift */; }; 3706FAB9293F65D500E42796 /* TabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1430DFF424D0580F00B8978C /* TabBarViewController.swift */; }; 3706FABA293F65D500E42796 /* BookmarkOutlineViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92929126670D2A00AD2C21 /* BookmarkOutlineViewDataSource.swift */; }; @@ -426,7 +394,6 @@ 3706FB60293F65D500E42796 /* PasswordManagementIdentityItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE6546E271FCD40008D1D63 /* PasswordManagementIdentityItemView.swift */; }; 3706FB61293F65D500E42796 /* ProgressExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F41030264D2B23003DA42C /* ProgressExtension.swift */; }; 3706FB62293F65D500E42796 /* CSVParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B723DF626B0002B00E14D75 /* CSVParser.swift */; }; - 3706FB64293F65D500E42796 /* PixelDataModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B6DA44062616B30600DD1EC2 /* PixelDataModel.xcdatamodeld */; }; 3706FB65293F65D500E42796 /* PrivacyDashboardWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B63BDF7D27FDAA640072D75B /* PrivacyDashboardWebView.swift */; }; 3706FB66293F65D500E42796 /* AppearancePreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CD54C727F2FDD100F1F7B9 /* AppearancePreferences.swift */; }; 3706FB67293F65D500E42796 /* DownloadListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B1E87A26D381710062C350 /* DownloadListCoordinator.swift */; }; @@ -508,7 +475,6 @@ 3706FBC7293F65D500E42796 /* EncryptedHistoryStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE7527B263B056C00B973F8 /* EncryptedHistoryStore.swift */; }; 3706FBC8293F65D500E42796 /* FirePopoverCollectionViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE246F12709EF3B00BEEAEE /* FirePopoverCollectionViewItem.swift */; }; 3706FBC9293F65D500E42796 /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA61C0D12727F59B00E6B681 /* ArrayExtension.swift */; }; - 3706FBCA293F65D500E42796 /* CrashReportSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC30A2B268F1ECD00D2D9CD /* CrashReportSender.swift */; }; 3706FBCB293F65D500E42796 /* BookmarkHTMLImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373A1AAF2842C4EA00586521 /* BookmarkHTMLImporter.swift */; }; 3706FBCC293F65D500E42796 /* CustomRoundedCornersShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31C3CE0128EDC1E70002C24A /* CustomRoundedCornersShape.swift */; }; 3706FBCD293F65D500E42796 /* LocaleExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8D9061276D1D880078DB17 /* LocaleExtension.swift */; }; @@ -545,9 +511,6 @@ 3706FBF0293F65D500E42796 /* PasswordManagementItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CC1D7C26A05F250062F04E /* PasswordManagementItemModel.swift */; }; 3706FBF2293F65D500E42796 /* FindInPageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85A0118125AF60E700FA6A0C /* FindInPageModel.swift */; }; 3706FBF3293F65D500E42796 /* PseudoFolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92929826670D2A00AD2C21 /* PseudoFolder.swift */; }; - 3706FBF5293F65D500E42796 /* PixelDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA44012616B28300DD1EC2 /* PixelDataStore.swift */; }; - 3706FBF6293F65D500E42796 /* Pixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A9E45226142B070067D1B9 /* Pixel.swift */; }; - 3706FBF7293F65D500E42796 /* PixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A9E47626146A570067D1B9 /* PixelEvent.swift */; }; 3706FBF8293F65D500E42796 /* TabBarFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA2CB1342587C29500AA6FBE /* TabBarFooter.swift */; }; 3706FBF9293F65D500E42796 /* BookmarksBarCollectionViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5336A286912D40019DBFD /* BookmarksBarCollectionViewItem.swift */; }; 3706FBFA293F65D500E42796 /* FileDownloadError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C0B23826E742610031CB7F /* FileDownloadError.swift */; }; @@ -613,7 +576,6 @@ 3706FC3F293F65D500E42796 /* ApplicationDockMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA97BF4525135DD30014931A /* ApplicationDockMenu.swift */; }; 3706FC40293F65D500E42796 /* SaveIdentityViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8A4DFE27C83B29005F40E8 /* SaveIdentityViewController.swift */; }; 3706FC41293F65D500E42796 /* FileStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BA1A69A258B076900F6F690 /* FileStore.swift */; }; - 3706FC42293F65D500E42796 /* PixelArguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A9E47E26146A800067D1B9 /* PixelArguments.swift */; }; 3706FC43293F65D500E42796 /* PinnedTabsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BF3F1E286F0A7A00BD9014 /* PinnedTabsViewModel.swift */; }; 3706FC44293F65D500E42796 /* BookmarkList.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC5E4CF25D6A709007F5990 /* BookmarkList.swift */; }; 3706FC45293F65D500E42796 /* BookmarkTableRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292C92667123700AD2C21 /* BookmarkTableRowView.swift */; }; @@ -655,9 +617,8 @@ 3706FC6F293F65D500E42796 /* FirePopoverViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA13DCB3271480B0006D48D3 /* FirePopoverViewModel.swift */; }; 3706FC71293F65D500E42796 /* NSColorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41D174025CB131900472416 /* NSColorExtension.swift */; }; 3706FC73293F65D500E42796 /* AddressBarButtonsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC5E4F525D6BF2C007F5990 /* AddressBarButtonsViewController.swift */; }; - 3706FC76293F65D500E42796 /* PixelDataRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68C92C32750EF76002AC6B0 /* PixelDataRecord.swift */; }; 3706FC77293F65D500E42796 /* PageObserverUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 853014D525E671A000FB8205 /* PageObserverUserScript.swift */; }; - 3706FC78293F65D500E42796 /* SecureVaultErrorReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B642738127B65BAC0005DFD1 /* SecureVaultErrorReporter.swift */; }; + 3706FC78293F65D500E42796 /* SecureVaultReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B642738127B65BAC0005DFD1 /* SecureVaultReporter.swift */; }; 3706FC79293F65D500E42796 /* NSImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B139AFC26B60BD800894F82 /* NSImageExtensions.swift */; }; 3706FC7B293F65D500E42796 /* PasswordManagementViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85625995269C953C00EE44BC /* PasswordManagementViewController.swift */; }; 3706FC7C293F65D500E42796 /* ImportedBookmarks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB99CFA26FE191E001E4761 /* ImportedBookmarks.swift */; }; @@ -758,7 +719,6 @@ 3706FDDF293F661700E42796 /* BookmarkSidebarTreeControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292B22667103000AD2C21 /* BookmarkSidebarTreeControllerTests.swift */; }; 3706FDE0293F661700E42796 /* TabIndexTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D2377B287EBDA300BCE03B /* TabIndexTests.swift */; }; 3706FDE1293F661700E42796 /* AdjacentItemEnumeratorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37534CA42811987D002621E7 /* AdjacentItemEnumeratorTests.swift */; }; - 3706FDE2293F661700E42796 /* PixelArgumentsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA44222616CABC00DD1EC2 /* PixelArgumentsTests.swift */; }; 3706FDE4293F661700E42796 /* TabLazyLoaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37534C9D28104D9B002621E7 /* TabLazyLoaderTests.swift */; }; 3706FDE5293F661700E42796 /* URLEventHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85F1B0C825EF9759004792B6 /* URLEventHandlerTests.swift */; }; 3706FDE6293F661700E42796 /* BookmarkOutlineViewDataSourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292B32667103000AD2C21 /* BookmarkOutlineViewDataSourceTests.swift */; }; @@ -810,7 +770,6 @@ 3706FE1A293F661700E42796 /* BrowserProfileTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B3F641D27A8D3BD00E0C118 /* BrowserProfileTests.swift */; }; 3706FE1B293F661700E42796 /* PermissionManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6106B9F26A7BE0B0013B453 /* PermissionManagerTests.swift */; }; 3706FE1C293F661700E42796 /* ConnectBitwardenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B59CC8B290083240058F2F6 /* ConnectBitwardenViewModelTests.swift */; }; - 3706FE1D293F661700E42796 /* PixelStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B662D3D82755D7AD0035D4D6 /* PixelStoreTests.swift */; }; 3706FE1E293F661700E42796 /* GeolocationProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6106BB426A809E60013B453 /* GeolocationProviderTests.swift */; }; 3706FE1F293F661700E42796 /* AppStateChangePublisherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A5A29F25B96E8300AA7ADA /* AppStateChangePublisherTests.swift */; }; 3706FE20293F661700E42796 /* CLLocationManagerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B63ED0E226B3E7FA00A9DAD1 /* CLLocationManagerMock.swift */; }; @@ -852,7 +811,6 @@ 3706FE45293F661700E42796 /* ProgressEstimationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AE74332609AFCE005B9B1A /* ProgressEstimationTests.swift */; }; 3706FE46293F661700E42796 /* EncryptedValueTransformerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BA1A6FD258C5C1300F6F690 /* EncryptedValueTransformerTests.swift */; }; 3706FE47293F661700E42796 /* URLExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85F69B3B25EDE81F00978E59 /* URLExtensionTests.swift */; }; - 3706FE48293F661700E42796 /* PixelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA44102616C0FC00DD1EC2 /* PixelTests.swift */; }; 3706FE49293F661700E42796 /* BookmarkNodePathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292B02667103000AD2C21 /* BookmarkNodePathTests.swift */; }; 3706FE4A293F661700E42796 /* BookmarkManagedObjectTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292B62667103000AD2C21 /* BookmarkManagedObjectTests.swift */; }; 3706FE4B293F661700E42796 /* BookmarksHTMLImporterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373A1AB128451ED400586521 /* BookmarksHTMLImporterTests.swift */; }; @@ -979,16 +937,13 @@ 371D00E129D8509400EC8598 /* OpenSSL in Frameworks */ = {isa = PBXBuildFile; productRef = 371D00E029D8509400EC8598 /* OpenSSL */; }; 372217802B3337FE00B8E9C2 /* TestUtils in Frameworks */ = {isa = PBXBuildFile; productRef = 3722177F2B3337FE00B8E9C2 /* TestUtils */; }; 372217822B33380700B8E9C2 /* TestUtils in Frameworks */ = {isa = PBXBuildFile; productRef = 372217812B33380700B8E9C2 /* TestUtils */; }; - 372217842B33380E00B8E9C2 /* TestUtils in Frameworks */ = {isa = PBXBuildFile; productRef = 372217832B33380E00B8E9C2 /* TestUtils */; }; 37269EFB2B332F9E005E8E46 /* Common in Frameworks */ = {isa = PBXBuildFile; productRef = 37269EFA2B332F9E005E8E46 /* Common */; }; 37269EFD2B332FAC005E8E46 /* Common in Frameworks */ = {isa = PBXBuildFile; productRef = 37269EFC2B332FAC005E8E46 /* Common */; }; 37269EFF2B332FBB005E8E46 /* Common in Frameworks */ = {isa = PBXBuildFile; productRef = 37269EFE2B332FBB005E8E46 /* Common */; }; 37269F012B332FC8005E8E46 /* Common in Frameworks */ = {isa = PBXBuildFile; productRef = 37269F002B332FC8005E8E46 /* Common */; }; - 37269F032B332FD8005E8E46 /* Common in Frameworks */ = {isa = PBXBuildFile; productRef = 37269F022B332FD8005E8E46 /* Common */; }; 37269F052B3332C2005E8E46 /* Common in Frameworks */ = {isa = PBXBuildFile; productRef = 37269F042B3332C2005E8E46 /* Common */; }; 372A0FEC2B2379310033BF7F /* SyncMetricsEventsHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372A0FEB2B2379310033BF7F /* SyncMetricsEventsHandler.swift */; }; 372A0FED2B2379310033BF7F /* SyncMetricsEventsHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372A0FEB2B2379310033BF7F /* SyncMetricsEventsHandler.swift */; }; - 372A0FEE2B2379310033BF7F /* SyncMetricsEventsHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372A0FEB2B2379310033BF7F /* SyncMetricsEventsHandler.swift */; }; 372BC2A12A4AFA47001D8FD5 /* SyncCredentialsAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372BC2A02A4AFA47001D8FD5 /* SyncCredentialsAdapter.swift */; }; 372BC2A22A4AFA47001D8FD5 /* SyncCredentialsAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372BC2A02A4AFA47001D8FD5 /* SyncCredentialsAdapter.swift */; }; 3739326529AE4B39009346AE /* DDGSync in Frameworks */ = {isa = PBXBuildFile; productRef = 3739326429AE4B39009346AE /* DDGSync */; }; @@ -999,9 +954,7 @@ 373A1AB228451ED400586521 /* BookmarksHTMLImporterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373A1AB128451ED400586521 /* BookmarksHTMLImporterTests.swift */; }; 373D9B4829EEAC1B00381FDD /* SyncMetadataDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373D9B4729EEAC1B00381FDD /* SyncMetadataDatabase.swift */; }; 373D9B4929EEAC1B00381FDD /* SyncMetadataDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373D9B4729EEAC1B00381FDD /* SyncMetadataDatabase.swift */; }; - 373FB4B12B4D6C42004C88D6 /* PreferencesViews in Frameworks */ = {isa = PBXBuildFile; productRef = 373FB4B02B4D6C42004C88D6 /* PreferencesViews */; }; 373FB4B32B4D6C4B004C88D6 /* PreferencesViews in Frameworks */ = {isa = PBXBuildFile; productRef = 373FB4B22B4D6C4B004C88D6 /* PreferencesViews */; }; - 373FB4B52B4D6C57004C88D6 /* PreferencesViews in Frameworks */ = {isa = PBXBuildFile; productRef = 373FB4B42B4D6C57004C88D6 /* PreferencesViews */; }; 37445F992A1566420029F789 /* SyncDataProviders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37445F982A1566420029F789 /* SyncDataProviders.swift */; }; 37445F9A2A1566420029F789 /* SyncDataProviders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37445F982A1566420029F789 /* SyncDataProviders.swift */; }; 37445F9C2A1569F00029F789 /* SyncBookmarksAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37445F9B2A1569F00029F789 /* SyncBookmarksAdapter.swift */; }; @@ -1022,7 +975,6 @@ 376E2D2629428353001CD31B /* PrivacyReferenceTestHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31E163BC293A579E00963C10 /* PrivacyReferenceTestHelper.swift */; }; 376E2D2729428353001CD31B /* BrokenSiteReportingReferenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31E163B9293A56F400963C10 /* BrokenSiteReportingReferenceTests.swift */; }; 376E2D282942843D001CD31B /* privacy-reference-tests in Resources */ = {isa = PBXBuildFile; fileRef = 31E163BF293A581900963C10 /* privacy-reference-tests */; }; - 376E2D29294286B8001CD31B /* PixelEventTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BC2621C293996410087A482 /* PixelEventTests.swift */; }; 37716D8029707E5D00A9FC6D /* FireproofingReferenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 310E79BE294A19A8007C49E8 /* FireproofingReferenceTests.swift */; }; 3775912D29AAC72700E26367 /* SyncPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3775912C29AAC72700E26367 /* SyncPreferences.swift */; }; 3775912E29AAC72700E26367 /* SyncPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3775912C29AAC72700E26367 /* SyncPreferences.swift */; }; @@ -1031,7 +983,6 @@ 3776582D27F71652009A6B35 /* WebsiteBreakageReportTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3776582C27F71652009A6B35 /* WebsiteBreakageReportTests.swift */; }; 3776582F27F82E62009A6B35 /* AutofillPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3776582E27F82E62009A6B35 /* AutofillPreferences.swift */; }; 3776583127F8325B009A6B35 /* AutofillPreferencesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3776583027F8325B009A6B35 /* AutofillPreferencesTests.swift */; }; - 3778183D2AD6F86D00533759 /* FavoritesDisplayModeSyncHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377D801B2AB47FBB002AF251 /* FavoritesDisplayModeSyncHandler.swift */; }; 377D801C2AB47FBB002AF251 /* FavoritesDisplayModeSyncHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377D801B2AB47FBB002AF251 /* FavoritesDisplayModeSyncHandler.swift */; }; 377D801F2AB48191002AF251 /* FavoritesDisplayModeSyncHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377D801B2AB47FBB002AF251 /* FavoritesDisplayModeSyncHandler.swift */; }; 378205F62837CBA800D1D4AA /* SavedStateMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 378205F52837CBA800D1D4AA /* SavedStateMock.swift */; }; @@ -1050,10 +1001,8 @@ 37A5E2F0298AA1B20047046B /* Persistence in Frameworks */ = {isa = PBXBuildFile; productRef = 37A5E2EF298AA1B20047046B /* Persistence */; }; 37A6A8F12AFCC988008580A3 /* FaviconsFetcherOnboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A6A8F02AFCC988008580A3 /* FaviconsFetcherOnboarding.swift */; }; 37A6A8F22AFCC988008580A3 /* FaviconsFetcherOnboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A6A8F02AFCC988008580A3 /* FaviconsFetcherOnboarding.swift */; }; - 37A6A8F42AFCC988008580A3 /* FaviconsFetcherOnboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A6A8F02AFCC988008580A3 /* FaviconsFetcherOnboarding.swift */; }; 37A6A8F62AFCCA59008580A3 /* FaviconsFetcherOnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A6A8F52AFCCA59008580A3 /* FaviconsFetcherOnboardingViewController.swift */; }; 37A6A8F72AFCCA59008580A3 /* FaviconsFetcherOnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A6A8F52AFCCA59008580A3 /* FaviconsFetcherOnboardingViewController.swift */; }; - 37A6A8F92AFCCA59008580A3 /* FaviconsFetcherOnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A6A8F52AFCCA59008580A3 /* FaviconsFetcherOnboardingViewController.swift */; }; 37A803DB27FD69D300052F4C /* DataImportResources in Resources */ = {isa = PBXBuildFile; fileRef = 37A803DA27FD69D300052F4C /* DataImportResources */; }; 37AFCE8127DA2CA600471A10 /* PreferencesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AFCE8027DA2CA600471A10 /* PreferencesViewController.swift */; }; 37AFCE8527DA2D3900471A10 /* PreferencesSidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AFCE8427DA2D3900471A10 /* PreferencesSidebar.swift */; }; @@ -1110,11 +1059,8 @@ 4B0511E1262CAA8600F6079C /* NSOpenPanelExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0511DF262CAA8600F6079C /* NSOpenPanelExtensions.swift */; }; 4B0511E2262CAA8600F6079C /* NSViewControllerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0511E0262CAA8600F6079C /* NSViewControllerExtension.swift */; }; 4B05265E2B1AE5C70054955A /* VPNMetadataCollector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B05265D2B1AE5C70054955A /* VPNMetadataCollector.swift */; }; - 4B05265F2B1AEFDB0054955A /* VPNMetadataCollector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B05265D2B1AE5C70054955A /* VPNMetadataCollector.swift */; }; 4B0526612B1D55320054955A /* VPNFeedbackSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0526602B1D55320054955A /* VPNFeedbackSender.swift */; }; - 4B0526622B1D55320054955A /* VPNFeedbackSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0526602B1D55320054955A /* VPNFeedbackSender.swift */; }; 4B0526642B1D55D80054955A /* VPNFeedbackCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0526632B1D55D80054955A /* VPNFeedbackCategory.swift */; }; - 4B0526652B1D55D80054955A /* VPNFeedbackCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0526632B1D55D80054955A /* VPNFeedbackCategory.swift */; }; 4B0A63E8289DB58E00378EF7 /* FirefoxFaviconsReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0A63E7289DB58E00378EF7 /* FirefoxFaviconsReader.swift */; }; 4B0AACAC28BC63ED001038AC /* ChromiumFaviconsReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0AACAB28BC63ED001038AC /* ChromiumFaviconsReader.swift */; }; 4B0AACAE28BC6FD0001038AC /* SafariFaviconsReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0AACAD28BC6FD0001038AC /* SafariFaviconsReader.swift */; }; @@ -1123,7 +1069,6 @@ 4B0DB5E528BD9D08007DD239 /* PinningManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0DB5E428BD9D08007DD239 /* PinningManager.swift */; }; 4B0EF7262B578095009D6481 /* AppVersionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BA71ED92B4B81E80002EBCE /* AppVersionExtension.swift */; }; 4B0EF7272B578096009D6481 /* AppVersionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BA71ED92B4B81E80002EBCE /* AppVersionExtension.swift */; }; - 4B0EF7282B5780AB009D6481 /* AppVersionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BA71ED92B4B81E80002EBCE /* AppVersionExtension.swift */; }; 4B0EF7292B5780EB009D6481 /* VPNAppEventsHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B8DB3192B504D7500EC16DA /* VPNAppEventsHandler.swift */; }; 4B11060525903E570039B979 /* CoreDataEncryptionTesting.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 4B11060325903E570039B979 /* CoreDataEncryptionTesting.xcdatamodeld */; }; 4B11060A25903EAC0039B979 /* CoreDataEncryptionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B11060925903EAC0039B979 /* CoreDataEncryptionTests.swift */; }; @@ -1139,7 +1084,6 @@ 4B1E6EF227AB5E5D00F51793 /* PasswordManagementItemList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1E6EF027AB5E5D00F51793 /* PasswordManagementItemList.swift */; }; 4B25375B2A11BE7300610219 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B4D603E2A0B290200BCD287 /* NetworkExtension.framework */; }; 4B2537722A11BF8B00610219 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B25376F2A11BF8B00610219 /* main.swift */; }; - 4B2537772A11BFE100610219 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 4B2537762A11BFE100610219 /* PixelKit */; }; 4B25377A2A11C01700610219 /* UserText+NetworkProtectionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D607C2A0B29FA00BCD287 /* UserText+NetworkProtectionExtensions.swift */; }; 4B29759728281F0900187C4E /* FirefoxEncryptionKeyReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B29759628281F0900187C4E /* FirefoxEncryptionKeyReader.swift */; }; 4B2975992828285900187C4E /* FirefoxKeyReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B2975982828285900187C4E /* FirefoxKeyReaderTests.swift */; }; @@ -1156,7 +1100,6 @@ 4B2D067F2A1334D700DE1F49 /* NetworkProtectionUI in Frameworks */ = {isa = PBXBuildFile; productRef = 4B2D067E2A1334D700DE1F49 /* NetworkProtectionUI */; }; 4B2E7D6326FF9D6500D2DB17 /* PrintingUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E7D6226FF9D6500D2DB17 /* PrintingUserScript.swift */; }; 4B2F565C2B38F93E001214C0 /* NetworkProtectionSubscriptionEventHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B2F565B2B38F93E001214C0 /* NetworkProtectionSubscriptionEventHandler.swift */; }; - 4B2F565D2B38F93E001214C0 /* NetworkProtectionSubscriptionEventHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B2F565B2B38F93E001214C0 /* NetworkProtectionSubscriptionEventHandler.swift */; }; 4B379C1527BD91E3008A968E /* QuartzIdleStateProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B379C1427BD91E3008A968E /* QuartzIdleStateProvider.swift */; }; 4B379C1E27BDB7FF008A968E /* DeviceAuthenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B379C1D27BDB7FF008A968E /* DeviceAuthenticator.swift */; }; 4B379C2227BDBA29008A968E /* LocalAuthenticationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B379C2127BDBA29008A968E /* LocalAuthenticationService.swift */; }; @@ -1172,11 +1115,6 @@ 4B37EE762B4CFF3300A89A61 /* DataBrokerProtectionRemoteMessaging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B37EE672B4CFC9500A89A61 /* DataBrokerProtectionRemoteMessaging.swift */; }; 4B37EE772B4CFF3900A89A61 /* DataBrokerProtectionRemoteMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B37EE662B4CFC9500A89A61 /* DataBrokerProtectionRemoteMessage.swift */; }; 4B37EE782B4CFF3900A89A61 /* DataBrokerProtectionRemoteMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B37EE662B4CFC9500A89A61 /* DataBrokerProtectionRemoteMessage.swift */; }; - 4B37EE792B4CFF6F00A89A61 /* DataBrokerProtectionRemoteMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B37EE662B4CFC9500A89A61 /* DataBrokerProtectionRemoteMessage.swift */; }; - 4B37EE7A2B4CFF7200A89A61 /* DataBrokerProtectionRemoteMessaging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B37EE672B4CFC9500A89A61 /* DataBrokerProtectionRemoteMessaging.swift */; }; - 4B37EE7B2B4CFF7C00A89A61 /* HomePageRemoteMessagingStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B37EE5C2B4CFC3C00A89A61 /* HomePageRemoteMessagingStorage.swift */; }; - 4B37EE7C2B4CFF8000A89A61 /* HomePageRemoteMessagingRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B37EE5E2B4CFC3C00A89A61 /* HomePageRemoteMessagingRequest.swift */; }; - 4B37EE7D2B4CFF8300A89A61 /* SurveyURLBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B37EE5D2B4CFC3C00A89A61 /* SurveyURLBuilder.swift */; }; 4B39AAF627D9B2C700A73FD5 /* NSStackViewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B39AAF527D9B2C700A73FD5 /* NSStackViewExtension.swift */; }; 4B3B8490297A0E1000A384BD /* EmailManagerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B3B848F297A0E1000A384BD /* EmailManagerExtension.swift */; }; 4B3F641E27A8D3BD00E0C118 /* BrowserProfileTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B3F641D27A8D3BD00E0C118 /* BrowserProfileTests.swift */; }; @@ -1186,10 +1124,8 @@ 4B41EDA12B15437A001EEDF4 /* NetworkProtectionNotificationsPresenterFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41ED9F2B15437A001EEDF4 /* NetworkProtectionNotificationsPresenterFactory.swift */; }; 4B41EDA32B1543B9001EEDF4 /* VPNPreferencesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41EDA22B1543B9001EEDF4 /* VPNPreferencesModel.swift */; }; 4B41EDA42B1543B9001EEDF4 /* VPNPreferencesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41EDA22B1543B9001EEDF4 /* VPNPreferencesModel.swift */; }; - 4B41EDA52B1543B9001EEDF4 /* VPNPreferencesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41EDA22B1543B9001EEDF4 /* VPNPreferencesModel.swift */; }; 4B41EDA72B1543C9001EEDF4 /* PreferencesVPNView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41EDA62B1543C9001EEDF4 /* PreferencesVPNView.swift */; }; 4B41EDA82B1543C9001EEDF4 /* PreferencesVPNView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41EDA62B1543C9001EEDF4 /* PreferencesVPNView.swift */; }; - 4B41EDA92B1543C9001EEDF4 /* PreferencesVPNView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41EDA62B1543C9001EEDF4 /* PreferencesVPNView.swift */; }; 4B41EDAB2B1544B2001EEDF4 /* LoginItems in Frameworks */ = {isa = PBXBuildFile; productRef = 4B41EDAA2B1544B2001EEDF4 /* LoginItems */; }; 4B41EDAE2B168AFF001EEDF4 /* VPNFeedbackFormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41EDAD2B168AFF001EEDF4 /* VPNFeedbackFormViewController.swift */; }; 4B41EDAF2B168AFF001EEDF4 /* VPNFeedbackFormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41EDAD2B168AFF001EEDF4 /* VPNFeedbackFormViewController.swift */; }; @@ -1197,14 +1133,10 @@ 4B41EDB22B168B1E001EEDF4 /* VPNFeedbackFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41EDB02B168B1E001EEDF4 /* VPNFeedbackFormView.swift */; }; 4B41EDB42B168C55001EEDF4 /* VPNFeedbackFormViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41EDB32B168C55001EEDF4 /* VPNFeedbackFormViewModel.swift */; }; 4B41EDB52B168C55001EEDF4 /* VPNFeedbackFormViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41EDB32B168C55001EEDF4 /* VPNFeedbackFormViewModel.swift */; }; - 4B41EDB62B169883001EEDF4 /* VPNFeedbackFormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41EDAD2B168AFF001EEDF4 /* VPNFeedbackFormViewController.swift */; }; - 4B41EDB72B169887001EEDF4 /* VPNFeedbackFormView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41EDB02B168B1E001EEDF4 /* VPNFeedbackFormView.swift */; }; - 4B41EDB82B169889001EEDF4 /* VPNFeedbackFormViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B41EDB32B168C55001EEDF4 /* VPNFeedbackFormViewModel.swift */; }; 4B434690285ED7A100177407 /* BookmarksBarViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B43468F285ED7A100177407 /* BookmarksBarViewModelTests.swift */; }; 4B43469528655D1400177407 /* FirefoxDataImporterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B43469428655D1400177407 /* FirefoxDataImporterTests.swift */; }; 4B44FEF32B1FEF5A000619D8 /* FocusableTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B44FEF22B1FEF5A000619D8 /* FocusableTextEditor.swift */; }; 4B44FEF42B1FEF5A000619D8 /* FocusableTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B44FEF22B1FEF5A000619D8 /* FocusableTextEditor.swift */; }; - 4B44FEF52B1FEF5A000619D8 /* FocusableTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B44FEF22B1FEF5A000619D8 /* FocusableTextEditor.swift */; }; 4B4BEC3D2A11B56B001D9AC5 /* DuckDuckGoNotificationsAppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4BEC382A11B509001D9AC5 /* DuckDuckGoNotificationsAppDelegate.swift */; }; 4B4BEC3E2A11B56E001D9AC5 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4BEC322A11B509001D9AC5 /* Logging.swift */; }; 4B4BEC412A11B5BD001D9AC5 /* NetworkProtectionUNNotificationsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60762A0B29FA00BCD287 /* NetworkProtectionUNNotificationsPresenter.swift */; }; @@ -1214,7 +1146,6 @@ 4B4BEC482A11B61F001D9AC5 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4B4BEC342A11B509001D9AC5 /* Assets.xcassets */; }; 4B4D603F2A0B290200BCD287 /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B4D603E2A0B290200BCD287 /* NetworkExtension.framework */; }; 4B4D60892A0B2A1C00BCD287 /* NetworkProtectionUNNotificationsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60762A0B29FA00BCD287 /* NetworkProtectionUNNotificationsPresenter.swift */; }; - 4B4D60982A0B2A5C00BCD287 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 4B4D60972A0B2A5C00BCD287 /* PixelKit */; }; 4B4D609F2A0B2C7300BCD287 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85799C1725DEBB3F0007EC87 /* Logging.swift */; }; 4B4D60A02A0B2D5B00BCD287 /* Bundle+VPN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605E2A0B29FA00BCD287 /* Bundle+VPN.swift */; }; 4B4D60A12A0B2D6100BCD287 /* NetworkProtectionOptionKeyExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605F2A0B29FA00BCD287 /* NetworkProtectionOptionKeyExtension.swift */; }; @@ -1246,7 +1177,6 @@ 4B4F72EC266B2ED300814C60 /* CollectionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4F72EB266B2ED300814C60 /* CollectionExtension.swift */; }; 4B520F632BA5573A006405C7 /* WaitlistThankYouView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B520F622BA5573A006405C7 /* WaitlistThankYouView.swift */; }; 4B520F642BA5573A006405C7 /* WaitlistThankYouView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B520F622BA5573A006405C7 /* WaitlistThankYouView.swift */; }; - 4B520F652BA5573A006405C7 /* WaitlistThankYouView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B520F622BA5573A006405C7 /* WaitlistThankYouView.swift */; }; 4B59023E26B35F3600489384 /* ChromiumLoginReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B59023926B35F3600489384 /* ChromiumLoginReader.swift */; }; 4B59024026B35F3600489384 /* ChromiumDataImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B59023B26B35F3600489384 /* ChromiumDataImporter.swift */; }; 4B59024826B3673600489384 /* ThirdPartyBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B59024726B3673600489384 /* ThirdPartyBrowser.swift */; }; @@ -1259,16 +1189,12 @@ 4B677433255DBEB800025BD8 /* httpsMobileV2Bloom.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4B677428255DBEB800025BD8 /* httpsMobileV2Bloom.bin */; }; 4B677435255DBEB800025BD8 /* httpsMobileV2FalsePositives.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B67742A255DBEB800025BD8 /* httpsMobileV2FalsePositives.json */; }; 4B677442255DBEEA00025BD8 /* Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B677440255DBEEA00025BD8 /* Database.swift */; }; - 4B67853F2AA7C726008A5004 /* DailyPixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67853E2AA7C726008A5004 /* DailyPixel.swift */; }; - 4B6785402AA7C726008A5004 /* DailyPixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67853E2AA7C726008A5004 /* DailyPixel.swift */; }; 4B6785472AA8DE68008A5004 /* NetworkProtectionFeatureDisabler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B6785432AA8DE1F008A5004 /* NetworkProtectionFeatureDisabler.swift */; }; 4B6785482AA8DE69008A5004 /* NetworkProtectionFeatureDisabler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B6785432AA8DE1F008A5004 /* NetworkProtectionFeatureDisabler.swift */; }; 4B67854A2AA8DE75008A5004 /* NetworkProtectionFeatureVisibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD8679A2A9E9E000063B9F7 /* NetworkProtectionFeatureVisibility.swift */; }; 4B67854B2AA8DE76008A5004 /* NetworkProtectionFeatureVisibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD8679A2A9E9E000063B9F7 /* NetworkProtectionFeatureVisibility.swift */; }; - 4B68DDFF2ACBA14100FB0973 /* FileLineError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B696AFFA2AC5924800C93203 /* FileLineError.swift */; }; 4B6B64842BA930420009FF9F /* WaitlistThankYouPromptPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B6B64832BA930420009FF9F /* WaitlistThankYouPromptPresenter.swift */; }; 4B6B64852BA930420009FF9F /* WaitlistThankYouPromptPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B6B64832BA930420009FF9F /* WaitlistThankYouPromptPresenter.swift */; }; - 4B6B64862BA930420009FF9F /* WaitlistThankYouPromptPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B6B64832BA930420009FF9F /* WaitlistThankYouPromptPresenter.swift */; }; 4B70C00127B0793D000386ED /* DuckDuckGo-ExampleCrash.ips in Resources */ = {isa = PBXBuildFile; fileRef = 4B70BFFF27B0793D000386ED /* DuckDuckGo-ExampleCrash.ips */; }; 4B70C00227B0793D000386ED /* CrashReportTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B70C00027B0793D000386ED /* CrashReportTests.swift */; }; 4B723E0526B0003E00E14D75 /* DataImportMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B723DFF26B0003E00E14D75 /* DataImportMocks.swift */; }; @@ -1286,8 +1212,6 @@ 4B7534CC2A1FD7EA00158A99 /* NetworkProtectionInviteDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606C2A0B29FA00BCD287 /* NetworkProtectionInviteDialog.swift */; }; 4B7A57CF279A4EF300B1C70E /* ChromiumPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7A57CE279A4EF300B1C70E /* ChromiumPreferences.swift */; }; 4B7A60A1273E0BE400BBDFEB /* WKWebsiteDataStoreExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7A60A0273E0BE400BBDFEB /* WKWebsiteDataStoreExtension.swift */; }; - 4B81AD352B29512B00706C96 /* PixelKitTestingUtilities in Frameworks */ = {isa = PBXBuildFile; productRef = 4B81AD342B29512B00706C96 /* PixelKitTestingUtilities */; }; - 4B81AD372B29513100706C96 /* PixelKitTestingUtilities in Frameworks */ = {isa = PBXBuildFile; productRef = 4B81AD362B29513100706C96 /* PixelKitTestingUtilities */; }; 4B85A48028821CC500FC4C39 /* NSPasteboardItemExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B85A47F28821CC500FC4C39 /* NSPasteboardItemExtension.swift */; }; 4B8A4DFF27C83B29005F40E8 /* SaveIdentityViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8A4DFE27C83B29005F40E8 /* SaveIdentityViewController.swift */; }; 4B8A4E0127C8447E005F40E8 /* SaveIdentityPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8A4E0027C8447E005F40E8 /* SaveIdentityPopover.swift */; }; @@ -1332,691 +1256,6 @@ 4B9292DB2667125D00AD2C21 /* ContextualMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292DA2667125D00AD2C21 /* ContextualMenu.swift */; }; 4B9579212AC687170062CA31 /* HardwareModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9579202AC687170062CA31 /* HardwareModel.swift */; }; 4B9579222AC687170062CA31 /* HardwareModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9579202AC687170062CA31 /* HardwareModel.swift */; }; - 4B9579462AC7AE700062CA31 /* FaviconUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA0CC562539EBC90079BC96 /* FaviconUserScript.swift */; }; - 4B9579472AC7AE700062CA31 /* BWResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDF076128F815AD00EDFBE3 /* BWResponse.swift */; }; - 4B9579482AC7AE700062CA31 /* LottieAnimationCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = AADCBF3926F7C2CE00EF67A8 /* LottieAnimationCache.swift */; }; - 4B9579492AC7AE700062CA31 /* WaitlistDialogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB0182A983B24000927DB /* WaitlistDialogView.swift */; }; - 4B95794A2AC7AE700062CA31 /* TabIndex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D23779287EB8CA00BCE03B /* TabIndex.swift */; }; - 4B95794B2AC7AE700062CA31 /* SavePanelAccessoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B60C6F8C29B200AB007BFAA8 /* SavePanelAccessoryView.swift */; }; - 4B95794C2AC7AE700062CA31 /* TabLazyLoaderDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37534CA2281132CB002621E7 /* TabLazyLoaderDataSource.swift */; }; - 4B95794D2AC7AE700062CA31 /* LoginImport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B723DF426B0002B00E14D75 /* LoginImport.swift */; }; - 4B95794E2AC7AE700062CA31 /* JoinWaitlistView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB0172A983B24000927DB /* JoinWaitlistView.swift */; }; - 4B95794F2AC7AE700062CA31 /* LazyLoadable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37534C9F28113101002621E7 /* LazyLoadable.swift */; }; - 4B9579502AC7AE700062CA31 /* ClickToLoadModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAE427FF275D47FA00DAC26B /* ClickToLoadModel.swift */; }; - 4B9579512AC7AE700062CA31 /* KeyedCodingExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0230C0A2272080090018F728 /* KeyedCodingExtension.swift */; }; - 4B9579522AC7AE700062CA31 /* PrivacyDashboardTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BF5D842946FFDA006742B1 /* PrivacyDashboardTabExtension.swift */; }; - 4B9579542AC7AE700062CA31 /* DownloadListStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C0B22F26E61D630031CB7F /* DownloadListStore.swift */; }; - 4B9579552AC7AE700062CA31 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85799C1725DEBB3F0007EC87 /* Logging.swift */; }; - 4B9579562AC7AE700062CA31 /* CrashReportPromptPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC30A2D268F1EE300D2D9CD /* CrashReportPromptPresenter.swift */; }; - 4B9579572AC7AE700062CA31 /* BWCredential.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDF075C28F815AD00EDFBE3 /* BWCredential.swift */; }; - 4B9579582AC7AE700062CA31 /* PreferencesRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AFCE8627DA334800471A10 /* PreferencesRootView.swift */; }; - 4B9579592AC7AE700062CA31 /* AppStateChangedPublisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = B684590725C9027900DC17B6 /* AppStateChangedPublisher.swift */; }; - 4B95795A2AC7AE700062CA31 /* BookmarkTableCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92928926670D1700AD2C21 /* BookmarkTableCellView.swift */; }; - 4B95795B2AC7AE700062CA31 /* BookmarkManagementSidebarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292C72667123700AD2C21 /* BookmarkManagementSidebarViewController.swift */; }; - 4B95795C2AC7AE700062CA31 /* NSStackViewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B39AAF527D9B2C700A73FD5 /* NSStackViewExtension.swift */; }; - 4B95795D2AC7AE700062CA31 /* OptionalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B637273C26CCF0C200C8CB02 /* OptionalExtension.swift */; }; - 4B95795E2AC7AE700062CA31 /* PasswordManagementLoginItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE65471271FCD40008D1D63 /* PasswordManagementLoginItemView.swift */; }; - 4B95795F2AC7AE700062CA31 /* UserText.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA80EC53256BE3BC007083E7 /* UserText.swift */; }; - 4B9579602AC7AE700062CA31 /* WKWebView+Download.swift in Sources */ = {isa = PBXBuildFile; fileRef = B61EF3EB266F91E700B4D78F /* WKWebView+Download.swift */; }; - 4B9579612AC7AE700062CA31 /* TabShadowConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 311B262628E73E0A00FD181A /* TabShadowConfig.swift */; }; - 4B9579622AC7AE700062CA31 /* URLSessionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DB3AEE278D5C370024C5C4 /* URLSessionExtension.swift */; }; - 4B9579632AC7AE700062CA31 /* WKWebsiteDataStoreExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7A60A0273E0BE400BBDFEB /* WKWebsiteDataStoreExtension.swift */; }; - 4B9579642AC7AE700062CA31 /* WindowDraggingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B693954526F04BEA0015B914 /* WindowDraggingView.swift */; }; - 4B9579652AC7AE700062CA31 /* SecureVaultSorting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1E6EEB27AB5E5100F51793 /* SecureVaultSorting.swift */; }; - 4B9579662AC7AE700062CA31 /* PreferencesSidebarModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CD54C627F2FDD100F1F7B9 /* PreferencesSidebarModel.swift */; }; - 4B9579672AC7AE700062CA31 /* DuckPlayerURLExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3767190128E724B2003A2A15 /* DuckPlayerURLExtension.swift */; }; - 4B9579682AC7AE700062CA31 /* BWEncryptionOutput.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D43EB31292788C70065E5D6 /* BWEncryptionOutput.m */; }; - 4B9579692AC7AE700062CA31 /* PermissionState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6106BAC26A7BF390013B453 /* PermissionState.swift */; }; - 4B95796A2AC7AE700062CA31 /* FeedbackPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371C0A2827E33EDC0070591F /* FeedbackPresenter.swift */; }; - 4B95796B2AC7AE700062CA31 /* NavigationProtectionTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66260DC29AC5D4300E9E3EE /* NavigationProtectionTabExtension.swift */; }; - 4B95796C2AC7AE700062CA31 /* BurnerMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D1A33482A6FEB170080ACED /* BurnerMode.swift */; }; - 4B95796D2AC7AE700062CA31 /* UserAgent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14505A07256084EF00272CC6 /* UserAgent.swift */; }; - 4B95796E2AC7AE700062CA31 /* LegacyBookmarkStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 987799EF2999993C005D8EB6 /* LegacyBookmarkStore.swift */; }; - 4B95796F2AC7AE700062CA31 /* NSAlert+DataImport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8AC93426B3B2FD00879451 /* NSAlert+DataImport.swift */; }; - 4B9579702AC7AE700062CA31 /* MainWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA7412BC24D2BEEE00D22FE0 /* MainWindow.swift */; }; - 4B9579712AC7AE700062CA31 /* CrashReportPromptViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAD6D8862696DF6D002393B3 /* CrashReportPromptViewController.swift */; }; - 4B9579722AC7AE700062CA31 /* BookmarksCleanupErrorHandling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 379E877529E98729001C8BB0 /* BookmarksCleanupErrorHandling.swift */; }; - 4B9579732AC7AE700062CA31 /* ContextMenuManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA06E32913ECEE00225DE2 /* ContextMenuManager.swift */; }; - 4B9579742AC7AE700062CA31 /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B693954326F04BE90015B914 /* GradientView.swift */; }; - 4B9579752AC7AE700062CA31 /* PreferencesSidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AFCE8427DA2D3900471A10 /* PreferencesSidebar.swift */; }; - 4B9579762AC7AE700062CA31 /* HoveredLinkTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C00ED4292FB21E009C73A6 /* HoveredLinkTabExtension.swift */; }; - 4B9579772AC7AE700062CA31 /* NSPointExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA5C8F5D2590EEE800748EB7 /* NSPointExtension.swift */; }; - 4B9579782AC7AE700062CA31 /* WindowsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA6EF9AC25066F42004754E6 /* WindowsManager.swift */; }; - 4B9579792AC7AE700062CA31 /* BWRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D43EB39292B63B00065E5D6 /* BWRequest.swift */; }; - 4B95797A2AC7AE700062CA31 /* WKWebViewConfigurationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68458CC25C7EB9000DC17B6 /* WKWebViewConfigurationExtensions.swift */; }; - 4B95797B2AC7AE700062CA31 /* HomePageDefaultBrowserModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85AC7ADC27BEB6EE00FFB69B /* HomePageDefaultBrowserModel.swift */; }; - 4B95797C2AC7AE700062CA31 /* CrashReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC30A25268DFEE200D2D9CD /* CrashReporter.swift */; }; - 4B95797D2AC7AE700062CA31 /* AddressBarTextSelectionNavigation.swift in Sources */ = {isa = PBXBuildFile; fileRef = B60D64482AAF1B7C00B26F50 /* AddressBarTextSelectionNavigation.swift */; }; - 4B95797E2AC7AE700062CA31 /* BadgeNotificationAnimationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3184AC6C288F29D800C35E4B /* BadgeNotificationAnimationModel.swift */; }; - 4B95797F2AC7AE700062CA31 /* HyperLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 857FFEBF27D239DC00415E7A /* HyperLink.swift */; }; - 4B9579802AC7AE700062CA31 /* SyncDataProviders.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37445F982A1566420029F789 /* SyncDataProviders.swift */; }; - 4B9579812AC7AE700062CA31 /* PasteboardWriting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92929A26670D2A00AD2C21 /* PasteboardWriting.swift */; }; - 4B9579822AC7AE700062CA31 /* BookmarkOutlineCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92928726670D1600AD2C21 /* BookmarkOutlineCellView.swift */; }; - 4B9579832AC7AE700062CA31 /* UnprotectedDomains.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B604085A274B8CA300680351 /* UnprotectedDomains.xcdatamodeld */; }; - 4B9579842AC7AE700062CA31 /* TabInstrumentation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB88B4F25B7BA2B006F6B06 /* TabInstrumentation.swift */; }; - 4B9579872AC7AE700062CA31 /* ConfigurationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85D33F1125C82EB3002B91A6 /* ConfigurationManager.swift */; }; - 4B9579882AC7AE700062CA31 /* YoutubePlayerUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31F28C4C28C8EEC500119F70 /* YoutubePlayerUserScript.swift */; }; - 4B9579892AC7AE700062CA31 /* PixelParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A9E48326146AAB0067D1B9 /* PixelParameters.swift */; }; - 4B95798B2AC7AE700062CA31 /* FaviconImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA5FA696275F90C400DCE9C9 /* FaviconImageCache.swift */; }; - 4B95798C2AC7AE700062CA31 /* TabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1430DFF424D0580F00B8978C /* TabBarViewController.swift */; }; - 4B95798D2AC7AE700062CA31 /* BookmarkOutlineViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92929126670D2A00AD2C21 /* BookmarkOutlineViewDataSource.swift */; }; - 4B95798E2AC7AE700062CA31 /* DataImportStatusProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D145EA29E6C99B00E3488A /* DataImportStatusProviding.swift */; }; - 4B95798F2AC7AE700062CA31 /* PasswordManagementBitwardenItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31D5375B291D944100407A95 /* PasswordManagementBitwardenItemView.swift */; }; - 4B9579912AC7AE700062CA31 /* NSNotificationName+PasswordManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85D885AF26A590A90077C374 /* NSNotificationName+PasswordManager.swift */; }; - 4B9579922AC7AE700062CA31 /* RulesCompilationMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B610F2BA27A145C500FCEBE9 /* RulesCompilationMonitor.swift */; }; - 4B9579932AC7AE700062CA31 /* FBProtectionTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D574B329472253008ED1B6 /* FBProtectionTabExtension.swift */; }; - 4B9579942AC7AE700062CA31 /* CrashReportReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC30A27268E045400D2D9CD /* CrashReportReader.swift */; }; - 4B9579952AC7AE700062CA31 /* DataTaskProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85AC3B3425DA82A600C7D2AA /* DataTaskProviding.swift */; }; - 4B9579962AC7AE700062CA31 /* FeatureFlag.swift in Sources */ = {isa = PBXBuildFile; fileRef = EECE10E429DD77E60044D027 /* FeatureFlag.swift */; }; - 4B9579972AC7AE700062CA31 /* FeedbackViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3D531627A1EEED00074EC1 /* FeedbackViewController.swift */; }; - 4B9579982AC7AE700062CA31 /* FaviconSelector.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAEF6BC7276A081C0024DCF4 /* FaviconSelector.swift */; }; - 4B95799A2AC7AE700062CA31 /* PrintingUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E7D6226FF9D6500D2DB17 /* PrintingUserScript.swift */; }; - 4B95799B2AC7AE700062CA31 /* ConnectBitwardenViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDEE9028FC14760092FAA6 /* ConnectBitwardenViewController.swift */; }; - 4B95799C2AC7AE700062CA31 /* BWManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDF075E28F815AD00EDFBE3 /* BWManager.swift */; }; - 4B95799D2AC7AE700062CA31 /* AppTrackerDataSetProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9833912E27AAA3CE00DAF119 /* AppTrackerDataSetProvider.swift */; }; - 4B95799E2AC7AE700062CA31 /* EncryptionKeyGeneration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BA1A6B2258B080A00F6F690 /* EncryptionKeyGeneration.swift */; }; - 4B95799F2AC7AE700062CA31 /* TabLazyLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37B11B3828095E6600CBB621 /* TabLazyLoader.swift */; }; - 4B9579A02AC7AE700062CA31 /* InvitedToWaitlistView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB0162A983B24000927DB /* InvitedToWaitlistView.swift */; }; - 4B9579A22AC7AE700062CA31 /* SaveCredentialsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8589063B267BCDC000D23B0D /* SaveCredentialsViewController.swift */; }; - 4B9579A32AC7AE700062CA31 /* PopUpButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBE0AA627B9B027003B37A8 /* PopUpButton.swift */; }; - 4B9579A42AC7AE700062CA31 /* NetworkProtectionInviteDialog.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606C2A0B29FA00BCD287 /* NetworkProtectionInviteDialog.swift */; }; - 4B9579A52AC7AE700062CA31 /* SuggestionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AABEE6A424AA0A7F0043105B /* SuggestionViewController.swift */; }; - 4B9579A82AC7AE700062CA31 /* BWKeyStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D6216B129069BBF00386B2C /* BWKeyStorage.swift */; }; - 4B9579A92AC7AE700062CA31 /* VisitViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA7E919E287872EA00AB6B62 /* VisitViewModel.swift */; }; - 4B9579AA2AC7AE700062CA31 /* AddressBarTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6676BE02AA986A700525A21 /* AddressBarTextEditor.swift */; }; - 4B9579AB2AC7AE700062CA31 /* Atb.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69B50352726A11F00758A2B /* Atb.swift */; }; - 4B9579AC2AC7AE700062CA31 /* BrowserTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C0BB6929AF1C7000AE8E3C /* BrowserTabView.swift */; }; - 4B9579AD2AC7AE700062CA31 /* DownloadsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B1E87F26D5DA9B0062C350 /* DownloadsViewController.swift */; }; - 4B9579AE2AC7AE700062CA31 /* DataExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85AC3AF625D5DBFD00C7D2AA /* DataExtension.swift */; }; - 4B9579AF2AC7AE700062CA31 /* ConfigurationStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85480FCE25D1AA22009424E3 /* ConfigurationStore.swift */; }; - 4B9579B02AC7AE700062CA31 /* Feedback.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3D531A27A2F57E00074EC1 /* Feedback.swift */; }; - 4B9579B22AC7AE700062CA31 /* FirefoxFaviconsReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0A63E7289DB58E00378EF7 /* FirefoxFaviconsReader.swift */; }; - 4B9579B32AC7AE700062CA31 /* CopyHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 858A798226A8B75F00A75A42 /* CopyHandler.swift */; }; - 4B9579B42AC7AE700062CA31 /* ContentBlockingRulesUpdateObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7E2E8F29029A2A00C01B54 /* ContentBlockingRulesUpdateObserver.swift */; }; - 4B9579B52AC7AE700062CA31 /* FirefoxLoginReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8AC93826B48A5100879451 /* FirefoxLoginReader.swift */; }; - 4B9579B62AC7AE700062CA31 /* AtbParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69B50382726A12400758A2B /* AtbParser.swift */; }; - 4B9579B72AC7AE700062CA31 /* PreferencesDuckPlayerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37F19A6428E1B3FB00740DC6 /* PreferencesDuckPlayerView.swift */; }; - 4B9579B92AC7AE700062CA31 /* BookmarkSidebarTreeController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92929426670D2A00AD2C21 /* BookmarkSidebarTreeController.swift */; }; - 4B9579BA2AC7AE700062CA31 /* HomePageFavoritesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85589E8627BBB8F20038AD11 /* HomePageFavoritesModel.swift */; }; - 4B9579BB2AC7AE700062CA31 /* SequenceExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB88B4925B7B690006F6B06 /* SequenceExtensions.swift */; }; - 4B9579BC2AC7AE700062CA31 /* WKBackForwardListExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B602E7CE2A93A5FF00F12201 /* WKBackForwardListExtension.swift */; }; - 4B9579BD2AC7AE700062CA31 /* ChromiumDataImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B59023B26B35F3600489384 /* ChromiumDataImporter.swift */; }; - 4B9579BE2AC7AE700062CA31 /* BackForwardListItemViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA0CC3B25337FAB0079BC96 /* BackForwardListItemViewModel.swift */; }; - 4B9579BF2AC7AE700062CA31 /* BWNotRespondingAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D43EB3329297D760065E5D6 /* BWNotRespondingAlert.swift */; }; - 4B9579C02AC7AE700062CA31 /* DebugUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB88B4425B7B55C006F6B06 /* DebugUserScript.swift */; }; - 4B9579C12AC7AE700062CA31 /* RecentlyClosedTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6881828626BF800D54247 /* RecentlyClosedTab.swift */; }; - 4B9579C22AC7AE700062CA31 /* PDFSearchTextMenuItemHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = B688B4DE27420D290087BEAF /* PDFSearchTextMenuItemHandler.swift */; }; - 4B9579C42AC7AE700062CA31 /* HistoryMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA7E919628746BCC00AB6B62 /* HistoryMenu.swift */; }; - 4B9579C52AC7AE700062CA31 /* ContentScopeFeatureFlagging.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4A6198B283CFFBB007F2080 /* ContentScopeFeatureFlagging.swift */; }; - 4B9579C62AC7AE700062CA31 /* OnboardingButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85707F23276A332A00DC0649 /* OnboardingButtonStyles.swift */; }; - 4B9579C72AC7AE700062CA31 /* SaveIdentityPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8A4E0027C8447E005F40E8 /* SaveIdentityPopover.swift */; }; - 4B9579C82AC7AE700062CA31 /* AuthenticationAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = B637273A26CBC8AF00C8CB02 /* AuthenticationAlert.swift */; }; - 4B9579C92AC7AE700062CA31 /* SetExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DFAB51C2A8982A600A0F7F6 /* SetExtension.swift */; }; - 4B9579CA2AC7AE700062CA31 /* YoutubePlayerNavigationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 315AA06F28CA5CC800200030 /* YoutubePlayerNavigationHandler.swift */; }; - 4B9579CB2AC7AE700062CA31 /* PreferencesAboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AFCE9127DB8CAD00471A10 /* PreferencesAboutView.swift */; }; - 4B9579CC2AC7AE700062CA31 /* ContentBlocking.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826B09F2747DF3D0092F683 /* ContentBlocking.swift */; }; - 4B9579CD2AC7AE700062CA31 /* LocalAuthenticationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B379C2127BDBA29008A968E /* LocalAuthenticationService.swift */; }; - 4B9579CE2AC7AE700062CA31 /* CredentialsCleanupErrorHandling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CEFCA82A6737A2001EF741 /* CredentialsCleanupErrorHandling.swift */; }; - 4B9579CF2AC7AE700062CA31 /* SafariBookmarksReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB99CFC26FE191E001E4761 /* SafariBookmarksReader.swift */; }; - 4B9579D02AC7AE700062CA31 /* HTTPCookie.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DA6D0FC2A1FF9A100540406 /* HTTPCookie.swift */; }; - 4B9579D12AC7AE700062CA31 /* SafariVersionReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = AACF6FD526BC366D00CF09F9 /* SafariVersionReader.swift */; }; - 4B9579D22AC7AE700062CA31 /* LoginFaviconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE65484271FCD7B008D1D63 /* LoginFaviconView.swift */; }; - 4B9579D32AC7AE700062CA31 /* FireproofDomainsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0511B4262CAA5A00F6079C /* FireproofDomainsViewController.swift */; }; - 4B9579D42AC7AE700062CA31 /* URLEventHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA4D700625545EF800C3411E /* URLEventHandler.swift */; }; - 4B9579D52AC7AE700062CA31 /* SupportedOsChecker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D8057C72A83CAEE00F4FED6 /* SupportedOsChecker.swift */; }; - 4B9579D62AC7AE700062CA31 /* WKWebViewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA92127625ADA07900600CD4 /* WKWebViewExtension.swift */; }; - 4B9579D72AC7AE700062CA31 /* CleanThisHistoryMenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAAB9113288EB1D600A057A9 /* CleanThisHistoryMenuItem.swift */; }; - 4B9579D92AC7AE700062CA31 /* DownloadListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C0B23526E732000031CB7F /* DownloadListItem.swift */; }; - 4B9579DA2AC7AE700062CA31 /* WaitlistRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB00A2A983B24000927DB /* WaitlistRequest.swift */; }; - 4B9579DB2AC7AE700062CA31 /* DownloadsPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B1E87D26D5DA0E0062C350 /* DownloadsPopover.swift */; }; - 4B9579DC2AC7AE700062CA31 /* BookmarksBarMenuFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85774AFE2A713D3B00DE0561 /* BookmarksBarMenuFactory.swift */; }; - 4B9579DD2AC7AE700062CA31 /* SpacerNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92929626670D2A00AD2C21 /* SpacerNode.swift */; }; - 4B9579DF2AC7AE700062CA31 /* SyncManagementDialogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3775913529AB9A1C00E26367 /* SyncManagementDialogViewController.swift */; }; - 4B9579E02AC7AE700062CA31 /* BookmarkExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C0BB6629AEFF8100AE8E3C /* BookmarkExtension.swift */; }; - 4B9579E12AC7AE700062CA31 /* PasswordManagementCreditCardModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE6547B271FCD4D008D1D63 /* PasswordManagementCreditCardModel.swift */; }; - 4B9579E22AC7AE700062CA31 /* NSEventExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31B4AF522901A4F20013585E /* NSEventExtension.swift */; }; - 4B9579E32AC7AE700062CA31 /* Onboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85707F25276A335700DC0649 /* Onboarding.swift */; }; - 4B9579E42AC7AE700062CA31 /* PopUpWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68C92C0274E3EF4002AC6B0 /* PopUpWindow.swift */; }; - 4B9579E52AC7AE700062CA31 /* Favicons.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = AA5FA69E275F948900DCE9C9 /* Favicons.xcdatamodeld */; }; - 4B9579E62AC7AE700062CA31 /* Publisher.asVoid.swift in Sources */ = {isa = PBXBuildFile; fileRef = B684592125C93BE000DC17B6 /* Publisher.asVoid.swift */; }; - 4B9579E72AC7AE700062CA31 /* Waitlist.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB0072A983B23000927DB /* Waitlist.swift */; }; - 4B9579E82AC7AE700062CA31 /* NavigationButtonMenuDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA0CC32252F181A0079BC96 /* NavigationButtonMenuDelegate.swift */; }; - 4B9579E92AC7AE700062CA31 /* CrashReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC30A29268E239100D2D9CD /* CrashReport.swift */; }; - 4B9579EA2AC7AE700062CA31 /* NSPopoverExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D6A491F29CF7A490011DF74 /* NSPopoverExtension.swift */; }; - 4B9579EB2AC7AE700062CA31 /* NSPathControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CC53F327E8D4620028713D /* NSPathControlView.swift */; }; - 4B9579EC2AC7AE700062CA31 /* HTTPSUpgradeTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BF5D8829470BC4006742B1 /* HTTPSUpgradeTabExtension.swift */; }; - 4B9579ED2AC7AE700062CA31 /* AppIconChanger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D36E65A298ACD2900AA485D /* AppIconChanger.swift */; }; - 4B9579EE2AC7AE700062CA31 /* AppMain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60E12A0C883A00BCD287 /* AppMain.swift */; }; - 4B9579EF2AC7AE700062CA31 /* ProductWaitlistRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB0092A983B23000927DB /* ProductWaitlistRequest.swift */; }; - 4B9579F02AC7AE700062CA31 /* Bookmark.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 987799FC29999B64005D8EB6 /* Bookmark.xcdatamodeld */; }; - 4B9579F12AC7AE700062CA31 /* DefaultBrowserPromptView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85589E9D27BFE4500038AD11 /* DefaultBrowserPromptView.swift */; }; - 4B9579F22AC7AE700062CA31 /* WaitlistActivationDateStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4032832AAAC24400CCA602 /* WaitlistActivationDateStore.swift */; }; - 4B9579F42AC7AE700062CA31 /* FaviconManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA512D1324D99D9800230283 /* FaviconManager.swift */; }; - 4B9579F52AC7AE700062CA31 /* PFMoveApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BB108582A43375D000AB95F /* PFMoveApplication.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - 4B9579F62AC7AE700062CA31 /* ChromiumFaviconsReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0AACAB28BC63ED001038AC /* ChromiumFaviconsReader.swift */; }; - 4B9579F72AC7AE700062CA31 /* SuggestionTableRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AABEE6AA24ACA0F90043105B /* SuggestionTableRowView.swift */; }; - 4B9579F82AC7AE700062CA31 /* DownloadsPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CD54C327F2FDD100F1F7B9 /* DownloadsPreferences.swift */; }; - 4B9579F92AC7AE700062CA31 /* PasswordManagementItemList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1E6EF027AB5E5D00F51793 /* PasswordManagementItemList.swift */; }; - 4B9579FA2AC7AE700062CA31 /* Bookmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC5E4CD25D6A709007F5990 /* Bookmark.swift */; }; - 4B9579FB2AC7AE700062CA31 /* ConnectBitwardenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDEE8F28FC14760092FAA6 /* ConnectBitwardenViewModel.swift */; }; - 4B9579FC2AC7AE700062CA31 /* NSNotificationName+DataImport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B5A4F4B27F3A5AA008FBD88 /* NSNotificationName+DataImport.swift */; }; - 4B9579FD2AC7AE700062CA31 /* StoredPermission.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64C853726944B880048FEBE /* StoredPermission.swift */; }; - 4B9579FE2AC7AE700062CA31 /* FirePopoverCollectionViewHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE246F7270A406200BEEAEE /* FirePopoverCollectionViewHeader.swift */; }; - 4B9579FF2AC7AE700062CA31 /* FireViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB7320826DD0CD9002FACF9 /* FireViewController.swift */; }; - 4B957A002AC7AE700062CA31 /* OutlineSeparatorViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92928626670D1600AD2C21 /* OutlineSeparatorViewCell.swift */; }; - 4B957A012AC7AE700062CA31 /* SafariDataImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB99CFD26FE191E001E4761 /* SafariDataImporter.swift */; }; - 4B957A022AC7AE700062CA31 /* WaitlistViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB00C2A983B24000927DB /* WaitlistViewModel.swift */; }; - 4B957A032AC7AE700062CA31 /* LocalBookmarkStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 987799F829999973005D8EB6 /* LocalBookmarkStore.swift */; }; - 4B957A042AC7AE700062CA31 /* BWEncryption.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D02633528D8A9A9005CBB41 /* BWEncryption.m */; settings = {COMPILER_FLAGS = "-Wno-deprecated -Wno-strict-prototypes"; }; }; - 4B957A052AC7AE700062CA31 /* StatisticsLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69B50342726A11F00758A2B /* StatisticsLoader.swift */; }; - 4B957A072AC7AE700062CA31 /* DataClearingPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CD54C127F2FDD100F1F7B9 /* DataClearingPreferences.swift */; }; - 4B957A082AC7AE700062CA31 /* LocalUnprotectedDomains.swift in Sources */ = {isa = PBXBuildFile; fileRef = 336B39E22726B4B700C417D3 /* LocalUnprotectedDomains.swift */; }; - 4B957A092AC7AE700062CA31 /* InternalUserDeciderStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D36E657298AA3BA00AA485D /* InternalUserDeciderStore.swift */; }; - 4B957A0A2AC7AE700062CA31 /* NewWindowPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B634DBE4293C944700C3C99E /* NewWindowPolicy.swift */; }; - 4B957A0B2AC7AE700062CA31 /* NavigationBarBadgeAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31CF3431288B0B1B0087244B /* NavigationBarBadgeAnimator.swift */; }; - 4B957A0C2AC7AE700062CA31 /* NSTextViewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 858A798426A8BB5D00A75A42 /* NSTextViewExtension.swift */; }; - 4B957A0D2AC7AE700062CA31 /* FutureExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B634DBE6293C98C500C3C99E /* FutureExtension.swift */; }; - 4B957A0E2AC7AE700062CA31 /* UserDialogRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B634DBE2293C8FFF00C3C99E /* UserDialogRequest.swift */; }; - 4B957A0F2AC7AE700062CA31 /* DownloadsCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B1E88326D5EB570062C350 /* DownloadsCellView.swift */; }; - 4B957A112AC7AE700062CA31 /* PublishedAfter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AAAC2C260330580029438D /* PublishedAfter.swift */; }; - 4B957A122AC7AE700062CA31 /* FirefoxBerkeleyDatabaseReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3701C9CD29BD040900305B15 /* FirefoxBerkeleyDatabaseReader.swift */; }; - 4B957A132AC7AE700062CA31 /* WebViewSnapshotView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37054FCD2876472D00033B6F /* WebViewSnapshotView.swift */; }; - 4B957A142AC7AE700062CA31 /* DeviceAuthenticationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBC169F27C4859400E00A38 /* DeviceAuthenticationService.swift */; }; - 4B957A152AC7AE700062CA31 /* AppConfigurationURLProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB24F70B29A3D9CB006DCC58 /* AppConfigurationURLProvider.swift */; }; - 4B957A162AC7AE700062CA31 /* SyncSettingsAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CBCA992A8966E60050218F /* SyncSettingsAdapter.swift */; }; - 4B957A172AC7AE700062CA31 /* AutofillPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3776582E27F82E62009A6B35 /* AutofillPreferences.swift */; }; - 4B957A192AC7AE700062CA31 /* PasswordManagerCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D074B262909A433006E4AC3 /* PasswordManagerCoordinator.swift */; }; - 4B957A1A2AC7AE700062CA31 /* PasswordManagementIdentityModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE6547A271FCD4D008D1D63 /* PasswordManagementIdentityModel.swift */; }; - 4B957A1B2AC7AE700062CA31 /* UserDefaultsWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85C6A29525CC1FFD00EEB5F1 /* UserDefaultsWrapper.swift */; }; - 4B957A1C2AC7AE700062CA31 /* PasswordManagementPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85625997269C9C5F00EE44BC /* PasswordManagementPopover.swift */; }; - 4B957A1D2AC7AE700062CA31 /* BWCommunicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDF075D28F815AD00EDFBE3 /* BWCommunicator.swift */; }; - 4B957A1E2AC7AE700062CA31 /* HomePageRecentlyVisitedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85589E9027BFB9810038AD11 /* HomePageRecentlyVisitedModel.swift */; }; - 4B957A1F2AC7AE700062CA31 /* NavigationBarPopovers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85012B0129133F9F003D0DCC /* NavigationBarPopovers.swift */; }; - 4B957A202AC7AE700062CA31 /* CancellableExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B626A75F2992407C00053070 /* CancellableExtension.swift */; }; - 4B957A212AC7AE700062CA31 /* PinnedTabsHostingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D23783287F4D6A00BCE03B /* PinnedTabsHostingView.swift */; }; - 4B957A222AC7AE700062CA31 /* FirefoxBookmarksReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB99CF526FE191E001E4761 /* FirefoxBookmarksReader.swift */; }; - 4B957A232AC7AE700062CA31 /* DeviceIdleStateDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBC16A127C485BC00E00A38 /* DeviceIdleStateDetector.swift */; }; - 4B957A242AC7AE700062CA31 /* FlatButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B379C2327BDE1B0008A968E /* FlatButton.swift */; }; - 4B957A252AC7AE700062CA31 /* PinnedTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37054FC82873301700033B6F /* PinnedTabView.swift */; }; - 4B957A262AC7AE700062CA31 /* DataEncryption.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BA1A69F258B079600F6F690 /* DataEncryption.swift */; }; - 4B957A272AC7AE700062CA31 /* PrivacyDashboardPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6FA8940269C425400588ECD /* PrivacyDashboardPopover.swift */; }; - 4B957A282AC7AE700062CA31 /* TestsClosureNavigationResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B626A76C29928B1600053070 /* TestsClosureNavigationResponder.swift */; }; - 4B957A292AC7AE700062CA31 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85B7184D27677CBB00B4277F /* RootView.swift */; }; - 4B957A2A2AC7AE700062CA31 /* AddressBarTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = AABEE6AE24AD22B90043105B /* AddressBarTextField.swift */; }; - 4B957A2B2AC7AE700062CA31 /* FocusRingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B693953E26F04BE70015B914 /* FocusRingView.swift */; }; - 4B957A2C2AC7AE700062CA31 /* BookmarksBarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE41A5D28446EAD00760399 /* BookmarksBarViewModel.swift */; }; - 4B957A2D2AC7AE700062CA31 /* NSPopUpButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1E6EEF27AB5E5D00F51793 /* NSPopUpButtonView.swift */; }; - 4B957A2E2AC7AE700062CA31 /* BlockMenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85774B022A71CDD000DE0561 /* BlockMenuItem.swift */; }; - 4B957A2F2AC7AE700062CA31 /* ContextualMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292DA2667125D00AD2C21 /* ContextualMenu.swift */; }; - 4B957A302AC7AE700062CA31 /* NavigationBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA68C3D22490ED62001B8783 /* NavigationBarViewController.swift */; }; - 4B957A312AC7AE700062CA31 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA585DAE2490E6E600E9A3E2 /* MainViewController.swift */; }; - 4B957A322AC7AE700062CA31 /* DuckPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37F19A6928E2F2D000740DC6 /* DuckPlayer.swift */; }; - 4B957A332AC7AE700062CA31 /* Favicon.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA5FA699275F91C700DCE9C9 /* Favicon.swift */; }; - 4B957A342AC7AE700062CA31 /* SuggestionContainerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AABEE69924A902A90043105B /* SuggestionContainerViewModel.swift */; }; - 4B957A352AC7AE700062CA31 /* FirePopoverWrapperViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA840A9727319D1600E63CDD /* FirePopoverWrapperViewController.swift */; }; - 4B957A362AC7AE700062CA31 /* NSPasteboardItemExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B85A47F28821CC500FC4C39 /* NSPasteboardItemExtension.swift */; }; - 4B957A372AC7AE700062CA31 /* AutofillPreferencesModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CD54C227F2FDD100F1F7B9 /* AutofillPreferencesModel.swift */; }; - 4B957A382AC7AE700062CA31 /* NetworkProtectionDebugUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBD45B02A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift */; }; - 4B957A392AC7AE700062CA31 /* NSException+Catch.swift in Sources */ = {isa = PBXBuildFile; fileRef = B657841E25FA497600D8DB33 /* NSException+Catch.swift */; }; - 4B957A3A2AC7AE700062CA31 /* PasswordManagementNoteModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE6547D271FCD4D008D1D63 /* PasswordManagementNoteModel.swift */; }; - 4B957A3B2AC7AE700062CA31 /* CookieNotificationAnimationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3184AC6E288F2A1100C35E4B /* CookieNotificationAnimationModel.swift */; }; - 4B957A3C2AC7AE700062CA31 /* JoinedWaitlistView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB0152A983B24000927DB /* JoinedWaitlistView.swift */; }; - 4B957A3D2AC7AE700062CA31 /* SharingMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = B63ED0E426BB8FB900A9DAD1 /* SharingMenu.swift */; }; - 4B957A3E2AC7AE700062CA31 /* EnableWaitlistFeatureView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB0132A983B24000927DB /* EnableWaitlistFeatureView.swift */; }; - 4B957A3F2AC7AE700062CA31 /* GrammarFeaturesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA4FF40B2624751A004E2377 /* GrammarFeaturesManager.swift */; }; - 4B957A402AC7AE700062CA31 /* WaitlistModalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB0192A983B24000927DB /* WaitlistModalViewController.swift */; }; - 4B957A412AC7AE700062CA31 /* WKMenuItemIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA06E7291401D700225DE2 /* WKMenuItemIdentifier.swift */; }; - 4B957A422AC7AE700062CA31 /* SafariFaviconsReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0AACAD28BC6FD0001038AC /* SafariFaviconsReader.swift */; }; - 4B957A432AC7AE700062CA31 /* NSScreenExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B3E0DC2657E9CF0040E0A2 /* NSScreenExtension.swift */; }; - 4B957A442AC7AE700062CA31 /* NSBezierPathExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65E6B9F26D9F10600095F96 /* NSBezierPathExtension.swift */; }; - 4B957A452AC7AE700062CA31 /* Bundle+VPN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605E2A0B29FA00BCD287 /* Bundle+VPN.swift */; }; - 4B957A462AC7AE700062CA31 /* WebsiteDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA6820E325502F19005ED0D5 /* WebsiteDataStore.swift */; }; - 4B957A472AC7AE700062CA31 /* NetworkProtectionFeatureVisibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD8679A2A9E9E000063B9F7 /* NetworkProtectionFeatureVisibility.swift */; }; - 4B957A482AC7AE700062CA31 /* PermissionContextMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64C852926942AC90048FEBE /* PermissionContextMenu.swift */; }; - 4B957A492AC7AE700062CA31 /* ContextMenuUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85D438B5256E7C9E00F3BAF8 /* ContextMenuUserScript.swift */; }; - 4B957A4A2AC7AE700062CA31 /* NSSavePanelExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B693954726F04BEA0015B914 /* NSSavePanelExtension.swift */; }; - 4B957A4B2AC7AE700062CA31 /* AppPrivacyConfigurationDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9826B0A12747DFEB0092F683 /* AppPrivacyConfigurationDataProvider.swift */; }; - 4B957A4C2AC7AE700062CA31 /* LinkButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B1E88A26D774090062C350 /* LinkButton.swift */; }; - 4B957A4D2AC7AE700062CA31 /* TemporaryFileHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF0914282DD40100EE1418 /* TemporaryFileHandler.swift */; }; - 4B957A4E2AC7AE700062CA31 /* URL+NetworkProtection.swift in Sources */ = {isa = PBXBuildFile; fileRef = B602E8152A1E2570006D261F /* URL+NetworkProtection.swift */; }; - 4B957A4F2AC7AE700062CA31 /* PrivacyFeatures.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB6BCDF827C6BEFF00CC76DC /* PrivacyFeatures.swift */; }; - 4B957A512AC7AE700062CA31 /* ViewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 378F44EA29B4C73E00899924 /* ViewExtension.swift */; }; - 4B957A522AC7AE700062CA31 /* AVCaptureDevice+SwizzledAuthState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DB3CF826A00E2D00D459B7 /* AVCaptureDevice+SwizzledAuthState.swift */; }; - 4B957A532AC7AE700062CA31 /* SubscriptionPagesUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E0C72052ABC63BD00802009 /* SubscriptionPagesUserScript.swift */; }; - 4B957A542AC7AE700062CA31 /* VisitMenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAAB9115288EB46B00A057A9 /* VisitMenuItem.swift */; }; - 4B957A552AC7AE700062CA31 /* EncryptionKeyStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BA1A6BC258B082300F6F690 /* EncryptionKeyStore.swift */; }; - 4B957A562AC7AE700062CA31 /* TabExtensionsBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C00ED6292FB4B4009C73A6 /* TabExtensionsBuilder.swift */; }; - 4B957A582AC7AE700062CA31 /* PasswordManagementIdentityItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE6546E271FCD40008D1D63 /* PasswordManagementIdentityItemView.swift */; }; - 4B957A592AC7AE700062CA31 /* ProgressExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F41030264D2B23003DA42C /* ProgressExtension.swift */; }; - 4B957A5A2AC7AE700062CA31 /* CSVParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B723DF626B0002B00E14D75 /* CSVParser.swift */; }; - 4B957A5B2AC7AE700062CA31 /* PixelDataModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B6DA44062616B30600DD1EC2 /* PixelDataModel.xcdatamodeld */; }; - 4B957A5C2AC7AE700062CA31 /* PrivacyDashboardWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B63BDF7D27FDAA640072D75B /* PrivacyDashboardWebView.swift */; }; - 4B957A5D2AC7AE700062CA31 /* AppearancePreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CD54C727F2FDD100F1F7B9 /* AppearancePreferences.swift */; }; - 4B957A5E2AC7AE700062CA31 /* DownloadListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B1E87A26D381710062C350 /* DownloadListCoordinator.swift */; }; - 4B957A5F2AC7AE700062CA31 /* AdClickAttributionTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B647EFBA2922584B00BA628D /* AdClickAttributionTabExtension.swift */; }; - 4B957A602AC7AE700062CA31 /* NSNotificationName+Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B980E202817604000282EE1 /* NSNotificationName+Debug.swift */; }; - 4B957A612AC7AE700062CA31 /* NavigationBarBadgeAnimationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31F7F2A5288AD2CA001C0D64 /* NavigationBarBadgeAnimationView.swift */; }; - 4B957A622AC7AE700062CA31 /* AddressBarButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC5E4F025D6BF10007F5990 /* AddressBarButton.swift */; }; - 4B957A642AC7AE700062CA31 /* FaviconStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA5FA69C275F945C00DCE9C9 /* FaviconStore.swift */; }; - 4B957A652AC7AE700062CA31 /* WaitlistTermsAndConditionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB0142A983B24000927DB /* WaitlistTermsAndConditionsView.swift */; }; - 4B957A662AC7AE700062CA31 /* SuggestionListCharacteristics.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB8203B26B2DE0D00788AC3 /* SuggestionListCharacteristics.swift */; }; - 4B957A672AC7AE700062CA31 /* TimeIntervalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAADFD05264AA282001555EA /* TimeIntervalExtension.swift */; }; - 4B957A682AC7AE700062CA31 /* NetworkProtectionFeatureDisabler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B6785432AA8DE1F008A5004 /* NetworkProtectionFeatureDisabler.swift */; }; - 4B957A692AC7AE700062CA31 /* BookmarkListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292CC2667123700AD2C21 /* BookmarkListViewController.swift */; }; - 4B957A6A2AC7AE700062CA31 /* SecureVaultLoginImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B723DF326B0002B00E14D75 /* SecureVaultLoginImporter.swift */; }; - 4B957A6B2AC7AE700062CA31 /* WKProcessPoolExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B645D8F529FA95440024461F /* WKProcessPoolExtension.swift */; }; - 4B957A6D2AC7AE700062CA31 /* LoginItemsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9AE86A2AA76CF90026E7DC /* LoginItemsManager.swift */; }; - 4B957A6E2AC7AE700062CA31 /* PixelExperiment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 857E5AF42A79045800FC0FB4 /* PixelExperiment.swift */; }; - 4B957A6F2AC7AE700062CA31 /* DuckPlayerTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C416A6294A4AE500C4F2E7 /* DuckPlayerTabExtension.swift */; }; - 4B957A702AC7AE700062CA31 /* RecentlyClosedCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA5C1DD4285C780C0089850C /* RecentlyClosedCoordinator.swift */; }; - 4B957A712AC7AE700062CA31 /* URLRequestExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA88D14A252A557100980B4E /* URLRequestExtension.swift */; }; - 4B957A722AC7AE700062CA31 /* FaviconHostReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA6197C5276B3168008396F0 /* FaviconHostReference.swift */; }; - 4B957A732AC7AE700062CA31 /* DownloadsTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6685E4129A61C460043D2EE /* DownloadsTabExtension.swift */; }; - 4B957A752AC7AE700062CA31 /* ASN1Parser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8AC93A26B48ADF00879451 /* ASN1Parser.swift */; }; - 4B957A762AC7AE700062CA31 /* FileDownloadManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 856C98DE257014BD00A22F1F /* FileDownloadManager.swift */; }; - 4B957A772AC7AE700062CA31 /* BookmarkImport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB99CF626FE191E001E4761 /* BookmarkImport.swift */; }; - 4B957A782AC7AE700062CA31 /* KeySetDictionary.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68503A6279141CD00893A05 /* KeySetDictionary.swift */; }; - 4B957A792AC7AE700062CA31 /* HistoryTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66260DF29AC6EBD00E9E3EE /* HistoryTabExtension.swift */; }; - 4B957A7A2AC7AE700062CA31 /* FireCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAEEC6A827088ADB008445F7 /* FireCoordinator.swift */; }; - 4B957A7B2AC7AE700062CA31 /* GeolocationProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B655369A268442EE00085A79 /* GeolocationProvider.swift */; }; - 4B957A7C2AC7AE700062CA31 /* NSAlert+ActiveDownloadsTermination.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C0B23B26E87D900031CB7F /* NSAlert+ActiveDownloadsTermination.swift */; }; - 4B957A7D2AC7AE700062CA31 /* IndexPathExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAECA41F24EEA4AC00EFA63A /* IndexPathExtension.swift */; }; - 4B957A7E2AC7AE700062CA31 /* PasswordManagementNoteItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE65472271FCD40008D1D63 /* PasswordManagementNoteItemView.swift */; }; - 4B957A7F2AC7AE700062CA31 /* NSApplicationExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA5C8F622591021700748EB7 /* NSApplicationExtension.swift */; }; - 4B957A802AC7AE700062CA31 /* NSWindowExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA9E9A5525A3AE8400D1959D /* NSWindowExtension.swift */; }; - 4B957A812AC7AE700062CA31 /* KeychainType+ClientDefault.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */; }; - 4B957A822AC7AE700062CA31 /* SyncDebugMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370A34B02AB24E3700C77F7C /* SyncDebugMenu.swift */; }; - 4B957A832AC7AE700062CA31 /* AddBookmarkPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC5E4C425D6A6E8007F5990 /* AddBookmarkPopover.swift */; }; - 4B957A852AC7AE700062CA31 /* QRSharingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F7127D29F6779000594A45 /* QRSharingService.swift */; }; - 4B957A862AC7AE700062CA31 /* ProcessExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68C2FB127706E6A00BF2C7D /* ProcessExtension.swift */; }; - 4B957A872AC7AE700062CA31 /* PermissionAuthorizationQuery.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6106BA526A7BEC80013B453 /* PermissionAuthorizationQuery.swift */; }; - 4B957A882AC7AE700062CA31 /* BadgeAnimationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3171D6B9288984D00068632A /* BadgeAnimationView.swift */; }; - 4B957A892AC7AE700062CA31 /* BrowserTabSelectionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292C62667123700AD2C21 /* BrowserTabSelectionDelegate.swift */; }; - 4B957A8A2AC7AE700062CA31 /* ContinueSetUpView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D6A3D529DB2BAB0055215A /* ContinueSetUpView.swift */; }; - 4B957A8B2AC7AE700062CA31 /* PasswordManagementListSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1E6EEC27AB5E5100F51793 /* PasswordManagementListSection.swift */; }; - 4B957A8C2AC7AE700062CA31 /* FaviconReferenceCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA222CB82760F74E00321475 /* FaviconReferenceCache.swift */; }; - 4B957A8D2AC7AE700062CA31 /* BookmarkTreeController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92929726670D2A00AD2C21 /* BookmarkTreeController.swift */; }; - 4B957A8E2AC7AE700062CA31 /* FirefoxEncryptionKeyReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B29759628281F0900187C4E /* FirefoxEncryptionKeyReader.swift */; }; - 4B957A8F2AC7AE700062CA31 /* EventMapping+NetworkProtectionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60722A0B29FA00BCD287 /* EventMapping+NetworkProtectionError.swift */; }; - 4B957A902AC7AE700062CA31 /* BookmarkManagementSplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292C82667123700AD2C21 /* BookmarkManagementSplitViewController.swift */; }; - 4B957A912AC7AE700062CA31 /* CookieManagedNotificationContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3171D6DA2889B64D0068632A /* CookieManagedNotificationContainerView.swift */; }; - 4B957A922AC7AE700062CA31 /* FileManagerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E61EE2263AC0C8004E11AB /* FileManagerExtension.swift */; }; - 4B957A932AC7AE700062CA31 /* PermissionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DB3CFA26A17CB800D459B7 /* PermissionModel.swift */; }; - 4B957A942AC7AE700062CA31 /* PasteboardFolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92929226670D2A00AD2C21 /* PasteboardFolder.swift */; }; - 4B957A952AC7AE700062CA31 /* CookieManagedNotificationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3171D6B72889849F0068632A /* CookieManagedNotificationView.swift */; }; - 4B957A962AC7AE700062CA31 /* PermissionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6106BAA26A7BF1D0013B453 /* PermissionType.swift */; }; - 4B957A982AC7AE700062CA31 /* RecentlyClosedWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC6881A28626C1900D54247 /* RecentlyClosedWindow.swift */; }; - 4B957A992AC7AE700062CA31 /* ActionSpeech.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85707F29276A35FE00DC0649 /* ActionSpeech.swift */; }; - 4B957A9B2AC7AE700062CA31 /* ModalSheetCancellable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BE9FA9293F7955006363C6 /* ModalSheetCancellable.swift */; }; - 4B957A9C2AC7AE700062CA31 /* FireproofDomainsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6830962274CDEC7004B46BB /* FireproofDomainsStore.swift */; }; - 4B957A9D2AC7AE700062CA31 /* NetworkProtectionSimulateFailureMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B430EA02A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift */; }; - 4B957A9E2AC7AE700062CA31 /* PrivacyDashboardPermissionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7E2E932902AC0E00C01B54 /* PrivacyDashboardPermissionHandler.swift */; }; - 4B957A9F2AC7AE700062CA31 /* TabCollectionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA9FF95E24A1FB680039E328 /* TabCollectionViewModel.swift */; }; - 4B957AA02AC7AE700062CA31 /* BookmarkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC5E4CE25D6A709007F5990 /* BookmarkManager.swift */; }; - 4B957AA12AC7AE700062CA31 /* AboutModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CD54C527F2FDD100F1F7B9 /* AboutModel.swift */; }; - 4B957AA22AC7AE700062CA31 /* PasswordManagementCreditCardItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE65470271FCD40008D1D63 /* PasswordManagementCreditCardItemView.swift */; }; - 4B957AA32AC7AE700062CA31 /* NSTextFieldExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA5C8F58258FE21F00748EB7 /* NSTextFieldExtension.swift */; }; - 4B957AA42AC7AE700062CA31 /* BWManagement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3706FEC7293F6F7500E42796 /* BWManagement.swift */; }; - 4B957AA52AC7AE700062CA31 /* FireproofDomainsContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6830960274CDE99004B46BB /* FireproofDomainsContainer.swift */; }; - 4B957AA62AC7AE700062CA31 /* ExternalAppSchemeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = B687B7CB2947A1E9001DEA6F /* ExternalAppSchemeHandler.swift */; }; - 4B957AA72AC7AE700062CA31 /* GeolocationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65536AD2685E17100085A79 /* GeolocationService.swift */; }; - 4B957AA82AC7AE700062CA31 /* FireproofingURLExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B02197F25E05FAC00ED7DEA /* FireproofingURLExtensions.swift */; }; - 4B957AA92AC7AE700062CA31 /* ContentOverlayPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B1E819B27C8874900FF0E60 /* ContentOverlayPopover.swift */; }; - 4B957AAA2AC7AE700062CA31 /* TabShadowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3154FD1328E6011A00909769 /* TabShadowView.swift */; }; - 4B957AAB2AC7AE700062CA31 /* BWMessageIdGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D43EB3B292B664A0065E5D6 /* BWMessageIdGenerator.swift */; }; - 4B957AAC2AC7AE700062CA31 /* EncryptedValueTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BA1A6A4258B07DF00F6F690 /* EncryptedValueTransformer.swift */; }; - 4B957AAD2AC7AE700062CA31 /* Tab+Dialogs.swift in Sources */ = {isa = PBXBuildFile; fileRef = B634DBE0293C8FD500C3C99E /* Tab+Dialogs.swift */; }; - 4B957AAE2AC7AE700062CA31 /* PasteboardBookmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92929526670D2A00AD2C21 /* PasteboardBookmark.swift */; }; - 4B957AAF2AC7AE700062CA31 /* PinnedTabsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BF3F13286D8A6500BD9014 /* PinnedTabsManager.swift */; }; - 4B957AB02AC7AE700062CA31 /* HoverUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 856CADEF271710F400E79BB0 /* HoverUserScript.swift */; }; - 4B957AB12AC7AE700062CA31 /* MainMenuActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA6EF9B425081B4C004754E6 /* MainMenuActions.swift */; }; - 4B957AB22AC7AE700062CA31 /* WKWebView+SessionState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B63D466825BEB6C200874977 /* WKWebView+SessionState.swift */; }; - 4B957AB32AC7AE700062CA31 /* NetworkProtectionControllerErrorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606A2A0B29FA00BCD287 /* NetworkProtectionControllerErrorStore.swift */; }; - 4B957AB42AC7AE700062CA31 /* DataImport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B723DEB26B0002B00E14D75 /* DataImport.swift */; }; - 4B957AB52AC7AE700062CA31 /* NetworkProtectionDebugMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BE146062A6A83C700C313B8 /* NetworkProtectionDebugMenu.swift */; }; - 4B957AB62AC7AE700062CA31 /* FireproofDomains.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B6085D072743993C00A9C456 /* FireproofDomains.xcdatamodeld */; }; - 4B957AB82AC7AE700062CA31 /* HomePageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85589E7C27BBB8630038AD11 /* HomePageView.swift */; }; - 4B957AB92AC7AE700062CA31 /* SerpHeadersNavigationResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BF5D922947199A006742B1 /* SerpHeadersNavigationResponder.swift */; }; - 4B957ABA2AC7AE700062CA31 /* HomePageContinueSetUpModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569277C029DDCBB500B633EF /* HomePageContinueSetUpModel.swift */; }; - 4B957ABB2AC7AE700062CA31 /* WebKitDownloadTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A924D82664C72D001A28CA /* WebKitDownloadTask.swift */; }; - 4B957ABC2AC7AE700062CA31 /* ChromiumLoginReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B59023926B35F3600489384 /* ChromiumLoginReader.swift */; }; - 4B957ABD2AC7AE700062CA31 /* NSAlert+PasswordManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85D885B226A5A9DE0077C374 /* NSAlert+PasswordManager.swift */; }; - 4B957ABE2AC7AE700062CA31 /* UserContentUpdating.swift in Sources */ = {isa = PBXBuildFile; fileRef = 983DFB2428B67036006B7E34 /* UserContentUpdating.swift */; }; - 4B957ABF2AC7AE700062CA31 /* ChromiumPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7A57CE279A4EF300B1C70E /* ChromiumPreferences.swift */; }; - 4B957AC02AC7AE700062CA31 /* FirePopoverViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA6AD95A2704B6DB00159F8A /* FirePopoverViewController.swift */; }; - 4B957AC12AC7AE700062CA31 /* SavePaymentMethodPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4005227CF3DC3007D3161 /* SavePaymentMethodPopover.swift */; }; - 4B957AC22AC7AE700062CA31 /* FindInPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85A0116825AF1D8900FA6A0C /* FindInPageViewController.swift */; }; - 4B957AC32AC7AE700062CA31 /* Cryptography.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB6CE5E26B77ED000EC5860 /* Cryptography.swift */; }; - 4B957AC42AC7AE700062CA31 /* BWVault.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D69C552291302F200B75945 /* BWVault.swift */; }; - 4B957AC52AC7AE700062CA31 /* NSViewExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA6FFB4324DC33320028F4D0 /* NSViewExtension.swift */; }; - 4B957AC72AC7AE700062CA31 /* DownloadListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C0B23D26E8BF1F0031CB7F /* DownloadListViewModel.swift */; }; - 4B957AC82AC7AE700062CA31 /* BookmarkManagementDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292CD2667123700AD2C21 /* BookmarkManagementDetailViewController.swift */; }; - 4B957AC92AC7AE700062CA31 /* CSVImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B723DF726B0002B00E14D75 /* CSVImporter.swift */; }; - 4B957ACA2AC7AE700062CA31 /* StartupPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37A4CEB9282E992F00D75B89 /* StartupPreferences.swift */; }; - 4B957ACB2AC7AE700062CA31 /* UserDefaults+NetworkProtectionWaitlist.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFE95532A9DF2930081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift */; }; - 4B957ACC2AC7AE700062CA31 /* MainMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA4BBA3A25C58FA200C4FB0F /* MainMenu.swift */; }; - 4B957ACE2AC7AE700062CA31 /* BrowserTabViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA585D83248FD31100E9A3E2 /* BrowserTabViewController.swift */; }; - 4B957ACF2AC7AE700062CA31 /* CallToAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85707F21276A32B600DC0649 /* CallToAction.swift */; }; - 4B957AD02AC7AE700062CA31 /* MouseOverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B693953D26F04BE70015B914 /* MouseOverView.swift */; }; - 4B957AD12AC7AE700062CA31 /* EncryptedHistoryStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE7527B263B056C00B973F8 /* EncryptedHistoryStore.swift */; }; - 4B957AD22AC7AE700062CA31 /* FirePopoverCollectionViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE246F12709EF3B00BEEAEE /* FirePopoverCollectionViewItem.swift */; }; - 4B957AD32AC7AE700062CA31 /* ArrayExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA61C0D12727F59B00E6B681 /* ArrayExtension.swift */; }; - 4B957AD42AC7AE700062CA31 /* NetworkProtectionInviteCodeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60702A0B29FA00BCD287 /* NetworkProtectionInviteCodeViewModel.swift */; }; - 4B957AD52AC7AE700062CA31 /* CrashReportSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC30A2B268F1ECD00D2D9CD /* CrashReportSender.swift */; }; - 4B957AD62AC7AE700062CA31 /* BookmarkHTMLImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373A1AAF2842C4EA00586521 /* BookmarkHTMLImporter.swift */; }; - 4B957AD72AC7AE700062CA31 /* CustomRoundedCornersShape.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31C3CE0128EDC1E70002C24A /* CustomRoundedCornersShape.swift */; }; - 4B957AD82AC7AE700062CA31 /* LocaleExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8D9061276D1D880078DB17 /* LocaleExtension.swift */; }; - 4B957AD92AC7AE700062CA31 /* SavePaymentMethodViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE4005427CF3F19007D3161 /* SavePaymentMethodViewController.swift */; }; - 4B957ADA2AC7AE700062CA31 /* BWStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDF075F28F815AD00EDFBE3 /* BWStatus.swift */; }; - 4B957ADB2AC7AE700062CA31 /* WebKitVersionProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAFE068226C7082D005434CC /* WebKitVersionProvider.swift */; }; - 4B957ADC2AC7AE700062CA31 /* NSCoderExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B63D467925BFC3E100874977 /* NSCoderExtensions.swift */; }; - 4B957ADD2AC7AE700062CA31 /* RunningApplicationCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D77921C28FFF27C00BE0210 /* RunningApplicationCheck.swift */; }; - 4B957ADE2AC7AE700062CA31 /* StatePersistenceService.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A5A27025B9377300AA7ADA /* StatePersistenceService.swift */; }; - 4B957ADF2AC7AE700062CA31 /* WindowManager+StateRestoration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68458AF25C7E76A00DC17B6 /* WindowManager+StateRestoration.swift */; }; - 4B957AE02AC7AE700062CA31 /* TabCollection+NSSecureCoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68458C425C7EA0C00DC17B6 /* TabCollection+NSSecureCoding.swift */; }; - 4B957AE12AC7AE700062CA31 /* Instruments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB88B5A25B7BA50006F6B06 /* Instruments.swift */; }; - 4B957AE22AC7AE700062CA31 /* ContentBlockerRulesLists.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9812D894276CEDA5004B6181 /* ContentBlockerRulesLists.swift */; }; - 4B957AE32AC7AE700062CA31 /* NSViewControllerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0511E0262CAA8600F6079C /* NSViewControllerExtension.swift */; }; - 4B957AE42AC7AE700062CA31 /* NSAppearanceExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F44C130125C2DA0400426E3E /* NSAppearanceExtension.swift */; }; - 4B957AE52AC7AE700062CA31 /* EmailManagerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B3B848F297A0E1000A384BD /* EmailManagerExtension.swift */; }; - 4B957AE62AC7AE700062CA31 /* PermissionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64C84F0269310120048FEBE /* PermissionManager.swift */; }; - 4B957AE72AC7AE700062CA31 /* DefaultBrowserPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CD54C827F2FDD100F1F7B9 /* DefaultBrowserPreferences.swift */; }; - 4B957AE82AC7AE700062CA31 /* Permissions.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B64C852E26943BC10048FEBE /* Permissions.xcdatamodeld */; }; - 4B957AE92AC7AE700062CA31 /* JSAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE339227291BDEFD009F62C1 /* JSAlertController.swift */; }; - 4B957AEA2AC7AE700062CA31 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB01C2A983B24000927DB /* NotificationService.swift */; }; - 4B957AEB2AC7AE700062CA31 /* SyncPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3775912C29AAC72700E26367 /* SyncPreferences.swift */; }; - 4B957AEC2AC7AE700062CA31 /* FaviconNullStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DB9617F29F67F3E00CF5568 /* FaviconNullStore.swift */; }; - 4B957AED2AC7AE700062CA31 /* PaddedImageButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B693954126F04BE80015B914 /* PaddedImageButton.swift */; }; - 4B957AEE2AC7AE700062CA31 /* EncryptionKeyStoring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BA1A6B7258B081600F6F690 /* EncryptionKeyStoring.swift */; }; - 4B957AEF2AC7AE700062CA31 /* String+Punycode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65783E625F8AAFB00D8DB33 /* String+Punycode.swift */; }; - 4B957AF02AC7AE700062CA31 /* NSException+Catch.m in Sources */ = {isa = PBXBuildFile; fileRef = B657841925FA484B00D8DB33 /* NSException+Catch.m */; }; - 4B957AF12AC7AE700062CA31 /* AppStateRestorationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B684592E25C93FBF00DC17B6 /* AppStateRestorationManager.swift */; }; - 4B957AF22AC7AE700062CA31 /* DailyPixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B67853E2AA7C726008A5004 /* DailyPixel.swift */; }; - 4B957AF32AC7AE700062CA31 /* NavigationHotkeyHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66260E529ACAE4B00E9E3EE /* NavigationHotkeyHandler.swift */; }; - 4B957AF42AC7AE700062CA31 /* ClickToLoadUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0BA3A8272217E6002A0B6C /* ClickToLoadUserScript.swift */; }; - 4B957AF52AC7AE700062CA31 /* WindowControllersManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA892E9250A4CEF005B37B2 /* WindowControllersManager.swift */; }; - 4B957AF62AC7AE700062CA31 /* FireAnimationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85C5991A27D10CF000E605B2 /* FireAnimationView.swift */; }; - 4B957AF72AC7AE700062CA31 /* FaviconUrlReference.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA6197C3276B314D008396F0 /* FaviconUrlReference.swift */; }; - 4B957AF92AC7AE700062CA31 /* PasswordManagementItemListModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CC1D7A26A05ECF0062F04E /* PasswordManagementItemListModel.swift */; }; - 4B957AFA2AC7AE700062CA31 /* SuggestionTableCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AABEE6A824AB4B910043105B /* SuggestionTableCellView.swift */; }; - 4B957AFB2AC7AE700062CA31 /* FireViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA6820F025503DA9005ED0D5 /* FireViewModel.swift */; }; - 4B957AFC2AC7AE700062CA31 /* SyncCredentialsAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372BC2A02A4AFA47001D8FD5 /* SyncCredentialsAdapter.swift */; }; - 4B957AFD2AC7AE700062CA31 /* WKUserContentControllerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA0CC69253CC43C0079BC96 /* WKUserContentControllerExtension.swift */; }; - 4B957AFE2AC7AE700062CA31 /* EditableTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE65473271FCD40008D1D63 /* EditableTextView.swift */; }; - 4B957AFF2AC7AE700062CA31 /* TabCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA9FF95C24A1FA1C0039E328 /* TabCollection.swift */; }; - 4B957B002AC7AE700062CA31 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B688B4D9273E6D3B0087BEAF /* MainView.swift */; }; - 4B957B012AC7AE700062CA31 /* Tab+Navigation.swift in Sources */ = {isa = PBXBuildFile; fileRef = B61E2CD4294346C000773D8A /* Tab+Navigation.swift */; }; - 4B957B022AC7AE700062CA31 /* EmailUrlExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B65143D263924B5005B46EB /* EmailUrlExtensions.swift */; }; - 4B957B032AC7AE700062CA31 /* PasswordManagementItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CC1D7C26A05F250062F04E /* PasswordManagementItemModel.swift */; }; - 4B957B042AC7AE700062CA31 /* UpdateController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAD86E51267A0DFF005C11BE /* UpdateController.swift */; }; - 4B957B052AC7AE700062CA31 /* FindInPageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85A0118125AF60E700FA6A0C /* FindInPageModel.swift */; }; - 4B957B062AC7AE700062CA31 /* PseudoFolder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92929826670D2A00AD2C21 /* PseudoFolder.swift */; }; - 4B957B082AC7AE700062CA31 /* PixelDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA44012616B28300DD1EC2 /* PixelDataStore.swift */; }; - 4B957B092AC7AE700062CA31 /* WaitlistStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB00E2A983B24000927DB /* WaitlistStorage.swift */; }; - 4B957B0A2AC7AE700062CA31 /* Pixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A9E45226142B070067D1B9 /* Pixel.swift */; }; - 4B957B0B2AC7AE700062CA31 /* PixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A9E47626146A570067D1B9 /* PixelEvent.swift */; }; - 4B957B0C2AC7AE700062CA31 /* TabBarFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA2CB1342587C29500AA6FBE /* TabBarFooter.swift */; }; - 4B957B0D2AC7AE700062CA31 /* JSAlertViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC111E5294D06290086524F /* JSAlertViewModel.swift */; }; - 4B957B0E2AC7AE700062CA31 /* BookmarksBarCollectionViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5336A286912D40019DBFD /* BookmarksBarCollectionViewItem.swift */; }; - 4B957B0F2AC7AE700062CA31 /* FileDownloadError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C0B23826E742610031CB7F /* FileDownloadError.swift */; }; - 4B957B102AC7AE700062CA31 /* MoreOrLessView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85589E9F27BFE60E0038AD11 /* MoreOrLessView.swift */; }; - 4B957B122AC7AE700062CA31 /* History.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = AAE75278263B046100B973F8 /* History.xcdatamodeld */; }; - 4B957B132AC7AE700062CA31 /* PermissionStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64C853C26944B940048FEBE /* PermissionStore.swift */; }; - 4B957B142AC7AE700062CA31 /* PrivacyIconViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA75A0AD26F3500C0086B667 /* PrivacyIconViewModel.swift */; }; - 4B957B152AC7AE700062CA31 /* ChromiumBookmarksReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB99CF926FE191E001E4761 /* ChromiumBookmarksReader.swift */; }; - 4B957B162AC7AE700062CA31 /* Downloads.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B6C0B23226E71BCD0031CB7F /* Downloads.xcdatamodeld */; }; - 4B957B172AC7AE700062CA31 /* TabPreviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE8B10F258A456C00E81239 /* TabPreviewViewController.swift */; }; - 4B957B182AC7AE700062CA31 /* PreferencesDataClearingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CC53EB27E8A4D10028713D /* PreferencesDataClearingView.swift */; }; - 4B957B192AC7AE700062CA31 /* NSPasteboardExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0135CD2729F1AA00D54834 /* NSPasteboardExtension.swift */; }; - 4B957B1A2AC7AE700062CA31 /* OnboardingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85707F30276A7DCA00DC0649 /* OnboardingViewModel.swift */; }; - 4B957B1B2AC7AE700062CA31 /* ScriptSourceProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85AC3B0425D6B1D800C7D2AA /* ScriptSourceProviding.swift */; }; - 4B957B1C2AC7AE700062CA31 /* CoreDataBookmarkImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB99CF726FE191E001E4761 /* CoreDataBookmarkImporter.swift */; }; - 4B957B1D2AC7AE700062CA31 /* SuggestionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3F895224C18AD500628DDE /* SuggestionViewModel.swift */; }; - 4B957B1E2AC7AE700062CA31 /* BookmarkManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92929926670D2A00AD2C21 /* BookmarkManagedObject.swift */; }; - 4B957B1F2AC7AE700062CA31 /* CSVLoginExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B723DFD26B0002B00E14D75 /* CSVLoginExporter.swift */; }; - 4B957B202AC7AE700062CA31 /* NSAttributedStringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85C48CCB278D808F00D3263E /* NSAttributedStringExtension.swift */; }; - 4B957B212AC7AE700062CA31 /* AnimationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA7EB6E427E7D6DC00036718 /* AnimationView.swift */; }; - 4B957B222AC7AE700062CA31 /* NSRectExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85625999269CA0A600EE44BC /* NSRectExtension.swift */; }; - 4B957B232AC7AE700062CA31 /* WaitlistRootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB01A2A983B24000927DB /* WaitlistRootView.swift */; }; - 4B957B242AC7AE700062CA31 /* YoutubeOverlayUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31F28C4E28C8EEC500119F70 /* YoutubeOverlayUserScript.swift */; }; - 4B957B252AC7AE700062CA31 /* DictionaryExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6040855274B830F00680351 /* DictionaryExtension.swift */; }; - 4B957B262AC7AE700062CA31 /* Publishers.NestedObjectChanges.swift in Sources */ = {isa = PBXBuildFile; fileRef = B684592625C93C0500DC17B6 /* Publishers.NestedObjectChanges.swift */; }; - 4B957B272AC7AE700062CA31 /* MenuItemSelectors.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA06E52913F39400225DE2 /* MenuItemSelectors.swift */; }; - 4B957B282AC7AE700062CA31 /* FaviconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85589E9927BFE3C30038AD11 /* FaviconView.swift */; }; - 4B957B292AC7AE700062CA31 /* OnboardingFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85707F2B276A364E00DC0649 /* OnboardingFlow.swift */; }; - 4B957B2A2AC7AE700062CA31 /* PasswordManagementLoginModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE6547C271FCD4D008D1D63 /* PasswordManagementLoginModel.swift */; }; - 4B957B2B2AC7AE700062CA31 /* TabViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA9FF95A24A1EFC20039E328 /* TabViewModel.swift */; }; - 4B957B2C2AC7AE700062CA31 /* TabDragAndDropManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA9E9A5D25A4867200D1959D /* TabDragAndDropManager.swift */; }; - 4B957B2D2AC7AE700062CA31 /* NSNotificationName+Favicons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBD3BFF285ACE090047A89D /* NSNotificationName+Favicons.swift */; }; - 4B957B2E2AC7AE700062CA31 /* PinningManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0DB5E428BD9D08007DD239 /* PinningManager.swift */; }; - 4B957B2F2AC7AE700062CA31 /* SyncMetadataDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373D9B4729EEAC1B00381FDD /* SyncMetadataDatabase.swift */; }; - 4B957B302AC7AE700062CA31 /* TabCollectionViewModel+NSSecureCoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68458BF25C7E9E000DC17B6 /* TabCollectionViewModel+NSSecureCoding.swift */; }; - 4B957B312AC7AE700062CA31 /* StringExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA8EDF2624923EC70071C2E8 /* StringExtension.swift */; }; - 4B957B322AC7AE700062CA31 /* EmailManagerRequestDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85378DA1274E7F25007C5CBF /* EmailManagerRequestDelegate.swift */; }; - 4B957B332AC7AE700062CA31 /* ApplicationVersionReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D43EB35292ACE690065E5D6 /* ApplicationVersionReader.swift */; }; - 4B957B342AC7AE700062CA31 /* BookmarksBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BD18EFF283F0BC500058124 /* BookmarksBarViewController.swift */; }; - 4B957B352AC7AE700062CA31 /* PreferencesAutofillView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 379DE4BC27EA31AC002CC3DE /* PreferencesAutofillView.swift */; }; - 4B957B362AC7AE700062CA31 /* BurnerHomePageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DCFBC8929ADF32B00313531 /* BurnerHomePageView.swift */; }; - 4B957B372AC7AE700062CA31 /* UserText+PasswordManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 858A797E26A79EAA00A75A42 /* UserText+PasswordManager.swift */; }; - 4B957B382AC7AE700062CA31 /* LoadingProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B693954026F04BE80015B914 /* LoadingProgressView.swift */; }; - 4B957B392AC7AE700062CA31 /* StatisticsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69B50362726A12000758A2B /* StatisticsStore.swift */; }; - 4B957B3A2AC7AE700062CA31 /* BWInstallationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDEE8C28FC14760092FAA6 /* BWInstallationService.swift */; }; - 4B957B3B2AC7AE700062CA31 /* BookmarksBarPromptPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 859F30632A72A7BB00C20372 /* BookmarksBarPromptPopover.swift */; }; - 4B957B3C2AC7AE700062CA31 /* NetworkProtectionInvitePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606F2A0B29FA00BCD287 /* NetworkProtectionInvitePresenter.swift */; }; - 4B957B3D2AC7AE700062CA31 /* ColorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B693954626F04BEA0015B914 /* ColorView.swift */; }; - 4B957B3E2AC7AE700062CA31 /* RecentlyClosedCacheItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA5C1DD2285A217F0089850C /* RecentlyClosedCacheItem.swift */; }; - 4B957B3F2AC7AE700062CA31 /* PopupBlockedPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BBF17327475B15004F850E /* PopupBlockedPopover.swift */; }; - 4B957B402AC7AE700062CA31 /* SaveCredentialsPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85890639267BCD8E00D23B0D /* SaveCredentialsPopover.swift */; }; - 4B957B412AC7AE700062CA31 /* LegacyBookmarksStoreMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 987799F02999993C005D8EB6 /* LegacyBookmarksStoreMigration.swift */; }; - 4B957B422AC7AE700062CA31 /* QuartzIdleStateProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B379C1427BD91E3008A968E /* QuartzIdleStateProvider.swift */; }; - 4B957B432AC7AE700062CA31 /* DuckPlayerPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37F19A6628E1B43200740DC6 /* DuckPlayerPreferences.swift */; }; - 4B957B442AC7AE700062CA31 /* DownloadViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C0B22D26E61CE70031CB7F /* DownloadViewModel.swift */; }; - 4B957B452AC7AE700062CA31 /* BookmarkHTMLReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 373A1AA7283ED1B900586521 /* BookmarkHTMLReader.swift */; }; - 4B957B462AC7AE700062CA31 /* Tab+NSSecureCoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68458B725C7E8B200DC17B6 /* Tab+NSSecureCoding.swift */; }; - 4B957B472AC7AE700062CA31 /* NSNotificationName+EmailManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85378D9F274E6F42007C5CBF /* NSNotificationName+EmailManager.swift */; }; - 4B957B482AC7AE700062CA31 /* MouseOverButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B693954926F04BEB0015B914 /* MouseOverButton.swift */; }; - 4B957B492AC7AE700062CA31 /* FireInfoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA61C0CF2722159B00E6B681 /* FireInfoViewController.swift */; }; - 4B957B4A2AC7AE700062CA31 /* LoginItem+NetworkProtection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9AE8682AA76CDC0026E7DC /* LoginItem+NetworkProtection.swift */; }; - 4B957B4B2AC7AE700062CA31 /* PermissionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64C85412694590B0048FEBE /* PermissionButton.swift */; }; - 4B957B4C2AC7AE700062CA31 /* MoreOptionsMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAA0CC462533833C0079BC96 /* MoreOptionsMenu.swift */; }; - 4B957B4D2AC7AE700062CA31 /* PermissionAuthorizationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64C84E22692DC9F0048FEBE /* PermissionAuthorizationViewController.swift */; }; - 4B957B4E2AC7AE700062CA31 /* BookmarkNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92929326670D2A00AD2C21 /* BookmarkNode.swift */; }; - 4B957B4F2AC7AE700062CA31 /* LongPressButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = B693954426F04BE90015B914 /* LongPressButton.swift */; }; - 4B957B502AC7AE700062CA31 /* CoreDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6085D052743905F00A9C456 /* CoreDataStore.swift */; }; - 4B957B512AC7AE700062CA31 /* BundleExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6106B9D26A565DA0013B453 /* BundleExtension.swift */; }; - 4B957B522AC7AE700062CA31 /* NSOpenPanelExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0511DF262CAA8600F6079C /* NSOpenPanelExtensions.swift */; }; - 4B957B532AC7AE700062CA31 /* FirePopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAE99B8827088A19008B6BD9 /* FirePopover.swift */; }; - 4B957B552AC7AE700062CA31 /* NetworkProtectionOnboardingMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B05829D2A812AC000AC3F7C /* NetworkProtectionOnboardingMenu.swift */; }; - 4B957B562AC7AE700062CA31 /* VariantManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69B50372726A12000758A2B /* VariantManager.swift */; }; - 4B957B572AC7AE700062CA31 /* ApplicationDockMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA97BF4525135DD30014931A /* ApplicationDockMenu.swift */; }; - 4B957B582AC7AE700062CA31 /* SaveIdentityViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8A4DFE27C83B29005F40E8 /* SaveIdentityViewController.swift */; }; - 4B957B592AC7AE700062CA31 /* AppLauncher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAD7A6E2A1D3E1F002A24E7 /* AppLauncher.swift */; }; - 4B957B5A2AC7AE700062CA31 /* FileStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BA1A69A258B076900F6F690 /* FileStore.swift */; }; - 4B957B5B2AC7AE700062CA31 /* PixelArguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A9E47E26146A800067D1B9 /* PixelArguments.swift */; }; - 4B957B5C2AC7AE700062CA31 /* PinnedTabsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BF3F1E286F0A7A00BD9014 /* PinnedTabsViewModel.swift */; }; - 4B957B5D2AC7AE700062CA31 /* BookmarkList.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC5E4CF25D6A709007F5990 /* BookmarkList.swift */; }; - 4B957B5E2AC7AE700062CA31 /* NEOnDemandRuleExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B602E81C2A1E25B0006D261F /* NEOnDemandRuleExtension.swift */; }; - 4B957B5F2AC7AE700062CA31 /* BookmarkTableRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292C92667123700AD2C21 /* BookmarkTableRowView.swift */; }; - 4B957B602AC7AE700062CA31 /* FavoritesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85589E9327BFE1E70038AD11 /* FavoritesView.swift */; }; - 4B957B612AC7AE700062CA31 /* HomePage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85AC7ADA27BD628400FFB69B /* HomePage.swift */; }; - 4B957B622AC7AE700062CA31 /* RoundedSelectionRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B0511B3262CAA5A00F6079C /* RoundedSelectionRowView.swift */; }; - 4B957B632AC7AE700062CA31 /* LocalStatisticsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69B50392726A12500758A2B /* LocalStatisticsStore.swift */; }; - 4B957B642AC7AE700062CA31 /* BackForwardListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B689ECD426C247DB006FB0C5 /* BackForwardListItem.swift */; }; - 4B957B672AC7AE700062CA31 /* AtbAndVariantCleanup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69B50562727D16900758A2B /* AtbAndVariantCleanup.swift */; }; - 4B957B692AC7AE700062CA31 /* FeedbackWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3D531427A1ED9300074EC1 /* FeedbackWindow.swift */; }; - 4B957B6A2AC7AE700062CA31 /* WorkspaceProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6685E3E29A606190043D2EE /* WorkspaceProtocol.swift */; }; - 4B957B6B2AC7AE700062CA31 /* RecentlyVisitedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85F0FF1227CFAB04001C7C6E /* RecentlyVisitedView.swift */; }; - 4B957B6C2AC7AE700062CA31 /* MouseOverAnimationButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA7EB6DE27E7C57D00036718 /* MouseOverAnimationButton.swift */; }; - 4B957B6D2AC7AE700062CA31 /* TabBarScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA7412B624D1687000D22FE0 /* TabBarScrollView.swift */; }; - 4B957B6E2AC7AE700062CA31 /* BookmarkListTreeControllerDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292D82667124B00AD2C21 /* BookmarkListTreeControllerDataSource.swift */; }; - 4B957B6F2AC7AE700062CA31 /* AddressBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 14D9B8F924F7E089000D4D13 /* AddressBarViewController.swift */; }; - 4B957B702AC7AE700062CA31 /* Permissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65536A52685B82B00085A79 /* Permissions.swift */; }; - 4B957B712AC7AE700062CA31 /* TabPreviewWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC82C5F258B6CB5009B6B42 /* TabPreviewWindowController.swift */; }; - 4B957B722AC7AE700062CA31 /* NSSizeExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC5E4E325D6BA9C007F5990 /* NSSizeExtension.swift */; }; - 4B957B732AC7AE700062CA31 /* Fire.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA6820EA25503D6A005ED0D5 /* Fire.swift */; }; - 4B957B742AC7AE700062CA31 /* SyncBookmarksAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37445F9B2A1569F00029F789 /* SyncBookmarksAdapter.swift */; }; - 4B957B752AC7AE700062CA31 /* RandomAccessCollectionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AAAC3D26048F690029438D /* RandomAccessCollectionExtension.swift */; }; - 4B957B762AC7AE700062CA31 /* NSOutlineViewExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292AE26670F5300AD2C21 /* NSOutlineViewExtensions.swift */; }; - 4B957B772AC7AE700062CA31 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA585D81248FD31100E9A3E2 /* AppDelegate.swift */; }; - 4B957B782AC7AE700062CA31 /* ContentOverlayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B1E819D27C8874900FF0E60 /* ContentOverlayViewController.swift */; }; - 4B957B792AC7AE700062CA31 /* ContentBlockingTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D574B12947224C008ED1B6 /* ContentBlockingTabExtension.swift */; }; - 4B957B7A2AC7AE700062CA31 /* OnboardingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85B7184B27677C6500B4277F /* OnboardingViewController.swift */; }; - 4B957B7B2AC7AE700062CA31 /* DeviceAuthenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B379C1D27BDB7FF008A968E /* DeviceAuthenticator.swift */; }; - 4B957B7C2AC7AE700062CA31 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFE95512A9DF1CE0081ABE9 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift */; }; - 4B957B7D2AC7AE700062CA31 /* TabBarCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1456D6E024EFCBC300775049 /* TabBarCollectionView.swift */; }; - 4B957B7E2AC7AE700062CA31 /* NetworkProtection+ConvenienceInitializers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60692A0B29FA00BCD287 /* NetworkProtection+ConvenienceInitializers.swift */; }; - 4B957B7F2AC7AE700062CA31 /* NavigationActionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66B9C5B29A5EBAD0010E8F3 /* NavigationActionExtension.swift */; }; - 4B957B802AC7AE700062CA31 /* NSAlertExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85308E24267FC9F2001ABD76 /* NSAlertExtension.swift */; }; - 4B957B812AC7AE700062CA31 /* ThirdPartyBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B59024726B3673600489384 /* ThirdPartyBrowser.swift */; }; - 4B957B822AC7AE700062CA31 /* SearchNonexistentDomainNavigationResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B60C6F7629B0E286007BFAA8 /* SearchNonexistentDomainNavigationResponder.swift */; }; - 4B957B832AC7AE700062CA31 /* CircularProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65E6B9D26D9EC0800095F96 /* CircularProgressView.swift */; }; - 4B957B842AC7AE700062CA31 /* SuggestionContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = AABEE69B24A902BB0043105B /* SuggestionContainer.swift */; }; - 4B957B852AC7AE700062CA31 /* FindInPageTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C00ECC292F89D9009C73A6 /* FindInPageTabExtension.swift */; }; - 4B957B862AC7AE700062CA31 /* HomePageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85589E7D27BBB8630038AD11 /* HomePageViewController.swift */; }; - 4B957B882AC7AE700062CA31 /* OperatingSystemVersionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A9E46A2614618A0067D1B9 /* OperatingSystemVersionExtension.swift */; }; - 4B957B892AC7AE700062CA31 /* ToggleableScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BDFA4AD27BF19E500648192 /* ToggleableScrollView.swift */; }; - 4B957B8A2AC7AE700062CA31 /* TabCleanupPreparer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D36F4232A3B85C50052B527 /* TabCleanupPreparer.swift */; }; - 4B957B8B2AC7AE700062CA31 /* NetworkProtectionOptionKeyExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605F2A0B29FA00BCD287 /* NetworkProtectionOptionKeyExtension.swift */; }; - 4B957B8C2AC7AE700062CA31 /* UserScripts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85AC3AEE25D5CE9800C7D2AA /* UserScripts.swift */; }; - 4B957B8D2AC7AE700062CA31 /* NSWorkspaceExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B643BF1327ABF772000BACEC /* NSWorkspaceExtension.swift */; }; - 4B957B8E2AC7AE700062CA31 /* AutofillTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C00ECA292F839D009C73A6 /* AutofillTabExtension.swift */; }; - 4B957B8F2AC7AE700062CA31 /* Assertions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E319372953446000DD3BCF /* Assertions.swift */; }; - 4B957B902AC7AE700062CA31 /* BookmarkViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAB549DE25DAB8F80058460B /* BookmarkViewModel.swift */; }; - 4B957B912AC7AE700062CA31 /* DaxSpeech.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85707F27276A34D900DC0649 /* DaxSpeech.swift */; }; - 4B957B922AC7AE700062CA31 /* DuckURLSchemeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31F28C5228C8EECA00119F70 /* DuckURLSchemeHandler.swift */; }; - 4B957B932AC7AE700062CA31 /* FirePopoverViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA13DCB3271480B0006D48D3 /* FirePopoverViewModel.swift */; }; - 4B957B942AC7AE700062CA31 /* BWCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D43EB37292B636E0065E5D6 /* BWCommand.swift */; }; - 4B957B952AC7AE700062CA31 /* NSColorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41D174025CB131900472416 /* NSColorExtension.swift */; }; - 4B957B972AC7AE700062CA31 /* AddressBarButtonsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC5E4F525D6BF2C007F5990 /* AddressBarButtonsViewController.swift */; }; - 4B957B982AC7AE700062CA31 /* BWError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1DDF076028F815AD00EDFBE3 /* BWError.swift */; }; - 4B957B9A2AC7AE700062CA31 /* PixelDataRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68C92C32750EF76002AC6B0 /* PixelDataRecord.swift */; }; - 4B957B9B2AC7AE700062CA31 /* PageObserverUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 853014D525E671A000FB8205 /* PageObserverUserScript.swift */; }; - 4B957B9C2AC7AE700062CA31 /* SecureVaultErrorReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B642738127B65BAC0005DFD1 /* SecureVaultErrorReporter.swift */; }; - 4B957B9D2AC7AE700062CA31 /* NSImageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B139AFC26B60BD800894F82 /* NSImageExtensions.swift */; }; - 4B957B9E2AC7AE700062CA31 /* WaitlistKeychainStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9DB00F2A983B24000927DB /* WaitlistKeychainStorage.swift */; }; - 4B957B9F2AC7AE700062CA31 /* PasswordManagementViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85625995269C953C00EE44BC /* PasswordManagementViewController.swift */; }; - 4B957BA02AC7AE700062CA31 /* ImportedBookmarks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BB99CFA26FE191E001E4761 /* ImportedBookmarks.swift */; }; - 4B957BA12AC7AE700062CA31 /* UserDefaults+NetworkProtectionShared.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B934C402A866DD400FC8F9C /* UserDefaults+NetworkProtectionShared.swift */; }; - 4B957BA22AC7AE700062CA31 /* NavigationActionPolicyExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B626A75929921FAA00053070 /* NavigationActionPolicyExtension.swift */; }; - 4B957BA32AC7AE700062CA31 /* CIImageExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B603FD9D2A02712E00F3FCA9 /* CIImageExtension.swift */; }; - 4B957BA42AC7AE700062CA31 /* NSMenuExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA6EF9B2250785D5004754E6 /* NSMenuExtension.swift */; }; - 4B957BA52AC7AE700062CA31 /* MainWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA7412B424D1536B00D22FE0 /* MainWindowController.swift */; }; - 4B957BA62AC7AE700062CA31 /* Tab.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA9FF95824A1ECF20039E328 /* Tab.swift */; }; - 4B957BA72AC7AE700062CA31 /* ConnectBitwardenView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBDEE8E28FC14760092FAA6 /* ConnectBitwardenView.swift */; }; - 4B957BA82AC7AE700062CA31 /* DispatchQueueExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B63D467025BFA6C100874977 /* DispatchQueueExtensions.swift */; }; - 4B957BA92AC7AE700062CA31 /* BookmarksBarAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 850E8DFA2A6FEC5E00691187 /* BookmarksBarAppearance.swift */; }; - 4B957BAA2AC7AE700062CA31 /* PermissionAuthorizationPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = B64C84EA2692DD650048FEBE /* PermissionAuthorizationPopover.swift */; }; - 4B957BAB2AC7AE700062CA31 /* PopoverMessageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85378D9D274E664C007C5CBF /* PopoverMessageViewController.swift */; }; - 4B957BAC2AC7AE700062CA31 /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA6FFB4524DC3B5A0028F4D0 /* WebView.swift */; }; - 4B957BAD2AC7AE700062CA31 /* ShadowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B693954226F04BE90015B914 /* ShadowView.swift */; }; - 4B957BAE2AC7AE700062CA31 /* FeedbackSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3D531C27A2F58F00074EC1 /* FeedbackSender.swift */; }; - 4B957BAF2AC7AE700062CA31 /* TabExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BDDA002942389000F68088 /* TabExtensions.swift */; }; - 4B957BB02AC7AE700062CA31 /* TabBarViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA7412B024D0B3AC00D22FE0 /* TabBarViewItem.swift */; }; - 4B957BB12AC7AE700062CA31 /* NSWindow+Toast.swift in Sources */ = {isa = PBXBuildFile; fileRef = 856C98D42570116900A22F1F /* NSWindow+Toast.swift */; }; - 4B957BB22AC7AE700062CA31 /* AutoconsentUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = B31055BC27A1BA1D001AC618 /* AutoconsentUserScript.swift */; }; - 4B957BB32AC7AE700062CA31 /* BookmarksExporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 859E7D6A27453BF3009C2B69 /* BookmarksExporter.swift */; }; - 4B957BB42AC7AE700062CA31 /* NetworkProtectionAppEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2DDCF72A93A8BB0039D884 /* NetworkProtectionAppEvents.swift */; }; - 4B957BB52AC7AE700062CA31 /* FirefoxDataImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B5FF67726B602B100D42879 /* FirefoxDataImporter.swift */; }; - 4B957BB62AC7AE700062CA31 /* PreferencesGeneralView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AFCE8A27DB69BC00471A10 /* PreferencesGeneralView.swift */; }; - 4B957BB72AC7AE700062CA31 /* PinnedTabsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37BF3F1F286F0A7A00BD9014 /* PinnedTabsView.swift */; }; - 4B957BB92AC7AE700062CA31 /* SyncErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37FD78102A29EBD100B36DB1 /* SyncErrorHandler.swift */; }; - 4B957BBA2AC7AE700062CA31 /* URLExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA8EDF2324923E980071C2E8 /* URLExtension.swift */; }; - 4B957BBB2AC7AE700062CA31 /* Tab+UIDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B634DBDE293C8F7F00C3C99E /* Tab+UIDelegate.swift */; }; - 4B957BBD2AC7AE700062CA31 /* NSStoryboardExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE0DF0426781961006337B7 /* NSStoryboardExtension.swift */; }; - 4B957BBE2AC7AE700062CA31 /* PreferencesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37AFCE8027DA2CA600471A10 /* PreferencesViewController.swift */; }; - 4B957BBF2AC7AE700062CA31 /* FireproofDomains.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B02198125E05FAC00ED7DEA /* FireproofDomains.swift */; }; - 4B957BC02AC7AE700062CA31 /* Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B677440255DBEEA00025BD8 /* Database.swift */; }; - 4B957BC12AC7AE700062CA31 /* HorizontallyCenteredLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE5336D286915A10019DBFD /* HorizontallyCenteredLayout.swift */; }; - 4B957BC22AC7AE700062CA31 /* BookmarksOutlineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92928526670D1600AD2C21 /* BookmarksOutlineView.swift */; }; - 4B957BC32AC7AE700062CA31 /* CountryList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE65482271FCD53008D1D63 /* CountryList.swift */; }; - 4B957BC42AC7AE700062CA31 /* PreferencesSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CD54C427F2FDD100F1F7B9 /* PreferencesSection.swift */; }; - 4B957BC52AC7AE700062CA31 /* NetworkProtectionNavBarButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60652A0B29FA00BCD287 /* NetworkProtectionNavBarButtonModel.swift */; }; - 4B957BC62AC7AE700062CA31 /* AutoconsentManagement.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD23FD2C2886A81D007F6985 /* AutoconsentManagement.swift */; }; - 4B957BC72AC7AE700062CA31 /* UserText+NetworkProtection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D60D22A0C84F700BCD287 /* UserText+NetworkProtection.swift */; }; - 4B957BC82AC7AE700062CA31 /* WebViewContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B2400D28083B49001B8F3A /* WebViewContainerView.swift */; }; - 4B957BC92AC7AE700062CA31 /* BookmarkStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC5E4D625D6A710007F5990 /* BookmarkStore.swift */; }; - 4B957BCA2AC7AE700062CA31 /* PrivacyDashboardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6FA893E269C424500588ECD /* PrivacyDashboardViewController.swift */; }; - 4B957BCB2AC7AE700062CA31 /* PreferencesAppearanceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D2771427E870D4003365FD /* PreferencesAppearanceView.swift */; }; - 4B957BCC2AC7AE700062CA31 /* NSMenuItemExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA72D5FD25FFF94E00C77619 /* NSMenuItemExtension.swift */; }; - 4B957BCD2AC7AE700062CA31 /* ContiguousBytesExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BA1A6C1258B0A1300F6F690 /* ContiguousBytesExtension.swift */; }; - 4B957BCE2AC7AE700062CA31 /* AdjacentItemEnumerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37534CA62811988E002621E7 /* AdjacentItemEnumerator.swift */; }; - 4B957BCF2AC7AE700062CA31 /* BookmarkDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 987799F52999996B005D8EB6 /* BookmarkDatabase.swift */; }; - 4B957BD02AC7AE700062CA31 /* ChromiumKeychainPrompt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BE53373286E39F10019DBFD /* ChromiumKeychainPrompt.swift */; }; - 4B957BD12AC7AE700062CA31 /* WKProcessPool+GeolocationProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6553691268440D700085A79 /* WKProcessPool+GeolocationProvider.swift */; }; - 4B957BD22AC7AE700062CA31 /* RecentlyClosedMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA5C1DD0285A154E0089850C /* RecentlyClosedMenu.swift */; }; - 4B957BD52AC7AE700062CA31 /* QuickLookUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B6F7128029F681EB00594A45 /* QuickLookUI.framework */; }; - 4B957BD62AC7AE700062CA31 /* LoginItems in Frameworks */ = {isa = PBXBuildFile; productRef = 4B95793F2AC7AE700062CA31 /* LoginItems */; }; - 4B957BD72AC7AE700062CA31 /* NetworkProtection in Frameworks */ = {isa = PBXBuildFile; productRef = 4B95793E2AC7AE700062CA31 /* NetworkProtection */; }; - 4B957BD82AC7AE700062CA31 /* BrowserServicesKit in Frameworks */ = {isa = PBXBuildFile; productRef = 4B95792B2AC7AE700062CA31 /* BrowserServicesKit */; }; - 4B957BDA2AC7AE700062CA31 /* Bookmarks in Frameworks */ = {isa = PBXBuildFile; productRef = 4B9579342AC7AE700062CA31 /* Bookmarks */; }; - 4B957BDB2AC7AE700062CA31 /* ContentBlocking in Frameworks */ = {isa = PBXBuildFile; productRef = 4B95792E2AC7AE700062CA31 /* ContentBlocking */; }; - 4B957BDC2AC7AE700062CA31 /* SwiftUIExtensions in Frameworks */ = {isa = PBXBuildFile; productRef = 4B9579372AC7AE700062CA31 /* SwiftUIExtensions */; }; - 4B957BDD2AC7AE700062CA31 /* UserScript in Frameworks */ = {isa = PBXBuildFile; productRef = 4B9579302AC7AE700062CA31 /* UserScript */; }; - 4B957BDE2AC7AE700062CA31 /* Configuration in Frameworks */ = {isa = PBXBuildFile; productRef = 4B9579322AC7AE700062CA31 /* Configuration */; }; - 4B957BE22AC7AE700062CA31 /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = 4B9579292AC7AE700062CA31 /* Sparkle */; }; - 4B957BE32AC7AE700062CA31 /* Navigation in Frameworks */ = {isa = PBXBuildFile; productRef = 4B9579332AC7AE700062CA31 /* Navigation */; }; - 4B957BE42AC7AE700062CA31 /* DDGSync in Frameworks */ = {isa = PBXBuildFile; productRef = 4B9579352AC7AE700062CA31 /* DDGSync */; }; - 4B957BE52AC7AE700062CA31 /* OpenSSL in Frameworks */ = {isa = PBXBuildFile; productRef = 4B9579382AC7AE700062CA31 /* OpenSSL */; }; - 4B957BE62AC7AE700062CA31 /* PrivacyDashboard in Frameworks */ = {isa = PBXBuildFile; productRef = 4B95792F2AC7AE700062CA31 /* PrivacyDashboard */; }; - 4B957BE72AC7AE700062CA31 /* SyncDataProviders in Frameworks */ = {isa = PBXBuildFile; productRef = 4B95793C2AC7AE700062CA31 /* SyncDataProviders */; }; - 4B957BE82AC7AE700062CA31 /* SyncUI in Frameworks */ = {isa = PBXBuildFile; productRef = 4B9579362AC7AE700062CA31 /* SyncUI */; }; - 4B957BE92AC7AE700062CA31 /* NetworkProtectionUI in Frameworks */ = {isa = PBXBuildFile; productRef = 4B95793D2AC7AE700062CA31 /* NetworkProtectionUI */; }; - 4B957BEB2AC7AE700062CA31 /* Persistence in Frameworks */ = {isa = PBXBuildFile; productRef = 4B9579312AC7AE700062CA31 /* Persistence */; }; - 4B957BEF2AC7AE700062CA31 /* CrashReports.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA693E5D2696E5B90007BB78 /* CrashReports.storyboard */; }; - 4B957BF02AC7AE700062CA31 /* trackerData.json in Resources */ = {isa = PBXBuildFile; fileRef = 9833913027AAA4B500DAF119 /* trackerData.json */; }; - 4B957BF12AC7AE700062CA31 /* dark-shield-dot-mouse-over.json in Resources */ = {isa = PBXBuildFile; fileRef = AA7EB6EC27E880B600036718 /* dark-shield-dot-mouse-over.json */; }; - 4B957BF22AC7AE700062CA31 /* 01_Fire_really_small.json in Resources */ = {isa = PBXBuildFile; fileRef = 8511E18325F82B34002F516B /* 01_Fire_really_small.json */; }; - 4B957BF32AC7AE700062CA31 /* Onboarding.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 85B7184927677C2D00B4277F /* Onboarding.storyboard */; }; - 4B957BF42AC7AE700062CA31 /* FireproofDomains.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4B0511AD262CAA5A00F6079C /* FireproofDomains.storyboard */; }; - 4B957BF52AC7AE700062CA31 /* clickToLoadConfig.json in Resources */ = {isa = PBXBuildFile; fileRef = EA47767F272A21B700419EDA /* clickToLoadConfig.json */; }; - 4B957BF72AC7AE700062CA31 /* dark-shield.json in Resources */ = {isa = PBXBuildFile; fileRef = AA34396F2754D4E900B241FA /* dark-shield.json */; }; - 4B957BF82AC7AE700062CA31 /* BookmarksBarPromptAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 859F30662A72B38500C20372 /* BookmarksBarPromptAssets.xcassets */; }; - 4B957BF92AC7AE700062CA31 /* dark-shield-mouse-over.json in Resources */ = {isa = PBXBuildFile; fileRef = AA7EB6EA27E880AE00036718 /* dark-shield-mouse-over.json */; }; - 4B957BFA2AC7AE700062CA31 /* autoconsent-bundle.js in Resources */ = {isa = PBXBuildFile; fileRef = B31055C327A1BA1D001AC618 /* autoconsent-bundle.js */; }; - 4B957BFB2AC7AE700062CA31 /* ContentOverlay.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B1E819C27C8874900FF0E60 /* ContentOverlay.storyboard */; }; - 4B957BFC2AC7AE700062CA31 /* FindInPage.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 85A0117325AF2EDF00FA6A0C /* FindInPage.storyboard */; }; - 4B957BFD2AC7AE700062CA31 /* JSAlert.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = EEC111E3294D06020086524F /* JSAlert.storyboard */; }; - 4B957C002AC7AE700062CA31 /* userscript.js in Resources */ = {isa = PBXBuildFile; fileRef = B31055BE27A1BA1D001AC618 /* userscript.js */; }; - 4B957C012AC7AE700062CA31 /* fb-tds.json in Resources */ = {isa = PBXBuildFile; fileRef = EA4617EF273A28A700F110A2 /* fb-tds.json */; }; - 4B957C032AC7AE700062CA31 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = AA68C3D62490F821001B8783 /* README.md */; }; - 4B957C042AC7AE700062CA31 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AA585D85248FD31400E9A3E2 /* Assets.xcassets */; }; - 4B957C052AC7AE700062CA31 /* NavigationBar.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 85589E8C27BBBB870038AD11 /* NavigationBar.storyboard */; }; - 4B957C062AC7AE700062CA31 /* FirePopoverCollectionViewHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = AAE246F5270A3D3000BEEAEE /* FirePopoverCollectionViewHeader.xib */; }; - 4B957C072AC7AE700062CA31 /* TabBar.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA80EC7B256C46AA007083E7 /* TabBar.storyboard */; }; - 4B957C082AC7AE700062CA31 /* shield-dot.json in Resources */ = {isa = PBXBuildFile; fileRef = AA34396B2754D4E300B241FA /* shield-dot.json */; }; - 4B957C0B2AC7AE700062CA31 /* BookmarksBarCollectionViewItem.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BE53369286912D40019DBFD /* BookmarksBarCollectionViewItem.xib */; }; - 4B957C0C2AC7AE700062CA31 /* PrivacyDashboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B6FA893C269C423100588ECD /* PrivacyDashboard.storyboard */; }; - 4B957C0D2AC7AE700062CA31 /* shield.json in Resources */ = {isa = PBXBuildFile; fileRef = AA34396A2754D4E200B241FA /* shield.json */; }; - 4B957C0E2AC7AE700062CA31 /* TabBarViewItem.xib in Resources */ = {isa = PBXBuildFile; fileRef = AA7412B124D0B3AC00D22FE0 /* TabBarViewItem.xib */; }; - 4B957C102AC7AE700062CA31 /* httpsMobileV2FalsePositives.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B67742A255DBEB800025BD8 /* httpsMobileV2FalsePositives.json */; }; - 4B957C112AC7AE700062CA31 /* BookmarksBar.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4BD18F04283F151F00058124 /* BookmarksBar.storyboard */; }; - 4B957C122AC7AE700062CA31 /* trackers-1.json in Resources */ = {isa = PBXBuildFile; fileRef = AA3439732754D55100B241FA /* trackers-1.json */; }; - 4B957C132AC7AE700062CA31 /* dark-trackers-1.json in Resources */ = {isa = PBXBuildFile; fileRef = AA3439762754D55100B241FA /* dark-trackers-1.json */; }; - 4B957C142AC7AE700062CA31 /* Feedback.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA3863C427A1E28F00749AB5 /* Feedback.storyboard */; }; - 4B957C182AC7AE700062CA31 /* shield-mouse-over.json in Resources */ = {isa = PBXBuildFile; fileRef = AA7EB6E627E8809D00036718 /* shield-mouse-over.json */; }; - 4B957C1A2AC7AE700062CA31 /* PermissionAuthorization.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B64C84DD2692D7400048FEBE /* PermissionAuthorization.storyboard */; }; - 4B957C1B2AC7AE700062CA31 /* dark-trackers-3.json in Resources */ = {isa = PBXBuildFile; fileRef = AA3439772754D55100B241FA /* dark-trackers-3.json */; }; - 4B957C1C2AC7AE700062CA31 /* dark-trackers-2.json in Resources */ = {isa = PBXBuildFile; fileRef = AA3439722754D55100B241FA /* dark-trackers-2.json */; }; - 4B957C1D2AC7AE700062CA31 /* Fire.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AAB7320626DD0C37002FACF9 /* Fire.storyboard */; }; - 4B957C1F2AC7AE700062CA31 /* social_images in Resources */ = {isa = PBXBuildFile; fileRef = EA18D1C9272F0DC8006DC101 /* social_images */; }; - 4B957C202AC7AE700062CA31 /* shield-dot-mouse-over.json in Resources */ = {isa = PBXBuildFile; fileRef = AA7EB6E827E880A600036718 /* shield-dot-mouse-over.json */; }; - 4B957C222AC7AE700062CA31 /* fb-sdk.js in Resources */ = {isa = PBXBuildFile; fileRef = EAC80DDF271F6C0100BBF02D /* fb-sdk.js */; }; - 4B957C232AC7AE700062CA31 /* PasswordManager.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 85625993269C8F9600EE44BC /* PasswordManager.storyboard */; }; - 4B957C242AC7AE700062CA31 /* dark-flame-mouse-over.json in Resources */ = {isa = PBXBuildFile; fileRef = AA7EB6E127E7D05500036718 /* dark-flame-mouse-over.json */; }; - 4B957C252AC7AE700062CA31 /* flame-mouse-over.json in Resources */ = {isa = PBXBuildFile; fileRef = AA7EB6E027E7D05500036718 /* flame-mouse-over.json */; }; - 4B957C262AC7AE700062CA31 /* httpsMobileV2Bloom.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4B677428255DBEB800025BD8 /* httpsMobileV2Bloom.bin */; }; - 4B957C272AC7AE700062CA31 /* trackers-3.json in Resources */ = {isa = PBXBuildFile; fileRef = AA3439752754D55100B241FA /* trackers-3.json */; }; - 4B957C282AC7AE700062CA31 /* macos-config.json in Resources */ = {isa = PBXBuildFile; fileRef = 026ADE1326C3010C002518EE /* macos-config.json */; }; - 4B957C292AC7AE700062CA31 /* httpsMobileV2BloomSpec.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B677427255DBEB800025BD8 /* httpsMobileV2BloomSpec.json */; }; - 4B957C2A2AC7AE700062CA31 /* TabBarFooter.xib in Resources */ = {isa = PBXBuildFile; fileRef = AA2CB12C2587BB5600AA6FBE /* TabBarFooter.xib */; }; - 4B957C2C2AC7AE700062CA31 /* FirePopoverCollectionViewItem.xib in Resources */ = {isa = PBXBuildFile; fileRef = AAE246F22709EF3B00BEEAEE /* FirePopoverCollectionViewItem.xib */; }; - 4B957C2D2AC7AE700062CA31 /* ProximaNova-Bold-webfont.woff2 in Resources */ = {isa = PBXBuildFile; fileRef = EAA29AE7278D2E43007070CF /* ProximaNova-Bold-webfont.woff2 */; }; - 4B957C2E2AC7AE700062CA31 /* dark-shield-dot.json in Resources */ = {isa = PBXBuildFile; fileRef = AA34396E2754D4E900B241FA /* dark-shield-dot.json */; }; - 4B957C2F2AC7AE700062CA31 /* trackers-2.json in Resources */ = {isa = PBXBuildFile; fileRef = AA3439742754D55100B241FA /* trackers-2.json */; }; - 4B957C302AC7AE700062CA31 /* ProximaNova-Reg-webfont.woff2 in Resources */ = {isa = PBXBuildFile; fileRef = EAA29AE8278D2E43007070CF /* ProximaNova-Reg-webfont.woff2 */; }; - 4B957C312AC7AE700062CA31 /* clickToLoad.js in Resources */ = {isa = PBXBuildFile; fileRef = EAFAD6C92728BD1200F9DF00 /* clickToLoad.js */; }; - 4B957C342AC7AE700062CA31 /* DuckDuckGo VPN.app in Embed Login Items */ = {isa = PBXBuildFile; fileRef = 4B2D06392A11CFBB00DE1F49 /* DuckDuckGo VPN.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 4B957C352AC7AE700062CA31 /* DuckDuckGo Notifications.app in Embed Login Items */ = {isa = PBXBuildFile; fileRef = 4B4BEC202A11B4E2001D9AC5 /* DuckDuckGo Notifications.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 4B9754EC2984300100D7B834 /* EmailManagerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B3B848F297A0E1000A384BD /* EmailManagerExtension.swift */; }; 4B980E212817604000282EE1 /* NSNotificationName+Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B980E202817604000282EE1 /* NSNotificationName+Debug.swift */; }; 4B98D27A28D95F1A003C2B6F /* ChromiumFaviconsReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B98D27928D95F1A003C2B6F /* ChromiumFaviconsReaderTests.swift */; }; @@ -2106,7 +1345,6 @@ 4BBF0917282DD6EF00EE1418 /* TemporaryFileHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF0916282DD6EF00EE1418 /* TemporaryFileHandlerTests.swift */; }; 4BBF09232830812900EE1418 /* FileSystemDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF09222830812900EE1418 /* FileSystemDSL.swift */; }; 4BBF0925283083EC00EE1418 /* FileSystemDSLTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BBF0924283083EC00EE1418 /* FileSystemDSLTests.swift */; }; - 4BC2621D293996410087A482 /* PixelEventTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BC2621C293996410087A482 /* PixelEventTests.swift */; }; 4BCBE4552BA7E16600FC75A1 /* NetworkProtectionSubscriptionEventHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B2F565B2B38F93E001214C0 /* NetworkProtectionSubscriptionEventHandler.swift */; }; 4BCBE4562BA7E16900FC75A1 /* DataBrokerProtectionSubscriptionEventHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB5789712B2CA70F0009DFE2 /* DataBrokerProtectionSubscriptionEventHandler.swift */; }; 4BCBE4582BA7E17800FC75A1 /* SubscriptionUI in Frameworks */ = {isa = PBXBuildFile; productRef = 4BCBE4572BA7E17800FC75A1 /* SubscriptionUI */; }; @@ -2148,14 +1386,12 @@ 4BF0E5062AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5042AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift */; }; 4BF0E5072AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5042AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift */; }; 4BF0E5082AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5042AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift */; }; - 4BF0E50A2AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5042AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift */; }; 4BF0E50B2AD2552200FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5042AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift */; }; 4BF0E50C2AD2552300FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5042AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift */; }; 4BF0E5122AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5112AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift */; }; 4BF0E5132AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5112AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift */; }; 4BF0E5142AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5112AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift */; }; 4BF0E5152AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5112AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift */; }; - 4BF0E5172AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0E5112AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift */; }; 4BF4951826C08395000547B8 /* ThirdPartyBrowserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF4951726C08395000547B8 /* ThirdPartyBrowserTests.swift */; }; 4BF4EA5027C71F26004E57C4 /* PasswordManagementListSectionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF4EA4F27C71F26004E57C4 /* PasswordManagementListSectionTests.swift */; }; 4BF6961D28BE911100D402D4 /* RecentlyVisitedSiteModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BF6961C28BE911100D402D4 /* RecentlyVisitedSiteModelTests.swift */; }; @@ -2174,9 +1410,12 @@ 5601FECD29B7973D00068905 /* TabBarViewItemTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5601FECC29B7973D00068905 /* TabBarViewItemTests.swift */; }; 5603D90629B7B746007F9F01 /* MockTabViewItemDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5603D90529B7B746007F9F01 /* MockTabViewItemDelegate.swift */; }; 5603D90729B7B746007F9F01 /* MockTabViewItemDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5603D90529B7B746007F9F01 /* MockTabViewItemDelegate.swift */; }; + 560C3FFC2BC9911000F589CE /* PermanentSurveyManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 560C3FFB2BC9911000F589CE /* PermanentSurveyManagerTests.swift */; }; + 560C3FFD2BC9911000F589CE /* PermanentSurveyManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 560C3FFB2BC9911000F589CE /* PermanentSurveyManagerTests.swift */; }; + 560C3FFF2BCD5A1E00F589CE /* PermanentSurveyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 560C3FFE2BCD5A1E00F589CE /* PermanentSurveyManager.swift */; }; + 560C40002BCD5A1E00F589CE /* PermanentSurveyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 560C3FFE2BCD5A1E00F589CE /* PermanentSurveyManager.swift */; }; 561D66662B95C45A008ACC5C /* Suggestion.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 561D66692B95C45A008ACC5C /* Suggestion.storyboard */; }; 561D66672B95C45A008ACC5C /* Suggestion.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 561D66692B95C45A008ACC5C /* Suggestion.storyboard */; }; - 561D66682B95C45A008ACC5C /* Suggestion.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 561D66692B95C45A008ACC5C /* Suggestion.storyboard */; }; 562984702AC4610100AC20EB /* SyncPreferencesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5629846E2AC4610100AC20EB /* SyncPreferencesTests.swift */; }; 562984712AC469E400AC20EB /* SyncPreferencesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5629846E2AC4610100AC20EB /* SyncPreferencesTests.swift */; }; 56534DED29DF252C00121467 /* CapturingDefaultBrowserProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56534DEC29DF252C00121467 /* CapturingDefaultBrowserProvider.swift */; }; @@ -2199,20 +1438,16 @@ 56B234C02A84EFD800F2A1CC /* NavigationBarUrlExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56B234BE2A84EFD200F2A1CC /* NavigationBarUrlExtensionsTests.swift */; }; 56BA1E752BAAF70F001CF69F /* SSLErrorPageTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E742BAAF70F001CF69F /* SSLErrorPageTabExtension.swift */; }; 56BA1E762BAAF70F001CF69F /* SSLErrorPageTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E742BAAF70F001CF69F /* SSLErrorPageTabExtension.swift */; }; - 56BA1E772BAAF70F001CF69F /* SSLErrorPageTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E742BAAF70F001CF69F /* SSLErrorPageTabExtension.swift */; }; 56BA1E7F2BAB2D29001CF69F /* ErrorPageTabExtensionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E7C2BAB290E001CF69F /* ErrorPageTabExtensionTest.swift */; }; 56BA1E802BAB2E43001CF69F /* ErrorPageTabExtensionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E7C2BAB290E001CF69F /* ErrorPageTabExtensionTest.swift */; }; 56BA1E822BAC506F001CF69F /* SSLErrorPageUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E812BAC506F001CF69F /* SSLErrorPageUserScript.swift */; }; 56BA1E832BAC506F001CF69F /* SSLErrorPageUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E812BAC506F001CF69F /* SSLErrorPageUserScript.swift */; }; - 56BA1E842BAC506F001CF69F /* SSLErrorPageUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E812BAC506F001CF69F /* SSLErrorPageUserScript.swift */; }; 56BA1E872BAC8239001CF69F /* SSLErrorPageUserScriptTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E862BAC8239001CF69F /* SSLErrorPageUserScriptTests.swift */; }; 56BA1E882BAC8239001CF69F /* SSLErrorPageUserScriptTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E862BAC8239001CF69F /* SSLErrorPageUserScriptTests.swift */; }; 56BA1E8A2BB1CB5B001CF69F /* CertificateTrustEvaluator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E892BB1CB5B001CF69F /* CertificateTrustEvaluator.swift */; }; 56BA1E8B2BB1CB5B001CF69F /* CertificateTrustEvaluator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E892BB1CB5B001CF69F /* CertificateTrustEvaluator.swift */; }; - 56BA1E8C2BB1CB5B001CF69F /* CertificateTrustEvaluator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56BA1E892BB1CB5B001CF69F /* CertificateTrustEvaluator.swift */; }; 56CEE90E2B7A725B00CF10AA /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 56CEE90D2B7A6DE100CF10AA /* InfoPlist.xcstrings */; }; 56CEE90F2B7A725C00CF10AA /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 56CEE90D2B7A6DE100CF10AA /* InfoPlist.xcstrings */; }; - 56CEE9102B7A72FE00CF10AA /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 56CEE90D2B7A6DE100CF10AA /* InfoPlist.xcstrings */; }; 56D145E829E6BB6300E3488A /* CapturingDataImportProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D145E729E6BB6300E3488A /* CapturingDataImportProvider.swift */; }; 56D145E929E6BB6300E3488A /* CapturingDataImportProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D145E729E6BB6300E3488A /* CapturingDataImportProvider.swift */; }; 56D145EB29E6C99B00E3488A /* DataImportStatusProviding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D145EA29E6C99B00E3488A /* DataImportStatusProviding.swift */; }; @@ -2243,25 +1478,18 @@ 7B2DDCFB2A93B25F0039D884 /* KeychainType+ClientDefault.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */; }; 7B2E52252A5FEC09000C6D39 /* NetworkProtectionAgentNotificationsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B2E52242A5FEC09000C6D39 /* NetworkProtectionAgentNotificationsPresenter.swift */; }; 7B31FD8C2AD125620086AA24 /* NetworkProtectionIPC in Frameworks */ = {isa = PBXBuildFile; productRef = 7B31FD8B2AD125620086AA24 /* NetworkProtectionIPC */; }; - 7B31FD902AD1257B0086AA24 /* NetworkProtectionIPC in Frameworks */ = {isa = PBXBuildFile; productRef = 7B31FD8F2AD1257B0086AA24 /* NetworkProtectionIPC */; }; 7B3618C22ADE75C8000D6154 /* NetworkProtectionNavBarPopoverManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3618C12ADE75C8000D6154 /* NetworkProtectionNavBarPopoverManager.swift */; }; - 7B3618C52ADE77D3000D6154 /* NetworkProtectionNavBarPopoverManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B3618C12ADE75C8000D6154 /* NetworkProtectionNavBarPopoverManager.swift */; }; 7B37C7A52BAA32A50062546A /* Subscription in Frameworks */ = {isa = PBXBuildFile; productRef = 7B37C7A42BAA32A50062546A /* Subscription */; }; 7B430EA12A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B430EA02A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift */; }; 7B430EA22A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B430EA02A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift */; }; 7B4CE8E726F02135009134B1 /* TabBarTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B4CE8E626F02134009134B1 /* TabBarTests.swift */; }; - 7B5DD69A2AE51FFA001DE99C /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7B5DD6992AE51FFA001DE99C /* PixelKit */; }; - 7B5F9A752AE2BE4E002AEBC0 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7B5F9A742AE2BE4E002AEBC0 /* PixelKit */; }; 7B624F172BA25C1F00A6C544 /* NetworkProtectionUI in Frameworks */ = {isa = PBXBuildFile; productRef = 7B624F162BA25C1F00A6C544 /* NetworkProtectionUI */; }; 7B7DFB202B7E736B009EA1A3 /* MacPacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEF12E6D2A2111880023E6BF /* MacPacketTunnelProvider.swift */; }; 7B7DFB222B7E7473009EA1A3 /* Networking in Frameworks */ = {isa = PBXBuildFile; productRef = 7B7DFB212B7E7473009EA1A3 /* Networking */; }; 7B7FCD0F2BA33B2700C04FBE /* UserDefaults+vpnLegacyUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B7FCD0E2BA33B2700C04FBE /* UserDefaults+vpnLegacyUser.swift */; }; 7B7FCD102BA33B2700C04FBE /* UserDefaults+vpnLegacyUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B7FCD0E2BA33B2700C04FBE /* UserDefaults+vpnLegacyUser.swift */; }; - 7B7FCD112BA33B2700C04FBE /* UserDefaults+vpnLegacyUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B7FCD0E2BA33B2700C04FBE /* UserDefaults+vpnLegacyUser.swift */; }; - 7B8C083C2AE1268E00F4C67F /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7B8C083B2AE1268E00F4C67F /* PixelKit */; }; 7B8DB31A2B504D7500EC16DA /* VPNAppEventsHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B8DB3192B504D7500EC16DA /* VPNAppEventsHandler.swift */; }; 7B934C412A866DD400FC8F9C /* UserDefaults+NetworkProtectionShared.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B934C402A866DD400FC8F9C /* UserDefaults+NetworkProtectionShared.swift */; }; - 7B94E1652B7ED95100E32B96 /* NetworkProtectionProxy in Frameworks */ = {isa = PBXBuildFile; productRef = 7B94E1642B7ED95100E32B96 /* NetworkProtectionProxy */; }; 7B97CD592B7E0B57004FEF43 /* NetworkProtectionProxy in Frameworks */ = {isa = PBXBuildFile; productRef = 7B97CD582B7E0B57004FEF43 /* NetworkProtectionProxy */; }; 7B97CD5B2B7E0B85004FEF43 /* Common in Frameworks */ = {isa = PBXBuildFile; productRef = 7B97CD5A2B7E0B85004FEF43 /* Common */; }; 7B97CD5C2B7E0BBB004FEF43 /* UserDefaultsWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85C6A29525CC1FFD00EEB5F1 /* UserDefaultsWrapper.swift */; }; @@ -2269,7 +1497,6 @@ 7B97CD5E2B7E0BEA004FEF43 /* OptionalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B637273C26CCF0C200C8CB02 /* OptionalExtension.swift */; }; 7B97CD5F2B7E0BF7004FEF43 /* NSApplicationExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA5C8F622591021700748EB7 /* NSApplicationExtension.swift */; }; 7B97CD602B7E0C2E004FEF43 /* Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85799C1725DEBB3F0007EC87 /* Logging.swift */; }; - 7B97CD622B7E0C4B004FEF43 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7B97CD612B7E0C4B004FEF43 /* PixelKit */; }; 7BA076BB2B65D61400D7FB72 /* NetworkProtectionProxy in Frameworks */ = {isa = PBXBuildFile; productRef = 7BA076BA2B65D61400D7FB72 /* NetworkProtectionProxy */; }; 7BA4727D26F01BC400EAA165 /* CoreDataTestUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B9292C42667104B00AD2C21 /* CoreDataTestUtilities.swift */; }; 7BA59C9B2AE18B49009A97B1 /* SystemExtensionManager in Frameworks */ = {isa = PBXBuildFile; productRef = 7BA59C9A2AE18B49009A97B1 /* SystemExtensionManager */; }; @@ -2289,7 +1516,6 @@ 7BA7CC4B2AD11EC60042E5CE /* NetworkProtectionControllerErrorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606A2A0B29FA00BCD287 /* NetworkProtectionControllerErrorStore.swift */; }; 7BA7CC4C2AD11EC70042E5CE /* NetworkProtectionControllerErrorStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D606A2A0B29FA00BCD287 /* NetworkProtectionControllerErrorStore.swift */; }; 7BA7CC4E2AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA7CC4D2AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift */; }; - 7BA7CC502AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BA7CC4D2AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift */; }; 7BA7CC532AD11FCE0042E5CE /* Bundle+VPN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605E2A0B29FA00BCD287 /* Bundle+VPN.swift */; }; 7BA7CC542AD11FCE0042E5CE /* Bundle+VPN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605E2A0B29FA00BCD287 /* Bundle+VPN.swift */; }; 7BA7CC552AD11FFB0042E5CE /* NetworkProtectionOptionKeyExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B4D605F2A0B29FA00BCD287 /* NetworkProtectionOptionKeyExtension.swift */; }; @@ -2306,8 +1532,6 @@ 7BB108592A43375D000AB95F /* PFMoveApplication.m in Sources */ = {isa = PBXBuildFile; fileRef = 7BB108582A43375D000AB95F /* PFMoveApplication.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; 7BBA7CE62BAB03C1007579A3 /* DefaultSubscriptionFeatureAvailability+DefaultInitializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBA7CE52BAB03C1007579A3 /* DefaultSubscriptionFeatureAvailability+DefaultInitializer.swift */; }; 7BBA7CE72BAB03C1007579A3 /* DefaultSubscriptionFeatureAvailability+DefaultInitializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBA7CE52BAB03C1007579A3 /* DefaultSubscriptionFeatureAvailability+DefaultInitializer.swift */; }; - 7BBA7CEA2BAB03C1007579A3 /* DefaultSubscriptionFeatureAvailability+DefaultInitializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBA7CE52BAB03C1007579A3 /* DefaultSubscriptionFeatureAvailability+DefaultInitializer.swift */; }; - 7BBD44282AD730A400D0A064 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7BBD44272AD730A400D0A064 /* PixelKit */; }; 7BBD45B12A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBD45B02A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift */; }; 7BBD45B22A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BBD45B02A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift */; }; 7BBE2B7B2B61663C00697445 /* NetworkProtectionProxy in Frameworks */ = {isa = PBXBuildFile; productRef = 7BBE2B7A2B61663C00697445 /* NetworkProtectionProxy */; }; @@ -2321,15 +1545,11 @@ 7BEC182F2AD5D8DC00D30536 /* SystemExtensionManager in Frameworks */ = {isa = PBXBuildFile; productRef = 7BEC182E2AD5D8DC00D30536 /* SystemExtensionManager */; }; 7BEC20422B0F505F00243D3E /* AddBookmarkPopoverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BEC20402B0F505F00243D3E /* AddBookmarkPopoverView.swift */; }; 7BEC20432B0F505F00243D3E /* AddBookmarkPopoverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BEC20402B0F505F00243D3E /* AddBookmarkPopoverView.swift */; }; - 7BEC20442B0F505F00243D3E /* AddBookmarkPopoverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BEC20402B0F505F00243D3E /* AddBookmarkPopoverView.swift */; }; 7BEC20452B0F505F00243D3E /* AddBookmarkFolderPopoverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BEC20412B0F505F00243D3E /* AddBookmarkFolderPopoverView.swift */; }; 7BEC20462B0F505F00243D3E /* AddBookmarkFolderPopoverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BEC20412B0F505F00243D3E /* AddBookmarkFolderPopoverView.swift */; }; - 7BEC20472B0F505F00243D3E /* AddBookmarkFolderPopoverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BEC20412B0F505F00243D3E /* AddBookmarkFolderPopoverView.swift */; }; 7BEEA5122AD1235B00A9E72B /* NetworkProtectionIPC in Frameworks */ = {isa = PBXBuildFile; productRef = 7BEEA5112AD1235B00A9E72B /* NetworkProtectionIPC */; }; 7BEEA5142AD1236300A9E72B /* NetworkProtectionIPC in Frameworks */ = {isa = PBXBuildFile; productRef = 7BEEA5132AD1236300A9E72B /* NetworkProtectionIPC */; }; 7BEEA5162AD1236E00A9E72B /* NetworkProtectionUI in Frameworks */ = {isa = PBXBuildFile; productRef = 7BEEA5152AD1236E00A9E72B /* NetworkProtectionUI */; }; - 7BFCB74E2ADE7E1A00DA3EA7 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7BFCB74D2ADE7E1A00DA3EA7 /* PixelKit */; }; - 7BFCB7502ADE7E2300DA3EA7 /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7BFCB74F2ADE7E2300DA3EA7 /* PixelKit */; }; 7BFE95522A9DF1CE0081ABE9 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFE95512A9DF1CE0081ABE9 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift */; }; 7BFE95542A9DF2930081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFE95532A9DF2930081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift */; }; 7BFE95552A9DF2990081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFE95532A9DF2930081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift */; }; @@ -2337,7 +1557,6 @@ 7BFE95592A9DF2AF0081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFE95532A9DF2930081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift */; }; 7BFE955A2A9DF4550081ABE9 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFE95512A9DF1CE0081ABE9 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift */; }; 7BFF850F2B0C09DA00ECACA2 /* DuckDuckGo Personal Information Removal.app in Embed Login Items */ = {isa = PBXBuildFile; fileRef = 9D9AE8D12AAA39A70026E7DC /* DuckDuckGo Personal Information Removal.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 7BFF85102B0C09E300ECACA2 /* DuckDuckGo Personal Information Removal.app in Embed Login Items */ = {isa = PBXBuildFile; fileRef = 9D9AE8D12AAA39A70026E7DC /* DuckDuckGo Personal Information Removal.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 85012B0229133F9F003D0DCC /* NavigationBarPopovers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85012B0129133F9F003D0DCC /* NavigationBarPopovers.swift */; }; 850E8DFB2A6FEC5E00691187 /* BookmarksBarAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 850E8DFA2A6FEC5E00691187 /* BookmarksBarAppearance.swift */; }; 8511E18425F82B34002F516B /* 01_Fire_really_small.json in Resources */ = {isa = PBXBuildFile; fileRef = 8511E18325F82B34002F516B /* 01_Fire_really_small.json */; }; @@ -2417,17 +1636,14 @@ 85CC1D7D26A05F250062F04E /* PasswordManagementItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85CC1D7C26A05F250062F04E /* PasswordManagementItemModel.swift */; }; 85D0327B2B8E3D090041D1FB /* HistoryCoordinatorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85D0327A2B8E3D090041D1FB /* HistoryCoordinatorExtension.swift */; }; 85D0327C2B8E3D090041D1FB /* HistoryCoordinatorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85D0327A2B8E3D090041D1FB /* HistoryCoordinatorExtension.swift */; }; - 85D0327D2B8E3D090041D1FB /* HistoryCoordinatorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85D0327A2B8E3D090041D1FB /* HistoryCoordinatorExtension.swift */; }; 85D33F1225C82EB3002B91A6 /* ConfigurationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85D33F1125C82EB3002B91A6 /* ConfigurationManager.swift */; }; 85D438B6256E7C9E00F3BAF8 /* ContextMenuUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85D438B5256E7C9E00F3BAF8 /* ContextMenuUserScript.swift */; }; 85D44B862BA08D29001B4AB5 /* Suggestions in Frameworks */ = {isa = PBXBuildFile; productRef = 85D44B852BA08D29001B4AB5 /* Suggestions */; }; 85D44B882BA08D30001B4AB5 /* Suggestions in Frameworks */ = {isa = PBXBuildFile; productRef = 85D44B872BA08D30001B4AB5 /* Suggestions */; }; - 85D44B8A2BA08D3B001B4AB5 /* Suggestions in Frameworks */ = {isa = PBXBuildFile; productRef = 85D44B892BA08D3B001B4AB5 /* Suggestions */; }; 85D885B026A590A90077C374 /* NSNotificationName+PasswordManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85D885AF26A590A90077C374 /* NSNotificationName+PasswordManager.swift */; }; 85D885B326A5A9DE0077C374 /* NSAlert+PasswordManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85D885B226A5A9DE0077C374 /* NSAlert+PasswordManager.swift */; }; 85E2BBCE2B8F534000DBEC7A /* History in Frameworks */ = {isa = PBXBuildFile; productRef = 85E2BBCD2B8F534000DBEC7A /* History */; }; 85E2BBD02B8F534A00DBEC7A /* History in Frameworks */ = {isa = PBXBuildFile; productRef = 85E2BBCF2B8F534A00DBEC7A /* History */; }; - 85E2BBD22B8F536F00DBEC7A /* History in Frameworks */ = {isa = PBXBuildFile; productRef = 85E2BBD12B8F536F00DBEC7A /* History */; }; 85F0FF1327CFAB04001C7C6E /* RecentlyVisitedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85F0FF1227CFAB04001C7C6E /* RecentlyVisitedView.swift */; }; 85F1B0C925EF9759004792B6 /* URLEventHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85F1B0C825EF9759004792B6 /* URLEventHandlerTests.swift */; }; 85F487B5276A8F2E003CE668 /* OnboardingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85F487B4276A8F2E003CE668 /* OnboardingTests.swift */; }; @@ -2458,8 +1674,6 @@ 98A50964294B691800D10880 /* Persistence in Frameworks */ = {isa = PBXBuildFile; productRef = 98A50963294B691800D10880 /* Persistence */; }; 98A95D88299A2DF900B9B81A /* BookmarkMigrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98A95D87299A2DF900B9B81A /* BookmarkMigrationTests.swift */; }; 98EB5D1027516A4800681FE6 /* AppPrivacyConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98EB5D0F27516A4800681FE6 /* AppPrivacyConfigurationTests.swift */; }; - 9D6983F92AC773C3002C02FC /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 9D6983F82AC773C3002C02FC /* PixelKit */; }; - 9D6983FB2AC773C8002C02FC /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = 9D6983FA2AC773C8002C02FC /* PixelKit */; }; 9D9AE8692AA76CDC0026E7DC /* LoginItem+NetworkProtection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9AE8682AA76CDC0026E7DC /* LoginItem+NetworkProtection.swift */; }; 9D9AE86B2AA76CF90026E7DC /* LoginItemsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9AE86A2AA76CF90026E7DC /* LoginItemsManager.swift */; }; 9D9AE86C2AA76D1B0026E7DC /* LoginItemsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9AE86A2AA76CF90026E7DC /* LoginItemsManager.swift */; }; @@ -2476,11 +1690,18 @@ 9D9AE92A2AAA43EB0026E7DC /* DataBrokerProtectionBackgroundManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9AE9282AAA43EB0026E7DC /* DataBrokerProtectionBackgroundManager.swift */; }; 9D9AE92C2AAB84FF0026E7DC /* DBPMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9AE92B2AAB84FF0026E7DC /* DBPMocks.swift */; }; 9D9AE92D2AAB84FF0026E7DC /* DBPMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9D9AE92B2AAB84FF0026E7DC /* DBPMocks.swift */; }; - 9DB6E7242AA0DC5800A17F3C /* LoginItems in Frameworks */ = {isa = PBXBuildFile; productRef = 9DB6E7232AA0DC5800A17F3C /* LoginItems */; }; 9DC70B1A2AA1FA5B005A844B /* LoginItems in Frameworks */ = {isa = PBXBuildFile; productRef = 9DC70B192AA1FA5B005A844B /* LoginItems */; }; 9DEF97E12B06C4EE00764F03 /* Networking in Frameworks */ = {isa = PBXBuildFile; productRef = 9DEF97E02B06C4EE00764F03 /* Networking */; }; 9F0A2CF82B96A58600C5B8C0 /* BaseBookmarkEntityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F0A2CF72B96A58600C5B8C0 /* BaseBookmarkEntityTests.swift */; }; 9F0A2CF92B96A58600C5B8C0 /* BaseBookmarkEntityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F0A2CF72B96A58600C5B8C0 /* BaseBookmarkEntityTests.swift */; }; + 9F0FFFB42BCCAE37007C87DD /* BookmarkAllTabsDialogCoordinatorViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F0FFFB32BCCAE37007C87DD /* BookmarkAllTabsDialogCoordinatorViewModelTests.swift */; }; + 9F0FFFB52BCCAE37007C87DD /* BookmarkAllTabsDialogCoordinatorViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F0FFFB32BCCAE37007C87DD /* BookmarkAllTabsDialogCoordinatorViewModelTests.swift */; }; + 9F0FFFB82BCCAE9C007C87DD /* AddEditBookmarkDialogViewModelMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F0FFFB72BCCAE9C007C87DD /* AddEditBookmarkDialogViewModelMock.swift */; }; + 9F0FFFB92BCCAE9C007C87DD /* AddEditBookmarkDialogViewModelMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F0FFFB72BCCAE9C007C87DD /* AddEditBookmarkDialogViewModelMock.swift */; }; + 9F0FFFBB2BCCAEC2007C87DD /* AddEditBookmarkFolderDialogViewModelMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F0FFFBA2BCCAEC2007C87DD /* AddEditBookmarkFolderDialogViewModelMock.swift */; }; + 9F0FFFBC2BCCAEC2007C87DD /* AddEditBookmarkFolderDialogViewModelMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F0FFFBA2BCCAEC2007C87DD /* AddEditBookmarkFolderDialogViewModelMock.swift */; }; + 9F0FFFBE2BCCAF1F007C87DD /* BookmarkAllTabsDialogViewModelMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F0FFFBD2BCCAF1F007C87DD /* BookmarkAllTabsDialogViewModelMock.swift */; }; + 9F0FFFBF2BCCAF1F007C87DD /* BookmarkAllTabsDialogViewModelMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F0FFFBD2BCCAF1F007C87DD /* BookmarkAllTabsDialogViewModelMock.swift */; }; 9F180D0F2B69C553000D695F /* Tab+WKUIDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F180D0E2B69C553000D695F /* Tab+WKUIDelegateTests.swift */; }; 9F180D102B69C553000D695F /* Tab+WKUIDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F180D0E2B69C553000D695F /* Tab+WKUIDelegateTests.swift */; }; 9F180D122B69C665000D695F /* DownloadsTabExtensionMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F180D112B69C665000D695F /* DownloadsTabExtensionMock.swift */; }; @@ -2491,7 +1712,6 @@ 9F26060F2B85E17D00819292 /* AddEditBookmarkDialogCoordinatorViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F26060D2B85E17D00819292 /* AddEditBookmarkDialogCoordinatorViewModelTests.swift */; }; 9F33445E2BBFA77F0040CBEB /* BookmarksBarVisibilityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F33445D2BBFA77F0040CBEB /* BookmarksBarVisibilityManager.swift */; }; 9F33445F2BBFA77F0040CBEB /* BookmarksBarVisibilityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F33445D2BBFA77F0040CBEB /* BookmarksBarVisibilityManager.swift */; }; - 9F3344602BBFA77F0040CBEB /* BookmarksBarVisibilityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F33445D2BBFA77F0040CBEB /* BookmarksBarVisibilityManager.swift */; }; 9F3344622BBFBDA40040CBEB /* BookmarksBarVisibilityManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F3344612BBFBDA40040CBEB /* BookmarksBarVisibilityManagerTests.swift */; }; 9F3344632BBFBDA40040CBEB /* BookmarksBarVisibilityManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F3344612BBFBDA40040CBEB /* BookmarksBarVisibilityManagerTests.swift */; }; 9F3910622B68C35600CB5112 /* DownloadsTabExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F3910612B68C35600CB5112 /* DownloadsTabExtensionTests.swift */; }; @@ -2500,51 +1720,58 @@ 9F39106A2B68D87B00CB5112 /* ProgressExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F3910682B68D87B00CB5112 /* ProgressExtensionTests.swift */; }; 9F514F912B7D88AD001832A9 /* AddEditBookmarkFolderDialogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F514F902B7D88AD001832A9 /* AddEditBookmarkFolderDialogView.swift */; }; 9F514F922B7D88AD001832A9 /* AddEditBookmarkFolderDialogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F514F902B7D88AD001832A9 /* AddEditBookmarkFolderDialogView.swift */; }; - 9F514F932B7D88AD001832A9 /* AddEditBookmarkFolderDialogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F514F902B7D88AD001832A9 /* AddEditBookmarkFolderDialogView.swift */; }; 9F56CFA92B82DC4300BB7F11 /* AddEditBookmarkFolderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F56CFA82B82DC4300BB7F11 /* AddEditBookmarkFolderView.swift */; }; 9F56CFAA2B82DC4300BB7F11 /* AddEditBookmarkFolderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F56CFA82B82DC4300BB7F11 /* AddEditBookmarkFolderView.swift */; }; - 9F56CFAB2B82DC4300BB7F11 /* AddEditBookmarkFolderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F56CFA82B82DC4300BB7F11 /* AddEditBookmarkFolderView.swift */; }; 9F56CFAD2B84326C00BB7F11 /* AddEditBookmarkDialogViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F56CFAC2B84326C00BB7F11 /* AddEditBookmarkDialogViewModel.swift */; }; 9F56CFAE2B84326C00BB7F11 /* AddEditBookmarkDialogViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F56CFAC2B84326C00BB7F11 /* AddEditBookmarkDialogViewModel.swift */; }; - 9F56CFAF2B84326C00BB7F11 /* AddEditBookmarkDialogViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F56CFAC2B84326C00BB7F11 /* AddEditBookmarkDialogViewModel.swift */; }; 9F56CFB12B843F6C00BB7F11 /* BookmarksDialogViewFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F56CFB02B843F6C00BB7F11 /* BookmarksDialogViewFactory.swift */; }; 9F56CFB22B843F6C00BB7F11 /* BookmarksDialogViewFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F56CFB02B843F6C00BB7F11 /* BookmarksDialogViewFactory.swift */; }; - 9F56CFB32B843F6C00BB7F11 /* BookmarksDialogViewFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F56CFB02B843F6C00BB7F11 /* BookmarksDialogViewFactory.swift */; }; 9F872D982B8DA9F800138637 /* Bookmarks+Tab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F872D972B8DA9F800138637 /* Bookmarks+Tab.swift */; }; 9F872D992B8DA9F800138637 /* Bookmarks+Tab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F872D972B8DA9F800138637 /* Bookmarks+Tab.swift */; }; - 9F872D9A2B8DA9F800138637 /* Bookmarks+Tab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F872D972B8DA9F800138637 /* Bookmarks+Tab.swift */; }; 9F872D9D2B9058D000138637 /* Bookmarks+TabTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F872D9C2B9058D000138637 /* Bookmarks+TabTests.swift */; }; 9F872D9E2B9058D000138637 /* Bookmarks+TabTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F872D9C2B9058D000138637 /* Bookmarks+TabTests.swift */; }; 9F872DA02B90644800138637 /* ContextualMenuTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F872D9F2B90644800138637 /* ContextualMenuTests.swift */; }; 9F872DA12B90644800138637 /* ContextualMenuTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F872D9F2B90644800138637 /* ContextualMenuTests.swift */; }; 9F872DA32B90920F00138637 /* BookmarkFolderInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F872DA22B90920F00138637 /* BookmarkFolderInfo.swift */; }; 9F872DA42B90920F00138637 /* BookmarkFolderInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F872DA22B90920F00138637 /* BookmarkFolderInfo.swift */; }; - 9F872DA52B90920F00138637 /* BookmarkFolderInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F872DA22B90920F00138637 /* BookmarkFolderInfo.swift */; }; + 9F8D57322BCCCB9A00AEA660 /* UserDefaultsBookmarkFoldersStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F8D57312BCCCB9A00AEA660 /* UserDefaultsBookmarkFoldersStoreTests.swift */; }; + 9F8D57332BCCCB9A00AEA660 /* UserDefaultsBookmarkFoldersStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F8D57312BCCCB9A00AEA660 /* UserDefaultsBookmarkFoldersStoreTests.swift */; }; 9F982F0D2B8224BF00231028 /* AddEditBookmarkFolderDialogViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F982F0C2B8224BE00231028 /* AddEditBookmarkFolderDialogViewModel.swift */; }; 9F982F0E2B8224BF00231028 /* AddEditBookmarkFolderDialogViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F982F0C2B8224BE00231028 /* AddEditBookmarkFolderDialogViewModel.swift */; }; - 9F982F0F2B8224BF00231028 /* AddEditBookmarkFolderDialogViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F982F0C2B8224BE00231028 /* AddEditBookmarkFolderDialogViewModel.swift */; }; 9F982F132B822B7B00231028 /* AddEditBookmarkFolderDialogViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F982F112B82268F00231028 /* AddEditBookmarkFolderDialogViewModelTests.swift */; }; 9F982F142B822C7400231028 /* AddEditBookmarkFolderDialogViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F982F112B82268F00231028 /* AddEditBookmarkFolderDialogViewModelTests.swift */; }; + 9F9C49F62BC786790099738D /* MoreOptionsMenu+BookmarksTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9C49F52BC786790099738D /* MoreOptionsMenu+BookmarksTests.swift */; }; + 9F9C49F72BC786790099738D /* MoreOptionsMenu+BookmarksTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9C49F52BC786790099738D /* MoreOptionsMenu+BookmarksTests.swift */; }; + 9F9C49F92BC7BC970099738D /* BookmarkAllTabsDialogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9C49F82BC7BC970099738D /* BookmarkAllTabsDialogView.swift */; }; + 9F9C49FA2BC7BC970099738D /* BookmarkAllTabsDialogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9C49F82BC7BC970099738D /* BookmarkAllTabsDialogView.swift */; }; + 9F9C49FD2BC7E9830099738D /* BookmarkAllTabsDialogViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9C49FC2BC7E9820099738D /* BookmarkAllTabsDialogViewModel.swift */; }; + 9F9C49FE2BC7E9830099738D /* BookmarkAllTabsDialogViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9C49FC2BC7E9820099738D /* BookmarkAllTabsDialogViewModel.swift */; }; + 9F9C4A012BC7F36D0099738D /* BookmarkAllTabsDialogCoordinatorViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9C4A002BC7F36D0099738D /* BookmarkAllTabsDialogCoordinatorViewModel.swift */; }; + 9F9C4A022BC7F36D0099738D /* BookmarkAllTabsDialogCoordinatorViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9F9C4A002BC7F36D0099738D /* BookmarkAllTabsDialogCoordinatorViewModel.swift */; }; 9FA173DA2B79BD8A00EE4E6E /* BookmarkDialogContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA173D92B79BD8A00EE4E6E /* BookmarkDialogContainerView.swift */; }; 9FA173DB2B79BD8A00EE4E6E /* BookmarkDialogContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA173D92B79BD8A00EE4E6E /* BookmarkDialogContainerView.swift */; }; - 9FA173DC2B79BD8A00EE4E6E /* BookmarkDialogContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA173D92B79BD8A00EE4E6E /* BookmarkDialogContainerView.swift */; }; 9FA173DF2B7A0EFE00EE4E6E /* BookmarkDialogButtonsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA173DE2B7A0EFE00EE4E6E /* BookmarkDialogButtonsView.swift */; }; 9FA173E02B7A0EFE00EE4E6E /* BookmarkDialogButtonsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA173DE2B7A0EFE00EE4E6E /* BookmarkDialogButtonsView.swift */; }; - 9FA173E12B7A0EFE00EE4E6E /* BookmarkDialogButtonsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA173DE2B7A0EFE00EE4E6E /* BookmarkDialogButtonsView.swift */; }; 9FA173E32B7A12B600EE4E6E /* BookmarkDialogFolderManagementView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA173E22B7A12B600EE4E6E /* BookmarkDialogFolderManagementView.swift */; }; 9FA173E42B7A12B600EE4E6E /* BookmarkDialogFolderManagementView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA173E22B7A12B600EE4E6E /* BookmarkDialogFolderManagementView.swift */; }; - 9FA173E52B7A12B600EE4E6E /* BookmarkDialogFolderManagementView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA173E22B7A12B600EE4E6E /* BookmarkDialogFolderManagementView.swift */; }; 9FA173E72B7B122E00EE4E6E /* BookmarkDialogStackedContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA173E62B7B122E00EE4E6E /* BookmarkDialogStackedContentView.swift */; }; 9FA173E82B7B122E00EE4E6E /* BookmarkDialogStackedContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA173E62B7B122E00EE4E6E /* BookmarkDialogStackedContentView.swift */; }; - 9FA173E92B7B122E00EE4E6E /* BookmarkDialogStackedContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA173E62B7B122E00EE4E6E /* BookmarkDialogStackedContentView.swift */; }; 9FA173EB2B7B232200EE4E6E /* AddEditBookmarkDialogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA173EA2B7B232200EE4E6E /* AddEditBookmarkDialogView.swift */; }; 9FA173EC2B7B232200EE4E6E /* AddEditBookmarkDialogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA173EA2B7B232200EE4E6E /* AddEditBookmarkDialogView.swift */; }; - 9FA173ED2B7B232200EE4E6E /* AddEditBookmarkDialogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA173EA2B7B232200EE4E6E /* AddEditBookmarkDialogView.swift */; }; + 9FA5A0A52BC8F34900153786 /* UserDefaultsBookmarkFoldersStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA5A0A42BC8F34900153786 /* UserDefaultsBookmarkFoldersStore.swift */; }; + 9FA5A0A62BC8F34900153786 /* UserDefaultsBookmarkFoldersStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA5A0A42BC8F34900153786 /* UserDefaultsBookmarkFoldersStore.swift */; }; + 9FA5A0A92BC900FC00153786 /* BookmarkAllTabsDialogViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA5A0A82BC900FC00153786 /* BookmarkAllTabsDialogViewModelTests.swift */; }; + 9FA5A0AA2BC900FC00153786 /* BookmarkAllTabsDialogViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA5A0A82BC900FC00153786 /* BookmarkAllTabsDialogViewModelTests.swift */; }; + 9FA5A0B02BC9039200153786 /* BookmarkFolderStoreMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA5A0AC2BC9037A00153786 /* BookmarkFolderStoreMock.swift */; }; + 9FA5A0B12BC9039300153786 /* BookmarkFolderStoreMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA5A0AC2BC9037A00153786 /* BookmarkFolderStoreMock.swift */; }; 9FA75A3E2BA00E1400DA5FA6 /* BookmarksBarMenuFactoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA75A3D2BA00E1400DA5FA6 /* BookmarksBarMenuFactoryTests.swift */; }; 9FA75A3F2BA00E1400DA5FA6 /* BookmarksBarMenuFactoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FA75A3D2BA00E1400DA5FA6 /* BookmarksBarMenuFactoryTests.swift */; }; + 9FAD623A2BCFDB32007F3A65 /* WebsiteInfoHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAD62392BCFDB32007F3A65 /* WebsiteInfoHelpers.swift */; }; + 9FAD623B2BCFDB32007F3A65 /* WebsiteInfoHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAD62392BCFDB32007F3A65 /* WebsiteInfoHelpers.swift */; }; + 9FAD623D2BD09DE5007F3A65 /* WebsiteInfoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAD623C2BD09DE5007F3A65 /* WebsiteInfoTests.swift */; }; + 9FAD623E2BD09DE5007F3A65 /* WebsiteInfoTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FAD623C2BD09DE5007F3A65 /* WebsiteInfoTests.swift */; }; 9FBD84522BB3AACB00220859 /* AttributionOriginFileProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBD84512BB3AACB00220859 /* AttributionOriginFileProvider.swift */; }; 9FBD84532BB3AACB00220859 /* AttributionOriginFileProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBD84512BB3AACB00220859 /* AttributionOriginFileProvider.swift */; }; - 9FBD84542BB3AACB00220859 /* AttributionOriginFileProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBD84512BB3AACB00220859 /* AttributionOriginFileProvider.swift */; }; 9FBD84562BB3ACFD00220859 /* AttributionOriginFileProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBD84552BB3ACFD00220859 /* AttributionOriginFileProviderTests.swift */; }; 9FBD84572BB3ACFD00220859 /* AttributionOriginFileProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBD84552BB3ACFD00220859 /* AttributionOriginFileProviderTests.swift */; }; 9FBD845D2BB3B80300220859 /* Origin.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9FBD845C2BB3B80300220859 /* Origin.txt */; }; @@ -2555,26 +1782,20 @@ 9FBD84712BB3DD8400220859 /* MockAttributionsPixelHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBD846F2BB3DD8400220859 /* MockAttributionsPixelHandler.swift */; }; 9FBD84732BB3E15D00220859 /* InstallationAttributionPixelHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBD84722BB3E15D00220859 /* InstallationAttributionPixelHandler.swift */; }; 9FBD84742BB3E15D00220859 /* InstallationAttributionPixelHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBD84722BB3E15D00220859 /* InstallationAttributionPixelHandler.swift */; }; - 9FBD84752BB3E15D00220859 /* InstallationAttributionPixelHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBD84722BB3E15D00220859 /* InstallationAttributionPixelHandler.swift */; }; 9FBD84772BB3E54200220859 /* InstallationAttributionPixelHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBD84762BB3E54200220859 /* InstallationAttributionPixelHandlerTests.swift */; }; 9FBD84782BB3E54200220859 /* InstallationAttributionPixelHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBD84762BB3E54200220859 /* InstallationAttributionPixelHandlerTests.swift */; }; 9FBD847A2BB3EC3300220859 /* MockAttributionOriginProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBD84792BB3EC3300220859 /* MockAttributionOriginProvider.swift */; }; 9FBD847B2BB3EC3300220859 /* MockAttributionOriginProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBD84792BB3EC3300220859 /* MockAttributionOriginProvider.swift */; }; 9FDA6C212B79A59D00E099A9 /* BookmarkFavoriteView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDA6C202B79A59D00E099A9 /* BookmarkFavoriteView.swift */; }; 9FDA6C222B79A59D00E099A9 /* BookmarkFavoriteView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDA6C202B79A59D00E099A9 /* BookmarkFavoriteView.swift */; }; - 9FDA6C232B79A59D00E099A9 /* BookmarkFavoriteView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FDA6C202B79A59D00E099A9 /* BookmarkFavoriteView.swift */; }; 9FEE98652B846870002E44E8 /* AddEditBookmarkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FEE98642B846870002E44E8 /* AddEditBookmarkView.swift */; }; 9FEE98662B846870002E44E8 /* AddEditBookmarkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FEE98642B846870002E44E8 /* AddEditBookmarkView.swift */; }; - 9FEE98672B846870002E44E8 /* AddEditBookmarkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FEE98642B846870002E44E8 /* AddEditBookmarkView.swift */; }; 9FEE98692B85B869002E44E8 /* BookmarksDialogViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FEE98682B85B869002E44E8 /* BookmarksDialogViewModel.swift */; }; 9FEE986A2B85B869002E44E8 /* BookmarksDialogViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FEE98682B85B869002E44E8 /* BookmarksDialogViewModel.swift */; }; - 9FEE986B2B85B869002E44E8 /* BookmarksDialogViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FEE98682B85B869002E44E8 /* BookmarksDialogViewModel.swift */; }; 9FEE986D2B85BA17002E44E8 /* AddEditBookmarkDialogCoordinatorViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FEE986C2B85BA17002E44E8 /* AddEditBookmarkDialogCoordinatorViewModel.swift */; }; 9FEE986E2B85BA17002E44E8 /* AddEditBookmarkDialogCoordinatorViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FEE986C2B85BA17002E44E8 /* AddEditBookmarkDialogCoordinatorViewModel.swift */; }; - 9FEE986F2B85BA17002E44E8 /* AddEditBookmarkDialogCoordinatorViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FEE986C2B85BA17002E44E8 /* AddEditBookmarkDialogCoordinatorViewModel.swift */; }; 9FF521462BAA908500B9819B /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = 9FF521452BAA908500B9819B /* Lottie */; }; 9FF521482BAA909C00B9819B /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = 9FF521472BAA909C00B9819B /* Lottie */; }; - 9FF5214A2BAA90C400B9819B /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = 9FF521492BAA90C400B9819B /* Lottie */; }; AA06B6B72672AF8100F541C5 /* Sparkle in Frameworks */ = {isa = PBXBuildFile; productRef = AA06B6B62672AF8100F541C5 /* Sparkle */; }; AA0877B826D5160D00B05660 /* SafariVersionReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA0877B726D5160D00B05660 /* SafariVersionReaderTests.swift */; }; AA0877BA26D5161D00B05660 /* WebKitVersionProviderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA0877B926D5161D00B05660 /* WebKitVersionProviderTests.swift */; }; @@ -2695,7 +1916,6 @@ AAC30A26268DFEE200D2D9CD /* CrashReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC30A25268DFEE200D2D9CD /* CrashReporter.swift */; }; AAC30A28268E045400D2D9CD /* CrashReportReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC30A27268E045400D2D9CD /* CrashReportReader.swift */; }; AAC30A2A268E239100D2D9CD /* CrashReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC30A29268E239100D2D9CD /* CrashReport.swift */; }; - AAC30A2C268F1ECD00D2D9CD /* CrashReportSender.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC30A2B268F1ECD00D2D9CD /* CrashReportSender.swift */; }; AAC30A2E268F1EE300D2D9CD /* CrashReportPromptPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC30A2D268F1EE300D2D9CD /* CrashReportPromptPresenter.swift */; }; AAC5E4C725D6A6E8007F5990 /* AddBookmarkPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC5E4C425D6A6E8007F5990 /* AddBookmarkPopover.swift */; }; AAC5E4D025D6A709007F5990 /* Bookmark.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAC5E4CD25D6A709007F5990 /* Bookmark.swift */; }; @@ -2738,7 +1958,6 @@ B31055CB27A1BA1D001AC618 /* autoconsent-bundle.js in Resources */ = {isa = PBXBuildFile; fileRef = B31055C327A1BA1D001AC618 /* autoconsent-bundle.js */; }; B60293E62BA19ECD0033186B /* NetPPopoverManagerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B60293E52BA19ECD0033186B /* NetPPopoverManagerMock.swift */; }; B60293E72BA19ECD0033186B /* NetPPopoverManagerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B60293E52BA19ECD0033186B /* NetPPopoverManagerMock.swift */; }; - B60293E82BA19ECD0033186B /* NetPPopoverManagerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B60293E52BA19ECD0033186B /* NetPPopoverManagerMock.swift */; }; B602E7CF2A93A5FF00F12201 /* WKBackForwardListExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B602E7CE2A93A5FF00F12201 /* WKBackForwardListExtension.swift */; }; B602E7D02A93A5FF00F12201 /* WKBackForwardListExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B602E7CE2A93A5FF00F12201 /* WKBackForwardListExtension.swift */; }; B602E8162A1E2570006D261F /* URL+NetworkProtection.swift in Sources */ = {isa = PBXBuildFile; fileRef = B602E8152A1E2570006D261F /* URL+NetworkProtection.swift */; }; @@ -2775,7 +1994,6 @@ B604085C274B8FBA00680351 /* UnprotectedDomains.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B604085A274B8CA300680351 /* UnprotectedDomains.xcdatamodeld */; }; B6080BC52B21E78100B418EF /* DataImportErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6080BC42B21E78100B418EF /* DataImportErrorView.swift */; }; B6080BC62B21E78100B418EF /* DataImportErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6080BC42B21E78100B418EF /* DataImportErrorView.swift */; }; - B6080BC82B21E78100B418EF /* DataImportErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6080BC42B21E78100B418EF /* DataImportErrorView.swift */; }; B6085D062743905F00A9C456 /* CoreDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6085D052743905F00A9C456 /* CoreDataStore.swift */; }; B6085D092743AAB600A9C456 /* FireproofDomains.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B6085D072743993C00A9C456 /* FireproofDomains.xcdatamodeld */; }; B60C6F7729B0E286007BFAA8 /* SearchNonexistentDomainNavigationResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B60C6F7629B0E286007BFAA8 /* SearchNonexistentDomainNavigationResponder.swift */; }; @@ -2798,7 +2016,6 @@ B60D644A2AAF1B7C00B26F50 /* AddressBarTextSelectionNavigation.swift in Sources */ = {isa = PBXBuildFile; fileRef = B60D64482AAF1B7C00B26F50 /* AddressBarTextSelectionNavigation.swift */; }; B6104E9B2BA9C173008636B2 /* DownloadResumeData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6104E9A2BA9C173008636B2 /* DownloadResumeData.swift */; }; B6104E9C2BA9C173008636B2 /* DownloadResumeData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6104E9A2BA9C173008636B2 /* DownloadResumeData.swift */; }; - B6104E9D2BA9C174008636B2 /* DownloadResumeData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6104E9A2BA9C173008636B2 /* DownloadResumeData.swift */; }; B6106BA026A7BE0B0013B453 /* PermissionManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6106B9F26A7BE0B0013B453 /* PermissionManagerTests.swift */; }; B6106BA726A7BECC0013B453 /* PermissionAuthorizationQuery.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6106BA526A7BEC80013B453 /* PermissionAuthorizationQuery.swift */; }; B6106BAB26A7BF1D0013B453 /* PermissionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6106BAA26A7BF1D0013B453 /* PermissionType.swift */; }; @@ -2827,13 +2044,10 @@ B62A234129C41D4400D22475 /* HistoryIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62A233F29C41D4400D22475 /* HistoryIntegrationTests.swift */; }; B62B48392ADE46FC000DECE5 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62B48382ADE46FC000DECE5 /* Application.swift */; }; B62B483A2ADE46FC000DECE5 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62B48382ADE46FC000DECE5 /* Application.swift */; }; - B62B483C2ADE46FC000DECE5 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62B48382ADE46FC000DECE5 /* Application.swift */; }; B62B483E2ADE48DE000DECE5 /* ArrayBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62B483D2ADE48DE000DECE5 /* ArrayBuilder.swift */; }; B62B483F2ADE48DE000DECE5 /* ArrayBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62B483D2ADE48DE000DECE5 /* ArrayBuilder.swift */; }; - B62B48412ADE48DE000DECE5 /* ArrayBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62B483D2ADE48DE000DECE5 /* ArrayBuilder.swift */; }; B62B48562ADE730D000DECE5 /* FileImportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62B48552ADE730D000DECE5 /* FileImportView.swift */; }; B62B48572ADE730D000DECE5 /* FileImportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62B48552ADE730D000DECE5 /* FileImportView.swift */; }; - B62B48592ADE730D000DECE5 /* FileImportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62B48552ADE730D000DECE5 /* FileImportView.swift */; }; B62EB47C25BAD3BB005745C6 /* WKWebViewPrivateMethodsAvailabilityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B62EB47B25BAD3BB005745C6 /* WKWebViewPrivateMethodsAvailabilityTests.swift */; }; B630793526731BC400DCEE41 /* URLSuggestedFilenameTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8553FF51257523760029327F /* URLSuggestedFilenameTests.swift */; }; B630793A26731F2600DCEE41 /* FileDownloadManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B630793926731F2600DCEE41 /* FileDownloadManagerTests.swift */; }; @@ -2860,7 +2074,7 @@ B63ED0E026AFE32F00A9DAD1 /* GeolocationProviderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B63ED0DF26AFE32F00A9DAD1 /* GeolocationProviderMock.swift */; }; B63ED0E326B3E7FA00A9DAD1 /* CLLocationManagerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B63ED0E226B3E7FA00A9DAD1 /* CLLocationManagerMock.swift */; }; B63ED0E526BB8FB900A9DAD1 /* SharingMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = B63ED0E426BB8FB900A9DAD1 /* SharingMenu.swift */; }; - B642738227B65BAC0005DFD1 /* SecureVaultErrorReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B642738127B65BAC0005DFD1 /* SecureVaultErrorReporter.swift */; }; + B642738227B65BAC0005DFD1 /* SecureVaultReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B642738127B65BAC0005DFD1 /* SecureVaultReporter.swift */; }; B643BF1427ABF772000BACEC /* NSWorkspaceExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B643BF1327ABF772000BACEC /* NSWorkspaceExtension.swift */; }; B644B43D29D56829003FA9AB /* SearchNonexistentDomainTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B644B43929D565DB003FA9AB /* SearchNonexistentDomainTests.swift */; }; B644B43E29D5682B003FA9AB /* SearchNonexistentDomainTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B644B43929D565DB003FA9AB /* SearchNonexistentDomainTests.swift */; }; @@ -2885,7 +2099,6 @@ B64E42AC2B909DC9006C1346 /* test.pdf in Resources */ = {isa = PBXBuildFile; fileRef = B64E42AA2B909DC9006C1346 /* test.pdf */; }; B65211252B29A42C00B30633 /* BookmarkStoreMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA652CDA25DDAB32009059CC /* BookmarkStoreMock.swift */; }; B65211262B29A42E00B30633 /* BookmarkStoreMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA652CDA25DDAB32009059CC /* BookmarkStoreMock.swift */; }; - B65211272B29A43000B30633 /* BookmarkStoreMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA652CDA25DDAB32009059CC /* BookmarkStoreMock.swift */; }; B65349AA265CF45000DCC645 /* DispatchQueueExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65349A9265CF45000DCC645 /* DispatchQueueExtensionsTests.swift */; }; B655124829A79465009BFE1C /* NavigationActionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66B9C5B29A5EBAD0010E8F3 /* NavigationActionExtension.swift */; }; B655124929A79465009BFE1C /* NavigationActionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66B9C5B29A5EBAD0010E8F3 /* NavigationActionExtension.swift */; }; @@ -2898,10 +2111,8 @@ B657841F25FA497600D8DB33 /* NSException+Catch.swift in Sources */ = {isa = PBXBuildFile; fileRef = B657841E25FA497600D8DB33 /* NSException+Catch.swift */; }; B658BAB62B0F845D00D1F2C7 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = B658BAB52B0F845D00D1F2C7 /* Localizable.xcstrings */; }; B658BAB72B0F848D00D1F2C7 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = B658BAB52B0F845D00D1F2C7 /* Localizable.xcstrings */; }; - B658BAB92B0F849100D1F2C7 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = B658BAB52B0F845D00D1F2C7 /* Localizable.xcstrings */; }; B65C7DFB2B886CF0001E2D5C /* WKPDFHUDViewWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65C7DFA2B886CF0001E2D5C /* WKPDFHUDViewWrapper.swift */; }; B65C7DFC2B886CF0001E2D5C /* WKPDFHUDViewWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65C7DFA2B886CF0001E2D5C /* WKPDFHUDViewWrapper.swift */; }; - B65C7DFD2B886CF0001E2D5C /* WKPDFHUDViewWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65C7DFA2B886CF0001E2D5C /* WKPDFHUDViewWrapper.swift */; }; B65CD8CB2B316DF100A595BB /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = B65CD8CA2B316DF100A595BB /* SnapshotTesting */; }; B65CD8CD2B316DFC00A595BB /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = B65CD8CC2B316DFC00A595BB /* SnapshotTesting */; }; B65CD8CF2B316E0200A595BB /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = B65CD8CE2B316E0200A595BB /* SnapshotTesting */; }; @@ -2917,14 +2128,12 @@ B65DA5F52A77D3FA00CBEE8D /* BundleExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6106B9D26A565DA0013B453 /* BundleExtension.swift */; }; B65E5DAF2B74DE6D00480415 /* TrackerNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65E5DAE2B74DE6D00480415 /* TrackerNetwork.swift */; }; B65E5DB02B74E6A900480415 /* TrackerNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65E5DAE2B74DE6D00480415 /* TrackerNetwork.swift */; }; - B65E5DB12B74E6AA00480415 /* TrackerNetwork.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65E5DAE2B74DE6D00480415 /* TrackerNetwork.swift */; }; B65E6B9E26D9EC0800095F96 /* CircularProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65E6B9D26D9EC0800095F96 /* CircularProgressView.swift */; }; B65E6BA026D9F10600095F96 /* NSBezierPathExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B65E6B9F26D9F10600095F96 /* NSBezierPathExtension.swift */; }; B6619EF62B10DFF700CD9186 /* InstructionsFormatParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6619EF52B10DFF700CD9186 /* InstructionsFormatParserTests.swift */; }; B6619EF72B10DFF700CD9186 /* InstructionsFormatParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6619EF52B10DFF700CD9186 /* InstructionsFormatParserTests.swift */; }; B6619EFB2B111CC500CD9186 /* InstructionsFormatParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6619EF82B111CBE00CD9186 /* InstructionsFormatParser.swift */; }; B6619EFC2B111CC600CD9186 /* InstructionsFormatParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6619EF82B111CBE00CD9186 /* InstructionsFormatParser.swift */; }; - B6619EFE2B111CCC00CD9186 /* InstructionsFormatParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6619EF82B111CBE00CD9186 /* InstructionsFormatParser.swift */; }; B6619F032B17123200CD9186 /* DataImportViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6619F022B17123200CD9186 /* DataImportViewModelTests.swift */; }; B6619F042B17123200CD9186 /* DataImportViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6619F022B17123200CD9186 /* DataImportViewModelTests.swift */; }; B6619F062B17138D00CD9186 /* DataImportSourceViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6619F052B17138D00CD9186 /* DataImportSourceViewModelTests.swift */; }; @@ -2936,12 +2145,10 @@ B66260E629ACAE4B00E9E3EE /* NavigationHotkeyHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66260E529ACAE4B00E9E3EE /* NavigationHotkeyHandler.swift */; }; B66260E729ACAE4B00E9E3EE /* NavigationHotkeyHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66260E529ACAE4B00E9E3EE /* NavigationHotkeyHandler.swift */; }; B66260E829ACD0C900E9E3EE /* DuckPlayerTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C416A6294A4AE500C4F2E7 /* DuckPlayerTabExtension.swift */; }; - B662D3D92755D7AD0035D4D6 /* PixelStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B662D3D82755D7AD0035D4D6 /* PixelStoreTests.swift */; }; B662D3DE275613BB0035D4D6 /* EncryptionKeyStoreMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B662D3DD275613BB0035D4D6 /* EncryptionKeyStoreMock.swift */; }; B662D3DF275616FF0035D4D6 /* EncryptionKeyStoreMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B662D3DD275613BB0035D4D6 /* EncryptionKeyStoreMock.swift */; }; B6656E0D2B29C733008798A1 /* FileImportViewLocalizationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6656E0C2B29C733008798A1 /* FileImportViewLocalizationTests.swift */; }; B6656E0E2B29C733008798A1 /* FileImportViewLocalizationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6656E0C2B29C733008798A1 /* FileImportViewLocalizationTests.swift */; }; - B6656E5B2B2ADB1C008798A1 /* RequestFilePermissionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5F5832B03580A008DB58A /* RequestFilePermissionView.swift */; }; B6676BE12AA986A700525A21 /* AddressBarTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6676BE02AA986A700525A21 /* AddressBarTextEditor.swift */; }; B6676BE22AA986A700525A21 /* AddressBarTextEditor.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6676BE02AA986A700525A21 /* AddressBarTextEditor.swift */; }; B6685E3D29A602D90043D2EE /* ExternalAppSchemeHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = B687B7CB2947A1E9001DEA6F /* ExternalAppSchemeHandler.swift */; }; @@ -2951,13 +2158,10 @@ B6685E4329A61C470043D2EE /* DownloadsTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6685E4129A61C460043D2EE /* DownloadsTabExtension.swift */; }; B66CA41E2AD910B300447CF0 /* DataImportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66CA41D2AD910B300447CF0 /* DataImportView.swift */; }; B66CA41F2AD910B300447CF0 /* DataImportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66CA41D2AD910B300447CF0 /* DataImportView.swift */; }; - B66CA4212AD910B300447CF0 /* DataImportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B66CA41D2AD910B300447CF0 /* DataImportView.swift */; }; B677FC4F2B06376B0099EB04 /* ReportFeedbackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B677FC4E2B06376B0099EB04 /* ReportFeedbackView.swift */; }; B677FC502B06376B0099EB04 /* ReportFeedbackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B677FC4E2B06376B0099EB04 /* ReportFeedbackView.swift */; }; - B677FC522B06376B0099EB04 /* ReportFeedbackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B677FC4E2B06376B0099EB04 /* ReportFeedbackView.swift */; }; B677FC542B064A9C0099EB04 /* DataImportViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B677FC532B064A9C0099EB04 /* DataImportViewModel.swift */; }; B677FC552B064A9C0099EB04 /* DataImportViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B677FC532B064A9C0099EB04 /* DataImportViewModel.swift */; }; - B677FC572B064A9C0099EB04 /* DataImportViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B677FC532B064A9C0099EB04 /* DataImportViewModel.swift */; }; B67C6C3D2654B897006C872E /* WebViewExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67C6C3C2654B897006C872E /* WebViewExtensionTests.swift */; }; B67C6C422654BF49006C872E /* DuckDuckGo-Symbol.jpg in Resources */ = {isa = PBXBuildFile; fileRef = B67C6C412654BF49006C872E /* DuckDuckGo-Symbol.jpg */; }; B67C6C472654C643006C872E /* FileManagerExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B67C6C462654C643006C872E /* FileManagerExtensionTests.swift */; }; @@ -2966,15 +2170,12 @@ B6830963274CDEC7004B46BB /* FireproofDomainsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6830962274CDEC7004B46BB /* FireproofDomainsStore.swift */; }; B68412142B694BA10092F66A /* NSObject+performSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = B68412132B694BA10092F66A /* NSObject+performSelector.m */; }; B68412152B694BA10092F66A /* NSObject+performSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = B68412132B694BA10092F66A /* NSObject+performSelector.m */; }; - B68412162B694BA10092F66A /* NSObject+performSelector.m in Sources */ = {isa = PBXBuildFile; fileRef = B68412132B694BA10092F66A /* NSObject+performSelector.m */; }; B684121C2B6A1D880092F66A /* ErrorPageHTMLTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B684121B2B6A1D880092F66A /* ErrorPageHTMLTemplate.swift */; }; B684121D2B6A1D880092F66A /* ErrorPageHTMLTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B684121B2B6A1D880092F66A /* ErrorPageHTMLTemplate.swift */; }; - B684121E2B6A1D880092F66A /* ErrorPageHTMLTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B684121B2B6A1D880092F66A /* ErrorPageHTMLTemplate.swift */; }; B68412202B6A30680092F66A /* StringExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B684121F2B6A30680092F66A /* StringExtensionTests.swift */; }; B68412212B6A30680092F66A /* StringExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B684121F2B6A30680092F66A /* StringExtensionTests.swift */; }; B68412272B6A68C10092F66A /* WKBackForwardListItemExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68412242B6A67920092F66A /* WKBackForwardListItemExtension.swift */; }; B68412282B6A68C20092F66A /* WKBackForwardListItemExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68412242B6A67920092F66A /* WKBackForwardListItemExtension.swift */; }; - B68412292B6A68C90092F66A /* WKBackForwardListItemExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68412242B6A67920092F66A /* WKBackForwardListItemExtension.swift */; }; B68458B025C7E76A00DC17B6 /* WindowManager+StateRestoration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68458AF25C7E76A00DC17B6 /* WindowManager+StateRestoration.swift */; }; B68458B825C7E8B200DC17B6 /* Tab+NSSecureCoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68458B725C7E8B200DC17B6 /* Tab+NSSecureCoding.swift */; }; B68458C025C7E9E000DC17B6 /* TabCollectionViewModel+NSSecureCoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68458BF25C7E9E000DC17B6 /* TabCollectionViewModel+NSSecureCoding.swift */; }; @@ -2992,19 +2193,14 @@ B689ECD526C247DB006FB0C5 /* BackForwardListItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B689ECD426C247DB006FB0C5 /* BackForwardListItem.swift */; }; B68C2FB227706E6A00BF2C7D /* ProcessExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68C2FB127706E6A00BF2C7D /* ProcessExtension.swift */; }; B68C92C1274E3EF4002AC6B0 /* PopUpWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68C92C0274E3EF4002AC6B0 /* PopUpWindow.swift */; }; - B68C92C42750EF76002AC6B0 /* PixelDataRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68C92C32750EF76002AC6B0 /* PixelDataRecord.swift */; }; B68D21C32ACBC916002DA3C2 /* ContentBlockingMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BDD9F429409DDD00F68088 /* ContentBlockingMock.swift */; }; B68D21C42ACBC917002DA3C2 /* ContentBlockingMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BDD9F429409DDD00F68088 /* ContentBlockingMock.swift */; }; B68D21C82ACBC96D002DA3C2 /* MockPrivacyConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B626A76F29928C4100053070 /* MockPrivacyConfiguration.swift */; }; B68D21C92ACBC96E002DA3C2 /* MockPrivacyConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B626A76F29928C4100053070 /* MockPrivacyConfiguration.swift */; }; - B68D21CA2ACBC971002DA3C2 /* MockPrivacyConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B626A76F29928C4100053070 /* MockPrivacyConfiguration.swift */; }; - B68D21CB2ACBC9A3002DA3C2 /* ContentBlockingMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BDD9F429409DDD00F68088 /* ContentBlockingMock.swift */; }; B68D21CF2ACBC9FC002DA3C2 /* ContentBlockerRulesManagerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B610F2E727AA397100FCEBE9 /* ContentBlockerRulesManagerMock.swift */; }; B68D21D02ACBC9FD002DA3C2 /* ContentBlockerRulesManagerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B610F2E727AA397100FCEBE9 /* ContentBlockerRulesManagerMock.swift */; }; - B68D21D22ACBCA01002DA3C2 /* ContentBlockerRulesManagerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B610F2E727AA397100FCEBE9 /* ContentBlockerRulesManagerMock.swift */; }; B690152C2ACBF4DA00AD0BAB /* MenuPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = B690152B2ACBF4DA00AD0BAB /* MenuPreview.swift */; }; B690152D2ACBF4DA00AD0BAB /* MenuPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = B690152B2ACBF4DA00AD0BAB /* MenuPreview.swift */; }; - B690152F2ACBF4DA00AD0BAB /* MenuPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = B690152B2ACBF4DA00AD0BAB /* MenuPreview.swift */; }; B693766E2B6B5F27005BD9D4 /* ErrorPageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B693766D2B6B5F26005BD9D4 /* ErrorPageTests.swift */; }; B693766F2B6B5F27005BD9D4 /* ErrorPageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B693766D2B6B5F26005BD9D4 /* ErrorPageTests.swift */; }; B693954B26F04BEB0015B914 /* MouseOverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B693953D26F04BE70015B914 /* MouseOverView.swift */; }; @@ -3027,13 +2223,10 @@ B698E5042908011E00A746A8 /* AppKitPrivateMethodsAvailabilityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B698E5032908011E00A746A8 /* AppKitPrivateMethodsAvailabilityTests.swift */; }; B69A14F22B4D6FE800B9417D /* AddBookmarkFolderPopoverViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69A14F12B4D6FE800B9417D /* AddBookmarkFolderPopoverViewModel.swift */; }; B69A14F32B4D6FE800B9417D /* AddBookmarkFolderPopoverViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69A14F12B4D6FE800B9417D /* AddBookmarkFolderPopoverViewModel.swift */; }; - B69A14F42B4D6FE800B9417D /* AddBookmarkFolderPopoverViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69A14F12B4D6FE800B9417D /* AddBookmarkFolderPopoverViewModel.swift */; }; B69A14F62B4D701F00B9417D /* AddBookmarkPopoverViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69A14F52B4D701F00B9417D /* AddBookmarkPopoverViewModel.swift */; }; B69A14F72B4D701F00B9417D /* AddBookmarkPopoverViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69A14F52B4D701F00B9417D /* AddBookmarkPopoverViewModel.swift */; }; - B69A14F82B4D701F00B9417D /* AddBookmarkPopoverViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69A14F52B4D701F00B9417D /* AddBookmarkPopoverViewModel.swift */; }; B69A14FA2B4D705D00B9417D /* BookmarkFolderPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69A14F92B4D705D00B9417D /* BookmarkFolderPicker.swift */; }; B69A14FB2B4D705D00B9417D /* BookmarkFolderPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69A14F92B4D705D00B9417D /* BookmarkFolderPicker.swift */; }; - B69A14FC2B4D705D00B9417D /* BookmarkFolderPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69A14F92B4D705D00B9417D /* BookmarkFolderPicker.swift */; }; B69B503A2726A12500758A2B /* StatisticsLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69B50342726A11F00758A2B /* StatisticsLoader.swift */; }; B69B503B2726A12500758A2B /* Atb.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69B50352726A11F00758A2B /* Atb.swift */; }; B69B503C2726A12500758A2B /* StatisticsStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69B50362726A12000758A2B /* StatisticsStore.swift */; }; @@ -3053,31 +2246,23 @@ B69B50572727D16900758A2B /* AtbAndVariantCleanup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B69B50562727D16900758A2B /* AtbAndVariantCleanup.swift */; }; B6A22B622B1E29D000ECD2BA /* DataImportSummaryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A22B612B1E29D000ECD2BA /* DataImportSummaryViewModel.swift */; }; B6A22B632B1E29D000ECD2BA /* DataImportSummaryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A22B612B1E29D000ECD2BA /* DataImportSummaryViewModel.swift */; }; - B6A22B652B1E29D000ECD2BA /* DataImportSummaryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A22B612B1E29D000ECD2BA /* DataImportSummaryViewModel.swift */; }; B6A5A27125B9377300AA7ADA /* StatePersistenceService.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A5A27025B9377300AA7ADA /* StatePersistenceService.swift */; }; B6A5A27925B93FFF00AA7ADA /* StateRestorationManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A5A27825B93FFE00AA7ADA /* StateRestorationManagerTests.swift */; }; B6A5A27E25B9403E00AA7ADA /* FileStoreMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A5A27D25B9403E00AA7ADA /* FileStoreMock.swift */; }; B6A5A2A025B96E8300AA7ADA /* AppStateChangePublisherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A5A29F25B96E8300AA7ADA /* AppStateChangePublisherTests.swift */; }; B6A5A2A825BAA35500AA7ADA /* WindowManagerStateRestorationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A5A2A725BAA35500AA7ADA /* WindowManagerStateRestorationTests.swift */; }; B6A924D92664C72E001A28CA /* WebKitDownloadTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A924D82664C72D001A28CA /* WebKitDownloadTask.swift */; }; - B6A9E45326142B070067D1B9 /* Pixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A9E45226142B070067D1B9 /* Pixel.swift */; }; B6A9E46B2614618A0067D1B9 /* OperatingSystemVersionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A9E46A2614618A0067D1B9 /* OperatingSystemVersionExtension.swift */; }; - B6A9E47726146A570067D1B9 /* PixelEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A9E47626146A570067D1B9 /* PixelEvent.swift */; }; - B6A9E47F26146A800067D1B9 /* PixelArguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A9E47E26146A800067D1B9 /* PixelArguments.swift */; }; - B6A9E48426146AAB0067D1B9 /* PixelParameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6A9E48326146AAB0067D1B9 /* PixelParameters.swift */; }; B6AA64732994B43300D99CD6 /* FutureExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AA64722994B43300D99CD6 /* FutureExtensionTests.swift */; }; B6AA64742994B43300D99CD6 /* FutureExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AA64722994B43300D99CD6 /* FutureExtensionTests.swift */; }; B6AAAC2D260330580029438D /* PublishedAfter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AAAC2C260330580029438D /* PublishedAfter.swift */; }; B6AAAC3E26048F690029438D /* RandomAccessCollectionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AAAC3D26048F690029438D /* RandomAccessCollectionExtension.swift */; }; B6ABC5962B4861D4008343B9 /* FocusableTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6ABC5952B4861D4008343B9 /* FocusableTextField.swift */; }; B6ABC5972B4861D4008343B9 /* FocusableTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6ABC5952B4861D4008343B9 /* FocusableTextField.swift */; }; - B6ABC5982B4861D4008343B9 /* FocusableTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6ABC5952B4861D4008343B9 /* FocusableTextField.swift */; }; B6ABD0CA2BC03F610000EB69 /* SecurityScopedFileURLController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6ABD0C92BC03F610000EB69 /* SecurityScopedFileURLController.swift */; }; B6ABD0CB2BC03F610000EB69 /* SecurityScopedFileURLController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6ABD0C92BC03F610000EB69 /* SecurityScopedFileURLController.swift */; }; - B6ABD0CC2BC03F610000EB69 /* SecurityScopedFileURLController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6ABD0C92BC03F610000EB69 /* SecurityScopedFileURLController.swift */; }; B6ABD0CE2BC042CE0000EB69 /* NSURL+sandboxExtensionRetainCount.m in Sources */ = {isa = PBXBuildFile; fileRef = B6ABD0CD2BC042CE0000EB69 /* NSURL+sandboxExtensionRetainCount.m */; }; B6ABD0CF2BC042CE0000EB69 /* NSURL+sandboxExtensionRetainCount.m in Sources */ = {isa = PBXBuildFile; fileRef = B6ABD0CD2BC042CE0000EB69 /* NSURL+sandboxExtensionRetainCount.m */; }; - B6ABD0D02BC042CE0000EB69 /* NSURL+sandboxExtensionRetainCount.m in Sources */ = {isa = PBXBuildFile; fileRef = B6ABD0CD2BC042CE0000EB69 /* NSURL+sandboxExtensionRetainCount.m */; }; B6AE39F129373AF200C37AA4 /* EmptyAttributionRulesProver.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6AE39F029373AF200C37AA4 /* EmptyAttributionRulesProver.swift */; }; B6AE39F329374AEC00C37AA4 /* OHHTTPStubs in Frameworks */ = {isa = PBXBuildFile; productRef = B6AE39F229374AEC00C37AA4 /* OHHTTPStubs */; }; B6AE39F529374AEC00C37AA4 /* OHHTTPStubsSwift in Frameworks */ = {isa = PBXBuildFile; productRef = B6AE39F429374AEC00C37AA4 /* OHHTTPStubsSwift */; }; @@ -3095,43 +2280,32 @@ B6B3E0E12657EA7A0040E0A2 /* NSScreenExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B3E0DC2657E9CF0040E0A2 /* NSScreenExtension.swift */; }; B6B4D1C52B0B3B5400C26286 /* DataImportReportModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B4D1C42B0B3B5400C26286 /* DataImportReportModel.swift */; }; B6B4D1C62B0B3B5400C26286 /* DataImportReportModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B4D1C42B0B3B5400C26286 /* DataImportReportModel.swift */; }; - B6B4D1C82B0B3B5400C26286 /* DataImportReportModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B4D1C42B0B3B5400C26286 /* DataImportReportModel.swift */; }; B6B4D1CA2B0C8C9200C26286 /* FirefoxCompatibilityPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B4D1C92B0C8C9200C26286 /* FirefoxCompatibilityPreferences.swift */; }; B6B4D1CB2B0C8C9200C26286 /* FirefoxCompatibilityPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B4D1C92B0C8C9200C26286 /* FirefoxCompatibilityPreferences.swift */; }; - B6B4D1CD2B0C8C9200C26286 /* FirefoxCompatibilityPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B4D1C92B0C8C9200C26286 /* FirefoxCompatibilityPreferences.swift */; }; B6B4D1CF2B0E0DD000C26286 /* DataImportNoDataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B4D1CE2B0E0DD000C26286 /* DataImportNoDataView.swift */; }; B6B4D1D02B0E0DD000C26286 /* DataImportNoDataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B4D1CE2B0E0DD000C26286 /* DataImportNoDataView.swift */; }; - B6B4D1D22B0E0DD000C26286 /* DataImportNoDataView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B4D1CE2B0E0DD000C26286 /* DataImportNoDataView.swift */; }; B6B5F57F2B024105008DB58A /* DataImportSummaryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5F57E2B024105008DB58A /* DataImportSummaryView.swift */; }; B6B5F5802B024105008DB58A /* DataImportSummaryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5F57E2B024105008DB58A /* DataImportSummaryView.swift */; }; - B6B5F5822B024105008DB58A /* DataImportSummaryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5F57E2B024105008DB58A /* DataImportSummaryView.swift */; }; B6B5F5842B03580A008DB58A /* RequestFilePermissionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5F5832B03580A008DB58A /* RequestFilePermissionView.swift */; }; B6B5F5852B03580A008DB58A /* RequestFilePermissionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5F5832B03580A008DB58A /* RequestFilePermissionView.swift */; }; B6B5F5892B03673B008DB58A /* BrowserImportMoreInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5F5882B03673B008DB58A /* BrowserImportMoreInfoView.swift */; }; B6B5F58A2B03673B008DB58A /* BrowserImportMoreInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5F5882B03673B008DB58A /* BrowserImportMoreInfoView.swift */; }; - B6B5F58C2B03673B008DB58A /* BrowserImportMoreInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B5F5882B03673B008DB58A /* BrowserImportMoreInfoView.swift */; }; B6B71C582B23379600487131 /* NSLayoutConstraintExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B71C572B23379600487131 /* NSLayoutConstraintExtension.swift */; }; B6B71C592B23379600487131 /* NSLayoutConstraintExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B71C572B23379600487131 /* NSLayoutConstraintExtension.swift */; }; - B6B71C5A2B23379600487131 /* NSLayoutConstraintExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B71C572B23379600487131 /* NSLayoutConstraintExtension.swift */; }; B6B77BE8297973D4001E68A1 /* Navigation in Frameworks */ = {isa = PBXBuildFile; productRef = B6B77BE7297973D4001E68A1 /* Navigation */; }; B6BBF1702744CDE1004F850E /* CoreDataStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BBF16F2744CDE1004F850E /* CoreDataStoreTests.swift */; }; B6BBF1722744CE36004F850E /* FireproofDomainsStoreMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BBF1712744CE36004F850E /* FireproofDomainsStoreMock.swift */; }; B6BBF17427475B15004F850E /* PopupBlockedPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BBF17327475B15004F850E /* PopupBlockedPopover.swift */; }; B6BCC51E2AFCD9ED002C5499 /* DataImportSourcePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BCC51D2AFCD9ED002C5499 /* DataImportSourcePicker.swift */; }; B6BCC51F2AFCD9ED002C5499 /* DataImportSourcePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BCC51D2AFCD9ED002C5499 /* DataImportSourcePicker.swift */; }; - B6BCC5212AFCD9ED002C5499 /* DataImportSourcePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BCC51D2AFCD9ED002C5499 /* DataImportSourcePicker.swift */; }; B6BCC5232AFCDABB002C5499 /* DataImportSourceViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BCC5222AFCDABB002C5499 /* DataImportSourceViewModel.swift */; }; B6BCC5242AFCDABB002C5499 /* DataImportSourceViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BCC5222AFCDABB002C5499 /* DataImportSourceViewModel.swift */; }; - B6BCC5262AFCDABB002C5499 /* DataImportSourceViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BCC5222AFCDABB002C5499 /* DataImportSourceViewModel.swift */; }; B6BCC53B2AFD15DF002C5499 /* DataImportProfilePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BCC53A2AFD15DF002C5499 /* DataImportProfilePicker.swift */; }; B6BCC53C2AFD15DF002C5499 /* DataImportProfilePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BCC53A2AFD15DF002C5499 /* DataImportProfilePicker.swift */; }; - B6BCC53E2AFD15DF002C5499 /* DataImportProfilePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BCC53A2AFD15DF002C5499 /* DataImportProfilePicker.swift */; }; B6BCC54A2AFDF24B002C5499 /* TaskWithProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BCC5492AFDF24B002C5499 /* TaskWithProgress.swift */; }; B6BCC54B2AFDF24B002C5499 /* TaskWithProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BCC5492AFDF24B002C5499 /* TaskWithProgress.swift */; }; - B6BCC54D2AFDF24B002C5499 /* TaskWithProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BCC5492AFDF24B002C5499 /* TaskWithProgress.swift */; }; B6BCC54F2AFE4F7D002C5499 /* DataImportTypePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BCC54E2AFE4F7D002C5499 /* DataImportTypePicker.swift */; }; B6BCC5502AFE4F7D002C5499 /* DataImportTypePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BCC54E2AFE4F7D002C5499 /* DataImportTypePicker.swift */; }; - B6BCC5522AFE4F7D002C5499 /* DataImportTypePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BCC54E2AFE4F7D002C5499 /* DataImportTypePicker.swift */; }; B6BDDA012942389000F68088 /* TabExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BDDA002942389000F68088 /* TabExtensions.swift */; }; B6BE9FAA293F7955006363C6 /* ModalSheetCancellable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BE9FA9293F7955006363C6 /* ModalSheetCancellable.swift */; }; B6BF5D852946FFDA006742B1 /* PrivacyDashboardTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6BF5D842946FFDA006742B1 /* PrivacyDashboardTabExtension.swift */; }; @@ -3160,15 +2334,12 @@ B6C843DB2BA1CAB6006FDEC3 /* FilePresenterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C843D92BA1CAB6006FDEC3 /* FilePresenterTests.swift */; }; B6C8CAA72AD010DD0060E1CD /* YandexDataImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C8CAA62AD010DD0060E1CD /* YandexDataImporter.swift */; }; B6C8CAA82AD010DD0060E1CD /* YandexDataImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C8CAA62AD010DD0060E1CD /* YandexDataImporter.swift */; }; - B6C8CAAA2AD010DD0060E1CD /* YandexDataImporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6C8CAA62AD010DD0060E1CD /* YandexDataImporter.swift */; }; B6CA4824298CDC2E0067ECCE /* AdClickAttributionTabExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6CA4823298CDC2E0067ECCE /* AdClickAttributionTabExtensionTests.swift */; }; B6CA4825298CE4B70067ECCE /* AdClickAttributionTabExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6CA4823298CDC2E0067ECCE /* AdClickAttributionTabExtensionTests.swift */; }; B6CC26682BAD959500F53F8D /* DownloadProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6CC26672BAD959500F53F8D /* DownloadProgress.swift */; }; B6CC26692BAD959500F53F8D /* DownloadProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6CC26672BAD959500F53F8D /* DownloadProgress.swift */; }; - B6CC266A2BAD959500F53F8D /* DownloadProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6CC26672BAD959500F53F8D /* DownloadProgress.swift */; }; B6CC266C2BAD9CD800F53F8D /* FileProgressPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6CC266B2BAD9CD800F53F8D /* FileProgressPresenter.swift */; }; B6CC266D2BAD9CD800F53F8D /* FileProgressPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6CC266B2BAD9CD800F53F8D /* FileProgressPresenter.swift */; }; - B6CC266E2BAD9CD800F53F8D /* FileProgressPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6CC266B2BAD9CD800F53F8D /* FileProgressPresenter.swift */; }; B6D574B429472253008ED1B6 /* FBProtectionTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D574B329472253008ED1B6 /* FBProtectionTabExtension.swift */; }; B6D6A5DD2982A4CE001F5F11 /* Tab+Navigation.swift in Sources */ = {isa = PBXBuildFile; fileRef = B61E2CD4294346C000773D8A /* Tab+Navigation.swift */; }; B6DA06E12913AEDC00225DE2 /* TestNavigationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA06E02913AEDB00225DE2 /* TestNavigationDelegate.swift */; }; @@ -3176,39 +2347,29 @@ B6DA06E42913ECEE00225DE2 /* ContextMenuManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA06E32913ECEE00225DE2 /* ContextMenuManager.swift */; }; B6DA06E62913F39400225DE2 /* MenuItemSelectors.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA06E52913F39400225DE2 /* MenuItemSelectors.swift */; }; B6DA06E8291401D700225DE2 /* WKMenuItemIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA06E7291401D700225DE2 /* WKMenuItemIdentifier.swift */; }; - B6DA44022616B28300DD1EC2 /* PixelDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA44012616B28300DD1EC2 /* PixelDataStore.swift */; }; - B6DA44082616B30600DD1EC2 /* PixelDataModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B6DA44062616B30600DD1EC2 /* PixelDataModel.xcdatamodeld */; }; - B6DA44112616C0FC00DD1EC2 /* PixelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA44102616C0FC00DD1EC2 /* PixelTests.swift */; }; B6DA44172616C13800DD1EC2 /* OHHTTPStubs in Frameworks */ = {isa = PBXBuildFile; productRef = B6DA44162616C13800DD1EC2 /* OHHTTPStubs */; }; B6DA44192616C13800DD1EC2 /* OHHTTPStubsSwift in Frameworks */ = {isa = PBXBuildFile; productRef = B6DA44182616C13800DD1EC2 /* OHHTTPStubsSwift */; }; B6DA441E2616C84600DD1EC2 /* PixelStoreMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA441D2616C84600DD1EC2 /* PixelStoreMock.swift */; }; - B6DA44232616CABC00DD1EC2 /* PixelArgumentsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA44222616CABC00DD1EC2 /* PixelArgumentsTests.swift */; }; B6DB3AEF278D5C370024C5C4 /* URLSessionExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DB3AEE278D5C370024C5C4 /* URLSessionExtension.swift */; }; B6DB3AF6278EA0130024C5C4 /* BundleExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6106B9D26A565DA0013B453 /* BundleExtension.swift */; }; B6DB3CF926A00E2D00D459B7 /* AVCaptureDevice+SwizzledAuthState.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DB3CF826A00E2D00D459B7 /* AVCaptureDevice+SwizzledAuthState.swift */; }; B6DB3CFB26A17CB800D459B7 /* PermissionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DB3CFA26A17CB800D459B7 /* PermissionModel.swift */; }; B6DE57F62B05EA9000CD54B9 /* SheetHostingWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DE57F52B05EA9000CD54B9 /* SheetHostingWindow.swift */; }; B6DE57F72B05EA9000CD54B9 /* SheetHostingWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DE57F52B05EA9000CD54B9 /* SheetHostingWindow.swift */; }; - B6DE57F92B05EA9000CD54B9 /* SheetHostingWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DE57F52B05EA9000CD54B9 /* SheetHostingWindow.swift */; }; B6E1491029A5C30500AAFBE8 /* ContentBlockingTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D574B12947224C008ED1B6 /* ContentBlockingTabExtension.swift */; }; B6E1491129A5C30A00AAFBE8 /* FBProtectionTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6D574B329472253008ED1B6 /* FBProtectionTabExtension.swift */; }; B6E319382953446000DD3BCF /* Assertions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E319372953446000DD3BCF /* Assertions.swift */; }; B6E3E5502BBFCDEE00A41922 /* OpenDownloadsCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E3E54F2BBFCDEE00A41922 /* OpenDownloadsCellView.swift */; }; B6E3E5512BBFCDEE00A41922 /* OpenDownloadsCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E3E54F2BBFCDEE00A41922 /* OpenDownloadsCellView.swift */; }; - B6E3E5522BBFCDEE00A41922 /* OpenDownloadsCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E3E54F2BBFCDEE00A41922 /* OpenDownloadsCellView.swift */; }; B6E3E5542BBFCEE300A41922 /* NoDownloadsCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E3E5532BBFCEE300A41922 /* NoDownloadsCellView.swift */; }; B6E3E5552BBFCEE300A41922 /* NoDownloadsCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E3E5532BBFCEE300A41922 /* NoDownloadsCellView.swift */; }; - B6E3E5562BBFCEE300A41922 /* NoDownloadsCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E3E5532BBFCEE300A41922 /* NoDownloadsCellView.swift */; }; B6E3E5582BBFD51400A41922 /* PreviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E3E5572BBFD51400A41922 /* PreviewViewController.swift */; }; B6E3E5592BBFD51400A41922 /* PreviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E3E5572BBFD51400A41922 /* PreviewViewController.swift */; }; - B6E3E55A2BBFD51400A41922 /* PreviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E3E5572BBFD51400A41922 /* PreviewViewController.swift */; }; B6E3E55B2BC0041900A41922 /* DownloadListStoreMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B693956026F1C1BC0015B914 /* DownloadListStoreMock.swift */; }; B6E3E55C2BC0041A00A41922 /* DownloadListStoreMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B693956026F1C1BC0015B914 /* DownloadListStoreMock.swift */; }; - B6E3E55D2BC0041C00A41922 /* DownloadListStoreMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B693956026F1C1BC0015B914 /* DownloadListStoreMock.swift */; }; B6E61EE3263AC0C8004E11AB /* FileManagerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E61EE2263AC0C8004E11AB /* FileManagerExtension.swift */; }; B6E6B9E32BA1F5F1008AA7E1 /* FilePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E6B9E22BA1F5F1008AA7E1 /* FilePresenter.swift */; }; B6E6B9E42BA1F5F1008AA7E1 /* FilePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E6B9E22BA1F5F1008AA7E1 /* FilePresenter.swift */; }; - B6E6B9E52BA1F5F1008AA7E1 /* FilePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E6B9E22BA1F5F1008AA7E1 /* FilePresenter.swift */; }; B6E6B9F62BA1FD90008AA7E1 /* SandboxTestTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E6B9F52BA1FD90008AA7E1 /* SandboxTestTool.swift */; }; B6E6BA042BA1FE05008AA7E1 /* FilePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E6B9E22BA1F5F1008AA7E1 /* FilePresenter.swift */; }; B6E6BA052BA1FE09008AA7E1 /* URLExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA8EDF2324923E980071C2E8 /* URLExtension.swift */; }; @@ -3234,6 +2395,14 @@ B6EECB322BC40A1400B3CB77 /* FileManagerExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E61EE2263AC0C8004E11AB /* FileManagerExtension.swift */; }; B6EEDD7D2B8C69E900637EBC /* TabContentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6EEDD7C2B8C69E900637EBC /* TabContentTests.swift */; }; B6EEDD7E2B8C69E900637EBC /* TabContentTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6EEDD7C2B8C69E900637EBC /* TabContentTests.swift */; }; + B6F1B0222BCE5658005E863C /* BrokenSiteInfoTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F1B0212BCE5658005E863C /* BrokenSiteInfoTabExtension.swift */; }; + B6F1B0232BCE5658005E863C /* BrokenSiteInfoTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F1B0212BCE5658005E863C /* BrokenSiteInfoTabExtension.swift */; }; + B6F1B0262BCE5A50005E863C /* TabContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F1B0252BCE5A50005E863C /* TabContent.swift */; }; + B6F1B0272BCE5A50005E863C /* TabContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F1B0252BCE5A50005E863C /* TabContent.swift */; }; + B6F1B02A2BCE675C005E863C /* NetworkProtectionControllerTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F1B0292BCE675C005E863C /* NetworkProtectionControllerTabExtension.swift */; }; + B6F1B02B2BCE675C005E863C /* NetworkProtectionControllerTabExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F1B0292BCE675C005E863C /* NetworkProtectionControllerTabExtension.swift */; }; + B6F1B02E2BCE6B47005E863C /* TunnelControllerProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F1B02D2BCE6B47005E863C /* TunnelControllerProvider.swift */; }; + B6F1B02F2BCE6B47005E863C /* TunnelControllerProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F1B02D2BCE6B47005E863C /* TunnelControllerProvider.swift */; }; B6F1C80B2761C45400334924 /* LocalUnprotectedDomains.swift in Sources */ = {isa = PBXBuildFile; fileRef = 336B39E22726B4B700C417D3 /* LocalUnprotectedDomains.swift */; }; B6F41031264D2B23003DA42C /* ProgressExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F41030264D2B23003DA42C /* ProgressExtension.swift */; }; B6F56567299A414300A04298 /* WKWebViewMockingExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F56566299A414300A04298 /* WKWebViewMockingExtension.swift */; }; @@ -3250,44 +2419,54 @@ B6F92BAD2A6937B5002ABA6B /* OptionalExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = B637273C26CCF0C200C8CB02 /* OptionalExtension.swift */; }; B6F9BDDC2B45B7EE00677B33 /* WebsiteInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F9BDDB2B45B7EE00677B33 /* WebsiteInfo.swift */; }; B6F9BDDD2B45B7EE00677B33 /* WebsiteInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F9BDDB2B45B7EE00677B33 /* WebsiteInfo.swift */; }; - B6F9BDDE2B45B7EE00677B33 /* WebsiteInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F9BDDB2B45B7EE00677B33 /* WebsiteInfo.swift */; }; B6F9BDE42B45CD1900677B33 /* ModalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F9BDE32B45CD1900677B33 /* ModalView.swift */; }; B6F9BDE52B45CD1900677B33 /* ModalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F9BDE32B45CD1900677B33 /* ModalView.swift */; }; - B6F9BDE62B45CD1900677B33 /* ModalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6F9BDE32B45CD1900677B33 /* ModalView.swift */; }; B6FA893D269C423100588ECD /* PrivacyDashboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B6FA893C269C423100588ECD /* PrivacyDashboard.storyboard */; }; B6FA893F269C424500588ECD /* PrivacyDashboardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6FA893E269C424500588ECD /* PrivacyDashboardViewController.swift */; }; B6FA8941269C425400588ECD /* PrivacyDashboardPopover.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6FA8940269C425400588ECD /* PrivacyDashboardPopover.swift */; }; BB5789722B2CA70F0009DFE2 /* DataBrokerProtectionSubscriptionEventHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB5789712B2CA70F0009DFE2 /* DataBrokerProtectionSubscriptionEventHandler.swift */; }; - BB5789732B2CC0300009DFE2 /* DataBrokerProtectionSubscriptionEventHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB5789712B2CA70F0009DFE2 /* DataBrokerProtectionSubscriptionEventHandler.swift */; }; BBDFDC5A2B2B8A0900F62D90 /* DataBrokerProtectionExternalWaitlistPixels.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBDFDC592B2B8A0900F62D90 /* DataBrokerProtectionExternalWaitlistPixels.swift */; }; - BBDFDC5C2B2B8D7000F62D90 /* DataBrokerProtectionExternalWaitlistPixels.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBDFDC592B2B8A0900F62D90 /* DataBrokerProtectionExternalWaitlistPixels.swift */; }; BBDFDC5D2B2B8E2100F62D90 /* DataBrokerProtectionExternalWaitlistPixels.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBDFDC592B2B8A0900F62D90 /* DataBrokerProtectionExternalWaitlistPixels.swift */; }; + BD384AC92BBC821A00EF3735 /* vpn-dark-mode.json in Resources */ = {isa = PBXBuildFile; fileRef = BD384AC82BBC821100EF3735 /* vpn-dark-mode.json */; }; + BD384ACA2BBC821A00EF3735 /* vpn-light-mode.json in Resources */ = {isa = PBXBuildFile; fileRef = BD384AC72BBC821100EF3735 /* vpn-light-mode.json */; }; + BD384ACB2BBC821B00EF3735 /* vpn-dark-mode.json in Resources */ = {isa = PBXBuildFile; fileRef = BD384AC82BBC821100EF3735 /* vpn-dark-mode.json */; }; + BD384ACC2BBC821B00EF3735 /* vpn-light-mode.json in Resources */ = {isa = PBXBuildFile; fileRef = BD384AC72BBC821100EF3735 /* vpn-light-mode.json */; }; + BDA7647C2BC497BE00D0400C /* DefaultVPNLocationFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDA7647B2BC497BE00D0400C /* DefaultVPNLocationFormatter.swift */; }; + BDA7647D2BC497BE00D0400C /* DefaultVPNLocationFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDA7647B2BC497BE00D0400C /* DefaultVPNLocationFormatter.swift */; }; + BDA7647F2BC4998900D0400C /* DefaultVPNLocationFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDA7647B2BC497BE00D0400C /* DefaultVPNLocationFormatter.swift */; }; + BDA764802BC4998A00D0400C /* DefaultVPNLocationFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDA7647B2BC497BE00D0400C /* DefaultVPNLocationFormatter.swift */; }; + BDA764842BC49E3F00D0400C /* NetworkProtectionVPNCountryLabelsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEA3EEB02B24EBD000E8333A /* NetworkProtectionVPNCountryLabelsModel.swift */; }; + BDA764852BC49E4000D0400C /* NetworkProtectionVPNCountryLabelsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEA3EEB02B24EBD000E8333A /* NetworkProtectionVPNCountryLabelsModel.swift */; }; + BDA7648D2BC4E4EF00D0400C /* DefaultVPNLocationFormatterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDA7648C2BC4E4EF00D0400C /* DefaultVPNLocationFormatterTests.swift */; }; + BDA7648E2BC4E4EF00D0400C /* DefaultVPNLocationFormatterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDA7648C2BC4E4EF00D0400C /* DefaultVPNLocationFormatterTests.swift */; }; + BDA764912BC4E57200D0400C /* MockVPNLocationFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDA764902BC4E57200D0400C /* MockVPNLocationFormatter.swift */; }; + BDA764922BC4E57200D0400C /* MockVPNLocationFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDA764902BC4E57200D0400C /* MockVPNLocationFormatter.swift */; }; + BDADBDC92BD2BC2200421B9B /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = BDADBDC82BD2BC2200421B9B /* Lottie */; }; + BDADBDCB2BD2BC2800421B9B /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = BDADBDCA2BD2BC2800421B9B /* Lottie */; }; + BDADBDCC2BD2BC4D00421B9B /* vpn-dark-mode.json in Resources */ = {isa = PBXBuildFile; fileRef = BD384AC82BBC821100EF3735 /* vpn-dark-mode.json */; }; + BDADBDCD2BD2BC5700421B9B /* vpn-light-mode.json in Resources */ = {isa = PBXBuildFile; fileRef = BD384AC72BBC821100EF3735 /* vpn-light-mode.json */; }; + BDE981D92BBD10D600645880 /* vpn-dark-mode.json in Resources */ = {isa = PBXBuildFile; fileRef = BD384AC82BBC821100EF3735 /* vpn-dark-mode.json */; }; + BDE981DA2BBD10D600645880 /* vpn-light-mode.json in Resources */ = {isa = PBXBuildFile; fileRef = BD384AC72BBC821100EF3735 /* vpn-light-mode.json */; }; C1372EF42BBC5BAD003F8793 /* SecureTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1372EF32BBC5BAD003F8793 /* SecureTextField.swift */; }; C1372EF52BBC5BAD003F8793 /* SecureTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1372EF32BBC5BAD003F8793 /* SecureTextField.swift */; }; - C1372EF62BBC5BAD003F8793 /* SecureTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1372EF32BBC5BAD003F8793 /* SecureTextField.swift */; }; C13909EF2B85FD4E001626ED /* AutofillActionExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C13909EE2B85FD4E001626ED /* AutofillActionExecutor.swift */; }; C13909F02B85FD4E001626ED /* AutofillActionExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C13909EE2B85FD4E001626ED /* AutofillActionExecutor.swift */; }; - C13909F12B85FD4E001626ED /* AutofillActionExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C13909EE2B85FD4E001626ED /* AutofillActionExecutor.swift */; }; C13909F42B85FD79001626ED /* AutofillDeleteAllPasswordsExecutorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C13909F32B85FD79001626ED /* AutofillDeleteAllPasswordsExecutorTests.swift */; }; C13909F52B85FD79001626ED /* AutofillDeleteAllPasswordsExecutorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C13909F32B85FD79001626ED /* AutofillDeleteAllPasswordsExecutorTests.swift */; }; C13909FB2B861039001626ED /* AutofillActionPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C13909FA2B861039001626ED /* AutofillActionPresenter.swift */; }; C13909FC2B861039001626ED /* AutofillActionPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C13909FA2B861039001626ED /* AutofillActionPresenter.swift */; }; - C13909FD2B861039001626ED /* AutofillActionPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C13909FA2B861039001626ED /* AutofillActionPresenter.swift */; }; C168B9AC2B31DC7E001AFAD9 /* AutofillNeverPromptWebsitesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C168B9AB2B31DC7E001AFAD9 /* AutofillNeverPromptWebsitesManager.swift */; }; C168B9AD2B31DC7F001AFAD9 /* AutofillNeverPromptWebsitesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C168B9AB2B31DC7E001AFAD9 /* AutofillNeverPromptWebsitesManager.swift */; }; - C168B9AE2B31DC7F001AFAD9 /* AutofillNeverPromptWebsitesManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C168B9AB2B31DC7E001AFAD9 /* AutofillNeverPromptWebsitesManager.swift */; }; C17CA7AD2B9B52E6008EC3C1 /* NavigationBarPopoversTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C17CA7AC2B9B52E6008EC3C1 /* NavigationBarPopoversTests.swift */; }; C17CA7AE2B9B52E6008EC3C1 /* NavigationBarPopoversTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C17CA7AC2B9B52E6008EC3C1 /* NavigationBarPopoversTests.swift */; }; C17CA7B22B9B5317008EC3C1 /* MockAutofillPopoverPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C17CA7B12B9B5317008EC3C1 /* MockAutofillPopoverPresenter.swift */; }; C17CA7B32B9B5317008EC3C1 /* MockAutofillPopoverPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C17CA7B12B9B5317008EC3C1 /* MockAutofillPopoverPresenter.swift */; }; C1DAF3B52B9A44860059244F /* AutofillPopoverPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1DAF3B42B9A44860059244F /* AutofillPopoverPresenter.swift */; }; C1DAF3B62B9A44860059244F /* AutofillPopoverPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1DAF3B42B9A44860059244F /* AutofillPopoverPresenter.swift */; }; - C1DAF3B72B9A44860059244F /* AutofillPopoverPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1DAF3B42B9A44860059244F /* AutofillPopoverPresenter.swift */; }; C1E961EB2B879E79001760E1 /* MockAutofillActionPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1E961E72B879E4D001760E1 /* MockAutofillActionPresenter.swift */; }; C1E961ED2B879ED9001760E1 /* MockAutofillActionExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1E961EC2B879ED9001760E1 /* MockAutofillActionExecutor.swift */; }; C1E961EF2B87AA29001760E1 /* AutofillActionBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1E961EE2B87AA29001760E1 /* AutofillActionBuilder.swift */; }; C1E961F02B87AA29001760E1 /* AutofillActionBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1E961EE2B87AA29001760E1 /* AutofillActionBuilder.swift */; }; - C1E961F22B87AA29001760E1 /* AutofillActionBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1E961EE2B87AA29001760E1 /* AutofillActionBuilder.swift */; }; C1E961F32B87B273001760E1 /* MockAutofillActionExecutor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1E961EC2B879ED9001760E1 /* MockAutofillActionExecutor.swift */; }; C1E961F42B87B276001760E1 /* MockAutofillActionPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1E961E72B879E4D001760E1 /* MockAutofillActionPresenter.swift */; }; CB24F70C29A3D9CB006DCC58 /* AppConfigurationURLProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB24F70B29A3D9CB006DCC58 /* AppConfigurationURLProvider.swift */; }; @@ -3298,7 +2477,6 @@ CBDD5DE429A6800300832877 /* MockConfigurationStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBDD5DE229A67F2700832877 /* MockConfigurationStore.swift */; }; D64A5FF82AEA5C2B00B6D6E7 /* HomeButtonMenuFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64A5FF72AEA5C2B00B6D6E7 /* HomeButtonMenuFactory.swift */; }; D64A5FF92AEA5C2B00B6D6E7 /* HomeButtonMenuFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64A5FF72AEA5C2B00B6D6E7 /* HomeButtonMenuFactory.swift */; }; - D64A5FFB2AEA5C2B00B6D6E7 /* HomeButtonMenuFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = D64A5FF72AEA5C2B00B6D6E7 /* HomeButtonMenuFactory.swift */; }; EA0BA3A9272217E6002A0B6C /* ClickToLoadUserScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA0BA3A8272217E6002A0B6C /* ClickToLoadUserScript.swift */; }; EA18D1CA272F0DC8006DC101 /* social_images in Resources */ = {isa = PBXBuildFile; fileRef = EA18D1C9272F0DC8006DC101 /* social_images */; }; EA1E52B52798CF98002EC53C /* ClickToLoadModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA1E52B42798CF98002EC53C /* ClickToLoadModelTests.swift */; }; @@ -3320,12 +2498,12 @@ EE339228291BDEFD009F62C1 /* JSAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE339227291BDEFD009F62C1 /* JSAlertController.swift */; }; EE3424602BA0853900173B1B /* VPNUninstaller.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE34245D2BA0853900173B1B /* VPNUninstaller.swift */; }; EE3424612BA0853900173B1B /* VPNUninstaller.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE34245D2BA0853900173B1B /* VPNUninstaller.swift */; }; + EE42CBCC2BC8004700AD411C /* PermissionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE42CBCB2BC8004700AD411C /* PermissionsTests.swift */; }; EE54F7B32BBFEA49006218DB /* BookmarksAndFavoritesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE54F7B22BBFEA48006218DB /* BookmarksAndFavoritesTests.swift */; }; EE66418C2B9B1981005BCD17 /* NetworkProtectionTokenStore+SubscriptionTokenKeychainStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE66418B2B9B1981005BCD17 /* NetworkProtectionTokenStore+SubscriptionTokenKeychainStorage.swift */; }; EE66418D2B9B1981005BCD17 /* NetworkProtectionTokenStore+SubscriptionTokenKeychainStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE66418B2B9B1981005BCD17 /* NetworkProtectionTokenStore+SubscriptionTokenKeychainStorage.swift */; }; EE66666F2B56EDE4001D898D /* VPNLocationsHostingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE66666E2B56EDE4001D898D /* VPNLocationsHostingViewController.swift */; }; EE6666702B56EDE4001D898D /* VPNLocationsHostingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE66666E2B56EDE4001D898D /* VPNLocationsHostingViewController.swift */; }; - EE6666712B56EDE4001D898D /* VPNLocationsHostingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE66666E2B56EDE4001D898D /* VPNLocationsHostingViewController.swift */; }; EE7295E32A545B9A008C0991 /* NetworkProtection in Frameworks */ = {isa = PBXBuildFile; productRef = EE7295E22A545B9A008C0991 /* NetworkProtection */; }; EE7295E72A545BBB008C0991 /* NetworkProtection in Frameworks */ = {isa = PBXBuildFile; productRef = EE7295E62A545BBB008C0991 /* NetworkProtection */; }; EE7295E92A545BC4008C0991 /* NetworkProtection in Frameworks */ = {isa = PBXBuildFile; productRef = EE7295E82A545BC4008C0991 /* NetworkProtection */; }; @@ -3343,17 +2521,12 @@ EEC111E6294D06290086524F /* JSAlertViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC111E5294D06290086524F /* JSAlertViewModel.swift */; }; EEC4A65E2B277E8D00F7C0AA /* NetworkProtectionVPNCountryLabelsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEA3EEB02B24EBD000E8333A /* NetworkProtectionVPNCountryLabelsModel.swift */; }; EEC4A65F2B277EE100F7C0AA /* VPNLocationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEA3EEB22B24EC0600E8333A /* VPNLocationViewModel.swift */; }; - EEC4A6602B277F0D00F7C0AA /* VPNLocationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEA3EEB22B24EC0600E8333A /* VPNLocationViewModel.swift */; }; - EEC4A6612B277F1100F7C0AA /* NetworkProtectionVPNCountryLabelsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEA3EEB02B24EBD000E8333A /* NetworkProtectionVPNCountryLabelsModel.swift */; }; EEC4A6692B2C87D300F7C0AA /* VPNLocationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC4A6682B2C87D300F7C0AA /* VPNLocationView.swift */; }; EEC4A66A2B2C87D300F7C0AA /* VPNLocationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC4A6682B2C87D300F7C0AA /* VPNLocationView.swift */; }; - EEC4A66B2B2C87D300F7C0AA /* VPNLocationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC4A6682B2C87D300F7C0AA /* VPNLocationView.swift */; }; EEC4A66D2B2C894F00F7C0AA /* VPNLocationPreferenceItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC4A66C2B2C894F00F7C0AA /* VPNLocationPreferenceItemModel.swift */; }; EEC4A66E2B2C894F00F7C0AA /* VPNLocationPreferenceItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC4A66C2B2C894F00F7C0AA /* VPNLocationPreferenceItemModel.swift */; }; - EEC4A66F2B2C894F00F7C0AA /* VPNLocationPreferenceItemModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC4A66C2B2C894F00F7C0AA /* VPNLocationPreferenceItemModel.swift */; }; EEC4A6712B2C90AB00F7C0AA /* VPNLocationPreferenceItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC4A6702B2C90AB00F7C0AA /* VPNLocationPreferenceItem.swift */; }; EEC4A6722B2C90AB00F7C0AA /* VPNLocationPreferenceItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC4A6702B2C90AB00F7C0AA /* VPNLocationPreferenceItem.swift */; }; - EEC4A6732B2C90AB00F7C0AA /* VPNLocationPreferenceItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEC4A6702B2C90AB00F7C0AA /* VPNLocationPreferenceItem.swift */; }; EEC589D92A4F1CE300BCD60C /* AppLauncher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAD7A6E2A1D3E1F002A24E7 /* AppLauncher.swift */; }; EEC589DA2A4F1CE400BCD60C /* AppLauncher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAD7A6E2A1D3E1F002A24E7 /* AppLauncher.swift */; }; EEC589DB2A4F1CE700BCD60C /* AppLauncher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAD7A6E2A1D3E1F002A24E7 /* AppLauncher.swift */; }; @@ -3369,18 +2542,41 @@ EEDE50122BA360C80017F3C4 /* NetworkProtection+VPNAgentConvenienceInitializers.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEDE50102BA360C80017F3C4 /* NetworkProtection+VPNAgentConvenienceInitializers.swift */; }; EEF12E6F2A2111880023E6BF /* MacPacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEF12E6D2A2111880023E6BF /* MacPacketTunnelProvider.swift */; }; EEF53E182950CED5002D78F4 /* JSAlertViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEF53E172950CED5002D78F4 /* JSAlertViewModelTests.swift */; }; + F116A7C32BD1924B00F3FCF7 /* PixelKitTestingUtilities in Frameworks */ = {isa = PBXBuildFile; productRef = F116A7C22BD1924B00F3FCF7 /* PixelKitTestingUtilities */; }; + F116A7C72BD1925500F3FCF7 /* PixelKitTestingUtilities in Frameworks */ = {isa = PBXBuildFile; productRef = F116A7C62BD1925500F3FCF7 /* PixelKitTestingUtilities */; }; + F116A7C92BD1929000F3FCF7 /* PixelKitTestingUtilities in Frameworks */ = {isa = PBXBuildFile; productRef = F116A7C82BD1929000F3FCF7 /* PixelKitTestingUtilities */; }; + F188267C2BBEB3AA00D9AC4F /* GeneralPixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F188267B2BBEB3AA00D9AC4F /* GeneralPixel.swift */; }; + F188267D2BBEB3AA00D9AC4F /* GeneralPixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F188267B2BBEB3AA00D9AC4F /* GeneralPixel.swift */; }; + F18826802BBEB58100D9AC4F /* PrivacyProPixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F188267F2BBEB58100D9AC4F /* PrivacyProPixel.swift */; }; + F18826812BBEB58100D9AC4F /* PrivacyProPixel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F188267F2BBEB58100D9AC4F /* PrivacyProPixel.swift */; }; + F18826842BBEE31700D9AC4F /* PixelKit+Assertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = F18826832BBEE31700D9AC4F /* PixelKit+Assertion.swift */; }; + F18826852BBEE31700D9AC4F /* PixelKit+Assertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = F18826832BBEE31700D9AC4F /* PixelKit+Assertion.swift */; }; + F188268D2BBF01C300D9AC4F /* PixelDataModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B6DA44062616B30600DD1EC2 /* PixelDataModel.xcdatamodeld */; }; + F188268E2BBF01C400D9AC4F /* PixelDataModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B6DA44062616B30600DD1EC2 /* PixelDataModel.xcdatamodeld */; }; + F18826902BC0105800D9AC4F /* PixelDataRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68C92C32750EF76002AC6B0 /* PixelDataRecord.swift */; }; + F18826912BC0105800D9AC4F /* PixelDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA44012616B28300DD1EC2 /* PixelDataStore.swift */; }; + F18826922BC0105900D9AC4F /* PixelDataRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = B68C92C32750EF76002AC6B0 /* PixelDataRecord.swift */; }; + F18826932BC0105900D9AC4F /* PixelDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6DA44012616B28300DD1EC2 /* PixelDataStore.swift */; }; + F198C7122BD18A28000BF24D /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = F198C7112BD18A28000BF24D /* PixelKit */; }; + F198C7142BD18A30000BF24D /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = F198C7132BD18A30000BF24D /* PixelKit */; }; + F198C7162BD18A44000BF24D /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = F198C7152BD18A44000BF24D /* PixelKit */; }; + F198C7182BD18A4C000BF24D /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = F198C7172BD18A4C000BF24D /* PixelKit */; }; + F198C71A2BD18A5B000BF24D /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = F198C7192BD18A5B000BF24D /* PixelKit */; }; + F198C71C2BD18A61000BF24D /* PixelKit in Frameworks */ = {isa = PBXBuildFile; productRef = F198C71B2BD18A61000BF24D /* PixelKit */; }; + F198C71E2BD18D88000BF24D /* SwiftLintTool in Frameworks */ = {isa = PBXBuildFile; productRef = F198C71D2BD18D88000BF24D /* SwiftLintTool */; }; + F198C7202BD18D92000BF24D /* SwiftLintTool in Frameworks */ = {isa = PBXBuildFile; productRef = F198C71F2BD18D92000BF24D /* SwiftLintTool */; }; F1B33DF22BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1B33DF12BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift */; }; F1B33DF32BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1B33DF12BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift */; }; - F1B33DF42BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1B33DF12BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift */; }; F1B33DF62BAD970E001128B3 /* SubscriptionErrorReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1B33DF52BAD970E001128B3 /* SubscriptionErrorReporter.swift */; }; F1B33DF72BAD970E001128B3 /* SubscriptionErrorReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1B33DF52BAD970E001128B3 /* SubscriptionErrorReporter.swift */; }; - F1B33DF82BAD970E001128B3 /* SubscriptionErrorReporter.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1B33DF52BAD970E001128B3 /* SubscriptionErrorReporter.swift */; }; F1D43AEE2B98D8DF00BAB743 /* MainMenuActions+VanillaBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1D43AED2B98D8DF00BAB743 /* MainMenuActions+VanillaBrowser.swift */; }; F1D43AEF2B98D8DF00BAB743 /* MainMenuActions+VanillaBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1D43AED2B98D8DF00BAB743 /* MainMenuActions+VanillaBrowser.swift */; }; - F1D43AF02B98D8DF00BAB743 /* MainMenuActions+VanillaBrowser.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1D43AED2B98D8DF00BAB743 /* MainMenuActions+VanillaBrowser.swift */; }; F1D43AF32B98E47800BAB743 /* BareBonesBrowserKit in Frameworks */ = {isa = PBXBuildFile; productRef = F1D43AF22B98E47800BAB743 /* BareBonesBrowserKit */; }; F1D43AF52B98E48900BAB743 /* BareBonesBrowserKit in Frameworks */ = {isa = PBXBuildFile; productRef = F1D43AF42B98E48900BAB743 /* BareBonesBrowserKit */; }; - F1D43AF72B98E48F00BAB743 /* BareBonesBrowserKit in Frameworks */ = {isa = PBXBuildFile; productRef = F1D43AF62B98E48F00BAB743 /* BareBonesBrowserKit */; }; + F1DF95E32BD1807C0045E591 /* Crashes in Frameworks */ = {isa = PBXBuildFile; productRef = 08D4923DC968236E22E373E2 /* Crashes */; }; + F1DF95E42BD1807C0045E591 /* Crashes in Frameworks */ = {isa = PBXBuildFile; productRef = 537FC71EA5115A983FAF3170 /* Crashes */; }; + F1DF95E52BD1807C0045E591 /* Subscription in Frameworks */ = {isa = PBXBuildFile; productRef = DC3F73D49B2D44464AFEFCD8 /* Subscription */; }; + F1DF95E72BD188B60045E591 /* LoginItems in Frameworks */ = {isa = PBXBuildFile; productRef = F1DF95E62BD188B60045E591 /* LoginItems */; }; F41D174125CB131900472416 /* NSColorExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F41D174025CB131900472416 /* NSColorExtension.swift */; }; F44C130225C2DA0400426E3E /* NSAppearanceExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F44C130125C2DA0400426E3E /* NSAppearanceExtension.swift */; }; F4A6198C283CFFBB007F2080 /* ContentScopeFeatureFlagging.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4A6198B283CFFBB007F2080 /* ContentScopeFeatureFlagging.swift */; }; @@ -3389,13 +2585,6 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 31C6E9AA2B0C07A30086DC30 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = AA585D76248FD31100E9A3E2 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 9D9AE8B22AAA39A70026E7DC; - remoteInfo = DuckDuckGoDBPBackgroundAgent; - }; 31C6E9AC2B0C07BA0086DC30 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = AA585D76248FD31100E9A3E2 /* Project object */; @@ -3531,19 +2720,6 @@ name = "Embed Login Items"; runOnlyForDeploymentPostprocessing = 0; }; - 4B957C332AC7AE700062CA31 /* Embed Login Items */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = Contents/Library/LoginItems; - dstSubfolderSpec = 1; - files = ( - 7BFF85102B0C09E300ECACA2 /* DuckDuckGo Personal Information Removal.app in Embed Login Items */, - 4B957C342AC7AE700062CA31 /* DuckDuckGo VPN.app in Embed Login Items */, - 4B957C352AC7AE700062CA31 /* DuckDuckGo Notifications.app in Embed Login Items */, - ); - name = "Embed Login Items"; - runOnlyForDeploymentPostprocessing = 0; - }; 4BA7C4E02B3F6F7500AFE511 /* Embed Network Extensions */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -3660,6 +2836,9 @@ 315AA06F28CA5CC800200030 /* YoutubePlayerNavigationHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YoutubePlayerNavigationHandler.swift; sourceTree = ""; }; 3168506C2AF3AD1C009A2828 /* WaitlistViewControllerPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WaitlistViewControllerPresenter.swift; sourceTree = ""; }; 316850712AF3AD58009A2828 /* DataBrokerProtectionDebugMenu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataBrokerProtectionDebugMenu.swift; sourceTree = ""; }; + 316913222BD2B6250051B46D /* DataBrokerProtectionPixelsHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataBrokerProtectionPixelsHandler.swift; sourceTree = ""; }; + 316913252BD2B76F0051B46D /* DataBrokerPrerequisitesStatusVerifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataBrokerPrerequisitesStatusVerifier.swift; sourceTree = ""; }; + 316913282BD2C7570051B46D /* DataBrokerProtectionErrorViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataBrokerProtectionErrorViewController.swift; sourceTree = ""; }; 3171D6B72889849F0068632A /* CookieManagedNotificationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CookieManagedNotificationView.swift; sourceTree = ""; }; 3171D6B9288984D00068632A /* BadgeAnimationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeAnimationView.swift; sourceTree = ""; }; 3171D6DA2889B64D0068632A /* CookieManagedNotificationContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CookieManagedNotificationContainerView.swift; sourceTree = ""; }; @@ -3679,6 +2858,7 @@ 31C9ADE42AF0564500CEF57D /* WaitlistFeatureSetupHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitlistFeatureSetupHandler.swift; sourceTree = ""; }; 31CF3431288B0B1B0087244B /* NavigationBarBadgeAnimator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationBarBadgeAnimator.swift; sourceTree = ""; }; 31D5375B291D944100407A95 /* PasswordManagementBitwardenItemView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PasswordManagementBitwardenItemView.swift; sourceTree = ""; }; + 31DC2F202BD6DE65001354EF /* DataBrokerPrerequisitesStatusVerifierTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataBrokerPrerequisitesStatusVerifierTests.swift; sourceTree = ""; }; 31E163B9293A56F400963C10 /* BrokenSiteReportingReferenceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrokenSiteReportingReferenceTests.swift; sourceTree = ""; }; 31E163BC293A579E00963C10 /* PrivacyReferenceTestHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyReferenceTestHelper.swift; sourceTree = ""; }; 31E163BF293A581900963C10 /* privacy-reference-tests */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "privacy-reference-tests"; path = "Submodules/privacy-reference-tests"; sourceTree = SOURCE_ROOT; }; @@ -3724,6 +2904,7 @@ 376C4DB828A1A48A00CC0F5B /* FirePopoverViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirePopoverViewModelTests.swift; sourceTree = ""; }; 376CC8B4296EB630006B63A7 /* AppStore.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppStore.xcconfig; sourceTree = ""; }; 376CC8B5296EBA8F006B63A7 /* BuildNumber.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = BuildNumber.xcconfig; sourceTree = ""; }; + 376E708D2BD686260082B7EB /* UI Tests.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = "UI Tests.xctestplan"; sourceTree = ""; }; 37717E66296B5A20002FAEDF /* Global.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Global.xcconfig; sourceTree = ""; }; 3775912C29AAC72700E26367 /* SyncPreferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncPreferences.swift; sourceTree = ""; }; 3775913529AB9A1C00E26367 /* SyncManagementDialogViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncManagementDialogViewController.swift; sourceTree = ""; }; @@ -3900,7 +3081,6 @@ 4B67742A255DBEB800025BD8 /* httpsMobileV2FalsePositives.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = httpsMobileV2FalsePositives.json; sourceTree = ""; }; 4B677440255DBEEA00025BD8 /* Database.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Database.swift; sourceTree = ""; }; 4B677454255DC18000025BD8 /* Bridging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Bridging.h; sourceTree = ""; }; - 4B67853E2AA7C726008A5004 /* DailyPixel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DailyPixel.swift; sourceTree = ""; }; 4B6785432AA8DE1F008A5004 /* NetworkProtectionFeatureDisabler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NetworkProtectionFeatureDisabler.swift; sourceTree = ""; }; 4B6B64832BA930420009FF9F /* WaitlistThankYouPromptPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WaitlistThankYouPromptPresenter.swift; sourceTree = ""; }; 4B70BFFF27B0793D000386ED /* DuckDuckGo-ExampleCrash.ips */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "DuckDuckGo-ExampleCrash.ips"; sourceTree = ""; }; @@ -3963,8 +3143,6 @@ 4B9292D82667124B00AD2C21 /* BookmarkListTreeControllerDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarkListTreeControllerDataSource.swift; sourceTree = ""; }; 4B9292DA2667125D00AD2C21 /* ContextualMenu.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContextualMenu.swift; sourceTree = ""; }; 4B9579202AC687170062CA31 /* HardwareModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HardwareModel.swift; sourceTree = ""; }; - 4B957C412AC7AE700062CA31 /* DuckDuckGo Privacy Pro.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "DuckDuckGo Privacy Pro.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - 4B957C432AC7AF190062CA31 /* DuckDuckGoPrivacyPro.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = DuckDuckGoPrivacyPro.xcconfig; sourceTree = ""; }; 4B980E202817604000282EE1 /* NSNotificationName+Debug.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSNotificationName+Debug.swift"; sourceTree = ""; }; 4B98D27928D95F1A003C2B6F /* ChromiumFaviconsReaderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChromiumFaviconsReaderTests.swift; sourceTree = ""; }; 4B98D27B28D960DD003C2B6F /* FirefoxFaviconsReaderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirefoxFaviconsReaderTests.swift; sourceTree = ""; }; @@ -4030,7 +3208,6 @@ 4BBF0916282DD6EF00EE1418 /* TemporaryFileHandlerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TemporaryFileHandlerTests.swift; sourceTree = ""; }; 4BBF09222830812900EE1418 /* FileSystemDSL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileSystemDSL.swift; sourceTree = ""; }; 4BBF0924283083EC00EE1418 /* FileSystemDSLTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileSystemDSLTests.swift; sourceTree = ""; }; - 4BC2621C293996410087A482 /* PixelEventTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PixelEventTests.swift; sourceTree = ""; }; 4BCF15D62ABB8A110083F6DF /* NetworkProtectionRemoteMessaging.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionRemoteMessaging.swift; sourceTree = ""; }; 4BCF15D82ABB8A7F0083F6DF /* NetworkProtectionRemoteMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionRemoteMessage.swift; sourceTree = ""; }; 4BCF15E42ABB98990083F6DF /* NetworkProtectionRemoteMessageTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionRemoteMessageTests.swift; sourceTree = ""; }; @@ -4040,7 +3217,6 @@ 4BD57C032AC112DF00B580EE /* NetworkProtectionRemoteMessagingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionRemoteMessagingTests.swift; sourceTree = ""; }; 4BDFA4AD27BF19E500648192 /* ToggleableScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleableScrollView.swift; sourceTree = ""; }; 4BE0DF0426781961006337B7 /* NSStoryboardExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSStoryboardExtension.swift; sourceTree = ""; }; - 4BE15DB12A0B0DD500898243 /* PixelKit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = PixelKit; sourceTree = ""; }; 4BE344ED2B2376DF003FC223 /* VPNFeedbackFormViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNFeedbackFormViewModelTests.swift; sourceTree = ""; }; 4BE4005227CF3DC3007D3161 /* SavePaymentMethodPopover.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavePaymentMethodPopover.swift; sourceTree = ""; }; 4BE4005427CF3F19007D3161 /* SavePaymentMethodViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SavePaymentMethodViewController.swift; sourceTree = ""; }; @@ -4068,6 +3244,8 @@ 4BF6961F28BEEE8B00D402D4 /* LocalPinningManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalPinningManagerTests.swift; sourceTree = ""; }; 5601FECC29B7973D00068905 /* TabBarViewItemTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarViewItemTests.swift; sourceTree = ""; }; 5603D90529B7B746007F9F01 /* MockTabViewItemDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockTabViewItemDelegate.swift; sourceTree = ""; }; + 560C3FFB2BC9911000F589CE /* PermanentSurveyManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PermanentSurveyManagerTests.swift; sourceTree = ""; }; + 560C3FFE2BCD5A1E00F589CE /* PermanentSurveyManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PermanentSurveyManager.swift; sourceTree = ""; }; 561D66692B95C45A008ACC5C /* Suggestion.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Suggestion.storyboard; sourceTree = ""; }; 5629846E2AC4610100AC20EB /* SyncPreferencesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SyncPreferencesTests.swift; sourceTree = ""; }; 56534DEC29DF252C00121467 /* CapturingDefaultBrowserProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CapturingDefaultBrowserProvider.swift; sourceTree = ""; }; @@ -4265,6 +3443,10 @@ 9D9AE92B2AAB84FF0026E7DC /* DBPMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DBPMocks.swift; sourceTree = ""; }; 9DB6E7222AA0DA7A00A17F3C /* LoginItems */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = LoginItems; sourceTree = ""; }; 9F0A2CF72B96A58600C5B8C0 /* BaseBookmarkEntityTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseBookmarkEntityTests.swift; sourceTree = ""; }; + 9F0FFFB32BCCAE37007C87DD /* BookmarkAllTabsDialogCoordinatorViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkAllTabsDialogCoordinatorViewModelTests.swift; sourceTree = ""; }; + 9F0FFFB72BCCAE9C007C87DD /* AddEditBookmarkDialogViewModelMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddEditBookmarkDialogViewModelMock.swift; sourceTree = ""; }; + 9F0FFFBA2BCCAEC2007C87DD /* AddEditBookmarkFolderDialogViewModelMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddEditBookmarkFolderDialogViewModelMock.swift; sourceTree = ""; }; + 9F0FFFBD2BCCAF1F007C87DD /* BookmarkAllTabsDialogViewModelMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkAllTabsDialogViewModelMock.swift; sourceTree = ""; }; 9F180D0E2B69C553000D695F /* Tab+WKUIDelegateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Tab+WKUIDelegateTests.swift"; sourceTree = ""; }; 9F180D112B69C665000D695F /* DownloadsTabExtensionMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DownloadsTabExtensionMock.swift; sourceTree = ""; }; 9F2606092B85C20400819292 /* AddEditBookmarkDialogViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddEditBookmarkDialogViewModelTests.swift; sourceTree = ""; }; @@ -4281,14 +3463,24 @@ 9F872D9C2B9058D000138637 /* Bookmarks+TabTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bookmarks+TabTests.swift"; sourceTree = ""; }; 9F872D9F2B90644800138637 /* ContextualMenuTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextualMenuTests.swift; sourceTree = ""; }; 9F872DA22B90920F00138637 /* BookmarkFolderInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkFolderInfo.swift; sourceTree = ""; }; + 9F8D57312BCCCB9A00AEA660 /* UserDefaultsBookmarkFoldersStoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsBookmarkFoldersStoreTests.swift; sourceTree = ""; }; 9F982F0C2B8224BE00231028 /* AddEditBookmarkFolderDialogViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddEditBookmarkFolderDialogViewModel.swift; sourceTree = ""; }; 9F982F112B82268F00231028 /* AddEditBookmarkFolderDialogViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddEditBookmarkFolderDialogViewModelTests.swift; sourceTree = ""; }; + 9F9C49F52BC786790099738D /* MoreOptionsMenu+BookmarksTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MoreOptionsMenu+BookmarksTests.swift"; sourceTree = ""; }; + 9F9C49F82BC7BC970099738D /* BookmarkAllTabsDialogView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkAllTabsDialogView.swift; sourceTree = ""; }; + 9F9C49FC2BC7E9820099738D /* BookmarkAllTabsDialogViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarkAllTabsDialogViewModel.swift; sourceTree = ""; }; + 9F9C4A002BC7F36D0099738D /* BookmarkAllTabsDialogCoordinatorViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkAllTabsDialogCoordinatorViewModel.swift; sourceTree = ""; }; 9FA173D92B79BD8A00EE4E6E /* BookmarkDialogContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkDialogContainerView.swift; sourceTree = ""; }; 9FA173DE2B7A0EFE00EE4E6E /* BookmarkDialogButtonsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkDialogButtonsView.swift; sourceTree = ""; }; 9FA173E22B7A12B600EE4E6E /* BookmarkDialogFolderManagementView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkDialogFolderManagementView.swift; sourceTree = ""; }; 9FA173E62B7B122E00EE4E6E /* BookmarkDialogStackedContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkDialogStackedContentView.swift; sourceTree = ""; }; 9FA173EA2B7B232200EE4E6E /* AddEditBookmarkDialogView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddEditBookmarkDialogView.swift; sourceTree = ""; }; + 9FA5A0A42BC8F34900153786 /* UserDefaultsBookmarkFoldersStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserDefaultsBookmarkFoldersStore.swift; sourceTree = ""; }; + 9FA5A0A82BC900FC00153786 /* BookmarkAllTabsDialogViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkAllTabsDialogViewModelTests.swift; sourceTree = ""; }; + 9FA5A0AC2BC9037A00153786 /* BookmarkFolderStoreMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarkFolderStoreMock.swift; sourceTree = ""; }; 9FA75A3D2BA00E1400DA5FA6 /* BookmarksBarMenuFactoryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksBarMenuFactoryTests.swift; sourceTree = ""; }; + 9FAD62392BCFDB32007F3A65 /* WebsiteInfoHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebsiteInfoHelpers.swift; sourceTree = ""; }; + 9FAD623C2BD09DE5007F3A65 /* WebsiteInfoTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebsiteInfoTests.swift; sourceTree = ""; }; 9FBD84512BB3AACB00220859 /* AttributionOriginFileProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributionOriginFileProvider.swift; sourceTree = ""; }; 9FBD84552BB3ACFD00220859 /* AttributionOriginFileProviderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributionOriginFileProviderTests.swift; sourceTree = ""; }; 9FBD845C2BB3B80300220859 /* Origin.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = Origin.txt; sourceTree = ""; }; @@ -4427,7 +3619,6 @@ AAC30A25268DFEE200D2D9CD /* CrashReporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReporter.swift; sourceTree = ""; }; AAC30A27268E045400D2D9CD /* CrashReportReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReportReader.swift; sourceTree = ""; }; AAC30A29268E239100D2D9CD /* CrashReport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReport.swift; sourceTree = ""; }; - AAC30A2B268F1ECD00D2D9CD /* CrashReportSender.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReportSender.swift; sourceTree = ""; }; AAC30A2D268F1EE300D2D9CD /* CrashReportPromptPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CrashReportPromptPresenter.swift; sourceTree = ""; }; AAC5E4C425D6A6E8007F5990 /* AddBookmarkPopover.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AddBookmarkPopover.swift; sourceTree = ""; }; AAC5E4CD25D6A709007F5990 /* Bookmark.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bookmark.swift; sourceTree = ""; }; @@ -4542,7 +3733,7 @@ B63ED0DF26AFE32F00A9DAD1 /* GeolocationProviderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeolocationProviderMock.swift; sourceTree = ""; }; B63ED0E226B3E7FA00A9DAD1 /* CLLocationManagerMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CLLocationManagerMock.swift; sourceTree = ""; }; B63ED0E426BB8FB900A9DAD1 /* SharingMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharingMenu.swift; sourceTree = ""; }; - B642738127B65BAC0005DFD1 /* SecureVaultErrorReporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureVaultErrorReporter.swift; sourceTree = ""; }; + B642738127B65BAC0005DFD1 /* SecureVaultReporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureVaultReporter.swift; sourceTree = ""; }; B643BF1327ABF772000BACEC /* NSWorkspaceExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSWorkspaceExtension.swift; sourceTree = ""; }; B644B43929D565DB003FA9AB /* SearchNonexistentDomainTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchNonexistentDomainTests.swift; sourceTree = ""; }; B645D8F529FA95440024461F /* WKProcessPoolExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WKProcessPoolExtension.swift; sourceTree = ""; }; @@ -4582,7 +3773,6 @@ B66260DC29AC5D4300E9E3EE /* NavigationProtectionTabExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationProtectionTabExtension.swift; sourceTree = ""; }; B66260DF29AC6EBD00E9E3EE /* HistoryTabExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryTabExtension.swift; sourceTree = ""; }; B66260E529ACAE4B00E9E3EE /* NavigationHotkeyHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationHotkeyHandler.swift; sourceTree = ""; }; - B662D3D82755D7AD0035D4D6 /* PixelStoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PixelStoreTests.swift; sourceTree = ""; }; B662D3DD275613BB0035D4D6 /* EncryptionKeyStoreMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EncryptionKeyStoreMock.swift; sourceTree = ""; }; B6656E0C2B29C733008798A1 /* FileImportViewLocalizationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileImportViewLocalizationTests.swift; sourceTree = ""; }; B6676BE02AA986A700525A21 /* AddressBarTextEditor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddressBarTextEditor.swift; sourceTree = ""; }; @@ -4671,11 +3861,7 @@ B6A60E4F2B73C3B800FD4968 /* WKURLSchemeTask+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WKURLSchemeTask+Private.h"; sourceTree = ""; }; B6A60E502B73C46B00FD4968 /* IntegrationTestsBridging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = IntegrationTestsBridging.h; sourceTree = ""; }; B6A924D82664C72D001A28CA /* WebKitDownloadTask.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebKitDownloadTask.swift; sourceTree = ""; }; - B6A9E45226142B070067D1B9 /* Pixel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Pixel.swift; sourceTree = ""; }; B6A9E46A2614618A0067D1B9 /* OperatingSystemVersionExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OperatingSystemVersionExtension.swift; sourceTree = ""; }; - B6A9E47626146A570067D1B9 /* PixelEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PixelEvent.swift; sourceTree = ""; }; - B6A9E47E26146A800067D1B9 /* PixelArguments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PixelArguments.swift; sourceTree = ""; }; - B6A9E48326146AAB0067D1B9 /* PixelParameters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PixelParameters.swift; sourceTree = ""; }; B6AA64722994B43300D99CD6 /* FutureExtensionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FutureExtensionTests.swift; sourceTree = ""; }; B6AAAC2C260330580029438D /* PublishedAfter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublishedAfter.swift; sourceTree = ""; }; B6AAAC3D26048F690029438D /* RandomAccessCollectionExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RandomAccessCollectionExtension.swift; sourceTree = ""; }; @@ -4744,9 +3930,7 @@ B6DA06E7291401D700225DE2 /* WKMenuItemIdentifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WKMenuItemIdentifier.swift; sourceTree = ""; }; B6DA44012616B28300DD1EC2 /* PixelDataStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PixelDataStore.swift; sourceTree = ""; }; B6DA44072616B30600DD1EC2 /* PixelDataModel.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = PixelDataModel.xcdatamodel; sourceTree = ""; }; - B6DA44102616C0FC00DD1EC2 /* PixelTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PixelTests.swift; sourceTree = ""; }; B6DA441D2616C84600DD1EC2 /* PixelStoreMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PixelStoreMock.swift; sourceTree = ""; }; - B6DA44222616CABC00DD1EC2 /* PixelArgumentsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PixelArgumentsTests.swift; sourceTree = ""; }; B6DB3AEE278D5C370024C5C4 /* URLSessionExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLSessionExtension.swift; sourceTree = ""; }; B6DB3CF826A00E2D00D459B7 /* AVCaptureDevice+SwizzledAuthState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AVCaptureDevice+SwizzledAuthState.swift"; sourceTree = ""; }; B6DB3CFA26A17CB800D459B7 /* PermissionModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PermissionModel.swift; sourceTree = ""; }; @@ -4771,6 +3955,10 @@ B6EC37FA29B6447F001ACE79 /* TestsServer.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = TestsServer.xcconfig; sourceTree = ""; }; B6EC37FB29B83E99001ACE79 /* TestsURLExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestsURLExtension.swift; sourceTree = ""; }; B6EEDD7C2B8C69E900637EBC /* TabContentTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabContentTests.swift; sourceTree = ""; }; + B6F1B0212BCE5658005E863C /* BrokenSiteInfoTabExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrokenSiteInfoTabExtension.swift; sourceTree = ""; }; + B6F1B0252BCE5A50005E863C /* TabContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabContent.swift; sourceTree = ""; }; + B6F1B0292BCE675C005E863C /* NetworkProtectionControllerTabExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkProtectionControllerTabExtension.swift; sourceTree = ""; }; + B6F1B02D2BCE6B47005E863C /* TunnelControllerProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelControllerProvider.swift; sourceTree = ""; }; B6F41030264D2B23003DA42C /* ProgressExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressExtension.swift; sourceTree = ""; }; B6F56566299A414300A04298 /* WKWebViewMockingExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WKWebViewMockingExtension.swift; sourceTree = ""; }; B6F7127D29F6779000594A45 /* QRSharingService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRSharingService.swift; sourceTree = ""; }; @@ -4782,6 +3970,11 @@ B6FA8940269C425400588ECD /* PrivacyDashboardPopover.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyDashboardPopover.swift; sourceTree = ""; }; BB5789712B2CA70F0009DFE2 /* DataBrokerProtectionSubscriptionEventHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataBrokerProtectionSubscriptionEventHandler.swift; sourceTree = ""; }; BBDFDC592B2B8A0900F62D90 /* DataBrokerProtectionExternalWaitlistPixels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataBrokerProtectionExternalWaitlistPixels.swift; sourceTree = ""; }; + BD384AC72BBC821100EF3735 /* vpn-light-mode.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "vpn-light-mode.json"; sourceTree = ""; }; + BD384AC82BBC821100EF3735 /* vpn-dark-mode.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "vpn-dark-mode.json"; sourceTree = ""; }; + BDA7647B2BC497BE00D0400C /* DefaultVPNLocationFormatter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DefaultVPNLocationFormatter.swift; sourceTree = ""; }; + BDA7648C2BC4E4EF00D0400C /* DefaultVPNLocationFormatterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DefaultVPNLocationFormatterTests.swift; sourceTree = ""; }; + BDA764902BC4E57200D0400C /* MockVPNLocationFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockVPNLocationFormatter.swift; sourceTree = ""; }; C1372EF32BBC5BAD003F8793 /* SecureTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecureTextField.swift; sourceTree = ""; }; C13909EE2B85FD4E001626ED /* AutofillActionExecutor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutofillActionExecutor.swift; sourceTree = ""; }; C13909F32B85FD79001626ED /* AutofillDeleteAllPasswordsExecutorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutofillDeleteAllPasswordsExecutorTests.swift; sourceTree = ""; }; @@ -4813,6 +4006,7 @@ EE0429DF2BA31D2F009EB20F /* FindInPageTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FindInPageTests.swift; sourceTree = ""; }; EE339227291BDEFD009F62C1 /* JSAlertController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSAlertController.swift; sourceTree = ""; }; EE34245D2BA0853900173B1B /* VPNUninstaller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNUninstaller.swift; sourceTree = ""; }; + EE42CBCB2BC8004700AD411C /* PermissionsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PermissionsTests.swift; sourceTree = ""; }; EE54F7B22BBFEA48006218DB /* BookmarksAndFavoritesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BookmarksAndFavoritesTests.swift; sourceTree = ""; }; EE66418B2B9B1981005BCD17 /* NetworkProtectionTokenStore+SubscriptionTokenKeychainStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NetworkProtectionTokenStore+SubscriptionTokenKeychainStorage.swift"; sourceTree = ""; }; EE66666E2B56EDE4001D898D /* VPNLocationsHostingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNLocationsHostingViewController.swift; sourceTree = ""; }; @@ -4833,6 +4027,9 @@ EEDE50102BA360C80017F3C4 /* NetworkProtection+VPNAgentConvenienceInitializers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NetworkProtection+VPNAgentConvenienceInitializers.swift"; sourceTree = ""; }; EEF12E6D2A2111880023E6BF /* MacPacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MacPacketTunnelProvider.swift; sourceTree = ""; }; EEF53E172950CED5002D78F4 /* JSAlertViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JSAlertViewModelTests.swift; sourceTree = ""; }; + F188267B2BBEB3AA00D9AC4F /* GeneralPixel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralPixel.swift; sourceTree = ""; }; + F188267F2BBEB58100D9AC4F /* PrivacyProPixel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivacyProPixel.swift; sourceTree = ""; }; + F18826832BBEE31700D9AC4F /* PixelKit+Assertion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PixelKit+Assertion.swift"; sourceTree = ""; }; F1B33DF12BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionAppStoreRestorer.swift; sourceTree = ""; }; F1B33DF52BAD970E001128B3 /* SubscriptionErrorReporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscriptionErrorReporter.swift; sourceTree = ""; }; F1D43AED2B98D8DF00BAB743 /* MainMenuActions+VanillaBrowser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MainMenuActions+VanillaBrowser.swift"; sourceTree = ""; }; @@ -4848,8 +4045,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F1DF95E42BD1807C0045E591 /* Crashes in Frameworks */, 373FB4B32B4D6C4B004C88D6 /* PreferencesViews in Frameworks */, - 7B5F9A752AE2BE4E002AEBC0 /* PixelKit in Frameworks */, 4BF97AD32B43C43F00EB4240 /* NetworkProtectionUI in Frameworks */, 7B1459572B7D43E500047F2C /* NetworkProtectionProxy in Frameworks */, B6F7128229F6820A00594A45 /* QuickLookUI.framework in Frameworks */, @@ -4858,10 +4055,12 @@ 37A5E2F0298AA1B20047046B /* Persistence in Frameworks */, 9DC70B1A2AA1FA5B005A844B /* LoginItems in Frameworks */, 37269EFD2B332FAC005E8E46 /* Common in Frameworks */, + F198C7142BD18A30000BF24D /* PixelKit in Frameworks */, F1D43AF52B98E48900BAB743 /* BareBonesBrowserKit in Frameworks */, 378F44E629B4BDEE00899924 /* SwiftUIExtensions in Frameworks */, 3706FCA7293F65D500E42796 /* BrowserServicesKit in Frameworks */, 3129788A2B64131200B67619 /* DataBrokerProtection in Frameworks */, + F198C7202BD18D92000BF24D /* SwiftLintTool in Frameworks */, 4BCBE4582BA7E17800FC75A1 /* SubscriptionUI in Frameworks */, 3706FCA9293F65D500E42796 /* ContentBlocking in Frameworks */, 85D44B882BA08D30001B4AB5 /* Suggestions in Frameworks */, @@ -4886,9 +4085,9 @@ buildActionMask = 2147483647; files = ( 3706FE88293F661700E42796 /* OHHTTPStubs in Frameworks */, + F116A7C72BD1925500F3FCF7 /* PixelKitTestingUtilities in Frameworks */, B65CD8CF2B316E0200A595BB /* SnapshotTesting in Frameworks */, 3706FE89293F661700E42796 /* OHHTTPStubsSwift in Frameworks */, - 4B81AD372B29513100706C96 /* PixelKitTestingUtilities in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4911,6 +4110,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F116A7C92BD1929000F3FCF7 /* PixelKitTestingUtilities in Frameworks */, B65CD8CD2B316DFC00A595BB /* SnapshotTesting in Frameworks */, B6AE39F329374AEC00C37AA4 /* OHHTTPStubs in Frameworks */, B6AE39F529374AEC00C37AA4 /* OHHTTPStubsSwift in Frameworks */, @@ -4923,8 +4123,8 @@ files = ( 37269F012B332FC8005E8E46 /* Common in Frameworks */, EE7295E92A545BC4008C0991 /* NetworkProtection in Frameworks */, - 4B2537772A11BFE100610219 /* PixelKit in Frameworks */, 7B37C7A52BAA32A50062546A /* Subscription in Frameworks */, + F198C7182BD18A4C000BF24D /* PixelKit in Frameworks */, 7BBE2B7B2B61663C00697445 /* NetworkProtectionProxy in Frameworks */, 4B2D062C2A11C0E100DE1F49 /* Networking in Frameworks */, 4B25375B2A11BE7300610219 /* NetworkExtension.framework in Frameworks */, @@ -4935,12 +4135,13 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F198C71A2BD18A5B000BF24D /* PixelKit in Frameworks */, 4B41EDAB2B1544B2001EEDF4 /* LoginItems in Frameworks */, 7B00997D2B6508B700FE7C31 /* NetworkProtectionProxy in Frameworks */, 7BEEA5122AD1235B00A9E72B /* NetworkProtectionIPC in Frameworks */, 7BA7CC5F2AD1210C0042E5CE /* Networking in Frameworks */, 7BEEA5162AD1236E00A9E72B /* NetworkProtectionUI in Frameworks */, - 7BFCB74E2ADE7E1A00DA3EA7 /* PixelKit in Frameworks */, + BDADBDC92BD2BC2200421B9B /* Lottie in Frameworks */, EE7295ED2A545C0A008C0991 /* NetworkProtection in Frameworks */, EE2F9C5B2B90F2FF00D45FC9 /* Subscription in Frameworks */, 7BEC182F2AD5D8DC00D30536 /* SystemExtensionManager in Frameworks */, @@ -4951,10 +4152,11 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 7BFCB7502ADE7E2300DA3EA7 /* PixelKit in Frameworks */, 4BCBE45C2BA7E18500FC75A1 /* Subscription in Frameworks */, 7BA7CC612AD1211C0042E5CE /* Networking in Frameworks */, + F198C71C2BD18A61000BF24D /* PixelKit in Frameworks */, 7BEEA5142AD1236300A9E72B /* NetworkProtectionIPC in Frameworks */, + BDADBDCB2BD2BC2800421B9B /* Lottie in Frameworks */, 7B00997F2B6508C200FE7C31 /* NetworkProtectionProxy in Frameworks */, EE7295EF2A545C12008C0991 /* NetworkProtection in Frameworks */, 4B2D067F2A1334D700DE1F49 /* NetworkProtectionUI in Frameworks */, @@ -4975,54 +4177,16 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F1DF95E52BD1807C0045E591 /* Subscription in Frameworks */, 37269EFF2B332FBB005E8E46 /* Common in Frameworks */, EE7295E72A545BBB008C0991 /* NetworkProtection in Frameworks */, - 4B4D60982A0B2A5C00BCD287 /* PixelKit in Frameworks */, + F198C7162BD18A44000BF24D /* PixelKit in Frameworks */, 4B4D60AF2A0C837F00BCD287 /* Networking in Frameworks */, 7B25856E2BA2F2ED00D49F79 /* NetworkProtectionUI in Frameworks */, 4B4D603F2A0B290200BCD287 /* NetworkExtension.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4B957BD42AC7AE700062CA31 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 4B957BD52AC7AE700062CA31 /* QuickLookUI.framework in Frameworks */, - 3143C8792B0D1F3D00382627 /* DataBrokerProtection in Frameworks */, - 372217842B33380E00B8E9C2 /* TestUtils in Frameworks */, - 4B957BD62AC7AE700062CA31 /* LoginItems in Frameworks */, - 7B94E1652B7ED95100E32B96 /* NetworkProtectionProxy in Frameworks */, - 4B957BD72AC7AE700062CA31 /* NetworkProtection in Frameworks */, - 4B957BD82AC7AE700062CA31 /* BrowserServicesKit in Frameworks */, - 4B957BDA2AC7AE700062CA31 /* Bookmarks in Frameworks */, - 4B957BDB2AC7AE700062CA31 /* ContentBlocking in Frameworks */, - 4B957BDC2AC7AE700062CA31 /* SwiftUIExtensions in Frameworks */, - 4B957BDD2AC7AE700062CA31 /* UserScript in Frameworks */, - 7BBD44282AD730A400D0A064 /* PixelKit in Frameworks */, - F1D43AF72B98E48F00BAB743 /* BareBonesBrowserKit in Frameworks */, - 7B31FD902AD1257B0086AA24 /* NetworkProtectionIPC in Frameworks */, - 4B957BDE2AC7AE700062CA31 /* Configuration in Frameworks */, - 4B957BE22AC7AE700062CA31 /* Sparkle in Frameworks */, - 373FB4B52B4D6C57004C88D6 /* PreferencesViews in Frameworks */, - 4B957BE32AC7AE700062CA31 /* Navigation in Frameworks */, - 1E21F8E32B73E48600FB272E /* Subscription in Frameworks */, - 4B957BE42AC7AE700062CA31 /* DDGSync in Frameworks */, - 4B957BE52AC7AE700062CA31 /* OpenSSL in Frameworks */, - 85E2BBD22B8F536F00DBEC7A /* History in Frameworks */, - 4B957BE62AC7AE700062CA31 /* PrivacyDashboard in Frameworks */, - 9FF5214A2BAA90C400B9819B /* Lottie in Frameworks */, - 7B8C083C2AE1268E00F4C67F /* PixelKit in Frameworks */, - 85D44B8A2BA08D3B001B4AB5 /* Suggestions in Frameworks */, - 4B957BE72AC7AE700062CA31 /* SyncDataProviders in Frameworks */, - 37269F032B332FD8005E8E46 /* Common in Frameworks */, - 4B957BE82AC7AE700062CA31 /* SyncUI in Frameworks */, - 4B957BE92AC7AE700062CA31 /* NetworkProtectionUI in Frameworks */, - 1E0068AD2B1673BB00BBF43B /* SubscriptionUI in Frameworks */, - 4B957BEB2AC7AE700062CA31 /* Persistence in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 565E46DA2B2725DC0013AC2A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -5045,7 +4209,6 @@ files = ( 7BDA36E62B7E037100AD5388 /* NetworkExtension.framework in Frameworks */, 7B97CD592B7E0B57004FEF43 /* NetworkProtectionProxy in Frameworks */, - 7B97CD622B7E0C4B004FEF43 /* PixelKit in Frameworks */, 7B7DFB222B7E7473009EA1A3 /* Networking in Frameworks */, 7B97CD5B2B7E0B85004FEF43 /* Common in Frameworks */, ); @@ -5056,7 +4219,6 @@ buildActionMask = 2147483647; files = ( 9DEF97E12B06C4EE00764F03 /* Networking in Frameworks */, - 9D6983F92AC773C3002C02FC /* PixelKit in Frameworks */, 9D9AE8F92AAA3AD00026E7DC /* DataBrokerProtection in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -5065,7 +4227,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9D6983FB2AC773C8002C02FC /* PixelKit in Frameworks */, 315A023F2B6421AE00BFA577 /* Networking in Frameworks */, 9D9AE8FB2AAA3AD90026E7DC /* DataBrokerProtection in Frameworks */, ); @@ -5075,15 +4236,13 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 373FB4B12B4D6C42004C88D6 /* PreferencesViews in Frameworks */, + F1DF95E32BD1807C0045E591 /* Crashes in Frameworks */, 85E2BBCE2B8F534000DBEC7A /* History in Frameworks */, 1EA7B8D32B7E078C000330A4 /* SubscriptionUI in Frameworks */, B6F7128129F681EB00594A45 /* QuickLookUI.framework in Frameworks */, - 9DB6E7242AA0DC5800A17F3C /* LoginItems in Frameworks */, EE7295E32A545B9A008C0991 /* NetworkProtection in Frameworks */, 9807F645278CA16F00E1547B /* BrowserServicesKit in Frameworks */, 987799ED299998B1005D8EB6 /* Bookmarks in Frameworks */, - 7B5DD69A2AE51FFA001DE99C /* PixelKit in Frameworks */, 1E950E3F2912A10D0051A99B /* ContentBlocking in Frameworks */, 31A3A4E32B0C115F0021063C /* DataBrokerProtection in Frameworks */, 378F44E429B4BDE900899924 /* SwiftUIExtensions in Frameworks */, @@ -5093,8 +4252,10 @@ 7B31FD8C2AD125620086AA24 /* NetworkProtectionIPC in Frameworks */, 37269EFB2B332F9E005E8E46 /* Common in Frameworks */, AA06B6B72672AF8100F541C5 /* Sparkle in Frameworks */, + F198C71E2BD18D88000BF24D /* SwiftLintTool in Frameworks */, 1EA7B8D52B7E078C000330A4 /* Subscription in Frameworks */, B6B77BE8297973D4001E68A1 /* Navigation in Frameworks */, + F198C7122BD18A28000BF24D /* PixelKit in Frameworks */, 3739326729AE4B42009346AE /* DDGSync in Frameworks */, 7BA59C9B2AE18B49009A97B1 /* SystemExtensionManager in Frameworks */, 371D00E129D8509400EC8598 /* OpenSSL in Frameworks */, @@ -5103,6 +4264,7 @@ 85D44B862BA08D29001B4AB5 /* Suggestions in Frameworks */, 37DF000529F9C056002B7D3E /* SyncDataProviders in Frameworks */, 37BA812D29B3CD690053F1A3 /* SyncUI in Frameworks */, + F1DF95E72BD188B60045E591 /* LoginItems in Frameworks */, 372217802B3337FE00B8E9C2 /* TestUtils in Frameworks */, 7BA076BB2B65D61400D7FB72 /* NetworkProtectionProxy in Frameworks */, 4B4D60B12A0C83B900BCD287 /* NetworkProtectionUI in Frameworks */, @@ -5115,9 +4277,9 @@ buildActionMask = 2147483647; files = ( B6DA44172616C13800DD1EC2 /* OHHTTPStubs in Frameworks */, + F116A7C32BD1924B00F3FCF7 /* PixelKitTestingUtilities in Frameworks */, B65CD8CB2B316DF100A595BB /* SnapshotTesting in Frameworks */, B6DA44192616C13800DD1EC2 /* OHHTTPStubsSwift in Frameworks */, - 4B81AD352B29512B00706C96 /* PixelKitTestingUtilities in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -5322,6 +4484,14 @@ path = Subscription; sourceTree = ""; }; + 3169132B2BD2C7960051B46D /* ErrorView */ = { + isa = PBXGroup; + children = ( + 316913282BD2C7570051B46D /* DataBrokerProtectionErrorViewController.swift */, + ); + path = ErrorView; + sourceTree = ""; + }; 3171D6DC2889B6700068632A /* CookieManaged */ = { isa = PBXGroup; children = ( @@ -5344,6 +4514,8 @@ 3192EC862A4DCF0E001E97A5 /* DBP */ = { isa = PBXGroup; children = ( + 3169132B2BD2C7960051B46D /* ErrorView */, + 316913222BD2B6250051B46D /* DataBrokerProtectionPixelsHandler.swift */, 316850712AF3AD58009A2828 /* DataBrokerProtectionDebugMenu.swift */, 3192EC872A4DCF21001E97A5 /* DBPHomeViewController.swift */, 3139A1512AA4B3C000969C7D /* DataBrokerProtectionManager.swift */, @@ -5356,6 +4528,7 @@ BBDFDC592B2B8A0900F62D90 /* DataBrokerProtectionExternalWaitlistPixels.swift */, BB5789712B2CA70F0009DFE2 /* DataBrokerProtectionSubscriptionEventHandler.swift */, 4B37EE652B4CFC9500A89A61 /* RemoteMessaging */, + 316913252BD2B76F0051B46D /* DataBrokerPrerequisitesStatusVerifier.swift */, ); path = DBP; sourceTree = ""; @@ -5364,6 +4537,7 @@ isa = PBXGroup; children = ( 31A2FD162BAB41C500D0E741 /* DataBrokerProtectionVisibilityTests.swift */, + 31DC2F202BD6DE65001354EF /* DataBrokerPrerequisitesStatusVerifierTests.swift */, ); path = DBP; sourceTree = ""; @@ -5483,6 +4657,7 @@ 566B195F29CDB7A9007E38F4 /* Mocks */, 378205FA283C277800D1D4AA /* MainMenuTests.swift */, 566B195C29CDB692007E38F4 /* MoreOptionsMenuTests.swift */, + 9F9C49F52BC786790099738D /* MoreOptionsMenu+BookmarksTests.swift */, ); path = Menus; sourceTree = ""; @@ -5510,7 +4685,6 @@ 378B588B295CF3B9002C0CC0 /* AppTargetsBase.xcconfig */, 378B58CD295ECA75002C0CC0 /* DuckDuckGo.xcconfig */, 37DD516C296EAEDC00837F27 /* DuckDuckGoAppStore.xcconfig */, - 4B957C432AC7AF190062CA31 /* DuckDuckGoPrivacyPro.xcconfig */, 378E2799296F6FDE00FCADA2 /* ManualAppStoreRelease.xcconfig */, 7B6EC5E32AE2D88C004FE6DF /* DBP */, 4B18E3222A1D31E4005D0AAA /* NetworkProtection */, @@ -5549,7 +4723,6 @@ 3192A2702A4C4E330084EA89 /* DataBrokerProtection */, 9DB6E7222AA0DA7A00A17F3C /* LoginItems */, 7B25FE322AD12C990012AFAB /* NetworkProtectionMac */, - 4BE15DB12A0B0DD500898243 /* PixelKit */, 378F44E229B4B7B600899924 /* SwiftUIExtensions */, 37BA812B29B3CB8A0053F1A3 /* SyncUI */, 1E862A882A9FC01200F84D4B /* SubscriptionUI */, @@ -5897,24 +5070,26 @@ 4B4D60632A0B29FA00BCD287 /* BothAppTargets */ = { isa = PBXGroup; children = ( - EEA3EEAF2B24EB5100E8333A /* VPNLocation */, + 4B4D60722A0B29FA00BCD287 /* EventMapping+NetworkProtectionError.swift */, + BDE981DB2BBD110800645880 /* Assets */, + 4B4D606B2A0B29FA00BCD287 /* Invite */, + 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */, 9D9AE8682AA76CDC0026E7DC /* LoginItem+NetworkProtection.swift */, + B602E81C2A1E25B0006D261F /* NEOnDemandRuleExtension.swift */, + 4B4D60692A0B29FA00BCD287 /* NetworkProtection+ConvenienceInitializers.swift */, + 7B2DDCF72A93A8BB0039D884 /* NetworkProtectionAppEvents.swift */, + 4B4D606A2A0B29FA00BCD287 /* NetworkProtectionControllerErrorStore.swift */, 7BE146062A6A83C700C313B8 /* NetworkProtectionDebugMenu.swift */, - 7B05829D2A812AC000AC3F7C /* NetworkProtectionOnboardingMenu.swift */, - 7B430EA02A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift */, 7BBD45B02A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift */, - 7B934C3D2A866CFF00FC8F9C /* NetworkProtectionOnboardingMenu.swift */, - 7BFE95512A9DF1CE0081ABE9 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift */, - B602E81C2A1E25B0006D261F /* NEOnDemandRuleExtension.swift */, 4B4D60652A0B29FA00BCD287 /* NetworkProtectionNavBarButtonModel.swift */, 7B3618C12ADE75C8000D6154 /* NetworkProtectionNavBarPopoverManager.swift */, + 7B05829D2A812AC000AC3F7C /* NetworkProtectionOnboardingMenu.swift */, + 7B430EA02A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift */, 4B8F52402A18326600BE7131 /* NetworkProtectionTunnelController.swift */, - 4B4D60692A0B29FA00BCD287 /* NetworkProtection+ConvenienceInitializers.swift */, - 7BD3AF5C2A8E7AF1006F9F56 /* KeychainType+ClientDefault.swift */, - 4B4D606A2A0B29FA00BCD287 /* NetworkProtectionControllerErrorStore.swift */, - 4B4D606B2A0B29FA00BCD287 /* Invite */, - 4B4D60722A0B29FA00BCD287 /* EventMapping+NetworkProtectionError.swift */, - 7B2DDCF72A93A8BB0039D884 /* NetworkProtectionAppEvents.swift */, + 7BFE95512A9DF1CE0081ABE9 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift */, + EEA3EEAF2B24EB5100E8333A /* VPNLocation */, + 7B934C3D2A866CFF00FC8F9C /* NetworkProtectionOnboardingMenu.swift */, + B6F1B02D2BCE6B47005E863C /* TunnelControllerProvider.swift */, ); path = BothAppTargets; sourceTree = ""; @@ -6470,10 +5645,12 @@ 4BCF15E32ABB987F0083F6DF /* NetworkProtection */ = { isa = PBXGroup; children = ( + BDA7648F2BC4E56200D0400C /* Mocks */, 4BCF15E62ABB98A20083F6DF /* Resources */, 4BCF15E42ABB98990083F6DF /* NetworkProtectionRemoteMessageTests.swift */, 4BD57C032AC112DF00B580EE /* NetworkProtectionRemoteMessagingTests.swift */, 7B09CBA72BA4BE7000CF245B /* NetworkProtectionPixelEventTests.swift */, + BDA7648C2BC4E4EF00D0400C /* DefaultVPNLocationFormatterTests.swift */, ); path = NetworkProtection; sourceTree = ""; @@ -6517,6 +5694,7 @@ 4BF6961C28BE911100D402D4 /* RecentlyVisitedSiteModelTests.swift */, 569277C329DEE09D00B633EF /* ContinueSetUpModelTests.swift */, 56D145ED29E6DAD900E3488A /* DataImportProviderTests.swift */, + 560C3FFB2BC9911000F589CE /* PermanentSurveyManagerTests.swift */, ); path = HomePage; sourceTree = ""; @@ -6607,6 +5785,7 @@ 7B4CE8DB26F02108009134B1 /* UITests */ = { isa = PBXGroup; children = ( + 376E708D2BD686260082B7EB /* UI Tests.xctestplan */, EEBCE6802BA444FA00B9DF00 /* Common */, EEC7BE2D2BC6C09400F86835 /* AddressBarKeyboardShortcutsTests.swift */, EED735352BB46B6000F173D6 /* AutocompleteTests.swift */, @@ -6614,6 +5793,7 @@ EE7F74902BB5D76600CD9456 /* BookmarksBarTests.swift */, EE02D41B2BB460A600DBE6B3 /* BrowsingHistoryTests.swift */, EE0429DF2BA31D2F009EB20F /* FindInPageTests.swift */, + EE42CBCB2BC8004700AD411C /* PermissionsTests.swift */, EE9D81C22BC57A3700338BE3 /* StateRestorationTests.swift */, 7B4CE8E626F02134009134B1 /* TabBarTests.swift */, ); @@ -6757,6 +5937,7 @@ 85589E9027BFB9810038AD11 /* HomePageRecentlyVisitedModel.swift */, 569277C029DDCBB500B633EF /* HomePageContinueSetUpModel.swift */, 56D145EA29E6C99B00E3488A /* DataImportStatusProviding.swift */, + 560C3FFE2BCD5A1E00F589CE /* PermanentSurveyManager.swift */, ); path = Model; sourceTree = ""; @@ -6840,7 +6021,7 @@ 85CC1D7826A05E790062F04E /* Model */, 85CC1D7F26A05F6C0062F04E /* Services */, 85CC1D7926A05E820062F04E /* View */, - B642738127B65BAC0005DFD1 /* SecureVaultErrorReporter.swift */, + B642738127B65BAC0005DFD1 /* SecureVaultReporter.swift */, ); path = SecureVault; sourceTree = ""; @@ -7073,6 +6254,16 @@ path = DuckDuckGoDBPBackgroundAgent; sourceTree = ""; }; + 9F0FFFB62BCCAE80007C87DD /* Mocks */ = { + isa = PBXGroup; + children = ( + 9F0FFFB72BCCAE9C007C87DD /* AddEditBookmarkDialogViewModelMock.swift */, + 9F0FFFBA2BCCAEC2007C87DD /* AddEditBookmarkFolderDialogViewModelMock.swift */, + 9F0FFFBD2BCCAF1F007C87DD /* BookmarkAllTabsDialogViewModelMock.swift */, + ); + path = Mocks; + sourceTree = ""; + }; 9F872D9B2B9058B000138637 /* Extensions */ = { isa = PBXGroup; children = ( @@ -7084,9 +6275,12 @@ 9F982F102B82264400231028 /* ViewModels */ = { isa = PBXGroup; children = ( + 9F0FFFB62BCCAE80007C87DD /* Mocks */, 9F982F112B82268F00231028 /* AddEditBookmarkFolderDialogViewModelTests.swift */, 9F2606092B85C20400819292 /* AddEditBookmarkDialogViewModelTests.swift */, 9F26060D2B85E17D00819292 /* AddEditBookmarkDialogCoordinatorViewModelTests.swift */, + 9F0FFFB32BCCAE37007C87DD /* BookmarkAllTabsDialogCoordinatorViewModelTests.swift */, + 9FA5A0A82BC900FC00153786 /* BookmarkAllTabsDialogViewModelTests.swift */, ); path = ViewModels; sourceTree = ""; @@ -7104,6 +6298,7 @@ 9F56CFA82B82DC4300BB7F11 /* AddEditBookmarkFolderView.swift */, 9FEE98642B846870002E44E8 /* AddEditBookmarkView.swift */, 9F56CFB02B843F6C00BB7F11 /* BookmarksDialogViewFactory.swift */, + 9F9C49F82BC7BC970099738D /* BookmarkAllTabsDialogView.swift */, ); path = Dialog; sourceTree = ""; @@ -7116,6 +6311,14 @@ path = Factory; sourceTree = ""; }; + 9FAD62382BCFDB1D007F3A65 /* Helpers */ = { + isa = PBXGroup; + children = ( + 9FAD62392BCFDB32007F3A65 /* WebsiteInfoHelpers.swift */, + ); + path = Helpers; + sourceTree = ""; + }; AA0877B626D515EE00B05660 /* UserAgent */ = { isa = PBXGroup; children = ( @@ -7236,7 +6439,6 @@ 565E46DE2B2725DD0013AC2A /* SyncE2EUITests */, AA585D7F248FD31100E9A3E2 /* Products */, 85AE2FF024A33A2D002D507F /* Frameworks */, - EE0629702B90EE3500D868B4 /* Recovered References */, ); sourceTree = ""; }; @@ -7258,7 +6460,6 @@ 4B2D06692A13318400DE1F49 /* DuckDuckGo VPN App Store.app */, 9D9AE8D12AAA39A70026E7DC /* DuckDuckGo Personal Information Removal.app */, 9D9AE8F22AAA39D30026E7DC /* DuckDuckGo Personal Information Removal App Store.app */, - 4B957C412AC7AE700062CA31 /* DuckDuckGo Privacy Pro.app */, 565E46DD2B2725DC0013AC2A /* SyncE2EUITests.xctest */, 376113D42B29CD5B00E794BB /* SyncE2EUITests App Store.xctest */, 7BDA36E52B7E037100AD5388 /* VPNProxyExtension.appex */, @@ -7467,6 +6668,7 @@ AA652CAB25DD820D009059CC /* Bookmarks */ = { isa = PBXGroup; children = ( + 9FAD62382BCFDB1D007F3A65 /* Helpers */, 9F872D9B2B9058B000138637 /* Extensions */, 9FA75A3C2BA00DF500DA5FA6 /* Factory */, 9F982F102B82264400231028 /* ViewModels */, @@ -7493,6 +6695,7 @@ 98A95D87299A2DF900B9B81A /* BookmarkMigrationTests.swift */, 9F872D9F2B90644800138637 /* ContextualMenuTests.swift */, 9F0A2CF72B96A58600C5B8C0 /* BaseBookmarkEntityTests.swift */, + 9FAD623C2BD09DE5007F3A65 /* WebsiteInfoTests.swift */, ); path = Model; sourceTree = ""; @@ -7502,6 +6705,8 @@ children = ( AA652CB025DD825B009059CC /* LocalBookmarkStoreTests.swift */, 986189E52A7CFB3E001B4519 /* LocalBookmarkStoreSavingTests.swift */, + 9FA5A0AC2BC9037A00153786 /* BookmarkFolderStoreMock.swift */, + 9F8D57312BCCCB9A00AEA660 /* UserDefaultsBookmarkFoldersStoreTests.swift */, ); path = Services; sourceTree = ""; @@ -7746,6 +6951,7 @@ B626A75929921FAA00053070 /* NavigationActionPolicyExtension.swift */, B634DBE4293C944700C3C99E /* NewWindowPolicy.swift */, AA9FF95824A1ECF20039E328 /* Tab.swift */, + B6F1B0252BCE5A50005E863C /* TabContent.swift */, B634DBE0293C8FD500C3C99E /* Tab+Dialogs.swift */, B61E2CD4294346C000773D8A /* Tab+Navigation.swift */, B634DBDE293C8F7F00C3C99E /* Tab+UIDelegate.swift */, @@ -7885,6 +7091,8 @@ 9F56CFAC2B84326C00BB7F11 /* AddEditBookmarkDialogViewModel.swift */, 9FEE98682B85B869002E44E8 /* BookmarksDialogViewModel.swift */, 9FEE986C2B85BA17002E44E8 /* AddEditBookmarkDialogCoordinatorViewModel.swift */, + 9F9C4A002BC7F36D0099738D /* BookmarkAllTabsDialogCoordinatorViewModel.swift */, + 9F9C49FC2BC7E9820099738D /* BookmarkAllTabsDialogViewModel.swift */, ); path = ViewModel; sourceTree = ""; @@ -7932,7 +7140,6 @@ children = ( AAC30A25268DFEE200D2D9CD /* CrashReporter.swift */, AAC30A27268E045400D2D9CD /* CrashReportReader.swift */, - AAC30A2B268F1ECD00D2D9CD /* CrashReportSender.swift */, AAC30A2D268F1EE300D2D9CD /* CrashReportPromptPresenter.swift */, AAC30A29268E239100D2D9CD /* CrashReport.swift */, ); @@ -8008,6 +7215,7 @@ B6DA06E52913F39400225DE2 /* MenuItemSelectors.swift */, AAC5E4D625D6A710007F5990 /* BookmarkStore.swift */, 987799F829999973005D8EB6 /* LocalBookmarkStore.swift */, + 9FA5A0A42BC8F34900153786 /* UserDefaultsBookmarkFoldersStore.swift */, ); path = Services; sourceTree = ""; @@ -8422,24 +7630,26 @@ B647EFB32922539400BA628D /* TabExtensions */ = { isa = PBXGroup; children = ( - B6BDDA002942389000F68088 /* TabExtensions.swift */, - 1D9A4E592B43213B00F449E2 /* TabSnapshotExtension.swift */, B647EFBA2922584B00BA628D /* AdClickAttributionTabExtension.swift */, B6C00ECA292F839D009C73A6 /* AutofillTabExtension.swift */, + B6F1B0212BCE5658005E863C /* BrokenSiteInfoTabExtension.swift */, B6D574B12947224C008ED1B6 /* ContentBlockingTabExtension.swift */, B6DA06E32913ECEE00225DE2 /* ContextMenuManager.swift */, + B6685E4129A61C460043D2EE /* DownloadsTabExtension.swift */, B6C416A6294A4AE500C4F2E7 /* DuckPlayerTabExtension.swift */, B6D574B329472253008ED1B6 /* FBProtectionTabExtension.swift */, - B6685E4129A61C460043D2EE /* DownloadsTabExtension.swift */, B6C00ECC292F89D9009C73A6 /* FindInPageTabExtension.swift */, B66260DF29AC6EBD00E9E3EE /* HistoryTabExtension.swift */, B6C00ED4292FB21E009C73A6 /* HoveredLinkTabExtension.swift */, B6BF5D8829470BC4006742B1 /* HTTPSUpgradeTabExtension.swift */, - B6BF5D842946FFDA006742B1 /* PrivacyDashboardTabExtension.swift */, B66260E529ACAE4B00E9E3EE /* NavigationHotkeyHandler.swift */, B66260DC29AC5D4300E9E3EE /* NavigationProtectionTabExtension.swift */, - B626A76C29928B1600053070 /* TestsClosureNavigationResponder.swift */, + B6F1B0292BCE675C005E863C /* NetworkProtectionControllerTabExtension.swift */, + B6BF5D842946FFDA006742B1 /* PrivacyDashboardTabExtension.swift */, 56BA1E742BAAF70F001CF69F /* SSLErrorPageTabExtension.swift */, + B6BDDA002942389000F68088 /* TabExtensions.swift */, + 1D9A4E592B43213B00F449E2 /* TabSnapshotExtension.swift */, + B626A76C29928B1600053070 /* TestsClosureNavigationResponder.swift */, ); path = TabExtensions; sourceTree = ""; @@ -8556,6 +7766,9 @@ B69B50392726A12500758A2B /* LocalStatisticsStore.swift */, B69B50372726A12000758A2B /* VariantManager.swift */, B69B50562727D16900758A2B /* AtbAndVariantCleanup.swift */, + B6DA44012616B28300DD1EC2 /* PixelDataStore.swift */, + B68C92C32750EF76002AC6B0 /* PixelDataRecord.swift */, + B6DA44062616B30600DD1EC2 /* PixelDataModel.xcdatamodeld */, 9FBD84512BB3AACB00220859 /* AttributionOriginFileProvider.swift */, 9FBD84722BB3E15D00220859 /* InstallationAttributionPixelHandler.swift */, ); @@ -8607,17 +7820,12 @@ B6A9E44E26142AF90067D1B9 /* Statistics */ = { isa = PBXGroup; children = ( - 857E5AF32A79044900FC0FB4 /* Experiment */, B69B50332726A10700758A2B /* ATB */, - B6A9E45226142B070067D1B9 /* Pixel.swift */, - 4B67853E2AA7C726008A5004 /* DailyPixel.swift */, - B6A9E47626146A570067D1B9 /* PixelEvent.swift */, - B6A9E47E26146A800067D1B9 /* PixelArguments.swift */, - B6A9E48326146AAB0067D1B9 /* PixelParameters.swift */, + 857E5AF32A79044900FC0FB4 /* Experiment */, B610F2BA27A145C500FCEBE9 /* RulesCompilationMonitor.swift */, - B6DA44012616B28300DD1EC2 /* PixelDataStore.swift */, - B68C92C32750EF76002AC6B0 /* PixelDataRecord.swift */, - B6DA44062616B30600DD1EC2 /* PixelDataModel.xcdatamodeld */, + F188267B2BBEB3AA00D9AC4F /* GeneralPixel.swift */, + F18826832BBEE31700D9AC4F /* PixelKit+Assertion.swift */, + F188267F2BBEB58100D9AC4F /* PrivacyProPixel.swift */, ); path = Statistics; sourceTree = ""; @@ -8707,10 +7915,6 @@ children = ( 857E5AF72A79617100FC0FB4 /* PixelExperiment */, B69B50402726C3F400758A2B /* ATB */, - B6DA44102616C0FC00DD1EC2 /* PixelTests.swift */, - 4BC2621C293996410087A482 /* PixelEventTests.swift */, - B662D3D82755D7AD0035D4D6 /* PixelStoreTests.swift */, - B6DA44222616CABC00DD1EC2 /* PixelArgumentsTests.swift */, B6DA441D2616C84600DD1EC2 /* PixelStoreMock.swift */, 4B117F7C276C0CB5002F3D8C /* LocalStatisticsStoreTests.swift */, B610F2E327A8F37A00FCEBE9 /* CBRCompileTimeReporterTests.swift */, @@ -8788,6 +7992,23 @@ path = View; sourceTree = ""; }; + BDA7648F2BC4E56200D0400C /* Mocks */ = { + isa = PBXGroup; + children = ( + BDA764902BC4E57200D0400C /* MockVPNLocationFormatter.swift */, + ); + path = Mocks; + sourceTree = ""; + }; + BDE981DB2BBD110800645880 /* Assets */ = { + isa = PBXGroup; + children = ( + BD384AC82BBC821100EF3735 /* vpn-dark-mode.json */, + BD384AC72BBC821100EF3735 /* vpn-light-mode.json */, + ); + path = Assets; + sourceTree = ""; + }; C13909F22B85FD60001626ED /* Autofill */ = { isa = PBXGroup; children = ( @@ -8849,16 +8070,10 @@ path = fonts; sourceTree = ""; }; - EE0629702B90EE3500D868B4 /* Recovered References */ = { - isa = PBXGroup; - children = ( - ); - name = "Recovered References"; - sourceTree = ""; - }; EEA3EEAF2B24EB5100E8333A /* VPNLocation */ = { isa = PBXGroup; children = ( + BDA7647B2BC497BE00D0400C /* DefaultVPNLocationFormatter.swift */, EEA3EEB22B24EC0600E8333A /* VPNLocationViewModel.swift */, EEA3EEB02B24EBD000E8333A /* NetworkProtectionVPNCountryLabelsModel.swift */, EEC4A6682B2C87D300F7C0AA /* VPNLocationView.swift */, @@ -8931,13 +8146,13 @@ 3706FCA6293F65D500E42796 /* Frameworks */, 3706FCB1293F65D500E42796 /* Resources */, 4BBA2D272B6AC09D00F6A470 /* Embed Login Items */, + 6A8856B31B2BC5078B61ED81 /* Run swiftlint */, ); buildRules = ( ); dependencies = ( 4BBA2D2B2B6AD01E00F6A470 /* PBXTargetDependency */, 4BBA2D292B6ACD4D00F6A470 /* PBXTargetDependency */, - B69D061C2A4C0BC10032D14D /* PBXTargetDependency */, 4B5F14FE2A1529230060320F /* PBXTargetDependency */, ); name = "DuckDuckGo Privacy Browser App Store"; @@ -8956,7 +8171,6 @@ B6EC37FE29B8D915001ACE79 /* Configuration */, 37DF000629F9C061002B7D3E /* SyncDataProviders */, 9DC70B192AA1FA5B005A844B /* LoginItems */, - 7B5F9A742AE2BE4E002AEBC0 /* PixelKit */, 37269EFC2B332FAC005E8E46 /* Common */, 372217812B33380700B8E9C2 /* TestUtils */, 4BF97AD02B43C43F00EB4240 /* NetworkProtectionIPC */, @@ -8971,6 +8185,9 @@ 85D44B872BA08D30001B4AB5 /* Suggestions */, 4BCBE4592BA7E17800FC75A1 /* Subscription */, 9FF521472BAA909C00B9819B /* Lottie */, + 537FC71EA5115A983FAF3170 /* Crashes */, + F198C7132BD18A30000BF24D /* PixelKit */, + F198C71F2BD18D92000BF24D /* SwiftLintTool */, ); productName = DuckDuckGo; productReference = 3706FD05293F65D500E42796 /* DuckDuckGo App Store.app */; @@ -8994,8 +8211,8 @@ packageProductDependencies = ( 3706FDD6293F661700E42796 /* OHHTTPStubs */, 3706FDD8293F661700E42796 /* OHHTTPStubsSwift */, - 4B81AD362B29513100706C96 /* PixelKitTestingUtilities */, B65CD8CE2B316E0200A595BB /* SnapshotTesting */, + F116A7C62BD1925500F3FCF7 /* PixelKitTestingUtilities */, ); productName = DuckDuckGoTests; productReference = 3706FE99293F661700E42796 /* Unit Tests App Store.xctest */; @@ -9012,7 +8229,6 @@ buildRules = ( ); dependencies = ( - B69D061A2A4C0AD80032D14D /* PBXTargetDependency */, B6EC37F429B5DA94001ACE79 /* PBXTargetDependency */, 37079A95294236FA0031BB3C /* PBXTargetDependency */, ); @@ -9035,12 +8251,9 @@ buildRules = ( ); dependencies = ( - B6F997C12B8F35F800476735 /* PBXTargetDependency */, 376113D62B29CD6800E794BB /* PBXTargetDependency */, ); name = "SyncE2EUITests App Store"; - packageProductDependencies = ( - ); productName = DuckDuckGoSyncUITests; productReference = 376113D42B29CD5B00E794BB /* SyncE2EUITests App Store.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; @@ -9057,7 +8270,6 @@ ); dependencies = ( B6CAC23F2B8F0ECA006CD402 /* PBXTargetDependency */, - B69D06162A4C0ACD0032D14D /* PBXTargetDependency */, B6EC37F229B5DA8F001ACE79 /* PBXTargetDependency */, ); name = "Integration Tests"; @@ -9065,6 +8277,7 @@ B6AE39F229374AEC00C37AA4 /* OHHTTPStubs */, B6AE39F429374AEC00C37AA4 /* OHHTTPStubsSwift */, B65CD8CC2B316DFC00A595BB /* SnapshotTesting */, + F116A7C82BD1929000F3FCF7 /* PixelKitTestingUtilities */, ); productName = "Integration Tests"; productReference = 4B1AD89D25FC27E200261379 /* Integration Tests.xctest */; @@ -9082,16 +8295,15 @@ buildRules = ( ); dependencies = ( - B6080B9F2B20AF7B00B418EF /* PBXTargetDependency */, ); name = NetworkProtectionSystemExtension; packageProductDependencies = ( - 4B2537762A11BFE100610219 /* PixelKit */, 4B2D062B2A11C0E100DE1F49 /* Networking */, EE7295E82A545BC4008C0991 /* NetworkProtection */, 37269F002B332FC8005E8E46 /* Common */, 7BBE2B7A2B61663C00697445 /* NetworkProtectionProxy */, 7B37C7A42BAA32A50062546A /* Subscription */, + F198C7172BD18A4C000BF24D /* PixelKit */, ); productName = NetworkProtectionSystemExtension; productReference = 4B25375A2A11BE7300610219 /* com.duckduckgo.macos.vpn.network-extension.debug.systemextension */; @@ -9110,7 +8322,6 @@ buildRules = ( ); dependencies = ( - B6080BA32B20AF8300B418EF /* PBXTargetDependency */, 7BEC18312AD5DA3300D30536 /* PBXTargetDependency */, ); name = DuckDuckGoVPN; @@ -9120,10 +8331,11 @@ 7BEEA5112AD1235B00A9E72B /* NetworkProtectionIPC */, 7BEEA5152AD1236E00A9E72B /* NetworkProtectionUI */, 7BEC182E2AD5D8DC00D30536 /* SystemExtensionManager */, - 7BFCB74D2ADE7E1A00DA3EA7 /* PixelKit */, 4B41EDAA2B1544B2001EEDF4 /* LoginItems */, 7B00997C2B6508B700FE7C31 /* NetworkProtectionProxy */, EE2F9C5A2B90F2FF00D45FC9 /* Subscription */, + F198C7192BD18A5B000BF24D /* PixelKit */, + BDADBDC82BD2BC2200421B9B /* Lottie */, ); productName = DuckDuckGoAgent; productReference = 4B2D06392A11CFBB00DE1F49 /* DuckDuckGo VPN.app */; @@ -9145,7 +8357,6 @@ dependencies = ( 7BDA36F82B7E082100AD5388 /* PBXTargetDependency */, 4BA7C4DF2B3F6F4900AFE511 /* PBXTargetDependency */, - B6080BA52B20AF8800B418EF /* PBXTargetDependency */, ); name = DuckDuckGoVPNAppStore; packageProductDependencies = ( @@ -9153,10 +8364,11 @@ EE7295EE2A545C12008C0991 /* NetworkProtection */, 7BA7CC602AD1211C0042E5CE /* Networking */, 7BEEA5132AD1236300A9E72B /* NetworkProtectionIPC */, - 7BFCB74F2ADE7E2300DA3EA7 /* PixelKit */, 7B00997E2B6508C200FE7C31 /* NetworkProtectionProxy */, 4BA7C4DC2B3F64E500AFE511 /* LoginItems */, 4BCBE45B2BA7E18500FC75A1 /* Subscription */, + F198C71B2BD18A61000BF24D /* PixelKit */, + BDADBDCA2BD2BC2800421B9B /* Lottie */, ); productName = DuckDuckGoAgentAppStore; productReference = 4B2D06692A13318400DE1F49 /* DuckDuckGo VPN App Store.app */; @@ -9173,7 +8385,6 @@ buildRules = ( ); dependencies = ( - B6080BA12B20AF7F00B418EF /* PBXTargetDependency */, 4B4BEC4A2A11B627001D9AC5 /* PBXTargetDependency */, ); name = DuckDuckGoNotifications; @@ -9196,76 +8407,21 @@ buildRules = ( ); dependencies = ( - B6080B9D2B20AF7700B418EF /* PBXTargetDependency */, 4B4D60532A0B29CB00BCD287 /* PBXTargetDependency */, ); name = NetworkProtectionAppExtension; packageProductDependencies = ( - 4B4D60972A0B2A5C00BCD287 /* PixelKit */, 4B4D60AE2A0C837F00BCD287 /* Networking */, EE7295E62A545BBB008C0991 /* NetworkProtection */, 37269EFE2B332FBB005E8E46 /* Common */, 7B25856D2BA2F2ED00D49F79 /* NetworkProtectionUI */, + DC3F73D49B2D44464AFEFCD8 /* Subscription */, + F198C7152BD18A44000BF24D /* PixelKit */, ); productName = NetworkProtectionAppExtension; productReference = 4B4D603D2A0B290200BCD287 /* NetworkProtectionAppExtension.appex */; productType = "com.apple.product-type.app-extension"; }; - 4B9579252AC7AE700062CA31 /* DuckDuckGo Privacy Pro */ = { - isa = PBXNativeTarget; - buildConfigurationList = 4B957C3C2AC7AE700062CA31 /* Build configuration list for PBXNativeTarget "DuckDuckGo Privacy Pro" */; - buildPhases = ( - 4B9579432AC7AE700062CA31 /* Assert Xcode version */, - 4B9579442AC7AE700062CA31 /* Check Embedded Config URLs */, - 4B9579452AC7AE700062CA31 /* Sources */, - 4B957BD42AC7AE700062CA31 /* Frameworks */, - 4B957BEC2AC7AE700062CA31 /* Resources */, - 4B957C322AC7AE700062CA31 /* Make /Applications symlink, remove app on Clean build */, - 4B957C332AC7AE700062CA31 /* Embed Login Items */, - 7B31FD942AD126FA0086AA24 /* Embed System Network Extension */, - ); - buildRules = ( - ); - dependencies = ( - 4B9579262AC7AE700062CA31 /* PBXTargetDependency */, - 31C6E9AB2B0C07A30086DC30 /* PBXTargetDependency */, - ); - name = "DuckDuckGo Privacy Pro"; - packageProductDependencies = ( - 4B9579292AC7AE700062CA31 /* Sparkle */, - 4B95792B2AC7AE700062CA31 /* BrowserServicesKit */, - 4B95792E2AC7AE700062CA31 /* ContentBlocking */, - 4B95792F2AC7AE700062CA31 /* PrivacyDashboard */, - 4B9579302AC7AE700062CA31 /* UserScript */, - 4B9579312AC7AE700062CA31 /* Persistence */, - 4B9579322AC7AE700062CA31 /* Configuration */, - 4B9579332AC7AE700062CA31 /* Navigation */, - 4B9579342AC7AE700062CA31 /* Bookmarks */, - 4B9579352AC7AE700062CA31 /* DDGSync */, - 4B9579362AC7AE700062CA31 /* SyncUI */, - 4B9579372AC7AE700062CA31 /* SwiftUIExtensions */, - 4B9579382AC7AE700062CA31 /* OpenSSL */, - 4B95793C2AC7AE700062CA31 /* SyncDataProviders */, - 4B95793D2AC7AE700062CA31 /* NetworkProtectionUI */, - 4B95793E2AC7AE700062CA31 /* NetworkProtection */, - 4B95793F2AC7AE700062CA31 /* LoginItems */, - 7B31FD8F2AD1257B0086AA24 /* NetworkProtectionIPC */, - 3143C8782B0D1F3D00382627 /* DataBrokerProtection */, - 1E0068AC2B1673BB00BBF43B /* SubscriptionUI */, - 37269F022B332FD8005E8E46 /* Common */, - 372217832B33380E00B8E9C2 /* TestUtils */, - 373FB4B42B4D6C57004C88D6 /* PreferencesViews */, - 1E21F8E22B73E48600FB272E /* Subscription */, - 7B94E1642B7ED95100E32B96 /* NetworkProtectionProxy */, - 85E2BBD12B8F536F00DBEC7A /* History */, - F1D43AF62B98E48F00BAB743 /* BareBonesBrowserKit */, - 85D44B892BA08D3B001B4AB5 /* Suggestions */, - 9FF521492BAA90C400B9819B /* Lottie */, - ); - productName = DuckDuckGo; - productReference = 4B957C412AC7AE700062CA31 /* DuckDuckGo Privacy Pro.app */; - productType = "com.apple.product-type.application"; - }; 565E46DC2B2725DC0013AC2A /* SyncE2EUITests */ = { isa = PBXNativeTarget; buildConfigurationList = 565E46E52B2725DD0013AC2A /* Build configuration list for PBXNativeTarget "SyncE2EUITests" */; @@ -9277,11 +8433,8 @@ buildRules = ( ); dependencies = ( - B6F997BF2B8F35F400476735 /* PBXTargetDependency */, ); name = SyncE2EUITests; - packageProductDependencies = ( - ); productName = DuckDuckGoSyncUITests; productReference = 565E46DD2B2725DC0013AC2A /* SyncE2EUITests.xctest */; productType = "com.apple.product-type.bundle.ui-testing"; @@ -9298,7 +8451,6 @@ ); dependencies = ( EE02D41E2BB460B500DBE6B3 /* PBXTargetDependency */, - B6F997BD2B8F35EF00476735 /* PBXTargetDependency */, ); name = "UI Tests"; packageProductDependencies = ( @@ -9325,7 +8477,6 @@ packageProductDependencies = ( 7B97CD582B7E0B57004FEF43 /* NetworkProtectionProxy */, 7B97CD5A2B7E0B85004FEF43 /* Common */, - 7B97CD612B7E0C4B004FEF43 /* PixelKit */, 7B7DFB212B7E7473009EA1A3 /* Networking */, ); productName = VPNProxyExtension; @@ -9344,12 +8495,10 @@ buildRules = ( ); dependencies = ( - B6080BA92B20AF8F00B418EF /* PBXTargetDependency */, ); name = DuckDuckGoDBPBackgroundAgent; packageProductDependencies = ( 9D9AE8F82AAA3AD00026E7DC /* DataBrokerProtection */, - 9D6983F82AC773C3002C02FC /* PixelKit */, 9DEF97E02B06C4EE00764F03 /* Networking */, ); productName = DuckDuckGoAgent; @@ -9368,12 +8517,10 @@ buildRules = ( ); dependencies = ( - B6080BAB2B20AF9200B418EF /* PBXTargetDependency */, ); name = DuckDuckGoDBPBackgroundAgentAppStore; packageProductDependencies = ( 9D9AE8FA2AAA3AD90026E7DC /* DataBrokerProtection */, - 9D6983FA2AC773C8002C02FC /* PixelKit */, 315A023E2B6421AE00BFA577 /* Networking */, ); productName = DuckDuckGoAgent; @@ -9391,12 +8538,12 @@ AA585D7C248FD31100E9A3E2 /* Resources */, B6F2C8722A7A4C7D000498CF /* Make /Applications symlink, remove app on Clean build */, 4B2D065D2A11D2AE00DE1F49 /* Embed Login Items */, + 28003FDBDB96625F1630CFF2 /* Run swiftlint */, ); buildRules = ( ); dependencies = ( 7B4627742B9AF2C8004ACE0B /* PBXTargetDependency */, - B6F997BB2B8F353F00476735 /* PBXTargetDependency */, 4B5F14FC2A15291D0060320F /* PBXTargetDependency */, 31C6E9AD2B0C07BA0086DC30 /* PBXTargetDependency */, ); @@ -9418,14 +8565,11 @@ 37DF000429F9C056002B7D3E /* SyncDataProviders */, 4B4D60B02A0C83B900BCD287 /* NetworkProtectionUI */, EE7295E22A545B9A008C0991 /* NetworkProtection */, - 9DB6E7232AA0DC5800A17F3C /* LoginItems */, 7B31FD8B2AD125620086AA24 /* NetworkProtectionIPC */, 7BA59C9A2AE18B49009A97B1 /* SystemExtensionManager */, - 7B5DD6992AE51FFA001DE99C /* PixelKit */, 31A3A4E22B0C115F0021063C /* DataBrokerProtection */, 37269EFA2B332F9E005E8E46 /* Common */, 3722177F2B3337FE00B8E9C2 /* TestUtils */, - 373FB4B02B4D6C42004C88D6 /* PreferencesViews */, 7BA076BA2B65D61400D7FB72 /* NetworkProtectionProxy */, 85E2BBCD2B8F534000DBEC7A /* History */, 1EA7B8D22B7E078C000330A4 /* SubscriptionUI */, @@ -9433,6 +8577,10 @@ F1D43AF22B98E47800BAB743 /* BareBonesBrowserKit */, 85D44B852BA08D29001B4AB5 /* Suggestions */, 9FF521452BAA908500B9819B /* Lottie */, + 08D4923DC968236E22E373E2 /* Crashes */, + F1DF95E62BD188B60045E591 /* LoginItems */, + F198C7112BD18A28000BF24D /* PixelKit */, + F198C71D2BD18D88000BF24D /* SwiftLintTool */, ); productName = DuckDuckGo; productReference = AA585D7E248FD31100E9A3E2 /* DuckDuckGo.app */; @@ -9451,14 +8599,13 @@ dependencies = ( B6E6BA1D2BA2E049008AA7E1 /* PBXTargetDependency */, B6CAC23D2B8F0EC6006CD402 /* PBXTargetDependency */, - B69D06142A4C0AC50032D14D /* PBXTargetDependency */, ); name = "Unit Tests"; packageProductDependencies = ( B6DA44162616C13800DD1EC2 /* OHHTTPStubs */, B6DA44182616C13800DD1EC2 /* OHHTTPStubsSwift */, - 4B81AD342B29512B00706C96 /* PixelKitTestingUtilities */, B65CD8CA2B316DF100A595BB /* SnapshotTesting */, + F116A7C22BD1924B00F3FCF7 /* PixelKitTestingUtilities */, ); productName = DuckDuckGoTests; productReference = AA585D90248FD31400E9A3E2 /* Unit Tests.xctest */; @@ -9621,7 +8768,6 @@ 4B2D06682A13318400DE1F49 /* DuckDuckGoVPNAppStore */, 9D9AE8B22AAA39A70026E7DC /* DuckDuckGoDBPBackgroundAgent */, 9D9AE8D32AAA39D30026E7DC /* DuckDuckGoDBPBackgroundAgentAppStore */, - 4B9579252AC7AE700062CA31 /* DuckDuckGo Privacy Pro */, B6E6B9F22BA1FD90008AA7E1 /* sandbox-test-tool */, ); }; @@ -9674,7 +8820,9 @@ 3706FCE6293F65D500E42796 /* social_images in Resources */, 3706FCE7293F65D500E42796 /* shield-dot-mouse-over.json in Resources */, 3706FCE9293F65D500E42796 /* fb-sdk.js in Resources */, + BD384ACB2BBC821B00EF3735 /* vpn-dark-mode.json in Resources */, 3706FCEA293F65D500E42796 /* PasswordManager.storyboard in Resources */, + BD384ACC2BBC821B00EF3735 /* vpn-light-mode.json in Resources */, 3706FCEB293F65D500E42796 /* dark-flame-mouse-over.json in Resources */, 3706FCEC293F65D500E42796 /* flame-mouse-over.json in Resources */, 3706FCED293F65D500E42796 /* httpsMobileV2Bloom.bin in Resources */, @@ -9736,7 +8884,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + BDE981DA2BBD10D600645880 /* vpn-light-mode.json in Resources */, 7BA7CC482AD11E5C0042E5CE /* Assets.xcassets in Resources */, + BDE981D92BBD10D600645880 /* vpn-dark-mode.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -9744,7 +8894,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + BDADBDCD2BD2BC5700421B9B /* vpn-light-mode.json in Resources */, 7BA7CC472AD11E5C0042E5CE /* Assets.xcassets in Resources */, + BDADBDCC2BD2BC4D00421B9B /* vpn-dark-mode.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -9756,69 +8908,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 4B957BEC2AC7AE700062CA31 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 561D66682B95C45A008ACC5C /* Suggestion.storyboard in Resources */, - 4B957BEF2AC7AE700062CA31 /* CrashReports.storyboard in Resources */, - 4B957BF02AC7AE700062CA31 /* trackerData.json in Resources */, - 4B957BF12AC7AE700062CA31 /* dark-shield-dot-mouse-over.json in Resources */, - 4B957BF22AC7AE700062CA31 /* 01_Fire_really_small.json in Resources */, - 4B957BF32AC7AE700062CA31 /* Onboarding.storyboard in Resources */, - 56CEE9102B7A72FE00CF10AA /* InfoPlist.xcstrings in Resources */, - 4B957BF42AC7AE700062CA31 /* FireproofDomains.storyboard in Resources */, - 4B957BF52AC7AE700062CA31 /* clickToLoadConfig.json in Resources */, - 4B957BF72AC7AE700062CA31 /* dark-shield.json in Resources */, - 4B957BF82AC7AE700062CA31 /* BookmarksBarPromptAssets.xcassets in Resources */, - 4B957BF92AC7AE700062CA31 /* dark-shield-mouse-over.json in Resources */, - 4B957BFA2AC7AE700062CA31 /* autoconsent-bundle.js in Resources */, - 4B957BFB2AC7AE700062CA31 /* ContentOverlay.storyboard in Resources */, - 4B957BFC2AC7AE700062CA31 /* FindInPage.storyboard in Resources */, - 4B957BFD2AC7AE700062CA31 /* JSAlert.storyboard in Resources */, - 4B957C002AC7AE700062CA31 /* userscript.js in Resources */, - 4B957C012AC7AE700062CA31 /* fb-tds.json in Resources */, - 4B957C032AC7AE700062CA31 /* README.md in Resources */, - 4B957C042AC7AE700062CA31 /* Assets.xcassets in Resources */, - 4B957C052AC7AE700062CA31 /* NavigationBar.storyboard in Resources */, - 4B957C062AC7AE700062CA31 /* FirePopoverCollectionViewHeader.xib in Resources */, - 4B957C072AC7AE700062CA31 /* TabBar.storyboard in Resources */, - 4B957C082AC7AE700062CA31 /* shield-dot.json in Resources */, - 4B957C0B2AC7AE700062CA31 /* BookmarksBarCollectionViewItem.xib in Resources */, - 4B957C0C2AC7AE700062CA31 /* PrivacyDashboard.storyboard in Resources */, - 4B957C0D2AC7AE700062CA31 /* shield.json in Resources */, - 4B957C0E2AC7AE700062CA31 /* TabBarViewItem.xib in Resources */, - 4B957C102AC7AE700062CA31 /* httpsMobileV2FalsePositives.json in Resources */, - 4B957C112AC7AE700062CA31 /* BookmarksBar.storyboard in Resources */, - 4B957C122AC7AE700062CA31 /* trackers-1.json in Resources */, - 4B957C132AC7AE700062CA31 /* dark-trackers-1.json in Resources */, - 4B957C142AC7AE700062CA31 /* Feedback.storyboard in Resources */, - B658BAB92B0F849100D1F2C7 /* Localizable.xcstrings in Resources */, - 4B957C182AC7AE700062CA31 /* shield-mouse-over.json in Resources */, - 4B957C1A2AC7AE700062CA31 /* PermissionAuthorization.storyboard in Resources */, - 4B957C1B2AC7AE700062CA31 /* dark-trackers-3.json in Resources */, - 4B957C1C2AC7AE700062CA31 /* dark-trackers-2.json in Resources */, - 4B957C1D2AC7AE700062CA31 /* Fire.storyboard in Resources */, - 4B957C1F2AC7AE700062CA31 /* social_images in Resources */, - 4B957C202AC7AE700062CA31 /* shield-dot-mouse-over.json in Resources */, - 4B957C222AC7AE700062CA31 /* fb-sdk.js in Resources */, - 4B957C232AC7AE700062CA31 /* PasswordManager.storyboard in Resources */, - 4B957C242AC7AE700062CA31 /* dark-flame-mouse-over.json in Resources */, - 4B957C252AC7AE700062CA31 /* flame-mouse-over.json in Resources */, - 4B957C262AC7AE700062CA31 /* httpsMobileV2Bloom.bin in Resources */, - 4B957C272AC7AE700062CA31 /* trackers-3.json in Resources */, - 4B957C282AC7AE700062CA31 /* macos-config.json in Resources */, - 4B957C292AC7AE700062CA31 /* httpsMobileV2BloomSpec.json in Resources */, - 4B957C2A2AC7AE700062CA31 /* TabBarFooter.xib in Resources */, - 4B957C2C2AC7AE700062CA31 /* FirePopoverCollectionViewItem.xib in Resources */, - 4B957C2D2AC7AE700062CA31 /* ProximaNova-Bold-webfont.woff2 in Resources */, - 4B957C2E2AC7AE700062CA31 /* dark-shield-dot.json in Resources */, - 4B957C2F2AC7AE700062CA31 /* trackers-2.json in Resources */, - 4B957C302AC7AE700062CA31 /* ProximaNova-Reg-webfont.woff2 in Resources */, - 4B957C312AC7AE700062CA31 /* clickToLoad.js in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 565E46DB2B2725DC0013AC2A /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -9917,7 +9006,9 @@ EA18D1CA272F0DC8006DC101 /* social_images in Resources */, AA7EB6E927E880A600036718 /* shield-dot-mouse-over.json in Resources */, EAC80DE0271F6C0100BBF02D /* fb-sdk.js in Resources */, + BD384AC92BBC821A00EF3735 /* vpn-dark-mode.json in Resources */, 85625994269C8F9600EE44BC /* PasswordManager.storyboard in Resources */, + BD384ACA2BBC821A00EF3735 /* vpn-light-mode.json in Resources */, AA7EB6E327E7D05500036718 /* dark-flame-mouse-over.json in Resources */, AA7EB6E227E7D05500036718 /* flame-mouse-over.json in Resources */, 4B677433255DBEB800025BD8 /* httpsMobileV2Bloom.bin in Resources */, @@ -9957,7 +9048,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 3121F62B2B64266A002F706A /* Copy Swift Package resources */ = { + 28003FDBDB96625F1630CFF2 /* Run swiftlint */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; buildActionMask = 2147483647; @@ -9967,16 +9058,16 @@ ); inputPaths = ( ); - name = "Copy Swift Package resources"; + name = "Run swiftlint"; outputFileListPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n# We had issues where the Swift Package resources were not being added to the Agent Apps,\n# so we're manually coping them here.\n# It seems to be a known issue: https://forums.swift.org/t/swift-packages-resource-bundle-not-present-in-xcarchive-when-framework-using-said-package-is-archived/50084/2\ncp -RL \"${BUILT_PRODUCTS_DIR}\"/ContentScopeScripts_ContentScopeScripts.bundle \"${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/\"\ncp -RL \"${BUILT_PRODUCTS_DIR}\"/DataBrokerProtection_DataBrokerProtection.bundle \"${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/\"\n"; + shellScript = "if [ \"$CONFIGURATION\" != \"Debug\" ] || [ \"$ENABLE_PREVIEWS\" = \"YES\" ]; then exit 0; fi\n${BUILT_PRODUCTS_DIR}/SwiftLintTool\n"; }; - 3705272528992C8A000C06A2 /* Check Embedded Config URLs */ = { + 3121F62B2B64266A002F706A /* Copy Swift Package resources */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; buildActionMask = 2147483647; @@ -9986,16 +9077,16 @@ ); inputPaths = ( ); - name = "Check Embedded Config URLs"; + name = "Copy Swift Package resources"; outputFileListPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if [ \"$ENABLE_PREVIEWS\" = \"YES\" ]; then exit 0; fi\nif [ \"$CONFIGURATION\" == \"Release\" ]; then\n \"${SRCROOT}/scripts/update_embedded.sh\" -c\nfi\n"; + shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n# We had issues where the Swift Package resources were not being added to the Agent Apps,\n# so we're manually coping them here.\n# It seems to be a known issue: https://forums.swift.org/t/swift-packages-resource-bundle-not-present-in-xcarchive-when-framework-using-said-package-is-archived/50084/2\ncp -RL \"${BUILT_PRODUCTS_DIR}\"/ContentScopeScripts_ContentScopeScripts.bundle \"${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/\"\ncp -RL \"${BUILT_PRODUCTS_DIR}\"/DataBrokerProtection_DataBrokerProtection.bundle \"${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/\"\n"; }; - 3706FA79293F65D500E42796 /* Check Embedded Config URLs */ = { + 3705272528992C8A000C06A2 /* Check Embedded Config URLs */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; buildActionMask = 2147483647; @@ -10014,7 +9105,7 @@ shellPath = /bin/sh; shellScript = "if [ \"$ENABLE_PREVIEWS\" = \"YES\" ]; then exit 0; fi\nif [ \"$CONFIGURATION\" == \"Release\" ]; then\n \"${SRCROOT}/scripts/update_embedded.sh\" -c\nfi\n"; }; - 378E2798296F6D1D00FCADA2 /* Validate PRODUCT_NAME */ = { + 3706FA79293F65D500E42796 /* Check Embedded Config URLs */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; buildActionMask = 2147483647; @@ -10024,16 +9115,16 @@ ); inputPaths = ( ); - name = "Validate PRODUCT_NAME"; + name = "Check Embedded Config URLs"; outputFileListPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if [[ \"${CONFIGURATION}\" == \"Release\" && \"${PRODUCT_NAME}\" != \"DuckDuckGo\" ]]; then\n echo \"PRODUCT_NAME must be equal to \\\"DuckDuckGo\\\" (is \\\"${PRODUCT_NAME}\\\")\"\n echo \"See ManualAppStoreRelease.xcconfig for instructions.\"\n exit 1\nfi\n"; + shellScript = "if [ \"$ENABLE_PREVIEWS\" = \"YES\" ]; then exit 0; fi\nif [ \"$CONFIGURATION\" == \"Release\" ]; then\n \"${SRCROOT}/scripts/update_embedded.sh\" -c\nfi\n"; }; - 4B2D065C2A11D23600DE1F49 /* Copy Assets */ = { + 378E2798296F6D1D00FCADA2 /* Validate PRODUCT_NAME */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; buildActionMask = 2147483647; @@ -10043,16 +9134,16 @@ ); inputPaths = ( ); - name = "Copy Assets"; + name = "Validate PRODUCT_NAME"; outputFileListPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# We had issues where the Swift Package resources were not being added to the Agent Apps,\n# so we're manually coping them here.\n# It seems to be a known issue: https://forums.swift.org/t/swift-packages-resource-bundle-not-present-in-xcarchive-when-framework-using-said-package-is-archived/50084/2\ncp -RL \"${BUILT_PRODUCTS_DIR}\"/NetworkProtectionMac_NetworkProtectionUI.bundle \"${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/\"\n"; + shellScript = "if [[ \"${CONFIGURATION}\" == \"Release\" && \"${PRODUCT_NAME}\" != \"DuckDuckGo\" ]]; then\n echo \"PRODUCT_NAME must be equal to \\\"DuckDuckGo\\\" (is \\\"${PRODUCT_NAME}\\\")\"\n echo \"See ManualAppStoreRelease.xcconfig for instructions.\"\n exit 1\nfi\n"; }; - 4B2D067D2A13341200DE1F49 /* ShellScript */ = { + 4B2D065C2A11D23600DE1F49 /* Copy Assets */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; buildActionMask = 2147483647; @@ -10062,6 +9153,7 @@ ); inputPaths = ( ); + name = "Copy Assets"; outputFileListPaths = ( ); outputPaths = ( @@ -10070,45 +9162,7 @@ shellPath = /bin/sh; shellScript = "# We had issues where the Swift Package resources were not being added to the Agent Apps,\n# so we're manually coping them here.\n# It seems to be a known issue: https://forums.swift.org/t/swift-packages-resource-bundle-not-present-in-xcarchive-when-framework-using-said-package-is-archived/50084/2\ncp -RL \"${BUILT_PRODUCTS_DIR}\"/NetworkProtectionMac_NetworkProtectionUI.bundle \"${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/\"\n"; }; - 4B9579432AC7AE700062CA31 /* Assert Xcode version */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "Assert Xcode version"; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/scripts/assert_xcode_version.sh\"\n"; - }; - 4B9579442AC7AE700062CA31 /* Check Embedded Config URLs */ = { - isa = PBXShellScriptBuildPhase; - alwaysOutOfDate = 1; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "Check Embedded Config URLs"; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "if [ \"$CONFIGURATION\" == \"Release\" ]; then\n \"${SRCROOT}/scripts/update_embedded.sh\" -c\nfi\n"; - }; - 4B957C322AC7AE700062CA31 /* Make /Applications symlink, remove app on Clean build */ = { + 4B2D067D2A13341200DE1F49 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; buildActionMask = 2147483647; @@ -10118,14 +9172,13 @@ ); inputPaths = ( ); - name = "Make /Applications symlink, remove app on Clean build"; outputFileListPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if [[ \"${CONFIGURATION}\" != \"Debug\" ]]; then\n # run only for Debug builds\n exit 0\nfi\n\n# if Xcode created real Applications directory inside BUILT_PRODUCTS_DIR \nif [[ ! -L ${BUILT_PRODUCTS_DIR}/Applications ]]; then\n # we only get here on clean build, remove an existing app in /Applications/DEBUG on clean build\n echo \"rm -rf /${INSTALL_PATH}/${PRODUCT_NAME}.app\"\n rm -rf \"/${INSTALL_PATH}/${PRODUCT_NAME}.app\"\n\n # create /Applications/DEBUG dir\n echo \"mkdir -p /${INSTALL_PATH}\"\n mkdir -p \"/${INSTALL_PATH}\"\n\n # move the app bundle to /Applications/DEBUG\n echo \"mv ${DSTROOT}/${INSTALL_PATH}/${PRODUCT_NAME}.app /${INSTALL_PATH}/${PRODUCT_NAME}.app\"\n mv \"${DSTROOT}/${INSTALL_PATH}/${PRODUCT_NAME}.app\" \"/${INSTALL_PATH}/${PRODUCT_NAME}.app\"\n\n # rm ${BUILT_PRODUCTS_DIR}/Applications directory created by Xcode\n echo \"rm -rf ${BUILT_PRODUCTS_DIR}/Applications\" \n rm -rf \"${BUILT_PRODUCTS_DIR}/Applications\"\n # create ${BUILT_PRODUCTS_DIR}/Applications symlink to /Applications\n echo \"ln -s /Applications ${BUILT_PRODUCTS_DIR}/Applications\"\n ln -s /Applications \"${BUILT_PRODUCTS_DIR}/Applications\"\nfi\n"; + shellScript = "# We had issues where the Swift Package resources were not being added to the Agent Apps,\n# so we're manually coping them here.\n# It seems to be a known issue: https://forums.swift.org/t/swift-packages-resource-bundle-not-present-in-xcarchive-when-framework-using-said-package-is-archived/50084/2\ncp -RL \"${BUILT_PRODUCTS_DIR}\"/NetworkProtectionMac_NetworkProtectionUI.bundle \"${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/\"\n"; }; 4BBA2D272B6AC09D00F6A470 /* Embed Login Items */ = { isa = PBXShellScriptBuildPhase; @@ -10146,7 +9199,7 @@ shellPath = /bin/sh; shellScript = "# Embeds login items for the App Store build.\n\n# Skip login item embedding for release builds until they're ready to go live.\nif [ \"${CONFIGURATION}\" = \"Release\" ]; then\n VPN_AGENT_NAME=\"${AGENT_RELEASE_PRODUCT_NAME}\"\n PIR_AGENT_NAME=\"${DBP_BACKGROUND_AGENT_RELEASE_PRODUCT_NAME}\"\nelse\n VPN_AGENT_NAME=\"${AGENT_PRODUCT_NAME}\"\n PIR_AGENT_NAME=\"${DBP_BACKGROUND_AGENT_PRODUCT_NAME}\"\nfi\n\nVPN_AGENT_ORIGIN=$(readlink -f \"${CONFIGURATION_BUILD_DIR}/${VPN_AGENT_NAME}.app\")\nPIR_AGENT_ORIGIN=$(readlink -f \"${CONFIGURATION_BUILD_DIR}/${PIR_AGENT_NAME}.app\")\nAGENT_DESTINATION=\"${CONFIGURATION_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/Library/LoginItems\"\n \n# Make sure that Library/LoginItems exists before copying\nmkdir -p \"$AGENT_DESTINATION\"\n \necho \"Copying VPN agent from $VPN_AGENT_ORIGIN to $AGENT_DESTINATION\"\nrsync -r --links \"$VPN_AGENT_ORIGIN\" \"$AGENT_DESTINATION\"\n \necho \"Copying Personal Information Removal agent from $PIR_AGENT_ORIGIN to $AGENT_DESTINATION\"\nrsync -r --links \"$PIR_AGENT_ORIGIN\" \"$AGENT_DESTINATION\"\n"; }; - 7B31FD922AD126C40086AA24 /* Embed System Network Extension */ = { + 6A8856B31B2BC5078B61ED81 /* Run swiftlint */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; buildActionMask = 2147483647; @@ -10156,16 +9209,16 @@ ); inputPaths = ( ); - name = "Embed System Network Extension"; + name = "Run swiftlint"; outputFileListPaths = ( ); outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if [[ -z \"${SYSEX_BUNDLE_ID}\" ]]; then\n echo \"Required build settings are not defined, please check xcconfig files\"\n exit 1\nfi\n\n\necho \"ditto ${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID}.systemextension $BUILT_PRODUCTS_DIR/${CONTENTS_FOLDER_PATH}/Library/SystemExtensions/${SYSEX_BUNDLE_ID}.systemextension\"\n\nditto \"${BUILT_PRODUCTS_DIR}/${SYSEX_BUNDLE_ID}.systemextension\" \"$BUILT_PRODUCTS_DIR/${CONTENTS_FOLDER_PATH}/Library/SystemExtensions/${SYSEX_BUNDLE_ID}.systemextension\" || exit 1\n"; + shellScript = "if [ \"$CONFIGURATION\" != \"Debug\" ] || [ \"$ENABLE_PREVIEWS\" = \"YES\" ]; then exit 0; fi\n${BUILT_PRODUCTS_DIR}/SwiftLintTool\n"; }; - 7B31FD942AD126FA0086AA24 /* Embed System Network Extension */ = { + 7B31FD922AD126C40086AA24 /* Embed System Network Extension */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; buildActionMask = 2147483647; @@ -10332,6 +9385,7 @@ 4B520F642BA5573A006405C7 /* WaitlistThankYouView.swift in Sources */, 3706FA80293F65D500E42796 /* TabLazyLoaderDataSource.swift in Sources */, 3706FA81293F65D500E42796 /* LoginImport.swift in Sources */, + 560C40002BCD5A1E00F589CE /* PermanentSurveyManager.swift in Sources */, C13909FC2B861039001626ED /* AutofillActionPresenter.swift in Sources */, 4BF97AD72B43C53D00EB4240 /* NetworkProtectionIPCTunnelController.swift in Sources */, EEC4A66E2B2C894F00F7C0AA /* VPNLocationPreferenceItemModel.swift in Sources */, @@ -10391,7 +9445,6 @@ 3706FAB6293F65D500E42796 /* YoutubePlayerUserScript.swift in Sources */, 1D8057C92A83CB3C00F4FED6 /* SupportedOsChecker.swift in Sources */, 373D9B4929EEAC1B00381FDD /* SyncMetadataDatabase.swift in Sources */, - 3706FAB7293F65D500E42796 /* PixelParameters.swift in Sources */, 3706FAB8293F65D500E42796 /* FaviconImageCache.swift in Sources */, 3706FAB9293F65D500E42796 /* TabBarViewController.swift in Sources */, 4B9DB0332A983B24000927DB /* EnableWaitlistFeatureView.swift in Sources */, @@ -10469,6 +9522,7 @@ 3706FAF3293F65D500E42796 /* LocalAuthenticationService.swift in Sources */, 1D36E659298AA3BA00AA485D /* InternalUserDeciderStore.swift in Sources */, B6BCC5242AFCDABB002C5499 /* DataImportSourceViewModel.swift in Sources */, + B6F1B02B2BCE675C005E863C /* NetworkProtectionControllerTabExtension.swift in Sources */, 3706FEBC293F6EFF00E42796 /* BWResponse.swift in Sources */, B65C7DFC2B886CF0001E2D5C /* WKPDFHUDViewWrapper.swift in Sources */, 3706FAF4293F65D500E42796 /* SafariBookmarksReader.swift in Sources */, @@ -10479,6 +9533,7 @@ F1B33DF72BAD970E001128B3 /* SubscriptionErrorReporter.swift in Sources */, 3706FEC0293F6EFF00E42796 /* BWRequest.swift in Sources */, 3706FAF7293F65D500E42796 /* FireproofDomainsViewController.swift in Sources */, + F18826852BBEE31700D9AC4F /* PixelKit+Assertion.swift in Sources */, 4BF0E5062AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */, 3706FAF8293F65D500E42796 /* URLEventHandler.swift in Sources */, 9FBD84742BB3E15D00220859 /* InstallationAttributionPixelHandler.swift in Sources */, @@ -10530,6 +9585,7 @@ 3706FB1B293F65D500E42796 /* SafariDataImporter.swift in Sources */, 3706FB1D293F65D500E42796 /* StatisticsLoader.swift in Sources */, 3793FDD829535EBA00A2E28F /* Assertions.swift in Sources */, + F188267D2BBEB3AA00D9AC4F /* GeneralPixel.swift in Sources */, B62B48572ADE730D000DECE5 /* FileImportView.swift in Sources */, B6676BE22AA986A700525A21 /* AddressBarTextEditor.swift in Sources */, 3706FB1F293F65D500E42796 /* DataClearingPreferences.swift in Sources */, @@ -10582,6 +9638,7 @@ 3706FB46293F65D500E42796 /* FirePopoverWrapperViewController.swift in Sources */, 3706FB47293F65D500E42796 /* NSPasteboardItemExtension.swift in Sources */, 3706FB48293F65D500E42796 /* AutofillPreferencesModel.swift in Sources */, + B6F1B0272BCE5A50005E863C /* TabContent.swift in Sources */, 3168506E2AF3AD1D009A2828 /* WaitlistViewControllerPresenter.swift in Sources */, 3706FB49293F65D500E42796 /* NSException+Catch.swift in Sources */, B6B71C592B23379600487131 /* NSLayoutConstraintExtension.swift in Sources */, @@ -10615,7 +9672,6 @@ 3706FB60293F65D500E42796 /* PasswordManagementIdentityItemView.swift in Sources */, 3706FB61293F65D500E42796 /* ProgressExtension.swift in Sources */, 3706FB62293F65D500E42796 /* CSVParser.swift in Sources */, - 3706FB64293F65D500E42796 /* PixelDataModel.xcdatamodeld in Sources */, B626A75B29921FAA00053070 /* NavigationActionPolicyExtension.swift in Sources */, 4B9DB02A2A983B24000927DB /* WaitlistStorage.swift in Sources */, 3706FB65293F65D500E42796 /* PrivacyDashboardWebView.swift in Sources */, @@ -10674,8 +9730,11 @@ 37197EA42942441D00394917 /* NewWindowPolicy.swift in Sources */, 3706FB84293F65D500E42796 /* NSWindowExtension.swift in Sources */, 3706FB85293F65D500E42796 /* AddBookmarkPopover.swift in Sources */, + F18826922BC0105900D9AC4F /* PixelDataRecord.swift in Sources */, + F18826932BC0105900D9AC4F /* PixelDataStore.swift in Sources */, 7BBD45B22A691AB500C83CA9 /* NetworkProtectionDebugUtilities.swift in Sources */, 3706FB87293F65D500E42796 /* ProcessExtension.swift in Sources */, + F18826812BBEB58100D9AC4F /* PrivacyProPixel.swift in Sources */, 3706FB88293F65D500E42796 /* PermissionAuthorizationQuery.swift in Sources */, 3706FB89293F65D500E42796 /* BadgeAnimationView.swift in Sources */, 4B4D60C32A0C849100BCD287 /* EventMapping+NetworkProtectionError.swift in Sources */, @@ -10686,6 +9745,7 @@ B66260E129AC6EBD00E9E3EE /* HistoryTabExtension.swift in Sources */, 3706FB8E293F65D500E42796 /* FirefoxEncryptionKeyReader.swift in Sources */, 3706FB8F293F65D500E42796 /* BookmarkManagementSplitViewController.swift in Sources */, + 316913272BD2B76F0051B46D /* DataBrokerPrerequisitesStatusVerifier.swift in Sources */, 3706FB90293F65D500E42796 /* CookieManagedNotificationContainerView.swift in Sources */, 3706FB91293F65D500E42796 /* FileManagerExtension.swift in Sources */, 3706FB92293F65D500E42796 /* PermissionModel.swift in Sources */, @@ -10714,12 +9774,14 @@ 98779A0129999B64005D8EB6 /* Bookmark.xcdatamodeld in Sources */, 3706FB9E293F65D500E42796 /* AboutModel.swift in Sources */, 3706FB9F293F65D500E42796 /* PasswordManagementCreditCardItemView.swift in Sources */, + 9F9C4A022BC7F36D0099738D /* BookmarkAllTabsDialogCoordinatorViewModel.swift in Sources */, 3706FBA0293F65D500E42796 /* NSTextFieldExtension.swift in Sources */, 9FA173E82B7B122E00EE4E6E /* BookmarkDialogStackedContentView.swift in Sources */, 3706FBA1293F65D500E42796 /* FireproofDomainsContainer.swift in Sources */, 3706FBA2293F65D500E42796 /* GeolocationService.swift in Sources */, 4B4D60C42A0C849600BCD287 /* NetworkProtectionInvitePresenter.swift in Sources */, 3706FBA3293F65D500E42796 /* FireproofingURLExtensions.swift in Sources */, + 3169132A2BD2C7570051B46D /* DataBrokerProtectionErrorViewController.swift in Sources */, 1DDD3EC12B84F5D5004CBF2B /* PreferencesCookiePopupProtectionView.swift in Sources */, 3706FBA4293F65D500E42796 /* ContentOverlayPopover.swift in Sources */, 3706FBA5293F65D500E42796 /* TabShadowView.swift in Sources */, @@ -10755,6 +9817,7 @@ 3706FBBE293F65D500E42796 /* DownloadListViewModel.swift in Sources */, 3706FBBF293F65D500E42796 /* BookmarkManagementDetailViewController.swift in Sources */, B6B4D1CB2B0C8C9200C26286 /* FirefoxCompatibilityPreferences.swift in Sources */, + F188268E2BBF01C400D9AC4F /* PixelDataModel.xcdatamodeld in Sources */, 3706FBC0293F65D500E42796 /* CSVImporter.swift in Sources */, 3706FBC1293F65D500E42796 /* StartupPreferences.swift in Sources */, 3706FBC2293F65D500E42796 /* MainMenu.swift in Sources */, @@ -10767,13 +9830,14 @@ 3706FBC7293F65D500E42796 /* EncryptedHistoryStore.swift in Sources */, 3706FBC8293F65D500E42796 /* FirePopoverCollectionViewItem.swift in Sources */, 3706FBC9293F65D500E42796 /* ArrayExtension.swift in Sources */, - 3706FBCA293F65D500E42796 /* CrashReportSender.swift in Sources */, 3706FBCB293F65D500E42796 /* BookmarkHTMLImporter.swift in Sources */, 4BF97ADC2B43C5E200EB4240 /* VPNFeedbackSender.swift in Sources */, 987799F72999996B005D8EB6 /* BookmarkDatabase.swift in Sources */, + BDA7647D2BC497BE00D0400C /* DefaultVPNLocationFormatter.swift in Sources */, 3706FBCC293F65D500E42796 /* CustomRoundedCornersShape.swift in Sources */, 3706FBCD293F65D500E42796 /* LocaleExtension.swift in Sources */, 3706FBCE293F65D500E42796 /* SavePaymentMethodViewController.swift in Sources */, + 9FA5A0A62BC8F34900153786 /* UserDefaultsBookmarkFoldersStore.swift in Sources */, 1DDC85002B835BC000670238 /* SearchPreferences.swift in Sources */, 3706FBD0293F65D500E42796 /* WebKitVersionProvider.swift in Sources */, 3706FBD1293F65D500E42796 /* NSCoderExtensions.swift in Sources */, @@ -10834,10 +9898,7 @@ 9F56CFAE2B84326C00BB7F11 /* AddEditBookmarkDialogViewModel.swift in Sources */, 3706FBF3293F65D500E42796 /* PseudoFolder.swift in Sources */, 1D26EBAD2B74BECB0002A93F /* NSImageSendable.swift in Sources */, - 3706FBF5293F65D500E42796 /* PixelDataStore.swift in Sources */, 1D220BFD2B87AACF00F8BBC6 /* PrivacyProtectionStatus.swift in Sources */, - 3706FBF6293F65D500E42796 /* Pixel.swift in Sources */, - 3706FBF7293F65D500E42796 /* PixelEvent.swift in Sources */, 3706FBF8293F65D500E42796 /* TabBarFooter.swift in Sources */, B626A7612992407D00053070 /* CancellableExtension.swift in Sources */, 3706FBF9293F65D500E42796 /* BookmarksBarCollectionViewItem.swift in Sources */, @@ -10863,7 +9924,6 @@ 1DCFBC8B29ADF32B00313531 /* BurnerHomePageView.swift in Sources */, 3706FC06293F65D500E42796 /* OnboardingViewModel.swift in Sources */, 3706FC07293F65D500E42796 /* ScriptSourceProviding.swift in Sources */, - 4B6785402AA7C726008A5004 /* DailyPixel.swift in Sources */, 31EF1E832B63FFCA00E6DB17 /* LoginItem+DataBrokerProtection.swift in Sources */, B6619EFC2B111CC600CD9186 /* InstructionsFormatParser.swift in Sources */, 3706FC08293F65D500E42796 /* CoreDataBookmarkImporter.swift in Sources */, @@ -10929,6 +9989,7 @@ B6685E4029A606190043D2EE /* WorkspaceProtocol.swift in Sources */, 3706FC2F293F65D500E42796 /* MouseOverButton.swift in Sources */, 3706FC30293F65D500E42796 /* FireInfoViewController.swift in Sources */, + B6F1B02F2BCE6B47005E863C /* TunnelControllerProvider.swift in Sources */, 56BA1E832BAC506F001CF69F /* SSLErrorPageUserScript.swift in Sources */, 3706FC31293F65D500E42796 /* PermissionButton.swift in Sources */, 3706FC32293F65D500E42796 /* MoreOptionsMenu.swift in Sources */, @@ -10951,7 +10012,6 @@ 3706FC40293F65D500E42796 /* SaveIdentityViewController.swift in Sources */, 3706FC41293F65D500E42796 /* FileStore.swift in Sources */, 1DB67F2E2B6FEFDB003DF243 /* ViewSnapshotRenderer.swift in Sources */, - 3706FC42293F65D500E42796 /* PixelArguments.swift in Sources */, 3706FC43293F65D500E42796 /* PinnedTabsViewModel.swift in Sources */, 85D0327C2B8E3D090041D1FB /* HistoryCoordinatorExtension.swift in Sources */, B6685E4329A61C470043D2EE /* DownloadsTabExtension.swift in Sources */, @@ -10973,6 +10033,7 @@ 3706FC51293F65D500E42796 /* RecentlyVisitedView.swift in Sources */, B6E3E5552BBFCEE300A41922 /* NoDownloadsCellView.swift in Sources */, B645D8F729FA95440024461F /* WKProcessPoolExtension.swift in Sources */, + 9F9C49FE2BC7E9830099738D /* BookmarkAllTabsDialogViewModel.swift in Sources */, 9F514F922B7D88AD001832A9 /* AddEditBookmarkFolderDialogView.swift in Sources */, 3706FC52293F65D500E42796 /* MouseOverAnimationButton.swift in Sources */, B60293E72BA19ECD0033186B /* NetPPopoverManagerMock.swift in Sources */, @@ -11022,13 +10083,13 @@ 3706FC71293F65D500E42796 /* NSColorExtension.swift in Sources */, 1DB9618229F67F6100CF5568 /* FaviconNullStore.swift in Sources */, 3706FC73293F65D500E42796 /* AddressBarButtonsViewController.swift in Sources */, - 3706FC76293F65D500E42796 /* PixelDataRecord.swift in Sources */, 7BFE955A2A9DF4550081ABE9 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift in Sources */, 9FDA6C222B79A59D00E099A9 /* BookmarkFavoriteView.swift in Sources */, C1372EF52BBC5BAD003F8793 /* SecureTextField.swift in Sources */, + 316913242BD2B6250051B46D /* DataBrokerProtectionPixelsHandler.swift in Sources */, 3706FC77293F65D500E42796 /* PageObserverUserScript.swift in Sources */, 4BF0E5132AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */, - 3706FC78293F65D500E42796 /* SecureVaultErrorReporter.swift in Sources */, + 3706FC78293F65D500E42796 /* SecureVaultReporter.swift in Sources */, 3706FC79293F65D500E42796 /* NSImageExtensions.swift in Sources */, 3706FEBD293F6EFF00E42796 /* BWCommand.swift in Sources */, 3706FC7B293F65D500E42796 /* PasswordManagementViewController.swift in Sources */, @@ -11048,6 +10109,7 @@ 3707C721294B5D2900682A9F /* WKMenuItemIdentifier.swift in Sources */, 3706FEBE293F6EFF00E42796 /* BWMessageIdGenerator.swift in Sources */, C1E961F02B87AA29001760E1 /* AutofillActionBuilder.swift in Sources */, + B6F1B0232BCE5658005E863C /* BrokenSiteInfoTabExtension.swift in Sources */, 3706FC85293F65D500E42796 /* ShadowView.swift in Sources */, 3706FC86293F65D500E42796 /* FeedbackSender.swift in Sources */, 3706FC88293F65D500E42796 /* TabBarViewItem.swift in Sources */, @@ -11082,6 +10144,7 @@ 3706FCA0293F65D500E42796 /* ContiguousBytesExtension.swift in Sources */, B602E8172A1E2570006D261F /* URL+NetworkProtection.swift in Sources */, 3706FCA1293F65D500E42796 /* AdjacentItemEnumerator.swift in Sources */, + 9F9C49FA2BC7BC970099738D /* BookmarkAllTabsDialogView.swift in Sources */, 3706FCA2293F65D500E42796 /* ChromiumKeychainPrompt.swift in Sources */, 3707C71E294B5D2900682A9F /* URLRequestExtension.swift in Sources */, 3706FCA3293F65D500E42796 /* WKProcessPool+GeolocationProvider.swift in Sources */, @@ -11096,6 +10159,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9F0FFFB92BCCAE9C007C87DD /* AddEditBookmarkDialogViewModelMock.swift in Sources */, 3706FDDA293F661700E42796 /* EmbeddedTrackerDataTests.swift in Sources */, 3706FDDB293F661700E42796 /* AutofillPreferencesTests.swift in Sources */, 3706FDDC293F661700E42796 /* FileManagerExtensionTests.swift in Sources */, @@ -11105,7 +10169,6 @@ 3706FDE0293F661700E42796 /* TabIndexTests.swift in Sources */, 9F26060F2B85E17D00819292 /* AddEditBookmarkDialogCoordinatorViewModelTests.swift in Sources */, 3706FDE1293F661700E42796 /* AdjacentItemEnumeratorTests.swift in Sources */, - 3706FDE2293F661700E42796 /* PixelArgumentsTests.swift in Sources */, 4B9DB0572A983B55000927DB /* MockNotificationService.swift in Sources */, 3706FDE4293F661700E42796 /* TabLazyLoaderTests.swift in Sources */, 3706FDE5293F661700E42796 /* URLEventHandlerTests.swift in Sources */, @@ -11129,6 +10192,7 @@ 3706FDF5293F661700E42796 /* StartupPreferencesTests.swift in Sources */, 3706FDF6293F661700E42796 /* DuckPlayerTests.swift in Sources */, 3706FDF7293F661700E42796 /* WebViewExtensionTests.swift in Sources */, + 9FA5A0AA2BC900FC00153786 /* BookmarkAllTabsDialogViewModelTests.swift in Sources */, 56534DEE29DF252C00121467 /* CapturingDefaultBrowserProvider.swift in Sources */, 3706FDF8293F661700E42796 /* FileStoreTests.swift in Sources */, 5603D90729B7B746007F9F01 /* MockTabViewItemDelegate.swift in Sources */, @@ -11181,13 +10245,14 @@ 3706FE1B293F661700E42796 /* PermissionManagerTests.swift in Sources */, 3706FE1C293F661700E42796 /* ConnectBitwardenViewModelTests.swift in Sources */, 4B9DB0552A983B55000927DB /* MockWaitlistStorage.swift in Sources */, - 3706FE1D293F661700E42796 /* PixelStoreTests.swift in Sources */, 1D9FDEC72B9B64DB0040B78C /* PrivacyProtectionStatusTests.swift in Sources */, C13909F52B85FD79001626ED /* AutofillDeleteAllPasswordsExecutorTests.swift in Sources */, 857E44642A9F70F200ED77A7 /* CampaignVariantTests.swift in Sources */, 3706FE1E293F661700E42796 /* GeolocationProviderTests.swift in Sources */, 9F39106A2B68D87B00CB5112 /* ProgressExtensionTests.swift in Sources */, + 9FAD623B2BCFDB32007F3A65 /* WebsiteInfoHelpers.swift in Sources */, 3706FE1F293F661700E42796 /* AppStateChangePublisherTests.swift in Sources */, + 9FA5A0B12BC9039300153786 /* BookmarkFolderStoreMock.swift in Sources */, 3706FE20293F661700E42796 /* CLLocationManagerMock.swift in Sources */, B6656E0E2B29C733008798A1 /* FileImportViewLocalizationTests.swift in Sources */, B6C843DB2BA1CAB6006FDEC3 /* FilePresenterTests.swift in Sources */, @@ -11218,10 +10283,12 @@ B630E80129C887ED00363609 /* NSErrorAdditionalInfo.swift in Sources */, 3706FE31293F661700E42796 /* TabCollectionViewModelDelegateMock.swift in Sources */, 3706FE32293F661700E42796 /* BookmarksHTMLReaderTests.swift in Sources */, + 9F0FFFBC2BCCAEC2007C87DD /* AddEditBookmarkFolderDialogViewModelMock.swift in Sources */, 3706FE33293F661700E42796 /* FireTests.swift in Sources */, B60C6F8229B1B4AD007BFAA8 /* TestRunHelper.swift in Sources */, 567DA94029E8045D008AC5EE /* MockEmailStorage.swift in Sources */, 317295D32AF058D3002C3206 /* MockWaitlistTermsAndConditionsActionHandler.swift in Sources */, + 9F0FFFB52BCCAE37007C87DD /* BookmarkAllTabsDialogCoordinatorViewModelTests.swift in Sources */, 3706FE34293F661700E42796 /* PermissionStoreTests.swift in Sources */, 3706FE35293F661700E42796 /* ThirdPartyBrowserTests.swift in Sources */, 1DFAB5232A8983E100A0F7F6 /* SetExtensionTests.swift in Sources */, @@ -11229,6 +10296,7 @@ 3706FE37293F661700E42796 /* TabCollectionViewModelTests+WithoutPinnedTabsManager.swift in Sources */, 3706FE38293F661700E42796 /* SuggestionContainerTests.swift in Sources */, 3706FE39293F661700E42796 /* TabTests.swift in Sources */, + 9FAD623E2BD09DE5007F3A65 /* WebsiteInfoTests.swift in Sources */, 3706FE3A293F661700E42796 /* MockVariantManager.swift in Sources */, 3706FE3C293F661700E42796 /* FireproofDomainsStoreMock.swift in Sources */, 3706FE3D293F661700E42796 /* DataEncryptionTests.swift in Sources */, @@ -11251,13 +10319,14 @@ 3706FE46293F661700E42796 /* EncryptedValueTransformerTests.swift in Sources */, 9F3910632B68C35600CB5112 /* DownloadsTabExtensionTests.swift in Sources */, 3706FE47293F661700E42796 /* URLExtensionTests.swift in Sources */, + 9F8D57332BCCCB9A00AEA660 /* UserDefaultsBookmarkFoldersStoreTests.swift in Sources */, 1DB9617B29F1D06D00CF5568 /* InternalUserDeciderMock.swift in Sources */, 317295D52AF058D3002C3206 /* MockWaitlistFeatureSetupHandler.swift in Sources */, - 3706FE48293F661700E42796 /* PixelTests.swift in Sources */, 3706FE49293F661700E42796 /* BookmarkNodePathTests.swift in Sources */, 1DE03425298BC7F000CAB3D7 /* InternalUserDeciderStoreMock.swift in Sources */, 3706FE4A293F661700E42796 /* BookmarkManagedObjectTests.swift in Sources */, EEC8EB402982CD550065AA39 /* JSAlertViewModelTests.swift in Sources */, + BDA764922BC4E57200D0400C /* MockVPNLocationFormatter.swift in Sources */, 3706FE4B293F661700E42796 /* BookmarksHTMLImporterTests.swift in Sources */, 9FA75A3F2BA00E1400DA5FA6 /* BookmarksBarMenuFactoryTests.swift in Sources */, 56D145E929E6BB6300E3488A /* CapturingDataImportProvider.swift in Sources */, @@ -11276,22 +10345,24 @@ 566B196429CDB824007E38F4 /* MoreOptionsMenuTests.swift in Sources */, 9F0A2CF92B96A58600C5B8C0 /* BaseBookmarkEntityTests.swift in Sources */, 3706FE56293F661700E42796 /* FaviconManagerMock.swift in Sources */, + 9F9C49F72BC786790099738D /* MoreOptionsMenu+BookmarksTests.swift in Sources */, 3706FE57293F661700E42796 /* LocalPinningManagerTests.swift in Sources */, 3706FE58293F661700E42796 /* HistoryStoreTests.swift in Sources */, 3706FE59293F661700E42796 /* EncryptionKeyGeneratorTests.swift in Sources */, 3706FE5A293F661700E42796 /* GeolocationServiceMock.swift in Sources */, 3706FE5B293F661700E42796 /* FirefoxLoginReaderTests.swift in Sources */, 1D1C36E429FAE8DA001FA40C /* FaviconManagerTests.swift in Sources */, - 376E2D29294286B8001CD31B /* PixelEventTests.swift in Sources */, 37716D8029707E5D00A9FC6D /* FireproofingReferenceTests.swift in Sources */, B6AA64742994B43300D99CD6 /* FutureExtensionTests.swift in Sources */, 3706FE5C293F661700E42796 /* DuckPlayerPreferencesTests.swift in Sources */, 1D9FDEB82B9B5D150040B78C /* SearchPreferencesTests.swift in Sources */, + 560C3FFD2BC9911000F589CE /* PermanentSurveyManagerTests.swift in Sources */, 3706FE5D293F661700E42796 /* FileSystemDSL.swift in Sources */, 3706FE5E293F661700E42796 /* DataImportMocks.swift in Sources */, 3706FE5F293F661700E42796 /* CrashReportTests.swift in Sources */, B60C6F7F29B1B41D007BFAA8 /* TestRunHelperInitializer.m in Sources */, 4B9DB0592A983B55000927DB /* MockNetworkProtectionCodeRedeemer.swift in Sources */, + 9F0FFFBF2BCCAF1F007C87DD /* BookmarkAllTabsDialogViewModelMock.swift in Sources */, 3706FE61293F661700E42796 /* PinnedTabsViewModelTests.swift in Sources */, 3706FE62293F661700E42796 /* PasswordManagementListSectionTests.swift in Sources */, 3706FE63293F661700E42796 /* RecentlyClosedCoordinatorMock.swift in Sources */, @@ -11310,6 +10381,7 @@ 1D9FDEBE2B9B5F0F0040B78C /* CookiePopupProtectionPreferencesTests.swift in Sources */, 028904212A7B25770028369C /* AppConfigurationURLProviderTests.swift in Sources */, 3706FE6F293F661700E42796 /* LocalStatisticsStoreTests.swift in Sources */, + 31DC2F232BD6E028001354EF /* DataBrokerPrerequisitesStatusVerifierTests.swift in Sources */, 3706FE70293F661700E42796 /* HistoryCoordinatorTests.swift in Sources */, 9F3344632BBFBDA40040CBEB /* BookmarksBarVisibilityManagerTests.swift in Sources */, 3706FE71293F661700E42796 /* SavedStateMock.swift in Sources */, @@ -11354,6 +10426,7 @@ B603975229C1FFAD00902A34 /* ExpectedNavigationExtension.swift in Sources */, 3706FE85293F661700E42796 /* BWRequestTests.swift in Sources */, 3706FE86293F661700E42796 /* FileDownloadManagerTests.swift in Sources */, + BDA7648E2BC4E4EF00D0400C /* DefaultVPNLocationFormatterTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -11481,8 +10554,10 @@ 7BA7CC3E2AD11E380042E5CE /* TunnelControllerIPCService.swift in Sources */, 7BA7CC402AD11E3D0042E5CE /* AppLauncher+DefaultInitializer.swift in Sources */, 7B0694982B6E980F00FA4DBA /* VPNProxyLauncher.swift in Sources */, + BDA764842BC49E3F00D0400C /* NetworkProtectionVPNCountryLabelsModel.swift in Sources */, EEC589DB2A4F1CE700BCD60C /* AppLauncher.swift in Sources */, B65DA5EF2A77CC3A00CBEE8D /* Bundle+NetworkProtectionExtensions.swift in Sources */, + BDA7647F2BC4998900D0400C /* DefaultVPNLocationFormatter.swift in Sources */, 4BF0E5072AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */, 7BA7CC442AD11E490042E5CE /* UserText.swift in Sources */, 4BF0E5142AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */, @@ -11515,8 +10590,10 @@ 7BFE95592A9DF2AF0081ABE9 /* UserDefaults+NetworkProtectionWaitlist.swift in Sources */, 7BA7CC5C2AD120C30042E5CE /* EventMapping+NetworkProtectionError.swift in Sources */, B65DA5F02A77CC3C00CBEE8D /* Bundle+NetworkProtectionExtensions.swift in Sources */, + BDA764852BC49E4000D0400C /* NetworkProtectionVPNCountryLabelsModel.swift in Sources */, 7BAF9E4D2A8A3CCB002D3B6E /* UserDefaults+NetworkProtectionShared.swift in Sources */, 7BA7CC392AD11E2D0042E5CE /* DuckDuckGoVPNAppDelegate.swift in Sources */, + BDA764802BC4998A00D0400C /* DefaultVPNLocationFormatter.swift in Sources */, 7BA7CC552AD11FFB0042E5CE /* NetworkProtectionOptionKeyExtension.swift in Sources */, 7BA7CC3D2AD11E380042E5CE /* TunnelControllerIPCService.swift in Sources */, 4BA7C4DA2B3F639800AFE511 /* NetworkProtectionTunnelController.swift in Sources */, @@ -11563,784 +10640,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 4B9579452AC7AE700062CA31 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 4B9579462AC7AE700062CA31 /* FaviconUserScript.swift in Sources */, - 4B9579472AC7AE700062CA31 /* BWResponse.swift in Sources */, - 4B37EE7A2B4CFF7200A89A61 /* DataBrokerProtectionRemoteMessaging.swift in Sources */, - 1E2AE4C72ACB215900684E0A /* NetworkProtectionRemoteMessaging.swift in Sources */, - 4B9579482AC7AE700062CA31 /* LottieAnimationCache.swift in Sources */, - 4B9579492AC7AE700062CA31 /* WaitlistDialogView.swift in Sources */, - 4B95794A2AC7AE700062CA31 /* TabIndex.swift in Sources */, - 4B95794B2AC7AE700062CA31 /* SavePanelAccessoryView.swift in Sources */, - 4B95794C2AC7AE700062CA31 /* TabLazyLoaderDataSource.swift in Sources */, - 4B95794D2AC7AE700062CA31 /* LoginImport.swift in Sources */, - 4B95794E2AC7AE700062CA31 /* JoinWaitlistView.swift in Sources */, - 4B95794F2AC7AE700062CA31 /* LazyLoadable.swift in Sources */, - 4B9579502AC7AE700062CA31 /* ClickToLoadModel.swift in Sources */, - B6F9BDDE2B45B7EE00677B33 /* WebsiteInfo.swift in Sources */, - 4B9579512AC7AE700062CA31 /* KeyedCodingExtension.swift in Sources */, - 31AA6B992B960BA60025014E /* DataBrokerProtectionLoginItemPixels.swift in Sources */, - 4B9579522AC7AE700062CA31 /* PrivacyDashboardTabExtension.swift in Sources */, - 4B9579542AC7AE700062CA31 /* DownloadListStore.swift in Sources */, - 4B9579552AC7AE700062CA31 /* Logging.swift in Sources */, - 4B9579562AC7AE700062CA31 /* CrashReportPromptPresenter.swift in Sources */, - 1DDC84F92B83558F00670238 /* PreferencesPrivateSearchView.swift in Sources */, - B6B4D1CD2B0C8C9200C26286 /* FirefoxCompatibilityPreferences.swift in Sources */, - 9FA173ED2B7B232200EE4E6E /* AddEditBookmarkDialogView.swift in Sources */, - 4B9579572AC7AE700062CA31 /* BWCredential.swift in Sources */, - 4B9579582AC7AE700062CA31 /* PreferencesRootView.swift in Sources */, - 4B9579592AC7AE700062CA31 /* AppStateChangedPublisher.swift in Sources */, - 4B95795A2AC7AE700062CA31 /* BookmarkTableCellView.swift in Sources */, - 4B95795B2AC7AE700062CA31 /* BookmarkManagementSidebarViewController.swift in Sources */, - 4B95795C2AC7AE700062CA31 /* NSStackViewExtension.swift in Sources */, - 4B95795D2AC7AE700062CA31 /* OptionalExtension.swift in Sources */, - 4B95795E2AC7AE700062CA31 /* PasswordManagementLoginItemView.swift in Sources */, - 4B95795F2AC7AE700062CA31 /* UserText.swift in Sources */, - 9F872D9A2B8DA9F800138637 /* Bookmarks+Tab.swift in Sources */, - 4B9579602AC7AE700062CA31 /* WKWebView+Download.swift in Sources */, - 4B9579612AC7AE700062CA31 /* TabShadowConfig.swift in Sources */, - 4B9579622AC7AE700062CA31 /* URLSessionExtension.swift in Sources */, - C13909FD2B861039001626ED /* AutofillActionPresenter.swift in Sources */, - 4B9579632AC7AE700062CA31 /* WKWebsiteDataStoreExtension.swift in Sources */, - 4B9579642AC7AE700062CA31 /* WindowDraggingView.swift in Sources */, - 4B9579652AC7AE700062CA31 /* SecureVaultSorting.swift in Sources */, - 4B9579662AC7AE700062CA31 /* PreferencesSidebarModel.swift in Sources */, - 4B9579672AC7AE700062CA31 /* DuckPlayerURLExtension.swift in Sources */, - C1E961F22B87AA29001760E1 /* AutofillActionBuilder.swift in Sources */, - 4B41EDB72B169887001EEDF4 /* VPNFeedbackFormView.swift in Sources */, - 4B9579682AC7AE700062CA31 /* BWEncryptionOutput.m in Sources */, - 4B9579692AC7AE700062CA31 /* PermissionState.swift in Sources */, - 4B95796A2AC7AE700062CA31 /* FeedbackPresenter.swift in Sources */, - 4B95796B2AC7AE700062CA31 /* NavigationProtectionTabExtension.swift in Sources */, - 4B95796C2AC7AE700062CA31 /* BurnerMode.swift in Sources */, - 4B95796D2AC7AE700062CA31 /* UserAgent.swift in Sources */, - 4B95796E2AC7AE700062CA31 /* LegacyBookmarkStore.swift in Sources */, - 4B95796F2AC7AE700062CA31 /* NSAlert+DataImport.swift in Sources */, - 4B9579702AC7AE700062CA31 /* MainWindow.swift in Sources */, - 9F872DA52B90920F00138637 /* BookmarkFolderInfo.swift in Sources */, - 9FEE986B2B85B869002E44E8 /* BookmarksDialogViewModel.swift in Sources */, - 4B9579712AC7AE700062CA31 /* CrashReportPromptViewController.swift in Sources */, - 4B9579722AC7AE700062CA31 /* BookmarksCleanupErrorHandling.swift in Sources */, - 4B9579732AC7AE700062CA31 /* ContextMenuManager.swift in Sources */, - 4B9579742AC7AE700062CA31 /* GradientView.swift in Sources */, - 4B9579752AC7AE700062CA31 /* PreferencesSidebar.swift in Sources */, - 1D9A4E5C2B43213B00F449E2 /* TabSnapshotExtension.swift in Sources */, - 4B9579762AC7AE700062CA31 /* HoveredLinkTabExtension.swift in Sources */, - 4B9579772AC7AE700062CA31 /* NSPointExtension.swift in Sources */, - 4B9579782AC7AE700062CA31 /* WindowsManager.swift in Sources */, - 4B9579792AC7AE700062CA31 /* BWRequest.swift in Sources */, - 4B95797A2AC7AE700062CA31 /* WKWebViewConfigurationExtensions.swift in Sources */, - 4B95797B2AC7AE700062CA31 /* HomePageDefaultBrowserModel.swift in Sources */, - 9F514F932B7D88AD001832A9 /* AddEditBookmarkFolderDialogView.swift in Sources */, - 4B95797C2AC7AE700062CA31 /* CrashReporter.swift in Sources */, - 4B95797D2AC7AE700062CA31 /* AddressBarTextSelectionNavigation.swift in Sources */, - 1D01A3DA2B88DF8B00FE8150 /* PreferencesSyncView.swift in Sources */, - 4B37EE7D2B4CFF8300A89A61 /* SurveyURLBuilder.swift in Sources */, - 4B95797E2AC7AE700062CA31 /* BadgeNotificationAnimationModel.swift in Sources */, - 4B95797F2AC7AE700062CA31 /* HyperLink.swift in Sources */, - 4B9579802AC7AE700062CA31 /* SyncDataProviders.swift in Sources */, - 4B9579812AC7AE700062CA31 /* PasteboardWriting.swift in Sources */, - 4B9579822AC7AE700062CA31 /* BookmarkOutlineCellView.swift in Sources */, - 4B9579832AC7AE700062CA31 /* UnprotectedDomains.xcdatamodeld in Sources */, - 4B9579842AC7AE700062CA31 /* TabInstrumentation.swift in Sources */, - 4B9579872AC7AE700062CA31 /* ConfigurationManager.swift in Sources */, - 4B9579882AC7AE700062CA31 /* YoutubePlayerUserScript.swift in Sources */, - 4B9579892AC7AE700062CA31 /* PixelParameters.swift in Sources */, - 4B95798B2AC7AE700062CA31 /* FaviconImageCache.swift in Sources */, - 4B95798C2AC7AE700062CA31 /* TabBarViewController.swift in Sources */, - 4B95798D2AC7AE700062CA31 /* BookmarkOutlineViewDataSource.swift in Sources */, - 4B95798E2AC7AE700062CA31 /* DataImportStatusProviding.swift in Sources */, - 3158B14C2B0BF74500AF130C /* DataBrokerProtectionDebugMenu.swift in Sources */, - 4B95798F2AC7AE700062CA31 /* PasswordManagementBitwardenItemView.swift in Sources */, - 4B9579912AC7AE700062CA31 /* NSNotificationName+PasswordManager.swift in Sources */, - 4B9579922AC7AE700062CA31 /* RulesCompilationMonitor.swift in Sources */, - 4B9579932AC7AE700062CA31 /* FBProtectionTabExtension.swift in Sources */, - 4B41EDB82B169889001EEDF4 /* VPNFeedbackFormViewModel.swift in Sources */, - 4B9579942AC7AE700062CA31 /* CrashReportReader.swift in Sources */, - 4B9579952AC7AE700062CA31 /* DataTaskProviding.swift in Sources */, - 4B9579962AC7AE700062CA31 /* FeatureFlag.swift in Sources */, - B6B4D1C82B0B3B5400C26286 /* DataImportReportModel.swift in Sources */, - 4B9579972AC7AE700062CA31 /* FeedbackViewController.swift in Sources */, - B6104E9D2BA9C174008636B2 /* DownloadResumeData.swift in Sources */, - 4B9579982AC7AE700062CA31 /* FaviconSelector.swift in Sources */, - 4B95799A2AC7AE700062CA31 /* PrintingUserScript.swift in Sources */, - 4B95799B2AC7AE700062CA31 /* ConnectBitwardenViewController.swift in Sources */, - 4B95799C2AC7AE700062CA31 /* BWManager.swift in Sources */, - B6BCC5262AFCDABB002C5499 /* DataImportSourceViewModel.swift in Sources */, - 4B95799D2AC7AE700062CA31 /* AppTrackerDataSetProvider.swift in Sources */, - D64A5FFB2AEA5C2B00B6D6E7 /* HomeButtonMenuFactory.swift in Sources */, - 4B95799E2AC7AE700062CA31 /* EncryptionKeyGeneration.swift in Sources */, - 4B95799F2AC7AE700062CA31 /* TabLazyLoader.swift in Sources */, - B690152F2ACBF4DA00AD0BAB /* MenuPreview.swift in Sources */, - 1D01A3D22B88CEC600FE8150 /* PreferencesAccessibilityView.swift in Sources */, - 4B9579A02AC7AE700062CA31 /* InvitedToWaitlistView.swift in Sources */, - 4B9579A22AC7AE700062CA31 /* SaveCredentialsViewController.swift in Sources */, - B6E3E55D2BC0041C00A41922 /* DownloadListStoreMock.swift in Sources */, - 4B9579A32AC7AE700062CA31 /* PopUpButton.swift in Sources */, - 4B9579A42AC7AE700062CA31 /* NetworkProtectionInviteDialog.swift in Sources */, - 4B9579A52AC7AE700062CA31 /* SuggestionViewController.swift in Sources */, - 4B9579A82AC7AE700062CA31 /* BWKeyStorage.swift in Sources */, - 4B9579A92AC7AE700062CA31 /* VisitViewModel.swift in Sources */, - 4B9579AA2AC7AE700062CA31 /* AddressBarTextEditor.swift in Sources */, - 3158B15B2B0BF76700AF130C /* DataBrokerProtectionFeatureDisabler.swift in Sources */, - 1D26EBAE2B74BECB0002A93F /* NSImageSendable.swift in Sources */, - 4B9579AB2AC7AE700062CA31 /* Atb.swift in Sources */, - 4B9579AC2AC7AE700062CA31 /* BrowserTabView.swift in Sources */, - 4B9579AD2AC7AE700062CA31 /* DownloadsViewController.swift in Sources */, - 4B9579AE2AC7AE700062CA31 /* DataExtension.swift in Sources */, - 4B9579AF2AC7AE700062CA31 /* ConfigurationStore.swift in Sources */, - 4B9579B02AC7AE700062CA31 /* Feedback.swift in Sources */, - 4B9579B22AC7AE700062CA31 /* FirefoxFaviconsReader.swift in Sources */, - 4B9579B32AC7AE700062CA31 /* CopyHandler.swift in Sources */, - 4B9579B42AC7AE700062CA31 /* ContentBlockingRulesUpdateObserver.swift in Sources */, - 4B9579B52AC7AE700062CA31 /* FirefoxLoginReader.swift in Sources */, - 4B9579B62AC7AE700062CA31 /* AtbParser.swift in Sources */, - 4B9579B72AC7AE700062CA31 /* PreferencesDuckPlayerView.swift in Sources */, - 4B41EDB62B169883001EEDF4 /* VPNFeedbackFormViewController.swift in Sources */, - 4B9579B92AC7AE700062CA31 /* BookmarkSidebarTreeController.swift in Sources */, - 4B9579BA2AC7AE700062CA31 /* HomePageFavoritesModel.swift in Sources */, - 4B9579BB2AC7AE700062CA31 /* SequenceExtensions.swift in Sources */, - 4B9579BC2AC7AE700062CA31 /* WKBackForwardListExtension.swift in Sources */, - 4B9579BD2AC7AE700062CA31 /* ChromiumDataImporter.swift in Sources */, - 4B9579BE2AC7AE700062CA31 /* BackForwardListItemViewModel.swift in Sources */, - 4B9579BF2AC7AE700062CA31 /* BWNotRespondingAlert.swift in Sources */, - 1DDC85052B83903E00670238 /* PreferencesWebTrackingProtectionView.swift in Sources */, - 4B9579C02AC7AE700062CA31 /* DebugUserScript.swift in Sources */, - 1DC669722B6CF0D700AA0645 /* TabSnapshotStore.swift in Sources */, - 4B9579C12AC7AE700062CA31 /* RecentlyClosedTab.swift in Sources */, - B6E3E55A2BBFD51400A41922 /* PreviewViewController.swift in Sources */, - 4B9579C22AC7AE700062CA31 /* PDFSearchTextMenuItemHandler.swift in Sources */, - 4B9579C42AC7AE700062CA31 /* HistoryMenu.swift in Sources */, - 4B9579C52AC7AE700062CA31 /* ContentScopeFeatureFlagging.swift in Sources */, - 4B9579C62AC7AE700062CA31 /* OnboardingButtonStyles.swift in Sources */, - 4B9579C72AC7AE700062CA31 /* SaveIdentityPopover.swift in Sources */, - 4B9579C82AC7AE700062CA31 /* AuthenticationAlert.swift in Sources */, - 4B9579C92AC7AE700062CA31 /* SetExtension.swift in Sources */, - 4B9579CA2AC7AE700062CA31 /* YoutubePlayerNavigationHandler.swift in Sources */, - 4B9579CB2AC7AE700062CA31 /* PreferencesAboutView.swift in Sources */, - 4B9579CC2AC7AE700062CA31 /* ContentBlocking.swift in Sources */, - 4B37EE792B4CFF6F00A89A61 /* DataBrokerProtectionRemoteMessage.swift in Sources */, - 4B9579CD2AC7AE700062CA31 /* LocalAuthenticationService.swift in Sources */, - 4B9579CE2AC7AE700062CA31 /* CredentialsCleanupErrorHandling.swift in Sources */, - 4B9579CF2AC7AE700062CA31 /* SafariBookmarksReader.swift in Sources */, - 4B9579D02AC7AE700062CA31 /* HTTPCookie.swift in Sources */, - 1DDD3EC62B84F96B004CBF2B /* CookiePopupProtectionPreferences.swift in Sources */, - 4B9579D12AC7AE700062CA31 /* SafariVersionReader.swift in Sources */, - 4B9579D22AC7AE700062CA31 /* LoginFaviconView.swift in Sources */, - 4B9579D32AC7AE700062CA31 /* FireproofDomainsViewController.swift in Sources */, - 1ED910D72B63BFB300936947 /* IdentityTheftRestorationPagesUserScript.swift in Sources */, - 4B9579D42AC7AE700062CA31 /* URLEventHandler.swift in Sources */, - 3158B15E2B0BF76F00AF130C /* DataBrokerProtectionAppEvents.swift in Sources */, - 4B9579D52AC7AE700062CA31 /* SupportedOsChecker.swift in Sources */, - 4B9579D62AC7AE700062CA31 /* WKWebViewExtension.swift in Sources */, - 4B9579D72AC7AE700062CA31 /* CleanThisHistoryMenuItem.swift in Sources */, - 4B9579D92AC7AE700062CA31 /* DownloadListItem.swift in Sources */, - 4B9579DA2AC7AE700062CA31 /* WaitlistRequest.swift in Sources */, - 4B9579DB2AC7AE700062CA31 /* DownloadsPopover.swift in Sources */, - 37A6A8F92AFCCA59008580A3 /* FaviconsFetcherOnboardingViewController.swift in Sources */, - 4B9579DC2AC7AE700062CA31 /* BookmarksBarMenuFactory.swift in Sources */, - 4B9579DD2AC7AE700062CA31 /* SpacerNode.swift in Sources */, - B62B483C2ADE46FC000DECE5 /* Application.swift in Sources */, - 4B9579DF2AC7AE700062CA31 /* SyncManagementDialogViewController.swift in Sources */, - 4B05265F2B1AEFDB0054955A /* VPNMetadataCollector.swift in Sources */, - 4B9579E02AC7AE700062CA31 /* BookmarkExtension.swift in Sources */, - 4B9579E12AC7AE700062CA31 /* PasswordManagementCreditCardModel.swift in Sources */, - B677FC522B06376B0099EB04 /* ReportFeedbackView.swift in Sources */, - 1D220BFE2B87AACF00F8BBC6 /* PrivacyProtectionStatus.swift in Sources */, - 4B9579E22AC7AE700062CA31 /* NSEventExtension.swift in Sources */, - 1D26EBB22B74DB600002A93F /* TabSnapshotCleanupService.swift in Sources */, - 4B9579E32AC7AE700062CA31 /* Onboarding.swift in Sources */, - 4B9579E42AC7AE700062CA31 /* PopUpWindow.swift in Sources */, - 4B9579E52AC7AE700062CA31 /* Favicons.xcdatamodeld in Sources */, - 4B9579E62AC7AE700062CA31 /* Publisher.asVoid.swift in Sources */, - 9FEE986F2B85BA17002E44E8 /* AddEditBookmarkDialogCoordinatorViewModel.swift in Sources */, - 4B9579E72AC7AE700062CA31 /* Waitlist.swift in Sources */, - 3158B1582B0BF76000AF130C /* DataBrokerProtectionFeatureVisibility.swift in Sources */, - 4B9579E82AC7AE700062CA31 /* NavigationButtonMenuDelegate.swift in Sources */, - 4B9579E92AC7AE700062CA31 /* CrashReport.swift in Sources */, - 4B9579EA2AC7AE700062CA31 /* NSPopoverExtension.swift in Sources */, - 4B9579EB2AC7AE700062CA31 /* NSPathControlView.swift in Sources */, - 4B9579EC2AC7AE700062CA31 /* HTTPSUpgradeTabExtension.swift in Sources */, - 4B9579ED2AC7AE700062CA31 /* AppIconChanger.swift in Sources */, - 4B9579EE2AC7AE700062CA31 /* AppMain.swift in Sources */, - 4B9579EF2AC7AE700062CA31 /* ProductWaitlistRequest.swift in Sources */, - 7BEC20442B0F505F00243D3E /* AddBookmarkPopoverView.swift in Sources */, - 4B9579F02AC7AE700062CA31 /* Bookmark.xcdatamodeld in Sources */, - 4B9579F12AC7AE700062CA31 /* DefaultBrowserPromptView.swift in Sources */, - 4B9579F22AC7AE700062CA31 /* WaitlistActivationDateStore.swift in Sources */, - 4B9579F42AC7AE700062CA31 /* FaviconManager.swift in Sources */, - 4B9579F52AC7AE700062CA31 /* PFMoveApplication.m in Sources */, - B68D21D22ACBCA01002DA3C2 /* ContentBlockerRulesManagerMock.swift in Sources */, - 4B9579F62AC7AE700062CA31 /* ChromiumFaviconsReader.swift in Sources */, - 4B9579F72AC7AE700062CA31 /* SuggestionTableRowView.swift in Sources */, - EEC4A6732B2C90AB00F7C0AA /* VPNLocationPreferenceItem.swift in Sources */, - 4B9579F82AC7AE700062CA31 /* DownloadsPreferences.swift in Sources */, - 4B9579F92AC7AE700062CA31 /* PasswordManagementItemList.swift in Sources */, - 4B9579FA2AC7AE700062CA31 /* Bookmark.swift in Sources */, - 4B9579FB2AC7AE700062CA31 /* ConnectBitwardenViewModel.swift in Sources */, - 4B9579FC2AC7AE700062CA31 /* NSNotificationName+DataImport.swift in Sources */, - 4B9579FD2AC7AE700062CA31 /* StoredPermission.swift in Sources */, - B6CC266A2BAD959500F53F8D /* DownloadProgress.swift in Sources */, - 4B9579FE2AC7AE700062CA31 /* FirePopoverCollectionViewHeader.swift in Sources */, - 4B9579FF2AC7AE700062CA31 /* FireViewController.swift in Sources */, - 4B957A002AC7AE700062CA31 /* OutlineSeparatorViewCell.swift in Sources */, - 4B957A012AC7AE700062CA31 /* SafariDataImporter.swift in Sources */, - 4B957A022AC7AE700062CA31 /* WaitlistViewModel.swift in Sources */, - 4B957A032AC7AE700062CA31 /* LocalBookmarkStore.swift in Sources */, - 4B957A042AC7AE700062CA31 /* BWEncryption.m in Sources */, - 4B957A052AC7AE700062CA31 /* StatisticsLoader.swift in Sources */, - 4B957A072AC7AE700062CA31 /* DataClearingPreferences.swift in Sources */, - 4B957A082AC7AE700062CA31 /* LocalUnprotectedDomains.swift in Sources */, - 4B957A092AC7AE700062CA31 /* InternalUserDeciderStore.swift in Sources */, - 4B957A0A2AC7AE700062CA31 /* NewWindowPolicy.swift in Sources */, - 4B957A0B2AC7AE700062CA31 /* NavigationBarBadgeAnimator.swift in Sources */, - 4B957A0C2AC7AE700062CA31 /* NSTextViewExtension.swift in Sources */, - 4B957A0D2AC7AE700062CA31 /* FutureExtension.swift in Sources */, - 4B957A0E2AC7AE700062CA31 /* UserDialogRequest.swift in Sources */, - 4B957A0F2AC7AE700062CA31 /* DownloadsCellView.swift in Sources */, - 4B957A112AC7AE700062CA31 /* PublishedAfter.swift in Sources */, - 1DDC85012B835BC000670238 /* SearchPreferences.swift in Sources */, - B6B5F58C2B03673B008DB58A /* BrowserImportMoreInfoView.swift in Sources */, - 4B957A122AC7AE700062CA31 /* FirefoxBerkeleyDatabaseReader.swift in Sources */, - 4B957A132AC7AE700062CA31 /* WebViewSnapshotView.swift in Sources */, - 4B957A142AC7AE700062CA31 /* DeviceAuthenticationService.swift in Sources */, - 4B957A152AC7AE700062CA31 /* AppConfigurationURLProvider.swift in Sources */, - 4B957A162AC7AE700062CA31 /* SyncSettingsAdapter.swift in Sources */, - 4B957A172AC7AE700062CA31 /* AutofillPreferences.swift in Sources */, - B6DE57F92B05EA9000CD54B9 /* SheetHostingWindow.swift in Sources */, - 4B957A192AC7AE700062CA31 /* PasswordManagerCoordinator.swift in Sources */, - 4B957A1A2AC7AE700062CA31 /* PasswordManagementIdentityModel.swift in Sources */, - 4B957A1B2AC7AE700062CA31 /* UserDefaultsWrapper.swift in Sources */, - B65C7DFD2B886CF0001E2D5C /* WKPDFHUDViewWrapper.swift in Sources */, - 4B957A1C2AC7AE700062CA31 /* PasswordManagementPopover.swift in Sources */, - 4B957A1D2AC7AE700062CA31 /* BWCommunicator.swift in Sources */, - 4B957A1E2AC7AE700062CA31 /* HomePageRecentlyVisitedModel.swift in Sources */, - 4B957A1F2AC7AE700062CA31 /* NavigationBarPopovers.swift in Sources */, - 4B957A202AC7AE700062CA31 /* CancellableExtension.swift in Sources */, - 4B957A212AC7AE700062CA31 /* PinnedTabsHostingView.swift in Sources */, - 4B957A222AC7AE700062CA31 /* FirefoxBookmarksReader.swift in Sources */, - 9F982F0F2B8224BF00231028 /* AddEditBookmarkFolderDialogViewModel.swift in Sources */, - 4B0526622B1D55320054955A /* VPNFeedbackSender.swift in Sources */, - 4B957A232AC7AE700062CA31 /* DeviceIdleStateDetector.swift in Sources */, - 85D0327D2B8E3D090041D1FB /* HistoryCoordinatorExtension.swift in Sources */, - 4B957A242AC7AE700062CA31 /* FlatButton.swift in Sources */, - 4B957A252AC7AE700062CA31 /* PinnedTabView.swift in Sources */, - 4B957A262AC7AE700062CA31 /* DataEncryption.swift in Sources */, - 4B957A272AC7AE700062CA31 /* PrivacyDashboardPopover.swift in Sources */, - 4B957A282AC7AE700062CA31 /* TestsClosureNavigationResponder.swift in Sources */, - 4B957A292AC7AE700062CA31 /* RootView.swift in Sources */, - 56BA1E772BAAF70F001CF69F /* SSLErrorPageTabExtension.swift in Sources */, - 4B37EE7C2B4CFF8000A89A61 /* HomePageRemoteMessagingRequest.swift in Sources */, - 4B957A2A2AC7AE700062CA31 /* AddressBarTextField.swift in Sources */, - 4B957A2B2AC7AE700062CA31 /* FocusRingView.swift in Sources */, - 4B957A2C2AC7AE700062CA31 /* BookmarksBarViewModel.swift in Sources */, - 4B957A2D2AC7AE700062CA31 /* NSPopUpButtonView.swift in Sources */, - 4B957A2E2AC7AE700062CA31 /* BlockMenuItem.swift in Sources */, - 4B957A2F2AC7AE700062CA31 /* ContextualMenu.swift in Sources */, - 9FBD84752BB3E15D00220859 /* InstallationAttributionPixelHandler.swift in Sources */, - 4B957A302AC7AE700062CA31 /* NavigationBarViewController.swift in Sources */, - 4B957A312AC7AE700062CA31 /* MainViewController.swift in Sources */, - 4B957A322AC7AE700062CA31 /* DuckPlayer.swift in Sources */, - F1D43AF02B98D8DF00BAB743 /* MainMenuActions+VanillaBrowser.swift in Sources */, - 4B957A332AC7AE700062CA31 /* Favicon.swift in Sources */, - 1E2AE4CA2ACB21A000684E0A /* NetworkProtectionRemoteMessage.swift in Sources */, - 4B957A342AC7AE700062CA31 /* SuggestionContainerViewModel.swift in Sources */, - 9F56CFAF2B84326C00BB7F11 /* AddEditBookmarkDialogViewModel.swift in Sources */, - 4B957A352AC7AE700062CA31 /* FirePopoverWrapperViewController.swift in Sources */, - 4B957A362AC7AE700062CA31 /* NSPasteboardItemExtension.swift in Sources */, - 4B957A372AC7AE700062CA31 /* AutofillPreferencesModel.swift in Sources */, - 4B957A382AC7AE700062CA31 /* NetworkProtectionDebugUtilities.swift in Sources */, - 4B957A392AC7AE700062CA31 /* NSException+Catch.swift in Sources */, - 4B957A3A2AC7AE700062CA31 /* PasswordManagementNoteModel.swift in Sources */, - 4B957A3B2AC7AE700062CA31 /* CookieNotificationAnimationModel.swift in Sources */, - 4B957A3C2AC7AE700062CA31 /* JoinedWaitlistView.swift in Sources */, - 4B957A3D2AC7AE700062CA31 /* SharingMenu.swift in Sources */, - 4B957A3E2AC7AE700062CA31 /* EnableWaitlistFeatureView.swift in Sources */, - 4B957A3F2AC7AE700062CA31 /* GrammarFeaturesManager.swift in Sources */, - 4B957A402AC7AE700062CA31 /* WaitlistModalViewController.swift in Sources */, - B60293E82BA19ECD0033186B /* NetPPopoverManagerMock.swift in Sources */, - B6BCC53E2AFD15DF002C5499 /* DataImportProfilePicker.swift in Sources */, - 4B957A412AC7AE700062CA31 /* WKMenuItemIdentifier.swift in Sources */, - 4B957A422AC7AE700062CA31 /* SafariFaviconsReader.swift in Sources */, - 4B957A432AC7AE700062CA31 /* NSScreenExtension.swift in Sources */, - 4B957A442AC7AE700062CA31 /* NSBezierPathExtension.swift in Sources */, - 4B957A452AC7AE700062CA31 /* Bundle+VPN.swift in Sources */, - B68D21CA2ACBC971002DA3C2 /* MockPrivacyConfiguration.swift in Sources */, - 4B957A462AC7AE700062CA31 /* WebsiteDataStore.swift in Sources */, - 4B957A472AC7AE700062CA31 /* NetworkProtectionFeatureVisibility.swift in Sources */, - 3778183D2AD6F86D00533759 /* FavoritesDisplayModeSyncHandler.swift in Sources */, - 4B957A482AC7AE700062CA31 /* PermissionContextMenu.swift in Sources */, - 4B957A492AC7AE700062CA31 /* ContextMenuUserScript.swift in Sources */, - 4B957A4A2AC7AE700062CA31 /* NSSavePanelExtension.swift in Sources */, - 4B957A4B2AC7AE700062CA31 /* AppPrivacyConfigurationDataProvider.swift in Sources */, - 4B957A4C2AC7AE700062CA31 /* LinkButton.swift in Sources */, - 4B957A4D2AC7AE700062CA31 /* TemporaryFileHandler.swift in Sources */, - 4B957A4E2AC7AE700062CA31 /* URL+NetworkProtection.swift in Sources */, - 4B957A4F2AC7AE700062CA31 /* PrivacyFeatures.swift in Sources */, - 4B957A512AC7AE700062CA31 /* ViewExtension.swift in Sources */, - 4B957A522AC7AE700062CA31 /* AVCaptureDevice+SwizzledAuthState.swift in Sources */, - 4B957A532AC7AE700062CA31 /* SubscriptionPagesUserScript.swift in Sources */, - 4B957A542AC7AE700062CA31 /* VisitMenuItem.swift in Sources */, - 4B957A552AC7AE700062CA31 /* EncryptionKeyStore.swift in Sources */, - 4B957A562AC7AE700062CA31 /* TabExtensionsBuilder.swift in Sources */, - 9F56CFB32B843F6C00BB7F11 /* BookmarksDialogViewFactory.swift in Sources */, - 1E2AE4C82ACB216B00684E0A /* HoverTrackingArea.swift in Sources */, - 4B957A582AC7AE700062CA31 /* PasswordManagementIdentityItemView.swift in Sources */, - 4B957A592AC7AE700062CA31 /* ProgressExtension.swift in Sources */, - 4B44FEF52B1FEF5A000619D8 /* FocusableTextEditor.swift in Sources */, - 4B957A5A2AC7AE700062CA31 /* CSVParser.swift in Sources */, - 4B957A5B2AC7AE700062CA31 /* PixelDataModel.xcdatamodeld in Sources */, - 4B957A5C2AC7AE700062CA31 /* PrivacyDashboardWebView.swift in Sources */, - B6656E5B2B2ADB1C008798A1 /* RequestFilePermissionView.swift in Sources */, - 4B957A5D2AC7AE700062CA31 /* AppearancePreferences.swift in Sources */, - 4B957A5E2AC7AE700062CA31 /* DownloadListCoordinator.swift in Sources */, - 4B957A5F2AC7AE700062CA31 /* AdClickAttributionTabExtension.swift in Sources */, - 7B3618C52ADE77D3000D6154 /* NetworkProtectionNavBarPopoverManager.swift in Sources */, - 4B957A602AC7AE700062CA31 /* NSNotificationName+Debug.swift in Sources */, - 4B957A612AC7AE700062CA31 /* NavigationBarBadgeAnimationView.swift in Sources */, - 4B957A622AC7AE700062CA31 /* AddressBarButton.swift in Sources */, - 4B957A642AC7AE700062CA31 /* FaviconStore.swift in Sources */, - 4B957A652AC7AE700062CA31 /* WaitlistTermsAndConditionsView.swift in Sources */, - B62B48592ADE730D000DECE5 /* FileImportView.swift in Sources */, - 4B957A662AC7AE700062CA31 /* SuggestionListCharacteristics.swift in Sources */, - 4B957A672AC7AE700062CA31 /* TimeIntervalExtension.swift in Sources */, - 4B957A682AC7AE700062CA31 /* NetworkProtectionFeatureDisabler.swift in Sources */, - 7BBA7CEA2BAB03C1007579A3 /* DefaultSubscriptionFeatureAvailability+DefaultInitializer.swift in Sources */, - 4B957A692AC7AE700062CA31 /* BookmarkListViewController.swift in Sources */, - 4B957A6A2AC7AE700062CA31 /* SecureVaultLoginImporter.swift in Sources */, - 4B957A6B2AC7AE700062CA31 /* WKProcessPoolExtension.swift in Sources */, - 4B957A6D2AC7AE700062CA31 /* LoginItemsManager.swift in Sources */, - B6E3E5562BBFCEE300A41922 /* NoDownloadsCellView.swift in Sources */, - 4B957A6E2AC7AE700062CA31 /* PixelExperiment.swift in Sources */, - 4B957A6F2AC7AE700062CA31 /* DuckPlayerTabExtension.swift in Sources */, - 4B957A702AC7AE700062CA31 /* RecentlyClosedCoordinator.swift in Sources */, - 4B957A712AC7AE700062CA31 /* URLRequestExtension.swift in Sources */, - B6080BC82B21E78100B418EF /* DataImportErrorView.swift in Sources */, - 4B957A722AC7AE700062CA31 /* FaviconHostReference.swift in Sources */, - 4B957A732AC7AE700062CA31 /* DownloadsTabExtension.swift in Sources */, - 1D220BFA2B86192200F8BBC6 /* PreferencesEmailProtectionView.swift in Sources */, - 4B957A752AC7AE700062CA31 /* ASN1Parser.swift in Sources */, - 4B957A762AC7AE700062CA31 /* FileDownloadManager.swift in Sources */, - 4B957A772AC7AE700062CA31 /* BookmarkImport.swift in Sources */, - 4BF0E5172AD25A2600FFEC9E /* DuckDuckGoUserAgent.swift in Sources */, - C1372EF62BBC5BAD003F8793 /* SecureTextField.swift in Sources */, - 4B957A782AC7AE700062CA31 /* KeySetDictionary.swift in Sources */, - B68D21CB2ACBC9A3002DA3C2 /* ContentBlockingMock.swift in Sources */, - 4B957A792AC7AE700062CA31 /* HistoryTabExtension.swift in Sources */, - 4B957A7A2AC7AE700062CA31 /* FireCoordinator.swift in Sources */, - 4B957A7B2AC7AE700062CA31 /* GeolocationProvider.swift in Sources */, - 4B957A7C2AC7AE700062CA31 /* NSAlert+ActiveDownloadsTermination.swift in Sources */, - B62B48412ADE48DE000DECE5 /* ArrayBuilder.swift in Sources */, - 4B957A7D2AC7AE700062CA31 /* IndexPathExtension.swift in Sources */, - 4B957A7E2AC7AE700062CA31 /* PasswordManagementNoteItemView.swift in Sources */, - B6B4D1D22B0E0DD000C26286 /* DataImportNoDataView.swift in Sources */, - 4B957A7F2AC7AE700062CA31 /* NSApplicationExtension.swift in Sources */, - 4B957A802AC7AE700062CA31 /* NSWindowExtension.swift in Sources */, - 4B957A812AC7AE700062CA31 /* KeychainType+ClientDefault.swift in Sources */, - C13909F12B85FD4E001626ED /* AutofillActionExecutor.swift in Sources */, - 4B41EDA52B1543B9001EEDF4 /* VPNPreferencesModel.swift in Sources */, - 4B957A822AC7AE700062CA31 /* SyncDebugMenu.swift in Sources */, - 4B957A832AC7AE700062CA31 /* AddBookmarkPopover.swift in Sources */, - 4B957A852AC7AE700062CA31 /* QRSharingService.swift in Sources */, - 4B957A862AC7AE700062CA31 /* ProcessExtension.swift in Sources */, - B68412162B694BA10092F66A /* NSObject+performSelector.m in Sources */, - 4B957A872AC7AE700062CA31 /* PermissionAuthorizationQuery.swift in Sources */, - 4B957A882AC7AE700062CA31 /* BadgeAnimationView.swift in Sources */, - 4B957A892AC7AE700062CA31 /* BrowserTabSelectionDelegate.swift in Sources */, - 4B957A8A2AC7AE700062CA31 /* ContinueSetUpView.swift in Sources */, - B69A14F42B4D6FE800B9417D /* AddBookmarkFolderPopoverViewModel.swift in Sources */, - 4B957A8B2AC7AE700062CA31 /* PasswordManagementListSection.swift in Sources */, - 4B957A8C2AC7AE700062CA31 /* FaviconReferenceCache.swift in Sources */, - 4B957A8D2AC7AE700062CA31 /* BookmarkTreeController.swift in Sources */, - EEC4A6602B277F0D00F7C0AA /* VPNLocationViewModel.swift in Sources */, - 4B957A8E2AC7AE700062CA31 /* FirefoxEncryptionKeyReader.swift in Sources */, - 4B957A8F2AC7AE700062CA31 /* EventMapping+NetworkProtectionError.swift in Sources */, - 4B957A902AC7AE700062CA31 /* BookmarkManagementSplitViewController.swift in Sources */, - 4B957A912AC7AE700062CA31 /* CookieManagedNotificationContainerView.swift in Sources */, - 4B957A922AC7AE700062CA31 /* FileManagerExtension.swift in Sources */, - 1DDD3EBE2B84DCB9004CBF2B /* WebTrackingProtectionPreferences.swift in Sources */, - 4B957A932AC7AE700062CA31 /* PermissionModel.swift in Sources */, - 4B957A942AC7AE700062CA31 /* PasteboardFolder.swift in Sources */, - 4B957A952AC7AE700062CA31 /* CookieManagedNotificationView.swift in Sources */, - 9F3344602BBFA77F0040CBEB /* BookmarksBarVisibilityManager.swift in Sources */, - 4B957A962AC7AE700062CA31 /* PermissionType.swift in Sources */, - 4B957A982AC7AE700062CA31 /* RecentlyClosedWindow.swift in Sources */, - 4B957A992AC7AE700062CA31 /* ActionSpeech.swift in Sources */, - 4B957A9B2AC7AE700062CA31 /* ModalSheetCancellable.swift in Sources */, - 4B957A9C2AC7AE700062CA31 /* FireproofDomainsStore.swift in Sources */, - 4B957A9D2AC7AE700062CA31 /* NetworkProtectionSimulateFailureMenu.swift in Sources */, - 4B957A9E2AC7AE700062CA31 /* PrivacyDashboardPermissionHandler.swift in Sources */, - 4B957A9F2AC7AE700062CA31 /* TabCollectionViewModel.swift in Sources */, - 4B520F652BA5573A006405C7 /* WaitlistThankYouView.swift in Sources */, - 4B957AA02AC7AE700062CA31 /* BookmarkManager.swift in Sources */, - 4B957AA12AC7AE700062CA31 /* AboutModel.swift in Sources */, - 56BA1E8C2BB1CB5B001CF69F /* CertificateTrustEvaluator.swift in Sources */, - 4B957AA22AC7AE700062CA31 /* PasswordManagementCreditCardItemView.swift in Sources */, - 3158B1552B0BF75900AF130C /* LoginItem+DataBrokerProtection.swift in Sources */, - 4B957AA32AC7AE700062CA31 /* NSTextFieldExtension.swift in Sources */, - 56BA1E842BAC506F001CF69F /* SSLErrorPageUserScript.swift in Sources */, - 4B957AA42AC7AE700062CA31 /* BWManagement.swift in Sources */, - 4B957AA52AC7AE700062CA31 /* FireproofDomainsContainer.swift in Sources */, - 4B957AA62AC7AE700062CA31 /* ExternalAppSchemeHandler.swift in Sources */, - 4B957AA72AC7AE700062CA31 /* GeolocationService.swift in Sources */, - 4B957AA82AC7AE700062CA31 /* FireproofingURLExtensions.swift in Sources */, - 4B957AA92AC7AE700062CA31 /* ContentOverlayPopover.swift in Sources */, - 4B957AAA2AC7AE700062CA31 /* TabShadowView.swift in Sources */, - 4B957AAB2AC7AE700062CA31 /* BWMessageIdGenerator.swift in Sources */, - B65E5DB12B74E6AA00480415 /* TrackerNetwork.swift in Sources */, - B6E6B9E52BA1F5F1008AA7E1 /* FilePresenter.swift in Sources */, - 31F2D2022AF026D800BF0144 /* WaitlistTermsAndConditionsActionHandler.swift in Sources */, - 4B957AAC2AC7AE700062CA31 /* EncryptedValueTransformer.swift in Sources */, - 4B957AAD2AC7AE700062CA31 /* Tab+Dialogs.swift in Sources */, - 4B957AAE2AC7AE700062CA31 /* PasteboardBookmark.swift in Sources */, - 4B957AAF2AC7AE700062CA31 /* PinnedTabsManager.swift in Sources */, - 1D01A3D62B88CF7700FE8150 /* AccessibilityPreferences.swift in Sources */, - 4B957AB02AC7AE700062CA31 /* HoverUserScript.swift in Sources */, - 4B957AB12AC7AE700062CA31 /* MainMenuActions.swift in Sources */, - 4B957AB22AC7AE700062CA31 /* WKWebView+SessionState.swift in Sources */, - B6F9BDE62B45CD1900677B33 /* ModalView.swift in Sources */, - 4B957AB32AC7AE700062CA31 /* NetworkProtectionControllerErrorStore.swift in Sources */, - 4B957AB42AC7AE700062CA31 /* DataImport.swift in Sources */, - 4B957AB52AC7AE700062CA31 /* NetworkProtectionDebugMenu.swift in Sources */, - 4B957AB62AC7AE700062CA31 /* FireproofDomains.xcdatamodeld in Sources */, - 3158B14F2B0BF74F00AF130C /* DataBrokerProtectionManager.swift in Sources */, - 4B957AB82AC7AE700062CA31 /* HomePageView.swift in Sources */, - 9FEE98672B846870002E44E8 /* AddEditBookmarkView.swift in Sources */, - 4B957AB92AC7AE700062CA31 /* SerpHeadersNavigationResponder.swift in Sources */, - 4B957ABA2AC7AE700062CA31 /* HomePageContinueSetUpModel.swift in Sources */, - 4B957ABB2AC7AE700062CA31 /* WebKitDownloadTask.swift in Sources */, - 4B957ABC2AC7AE700062CA31 /* ChromiumLoginReader.swift in Sources */, - B6BCC5522AFE4F7D002C5499 /* DataImportTypePicker.swift in Sources */, - 4B957ABD2AC7AE700062CA31 /* NSAlert+PasswordManager.swift in Sources */, - 4B957ABE2AC7AE700062CA31 /* UserContentUpdating.swift in Sources */, - 4B957ABF2AC7AE700062CA31 /* ChromiumPreferences.swift in Sources */, - 4B957AC02AC7AE700062CA31 /* FirePopoverViewController.swift in Sources */, - 4B957AC12AC7AE700062CA31 /* SavePaymentMethodPopover.swift in Sources */, - 4B957AC22AC7AE700062CA31 /* FindInPageViewController.swift in Sources */, - 4B957AC32AC7AE700062CA31 /* Cryptography.swift in Sources */, - 9FBD84542BB3AACB00220859 /* AttributionOriginFileProvider.swift in Sources */, - 4B957AC42AC7AE700062CA31 /* BWVault.swift in Sources */, - 4B957AC52AC7AE700062CA31 /* NSViewExtension.swift in Sources */, - BBDFDC5C2B2B8D7000F62D90 /* DataBrokerProtectionExternalWaitlistPixels.swift in Sources */, - 9FA173E52B7A12B600EE4E6E /* BookmarkDialogFolderManagementView.swift in Sources */, - 4B957AC72AC7AE700062CA31 /* DownloadListViewModel.swift in Sources */, - 4B957AC82AC7AE700062CA31 /* BookmarkManagementDetailViewController.swift in Sources */, - 4B957AC92AC7AE700062CA31 /* CSVImporter.swift in Sources */, - 4B957ACA2AC7AE700062CA31 /* StartupPreferences.swift in Sources */, - 4B957ACB2AC7AE700062CA31 /* UserDefaults+NetworkProtectionWaitlist.swift in Sources */, - 4B957ACC2AC7AE700062CA31 /* MainMenu.swift in Sources */, - 4B957ACE2AC7AE700062CA31 /* BrowserTabViewController.swift in Sources */, - 4B957ACF2AC7AE700062CA31 /* CallToAction.swift in Sources */, - 4B957AD02AC7AE700062CA31 /* MouseOverView.swift in Sources */, - 4B957AD12AC7AE700062CA31 /* EncryptedHistoryStore.swift in Sources */, - 4B957AD22AC7AE700062CA31 /* FirePopoverCollectionViewItem.swift in Sources */, - 4B957AD32AC7AE700062CA31 /* ArrayExtension.swift in Sources */, - 4B957AD42AC7AE700062CA31 /* NetworkProtectionInviteCodeViewModel.swift in Sources */, - 4B957AD52AC7AE700062CA31 /* CrashReportSender.swift in Sources */, - B6BCC5212AFCD9ED002C5499 /* DataImportSourcePicker.swift in Sources */, - 4B957AD62AC7AE700062CA31 /* BookmarkHTMLImporter.swift in Sources */, - 4B957AD72AC7AE700062CA31 /* CustomRoundedCornersShape.swift in Sources */, - 4B957AD82AC7AE700062CA31 /* LocaleExtension.swift in Sources */, - 4B957AD92AC7AE700062CA31 /* SavePaymentMethodViewController.swift in Sources */, - 9FA173E92B7B122E00EE4E6E /* BookmarkDialogStackedContentView.swift in Sources */, - 4B957ADA2AC7AE700062CA31 /* BWStatus.swift in Sources */, - 4B957ADB2AC7AE700062CA31 /* WebKitVersionProvider.swift in Sources */, - B6BCC54D2AFDF24B002C5499 /* TaskWithProgress.swift in Sources */, - 4B957ADC2AC7AE700062CA31 /* NSCoderExtensions.swift in Sources */, - 4B957ADD2AC7AE700062CA31 /* RunningApplicationCheck.swift in Sources */, - 4B957ADE2AC7AE700062CA31 /* StatePersistenceService.swift in Sources */, - 4B957ADF2AC7AE700062CA31 /* WindowManager+StateRestoration.swift in Sources */, - 4B957AE02AC7AE700062CA31 /* TabCollection+NSSecureCoding.swift in Sources */, - 4B957AE12AC7AE700062CA31 /* Instruments.swift in Sources */, - 4B957AE22AC7AE700062CA31 /* ContentBlockerRulesLists.swift in Sources */, - 4B957AE32AC7AE700062CA31 /* NSViewControllerExtension.swift in Sources */, - 4B957AE42AC7AE700062CA31 /* NSAppearanceExtension.swift in Sources */, - 4B957AE52AC7AE700062CA31 /* EmailManagerExtension.swift in Sources */, - 4B957AE62AC7AE700062CA31 /* PermissionManager.swift in Sources */, - 4B957AE72AC7AE700062CA31 /* DefaultBrowserPreferences.swift in Sources */, - 4B957AE82AC7AE700062CA31 /* Permissions.xcdatamodeld in Sources */, - 4B957AE92AC7AE700062CA31 /* JSAlertController.swift in Sources */, - 4B957AEA2AC7AE700062CA31 /* NotificationService.swift in Sources */, - 4B41EDA92B1543C9001EEDF4 /* PreferencesVPNView.swift in Sources */, - 4B957AEB2AC7AE700062CA31 /* SyncPreferences.swift in Sources */, - 4B957AEC2AC7AE700062CA31 /* FaviconNullStore.swift in Sources */, - 4B957AED2AC7AE700062CA31 /* PaddedImageButton.swift in Sources */, - 4B957AEE2AC7AE700062CA31 /* EncryptionKeyStoring.swift in Sources */, - 4B957AEF2AC7AE700062CA31 /* String+Punycode.swift in Sources */, - 4B957AF02AC7AE700062CA31 /* NSException+Catch.m in Sources */, - 4B957AF12AC7AE700062CA31 /* AppStateRestorationManager.swift in Sources */, - 4B957AF22AC7AE700062CA31 /* DailyPixel.swift in Sources */, - 9FDA6C232B79A59D00E099A9 /* BookmarkFavoriteView.swift in Sources */, - 4B957AF32AC7AE700062CA31 /* NavigationHotkeyHandler.swift in Sources */, - B6CC266E2BAD9CD800F53F8D /* FileProgressPresenter.swift in Sources */, - 4B957AF42AC7AE700062CA31 /* ClickToLoadUserScript.swift in Sources */, - 4B957AF52AC7AE700062CA31 /* WindowControllersManager.swift in Sources */, - 4B957AF62AC7AE700062CA31 /* FireAnimationView.swift in Sources */, - 4B957AF72AC7AE700062CA31 /* FaviconUrlReference.swift in Sources */, - 4B957AF92AC7AE700062CA31 /* PasswordManagementItemListModel.swift in Sources */, - 4B957AFA2AC7AE700062CA31 /* SuggestionTableCellView.swift in Sources */, - 4B957AFB2AC7AE700062CA31 /* FireViewModel.swift in Sources */, - 4B957AFC2AC7AE700062CA31 /* SyncCredentialsAdapter.swift in Sources */, - 4B957AFD2AC7AE700062CA31 /* WKUserContentControllerExtension.swift in Sources */, - 4B957AFE2AC7AE700062CA31 /* EditableTextView.swift in Sources */, - 1E559BB32BBCA9F1002B4AF6 /* RedirectNavigationResponder.swift in Sources */, - 4B957AFF2AC7AE700062CA31 /* TabCollection.swift in Sources */, - 4B957B002AC7AE700062CA31 /* MainView.swift in Sources */, - 4B957B012AC7AE700062CA31 /* Tab+Navigation.swift in Sources */, - 4B957B022AC7AE700062CA31 /* EmailUrlExtensions.swift in Sources */, - 4B957B032AC7AE700062CA31 /* PasswordManagementItemModel.swift in Sources */, - 4B957B042AC7AE700062CA31 /* UpdateController.swift in Sources */, - 4B957B052AC7AE700062CA31 /* FindInPageModel.swift in Sources */, - 4B957B062AC7AE700062CA31 /* PseudoFolder.swift in Sources */, - 4B2F565D2B38F93E001214C0 /* NetworkProtectionSubscriptionEventHandler.swift in Sources */, - 4B957B082AC7AE700062CA31 /* PixelDataStore.swift in Sources */, - 4B957B092AC7AE700062CA31 /* WaitlistStorage.swift in Sources */, - B6ABD0D02BC042CE0000EB69 /* NSURL+sandboxExtensionRetainCount.m in Sources */, - 4B957B0A2AC7AE700062CA31 /* Pixel.swift in Sources */, - 4B957B0B2AC7AE700062CA31 /* PixelEvent.swift in Sources */, - 4B957B0C2AC7AE700062CA31 /* TabBarFooter.swift in Sources */, - C168B9AE2B31DC7F001AFAD9 /* AutofillNeverPromptWebsitesManager.swift in Sources */, - 4B957B0D2AC7AE700062CA31 /* JSAlertViewModel.swift in Sources */, - 4B957B0E2AC7AE700062CA31 /* BookmarksBarCollectionViewItem.swift in Sources */, - B69A14FC2B4D705D00B9417D /* BookmarkFolderPicker.swift in Sources */, - 4B957B0F2AC7AE700062CA31 /* FileDownloadError.swift in Sources */, - 4B957B102AC7AE700062CA31 /* MoreOrLessView.swift in Sources */, - 4B957B122AC7AE700062CA31 /* History.xcdatamodeld in Sources */, - 4B957B132AC7AE700062CA31 /* PermissionStore.swift in Sources */, - EEC4A6612B277F1100F7C0AA /* NetworkProtectionVPNCountryLabelsModel.swift in Sources */, - 4B957B142AC7AE700062CA31 /* PrivacyIconViewModel.swift in Sources */, - 4B957B152AC7AE700062CA31 /* ChromiumBookmarksReader.swift in Sources */, - B66CA4212AD910B300447CF0 /* DataImportView.swift in Sources */, - 4B957B162AC7AE700062CA31 /* Downloads.xcdatamodeld in Sources */, - 4B957B172AC7AE700062CA31 /* TabPreviewViewController.swift in Sources */, - 4B957B182AC7AE700062CA31 /* PreferencesDataClearingView.swift in Sources */, - 4B957B182AC7AE700062CA31 /* PreferencesDataClearingView.swift in Sources */, - 4B957B192AC7AE700062CA31 /* NSPasteboardExtension.swift in Sources */, - 4B957B1A2AC7AE700062CA31 /* OnboardingViewModel.swift in Sources */, - F1B33DF42BAD929D001128B3 /* SubscriptionAppStoreRestorer.swift in Sources */, - 4B957B1B2AC7AE700062CA31 /* ScriptSourceProviding.swift in Sources */, - 4B957B1C2AC7AE700062CA31 /* CoreDataBookmarkImporter.swift in Sources */, - B6ABD0CC2BC03F610000EB69 /* SecurityScopedFileURLController.swift in Sources */, - 4B957B1D2AC7AE700062CA31 /* SuggestionViewModel.swift in Sources */, - 4B957B1E2AC7AE700062CA31 /* BookmarkManagedObject.swift in Sources */, - 4B957B1F2AC7AE700062CA31 /* CSVLoginExporter.swift in Sources */, - 4B957B202AC7AE700062CA31 /* NSAttributedStringExtension.swift in Sources */, - 4B957B212AC7AE700062CA31 /* AnimationView.swift in Sources */, - 4B957B222AC7AE700062CA31 /* NSRectExtension.swift in Sources */, - 4B957B232AC7AE700062CA31 /* WaitlistRootView.swift in Sources */, - 4B957B242AC7AE700062CA31 /* YoutubeOverlayUserScript.swift in Sources */, - 4B957B252AC7AE700062CA31 /* DictionaryExtension.swift in Sources */, - 4B957B262AC7AE700062CA31 /* Publishers.NestedObjectChanges.swift in Sources */, - 4B957B272AC7AE700062CA31 /* MenuItemSelectors.swift in Sources */, - 4B957B282AC7AE700062CA31 /* FaviconView.swift in Sources */, - 4B957B292AC7AE700062CA31 /* OnboardingFlow.swift in Sources */, - 4B957B2A2AC7AE700062CA31 /* PasswordManagementLoginModel.swift in Sources */, - 4B957B2B2AC7AE700062CA31 /* TabViewModel.swift in Sources */, - 4B957B2C2AC7AE700062CA31 /* TabDragAndDropManager.swift in Sources */, - B677FC572B064A9C0099EB04 /* DataImportViewModel.swift in Sources */, - 4B957B2D2AC7AE700062CA31 /* NSNotificationName+Favicons.swift in Sources */, - 4B957B2E2AC7AE700062CA31 /* PinningManager.swift in Sources */, - 4B957B2F2AC7AE700062CA31 /* SyncMetadataDatabase.swift in Sources */, - 4B957B302AC7AE700062CA31 /* TabCollectionViewModel+NSSecureCoding.swift in Sources */, - 4B957B312AC7AE700062CA31 /* StringExtension.swift in Sources */, - 4B957B322AC7AE700062CA31 /* EmailManagerRequestDelegate.swift in Sources */, - 4B957B332AC7AE700062CA31 /* ApplicationVersionReader.swift in Sources */, - 4B957B342AC7AE700062CA31 /* BookmarksBarViewController.swift in Sources */, - 4B957B352AC7AE700062CA31 /* PreferencesAutofillView.swift in Sources */, - 4B957B362AC7AE700062CA31 /* BurnerHomePageView.swift in Sources */, - 4B957B372AC7AE700062CA31 /* UserText+PasswordManager.swift in Sources */, - 4B957B382AC7AE700062CA31 /* LoadingProgressView.swift in Sources */, - 7BEC20472B0F505F00243D3E /* AddBookmarkFolderPopoverView.swift in Sources */, - 4B957B392AC7AE700062CA31 /* StatisticsStore.swift in Sources */, - EEC4A66B2B2C87D300F7C0AA /* VPNLocationView.swift in Sources */, - B6E3E5522BBFCDEE00A41922 /* OpenDownloadsCellView.swift in Sources */, - 4B957B3A2AC7AE700062CA31 /* BWInstallationService.swift in Sources */, - 4B957B3B2AC7AE700062CA31 /* BookmarksBarPromptPopover.swift in Sources */, - 4B957B3C2AC7AE700062CA31 /* NetworkProtectionInvitePresenter.swift in Sources */, - 4B957B3D2AC7AE700062CA31 /* ColorView.swift in Sources */, - 4B957B3E2AC7AE700062CA31 /* RecentlyClosedCacheItem.swift in Sources */, - 4B957B3F2AC7AE700062CA31 /* PopupBlockedPopover.swift in Sources */, - 4B957B402AC7AE700062CA31 /* SaveCredentialsPopover.swift in Sources */, - 4B957B412AC7AE700062CA31 /* LegacyBookmarksStoreMigration.swift in Sources */, - 4B957B422AC7AE700062CA31 /* QuartzIdleStateProvider.swift in Sources */, - 4B957B432AC7AE700062CA31 /* DuckPlayerPreferences.swift in Sources */, - 4B957B442AC7AE700062CA31 /* DownloadViewModel.swift in Sources */, - 4B957B452AC7AE700062CA31 /* BookmarkHTMLReader.swift in Sources */, - 4B957B462AC7AE700062CA31 /* Tab+NSSecureCoding.swift in Sources */, - 4B957B472AC7AE700062CA31 /* NSNotificationName+EmailManager.swift in Sources */, - B6619EFE2B111CCC00CD9186 /* InstructionsFormatParser.swift in Sources */, - 1DDD3EC22B84F5D5004CBF2B /* PreferencesCookiePopupProtectionView.swift in Sources */, - 4B957B482AC7AE700062CA31 /* MouseOverButton.swift in Sources */, - 4B957B492AC7AE700062CA31 /* FireInfoViewController.swift in Sources */, - 4B957B4A2AC7AE700062CA31 /* LoginItem+NetworkProtection.swift in Sources */, - B6C8CAAA2AD010DD0060E1CD /* YandexDataImporter.swift in Sources */, - 4B957B4B2AC7AE700062CA31 /* PermissionButton.swift in Sources */, - 4B957B4C2AC7AE700062CA31 /* MoreOptionsMenu.swift in Sources */, - 4B957B4D2AC7AE700062CA31 /* PermissionAuthorizationViewController.swift in Sources */, - EE6666712B56EDE4001D898D /* VPNLocationsHostingViewController.swift in Sources */, - 4B957B4E2AC7AE700062CA31 /* BookmarkNode.swift in Sources */, - 4B957B4F2AC7AE700062CA31 /* LongPressButton.swift in Sources */, - 4B957B502AC7AE700062CA31 /* CoreDataStore.swift in Sources */, - 4B957B512AC7AE700062CA31 /* BundleExtension.swift in Sources */, - 4B957B522AC7AE700062CA31 /* NSOpenPanelExtensions.swift in Sources */, - EEC4A66F2B2C894F00F7C0AA /* VPNLocationPreferenceItemModel.swift in Sources */, - 4B957B532AC7AE700062CA31 /* FirePopover.swift in Sources */, - 4B957B552AC7AE700062CA31 /* NetworkProtectionOnboardingMenu.swift in Sources */, - 4B957B562AC7AE700062CA31 /* VariantManager.swift in Sources */, - 4B957B572AC7AE700062CA31 /* ApplicationDockMenu.swift in Sources */, - 4B957B582AC7AE700062CA31 /* SaveIdentityViewController.swift in Sources */, - 4B957B592AC7AE700062CA31 /* AppLauncher.swift in Sources */, - 4B957B5A2AC7AE700062CA31 /* FileStore.swift in Sources */, - 1DB67F2F2B6FEFDB003DF243 /* ViewSnapshotRenderer.swift in Sources */, - 4B957B5B2AC7AE700062CA31 /* PixelArguments.swift in Sources */, - 4B957B5C2AC7AE700062CA31 /* PinnedTabsViewModel.swift in Sources */, - 4B957B5D2AC7AE700062CA31 /* BookmarkList.swift in Sources */, - 4B957B5E2AC7AE700062CA31 /* NEOnDemandRuleExtension.swift in Sources */, - 1DB67F2B2B6FEB19003DF243 /* WebViewSnapshotRenderer.swift in Sources */, - 4B957B5F2AC7AE700062CA31 /* BookmarkTableRowView.swift in Sources */, - 4B957B602AC7AE700062CA31 /* FavoritesView.swift in Sources */, - 3158B1522B0BF75400AF130C /* DataBrokerProtectionLoginItemScheduler.swift in Sources */, - 4B957B612AC7AE700062CA31 /* HomePage.swift in Sources */, - 4B957B622AC7AE700062CA31 /* RoundedSelectionRowView.swift in Sources */, - B6A22B652B1E29D000ECD2BA /* DataImportSummaryViewModel.swift in Sources */, - 9FA173E12B7A0EFE00EE4E6E /* BookmarkDialogButtonsView.swift in Sources */, - 4B957B632AC7AE700062CA31 /* LocalStatisticsStore.swift in Sources */, - 4B957B642AC7AE700062CA31 /* BackForwardListItem.swift in Sources */, - 4B957B672AC7AE700062CA31 /* AtbAndVariantCleanup.swift in Sources */, - 4B957B692AC7AE700062CA31 /* FeedbackWindow.swift in Sources */, - 4B957B6A2AC7AE700062CA31 /* WorkspaceProtocol.swift in Sources */, - 4B957B6B2AC7AE700062CA31 /* RecentlyVisitedView.swift in Sources */, - 4B957B6C2AC7AE700062CA31 /* MouseOverAnimationButton.swift in Sources */, - 4B957B6D2AC7AE700062CA31 /* TabBarScrollView.swift in Sources */, - B6B5F5822B024105008DB58A /* DataImportSummaryView.swift in Sources */, - B684121E2B6A1D880092F66A /* ErrorPageHTMLTemplate.swift in Sources */, - 4B957B6E2AC7AE700062CA31 /* BookmarkListTreeControllerDataSource.swift in Sources */, - 4B957B6F2AC7AE700062CA31 /* AddressBarViewController.swift in Sources */, - 4B957B702AC7AE700062CA31 /* Permissions.swift in Sources */, - 4B957B712AC7AE700062CA31 /* TabPreviewWindowController.swift in Sources */, - 4B957B722AC7AE700062CA31 /* NSSizeExtension.swift in Sources */, - 4B957B732AC7AE700062CA31 /* Fire.swift in Sources */, - 1DDC84FD2B8356CE00670238 /* PreferencesDefaultBrowserView.swift in Sources */, - 4B957B742AC7AE700062CA31 /* SyncBookmarksAdapter.swift in Sources */, - B6ABC5982B4861D4008343B9 /* FocusableTextField.swift in Sources */, - 4B957B752AC7AE700062CA31 /* RandomAccessCollectionExtension.swift in Sources */, - 4B957B762AC7AE700062CA31 /* NSOutlineViewExtensions.swift in Sources */, - 4B957B772AC7AE700062CA31 /* AppDelegate.swift in Sources */, - 4B957B782AC7AE700062CA31 /* ContentOverlayViewController.swift in Sources */, - 4B957B792AC7AE700062CA31 /* ContentBlockingTabExtension.swift in Sources */, - 4B957B7A2AC7AE700062CA31 /* OnboardingViewController.swift in Sources */, - B68412292B6A68C90092F66A /* WKBackForwardListItemExtension.swift in Sources */, - 4B957B7B2AC7AE700062CA31 /* DeviceAuthenticator.swift in Sources */, - 4B957B7C2AC7AE700062CA31 /* NetworkProtectionWaitlistFeatureFlagOverridesMenu.swift in Sources */, - 4B957B7D2AC7AE700062CA31 /* TabBarCollectionView.swift in Sources */, - C1DAF3B72B9A44860059244F /* AutofillPopoverPresenter.swift in Sources */, - 4B957B7E2AC7AE700062CA31 /* NetworkProtection+ConvenienceInitializers.swift in Sources */, - 7BA7CC502AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift in Sources */, - 4B957B7F2AC7AE700062CA31 /* NavigationActionExtension.swift in Sources */, - F1B33DF82BAD970E001128B3 /* SubscriptionErrorReporter.swift in Sources */, - 4B957B802AC7AE700062CA31 /* NSAlertExtension.swift in Sources */, - 4B957B812AC7AE700062CA31 /* ThirdPartyBrowser.swift in Sources */, - 4B957B822AC7AE700062CA31 /* SearchNonexistentDomainNavigationResponder.swift in Sources */, - 4B6B64862BA930420009FF9F /* WaitlistThankYouPromptPresenter.swift in Sources */, - B6B71C5A2B23379600487131 /* NSLayoutConstraintExtension.swift in Sources */, - B65211272B29A43000B30633 /* BookmarkStoreMock.swift in Sources */, - 4B957B832AC7AE700062CA31 /* CircularProgressView.swift in Sources */, - 4B957B842AC7AE700062CA31 /* SuggestionContainer.swift in Sources */, - 4B957B852AC7AE700062CA31 /* FindInPageTabExtension.swift in Sources */, - 4B957B862AC7AE700062CA31 /* HomePageViewController.swift in Sources */, - 4B957B882AC7AE700062CA31 /* OperatingSystemVersionExtension.swift in Sources */, - 4B957B892AC7AE700062CA31 /* ToggleableScrollView.swift in Sources */, - 4B957B8A2AC7AE700062CA31 /* TabCleanupPreparer.swift in Sources */, - 4B37EE7B2B4CFF7C00A89A61 /* HomePageRemoteMessagingStorage.swift in Sources */, - 4B957B8B2AC7AE700062CA31 /* NetworkProtectionOptionKeyExtension.swift in Sources */, - 372A0FEE2B2379310033BF7F /* SyncMetricsEventsHandler.swift in Sources */, - 316850702AF3AD1D009A2828 /* WaitlistViewControllerPresenter.swift in Sources */, - 1E2AE4CB2ACB21C800684E0A /* HardwareModel.swift in Sources */, - 4B957B8C2AC7AE700062CA31 /* UserScripts.swift in Sources */, - 4B957B8D2AC7AE700062CA31 /* NSWorkspaceExtension.swift in Sources */, - 4B957B8E2AC7AE700062CA31 /* AutofillTabExtension.swift in Sources */, - 4B957B8F2AC7AE700062CA31 /* Assertions.swift in Sources */, - 4B0EF7282B5780AB009D6481 /* AppVersionExtension.swift in Sources */, - 4B957B902AC7AE700062CA31 /* BookmarkViewModel.swift in Sources */, - 4B957B912AC7AE700062CA31 /* DaxSpeech.swift in Sources */, - BB5789732B2CC0300009DFE2 /* DataBrokerProtectionSubscriptionEventHandler.swift in Sources */, - 4B957B922AC7AE700062CA31 /* DuckURLSchemeHandler.swift in Sources */, - 4B957B932AC7AE700062CA31 /* FirePopoverViewModel.swift in Sources */, - 4B957B942AC7AE700062CA31 /* BWCommand.swift in Sources */, - 4B957B952AC7AE700062CA31 /* NSColorExtension.swift in Sources */, - 4B957B972AC7AE700062CA31 /* AddressBarButtonsViewController.swift in Sources */, - 4B957B982AC7AE700062CA31 /* BWError.swift in Sources */, - 4B957B9A2AC7AE700062CA31 /* PixelDataRecord.swift in Sources */, - 4B957B9B2AC7AE700062CA31 /* PageObserverUserScript.swift in Sources */, - 4B957B9C2AC7AE700062CA31 /* SecureVaultErrorReporter.swift in Sources */, - 4B68DDFF2ACBA14100FB0973 /* FileLineError.swift in Sources */, - 4B957B9D2AC7AE700062CA31 /* NSImageExtensions.swift in Sources */, - 4B957B9E2AC7AE700062CA31 /* WaitlistKeychainStorage.swift in Sources */, - B69A14F82B4D701F00B9417D /* AddBookmarkPopoverViewModel.swift in Sources */, - 4B957B9F2AC7AE700062CA31 /* PasswordManagementViewController.swift in Sources */, - 4B957BA02AC7AE700062CA31 /* ImportedBookmarks.swift in Sources */, - 4B957BA12AC7AE700062CA31 /* UserDefaults+NetworkProtectionShared.swift in Sources */, - 4B957BA22AC7AE700062CA31 /* NavigationActionPolicyExtension.swift in Sources */, - 4B957BA32AC7AE700062CA31 /* CIImageExtension.swift in Sources */, - 9F56CFAB2B82DC4300BB7F11 /* AddEditBookmarkFolderView.swift in Sources */, - 9FA173DC2B79BD8A00EE4E6E /* BookmarkDialogContainerView.swift in Sources */, - 4B957BA42AC7AE700062CA31 /* NSMenuExtension.swift in Sources */, - 4B957BA52AC7AE700062CA31 /* MainWindowController.swift in Sources */, - 4B957BA62AC7AE700062CA31 /* Tab.swift in Sources */, - 4B957BA72AC7AE700062CA31 /* ConnectBitwardenView.swift in Sources */, - 4B957BA82AC7AE700062CA31 /* DispatchQueueExtensions.swift in Sources */, - 4B957BA92AC7AE700062CA31 /* BookmarksBarAppearance.swift in Sources */, - 31C9ADE82AF0564500CEF57D /* WaitlistFeatureSetupHandler.swift in Sources */, - 3158B1472B0BF72E00AF130C /* DBPHomeViewController.swift in Sources */, - 4B957BAA2AC7AE700062CA31 /* PermissionAuthorizationPopover.swift in Sources */, - 4B957BAB2AC7AE700062CA31 /* PopoverMessageViewController.swift in Sources */, - 4B957BAC2AC7AE700062CA31 /* WebView.swift in Sources */, - 4B957BAD2AC7AE700062CA31 /* ShadowView.swift in Sources */, - 4B957BAE2AC7AE700062CA31 /* FeedbackSender.swift in Sources */, - 4B957BAF2AC7AE700062CA31 /* TabExtensions.swift in Sources */, - 4B957BB02AC7AE700062CA31 /* TabBarViewItem.swift in Sources */, - 4B957BB12AC7AE700062CA31 /* NSWindow+Toast.swift in Sources */, - 4B0526652B1D55D80054955A /* VPNFeedbackCategory.swift in Sources */, - 4B957BB22AC7AE700062CA31 /* AutoconsentUserScript.swift in Sources */, - 4B957BB32AC7AE700062CA31 /* BookmarksExporter.swift in Sources */, - 4B957BB42AC7AE700062CA31 /* NetworkProtectionAppEvents.swift in Sources */, - 4B957BB52AC7AE700062CA31 /* FirefoxDataImporter.swift in Sources */, - 4B957BB62AC7AE700062CA31 /* PreferencesGeneralView.swift in Sources */, - 4B957BB72AC7AE700062CA31 /* PinnedTabsView.swift in Sources */, - 4B957BB92AC7AE700062CA31 /* SyncErrorHandler.swift in Sources */, - 4BF0E50A2AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */, - 4B957BBA2AC7AE700062CA31 /* URLExtension.swift in Sources */, - 4B957BBB2AC7AE700062CA31 /* Tab+UIDelegate.swift in Sources */, - 4B957BBD2AC7AE700062CA31 /* NSStoryboardExtension.swift in Sources */, - 4B957BBE2AC7AE700062CA31 /* PreferencesViewController.swift in Sources */, - 4B957BBF2AC7AE700062CA31 /* FireproofDomains.swift in Sources */, - 4B957BC02AC7AE700062CA31 /* Database.swift in Sources */, - 4B957BC12AC7AE700062CA31 /* HorizontallyCenteredLayout.swift in Sources */, - 4B957BC22AC7AE700062CA31 /* BookmarksOutlineView.swift in Sources */, - 4B957BC32AC7AE700062CA31 /* CountryList.swift in Sources */, - 4B957BC42AC7AE700062CA31 /* PreferencesSection.swift in Sources */, - 4B957BC52AC7AE700062CA31 /* NetworkProtectionNavBarButtonModel.swift in Sources */, - 4B957BC62AC7AE700062CA31 /* AutoconsentManagement.swift in Sources */, - 4B957BC72AC7AE700062CA31 /* UserText+NetworkProtection.swift in Sources */, - 4B957BC82AC7AE700062CA31 /* WebViewContainerView.swift in Sources */, - 4B957BC92AC7AE700062CA31 /* BookmarkStore.swift in Sources */, - 4B957BCA2AC7AE700062CA31 /* PrivacyDashboardViewController.swift in Sources */, - 37A6A8F42AFCC988008580A3 /* FaviconsFetcherOnboarding.swift in Sources */, - 4B957BCB2AC7AE700062CA31 /* PreferencesAppearanceView.swift in Sources */, - 4B957BCC2AC7AE700062CA31 /* NSMenuItemExtension.swift in Sources */, - 4B957BCD2AC7AE700062CA31 /* ContiguousBytesExtension.swift in Sources */, - 7B7FCD112BA33B2700C04FBE /* UserDefaults+vpnLegacyUser.swift in Sources */, - 4B957BCE2AC7AE700062CA31 /* AdjacentItemEnumerator.swift in Sources */, - 4B957BCF2AC7AE700062CA31 /* BookmarkDatabase.swift in Sources */, - 4B957BD02AC7AE700062CA31 /* ChromiumKeychainPrompt.swift in Sources */, - 4B957BD12AC7AE700062CA31 /* WKProcessPool+GeolocationProvider.swift in Sources */, - 4B957BD22AC7AE700062CA31 /* RecentlyClosedMenu.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 565E46D92B2725DC0013AC2A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -12363,6 +10662,7 @@ EEC7BE2E2BC6C09500F86835 /* AddressBarKeyboardShortcutsTests.swift in Sources */, EE54F7B32BBFEA49006218DB /* BookmarksAndFavoritesTests.swift in Sources */, EE02D4222BB4611A00DBE6B3 /* TestsURLExtension.swift in Sources */, + EE42CBCC2BC8004700AD411C /* PermissionsTests.swift in Sources */, 7B4CE8E726F02135009134B1 /* TabBarTests.swift in Sources */, EEBCE6832BA463DD00B9DF00 /* NSImageExtensions.swift in Sources */, EEBCE6822BA444FA00B9DF00 /* XCUIElementExtension.swift in Sources */, @@ -12431,11 +10731,13 @@ 31AA6B972B960B870025014E /* DataBrokerProtectionLoginItemPixels.swift in Sources */, B6BF5D852946FFDA006742B1 /* PrivacyDashboardTabExtension.swift in Sources */, B6E3E55B2BC0041900A41922 /* DownloadListStoreMock.swift in Sources */, + 9FA5A0A52BC8F34900153786 /* UserDefaultsBookmarkFoldersStore.swift in Sources */, B6C0B23026E61D630031CB7F /* DownloadListStore.swift in Sources */, 85799C1825DEBB3F0007EC87 /* Logging.swift in Sources */, AAC30A2E268F1EE300D2D9CD /* CrashReportPromptPresenter.swift in Sources */, 1D2DC00629016798008083A1 /* BWCredential.swift in Sources */, EEA3EEB12B24EBD000E8333A /* NetworkProtectionVPNCountryLabelsModel.swift in Sources */, + 316913232BD2B6250051B46D /* DataBrokerProtectionPixelsHandler.swift in Sources */, 37AFCE8727DA334800471A10 /* PreferencesRootView.swift in Sources */, B684590825C9027900DC17B6 /* AppStateChangedPublisher.swift in Sources */, 4B92928F26670D1700AD2C21 /* BookmarkTableCellView.swift in Sources */, @@ -12494,12 +10796,12 @@ 1D26EBAC2B74BECB0002A93F /* NSImageSendable.swift in Sources */, B6B4D1C52B0B3B5400C26286 /* DataImportReportModel.swift in Sources */, 4B92928D26670D1700AD2C21 /* BookmarkOutlineCellView.swift in Sources */, + F18826802BBEB58100D9AC4F /* PrivacyProPixel.swift in Sources */, B604085C274B8FBA00680351 /* UnprotectedDomains.xcdatamodeld in Sources */, 4BB88B5025B7BA2B006F6B06 /* TabInstrumentation.swift in Sources */, 85D33F1225C82EB3002B91A6 /* ConfigurationManager.swift in Sources */, 31F28C4F28C8EEC500119F70 /* YoutubePlayerUserScript.swift in Sources */, 4B41EDAE2B168AFF001EEDF4 /* VPNFeedbackFormViewController.swift in Sources */, - B6A9E48426146AAB0067D1B9 /* PixelParameters.swift in Sources */, AA5FA697275F90C400DCE9C9 /* FaviconImageCache.swift in Sources */, 1430DFF524D0580F00B8978C /* TabBarViewController.swift in Sources */, B62B483E2ADE48DE000DECE5 /* ArrayBuilder.swift in Sources */, @@ -12519,6 +10821,7 @@ B6E3E5542BBFCEE300A41922 /* NoDownloadsCellView.swift in Sources */, 4BBDEE9428FC14760092FAA6 /* ConnectBitwardenViewController.swift in Sources */, 1DDF076428F815AD00EDFBE3 /* BWManager.swift in Sources */, + 560C3FFF2BCD5A1E00F589CE /* PermanentSurveyManager.swift in Sources */, 9833912F27AAA3CE00DAF119 /* AppTrackerDataSetProvider.swift in Sources */, B65211252B29A42C00B30633 /* BookmarkStoreMock.swift in Sources */, 4BA1A6B3258B080A00F6F690 /* EncryptionKeyGeneration.swift in Sources */, @@ -12543,6 +10846,8 @@ 858A798326A8B75F00A75A42 /* CopyHandler.swift in Sources */, 1E7E2E9029029A2A00C01B54 /* ContentBlockingRulesUpdateObserver.swift in Sources */, 4B8AC93926B48A5100879451 /* FirefoxLoginReader.swift in Sources */, + F18826902BC0105800D9AC4F /* PixelDataRecord.swift in Sources */, + F18826912BC0105800D9AC4F /* PixelDataStore.swift in Sources */, B69B503E2726A12500758A2B /* AtbParser.swift in Sources */, 37F19A6528E1B3FB00740DC6 /* PreferencesDuckPlayerView.swift in Sources */, 4B92929E26670D2A00AD2C21 /* BookmarkSidebarTreeController.swift in Sources */, @@ -12571,6 +10876,7 @@ 4B379C2227BDBA29008A968E /* LocalAuthenticationService.swift in Sources */, 37CEFCA92A6737A2001EF741 /* CredentialsCleanupErrorHandling.swift in Sources */, 4BB99D0326FE191E001E4761 /* SafariBookmarksReader.swift in Sources */, + 316913292BD2C7570051B46D /* DataBrokerProtectionErrorViewController.swift in Sources */, 1DA6D0FD2A1FF9A100540406 /* HTTPCookie.swift in Sources */, AACF6FD626BC366D00CF09F9 /* SafariVersionReader.swift in Sources */, 4BE65485271FCD7B008D1D63 /* LoginFaviconView.swift in Sources */, @@ -12723,7 +11029,6 @@ B68412142B694BA10092F66A /* NSObject+performSelector.m in Sources */, B6F41031264D2B23003DA42C /* ProgressExtension.swift in Sources */, 4B723E0F26B0006500E14D75 /* CSVParser.swift in Sources */, - B6DA44082616B30600DD1EC2 /* PixelDataModel.xcdatamodeld in Sources */, B63BDF7E27FDAA640072D75B /* PrivacyDashboardWebView.swift in Sources */, 37CD54CF27F2FDD100F1F7B9 /* AppearancePreferences.swift in Sources */, B6B1E87B26D381710062C350 /* DownloadListCoordinator.swift in Sources */, @@ -12803,6 +11108,7 @@ 85707F2A276A35FE00DC0649 /* ActionSpeech.swift in Sources */, B6BE9FAA293F7955006363C6 /* ModalSheetCancellable.swift in Sources */, B6830963274CDEC7004B46BB /* FireproofDomainsStore.swift in Sources */, + F188268D2BBF01C300D9AC4F /* PixelDataModel.xcdatamodeld in Sources */, 7B430EA12A71411A00BAC4A1 /* NetworkProtectionSimulateFailureMenu.swift in Sources */, 1E7E2E942902AC0E00C01B54 /* PrivacyDashboardPermissionHandler.swift in Sources */, AA9FF95F24A1FB690039E328 /* TabCollectionViewModel.swift in Sources */, @@ -12810,6 +11116,7 @@ 4BF0E5052AD2551A00FFEC9E /* NetworkProtectionPixelEvent.swift in Sources */, AAC5E4D125D6A709007F5990 /* BookmarkManager.swift in Sources */, 37CD54CD27F2FDD100F1F7B9 /* AboutModel.swift in Sources */, + B6F1B0262BCE5A50005E863C /* TabContent.swift in Sources */, 4BE65476271FCD41008D1D63 /* PasswordManagementCreditCardItemView.swift in Sources */, AA5C8F59258FE21F00748EB7 /* NSTextFieldExtension.swift in Sources */, 3706FEC8293F6F7500E42796 /* BWManagement.swift in Sources */, @@ -12832,6 +11139,7 @@ B6DE57F62B05EA9000CD54B9 /* SheetHostingWindow.swift in Sources */, AA6EF9B525081B4C004754E6 /* MainMenuActions.swift in Sources */, B63D466925BEB6C200874977 /* WKWebView+SessionState.swift in Sources */, + B6F1B0222BCE5658005E863C /* BrokenSiteInfoTabExtension.swift in Sources */, 4B4D60C02A0C848D00BCD287 /* NetworkProtectionControllerErrorStore.swift in Sources */, 4B723E1226B0006E00E14D75 /* DataImport.swift in Sources */, 7BE146072A6A83C700C313B8 /* NetworkProtectionDebugMenu.swift in Sources */, @@ -12849,6 +11157,7 @@ 85D885B326A5A9DE0077C374 /* NSAlert+PasswordManager.swift in Sources */, 983DFB2528B67036006B7E34 /* UserContentUpdating.swift in Sources */, 1D9A4E5A2B43213B00F449E2 /* TabSnapshotExtension.swift in Sources */, + 316913262BD2B76F0051B46D /* DataBrokerPrerequisitesStatusVerifier.swift in Sources */, 4B7A57CF279A4EF300B1C70E /* ChromiumPreferences.swift in Sources */, AA6AD95B2704B6DB00159F8A /* FirePopoverViewController.swift in Sources */, 4BE4005327CF3DC3007D3161 /* SavePaymentMethodPopover.swift in Sources */, @@ -12858,6 +11167,7 @@ AA6FFB4424DC33320028F4D0 /* NSViewExtension.swift in Sources */, B6C0B23E26E8BF1F0031CB7F /* DownloadListViewModel.swift in Sources */, 4B9292D52667123700AD2C21 /* BookmarkManagementDetailViewController.swift in Sources */, + F188267C2BBEB3AA00D9AC4F /* GeneralPixel.swift in Sources */, 4B723E1026B0006700E14D75 /* CSVImporter.swift in Sources */, 37A4CEBA282E992F00D75B89 /* StartupPreferences.swift in Sources */, 4B41EDB12B168B1E001EEDF4 /* VPNFeedbackFormView.swift in Sources */, @@ -12871,7 +11181,6 @@ 4B41EDA32B1543B9001EEDF4 /* VPNPreferencesModel.swift in Sources */, AA61C0D22727F59B00E6B681 /* ArrayExtension.swift in Sources */, 4B4D60CC2A0C849600BCD287 /* NetworkProtectionInviteCodeViewModel.swift in Sources */, - AAC30A2C268F1ECD00D2D9CD /* CrashReportSender.swift in Sources */, 373A1AB02842C4EA00586521 /* BookmarkHTMLImporter.swift in Sources */, B6B5F57F2B024105008DB58A /* DataImportSummaryView.swift in Sources */, 31C3CE0228EDC1E70002C24A /* CustomRoundedCornersShape.swift in Sources */, @@ -12907,7 +11216,6 @@ B65783E725F8AAFB00D8DB33 /* String+Punycode.swift in Sources */, B657841A25FA484B00D8DB33 /* NSException+Catch.m in Sources */, B684592F25C93FBF00DC17B6 /* AppStateRestorationManager.swift in Sources */, - 4B67853F2AA7C726008A5004 /* DailyPixel.swift in Sources */, B66260E629ACAE4B00E9E3EE /* NavigationHotkeyHandler.swift in Sources */, EA0BA3A9272217E6002A0B6C /* ClickToLoadUserScript.swift in Sources */, AAA892EA250A4CEF005B37B2 /* WindowControllersManager.swift in Sources */, @@ -12931,14 +11239,12 @@ AAD86E52267A0DFF005C11BE /* UpdateController.swift in Sources */, 85A0118225AF60E700FA6A0C /* FindInPageModel.swift in Sources */, 7BA7CC4E2AD11F6F0042E5CE /* NetworkProtectionIPCTunnelController.swift in Sources */, + 9F9C49FD2BC7E9830099738D /* BookmarkAllTabsDialogViewModel.swift in Sources */, 4B9292A226670D2A00AD2C21 /* PseudoFolder.swift in Sources */, 1DDD3EC42B84F96B004CBF2B /* CookiePopupProtectionPreferences.swift in Sources */, 4BCF15D92ABB8A7F0083F6DF /* NetworkProtectionRemoteMessage.swift in Sources */, 4B05265E2B1AE5C70054955A /* VPNMetadataCollector.swift in Sources */, - B6DA44022616B28300DD1EC2 /* PixelDataStore.swift in Sources */, 4B9DB0292A983B24000927DB /* WaitlistStorage.swift in Sources */, - B6A9E45326142B070067D1B9 /* Pixel.swift in Sources */, - B6A9E47726146A570067D1B9 /* PixelEvent.swift in Sources */, AA2CB1352587C29500AA6FBE /* TabBarFooter.swift in Sources */, EEC111E6294D06290086524F /* JSAlertViewModel.swift in Sources */, 4BE5336C286912D40019DBFD /* BookmarksBarCollectionViewItem.swift in Sources */, @@ -12952,6 +11258,7 @@ B6C0B23426E71BCD0031CB7F /* Downloads.xcdatamodeld in Sources */, 9FBD84732BB3E15D00220859 /* InstallationAttributionPixelHandler.swift in Sources */, AAE8B110258A456C00E81239 /* TabPreviewViewController.swift in Sources */, + B6F1B02A2BCE675C005E863C /* NetworkProtectionControllerTabExtension.swift in Sources */, B6C8CAA72AD010DD0060E1CD /* YandexDataImporter.swift in Sources */, EE66666F2B56EDE4001D898D /* VPNLocationsHostingViewController.swift in Sources */, 37CC53EC27E8A4D10028713D /* PreferencesDataClearingView.swift in Sources */, @@ -13022,6 +11329,7 @@ B693955726F04BEC0015B914 /* MouseOverButton.swift in Sources */, AA61C0D02722159B00E6B681 /* FireInfoViewController.swift in Sources */, 9D9AE8692AA76CDC0026E7DC /* LoginItem+NetworkProtection.swift in Sources */, + 9F9C49F92BC7BC970099738D /* BookmarkAllTabsDialogView.swift in Sources */, B64C85422694590B0048FEBE /* PermissionButton.swift in Sources */, AAA0CC472533833C0079BC96 /* MoreOptionsMenu.swift in Sources */, B64C84E32692DC9F0048FEBE /* PermissionAuthorizationViewController.swift in Sources */, @@ -13039,7 +11347,6 @@ F1B33DF62BAD970E001128B3 /* SubscriptionErrorReporter.swift in Sources */, EEC589D92A4F1CE300BCD60C /* AppLauncher.swift in Sources */, 4BA1A69B258B076900F6F690 /* FileStore.swift in Sources */, - B6A9E47F26146A800067D1B9 /* PixelArguments.swift in Sources */, 1D01A3D02B88CEC600FE8150 /* PreferencesAccessibilityView.swift in Sources */, 37BF3F21286F0A7A00BD9014 /* PinnedTabsViewModel.swift in Sources */, EEC4A6692B2C87D300F7C0AA /* VPNLocationView.swift in Sources */, @@ -13084,6 +11391,7 @@ 1456D6E124EFCBC300775049 /* TabBarCollectionView.swift in Sources */, 4B4D60BF2A0C848A00BCD287 /* NetworkProtection+ConvenienceInitializers.swift in Sources */, 4B6B64842BA930420009FF9F /* WaitlistThankYouPromptPresenter.swift in Sources */, + BDA7647C2BC497BE00D0400C /* DefaultVPNLocationFormatter.swift in Sources */, 3158B1592B0BF76400AF130C /* DataBrokerProtectionFeatureDisabler.swift in Sources */, B655124829A79465009BFE1C /* NavigationActionExtension.swift in Sources */, 9FA173EB2B7B232200EE4E6E /* AddEditBookmarkDialogView.swift in Sources */, @@ -13113,11 +11421,12 @@ F41D174125CB131900472416 /* NSColorExtension.swift in Sources */, AAC5E4F625D6BF2C007F5990 /* AddressBarButtonsViewController.swift in Sources */, B6F9BDE42B45CD1900677B33 /* ModalView.swift in Sources */, + F18826842BBEE31700D9AC4F /* PixelKit+Assertion.swift in Sources */, 1D2DC0072901679C008083A1 /* BWError.swift in Sources */, - B68C92C42750EF76002AC6B0 /* PixelDataRecord.swift in Sources */, 853014D625E671A000FB8205 /* PageObserverUserScript.swift in Sources */, B677FC4F2B06376B0099EB04 /* ReportFeedbackView.swift in Sources */, - B642738227B65BAC0005DFD1 /* SecureVaultErrorReporter.swift in Sources */, + B642738227B65BAC0005DFD1 /* SecureVaultReporter.swift in Sources */, + 9F9C4A012BC7F36D0099738D /* BookmarkAllTabsDialogCoordinatorViewModel.swift in Sources */, 4B139AFD26B60BD800894F82 /* NSImageExtensions.swift in Sources */, B62B48392ADE46FC000DECE5 /* Application.swift in Sources */, 4B9DB02C2A983B24000927DB /* WaitlistKeychainStorage.swift in Sources */, @@ -13154,6 +11463,7 @@ 37FD78112A29EBD100B36DB1 /* SyncErrorHandler.swift in Sources */, AA8EDF2424923E980071C2E8 /* URLExtension.swift in Sources */, B634DBDF293C8F7F00C3C99E /* Tab+UIDelegate.swift in Sources */, + B6F1B02E2BCE6B47005E863C /* TunnelControllerProvider.swift in Sources */, 4BE0DF06267819A1006337B7 /* NSStoryboardExtension.swift in Sources */, 37AFCE8127DA2CA600471A10 /* PreferencesViewController.swift in Sources */, 4B02198A25E05FAC00ED7DEA /* FireproofDomains.swift in Sources */, @@ -13202,8 +11512,8 @@ 4B9DB05A2A983B55000927DB /* MockWaitlistRequest.swift in Sources */, 37D2377C287EBDA300BCE03B /* TabIndexTests.swift in Sources */, 37534CA52811987D002621E7 /* AdjacentItemEnumeratorTests.swift in Sources */, - B6DA44232616CABC00DD1EC2 /* PixelArgumentsTests.swift in Sources */, 56B234BF2A84EFD200F2A1CC /* NavigationBarUrlExtensionsTests.swift in Sources */, + 9FAD623A2BCFDB32007F3A65 /* WebsiteInfoHelpers.swift in Sources */, C13909F42B85FD79001626ED /* AutofillDeleteAllPasswordsExecutorTests.swift in Sources */, 37534C9E28104D9B002621E7 /* TabLazyLoaderTests.swift in Sources */, B6619EF62B10DFF700CD9186 /* InstructionsFormatParserTests.swift in Sources */, @@ -13213,6 +11523,7 @@ 4B9292BD2667103100AD2C21 /* BookmarkOutlineViewDataSourceTests.swift in Sources */, C17CA7B22B9B5317008EC3C1 /* MockAutofillPopoverPresenter.swift in Sources */, 4BF6961D28BE911100D402D4 /* RecentlyVisitedSiteModelTests.swift in Sources */, + 9FA5A0A92BC900FC00153786 /* BookmarkAllTabsDialogViewModelTests.swift in Sources */, B6619F062B17138D00CD9186 /* DataImportSourceViewModelTests.swift in Sources */, 4BBF0917282DD6EF00EE1418 /* TemporaryFileHandlerTests.swift in Sources */, B6A5A27925B93FFF00AA7ADA /* StateRestorationManagerTests.swift in Sources */, @@ -13261,6 +11572,7 @@ 858A798826A99DBE00A75A42 /* PasswordManagementItemListModelTests.swift in Sources */, 566B196529CDB828007E38F4 /* CapturingOptionsButtonMenuDelegate.swift in Sources */, 4B8AD0B127A86D9200AE44D6 /* WKWebsiteDataStoreExtensionTests.swift in Sources */, + 9FA5A0B02BC9039200153786 /* BookmarkFolderStoreMock.swift in Sources */, B69B50472726C5C200758A2B /* VariantManagerTests.swift in Sources */, 8546DE6225C03056000CA5E1 /* UserAgentTests.swift in Sources */, 9F26060B2B85C20A00819292 /* AddEditBookmarkDialogViewModelTests.swift in Sources */, @@ -13277,16 +11589,18 @@ 85AC3B4925DAC9BD00C7D2AA /* ConfigurationStorageTests.swift in Sources */, 9F180D122B69C665000D695F /* DownloadsTabExtensionMock.swift in Sources */, AA91F83927076F1900771A0D /* PrivacyIconViewModelTests.swift in Sources */, + 9F9C49F62BC786790099738D /* MoreOptionsMenu+BookmarksTests.swift in Sources */, 4B723E0726B0003E00E14D75 /* CSVImporterTests.swift in Sources */, 4BCF15EC2ABB9AF80083F6DF /* NetworkProtectionRemoteMessageTests.swift in Sources */, B62EB47C25BAD3BB005745C6 /* WKWebViewPrivateMethodsAvailabilityTests.swift in Sources */, + 9F0FFFBB2BCCAEC2007C87DD /* AddEditBookmarkFolderDialogViewModelMock.swift in Sources */, 4BBC16A527C488C900E00A38 /* DeviceAuthenticatorTests.swift in Sources */, 4B3F641E27A8D3BD00E0C118 /* BrowserProfileTests.swift in Sources */, B6106BA026A7BE0B0013B453 /* PermissionManagerTests.swift in Sources */, 4B59CC8C290083240058F2F6 /* ConnectBitwardenViewModelTests.swift in Sources */, B68412202B6A30680092F66A /* StringExtensionTests.swift in Sources */, - B662D3D92755D7AD0035D4D6 /* PixelStoreTests.swift in Sources */, B6106BB526A809E60013B453 /* GeolocationProviderTests.swift in Sources */, + BDA764912BC4E57200D0400C /* MockVPNLocationFormatter.swift in Sources */, B6E6BA232BA2EDDE008AA7E1 /* FileReadResult.swift in Sources */, B6A5A2A025B96E8300AA7ADA /* AppStateChangePublisherTests.swift in Sources */, B63ED0E326B3E7FA00A9DAD1 /* CLLocationManagerMock.swift in Sources */, @@ -13312,6 +11626,7 @@ 142879DC24CE1185005419BB /* SuggestionContainerViewModelTests.swift in Sources */, 566B195D29CDB692007E38F4 /* MoreOptionsMenuTests.swift in Sources */, AA0877B826D5160D00B05660 /* SafariVersionReaderTests.swift in Sources */, + 31DC2F222BD6DE6C001354EF /* DataBrokerPrerequisitesStatusVerifierTests.swift in Sources */, B69B50452726C5C200758A2B /* AtbParserTests.swift in Sources */, 1D8C2FED2B70F5D0005E4BBD /* MockViewSnapshotRenderer.swift in Sources */, B6106BAF26A7C6180013B453 /* PermissionStoreMock.swift in Sources */, @@ -13325,12 +11640,14 @@ AAE39D1B24F44885008EF28B /* TabCollectionViewModelDelegateMock.swift in Sources */, 9F0A2CF82B96A58600C5B8C0 /* BaseBookmarkEntityTests.swift in Sources */, 373A1AAA283ED86C00586521 /* BookmarksHTMLReaderTests.swift in Sources */, + 560C3FFC2BC9911000F589CE /* PermanentSurveyManagerTests.swift in Sources */, 317295D42AF058D3002C3206 /* MockWaitlistFeatureSetupHandler.swift in Sources */, 9FBD84772BB3E54200220859 /* InstallationAttributionPixelHandlerTests.swift in Sources */, AA9C363025518CA9004B1BA3 /* FireTests.swift in Sources */, B6106BB126A7D8720013B453 /* PermissionStoreTests.swift in Sources */, 4BF4951826C08395000547B8 /* ThirdPartyBrowserTests.swift in Sources */, 4B98D27C28D960DD003C2B6F /* FirefoxFaviconsReaderTests.swift in Sources */, + 9F0FFFBE2BCCAF1F007C87DD /* BookmarkAllTabsDialogViewModelMock.swift in Sources */, B60C6F7E29B1B41D007BFAA8 /* TestRunHelperInitializer.m in Sources */, 37479F152891BC8300302FE2 /* TabCollectionViewModelTests+WithoutPinnedTabsManager.swift in Sources */, AA63745424C9BF9A00AB2AC4 /* SuggestionContainerTests.swift in Sources */, @@ -13360,12 +11677,12 @@ C1E961EB2B879E79001760E1 /* MockAutofillActionPresenter.swift in Sources */, 4BA1A6FE258C5C1300F6F690 /* EncryptedValueTransformerTests.swift in Sources */, 85F69B3C25EDE81F00978E59 /* URLExtensionTests.swift in Sources */, - B6DA44112616C0FC00DD1EC2 /* PixelTests.swift in Sources */, 4B9292BA2667103100AD2C21 /* BookmarkNodePathTests.swift in Sources */, 4B9292C02667103100AD2C21 /* BookmarkManagedObjectTests.swift in Sources */, 373A1AB228451ED400586521 /* BookmarksHTMLImporterTests.swift in Sources */, 4B723E0626B0003E00E14D75 /* CSVParserTests.swift in Sources */, B60C6F8429B1BAD3007BFAA8 /* FileManagerTempDirReplacement.swift in Sources */, + BDA7648D2BC4E4EF00D0400C /* DefaultVPNLocationFormatterTests.swift in Sources */, 85F487B5276A8F2E003CE668 /* OnboardingTests.swift in Sources */, B626A7642992506A00053070 /* SerpHeadersNavigationResponderTests.swift in Sources */, AA652CCE25DD9071009059CC /* BookmarkListTests.swift in Sources */, @@ -13382,7 +11699,9 @@ AABAF59C260A7D130085060C /* FaviconManagerMock.swift in Sources */, 1DFAB5222A8983DE00A0F7F6 /* SetExtensionTests.swift in Sources */, 4BF6962028BEEE8B00D402D4 /* LocalPinningManagerTests.swift in Sources */, + 9F0FFFB82BCCAE9C007C87DD /* AddEditBookmarkDialogViewModelMock.swift in Sources */, AAEC74B82642E43800C2EFBC /* HistoryStoreTests.swift in Sources */, + 9FAD623D2BD09DE5007F3A65 /* WebsiteInfoTests.swift in Sources */, 9F180D0F2B69C553000D695F /* Tab+WKUIDelegateTests.swift in Sources */, 4BA1A6E6258C270800F6F690 /* EncryptionKeyGeneratorTests.swift in Sources */, B6106BB326A7F4AA0013B453 /* GeolocationServiceMock.swift in Sources */, @@ -13391,6 +11710,7 @@ 4BBF09232830812900EE1418 /* FileSystemDSL.swift in Sources */, 4B9DB05C2A983B55000927DB /* WaitlistViewModelTests.swift in Sources */, 1D1C36E329FAE8DA001FA40C /* FaviconManagerTests.swift in Sources */, + 9F0FFFB42BCCAE37007C87DD /* BookmarkAllTabsDialogCoordinatorViewModelTests.swift in Sources */, 4B723E0526B0003E00E14D75 /* DataImportMocks.swift in Sources */, 4B70C00227B0793D000386ED /* CrashReportTests.swift in Sources */, B6656E0D2B29C733008798A1 /* FileImportViewLocalizationTests.swift in Sources */, @@ -13408,7 +11728,6 @@ B698E5042908011E00A746A8 /* AppKitPrivateMethodsAvailabilityTests.swift in Sources */, 56D145EE29E6DAD900E3488A /* DataImportProviderTests.swift in Sources */, 4BB99D0F26FE1A84001E4761 /* ChromiumBookmarksReaderTests.swift in Sources */, - 4BC2621D293996410087A482 /* PixelEventTests.swift in Sources */, 1D9FDEB72B9B5D150040B78C /* SearchPreferencesTests.swift in Sources */, 1D12F2E2298BC660009A65FD /* InternalUserDeciderStoreMock.swift in Sources */, 4BB99D1026FE1A84001E4761 /* FirefoxBookmarksReaderTests.swift in Sources */, @@ -13426,6 +11745,7 @@ 9FBD84562BB3ACFD00220859 /* AttributionOriginFileProviderTests.swift in Sources */, 31E163BA293A56F400963C10 /* BrokenSiteReportingReferenceTests.swift in Sources */, 1D9FDEC32B9B63C90040B78C /* DataClearingPreferencesTests.swift in Sources */, + 9F8D57322BCCCB9A00AEA660 /* UserDefaultsBookmarkFoldersStoreTests.swift in Sources */, 4B723E0826B0003E00E14D75 /* MockSecureVault.swift in Sources */, 37CD54B527F1AC1300F1F7B9 /* PreferencesSidebarModelTests.swift in Sources */, B6CA4824298CDC2E0067ECCE /* AdClickAttributionTabExtensionTests.swift in Sources */, @@ -13482,11 +11802,6 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 31C6E9AB2B0C07A30086DC30 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 9D9AE8B22AAA39A70026E7DC /* DuckDuckGoDBPBackgroundAgent */; - targetProxy = 31C6E9AA2B0C07A30086DC30 /* PBXContainerItemProxy */; - }; 31C6E9AD2B0C07BA0086DC30 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 9D9AE8B22AAA39A70026E7DC /* DuckDuckGoDBPBackgroundAgent */; @@ -13523,10 +11838,6 @@ isa = PBXTargetDependency; productRef = 4B5F14FD2A1529230060320F /* InputFilesChecker */; }; - 4B9579262AC7AE700062CA31 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = 4B5F14FB2A15291D0060320F /* InputFilesChecker */; - }; 4BA7C4DF2B3F6F4900AFE511 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 4B4D603C2A0B290200BCD287 /* NetworkProtectionAppExtension */; @@ -13557,50 +11868,6 @@ target = 4B2537592A11BE7300610219 /* NetworkProtectionSystemExtension */; targetProxy = 7BEC18302AD5DA3300D30536 /* PBXContainerItemProxy */; }; - B6080B9D2B20AF7700B418EF /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = B6F997BA2B8F353F00476735 /* SwiftLintPlugin */; - }; - B6080B9F2B20AF7B00B418EF /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = B6F997BA2B8F353F00476735 /* SwiftLintPlugin */; - }; - B6080BA12B20AF7F00B418EF /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = B6F997BA2B8F353F00476735 /* SwiftLintPlugin */; - }; - B6080BA32B20AF8300B418EF /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = B6F997BA2B8F353F00476735 /* SwiftLintPlugin */; - }; - B6080BA52B20AF8800B418EF /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = B6F997BA2B8F353F00476735 /* SwiftLintPlugin */; - }; - B6080BA92B20AF8F00B418EF /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = B6F997BA2B8F353F00476735 /* SwiftLintPlugin */; - }; - B6080BAB2B20AF9200B418EF /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = B6F997BA2B8F353F00476735 /* SwiftLintPlugin */; - }; - B69D06142A4C0AC50032D14D /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = B6F997BA2B8F353F00476735 /* SwiftLintPlugin */; - }; - B69D06162A4C0ACD0032D14D /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = B6F997BA2B8F353F00476735 /* SwiftLintPlugin */; - }; - B69D061A2A4C0AD80032D14D /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = B6F997BA2B8F353F00476735 /* SwiftLintPlugin */; - }; - B69D061C2A4C0BC10032D14D /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = B6F997BA2B8F353F00476735 /* SwiftLintPlugin */; - }; B6AEB5552BA3042300781A09 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B6E6B9F22BA1FD90008AA7E1 /* sandbox-test-tool */; @@ -13631,22 +11898,6 @@ target = B6EC37E729B5DA2A001ACE79 /* tests-server */; targetProxy = B6EC37F329B5DA94001ACE79 /* PBXContainerItemProxy */; }; - B6F997BB2B8F353F00476735 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = B6F997BA2B8F353F00476735 /* SwiftLintPlugin */; - }; - B6F997BD2B8F35EF00476735 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = B6F997BC2B8F35EF00476735 /* SwiftLintPlugin */; - }; - B6F997BF2B8F35F400476735 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = B6F997BE2B8F35F400476735 /* SwiftLintPlugin */; - }; - B6F997C12B8F35F800476735 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - productRef = B6F997C02B8F35F800476735 /* SwiftLintPlugin */; - }; EE02D41E2BB460B500DBE6B3 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B6EC37E729B5DA2A001ACE79 /* tests-server */; @@ -13960,34 +12211,6 @@ }; name = Review; }; - 4B957C3D2AC7AE700062CA31 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4B957C432AC7AF190062CA31 /* DuckDuckGoPrivacyPro.xcconfig */; - buildSettings = { - }; - name = Debug; - }; - 4B957C3E2AC7AE700062CA31 /* CI */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4B957C432AC7AF190062CA31 /* DuckDuckGoPrivacyPro.xcconfig */; - buildSettings = { - }; - name = CI; - }; - 4B957C3F2AC7AE700062CA31 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4B957C432AC7AF190062CA31 /* DuckDuckGoPrivacyPro.xcconfig */; - buildSettings = { - }; - name = Release; - }; - 4B957C402AC7AE700062CA31 /* Review */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4B957C432AC7AF190062CA31 /* DuckDuckGoPrivacyPro.xcconfig */; - buildSettings = { - }; - name = Review; - }; 565E46E62B2725DD0013AC2A /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 376113C52B29BCD600E794BB /* SyncE2EUITests.xcconfig */; @@ -14367,17 +12590,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4B957C3C2AC7AE700062CA31 /* Build configuration list for PBXNativeTarget "DuckDuckGo Privacy Pro" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 4B957C3D2AC7AE700062CA31 /* Debug */, - 4B957C3E2AC7AE700062CA31 /* CI */, - 4B957C3F2AC7AE700062CA31 /* Release */, - 4B957C402AC7AE700062CA31 /* Review */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 565E46E52B2725DD0013AC2A /* Build configuration list for PBXNativeTarget "SyncE2EUITests" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -14515,28 +12727,20 @@ version = 3.1.4000; }; }; - 4B95792A2AC7AE700062CA31 /* XCRemoteSwiftPackageReference "Sparkle" */ = { + 3FFD51CF7C19ACBDB9687474 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */ = { isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/sparkle-project/Sparkle.git"; + repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit"; requirement = { kind = exactVersion; - version = 2.4.2; + version = 138.0.0; }; }; - 4B95792C2AC7AE700062CA31 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */ = { + 4311906792B7676CE9535D76 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit"; requirement = { kind = revision; - revision = ffdf1872798f23de073586d4b609b349093a0755; - }; - }; - 4B9579392AC7AE700062CA31 /* XCRemoteSwiftPackageReference "OpenSSL-XCFramework" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/duckduckgo/OpenSSL-XCFramework"; - requirement = { - kind = exactVersion; - version = 3.1.2000; + revision = c06709ba8a586f6a40190bacaaaaa96b2d55e540; }; }; 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */ = { @@ -14544,7 +12748,7 @@ repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit"; requirement = { kind = exactVersion; - version = 134.0.1; + version = 140.0.1; }; }; 9FF521422BAA8FF300B9819B /* XCRemoteSwiftPackageReference "lottie-spm" */ = { @@ -14560,7 +12764,7 @@ repositoryURL = "https://github.com/sparkle-project/Sparkle.git"; requirement = { kind = exactVersion; - version = 2.5.2; + version = 2.6.0; }; }; B65CD8C92B316DF100A595BB /* XCRemoteSwiftPackageReference "swift-snapshot-testing" */ = { @@ -14592,7 +12796,7 @@ repositoryURL = "https://github.com/duckduckgo/apple-toolbox.git"; requirement = { kind = exactVersion; - version = 2.0.0; + version = 3.1.1; }; }; F1D43AF12B98E47800BAB743 /* XCRemoteSwiftPackageReference "BareBonesBrowser" */ = { @@ -14603,17 +12807,21 @@ version = 0.1.0; }; }; + FAE06B199CA1F209B55B34E9 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/duckduckgo/BrowserServicesKit"; + requirement = { + kind = exactVersion; + version = 137.0.0; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - 1E0068AC2B1673BB00BBF43B /* SubscriptionUI */ = { + 08D4923DC968236E22E373E2 /* Crashes */ = { isa = XCSwiftPackageProductDependency; - productName = SubscriptionUI; - }; - 1E21F8E22B73E48600FB272E /* Subscription */ = { - isa = XCSwiftPackageProductDependency; - package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = Subscription; + package = FAE06B199CA1F209B55B34E9 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = Crashes; }; 1E950E3E2912A10D0051A99B /* ContentBlocking */ = { isa = XCSwiftPackageProductDependency; @@ -14643,10 +12851,6 @@ isa = XCSwiftPackageProductDependency; productName = DataBrokerProtection; }; - 3143C8782B0D1F3D00382627 /* DataBrokerProtection */ = { - isa = XCSwiftPackageProductDependency; - productName = DataBrokerProtection; - }; 315A023E2B6421AE00BFA577 /* Networking */ = { isa = XCSwiftPackageProductDependency; package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; @@ -14705,11 +12909,6 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = TestUtils; }; - 372217832B33380E00B8E9C2 /* TestUtils */ = { - isa = XCSwiftPackageProductDependency; - package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = TestUtils; - }; 37269EFA2B332F9E005E8E46 /* Common */ = { isa = XCSwiftPackageProductDependency; package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; @@ -14730,11 +12929,6 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = Common; }; - 37269F022B332FD8005E8E46 /* Common */ = { - isa = XCSwiftPackageProductDependency; - package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = Common; - }; 37269F042B3332C2005E8E46 /* Common */ = { isa = XCSwiftPackageProductDependency; package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; @@ -14750,18 +12944,10 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = DDGSync; }; - 373FB4B02B4D6C42004C88D6 /* PreferencesViews */ = { - isa = XCSwiftPackageProductDependency; - productName = PreferencesViews; - }; 373FB4B22B4D6C4B004C88D6 /* PreferencesViews */ = { isa = XCSwiftPackageProductDependency; productName = PreferencesViews; }; - 373FB4B42B4D6C57004C88D6 /* PreferencesViews */ = { - isa = XCSwiftPackageProductDependency; - productName = PreferencesViews; - }; 378F44E329B4BDE900899924 /* SwiftUIExtensions */ = { isa = XCSwiftPackageProductDependency; productName = SwiftUIExtensions; @@ -14798,10 +12984,6 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = Navigation; }; - 4B2537762A11BFE100610219 /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; 4B2D062B2A11C0E100DE1F49 /* Networking */ = { isa = XCSwiftPackageProductDependency; package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; @@ -14823,10 +13005,6 @@ isa = XCSwiftPackageProductDependency; productName = NetworkProtection; }; - 4B4D60972A0B2A5C00BCD287 /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; 4B4D60AE2A0C837F00BCD287 /* Networking */ = { isa = XCSwiftPackageProductDependency; package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; @@ -14844,95 +13022,6 @@ isa = XCSwiftPackageProductDependency; productName = "plugin:InputFilesChecker"; }; - 4B81AD342B29512B00706C96 /* PixelKitTestingUtilities */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKitTestingUtilities; - }; - 4B81AD362B29513100706C96 /* PixelKitTestingUtilities */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKitTestingUtilities; - }; - 4B9579292AC7AE700062CA31 /* Sparkle */ = { - isa = XCSwiftPackageProductDependency; - package = 4B95792A2AC7AE700062CA31 /* XCRemoteSwiftPackageReference "Sparkle" */; - productName = Sparkle; - }; - 4B95792B2AC7AE700062CA31 /* BrowserServicesKit */ = { - isa = XCSwiftPackageProductDependency; - package = 4B95792C2AC7AE700062CA31 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = BrowserServicesKit; - }; - 4B95792E2AC7AE700062CA31 /* ContentBlocking */ = { - isa = XCSwiftPackageProductDependency; - package = 4B95792C2AC7AE700062CA31 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = ContentBlocking; - }; - 4B95792F2AC7AE700062CA31 /* PrivacyDashboard */ = { - isa = XCSwiftPackageProductDependency; - package = 4B95792C2AC7AE700062CA31 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = PrivacyDashboard; - }; - 4B9579302AC7AE700062CA31 /* UserScript */ = { - isa = XCSwiftPackageProductDependency; - package = 4B95792C2AC7AE700062CA31 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = UserScript; - }; - 4B9579312AC7AE700062CA31 /* Persistence */ = { - isa = XCSwiftPackageProductDependency; - package = 4B95792C2AC7AE700062CA31 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = Persistence; - }; - 4B9579322AC7AE700062CA31 /* Configuration */ = { - isa = XCSwiftPackageProductDependency; - package = 4B95792C2AC7AE700062CA31 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = Configuration; - }; - 4B9579332AC7AE700062CA31 /* Navigation */ = { - isa = XCSwiftPackageProductDependency; - package = 4B95792C2AC7AE700062CA31 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = Navigation; - }; - 4B9579342AC7AE700062CA31 /* Bookmarks */ = { - isa = XCSwiftPackageProductDependency; - package = 4B95792C2AC7AE700062CA31 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = Bookmarks; - }; - 4B9579352AC7AE700062CA31 /* DDGSync */ = { - isa = XCSwiftPackageProductDependency; - package = 4B95792C2AC7AE700062CA31 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = DDGSync; - }; - 4B9579362AC7AE700062CA31 /* SyncUI */ = { - isa = XCSwiftPackageProductDependency; - productName = SyncUI; - }; - 4B9579372AC7AE700062CA31 /* SwiftUIExtensions */ = { - isa = XCSwiftPackageProductDependency; - productName = SwiftUIExtensions; - }; - 4B9579382AC7AE700062CA31 /* OpenSSL */ = { - isa = XCSwiftPackageProductDependency; - package = 4B9579392AC7AE700062CA31 /* XCRemoteSwiftPackageReference "OpenSSL-XCFramework" */; - productName = OpenSSL; - }; - 4B95793C2AC7AE700062CA31 /* SyncDataProviders */ = { - isa = XCSwiftPackageProductDependency; - package = 4B95792C2AC7AE700062CA31 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = SyncDataProviders; - }; - 4B95793D2AC7AE700062CA31 /* NetworkProtectionUI */ = { - isa = XCSwiftPackageProductDependency; - productName = NetworkProtectionUI; - }; - 4B95793E2AC7AE700062CA31 /* NetworkProtection */ = { - isa = XCSwiftPackageProductDependency; - package = 4B95792C2AC7AE700062CA31 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = NetworkProtection; - }; - 4B95793F2AC7AE700062CA31 /* LoginItems */ = { - isa = XCSwiftPackageProductDependency; - productName = LoginItems; - }; 4BA7C4DC2B3F64E500AFE511 /* LoginItems */ = { isa = XCSwiftPackageProductDependency; productName = LoginItems; @@ -14964,6 +13053,11 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = NetworkProtection; }; + 537FC71EA5115A983FAF3170 /* Crashes */ = { + isa = XCSwiftPackageProductDependency; + package = 4311906792B7676CE9535D76 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = Crashes; + }; 7B00997C2B6508B700FE7C31 /* NetworkProtectionProxy */ = { isa = XCSwiftPackageProductDependency; productName = NetworkProtectionProxy; @@ -14984,23 +13078,11 @@ isa = XCSwiftPackageProductDependency; productName = NetworkProtectionIPC; }; - 7B31FD8F2AD1257B0086AA24 /* NetworkProtectionIPC */ = { - isa = XCSwiftPackageProductDependency; - productName = NetworkProtectionIPC; - }; 7B37C7A42BAA32A50062546A /* Subscription */ = { isa = XCSwiftPackageProductDependency; package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = Subscription; }; - 7B5DD6992AE51FFA001DE99C /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; - 7B5F9A742AE2BE4E002AEBC0 /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; 7B624F162BA25C1F00A6C544 /* NetworkProtectionUI */ = { isa = XCSwiftPackageProductDependency; productName = NetworkProtectionUI; @@ -15010,14 +13092,6 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = Networking; }; - 7B8C083B2AE1268E00F4C67F /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; - 7B94E1642B7ED95100E32B96 /* NetworkProtectionProxy */ = { - isa = XCSwiftPackageProductDependency; - productName = NetworkProtectionProxy; - }; 7B97CD582B7E0B57004FEF43 /* NetworkProtectionProxy */ = { isa = XCSwiftPackageProductDependency; productName = NetworkProtectionProxy; @@ -15027,10 +13101,6 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = Common; }; - 7B97CD612B7E0C4B004FEF43 /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; 7BA076BA2B65D61400D7FB72 /* NetworkProtectionProxy */ = { isa = XCSwiftPackageProductDependency; productName = NetworkProtectionProxy; @@ -15049,10 +13119,6 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = Networking; }; - 7BBD44272AD730A400D0A064 /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; 7BBE2B7A2B61663C00697445 /* NetworkProtectionProxy */ = { isa = XCSwiftPackageProductDependency; productName = NetworkProtectionProxy; @@ -15073,14 +13139,6 @@ isa = XCSwiftPackageProductDependency; productName = NetworkProtectionUI; }; - 7BFCB74D2ADE7E1A00DA3EA7 /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; - 7BFCB74F2ADE7E2300DA3EA7 /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; 85D44B852BA08D29001B4AB5 /* Suggestions */ = { isa = XCSwiftPackageProductDependency; package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; @@ -15091,11 +13149,6 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = Suggestions; }; - 85D44B892BA08D3B001B4AB5 /* Suggestions */ = { - isa = XCSwiftPackageProductDependency; - package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = Suggestions; - }; 85E2BBCD2B8F534000DBEC7A /* History */ = { isa = XCSwiftPackageProductDependency; package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; @@ -15106,11 +13159,6 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = History; }; - 85E2BBD12B8F536F00DBEC7A /* History */ = { - isa = XCSwiftPackageProductDependency; - package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; - productName = History; - }; 9807F644278CA16F00E1547B /* BrowserServicesKit */ = { isa = XCSwiftPackageProductDependency; package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; @@ -15131,14 +13179,6 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = Persistence; }; - 9D6983F82AC773C3002C02FC /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; - 9D6983FA2AC773C8002C02FC /* PixelKit */ = { - isa = XCSwiftPackageProductDependency; - productName = PixelKit; - }; 9D9AE8F82AAA3AD00026E7DC /* DataBrokerProtection */ = { isa = XCSwiftPackageProductDependency; productName = DataBrokerProtection; @@ -15147,10 +13187,6 @@ isa = XCSwiftPackageProductDependency; productName = DataBrokerProtection; }; - 9DB6E7232AA0DC5800A17F3C /* LoginItems */ = { - isa = XCSwiftPackageProductDependency; - productName = LoginItems; - }; 9DC70B192AA1FA5B005A844B /* LoginItems */ = { isa = XCSwiftPackageProductDependency; productName = LoginItems; @@ -15170,11 +13206,6 @@ package = 9FF521422BAA8FF300B9819B /* XCRemoteSwiftPackageReference "lottie-spm" */; productName = Lottie; }; - 9FF521492BAA90C400B9819B /* Lottie */ = { - isa = XCSwiftPackageProductDependency; - package = 9FF521422BAA8FF300B9819B /* XCRemoteSwiftPackageReference "lottie-spm" */; - productName = Lottie; - }; AA06B6B62672AF8100F541C5 /* Sparkle */ = { isa = XCSwiftPackageProductDependency; package = AA06B6B52672AF8100F541C5 /* XCRemoteSwiftPackageReference "Sparkle" */; @@ -15250,31 +13281,26 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = Configuration; }; - B6F997BA2B8F353F00476735 /* SwiftLintPlugin */ = { - isa = XCSwiftPackageProductDependency; - package = B6F997B92B8F352500476735 /* XCRemoteSwiftPackageReference "apple-toolbox" */; - productName = "plugin:SwiftLintPlugin"; - }; - B6F997BC2B8F35EF00476735 /* SwiftLintPlugin */ = { + BDADBDC82BD2BC2200421B9B /* Lottie */ = { isa = XCSwiftPackageProductDependency; - package = B6F997B92B8F352500476735 /* XCRemoteSwiftPackageReference "apple-toolbox" */; - productName = "plugin:SwiftLintPlugin"; - }; - B6F997BE2B8F35F400476735 /* SwiftLintPlugin */ = { - isa = XCSwiftPackageProductDependency; - package = B6F997B92B8F352500476735 /* XCRemoteSwiftPackageReference "apple-toolbox" */; - productName = "plugin:SwiftLintPlugin"; + package = 9FF521422BAA8FF300B9819B /* XCRemoteSwiftPackageReference "lottie-spm" */; + productName = Lottie; }; - B6F997C02B8F35F800476735 /* SwiftLintPlugin */ = { + BDADBDCA2BD2BC2800421B9B /* Lottie */ = { isa = XCSwiftPackageProductDependency; - package = B6F997B92B8F352500476735 /* XCRemoteSwiftPackageReference "apple-toolbox" */; - productName = "plugin:SwiftLintPlugin"; + package = 9FF521422BAA8FF300B9819B /* XCRemoteSwiftPackageReference "lottie-spm" */; + productName = Lottie; }; CBC83E3529B63D380008E19C /* Configuration */ = { isa = XCSwiftPackageProductDependency; package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = Configuration; }; + DC3F73D49B2D44464AFEFCD8 /* Subscription */ = { + isa = XCSwiftPackageProductDependency; + package = 3FFD51CF7C19ACBDB9687474 /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = Subscription; + }; EE02D41F2BB460C000DBE6B3 /* BrowserServicesKit */ = { isa = XCSwiftPackageProductDependency; package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; @@ -15310,6 +13336,61 @@ package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; productName = NetworkProtection; }; + F116A7C22BD1924B00F3FCF7 /* PixelKitTestingUtilities */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = PixelKitTestingUtilities; + }; + F116A7C62BD1925500F3FCF7 /* PixelKitTestingUtilities */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = PixelKitTestingUtilities; + }; + F116A7C82BD1929000F3FCF7 /* PixelKitTestingUtilities */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = PixelKitTestingUtilities; + }; + F198C7112BD18A28000BF24D /* PixelKit */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = PixelKit; + }; + F198C7132BD18A30000BF24D /* PixelKit */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = PixelKit; + }; + F198C7152BD18A44000BF24D /* PixelKit */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = PixelKit; + }; + F198C7172BD18A4C000BF24D /* PixelKit */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = PixelKit; + }; + F198C7192BD18A5B000BF24D /* PixelKit */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = PixelKit; + }; + F198C71B2BD18A61000BF24D /* PixelKit */ = { + isa = XCSwiftPackageProductDependency; + package = 9807F643278CA16F00E1547B /* XCRemoteSwiftPackageReference "BrowserServicesKit" */; + productName = PixelKit; + }; + F198C71D2BD18D88000BF24D /* SwiftLintTool */ = { + isa = XCSwiftPackageProductDependency; + package = B6F997B92B8F352500476735 /* XCRemoteSwiftPackageReference "apple-toolbox" */; + productName = SwiftLintTool; + }; + F198C71F2BD18D92000BF24D /* SwiftLintTool */ = { + isa = XCSwiftPackageProductDependency; + package = B6F997B92B8F352500476735 /* XCRemoteSwiftPackageReference "apple-toolbox" */; + productName = SwiftLintTool; + }; F1D43AF22B98E47800BAB743 /* BareBonesBrowserKit */ = { isa = XCSwiftPackageProductDependency; package = F1D43AF12B98E47800BAB743 /* XCRemoteSwiftPackageReference "BareBonesBrowser" */; @@ -15320,10 +13401,9 @@ package = F1D43AF12B98E47800BAB743 /* XCRemoteSwiftPackageReference "BareBonesBrowser" */; productName = BareBonesBrowserKit; }; - F1D43AF62B98E48F00BAB743 /* BareBonesBrowserKit */ = { + F1DF95E62BD188B60045E591 /* LoginItems */ = { isa = XCSwiftPackageProductDependency; - package = F1D43AF12B98E47800BAB743 /* XCRemoteSwiftPackageReference "BareBonesBrowser" */; - productName = BareBonesBrowserKit; + productName = LoginItems; }; /* End XCSwiftPackageProductDependency section */ diff --git a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 48d2d9aea8..4fc95d491e 100644 --- a/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/DuckDuckGo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/apple-toolbox.git", "state" : { - "revision" : "d51beaf1736013b530576ace13a16d6d1a63742c", - "version" : "2.0.0" + "revision" : "ab53ca41e9044a20eab7e53249526fadcf9acc9f", + "version" : "3.1.1" } }, { @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/BrowserServicesKit", "state" : { - "revision" : "b0749d25996c0fa18be07b7851f02ebb3b9fab50", - "version" : "134.0.1" + "revision" : "b1501e60d245625d4a5d42a61b329364134f0879", + "version" : "140.0.1" } }, { @@ -113,8 +113,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/sparkle-project/Sparkle.git", "state" : { - "revision" : "47d3d90aee3c52b6f61d04ceae426e607df62347", - "version" : "2.5.2" + "revision" : "0a4caaf7a81eea2cece651ef4b17331fa0634dff", + "version" : "2.6.0" } }, { @@ -138,7 +138,7 @@ { "identity" : "swift-syntax", "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-syntax", + "location" : "https://github.com/apple/swift-syntax.git", "state" : { "revision" : "64889f0c732f210a935a0ad7cda38f77f876262d", "version" : "509.1.1" @@ -167,8 +167,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/duckduckgo/TrackerRadarKit", "state" : { - "revision" : "a6b7ba151d9dc6684484f3785293875ec01cc1ff", - "version" : "1.2.2" + "revision" : "6c84fd19139414fc0edbf9673ade06e532a564f0", + "version" : "2.0.0" } }, { diff --git a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGo Privacy Browser App Store.xcscheme b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGo Privacy Browser App Store.xcscheme index 86fd422c11..e343e06df9 100644 --- a/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGo Privacy Browser App Store.xcscheme +++ b/DuckDuckGo.xcodeproj/xcshareddata/xcschemes/DuckDuckGo Privacy Browser App Store.xcscheme @@ -157,16 +157,6 @@ ReferencedContainer = "container:LocalPackages/SyncUI"> - - - - - - - - + + @@ -185,16 +188,6 @@ ReferencedContainer = "container:LocalPackages/NetworkProtectionMac"> - - - - - - - - + shouldUseLaunchSchemeArgsEnv = "YES"> @@ -55,6 +54,12 @@ + + + + @@ -65,6 +70,11 @@ BlueprintName = "UI Tests" ReferencedContainer = "container:DuckDuckGo.xcodeproj"> + + + + diff --git a/DuckDuckGo/Application/AppDelegate.swift b/DuckDuckGo/Application/AppDelegate.swift index 53ac49ff5b..5b6d2a1eb4 100644 --- a/DuckDuckGo/Application/AppDelegate.swift +++ b/DuckDuckGo/Application/AppDelegate.swift @@ -23,8 +23,10 @@ import Combine import Common import Configuration import CoreData +import Crashes import DDGSync import History +import MetricKit import Networking import Persistence import PixelKit @@ -34,10 +36,7 @@ import UserNotifications import Lottie import NetworkProtection - -#if SUBSCRIPTION import Subscription -#endif @MainActor final class AppDelegate: NSObject, NSApplicationDelegate { @@ -64,9 +63,14 @@ final class AppDelegate: NSObject, NSApplicationDelegate { let fileStore: FileStore +#if APPSTORE + private let crashCollection = CrashCollection(platform: .macOSAppStore, log: .default) +#else + private let crashReporter = CrashReporter() +#endif + private(set) var stateRestorationManager: AppStateRestorationManager! private var grammarFeaturesManager = GrammarFeaturesManager() - private let crashReporter = CrashReporter() let internalUserDecider: InternalUserDecider let featureFlagger: FeatureFlagger private var appIconChanger: AppIconChanger! @@ -80,12 +84,10 @@ final class AppDelegate: NSObject, NSApplicationDelegate { let bookmarksManager = LocalBookmarkManager.shared var privacyDashboardWindow: NSWindow? -#if SUBSCRIPTION // Needs to be lazy as indirectly depends on AppDelegate private lazy var networkProtectionSubscriptionEventHandler = NetworkProtectionSubscriptionEventHandler() -#endif -#if DBP && SUBSCRIPTION +#if DBP private let dataBrokerProtectionSubscriptionEventHandler = DataBrokerProtectionSubscriptionEventHandler() #endif @@ -95,6 +97,13 @@ final class AppDelegate: NSObject, NSApplicationDelegate { var updateController: UpdateController! #endif + @UserDefaultsWrapper(key: .firstLaunchDate, defaultValue: Date.monthAgo) + static var firstLaunchDate: Date + + static var isNewUser: Bool { + return firstLaunchDate >= Date.weekAgo + } + // swiftlint:disable:next function_body_length override init() { do { @@ -109,22 +118,16 @@ final class AppDelegate: NSObject, NSApplicationDelegate { internalUserDecider = DefaultInternalUserDecider(store: internalUserDeciderStore) if NSApplication.runType.requiresEnvironment { -#if DEBUG - Pixel.setUp(dryRun: true) - Self.setUpPixelKit(dryRun: true) -#else - Pixel.setUp() - Self.setUpPixelKit(dryRun: false) -#endif + Self.configurePixelKit() Database.shared.loadStore { _, error in guard let error = error else { return } switch error { case CoreDataDatabase.Error.containerLocationCouldNotBePrepared(let underlyingError): - Pixel.fire(.debug(event: .dbContainerInitializationError, error: underlyingError)) + PixelKit.fire(DebugEvent(GeneralPixel.dbContainerInitializationError(error: underlyingError))) default: - Pixel.fire(.debug(event: .dbInitializationError, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.dbInitializationError(error: error))) } // Give Pixel a chance to be sent, but not too long @@ -133,12 +136,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate { } let preMigrationErrorHandling = EventMapping { _, error, _, _ in - if let error = error { - Pixel.fire(.debug(event: .bookmarksCouldNotLoadDatabase, error: error)) - } else { - Pixel.fire(.debug(event: .bookmarksCouldNotLoadDatabase)) - } - + PixelKit.fire(DebugEvent(GeneralPixel.bookmarksCouldNotLoadDatabase(error: error))) Thread.sleep(forTimeInterval: 1) fatalError("Could not create Bookmarks database stack: \(error?.localizedDescription ?? "err")") } @@ -152,12 +150,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate { BookmarkDatabase.shared.db.loadStore { context, error in guard let context = context else { - if let error = error { - Pixel.fire(.debug(event: .bookmarksCouldNotLoadDatabase, error: error)) - } else { - Pixel.fire(.debug(event: .bookmarksCouldNotLoadDatabase)) - } - + PixelKit.fire(DebugEvent(GeneralPixel.bookmarksCouldNotLoadDatabase(error: error))) Thread.sleep(forTimeInterval: 1) fatalError("Could not create Bookmarks database stack: \(error?.localizedDescription ?? "err")") } @@ -184,12 +177,18 @@ final class AppDelegate: NSObject, NSApplicationDelegate { privacyConfigManager: AppPrivacyFeatures.shared.contentBlocking.privacyConfigurationManager ) -#if SUBSCRIPTION #if APPSTORE || !STRIPE SubscriptionPurchaseEnvironment.current = .appStore #else SubscriptionPurchaseEnvironment.current = .stripe #endif + } + + static func configurePixelKit() { +#if DEBUG + Self.setUpPixelKit(dryRun: true) +#else + Self.setUpPixelKit(dryRun: false) #endif } @@ -236,11 +235,12 @@ final class AppDelegate: NSObject, NSApplicationDelegate { _ = RecentlyClosedCoordinator.shared // Clean up previous experiment - if PixelExperiment.allocatedCohortDoesNotMatchCurrentCohorts { - PixelExperiment.cleanup() - } +// if PixelExperiment.allocatedCohortDoesNotMatchCurrentCohorts { // Re-implement https://app.asana.com/0/0/1207002879349166/f +// PixelExperiment.cleanup() +// } + if LocalStatisticsStore().atb == nil { - Pixel.firstLaunchDate = Date() + AppDelegate.firstLaunchDate = Date() // MARK: Enable pixel experiments here } AtbAndVariantCleanup.cleanup() @@ -253,7 +253,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate { startupSync() -#if SUBSCRIPTION let defaultEnvironment = SubscriptionPurchaseEnvironment.ServiceEnvironment.default let currentEnvironment = UserDefaultsWrapper(key: .subscriptionEnvironment, @@ -267,7 +266,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate { _ = await accountManager.fetchEntitlements(cachePolicy: .reloadIgnoringLocalCacheData) } } -#endif if [.normal, .uiTests].contains(NSApp.runType) { stateRestorationManager.applicationDidFinishLaunching() @@ -284,7 +282,19 @@ final class AppDelegate: NSObject, NSApplicationDelegate { applyPreferredTheme() +#if APPSTORE + crashCollection.start { pixelParameters, payloads, completion in + pixelParameters.forEach { _ in PixelKit.fire(GeneralPixel.crash) } + guard let lastPayload = payloads.last else { + return + } + DispatchQueue.main.async { + CrashReportPromptPresenter().showPrompt(for: lastPayload, userDidAllowToReport: completion) + } + } +#else crashReporter.checkForNewReports() +#endif urlEventHandler.applicationDidFinishLaunching() @@ -293,23 +303,17 @@ final class AppDelegate: NSObject, NSApplicationDelegate { UserDefaultsWrapper.clearRemovedKeys() -#if SUBSCRIPTION networkProtectionSubscriptionEventHandler.registerForSubscriptionAccountManagerEvents() -#endif NetworkProtectionAppEvents().applicationDidFinishLaunching() UNUserNotificationCenter.current().delegate = self -#if DBP && SUBSCRIPTION +#if DBP dataBrokerProtectionSubscriptionEventHandler.registerForSubscriptionAccountManagerEvents() #endif #if DBP DataBrokerProtectionAppEvents().applicationDidFinishLaunching() -#endif - -#if SUBSCRIPTION - #endif } @@ -384,7 +388,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate { appVersion: AppVersion.shared.versionNumber, source: source, defaultHeaders: [:], - log: .networkProtectionPixel, defaults: .netP) { (pixelName: String, headers: [String: String], parameters: [String: String], _, _, onComplete: @escaping PixelKit.CompletionBlock) in let url = URL.pixelUrl(forPixelNamed: pixelName) @@ -442,9 +445,9 @@ final class AppDelegate: NSObject, NSApplicationDelegate { .filter { $0 } .asVoid() .sink { [weak syncService] in - Pixel.fire(.syncDaily, limitTo: .dailyFirst) + PixelKit.fire(GeneralPixel.syncDaily, frequency: .daily) syncService?.syncDailyStats.sendStatsIfNeeded(handler: { params in - Pixel.fire(.syncSuccessRateDaily, withAdditionalParameters: params) + PixelKit.fire(GeneralPixel.syncSuccessRateDaily, withAdditionalParameters: params) }) } @@ -525,9 +528,9 @@ final class AppDelegate: NSObject, NSApplicationDelegate { } private func emailDidSignInNotification(_ notification: Notification) { - Pixel.fire(.emailEnabled) - if Pixel.isNewUser { - Pixel.fire(.emailEnabledInitial, limitTo: .initial) + PixelKit.fire(GeneralPixel.emailEnabled) + if AppDelegate.isNewUser { + PixelKit.fire(GeneralPixel.emailEnabledInitial, frequency: .legacyInitial) } if let object = notification.object as? EmailManager, let emailManager = syncDataProviders.settingsAdapter.emailManager, object !== emailManager { @@ -536,22 +539,20 @@ final class AppDelegate: NSObject, NSApplicationDelegate { } private func emailDidSignOutNotification(_ notification: Notification) { - Pixel.fire(.emailDisabled) + PixelKit.fire(GeneralPixel.emailDisabled) if let object = notification.object as? EmailManager, let emailManager = syncDataProviders.settingsAdapter.emailManager, object !== emailManager { syncService?.scheduler.notifyDataChanged() } } @objc private func dataImportCompleteNotification(_ notification: Notification) { - if Pixel.isNewUser { - Pixel.fire(.importDataInitial, limitTo: .initial) + if AppDelegate.isNewUser { + PixelKit.fire(GeneralPixel.importDataInitial, frequency: .legacyInitial) } } - } func updateSubscriptionStatus() { -#if SUBSCRIPTION Task { let accountManager = AccountManager(subscriptionAppGroup: Bundle.main.appGroup(bundle: .subs)) @@ -559,13 +560,12 @@ func updateSubscriptionStatus() { if case .success(let subscription) = await SubscriptionService.getSubscription(accessToken: token, cachePolicy: .reloadIgnoringLocalCacheData) { if subscription.isActive { - DailyPixel.fire(pixel: .privacyProSubscriptionActive, frequency: .dailyOnly) + PixelKit.fire(PrivacyProPixel.privacyProSubscriptionActive, frequency: .daily) } } _ = await accountManager.fetchEntitlements(cachePolicy: .reloadIgnoringLocalCacheData) } -#endif } extension AppDelegate: UNUserNotificationCenterDelegate { diff --git a/DuckDuckGo/Application/URLEventHandler.swift b/DuckDuckGo/Application/URLEventHandler.swift index 696d2b59d7..003cf5500b 100644 --- a/DuckDuckGo/Application/URLEventHandler.swift +++ b/DuckDuckGo/Application/URLEventHandler.swift @@ -19,6 +19,7 @@ import Common import Foundation import AppKit +import PixelKit import NetworkProtectionUI @@ -61,15 +62,15 @@ final class URLEventHandler { @objc func handleUrlEvent(event: NSAppleEventDescriptor, reply: NSAppleEventDescriptor) { guard let stringValue = event.paramDescriptor(forKeyword: keyDirectObject)?.stringValue else { os_log("UrlEventListener: unable to determine path", type: .error) - Pixel.fire(.debug(event: .appOpenURLFailed, - error: NSError(domain: "CouldNotGetPath", code: -1, userInfo: nil))) + let error = NSError(domain: "CouldNotGetPath", code: -1, userInfo: nil) + PixelKit.fire(DebugEvent(GeneralPixel.appOpenURLFailed, error: error)) return } guard let url = URL.makeURL(from: stringValue) else { os_log("UrlEventListener: failed to construct URL from path %s", type: .error, stringValue) - Pixel.fire(.debug(event: .appOpenURLFailed, - error: NSError(domain: "CouldNotConstructURL", code: -1, userInfo: nil))) + let error = NSError(domain: "CouldNotConstructURL", code: -1, userInfo: nil) + PixelKit.fire(DebugEvent(GeneralPixel.appOpenURLFailed, error: error)) return } @@ -146,15 +147,13 @@ final class URLEventHandler { case AppLaunchCommand.shareFeedback.launchURL: WindowControllersManager.shared.showShareFeedbackModal() case AppLaunchCommand.justOpen.launchURL: - WindowControllersManager.shared.showNewWindow() + WindowControllersManager.shared.showMainWindow() case AppLaunchCommand.showVPNLocations.launchURL: WindowControllersManager.shared.showPreferencesTab(withSelectedPane: .vpn) WindowControllersManager.shared.showLocationPickerSheet() -#if SUBSCRIPTION case AppLaunchCommand.showPrivacyPro.launchURL: WindowControllersManager.shared.showTab(with: .subscription(.subscriptionPurchase)) - Pixel.fire(.privacyProOfferScreenImpression) -#endif + PixelKit.fire(PrivacyProPixel.privacyProOfferScreenImpression) #if !APPSTORE && !DEBUG case AppLaunchCommand.moveAppToApplications.launchURL: // this should be run after NSApplication.shared is set diff --git a/DuckDuckGo/Application/UpdateController.swift b/DuckDuckGo/Application/UpdateController.swift index 13fcacd30d..56f8d5c0fb 100644 --- a/DuckDuckGo/Application/UpdateController.swift +++ b/DuckDuckGo/Application/UpdateController.swift @@ -21,6 +21,7 @@ import Combine import Sparkle import BrowserServicesKit import SwiftUIExtensions +import PixelKit #if SPARKLE @@ -107,7 +108,7 @@ extension UpdateController: SPUUpdaterDelegate { return } - Pixel.fire(.debug(event: .updaterAborted, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.updaterAborted, error: error)) } func updater(_ updater: SPUUpdater, @@ -116,11 +117,11 @@ extension UpdateController: SPUUpdaterDelegate { state: SPUUserUpdateState) { switch choice { case .skip: - Pixel.fire(.debug(event: .userSelectedToSkipUpdate)) + PixelKit.fire(DebugEvent(GeneralPixel.userSelectedToSkipUpdate)) case .install: - Pixel.fire(.debug(event: .userSelectedToInstallUpdate)) + PixelKit.fire(DebugEvent(GeneralPixel.userSelectedToInstallUpdate)) case .dismiss: - Pixel.fire(.debug(event: .userSelectedToDismissUpdate)) + PixelKit.fire(DebugEvent(GeneralPixel.userSelectedToDismissUpdate)) @unknown default: break } diff --git a/DuckDuckGo/Assets.xcassets/Images/DataBrokerProtectionWaitlist/Contents.json b/DuckDuckGo/Assets.xcassets/Images/DataBrokerProtection/Contents.json similarity index 100% rename from DuckDuckGo/Assets.xcassets/Images/DataBrokerProtectionWaitlist/Contents.json rename to DuckDuckGo/Assets.xcassets/Images/DataBrokerProtection/Contents.json diff --git a/DuckDuckGo/Assets.xcassets/Images/DataBrokerProtectionWaitlist/DBP-Icon.imageset/Contents.json b/DuckDuckGo/Assets.xcassets/Images/DataBrokerProtection/DBP-Icon.imageset/Contents.json similarity index 100% rename from DuckDuckGo/Assets.xcassets/Images/DataBrokerProtectionWaitlist/DBP-Icon.imageset/Contents.json rename to DuckDuckGo/Assets.xcassets/Images/DataBrokerProtection/DBP-Icon.imageset/Contents.json diff --git a/DuckDuckGo/Assets.xcassets/Images/DataBrokerProtectionWaitlist/DBP-Icon.imageset/DBP-Icon.pdf b/DuckDuckGo/Assets.xcassets/Images/DataBrokerProtection/DBP-Icon.imageset/DBP-Icon.pdf similarity index 100% rename from DuckDuckGo/Assets.xcassets/Images/DataBrokerProtectionWaitlist/DBP-Icon.imageset/DBP-Icon.pdf rename to DuckDuckGo/Assets.xcassets/Images/DataBrokerProtection/DBP-Icon.imageset/DBP-Icon.pdf diff --git a/DuckDuckGo/Assets.xcassets/Images/DataBrokerProtectionWaitlist/DBP-Information-Remover.imageset/Contents.json b/DuckDuckGo/Assets.xcassets/Images/DataBrokerProtection/DBP-Information-Remover.imageset/Contents.json similarity index 100% rename from DuckDuckGo/Assets.xcassets/Images/DataBrokerProtectionWaitlist/DBP-Information-Remover.imageset/Contents.json rename to DuckDuckGo/Assets.xcassets/Images/DataBrokerProtection/DBP-Information-Remover.imageset/Contents.json diff --git a/DuckDuckGo/Assets.xcassets/Images/DataBrokerProtectionWaitlist/DBP-Information-Remover.imageset/DBP-Information-Remover.svg b/DuckDuckGo/Assets.xcassets/Images/DataBrokerProtection/DBP-Information-Remover.imageset/DBP-Information-Remover.svg similarity index 100% rename from DuckDuckGo/Assets.xcassets/Images/DataBrokerProtectionWaitlist/DBP-Information-Remover.imageset/DBP-Information-Remover.svg rename to DuckDuckGo/Assets.xcassets/Images/DataBrokerProtection/DBP-Information-Remover.imageset/DBP-Information-Remover.svg diff --git a/LocalPackages/NetworkProtectionMac/Sources/NetworkProtectionUI/Resources/Assets.xcassets/Icons/Server-Location-16.imageset/Contents.json b/DuckDuckGo/Assets.xcassets/Images/DataBrokerProtection/dbp-error-info.imageset/Contents.json similarity index 62% rename from LocalPackages/NetworkProtectionMac/Sources/NetworkProtectionUI/Resources/Assets.xcassets/Icons/Server-Location-16.imageset/Contents.json rename to DuckDuckGo/Assets.xcassets/Images/DataBrokerProtection/dbp-error-info.imageset/Contents.json index e020cd9994..9869fe984d 100644 --- a/LocalPackages/NetworkProtectionMac/Sources/NetworkProtectionUI/Resources/Assets.xcassets/Icons/Server-Location-16.imageset/Contents.json +++ b/DuckDuckGo/Assets.xcassets/Images/DataBrokerProtection/dbp-error-info.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "Server-Location-16.pdf", + "filename" : "dbp-error-info.pdf", "idiom" : "universal" } ], @@ -10,6 +10,6 @@ "version" : 1 }, "properties" : { - "template-rendering-intent" : "template" + "template-rendering-intent" : "original" } } diff --git a/DuckDuckGo/Assets.xcassets/Images/DataBrokerProtection/dbp-error-info.imageset/dbp-error-info.pdf b/DuckDuckGo/Assets.xcassets/Images/DataBrokerProtection/dbp-error-info.imageset/dbp-error-info.pdf new file mode 100644 index 0000000000..c9486753e5 Binary files /dev/null and b/DuckDuckGo/Assets.xcassets/Images/DataBrokerProtection/dbp-error-info.imageset/dbp-error-info.pdf differ diff --git a/DuckDuckGo/Assets.xcassets/Images/NetworkProtectionWaitlist/NetworkProtectionAvailableButton.imageset/Contents.json b/DuckDuckGo/Assets.xcassets/Images/NetworkProtectionWaitlist/NetworkProtectionAvailableButton.imageset/Contents.json deleted file mode 100644 index 89e4996541..0000000000 --- a/DuckDuckGo/Assets.xcassets/Images/NetworkProtectionWaitlist/NetworkProtectionAvailableButton.imageset/Contents.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "images" : [ - { - "filename" : "Toolbar Button.pdf", - "idiom" : "universal" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "filename" : "Toolbar Button 1.pdf", - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/DuckDuckGo/Assets.xcassets/Images/NetworkProtectionWaitlist/NetworkProtectionAvailableButton.imageset/Toolbar Button 1.pdf b/DuckDuckGo/Assets.xcassets/Images/NetworkProtectionWaitlist/NetworkProtectionAvailableButton.imageset/Toolbar Button 1.pdf deleted file mode 100644 index 6fca4a04e3..0000000000 Binary files a/DuckDuckGo/Assets.xcassets/Images/NetworkProtectionWaitlist/NetworkProtectionAvailableButton.imageset/Toolbar Button 1.pdf and /dev/null differ diff --git a/DuckDuckGo/Assets.xcassets/Images/NetworkProtectionWaitlist/NetworkProtectionAvailableButton.imageset/Toolbar Button.pdf b/DuckDuckGo/Assets.xcassets/Images/NetworkProtectionWaitlist/NetworkProtectionAvailableButton.imageset/Toolbar Button.pdf deleted file mode 100644 index 04826a0a10..0000000000 Binary files a/DuckDuckGo/Assets.xcassets/Images/NetworkProtectionWaitlist/NetworkProtectionAvailableButton.imageset/Toolbar Button.pdf and /dev/null differ diff --git a/DuckDuckGo/Autofill/AutofillActionBuilder.swift b/DuckDuckGo/Autofill/AutofillActionBuilder.swift index de48f8d6b3..cbf46a19e2 100644 --- a/DuckDuckGo/Autofill/AutofillActionBuilder.swift +++ b/DuckDuckGo/Autofill/AutofillActionBuilder.swift @@ -35,7 +35,7 @@ extension AutofillActionBuilder { struct AutofillDeleteAllPasswordsBuilder: AutofillActionBuilder { @MainActor func buildExecutor() -> AutofillActionExecutor? { - guard let secureVault = try? AutofillSecureVaultFactory.makeVault(errorReporter: SecureVaultErrorReporter.shared), + guard let secureVault = try? AutofillSecureVaultFactory.makeVault(reporter: SecureVaultReporter.shared), let syncService = NSApp.delegateTyped.syncService else { return nil } return AutofillDeleteAllPasswordsExecutor(userAuthenticator: DeviceAuthenticator.shared, diff --git a/DuckDuckGo/Autofill/AutofillActionExecutor.swift b/DuckDuckGo/Autofill/AutofillActionExecutor.swift index f574c7e974..cbdc445d1f 100644 --- a/DuckDuckGo/Autofill/AutofillActionExecutor.swift +++ b/DuckDuckGo/Autofill/AutofillActionExecutor.swift @@ -20,6 +20,7 @@ import Foundation import BrowserServicesKit import DDGSync import AppKit +import PixelKit /// Conforming types provide an `execute` method which performs some action on autofill types (e.g delete all passwords) protocol AutofillActionExecutor { @@ -68,7 +69,7 @@ struct AutofillDeleteAllPasswordsExecutor: AutofillActionExecutor { syncService.scheduler.notifyDataChanged() onSuccess?() } catch { - Pixel.fire(.debug(event: .secureVaultError, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.secureVaultError(error: error))) } return diff --git a/DuckDuckGo/Autofill/ContentOverlayViewController.swift b/DuckDuckGo/Autofill/ContentOverlayViewController.swift index d90b35f71d..5bfdf2ca85 100644 --- a/DuckDuckGo/Autofill/ContentOverlayViewController.swift +++ b/DuckDuckGo/Autofill/ContentOverlayViewController.swift @@ -22,6 +22,7 @@ import Combine import BrowserServicesKit import SecureStorage import Autofill +import PixelKit @MainActor public final class ContentOverlayViewController: NSViewController, EmailManagerRequestDelegate { @@ -191,7 +192,7 @@ public final class ContentOverlayViewController: NSViewController, EmailManagerR parameters["keychain_operation"] = "save" } - Pixel.fire(.debug(event: .emailAutofillKeychainError, error: error), withAdditionalParameters: parameters) + PixelKit.fire(DebugEvent(GeneralPixel.emailAutofillKeychainError), withAdditionalParameters: parameters) } private enum Constants { @@ -294,7 +295,7 @@ extension ContentOverlayViewController: SecureVaultManagerDelegate { } public func secureVaultManager(_: SecureVaultManager, didAutofill type: AutofillType, withObjectId objectId: String) { - Pixel.fire(.formAutofilled(kind: type.formAutofillKind)) + PixelKit.fire(GeneralPixel.formAutofilled(kind: type.formAutofillKind)) if type.formAutofillKind == .password && passwordManagerCoordinator.isEnabled { @@ -308,8 +309,8 @@ extension ContentOverlayViewController: SecureVaultManagerDelegate { } } - public func secureVaultInitFailed(_ error: SecureStorageError) { - SecureVaultErrorReporter.shared.secureVaultInitFailed(error) + public func secureVaultError(_ error: SecureStorageError) { + SecureVaultReporter.shared.secureVaultError(error) } public func secureVaultManager(_: BrowserServicesKit.SecureVaultManager, didReceivePixel pixel: AutofillUserScript.JSPixel) { @@ -320,9 +321,9 @@ extension ContentOverlayViewController: SecureVaultManagerDelegate { self.emailManager.updateLastUseDate() - Pixel.fire(.jsPixel(pixel), withAdditionalParameters: pixelParameters) + PixelKit.fire(GeneralPixel.jsPixel(pixel), withAdditionalParameters: pixelParameters) } else { - Pixel.fire(.jsPixel(pixel), withAdditionalParameters: pixel.pixelParameters) + PixelKit.fire(GeneralPixel.jsPixel(pixel), withAdditionalParameters: pixel.pixelParameters) } } diff --git a/DuckDuckGo/Bookmarks/Extensions/Bookmarks+Tab.swift b/DuckDuckGo/Bookmarks/Extensions/Bookmarks+Tab.swift index 82e5748c72..78c60f30ea 100644 --- a/DuckDuckGo/Bookmarks/Extensions/Bookmarks+Tab.swift +++ b/DuckDuckGo/Bookmarks/Extensions/Bookmarks+Tab.swift @@ -22,7 +22,7 @@ extension Tab { @MainActor static func withContentOfBookmark(folder: BookmarkFolder, burnerMode: BurnerMode) -> [Tab] { - folder.children.compactMap { entity in + folder.children.compactMap { entity -> Tab? in guard let url = (entity as? Bookmark)?.urlObject else { return nil } return Tab(content: .url(url, source: .bookmark), shouldLoadInBackground: true, burnerMode: burnerMode) } diff --git a/DuckDuckGo/Bookmarks/Legacy/LegacyBookmarkStore.swift b/DuckDuckGo/Bookmarks/Legacy/LegacyBookmarkStore.swift index 9634ca221f..ebfc15be43 100644 --- a/DuckDuckGo/Bookmarks/Legacy/LegacyBookmarkStore.swift +++ b/DuckDuckGo/Bookmarks/Legacy/LegacyBookmarkStore.swift @@ -19,6 +19,7 @@ import Foundation import CoreData import Cocoa +import PixelKit fileprivate extension UUID { @@ -171,7 +172,7 @@ extension LegacyBookmarkStore { try context.save() } catch { - Pixel.fire(.debug(event: .bookmarksStoreRootFolderMigrationFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.bookmarksStoreRootFolderMigrationFailed, error: error)) } } @@ -211,7 +212,7 @@ extension LegacyBookmarkStore { // 4. Save the migration: try context.save() } catch { - Pixel.fire(.debug(event: .bookmarksStoreRootFolderMigrationFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.bookmarksStoreRootFolderMigrationFailed, error: error)) } } } diff --git a/DuckDuckGo/Bookmarks/Legacy/LegacyBookmarksStoreMigration.swift b/DuckDuckGo/Bookmarks/Legacy/LegacyBookmarksStoreMigration.swift index c5ecef1b7c..734275e1c5 100644 --- a/DuckDuckGo/Bookmarks/Legacy/LegacyBookmarksStoreMigration.swift +++ b/DuckDuckGo/Bookmarks/Legacy/LegacyBookmarksStoreMigration.swift @@ -20,6 +20,7 @@ import Foundation import CoreData import Bookmarks import Persistence +import PixelKit public class LegacyBookmarksStoreMigration { @@ -55,7 +56,7 @@ public class LegacyBookmarksStoreMigration { guard BookmarkUtils.fetchRootFolder(destination) == nil else { // There should be no data left as migration has been done already if !bookmarkRoots.isEmpty { - Pixel.fire(.debug(event: .bookmarksMigrationAlreadyPerformed)) + PixelKit.fire(DebugEvent(GeneralPixel.bookmarksMigrationAlreadyPerformed)) cleanupOldData(in: source) } @@ -72,9 +73,9 @@ public class LegacyBookmarksStoreMigration { let newFavoritesRoot = BookmarkUtils.fetchLegacyFavoritesFolder(destination) else { if bookmarkRoots.isEmpty { - Pixel.fire(.debug(event: .bookmarksCouldNotPrepareDatabase)) + PixelKit.fire(DebugEvent(GeneralPixel.bookmarksCouldNotPrepareDatabase)) } else { - Pixel.fire(.debug(event: .bookmarksMigrationCouldNotPrepareDatabase)) + PixelKit.fire(DebugEvent(GeneralPixel.bookmarksMigrationCouldNotPrepareDatabase)) } Thread.sleep(forTimeInterval: 2) @@ -157,7 +158,7 @@ public class LegacyBookmarksStoreMigration { } do { - try destination.save(onErrorFire: .bookmarksMigrationFailed) + try destination.save(onErrorFire: GeneralPixel.bookmarksMigrationFailed) cleanupOldData(in: source) } catch { @@ -165,7 +166,7 @@ public class LegacyBookmarksStoreMigration { BookmarkUtils.prepareLegacyFoldersStructure(in: destination) do { - try destination.save(onErrorFire: .bookmarksMigrationCouldNotPrepareDatabaseOnFailedMigration) + try destination.save(onErrorFire: GeneralPixel.bookmarksMigrationCouldNotPrepareDatabaseOnFailedMigration) } catch { Thread.sleep(forTimeInterval: 2) fatalError("Could not write to Bookmarks DB") @@ -181,7 +182,7 @@ public class LegacyBookmarksStoreMigration { allObjects.forEach { context.delete($0) } if context.hasChanges { - try? context.save(onErrorFire: .bookmarksMigrationCouldNotRemoveOldStore) + try? context.save(onErrorFire: GeneralPixel.bookmarksMigrationCouldNotRemoveOldStore) } } diff --git a/DuckDuckGo/Bookmarks/Model/BookmarkManager.swift b/DuckDuckGo/Bookmarks/Model/BookmarkManager.swift index b3172da78e..1220f5eabb 100644 --- a/DuckDuckGo/Bookmarks/Model/BookmarkManager.swift +++ b/DuckDuckGo/Bookmarks/Model/BookmarkManager.swift @@ -28,8 +28,10 @@ protocol BookmarkManager: AnyObject { func allHosts() -> Set func getBookmark(for url: URL) -> Bookmark? func getBookmark(forUrl url: String) -> Bookmark? + func getBookmarkFolder(withId id: String) -> BookmarkFolder? @discardableResult func makeBookmark(for url: URL, title: String, isFavorite: Bool) -> Bookmark? @discardableResult func makeBookmark(for url: URL, title: String, isFavorite: Bool, index: Int?, parent: BookmarkFolder?) -> Bookmark? + func makeBookmarks(for websitesInfo: [WebsiteInfo], inNewFolderNamed folderName: String, withinParentFolder parent: ParentFolderType) func makeFolder(for title: String, parent: BookmarkFolder?, completion: @escaping (BookmarkFolder) -> Void) func remove(bookmark: Bookmark) func remove(folder: BookmarkFolder) @@ -46,7 +48,6 @@ protocol BookmarkManager: AnyObject { func move(objectUUIDs: [String], toIndex: Int?, withinParentFolder: ParentFolderType, completion: @escaping (Error?) -> Void) func moveFavorites(with objectUUIDs: [String], toIndex: Int?, completion: @escaping (Error?) -> Void) func importBookmarks(_ bookmarks: ImportedBookmarks, source: BookmarkImportSource) -> BookmarksImportSummary - func handleFavoritesAfterDisablingSync() // Wrapper definition in a protocol is not supported yet @@ -138,6 +139,10 @@ final class LocalBookmarkManager: BookmarkManager { return list?[url] } + func getBookmarkFolder(withId id: String) -> BookmarkFolder? { + bookmarkStore.bookmarkFolder(withId: id) + } + @discardableResult func makeBookmark(for url: URL, title: String, isFavorite: Bool) -> Bookmark? { makeBookmark(for: url, title: title, isFavorite: isFavorite, index: nil, parent: nil) } @@ -167,6 +172,12 @@ final class LocalBookmarkManager: BookmarkManager { return bookmark } + func makeBookmarks(for websitesInfo: [WebsiteInfo], inNewFolderNamed folderName: String, withinParentFolder parent: ParentFolderType) { + bookmarkStore.saveBookmarks(for: websitesInfo, inNewFolderNamed: folderName, withinParentFolder: parent) + loadBookmarks() + requestSync() + } + func remove(bookmark: Bookmark) { guard list != nil else { return } guard let latestBookmark = getBookmark(forUrl: bookmark.url) else { diff --git a/DuckDuckGo/Bookmarks/Model/BookmarksCleanupErrorHandling.swift b/DuckDuckGo/Bookmarks/Model/BookmarksCleanupErrorHandling.swift index 815dc8ecf9..467af32bbd 100644 --- a/DuckDuckGo/Bookmarks/Model/BookmarksCleanupErrorHandling.swift +++ b/DuckDuckGo/Bookmarks/Model/BookmarksCleanupErrorHandling.swift @@ -20,18 +20,19 @@ import Foundation import Bookmarks import Common import Persistence +import PixelKit public class BookmarksCleanupErrorHandling: EventMapping { public init() { super.init { event, _, _, _ in if event.cleanupError is BookmarksCleanupCancelledError { - Pixel.fire(.debug(event: .bookmarksCleanupAttemptedWhileSyncWasEnabled)) + PixelKit.fire(DebugEvent(GeneralPixel.bookmarksCleanupAttemptedWhileSyncWasEnabled)) } else { let processedErrors = CoreDataErrorsParser.parse(error: event.cleanupError as NSError) let params = processedErrors.errorPixelParameters - Pixel.fire(.debug(event: .bookmarksCleanupFailed, error: event.cleanupError), withAdditionalParameters: params) + PixelKit.fire(DebugEvent(GeneralPixel.bookmarksCleanupFailed, error: event.cleanupError), withAdditionalParameters: params) } } } diff --git a/DuckDuckGo/Bookmarks/Model/WebsiteInfo.swift b/DuckDuckGo/Bookmarks/Model/WebsiteInfo.swift index fc393b256d..a4d146abd7 100644 --- a/DuckDuckGo/Bookmarks/Model/WebsiteInfo.swift +++ b/DuckDuckGo/Bookmarks/Model/WebsiteInfo.swift @@ -18,15 +18,17 @@ import Foundation -struct WebsiteInfo { +struct WebsiteInfo: Equatable { let url: URL - let title: String? + /// Returns the title of the website if available, otherwise returns the domain of the URL. + /// If both title and and domain are nil, it returns the absolute string representation of the URL. + let title: String init?(_ tab: Tab) { guard case let .url(url, _, _) = tab.content else { return nil } self.url = url - self.title = tab.title + self.title = tab.title ?? url.host ?? url.absoluteString } } diff --git a/DuckDuckGo/Bookmarks/Services/BookmarkStore.swift b/DuckDuckGo/Bookmarks/Services/BookmarkStore.swift index 3466d1a7fa..8c8f4a6d06 100644 --- a/DuckDuckGo/Bookmarks/Services/BookmarkStore.swift +++ b/DuckDuckGo/Bookmarks/Services/BookmarkStore.swift @@ -48,9 +48,11 @@ protocol BookmarkStore { func loadAll(type: BookmarkStoreFetchPredicateType, completion: @escaping ([BaseBookmarkEntity]?, Error?) -> Void) func save(bookmark: Bookmark, parent: BookmarkFolder?, index: Int?, completion: @escaping (Bool, Error?) -> Void) + func saveBookmarks(for websitesInfo: [WebsiteInfo], inNewFolderNamed folderName: String, withinParentFolder parent: ParentFolderType) func save(folder: BookmarkFolder, parent: BookmarkFolder?, completion: @escaping (Bool, Error?) -> Void) func remove(objectsWithUUIDs: [String], completion: @escaping (Bool, Error?) -> Void) func update(bookmark: Bookmark) + func bookmarkFolder(withId id: String) -> BookmarkFolder? func update(folder: BookmarkFolder) func update(folder: BookmarkFolder, andMoveToParent parent: ParentFolderType) func add(objectsWithUUIDs: [String], to parent: BookmarkFolder?, completion: @escaping (Error?) -> Void) @@ -59,6 +61,5 @@ protocol BookmarkStore { func move(objectUUIDs: [String], toIndex: Int?, withinParentFolder: ParentFolderType, completion: @escaping (Error?) -> Void) func moveFavorites(with objectUUIDs: [String], toIndex: Int?, completion: @escaping (Error?) -> Void) func importBookmarks(_ bookmarks: ImportedBookmarks, source: BookmarkImportSource) -> BookmarksImportSummary - func handleFavoritesAfterDisablingSync() } diff --git a/DuckDuckGo/Bookmarks/Services/BookmarkStoreMock.swift b/DuckDuckGo/Bookmarks/Services/BookmarkStoreMock.swift index 2ab57158a9..003ba7bb59 100644 --- a/DuckDuckGo/Bookmarks/Services/BookmarkStoreMock.swift +++ b/DuckDuckGo/Bookmarks/Services/BookmarkStoreMock.swift @@ -104,6 +104,15 @@ public final class BookmarkStoreMock: BookmarkStore { capturedBookmark = bookmark } + var bookmarkFolderWithIdCalled = false + var capturedFolderId: String? + var bookmarkFolder: BookmarkFolder? + func bookmarkFolder(withId id: String) -> BookmarkFolder? { + bookmarkFolderWithIdCalled = true + capturedFolderId = id + return bookmarkFolder + } + var updateFolderCalled = false func update(folder: BookmarkFolder) { updateFolderCalled = true @@ -133,6 +142,16 @@ public final class BookmarkStoreMock: BookmarkStore { return BookmarksImportSummary(successful: 0, duplicates: 0, failed: 0) } + var saveBookmarksInNewFolderNamedCalled = false + var capturedWebsitesInfo: [WebsiteInfo]? + var capturedNewFolderName: String? + func saveBookmarks(for websitesInfo: [WebsiteInfo], inNewFolderNamed folderName: String, withinParentFolder parent: ParentFolderType) { + saveBookmarksInNewFolderNamedCalled = true + capturedWebsitesInfo = websitesInfo + capturedNewFolderName = folderName + capturedParentFolderType = parent + } + var canMoveObjectWithUUIDCalled = false func canMoveObjectWithUUID(objectUUID uuid: String, to parent: BookmarkFolder) -> Bool { canMoveObjectWithUUIDCalled = true diff --git a/DuckDuckGo/Bookmarks/Services/LocalBookmarkStore.swift b/DuckDuckGo/Bookmarks/Services/LocalBookmarkStore.swift index e2be507a44..2a480e8333 100644 --- a/DuckDuckGo/Bookmarks/Services/LocalBookmarkStore.swift +++ b/DuckDuckGo/Bookmarks/Services/LocalBookmarkStore.swift @@ -65,6 +65,7 @@ final class LocalBookmarkStore: BookmarkStore { case missingRoot case missingFavoritesRoot case saveLoopError(Error?) + case badModelMapping } private(set) var favoritesDisplayMode: FavoritesDisplayMode @@ -199,10 +200,10 @@ final class LocalBookmarkStore: BookmarkStore { var params = processedErrors.errorPixelParameters params[PixelKit.Parameters.errorSource] = source - Pixel.fire(.debug(event: .bookmarksSaveFailed, error: error), + PixelKit.fire(DebugEvent(GeneralPixel.bookmarksSaveFailed, error: error), withAdditionalParameters: params) } else { - Pixel.fire(.debug(event: .bookmarksSaveFailed, error: localError), + PixelKit.fire(DebugEvent(GeneralPixel.bookmarksSaveFailed, error: localError), withAdditionalParameters: [PixelKit.Parameters.errorSource: source]) } } else { @@ -211,7 +212,7 @@ final class LocalBookmarkStore: BookmarkStore { var params = processedErrors.errorPixelParameters params[PixelKit.Parameters.errorSource] = source - Pixel.fire(.debug(event: .bookmarksSaveFailed, error: error), + PixelKit.fire(DebugEvent(GeneralPixel.bookmarksSaveFailed, error: error), withAdditionalParameters: params) } } @@ -228,7 +229,7 @@ final class LocalBookmarkStore: BookmarkStore { ) if context.hasChanges { - try context.save(onErrorFire: .bookmarksMigrationCouldNotPrepareMultipleFavoriteFolders) + try context.save(onErrorFire: GeneralPixel.bookmarksMigrationCouldNotPrepareMultipleFavoriteFolders) } } catch { Thread.sleep(forTimeInterval: 1) @@ -310,7 +311,7 @@ final class LocalBookmarkStore: BookmarkStore { } else if let root = bookmarksRoot(in: context) { parentEntity = root } else { - Pixel.fire(.debug(event: .missingParent)) + PixelKit.fire(DebugEvent(GeneralPixel.missingParent)) throw BookmarkStoreError.missingParent } @@ -339,6 +340,23 @@ final class LocalBookmarkStore: BookmarkStore { }) } + func saveBookmarks(for websitesInfo: [WebsiteInfo], inNewFolderNamed folderName: String, withinParentFolder parent: ParentFolderType) { + do { + try applyChangesAndSave { context in + // Fetch Parent folder + let parentFolder = try bookmarkEntity(for: parent, in: context) + // Create new Folder for all bookmarks + let newFolderMO = BookmarkEntity.makeFolder(title: folderName, parent: parentFolder, context: context) + // Save the bookmarks + websitesInfo.forEach { info in + _ = BookmarkEntity.makeBookmark(title: info.title, url: info.url.absoluteString, parent: newFolderMO, context: context) + } + } + } catch { + commonOnSaveErrorHandler(error) + } + } + func remove(objectsWithUUIDs identifiers: [String], completion: @escaping (Bool, Error?) -> Void) { applyChangesAndSave(changes: { [weak self] context in @@ -390,6 +408,38 @@ final class LocalBookmarkStore: BookmarkStore { } } + func bookmarkFolder(withId id: String) -> BookmarkFolder? { + let context = makeContext() + + var bookmarkFolderToReturn: BookmarkFolder? + let favoritesDisplayMode = self.favoritesDisplayMode + + context.performAndWait { + let folderFetchRequest = BaseBookmarkEntity.singleEntity(with: id) + do { + let folderFetchRequestResult = try context.fetch(folderFetchRequest) + guard let bookmarkFolderManagedObject = folderFetchRequestResult.first else { return } + + guard let bookmarkFolder = BaseBookmarkEntity.from( + managedObject: bookmarkFolderManagedObject, + parentFolderUUID: bookmarkFolderManagedObject.parent?.uuid, + favoritesDisplayMode: favoritesDisplayMode + ) as? BookmarkFolder + else { + throw BookmarkStoreError.badModelMapping + } + bookmarkFolderToReturn = bookmarkFolder + + } catch BookmarkStoreError.badModelMapping { + os_log("Failed to map BookmarkEntity to BookmarkFolder, with error: %s", log: .bookmarks, type: .error) + } catch { + os_log("Failed to fetch last saved folder for bookmarks all tabs, with error: %s", log: .bookmarks, type: .error, error.localizedDescription) + } + } + + return bookmarkFolderToReturn + } + func update(folder: BookmarkFolder) { do { _ = try applyChangesAndSave(changes: { [weak self] context in @@ -506,7 +556,7 @@ final class LocalBookmarkStore: BookmarkStore { } else if let root = self.bookmarksRoot(in: context) { parentEntity = root } else { - Pixel.fire(.debug(event: .missingParent)) + PixelKit.fire(DebugEvent(GeneralPixel.missingParent)) throw BookmarkStoreError.missingParent } @@ -720,7 +770,7 @@ final class LocalBookmarkStore: BookmarkStore { let processedErrors = CoreDataErrorsParser.parse(error: error) if NSApp.runType.requiresEnvironment { - Pixel.fire(.debug(event: .bookmarksSaveFailedOnImport, error: error), + PixelKit.fire(DebugEvent(GeneralPixel.bookmarksSaveFailedOnImport, error: error), withAdditionalParameters: processedErrors.errorPixelParameters) assertionFailure("LocalBookmarkStore: Saving of context failed, error: \(error.localizedDescription)") } @@ -856,7 +906,7 @@ final class LocalBookmarkStore: BookmarkStore { } if deletedEntityCount > 0 { - Pixel.fire(.debug(event: .removedInvalidBookmarkManagedObjects)) + PixelKit.fire(DebugEvent(GeneralPixel.removedInvalidBookmarkManagedObjects)) } } onError: { [weak self] error in self?.commonOnSaveErrorHandler(error) @@ -904,7 +954,7 @@ final class LocalBookmarkStore: BookmarkStore { let nsError = error as NSError let processedErrors = CoreDataErrorsParser.parse(error: nsError) let params = processedErrors.errorPixelParameters - Pixel.fire(.debug(event: .favoritesCleanupFailed, error: error), withAdditionalParameters: params) + PixelKit.fire(DebugEvent(GeneralPixel.favoritesCleanupFailed, error: error), withAdditionalParameters: params) } onDidSave: {} } @@ -998,32 +1048,38 @@ private extension LocalBookmarkStore { } func move(entities: [BookmarkEntity], toIndex index: Int?, withinParentFolderType type: ParentFolderType, in context: NSManagedObjectContext) throws { + let newParentFolder = try bookmarkEntity(for: type, in: context) + + if let index = index, index < newParentFolder.childrenArray.count { + self.move(entities: entities, to: index, within: newParentFolder) + } else { + for bookmarkManagedObject in entities { + bookmarkManagedObject.parent = nil + newParentFolder.addToChildren(bookmarkManagedObject) + } + } + } + + func bookmarkEntity(for parentFolderType: ParentFolderType, in context: NSManagedObjectContext) throws -> BookmarkEntity { guard let rootFolder = bookmarksRoot(in: context) else { throw BookmarkStoreError.missingRoot } - let newParentFolder: BookmarkEntity + let parentFolder: BookmarkEntity - switch type { - case .root: newParentFolder = rootFolder - case .parent(let newParentUUID): - let bookmarksFetchRequest = BaseBookmarkEntity.singleEntity(with: newParentUUID) + switch parentFolderType { + case .root: + parentFolder = rootFolder + case let .parent(parentUUID): + let bookmarksFetchRequest = BaseBookmarkEntity.singleEntity(with: parentUUID) if let fetchedParent = try context.fetch(bookmarksFetchRequest).first, fetchedParent.isFolder { - newParentFolder = fetchedParent + parentFolder = fetchedParent } else { throw BookmarkStoreError.missingEntity } } - - if let index = index, index < newParentFolder.childrenArray.count { - self.move(entities: entities, to: index, within: newParentFolder) - } else { - for bookmarkManagedObject in entities { - bookmarkManagedObject.parent = nil - newParentFolder.addToChildren(bookmarkManagedObject) - } - } + return parentFolder } } @@ -1041,6 +1097,7 @@ extension LocalBookmarkStore.BookmarkStoreError: CustomNSError { case .missingRoot: return 7 case .missingFavoritesRoot: return 8 case .saveLoopError: return 9 + case .badModelMapping: return 10 } } diff --git a/DuckDuckGo/Bookmarks/Services/UserDefaultsBookmarkFoldersStore.swift b/DuckDuckGo/Bookmarks/Services/UserDefaultsBookmarkFoldersStore.swift new file mode 100644 index 0000000000..7fb3187329 --- /dev/null +++ b/DuckDuckGo/Bookmarks/Services/UserDefaultsBookmarkFoldersStore.swift @@ -0,0 +1,48 @@ +// +// UserDefaultsBookmarkFoldersStore.swift +// +// Copyright © 2024 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. +// + +import Foundation + +/// A type used to provide the ID of the folder where all tabs were last saved. +protocol BookmarkFoldersStore: AnyObject { + /// The ID of the folder where all bookmarks from the last session were saved. + var lastBookmarkAllTabsFolderIdUsed: String? { get set } +} + +final class UserDefaultsBookmarkFoldersStore: BookmarkFoldersStore { + + enum Keys { + static let bookmarkAllTabsFolderUsedKey = "bookmarks.all-tabs.last-used-folder" + } + + private let userDefaults: UserDefaults + + init(userDefaults: UserDefaults = .standard) { + self.userDefaults = userDefaults + } + + var lastBookmarkAllTabsFolderIdUsed: String? { + get { + userDefaults.string(forKey: Keys.bookmarkAllTabsFolderUsedKey) + } + set { + userDefaults.set(newValue, forKey: Keys.bookmarkAllTabsFolderUsedKey) + } + } + +} diff --git a/DuckDuckGo/Bookmarks/View/AddBookmarkFolderPopoverView.swift b/DuckDuckGo/Bookmarks/View/AddBookmarkFolderPopoverView.swift index f15465df36..8ce41c17f2 100644 --- a/DuckDuckGo/Bookmarks/View/AddBookmarkFolderPopoverView.swift +++ b/DuckDuckGo/Bookmarks/View/AddBookmarkFolderPopoverView.swift @@ -36,7 +36,6 @@ struct AddBookmarkFolderPopoverView: ModalView { isDefaultActionDisabled: model.isDefaultActionButtonDisabled, defaultAction: { _ in model.addFolder() } ) - .padding(.vertical, 16.0) .font(.system(size: 13)) .frame(width: 320) } diff --git a/DuckDuckGo/Bookmarks/View/AddBookmarkPopoverView.swift b/DuckDuckGo/Bookmarks/View/AddBookmarkPopoverView.swift index fba84b44bc..1faa240398 100644 --- a/DuckDuckGo/Bookmarks/View/AddBookmarkPopoverView.swift +++ b/DuckDuckGo/Bookmarks/View/AddBookmarkPopoverView.swift @@ -55,7 +55,6 @@ struct AddBookmarkPopoverView: View { isDefaultActionDisabled: model.isDefaultActionButtonDisabled, defaultAction: model.doneButtonAction ) - .padding(.vertical, 16.0) .font(.system(size: 13)) .frame(width: 320) } diff --git a/DuckDuckGo/Bookmarks/View/BookmarkManagementDetailViewController.swift b/DuckDuckGo/Bookmarks/View/BookmarkManagementDetailViewController.swift index ecc643b33d..837af92acd 100644 --- a/DuckDuckGo/Bookmarks/View/BookmarkManagementDetailViewController.swift +++ b/DuckDuckGo/Bookmarks/View/BookmarkManagementDetailViewController.swift @@ -603,7 +603,7 @@ extension BookmarkManagementDetailViewController: NSMenuDelegate { } // If only one item is selected try to get the item and its parent folder otherwise show the menu for multiple items. - if tableView.selectedRowIndexes.contains(row), tableView.selectedRowIndexes.count > 1 { + if tableView.selectedRowIndexes.contains(row), tableView.selectedRowIndexes.count > 1 { return ContextualMenu.menu(for: self.selectedItems()) } diff --git a/DuckDuckGo/Bookmarks/View/Dialog/AddEditBookmarkDialogView.swift b/DuckDuckGo/Bookmarks/View/Dialog/AddEditBookmarkDialogView.swift index 2c0256bba4..78cdc6efcd 100644 --- a/DuckDuckGo/Bookmarks/View/Dialog/AddEditBookmarkDialogView.swift +++ b/DuckDuckGo/Bookmarks/View/Dialog/AddEditBookmarkDialogView.swift @@ -55,7 +55,7 @@ struct AddEditBookmarkDialogView: ModalView { isDefaultActionDisabled: viewModel.bookmarkModel.isDefaultActionDisabled, defaultAction: viewModel.bookmarkModel.addOrSave ) - .frame(width: 448, height: 288) + .frame(width: 448) } private var addFolderView: some View { diff --git a/DuckDuckGo/Bookmarks/View/Dialog/BookmarkAllTabsDialogView.swift b/DuckDuckGo/Bookmarks/View/Dialog/BookmarkAllTabsDialogView.swift new file mode 100644 index 0000000000..ad920b10c6 --- /dev/null +++ b/DuckDuckGo/Bookmarks/View/Dialog/BookmarkAllTabsDialogView.swift @@ -0,0 +1,141 @@ +// +// BookmarkAllTabsDialogView.swift +// +// Copyright © 2024 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. +// + +import SwiftUI +import SwiftUIExtensions + +struct BookmarkAllTabsDialogView: ModalView { + @ObservedObject private var viewModel: BookmarkAllTabsDialogCoordinatorViewModel + + init(viewModel: BookmarkAllTabsDialogCoordinatorViewModel) { + self.viewModel = viewModel + } + + var body: some View { + Group { + switch viewModel.viewState { + case .bookmarkAllTabs: + bookmarkAllTabsView + case .addFolder: + addFolderView + } + } + .font(.system(size: 13)) + } + + private var bookmarkAllTabsView: some View { + BookmarkDialogContainerView( + title: viewModel.bookmarkModel.title, + middleSection: { + Text(viewModel.bookmarkModel.educationalMessage) + .multilineText() + .multilineTextAlignment(.leading) + .foregroundColor(.secondary) + .font(.system(size: 11)) + BookmarkDialogStackedContentView( + .init( + title: UserText.Bookmarks.Dialog.Field.folderName, + content: TextField("", text: $viewModel.bookmarkModel.folderName) + .focusedOnAppear() + .textFieldStyle(RoundedBorderTextFieldStyle()) + .font(.system(size: 14)) + ), + .init( + title: UserText.Bookmarks.Dialog.Field.location, + content: BookmarkDialogFolderManagementView( + folders: viewModel.bookmarkModel.folders, + selectedFolder: $viewModel.bookmarkModel.selectedFolder, + onActionButton: viewModel.addFolderAction + ) + ) + ) + }, + bottomSection: { + BookmarkDialogButtonsView( + viewState: .init(.compressed), + otherButtonAction: .init( + title: viewModel.bookmarkModel.cancelActionTitle, + isDisabled: viewModel.bookmarkModel.isOtherActionDisabled, + action: viewModel.bookmarkModel.cancel + ), + defaultButtonAction: .init( + title: viewModel.bookmarkModel.defaultActionTitle, + keyboardShortCut: .defaultAction, + isDisabled: viewModel.bookmarkModel.isDefaultActionDisabled, + action: viewModel.bookmarkModel.addOrSave + ) + ) + } + + ) + .frame(width: 448) + } + + private var addFolderView: some View { + AddEditBookmarkFolderView( + title: viewModel.folderModel.title, + buttonsState: .compressed, + folders: viewModel.folderModel.folders, + folderName: $viewModel.folderModel.folderName, + selectedFolder: $viewModel.folderModel.selectedFolder, + cancelActionTitle: viewModel.folderModel.cancelActionTitle, + isCancelActionDisabled: viewModel.folderModel.isOtherActionDisabled, + cancelAction: { _ in + viewModel.dismissAction() + }, + defaultActionTitle: viewModel.folderModel.defaultActionTitle, + isDefaultActionDisabled: viewModel.folderModel.isDefaultActionDisabled, + defaultAction: { _ in + viewModel.folderModel.addOrSave { + viewModel.dismissAction() + } + } + ) + .frame(width: 448, height: 210) + } +} + +#if DEBUG +#Preview("Bookmark All Tabs - Light") { + let parentFolder = BookmarkFolder(id: "7", title: "DuckDuckGo") + let bookmark = Bookmark(id: "1", url: "www.duckduckgo.com", title: "DuckDuckGo", isFavorite: true, parentFolderUUID: "7") + let bookmarkManager = LocalBookmarkManager(bookmarkStore: BookmarkStoreMock(bookmarks: [bookmark, parentFolder])) + bookmarkManager.loadBookmarks() + let websitesInfo: [WebsiteInfo] = [ + .init(.init(content: .url(URL.duckDuckGo, credential: nil, source: .ui)))!, + .init(.init(content: .url(URL.duckDuckGoEmail, credential: nil, source: .ui)))!, + ] + + return BookmarksDialogViewFactory.makeBookmarkAllOpenTabsView(websitesInfo: websitesInfo, bookmarkManager: bookmarkManager) + .preferredColorScheme(.light) +} + +#Preview("Bookmark All Tabs - Dark") { + let parentFolder = BookmarkFolder(id: "7", title: "DuckDuckGo") + let bookmark = Bookmark(id: "1", url: "www.duckduckgo.com", title: "DuckDuckGo", isFavorite: true, parentFolderUUID: "7") + let bookmarkManager = LocalBookmarkManager(bookmarkStore: BookmarkStoreMock(bookmarks: [bookmark, parentFolder])) + bookmarkManager.loadBookmarks() + let websitesInfo: [WebsiteInfo] = [ + .init(.init(content: .url(URL.duckDuckGo, credential: nil, source: .ui)))!, + .init(.init(content: .url(URL.duckDuckGoEmail, credential: nil, source: .ui)))!, + ] + + return BookmarksDialogViewFactory.makeBookmarkAllOpenTabsView(websitesInfo: websitesInfo, bookmarkManager: bookmarkManager) + .preferredColorScheme(.dark) +} +#endif diff --git a/DuckDuckGo/Bookmarks/View/Dialog/BookmarkDialogContainerView.swift b/DuckDuckGo/Bookmarks/View/Dialog/BookmarkDialogContainerView.swift index ea49712abb..120869ea4f 100644 --- a/DuckDuckGo/Bookmarks/View/Dialog/BookmarkDialogContainerView.swift +++ b/DuckDuckGo/Bookmarks/View/Dialog/BookmarkDialogContainerView.swift @@ -42,9 +42,13 @@ struct BookmarkDialogContainerView: View { Text(title) .foregroundColor(.primary) .fontWeight(.semibold) + .padding(.top, 20) }, center: middleSection, - bottom: bottomSection + bottom: { + bottomSection() + .padding(.bottom, 16.0) + } ) } } diff --git a/DuckDuckGo/Bookmarks/View/Dialog/BookmarksDialogViewFactory.swift b/DuckDuckGo/Bookmarks/View/Dialog/BookmarksDialogViewFactory.swift index b29b50bbbb..3bff7ff4af 100644 --- a/DuckDuckGo/Bookmarks/View/Dialog/BookmarksDialogViewFactory.swift +++ b/DuckDuckGo/Bookmarks/View/Dialog/BookmarksDialogViewFactory.swift @@ -80,6 +80,18 @@ enum BookmarksDialogViewFactory { return makeAddEditBookmarkDialogView(viewModel: viewModel, bookmarkManager: bookmarkManager) } + /// Creates an instance of AddEditBookmarkDialogView for adding Bookmarks for all the open Tabs. + /// - Parameters: + /// - websitesInfo: A list of websites to add as bookmarks. + /// - bookmarkManager: An instance of `BookmarkManager`. This should be used for `#previews` only. + /// - Returns: An instance of BookmarkAllTabsDialogView + static func makeBookmarkAllOpenTabsView(websitesInfo: [WebsiteInfo], bookmarkManager: LocalBookmarkManager = .shared) -> BookmarkAllTabsDialogView { + let addFolderViewModel = AddEditBookmarkFolderDialogViewModel(mode: .add(parentFolder: nil), bookmarkManager: bookmarkManager) + let bookmarkAllTabsViewModel = BookmarkAllTabsDialogViewModel(websites: websitesInfo, foldersStore: UserDefaultsBookmarkFoldersStore(), bookmarkManager: bookmarkManager) + let viewModel = BookmarkAllTabsDialogCoordinatorViewModel(bookmarkModel: bookmarkAllTabsViewModel, folderModel: addFolderViewModel) + return BookmarkAllTabsDialogView(viewModel: viewModel) + } + } private extension BookmarksDialogViewFactory { diff --git a/DuckDuckGo/Bookmarks/ViewModel/AddEditBookmarkFolderDialogViewModel.swift b/DuckDuckGo/Bookmarks/ViewModel/AddEditBookmarkFolderDialogViewModel.swift index 62c1e0356c..48815ebc8d 100644 --- a/DuckDuckGo/Bookmarks/ViewModel/AddEditBookmarkFolderDialogViewModel.swift +++ b/DuckDuckGo/Bookmarks/ViewModel/AddEditBookmarkFolderDialogViewModel.swift @@ -42,8 +42,9 @@ final class AddEditBookmarkFolderDialogViewModel: BookmarkFolderDialogEditing { @Published var folderName: String @Published var selectedFolder: BookmarkFolder? + @Published private(set) var folders: [FolderViewModel] - let folders: [FolderViewModel] + private var folderCancellable: AnyCancellable? var title: String { mode.title @@ -77,14 +78,20 @@ final class AddEditBookmarkFolderDialogViewModel: BookmarkFolderDialogEditing { folderName = mode.folderName folders = .init(bookmarkManager.list) selectedFolder = mode.parentFolder + + bind() } func cancel(dismiss: () -> Void) { + reset() dismiss() } func addOrSave(dismiss: () -> Void) { - defer { dismiss() } + defer { + reset() + dismiss() + } guard !folderName.isEmpty else { assertionFailure("folderName is empty, button should be disabled") @@ -110,6 +117,14 @@ final class AddEditBookmarkFolderDialogViewModel: BookmarkFolderDialogEditing { private extension AddEditBookmarkFolderDialogViewModel { + func bind() { + folderCancellable = bookmarkManager.listPublisher + .receive(on: DispatchQueue.main) + .sink(receiveValue: { [weak self] bookmarkList in + self?.folders = .init(bookmarkList) + }) + } + func update(folder: BookmarkFolder, originalParent: BookmarkFolder?, newParent: BookmarkFolder?) { // If the original location of the folder changed move it to the new folder. if selectedFolder?.id != originalParent?.id { @@ -129,6 +144,10 @@ private extension AddEditBookmarkFolderDialogViewModel { } } + func reset() { + self.folderName = "" + } + } // MARK: - AddEditBookmarkFolderDialogViewModel.Mode diff --git a/DuckDuckGo/Bookmarks/ViewModel/BookmarkAllTabsDialogCoordinatorViewModel.swift b/DuckDuckGo/Bookmarks/ViewModel/BookmarkAllTabsDialogCoordinatorViewModel.swift new file mode 100644 index 0000000000..975c8811b6 --- /dev/null +++ b/DuckDuckGo/Bookmarks/ViewModel/BookmarkAllTabsDialogCoordinatorViewModel.swift @@ -0,0 +1,74 @@ +// +// BookmarkAllTabsDialogCoordinatorViewModel.swift +// +// Copyright © 2024 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. +// + +import SwiftUI +import Combine + +final class BookmarkAllTabsDialogCoordinatorViewModel: ObservableObject { + @ObservedObject var bookmarkModel: BookmarkViewModel + @ObservedObject var folderModel: AddFolderViewModel + @Published var viewState: ViewState + + private var cancellables: Set = [] + + init(bookmarkModel: BookmarkViewModel, folderModel: AddFolderViewModel) { + self.bookmarkModel = bookmarkModel + self.folderModel = folderModel + viewState = .bookmarkAllTabs + bind() + } + + func dismissAction() { + viewState = .bookmarkAllTabs + } + + func addFolderAction() { + folderModel.selectedFolder = bookmarkModel.selectedFolder + viewState = .addFolder + } + + private func bind() { + bookmarkModel.objectWillChange + .receive(on: DispatchQueue.main) + .sink { [weak self] _ in + self?.objectWillChange.send() + } + .store(in: &cancellables) + + folderModel.objectWillChange + .receive(on: DispatchQueue.main) + .sink { [weak self] _ in + self?.objectWillChange.send() + } + .store(in: &cancellables) + + folderModel.addFolderPublisher + .receive(on: DispatchQueue.main) + .sink { [weak self] bookmarkFolder in + self?.bookmarkModel.selectedFolder = bookmarkFolder + } + .store(in: &cancellables) + } +} + +extension BookmarkAllTabsDialogCoordinatorViewModel { + enum ViewState { + case bookmarkAllTabs + case addFolder + } +} diff --git a/DuckDuckGo/Bookmarks/ViewModel/BookmarkAllTabsDialogViewModel.swift b/DuckDuckGo/Bookmarks/ViewModel/BookmarkAllTabsDialogViewModel.swift new file mode 100644 index 0000000000..daf6018403 --- /dev/null +++ b/DuckDuckGo/Bookmarks/ViewModel/BookmarkAllTabsDialogViewModel.swift @@ -0,0 +1,127 @@ +// +// BookmarkAllTabsDialogViewModel.swift +// +// Copyright © 2024 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. +// + +import Foundation +import Combine + +@MainActor +protocol BookmarkAllTabsDialogEditing: BookmarksDialogViewModel { + var folderName: String { get set } + var educationalMessage: String { get } + var folderNameFieldTitle: String { get } + var locationFieldTitle: String { get } +} + +final class BookmarkAllTabsDialogViewModel: BookmarkAllTabsDialogEditing { + private static let dateFormatter: ISO8601DateFormatter = { + let formatter = ISO8601DateFormatter() + formatter.formatOptions = [.withFullDate, .withDashSeparatorInDate] + return formatter + }() + + private let websites: [WebsiteInfo] + private let foldersStore: BookmarkFoldersStore + private let bookmarkManager: BookmarkManager + + private var folderCancellable: AnyCancellable? + + @Published private(set) var folders: [FolderViewModel] + @Published var selectedFolder: BookmarkFolder? + @Published var folderName: String + + var title: String { + String(format: UserText.Bookmarks.Dialog.Title.bookmarkOpenTabs, websites.count) + } + let cancelActionTitle = UserText.cancel + let defaultActionTitle = UserText.Bookmarks.Dialog.Action.addAllBookmarks + let educationalMessage = UserText.Bookmarks.Dialog.Message.bookmarkOpenTabsEducational + let folderNameFieldTitle = UserText.Bookmarks.Dialog.Field.folderName + let locationFieldTitle = UserText.Bookmarks.Dialog.Field.location + let isOtherActionDisabled = false + + var isDefaultActionDisabled: Bool { + folderName.trimmingWhitespace().isEmpty + } + + init( + websites: [WebsiteInfo], + foldersStore: BookmarkFoldersStore, + bookmarkManager: BookmarkManager = LocalBookmarkManager.shared, + dateFormatterConfigurationProvider: () -> DateFormatterConfiguration = DateFormatterConfiguration.defaultConfiguration + ) { + self.websites = websites + self.foldersStore = foldersStore + self.bookmarkManager = bookmarkManager + + folders = .init(bookmarkManager.list) + selectedFolder = foldersStore.lastBookmarkAllTabsFolderIdUsed.flatMap(bookmarkManager.getBookmarkFolder(withId:)) + folderName = Self.folderName(configuration: dateFormatterConfigurationProvider(), websitesNumber: websites.count) + bind() + } + + func cancel(dismiss: () -> Void) { + dismiss() + } + + func addOrSave(dismiss: () -> Void) { + // Save last used folder + foldersStore.lastBookmarkAllTabsFolderIdUsed = selectedFolder?.id + + // Save all bookmarks + let parentFolder: ParentFolderType = selectedFolder.flatMap { .parent(uuid: $0.id) } ?? .root + bookmarkManager.makeBookmarks(for: websites, inNewFolderNamed: folderName, withinParentFolder: parentFolder) + + // Dismiss the view + dismiss() + } +} + +// MARK: - Private + +private extension BookmarkAllTabsDialogViewModel { + + static func folderName(configuration: DateFormatterConfiguration, websitesNumber: Int) -> String { + Self.dateFormatter.timeZone = configuration.timeZone + let dateString = Self.dateFormatter.string(from: configuration.date) + return String(format: UserText.Bookmarks.Dialog.Value.folderName, dateString, websitesNumber) + } + + func bind() { + folderCancellable = bookmarkManager.listPublisher + .receive(on: DispatchQueue.main) + .sink(receiveValue: { [weak self] bookmarkList in + self?.folders = .init(bookmarkList) + }) + } + +} + +// MARK: - DateConfiguration + +extension BookmarkAllTabsDialogViewModel { + + struct DateFormatterConfiguration { + let date: Date + let timeZone: TimeZone + + static func defaultConfiguration() -> DateFormatterConfiguration { + .init(date: Date(), timeZone: .current) + } + } + +} diff --git a/DuckDuckGo/Common/Database/Database.swift b/DuckDuckGo/Common/Database/Database.swift index 10e116d3a7..dee8aef2d8 100644 --- a/DuckDuckGo/Common/Database/Database.swift +++ b/DuckDuckGo/Common/Database/Database.swift @@ -21,6 +21,7 @@ import BrowserServicesKit import CoreData import Foundation import Persistence +import PixelKit final class Database { @@ -100,7 +101,7 @@ final class Database { // Fire the pixel once a day at max if lastPixelSentAt < Date.daysAgo(1) { lastDatabaseFactoryFailurePixelDate = Date() - Pixel.fire(.debug(event: .dbMakeDatabaseError, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.dbMakeDatabaseError(error: error))) } } } @@ -185,14 +186,14 @@ extension NSManagedObjectModel { extension NSManagedObjectContext { - func save(onErrorFire event: Pixel.Event.Debug) throws { + func save(onErrorFire event: PixelKitEventV2) throws { do { try save() } catch { let nsError = error as NSError let processedErrors = CoreDataErrorsParser.parse(error: nsError) - Pixel.fire(.debug(event: event, error: error), + PixelKit.fire(DebugEvent(event, error: error), withAdditionalParameters: processedErrors.errorPixelParameters) throw error diff --git a/DuckDuckGo/Common/Extensions/NSPointExtension.swift b/DuckDuckGo/Common/Extensions/NSPointExtension.swift index 18bfbf0c2e..594cea0de4 100644 --- a/DuckDuckGo/Common/Extensions/NSPointExtension.swift +++ b/DuckDuckGo/Common/Extensions/NSPointExtension.swift @@ -20,6 +20,12 @@ import Foundation extension NSPoint { + func distance(to point: NSPoint) -> CGFloat { + let deltaX = self.x - point.x + let deltaY = self.y - point.y + return sqrt(deltaX * deltaX + deltaY * deltaY) + } + func isNearRect(_ rect: NSRect, allowedDistance: CGFloat) -> Bool { let expandedRect = rect.insetBy(dx: -allowedDistance, dy: -allowedDistance) return expandedRect.contains(self) diff --git a/DuckDuckGo/Common/Extensions/URLExtension.swift b/DuckDuckGo/Common/Extensions/URLExtension.swift index 3d95ae07f1..62b6c8fc2b 100644 --- a/DuckDuckGo/Common/Extensions/URLExtension.swift +++ b/DuckDuckGo/Common/Extensions/URLExtension.swift @@ -24,6 +24,7 @@ import Foundation extension URL.NavigationalScheme { static let duck = URL.NavigationalScheme(rawValue: "duck") + static let javascript = URL.NavigationalScheme(rawValue: "javascript") static var validSchemes: [URL.NavigationalScheme] { return [.http, .https, .file] @@ -278,6 +279,14 @@ extension URL { return string } + func hostAndPort() -> String? { + guard let host else { return nil } + + guard let port = port else { return host } + + return "\(host):\(port)" + } + #if !SANDBOX_TEST_TOOL func toString(forUserInput input: String, decodePunycode: Bool = true) -> String { let hasInputScheme = input.hasOrIsPrefix(of: self.separatedScheme ?? "") @@ -323,7 +332,7 @@ extension URL { } var isExternalSchemeLink: Bool { - return !["https", "http", "about", "file", "blob", "data", "ftp"].contains(scheme) + return ![.https, .http, .about, .file, .blob, .data, .ftp, .javascript].contains(navigationalScheme) } // MARK: - DuckDuckGo @@ -524,6 +533,8 @@ extension URL { static var fullDiskAccess = URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles")! + static var touchIDAndPassword = URL(string: "x-apple.systempreferences:com.apple.preferences.password")! + // MARK: - Blob URLs var isBlobURL: Bool { @@ -546,10 +557,8 @@ extension URL { return self.absoluteString } - public func isChild(of url: URL) -> Bool { - var components = URLComponents(string: url.absoluteString) - components?.query = nil - - return self.absoluteString.hasPrefix(components?.url?.absoluteString ?? url.absoluteString) + public func isChild(of parentURL: URL) -> Bool { + guard let parentURLHost = parentURL.host, self.isPart(ofDomain: parentURLHost) else { return false } + return pathComponents.starts(with: parentURL.pathComponents) } } diff --git a/DuckDuckGo/Common/Extensions/WKWebView+Private.h b/DuckDuckGo/Common/Extensions/WKWebView+Private.h index b5e8c44d99..daa465149f 100644 --- a/DuckDuckGo/Common/Extensions/WKWebView+Private.h +++ b/DuckDuckGo/Common/Extensions/WKWebView+Private.h @@ -63,8 +63,6 @@ typedef NS_OPTIONS(NSUInteger, _WKFindOptions) { - (void)_stopMediaCapture API_AVAILABLE(macos(10.15.4), ios(13.4)); - (void)_stopAllMediaPlayback; -- (_WKMediaMutedState)_mediaMutedState API_AVAILABLE(macos(11.0), ios(14.0));; -- (void)_setPageMuted:(_WKMediaMutedState)mutedState API_AVAILABLE(macos(10.13), ios(11.0)); @end diff --git a/DuckDuckGo/Common/Extensions/WKWebViewExtension.swift b/DuckDuckGo/Common/Extensions/WKWebViewExtension.swift index fcd19de900..5f7a7b316c 100644 --- a/DuckDuckGo/Common/Extensions/WKWebViewExtension.swift +++ b/DuckDuckGo/Common/Extensions/WKWebViewExtension.swift @@ -32,7 +32,17 @@ extension WKWebView { enum AudioState { case muted case unmuted - case notSupported + + init(wkMediaMutedState: _WKMediaMutedState) { + self = wkMediaMutedState.contains(.audioMuted) ? .muted : .unmuted + } + + mutating func toggle() { + self = switch self { + case .muted: .unmuted + case .unmuted: .muted + } + } } enum CaptureState { @@ -114,96 +124,84 @@ extension WKWebView { return .active } -#if !APPSTORE - private func setMediaCaptureMuted(_ muted: Bool) { - guard self.responds(to: #selector(WKWebView._setPageMuted(_:))) else { - assertionFailure("WKWebView does not respond to selector _stopMediaCapture") - return + @objc dynamic var mediaMutedState: _WKMediaMutedState { + get { + // swizzle the method to call `_mediaMutedState` without performSelector: usage + guard Self.swizzleMediaMutedStateOnce else { return [] } + return self.mediaMutedState // call the original } - let mutedState: _WKMediaMutedState = { - guard self.responds(to: #selector(WKWebView._mediaMutedState)) else { return [] } - return self._mediaMutedState() - }() - var newState = mutedState - if muted { - newState.insert(.captureDevicesMuted) - } else { - newState.remove(.captureDevicesMuted) + set { + // swizzle the method to call `_setPageMuted:` without performSelector: usage (as there‘s a non-object argument to pass) + guard Self.swizzleSetPageMutedOnce else { return } + self.mediaMutedState = newValue // call the original } - guard newState != mutedState else { return } - self._setPageMuted(newState) } -#endif - func muteOrUnmute() { -#if !APPSTORE - guard self.responds(to: #selector(WKWebView._setPageMuted(_:))) else { - assertionFailure("WKWebView does not respond to selector _stopMediaCapture") - return + static private let swizzleMediaMutedStateOnce: Bool = { + guard let originalMethod = class_getInstanceMethod(WKWebView.self, Selector.mediaMutedState), + let swizzledMethod = class_getInstanceMethod(WKWebView.self, #selector(getter: mediaMutedState)) else { + assertionFailure("WKWebView does not respond to selector _mediaMutedState") + return false } - let mutedState: _WKMediaMutedState = { - guard self.responds(to: #selector(WKWebView._mediaMutedState)) else { return [] } - return self._mediaMutedState() - }() - var newState = mutedState - - if newState == .audioMuted { - newState.remove(.audioMuted) - } else { - newState.insert(.audioMuted) + method_exchangeImplementations(originalMethod, swizzledMethod) + return true + }() + + static private let swizzleSetPageMutedOnce: Bool = { + guard let originalMethod = class_getInstanceMethod(WKWebView.self, Selector.setPageMuted), + let swizzledMethod = class_getInstanceMethod(WKWebView.self, #selector(setter: mediaMutedState)) else { + assertionFailure("WKWebView does not respond to selector _setPageMuted:") + return false } - guard newState != mutedState else { return } - self._setPageMuted(newState) -#endif - } + method_exchangeImplementations(originalMethod, swizzledMethod) + return true + }() /// Returns the audio state of the WKWebView. /// /// - Returns: `muted` if the web view is muted /// `unmuted` if the web view is unmuted - /// `notSupported` if the web view does not support fetching the current audio state - func audioState() -> AudioState { -#if APPSTORE - return .notSupported -#else - guard self.responds(to: #selector(WKWebView._mediaMutedState)) else { - assertionFailure("WKWebView does not respond to selector _mediaMutedState") - return .notSupported + var audioState: AudioState { + get { + AudioState(wkMediaMutedState: mediaMutedState) + } + set { + switch newValue { + case .muted: + self.mediaMutedState.insert(.audioMuted) + case .unmuted: + self.mediaMutedState.remove(.audioMuted) + } } - - let mutedState = self._mediaMutedState() - - return mutedState.contains(.audioMuted) ? .muted : .unmuted -#endif } func stopMediaCapture() { - guard #available(macOS 12.0, *) else { #if !APPSTORE + guard #available(macOS 12.0, *) else { guard self.responds(to: #selector(_stopMediaCapture)) else { assertionFailure("WKWebView does not respond to _stopMediaCapture") return } self._stopMediaCapture() -#endif return } +#endif setCameraCaptureState(.none) setMicrophoneCaptureState(.none) } func stopAllMediaPlayback() { - guard #available(macOS 12.0, *) else { #if !APPSTORE + guard #available(macOS 12.0, *) else { guard self.responds(to: #selector(_stopAllMediaPlayback)) else { assertionFailure("WKWebView does not respond to _stopAllMediaPlayback") return } self._stopAllMediaPlayback() return -#endif } +#endif pauseAllMediaPlayback() } @@ -212,20 +210,26 @@ extension WKWebView { switch permission { case .camera: guard #available(macOS 12.0, *) else { -#if !APPSTORE - self.setMediaCaptureMuted(muted) -#endif + if muted { + self.mediaMutedState.insert(.captureDevicesMuted) + } else { + self.mediaMutedState.remove(.captureDevicesMuted) + } return } + self.setCameraCaptureState(muted ? .muted : .active, completionHandler: {}) case .microphone: guard #available(macOS 12.0, *) else { -#if !APPSTORE - self.setMediaCaptureMuted(muted) -#endif + if muted { + self.mediaMutedState.insert(.captureDevicesMuted) + } else { + self.mediaMutedState.remove(.captureDevicesMuted) + } return } + self.setMicrophoneCaptureState(muted ? .muted : .active, completionHandler: {}) case .geolocation: self.configuration.processPool.geolocationProvider?.isPaused = muted @@ -360,6 +364,8 @@ extension WKWebView { static let fullScreenPlaceholderView = NSSelectorFromString("_fullScreenPlaceholderView") static let printOperationWithPrintInfoForFrame = NSSelectorFromString("_printOperationWithPrintInfo:forFrame:") static let loadAlternateHTMLString = NSSelectorFromString("_loadAlternateHTMLString:baseURL:forUnreachableURL:") + static let mediaMutedState = NSSelectorFromString("_mediaMutedState") + static let setPageMuted = NSSelectorFromString("_setPageMuted:") } } diff --git a/DuckDuckGo/Common/FileSystem/FileStore.swift b/DuckDuckGo/Common/FileSystem/FileStore.swift index 99b03e5a01..22dc52c7d1 100644 --- a/DuckDuckGo/Common/FileSystem/FileStore.swift +++ b/DuckDuckGo/Common/FileSystem/FileStore.swift @@ -18,6 +18,7 @@ import Foundation import CryptoKit +import PixelKit protocol FileStore { func persist(_ data: Data, url: URL) -> Bool @@ -57,7 +58,7 @@ final class EncryptedFileStore: FileStore { return true } catch { - Pixel.fire(.debug(event: .fileStoreWriteFailed, error: error), + PixelKit.fire(DebugEvent(GeneralPixel.fileStoreWriteFailed, error: error), withAdditionalParameters: ["config": url.lastPathComponent]) return false } diff --git a/DuckDuckGo/Common/Localizables/UserText+NetworkProtection.swift b/DuckDuckGo/Common/Localizables/UserText+NetworkProtection.swift index 2a5ec04f2d..4dd17342ea 100644 --- a/DuckDuckGo/Common/Localizables/UserText+NetworkProtection.swift +++ b/DuckDuckGo/Common/Localizables/UserText+NetworkProtection.swift @@ -42,8 +42,8 @@ extension UserText { static let networkProtectionInviteSuccessMessage = "DuckDuckGo's VPN secures all of your device's Internet traffic anytime, anywhere." // MARK: - Navigation Bar Status View - // "network.protection.navbar.status.view.share.feedback" - Menu item for 'Send VPN Feedback' in the VPN status view that's shown in the navigation bar - static let networkProtectionNavBarStatusViewShareFeedback = "Send VPN Feedback…" + // "network.protection.navbar.status.view.share.feedback" - Menu item for 'Share VPN Feedback' in the VPN status view that's shown in the navigation bar + static let networkProtectionNavBarStatusViewShareFeedback = "Share VPN Feedback…" // "network.protection.status.menu.vpn.settings" - The status menu 'VPN Settings' menu item static let networkProtectionNavBarStatusMenuVPNSettings = "VPN Settings…" // "network.protection.status.menu.faq" - The status menu 'FAQ' menu item @@ -299,7 +299,7 @@ extension UserText { // "vpn.location.description.nearest" - Nearest city setting description static let vpnLocationNearest = "Nearest" // "vpn.location.description.nearest.available" - Nearest available location setting description - static let vpnLocationNearestAvailable = "Nearest available" + static let vpnLocationNearestAvailable = "Nearest Location" // "vpn.location.nearest.available.title" - Subtitle underneath the nearest available vpn location preference text. static let vpnLocationNearestAvailableSubtitle = "Automatically connect to the nearest server we can find." @@ -330,6 +330,15 @@ extension UserText { static let uninstallVPNAlertTitle = "Are you sure you want to uninstall the VPN?" // "vpn.uninstall.alert.informative.text" - Informative text for the alert that comes up when the user decides to uninstall our VPN static let uninstallVPNInformativeText = "Uninstalling the DuckDuckGo VPN will disconnect the VPN and remove it from your device." + + // MARK: - VPN Screen + // "network.protection.vpn.location.nearest" - Description of the location type in the VPN status view + static let netPVPNLocationNearest = "(Nearest)" + + // "network.protection.vpn.location.subtitle.formatted.city.and.country" - Subtitle for the preferred location item that formats a city and country. E.g Chicago, United States + static func netPVPNSettingsLocationSubtitleFormattedCityAndCountry(city: String, country: String) -> String { + return "\(city), \(country)" + } } #if DBP diff --git a/DuckDuckGo/Common/Localizables/UserText.swift b/DuckDuckGo/Common/Localizables/UserText.swift index 0337f4f9a6..a201afff72 100644 --- a/DuckDuckGo/Common/Localizables/UserText.swift +++ b/DuckDuckGo/Common/Localizables/UserText.swift @@ -66,54 +66,54 @@ struct UserText { } // MARK: - Main Menu -> DuckDuckGo - static let mainMenuAppPreferences = NSLocalizedString("main-menu.app.preferences" ,value:"Preferences…", comment: "Main Menu DuckDuckGo item") - static let mainMenuAppServices = NSLocalizedString("main-menu.app.services", value:"Services", comment: "Main Menu DuckDuckGo item") - static let mainMenuAppCheckforUpdates = NSLocalizedString("main-menu.app.check-for-updates", value:"Check for Updates…", comment: "Main Menu DuckDuckGo item") - static let mainMenuAppHideDuckDuckGo = NSLocalizedString("main-menu.app.hide-duck-duck-go", value:"Hide DuckDuckGo", comment: "Main Menu DuckDuckGo item") - static let mainMenuAppHideOthers = NSLocalizedString("main-menu.app.hide-others", value:"Hide Others", comment: "Main Menu DuckDuckGo item") - static let mainMenuAppShowAll = NSLocalizedString("main-menu.app.show-all", value:"Show All", comment: "Main Menu DuckDuckGo item") - static let mainMenuAppQuitDuckDuckGo = NSLocalizedString("main-menu.app.quit-duck-duck-go", value:"Quit DuckDuckGo", comment: "Main Menu DuckDuckGo item") + static let mainMenuAppPreferences = NSLocalizedString("main-menu.app.preferences", value: "Preferences…", comment: "Main Menu DuckDuckGo item") + static let mainMenuAppServices = NSLocalizedString("main-menu.app.services", value: "Services", comment: "Main Menu DuckDuckGo item") + static let mainMenuAppCheckforUpdates = NSLocalizedString("main-menu.app.check-for-updates", value: "Check for Updates…", comment: "Main Menu DuckDuckGo item") + static let mainMenuAppHideDuckDuckGo = NSLocalizedString("main-menu.app.hide-duck-duck-go", value: "Hide DuckDuckGo", comment: "Main Menu DuckDuckGo item") + static let mainMenuAppHideOthers = NSLocalizedString("main-menu.app.hide-others", value: "Hide Others", comment: "Main Menu DuckDuckGo item") + static let mainMenuAppShowAll = NSLocalizedString("main-menu.app.show-all", value: "Show All", comment: "Main Menu DuckDuckGo item") + static let mainMenuAppQuitDuckDuckGo = NSLocalizedString("main-menu.app.quit-duck-duck-go", value: "Quit DuckDuckGo", comment: "Main Menu DuckDuckGo item") // MARK: - Main Menu -> -File - static let mainMenuFile = NSLocalizedString("main-menu.file", value:"File", comment: "Main Menu File") - static let mainMenuFileNewTab = NSLocalizedString("main-menu.file.new-tab", value:"New Tab", comment: "Main Menu File item") - static let mainMenuFileOpenLocation = NSLocalizedString("main-menu.file.open-location", value:"Open Location…", comment: "Main Menu File item- Menu option that allows the user to connect to an address (type an address) on click the address bar of the browser is selected and the user can type.") - static let mainMenuFileCloseWindow = NSLocalizedString("main-menu.file.close-window", value:"Close Window", comment: "Main Menu File item") - static let mainMenuFileCloseAllWindows = NSLocalizedString("main-menu.file.close-all-windows", value:"Close All Windows", comment: "Main Menu File item") - static let mainMenuFileSaveAs = NSLocalizedString("main-menu.file.save-as", value:"Save As…", comment: "Main Menu File item") - static let mainMenuFileImportBookmarksandPasswords = NSLocalizedString("main-menu.file.import-bookmarks-and-passwords", value:"Import Bookmarks and Passwords…", comment: "Main Menu File item") - static let mainMenuFileExport = NSLocalizedString("main-menu.file.export", value:"Export", comment: "Main Menu File item") - static let mainMenuFileExportPasswords = NSLocalizedString("main-menu.file.export-passwords", value:"Passwords…", comment: "Main Menu File-Export item") - static let mainMenuFileExportBookmarks = NSLocalizedString("main-menu.file.export-bookmarks", value:"Bookmarks…", comment: "Main Menu File-Export item") + static let mainMenuFile = NSLocalizedString("main-menu.file", value: "File", comment: "Main Menu File") + static let mainMenuFileNewTab = NSLocalizedString("main-menu.file.new-tab", value: "New Tab", comment: "Main Menu File item") + static let mainMenuFileOpenLocation = NSLocalizedString("main-menu.file.open-location", value: "Open Location…", comment: "Main Menu File item- Menu option that allows the user to connect to an address (type an address) on click the address bar of the browser is selected and the user can type.") + static let mainMenuFileCloseWindow = NSLocalizedString("main-menu.file.close-window", value: "Close Window", comment: "Main Menu File item") + static let mainMenuFileCloseAllWindows = NSLocalizedString("main-menu.file.close-all-windows", value: "Close All Windows", comment: "Main Menu File item") + static let mainMenuFileSaveAs = NSLocalizedString("main-menu.file.save-as", value: "Save As…", comment: "Main Menu File item") + static let mainMenuFileImportBookmarksandPasswords = NSLocalizedString("main-menu.file.import-bookmarks-and-passwords", value: "Import Bookmarks and Passwords…", comment: "Main Menu File item") + static let mainMenuFileExport = NSLocalizedString("main-menu.file.export", value: "Export", comment: "Main Menu File item") + static let mainMenuFileExportPasswords = NSLocalizedString("main-menu.file.export-passwords", value: "Passwords…", comment: "Main Menu File-Export item") + static let mainMenuFileExportBookmarks = NSLocalizedString("main-menu.file.export-bookmarks", value: "Bookmarks…", comment: "Main Menu File-Export item") // MARK: - Main Menu -> Edit - static let mainMenuEdit = NSLocalizedString("main-menu.edit", value:"Edit", comment: "Main Menu Edit") - static let mainMenuEditUndo = NSLocalizedString("main-menu.edit.undo", value:"Undo", comment: "Main Menu Edit item") - static let mainMenuEditRedo = NSLocalizedString("main-menu.edit.redo", value:"Redo", comment: "Main Menu Edit item") - static let mainMenuEditCut = NSLocalizedString("main-menu.edit.cut", value:"Cut", comment: "Main Menu Edit item") - static let mainMenuEditCopy = NSLocalizedString("main-menu.edit.copy", value:"Copy", comment: "Main Menu Edit item") - static let mainMenuEditPaste = NSLocalizedString("main-menu.edit.paste", value:"Paste", comment: "Main Menu Edit item") - static let mainMenuEditPasteAndMatchStyle = NSLocalizedString("main-menu.edit.paste-and-match-style", value:"Paste and Match Style", comment: "Main Menu Edit item - Action that allows the user to paste copy into a target document and the target document's style will be retained (instead of the source style)") - static let mainMenuEditDelete = NSLocalizedString("main-menu.edit.delete", value:"Delete", comment: "Main Menu Edit item") - static let mainMenuEditSelectAll = NSLocalizedString("main-menu.edit.select-all", value:"Select All", comment: "Main Menu Edit item") - - static let mainMenuEditFind = NSLocalizedString("main-menu.edit.find", value:"Find", comment: "Main Menu Edit item") + static let mainMenuEdit = NSLocalizedString("main-menu.edit", value: "Edit", comment: "Main Menu Edit") + static let mainMenuEditUndo = NSLocalizedString("main-menu.edit.undo", value: "Undo", comment: "Main Menu Edit item") + static let mainMenuEditRedo = NSLocalizedString("main-menu.edit.redo", value: "Redo", comment: "Main Menu Edit item") + static let mainMenuEditCut = NSLocalizedString("main-menu.edit.cut", value: "Cut", comment: "Main Menu Edit item") + static let mainMenuEditCopy = NSLocalizedString("main-menu.edit.copy", value: "Copy", comment: "Main Menu Edit item") + static let mainMenuEditPaste = NSLocalizedString("main-menu.edit.paste", value: "Paste", comment: "Main Menu Edit item") + static let mainMenuEditPasteAndMatchStyle = NSLocalizedString("main-menu.edit.paste-and-match-style", value: "Paste and Match Style", comment: "Main Menu Edit item - Action that allows the user to paste copy into a target document and the target document's style will be retained (instead of the source style)") + static let mainMenuEditDelete = NSLocalizedString("main-menu.edit.delete", value: "Delete", comment: "Main Menu Edit item") + static let mainMenuEditSelectAll = NSLocalizedString("main-menu.edit.select-all", value: "Select All", comment: "Main Menu Edit item") + + static let mainMenuEditFind = NSLocalizedString("main-menu.edit.find", value: "Find", comment: "Main Menu Edit item") // MARK: Main Menu -> Edit -> Find - static let mainMenuEditFindFindNext = NSLocalizedString("main-menu.edit.find.find-next", value:"Find Next", comment: "Main Menu Edit-Find item") - static let mainMenuEditFindFindPrevious = NSLocalizedString("main-menu.edit.find.find-previous", value:"Find Previous", comment: "Main Menu Edit-Find item") - static let mainMenuEditFindHideFind = NSLocalizedString("main-menu.edit.find.hide-find", value:"Hide Find", comment: "Main Menu Edit-Find item") + static let mainMenuEditFindFindNext = NSLocalizedString("main-menu.edit.find.find-next", value: "Find Next", comment: "Main Menu Edit-Find item") + static let mainMenuEditFindFindPrevious = NSLocalizedString("main-menu.edit.find.find-previous", value: "Find Previous", comment: "Main Menu Edit-Find item") + static let mainMenuEditFindHideFind = NSLocalizedString("main-menu.edit.find.hide-find", value: "Hide Find", comment: "Main Menu Edit-Find item") static let mainMenuEditSpellingandGrammar = NSLocalizedString("main-menu.edit.edit-spelling-and-grammar", value: "Spelling and Grammar", comment: "Main Menu Edit item") // MARK: Main Menu -> Edit -> Spellingand - static let mainMenuEditSpellingandShowSpellingandGrammar = NSLocalizedString("main-menu.edit.spelling-and.show-spelling-and-grammar", value:"Show Spelling and Grammar", comment: "Main Menu Edit-Spellingand item") - static let mainMenuEditSpellingandCheckDocumentNow = NSLocalizedString("main-menu.edit.spelling-and.check-document-now", value:"Check Document Now", comment: "Main Menu Edit-Spellingand item") - static let mainMenuEditSpellingandCheckSpellingWhileTyping = NSLocalizedString("main-menu.edit.spelling-and.check-spelling-while-typing", value:"Check Spelling While Typing", comment: "Main Menu Edit-Spellingand item") - static let mainMenuEditSpellingandCheckGrammarWithSpelling = NSLocalizedString("main-menu.edit.spelling-and.check-grammar-with-spelling", value:"Check Grammar With Spelling", comment: "Main Menu Edit-Spellingand item") - static let mainMenuEditSpellingandCorrectSpellingAutomatically = NSLocalizedString("main-menu.edit.spelling-and.correct-spelling-automatically", value:"Correct Spelling Automatically", comment: "Main Menu Edit-Spellingand item") + static let mainMenuEditSpellingandShowSpellingandGrammar = NSLocalizedString("main-menu.edit.spelling-and.show-spelling-and-grammar", value: "Show Spelling and Grammar", comment: "Main Menu Edit-Spellingand item") + static let mainMenuEditSpellingandCheckDocumentNow = NSLocalizedString("main-menu.edit.spelling-and.check-document-now", value: "Check Document Now", comment: "Main Menu Edit-Spellingand item") + static let mainMenuEditSpellingandCheckSpellingWhileTyping = NSLocalizedString("main-menu.edit.spelling-and.check-spelling-while-typing", value: "Check Spelling While Typing", comment: "Main Menu Edit-Spellingand item") + static let mainMenuEditSpellingandCheckGrammarWithSpelling = NSLocalizedString("main-menu.edit.spelling-and.check-grammar-with-spelling", value: "Check Grammar With Spelling", comment: "Main Menu Edit-Spellingand item") + static let mainMenuEditSpellingandCorrectSpellingAutomatically = NSLocalizedString("main-menu.edit.spelling-and.correct-spelling-automatically", value: "Correct Spelling Automatically", comment: "Main Menu Edit-Spellingand item") - static let mainMenuEditSubstitutions = NSLocalizedString("main-menu.edit.subsitutions", value:"Substitutions", comment: "Main Menu Edit item") + static let mainMenuEditSubstitutions = NSLocalizedString("main-menu.edit.subsitutions", value: "Substitutions", comment: "Main Menu Edit item") // TODO: Done till here // MARK: Main Menu -> Edit -> Substitutions static let mainMenuEditSubstitutionsShowSubstitutions = NSLocalizedString("Show Substitutions", comment: "Main Menu Edit-Substitutions item") @@ -143,7 +143,7 @@ struct UserText { static let mainMenuViewReloadPage = NSLocalizedString("Reload Page", comment: "Main Menu View item") static let mainMenuViewHome = NSLocalizedString("Home", comment: "Main Menu View item") static let mainMenuHomeButton = NSLocalizedString("Home Button", comment: "Main Menu > View > Home Button item") - + static func mainMenuHomeButtonMode(for position: HomeButtonPosition) -> String { switch position { case .hidden: @@ -154,7 +154,7 @@ struct UserText { return NSLocalizedString("main.menu.home.button.mode.right", value: "Show Right of the Reload Button", comment: "Main Menu > View > Home Button > right position item") } } - + static let mainMenuViewShowAutofillShortcut = NSLocalizedString("Show Autofill Shortcut", comment: "Main Menu View item") static let mainMenuViewShowBookmarksShortcut = NSLocalizedString("Show Bookmarks Shortcut", comment: "Main Menu View item") static let mainMenuViewShowDownloadsShortcut = NSLocalizedString("Show Downloads Shortcut", comment: "Main Menu View item") @@ -212,6 +212,7 @@ struct UserText { static let addFolder = NSLocalizedString("menu.add.folder", value: "Add Folder…", comment: "Menu item to add a folder") static let tabHomeTitle = NSLocalizedString("tab.home.title", value: "New Tab", comment: "Tab home title") + static let tabUntitledTitle = NSLocalizedString("tab.empty.title", value: "Untitled", comment: "Title for an empty tab without a title") static let tabPreferencesTitle = NSLocalizedString("tab.preferences.title", value: "Settings", comment: "Tab preferences title") static let tabBookmarksTitle = NSLocalizedString("tab.bookmarks.title", value: "Bookmarks", comment: "Tab bookmarks title") static let tabOnboardingTitle = NSLocalizedString("tab.onboarding.title", value: "Welcome", comment: "Tab onboarding title") @@ -391,7 +392,7 @@ struct UserText { static let restartBitwarden = NSLocalizedString("restart.bitwarden", value: "Restart Bitwarden", comment: "Button to restart Bitwarden application") static let restartBitwardenInfo = NSLocalizedString("restart.bitwarden.info", value: "Bitwarden is not responding. Please restart it to initiate the communication again", comment: "This string represents a message informing the user that Bitwarden is not responding and prompts them to restart the application to initiate communication again.") - static let autofillViewContentButton = NSLocalizedString("autofill.view-autofill-content", value: "View Autofill Content…", comment: "View Autofill Content Button name in the autofill settings") + static let autofillViewContentButton = NSLocalizedString("autofill.view-autofill-content", value: "View Autofill Content…", comment: "View Autofill Content Button name in the autofill settings") static let autofillAskToSave = NSLocalizedString("autofill.ask-to-save", value: "Save and Autofill", comment: "Autofill settings section title") static let autofillAskToSaveExplanation = NSLocalizedString("autofill.ask-to-save.explanation", value: "Receive prompts to save new information and autofill online forms.", comment: "Description of Autofill autosaving feature - used in settings") static let autofillUsernamesAndPasswords = NSLocalizedString("autofill.usernames-and-passwords", value: "Usernames and passwords", comment: "Autofill autosaved data type") @@ -400,14 +401,14 @@ struct UserText { static let autofillExcludedSites = NSLocalizedString("autofill.excluded-sites", value: "Excluded Sites", comment: "Autofill settings section title") static let autofillExcludedSitesExplanation = NSLocalizedString("autofill.excluded-sites.explanation", value: "Websites you selected to never ask to save your password.", comment: "Subtitle providing additional information about the excluded sites section") static let autofillExcludedSitesReset = NSLocalizedString("autofill.excluded-sites.reset", value: "Reset", comment: "Button title allowing users to reset their list of excluded sites") - static let autofillExcludedSitesResetActionTitle = NSLocalizedString("autofill.excluded-sites.reset.action.title", value:"Reset Excluded Sites?", comment: "Alert title") - static let autofillExcludedSitesResetActionMessage = NSLocalizedString("autofill.excluded-sites.reset.action.message", value:"If you reset excluded sites, you will be prompted to save your password next time you sign in to any of these sites.", comment: "Alert title") + static let autofillExcludedSitesResetActionTitle = NSLocalizedString("autofill.excluded-sites.reset.action.title", value: "Reset Excluded Sites?", comment: "Alert title") + static let autofillExcludedSitesResetActionMessage = NSLocalizedString("autofill.excluded-sites.reset.action.message", value: "If you reset excluded sites, you will be prompted to save your password next time you sign in to any of these sites.", comment: "Alert title") static let autofillAutoLock = NSLocalizedString("autofill.auto-lock", value: "Auto-lock", comment: "Autofill settings section title") static let autofillLockWhenIdle = NSLocalizedString("autofill.lock-when-idle", value: "Lock autofill after computer is idle for", comment: "Autofill auto-lock setting") static let autofillNeverLock = NSLocalizedString("autofill.never-lock", value: "Never lock autofill", comment: "Autofill auto-lock setting") static let autofillNeverLockWarning = NSLocalizedString("autofill.never-lock-warning", value: "If not locked, anyone with access to your device will be able to use and modify your autofill data. For security purposes, credit card form fill always requires authentication.", comment: "Autofill disabled auto-lock warning") static let autolockLocksFormFill = NSLocalizedString("autofill.autolock-locks-form-filling", value: "Also lock password form fill", comment: "Lock form filling when auto-lock is active text") - + static let downloadsLocation = NSLocalizedString("downloads.location", value: "Location", comment: "Downloads directory location") static let downloadsAlwaysAsk = NSLocalizedString("downloads.always-ask", value: "Always ask where to save files", comment: "Downloads preferences checkbox") static let downloadsChangeDirectory = NSLocalizedString("downloads.change", value: "Change…", comment: "Change downloads directory button") @@ -464,7 +465,8 @@ struct UserText { static let addFavorite = NSLocalizedString("add.favorite", value: "Add Favorite", comment: "Button for adding a favorite bookmark") static let editFavorite = NSLocalizedString("edit.favorite", value: "Edit Favorite", comment: "Header of the view that edits a favorite bookmark") static let removeFromFavorites = NSLocalizedString("remove.from.favorites", value: "Remove from Favorites", comment: "Button for removing bookmarks from favorites") - static let bookmarkThisPage = NSLocalizedString("bookmark.this.page", value: "Bookmark This Page", comment: "Menu item for bookmarking current page") + static let bookmarkThisPage = NSLocalizedString("bookmark.this.page", value: "Bookmark This Page…", comment: "Menu item for bookmarking current page") + static let bookmarkAllTabs = NSLocalizedString("bookmark.all.tabs", value: "Bookmark All Tabs…", comment: "Menu item for bookmarking all the open tabs") static let bookmarksShowToolbarPanel = NSLocalizedString("bookmarks.show-toolbar-panel", value: "Open Bookmarks Panel", comment: "Menu item for opening the bookmarks panel") static let bookmarksManageBookmarks = NSLocalizedString("bookmarks.manage-bookmarks", value: "Manage Bookmarks", comment: "Menu item for opening the bookmarks management interface") static let bookmarkImportedFromFolder = NSLocalizedString("bookmarks.imported.from.folder", value: "Imported from", comment: "Name of the folder the imported bookmarks are saved into") @@ -555,7 +557,7 @@ struct UserText { static let general = NSLocalizedString("preferences.general", value: "General", comment: "Title of the option to show the General preferences") static let sync = NSLocalizedString("preferences.sync", value: "Sync & Backup", comment: "Title of the option to show the Sync preferences") - static let syncAutoLockPrompt = NSLocalizedString("preferences.sync.auto-lock-prompt", value:"Unlock device to setup Sync & Backup", comment: "Reason for auth when setting up Sync") + static let syncAutoLockPrompt = NSLocalizedString("preferences.sync.auto-lock-prompt", value: "Unlock device to setup Sync & Backup", comment: "Reason for auth when setting up Sync") static let syncBookmarkPausedAlertTitle = NSLocalizedString("alert.sync-bookmarks-paused-title", value: "Bookmarks Sync is Paused", comment: "Title for alert shown when sync bookmarks paused for too many items") static let syncBookmarkPausedAlertDescription = NSLocalizedString("alert.sync-bookmarks-paused-description", value: "You have exceeded the bookmarks sync limit. Try deleting some bookmarks. Until this is resolved your bookmarks will not be backed up.", comment: "Description for alert shown when sync bookmarks paused for too many items") static let syncCredentialsPausedAlertTitle = NSLocalizedString("alert.sync-credentials-paused-title", value: "Passwords Sync is Paused", comment: "Title for alert shown when sync credentials paused for too many items") @@ -592,7 +594,7 @@ struct UserText { static let onStartup = NSLocalizedString("preferences.on-startup", value: "On Startup", comment: "Name of the preferences section related to app startup") static let reopenAllWindowsFromLastSession = NSLocalizedString("preferences.reopen-windows", value: "Reopen all windows from last session", comment: "Option to control session restoration") static let showHomePage = NSLocalizedString("preferences.show-home", value: "Open a new window", comment: "Option to control session startup") - + static let homePage = NSLocalizedString("preferences-homepage.title", value: "Homepage", comment: "Title for Homepage section in settings") static let homePageDescription = NSLocalizedString("preferences-homepage.description", value: "When navigating home or opening new windows.", comment: "Homepage behavior description") static let newTab = NSLocalizedString("preferences-homepage-newTab", value: "New Tab page", comment: "Option to open a new tab") @@ -639,7 +641,6 @@ struct UserText { static let aboutUnsupportedDeviceInfo2Part4 = "of DuckDuckGo. You can also keep using your current version of the browser, but it will not receive further updates." static let unsupportedDeviceInfoAlertHeader = NSLocalizedString("unsupported.device.info.alert.header", value: "Your version of macOS is no longer supported.", comment: "his string represents the header for an alert informing the user that their version of macOS is no longer supported") - static func moreAt(url: String) -> String { let localized = NSLocalizedString("preferences.about.more-at", value: "More at %@", comment: "Link to the about page") return String(format: localized, url) @@ -868,6 +869,9 @@ struct UserText { static let bitwardenError = NSLocalizedString("bitwarden.error", value: "Unable to find or connect to Bitwarden", comment: "This message appears when the application is unable to find or connect to Bitwarden, indicating a connection issue.") static let bitwardenNotInstalled = NSLocalizedString("bitwarden.not.installed", value: "Bitwarden app is not installed", comment: "") static let bitwardenOldVersion = NSLocalizedString("bitwarden.old.version", value: "Please update Bitwarden to the latest version", comment: "Message that warns user they need to update their password manager Bitwarden app vesion") + static let bitwardenIncompatible = NSLocalizedString("bitwarden.incompatible", value: "The following Bitwarden versions are incompatible with DuckDuckGo: v2024.3.0, v2024.3.2, v2024.4.0, v2024.4.1. Please revert to an older version by following these steps:", comment: "Message that warns user that specific Bitwarden app vesions are not compatible with this app") + static let bitwardenIncompatibleStep1 = NSLocalizedString("bitwarden.incompatible.step.1", value: "Download v2014.2.1", comment: "First step to downgrade Bitwarden") + static let bitwardenIncompatibleStep2 = NSLocalizedString("bitwarden.incompatible.step.2", value: "2. Open the downloaded DMG file and drag the Bitwarden application to\nthe /Applications folder.", comment: "Second step to downgrade Bitwarden") static let bitwardenIntegrationNotApproved = NSLocalizedString("bitwarden.integration.not.approved", value: "Integration with DuckDuckGo is not approved in Bitwarden app", comment: "While the user tries to connect the DuckDuckGo Browser to password manager Bitwarden This message indicates that the integration with DuckDuckGo has not been approved in the Bitwarden app.") static let bitwardenMissingHandshake = NSLocalizedString("bitwarden.missing.handshake", value: "Missing handshake", comment: "While the user tries to connect the DuckDuckGo Browser to password manager Bitwarden This message indicates a missing handshake (a way for two devices or systems to say hello to each other and agree to communicate or exchange information).") static let bitwardenWaitingForHandshake = NSLocalizedString("bitwarden.waiting.for.handshake", value: "Waiting for the handshake approval in Bitwarden app", comment: "While the user tries to connect the DuckDuckGo Browser to password manager Bitwarden This message indicates the system is waiting for the handshake (a way for two devices or systems to say hello to each other and agree to communicate or exchange information).") @@ -916,9 +920,9 @@ struct UserText { // MARK: - Tooltips static let autofillShortcutTooltip = NSLocalizedString("tooltip.autofill.shortcut", value: "Autofill", comment: "Tooltip for the autofill shortcut") - + static let homeButtonTooltip = NSLocalizedString("tooltip.home.button", value: "Home", comment: "Tooltip for the home button") - + static let bookmarksShortcutTooltip = NSLocalizedString("tooltip.bookmarks.shortcut", value: "Bookmarks", comment: "Tooltip for the bookmarks shortcut") static let downloadsShortcutTooltip = NSLocalizedString("tooltip.downloads.shortcut", value: "Downloads", comment: "Tooltip for the downloads shortcut") @@ -957,7 +961,7 @@ struct UserText { static let copyPasswordTooltip = NSLocalizedString("autofill.copy-password", value: "Copy password", comment: "Tooltip for the Autofill panel's Copy Password button") static let showPasswordTooltip = NSLocalizedString("autofill.show-password", value: "Show password", comment: "Tooltip for the Autofill panel's Show Password button") static let hidePasswordTooltip = NSLocalizedString("autofill.hide-password", value: "Hide password", comment: "Tooltip for the Autofill panel's Hide Password button") - + static let autofillShowCardCvvTooltip = NSLocalizedString("autofill.show-card-cvv", value: "Show CVV", comment: "Tooltip for the Autofill panel's Show CVV button") static let autofillHideCardCvvTooltip = NSLocalizedString("autofill.hide-card-cvv", value: "Hide CVV", comment: "Tooltip for the Autofill panel's Hide CVV button") @@ -975,17 +979,16 @@ struct UserText { let localized = NSLocalizedString("autofill.popover.password-manager-connected-to-user", value: "Connected to user %@", comment: "Label describing what user is connected to the password manager") return String(format: localized, user) } - + static func passwordManagerAutosavePopoverText(domain: String) -> String { let localized = NSLocalizedString("autofill.popover.autosave.text", value: "Password saved for %@", comment: "Text confirming a password has been saved for the %@ domain") return String(format: localized, domain) } - + static let passwordManagerAutosaveButtonText = NSLocalizedString("autofill.popover.autosave.button.text", value: "View", comment: "Button to view the recently autosaved password") - static func openPasswordManagerButton(managerName: String) -> String { let localized = NSLocalizedString("autofill.popover.open-password-manager", value: "Open %@", comment: "Open password manager button") return String(format: localized, managerName) @@ -993,7 +996,7 @@ struct UserText { static let passwordManagerLockedStatus = NSLocalizedString("autofill.manager.status.locked", value: "Locked", comment: "Locked status for password manager") static let passwordManagerUnlockedStatus = NSLocalizedString("autofill.manager.status.unlocked", value: "Unlocked", comment: "Unlocked status for password manager") - + static func alertTitle(from domain: String) -> String { let localized = NSLocalizedString("alert.title", value: "A message from %@", comment: "Title formatted with presenting domain") return String(format: localized, domain) @@ -1031,23 +1034,17 @@ struct UserText { static let newTabSetUpImportCardTitle = NSLocalizedString("newTab.setup.import.title", value: "Bring Your Stuff", comment: "Title of the Import card of the Set Up section in the home page") static let newTabSetUpDuckPlayerCardTitle = NSLocalizedString("newTab.setup.duck.player.title", value: "Clean Up YouTube", comment: "Title of the Duck Player card of the Set Up section in the home page") static let newTabSetUpEmailProtectionCardTitle = NSLocalizedString("newTab.setup.email.protection.title", value: "Protect Your Inbox", comment: "Title of the Email Protection card of the Set Up section in the home page") - static let newTabSetUpSurveyDay0CardTitle = NSLocalizedString("newTab.setup.survey.day.0.title", value: "Share Your Thoughts With Us", comment: "Title of the Day 0 durvey of the Set Up section in the home page") - static let newTabSetUpSurveyDay14CardTitle = NSLocalizedString("newTab.setup.survey.day.14.title", value: "Share Your Thoughts With Us", comment: "Title of the Day 14 durvey of the Set Up section in the home page") static let newTabSetUpDefaultBrowserAction = NSLocalizedString("newTab.setup.default.browser.action", value: "Make Default Browser", comment: "Action title on the action menu of the Default Browser card") static let newTabSetUpImportAction = NSLocalizedString("newTab.setup.Import.action", value: "Import Now", comment: "Action title on the action menu of the Import card of the Set Up section in the home page") static let newTabSetUpDuckPlayerAction = NSLocalizedString("newTab.setup.duck.player.action", value: "Try Duck Player", comment: "Action title on the action menu of the Duck Player card of the Set Up section in the home page") static let newTabSetUpEmailProtectionAction = NSLocalizedString("newTab.setup.email.protection.action", value: "Get a Duck Address", comment: "Action title on the action menu of the Email Protection card of the Set Up section in the home page") static let newTabSetUpRemoveItemAction = NSLocalizedString("newTab.setup.remove.item", value: "Dismiss", comment: "Action title on the action menu of the set up cards card of the SetUp section in the home page to remove the item") - static let newTabSetUpSurveyDay0Action = NSLocalizedString("newTab.setup.survey.day.0.action", value: "Sign Up To Participate", comment: "Action title of the Day 0 survey of the Set Up section in the home page") - static let newTabSetUpSurveyDay14Action = NSLocalizedString("newTab.setup.survey.day.14.action", value: "Sign Up To Participate", comment: "Action title of the Day 14 survey of the Set Up section in the home page") static let newTabSetUpDefaultBrowserSummary = NSLocalizedString("newTab.setup.default.browser.summary", value: "We automatically block trackers as you browse. It's privacy, simplified.", comment: "Summary of the Default Browser card") static let newTabSetUpImportSummary = NSLocalizedString("newTab.setup.import.summary", value: "Import bookmarks, favorites, and passwords from your old browser.", comment: "Summary of the Import card of the Set Up section in the home page") static let newTabSetUpDuckPlayerSummary = NSLocalizedString("newTab.setup.duck.player.summary", value: "Enjoy a clean viewing experience without personalized ads.", comment: "Summary of the Duck Player card of the Set Up section in the home page") static let newTabSetUpEmailProtectionSummary = NSLocalizedString("newTab.setup.email.protection.summary", value: "Generate custom @duck.com addresses that clean trackers from incoming email.", comment: "Summary of the Email Protection card of the Set Up section in the home page") - static let newTabSetUpSurveyDay0Summary = NSLocalizedString("newTab.setup.survey.day.0.summary", value: "Join an interview with a member of our research team to help us build the best browser.", comment: "Summary of the card on the new tab page that invites users to partecipate to a survey") - static let newTabSetUpSurveyDay14Summary = NSLocalizedString("newTab.setup.survey.day.14.summary", value: "Join an interview with a member of our research team to help us build the best browser.", comment: "Summary of the card on the new tab page that invites users to partecipate to a survey") // Recent Activity static let newTabRecentActivitySectionTitle = NSLocalizedString("newTab.recent.activity.section.title", value: "Recent Activity", comment: "Title of the RecentActivity section in the home page") @@ -1068,7 +1065,6 @@ struct UserText { // "tab.dbp.title" - Tab data broker protection title static let tabDataBrokerProtectionTitle = "Personal Information Removal" - // Bookmarks bar prompt static let bookmarksBarPromptTitle = NSLocalizedString("bookmarks.bar.prompt.title", value: "Show Bookmarks Bar?", comment: "Title for bookmarks bar prompt") static let bookmarksBarPromptMessage = NSLocalizedString("bookmarks.bar.prompt.message", value: "Show the Bookmarks Bar for quick access to your new bookmarks.", comment: "Message show for bookmarks bar prompt") @@ -1110,20 +1106,28 @@ struct UserText { static let editBookmark = NSLocalizedString("bookmarks.dialog.title.edit", value: "Edit Bookmark", comment: "Bookmark edit dialog title") static let addFolder = NSLocalizedString("bookmarks.dialog.folder.title.add", value: "Add Folder", comment: "Bookmark folder creation dialog title") static let editFolder = NSLocalizedString("bookmarks.dialog.folder.title.edit", value: "Edit Folder", comment: "Bookmark folder edit dialog title") + static let bookmarkOpenTabs = NSLocalizedString("bookmarks.dialog.allTabs.title.add", value: "Bookmark Open Tabs (%d)", comment: "Title of dialog to bookmark all open tabs. E.g. 'Bookmark Open Tabs (42)'") + } + enum Message { + static let bookmarkOpenTabsEducational = NSLocalizedString("bookmarks.dialog.allTabs.message.add", value: "These bookmarks will be saved in a new folder:", comment: "Bookmark creation for all open tabs dialog title") } enum Field { static let name = NSLocalizedString("bookmarks.dialog.field.name", value: "Name", comment: "Name field label for Bookmark or Folder") static let url = NSLocalizedString("bookmarks.dialog.field.url", value: "URL", comment: "URL field label for Bookmar") static let location = NSLocalizedString("bookmarks.dialog.field.location", value: "Location", comment: "Location field label for Bookmark folder") + static let folderName = NSLocalizedString("bookmarks.dialog.field.folderName", value: "Folder Name", comment: "Folder name field label for Bookmarks folder") + } + enum Value { + static let folderName = NSLocalizedString("bookmarks.dialog.field.folderName.value", value: "%@ - Tabs (%d)", comment: "The suggested name of the folder that will contain the bookmark tabs. Eg. 2024-02-12 - Tabs (42)") } enum Action { static let addBookmark = NSLocalizedString("bookmarks.dialog.action.addBookmark", value: "Add Bookmark", comment: "CTA title for adding a Bookmark") static let addFolder = NSLocalizedString("bookmarks.dialog.action.addFolder", value: "Add Folder", comment: "CTA title for adding a Folder") + static let addAllBookmarks = NSLocalizedString("bookmarks.dialog.action.addAllBookmarks", value: "Save Bookmarks", comment: "CTA title for saving multiple Bookmarks at once") } } } -#if SUBSCRIPTION // Key: "subscription.menu.item" // Comment: "Title for Subscription item in the options menu" static let subscriptionOptionsMenuItem = "Privacy Pro" @@ -1145,5 +1149,14 @@ struct UserText { // Key: "subscription.progress.view.completing.purchase" // Comment: "Progress view title when completing the purchase" static let completingPurchaseTitle = "Completing purchase..." -#endif + + // MARK: - DBP Error pages + + static let dbpErrorPageBadPathTitle = "Move DuckDuckGo App to Applications" + static let dbpErrorPageBadPathMessage = "To use Personal Information Removal, the DuckDuckGo app needs to be in the Applications folder on your Mac. You can move the app yourself and restart the browser, or we can do it for you." + static let dbpErrorPageBadPathCTA = "Move App for Me..." + + static let dbpErrorPageNoPermissionTitle = "Change System Setting" + static let dbpErrorPageNoPermissionMessage = "Open System Settings and allow DuckDuckGo Personal Information Removal to run in the background." + static let dbpErrorPageNoPermissionCTA = "Open System Settings..." } diff --git a/DuckDuckGo/Common/Utilities/CertificateTrustEvaluator.swift b/DuckDuckGo/Common/Utilities/CertificateTrustEvaluator.swift index 541f61c95d..63ea3638cd 100644 --- a/DuckDuckGo/Common/Utilities/CertificateTrustEvaluator.swift +++ b/DuckDuckGo/Common/Utilities/CertificateTrustEvaluator.swift @@ -19,13 +19,13 @@ import Foundation protocol CertificateTrustEvaluating { - func evaluateCertificateTrust(trust: SecTrust?) -> Bool? + func evaluateCertificateTrust(trust: SecTrust?) async -> Bool? } struct CertificateTrustEvaluator: CertificateTrustEvaluating { - func evaluateCertificateTrust(trust: SecTrust?) -> Bool? { + func evaluateCertificateTrust(trust: SecTrust?) async -> Bool? { var error: CFError? - guard let trust else { return nil } + guard let trust = trust else { return nil } let result = SecTrustEvaluateWithError(trust, &error) return result } diff --git a/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift b/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift index 2d7d25f85e..84c3835b1e 100644 --- a/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift +++ b/DuckDuckGo/Common/Utilities/UserDefaultsWrapper.swift @@ -111,11 +111,8 @@ public struct UserDefaultsWrapper { case homePageShowImport = "home.page.show.import" case homePageShowDuckPlayer = "home.page.show.duck.player" case homePageShowEmailProtection = "home.page.show.email.protection" - case homePageShowSurveyDay0 = "home.page.show.survey.0" - case homePageShowSurveyDay0in10Percent = "home.page.show.survey.0.in.10.pervent" - case homePageShowSurveyDay14in10Percent = "home.page.show.survey.0.in.14.pervent" - case homePageUserInteractedWithSurveyDay0 = "home.page.user.interacted.with.survey.0" - case homePageShowSurveyDay14 = "home.page.show.survey.14" + case homePageUserInSurveyShare = "home.page.user.in.survey.share" + case homePageShowPermanentSurvey = "home.page.show.import.permanent.survey" case homePageShowPageTitles = "home.page.show.page.titles" case homePageShowRecentlyVisited = "home.page.show.recently.visited" case homePageContinueSetUpImport = "home.page.continue.set.up.import" diff --git a/DuckDuckGo/Configuration/ConfigurationManager.swift b/DuckDuckGo/Configuration/ConfigurationManager.swift index a64673dfc0..531fbe4985 100644 --- a/DuckDuckGo/Configuration/ConfigurationManager.swift +++ b/DuckDuckGo/Configuration/ConfigurationManager.swift @@ -22,6 +22,7 @@ import BrowserServicesKit import Configuration import Common import Networking +import PixelKit @MainActor final class ConfigurationManager { @@ -72,13 +73,13 @@ final class ConfigurationManager { eventMapping: Self.configurationDebugEvents) private static let configurationDebugEvents = EventMapping { event, error, _, _ in - let domainEvent: Pixel.Event.Debug + let domainEvent: GeneralPixel switch event { case .invalidPayload(let configuration): domainEvent = .invalidPayload(configuration) } - Pixel.fire(.debug(event: domainEvent, error: error)) + PixelKit.fire(DebugEvent(domainEvent, error: error)) } func start() { @@ -170,7 +171,7 @@ final class ConfigurationManager { } os_log("Failed to complete configuration update %@", log: .config, type: .error, error.localizedDescription) - Pixel.fire(.debug(event: .configurationFetchError, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.configurationFetchError(error: error))) tryAgainSoon() } diff --git a/DuckDuckGo/Configuration/ConfigurationStore.swift b/DuckDuckGo/Configuration/ConfigurationStore.swift index 179e5addd7..fe58ca3df2 100644 --- a/DuckDuckGo/Configuration/ConfigurationStore.swift +++ b/DuckDuckGo/Configuration/ConfigurationStore.swift @@ -19,6 +19,7 @@ import Common import Foundation import Configuration +import PixelKit final class ConfigurationStore: ConfigurationStoring { @@ -99,7 +100,7 @@ final class ConfigurationStore: ConfigurationStoring { let nserror = error as NSError if nserror.domain != NSCocoaErrorDomain || nserror.code != NSFileReadNoSuchFileError { - Pixel.fire(.debug(event: .trackerDataCouldNotBeLoaded, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.trackerDataCouldNotBeLoaded, error: error)) } return nil diff --git a/DuckDuckGo/ContentBlocker/AppPrivacyConfigurationDataProvider.swift b/DuckDuckGo/ContentBlocker/AppPrivacyConfigurationDataProvider.swift index f0052639b2..e4add5a17e 100644 --- a/DuckDuckGo/ContentBlocker/AppPrivacyConfigurationDataProvider.swift +++ b/DuckDuckGo/ContentBlocker/AppPrivacyConfigurationDataProvider.swift @@ -22,8 +22,8 @@ import BrowserServicesKit final class AppPrivacyConfigurationDataProvider: EmbeddedDataProvider { public struct Constants { - public static let embeddedDataETag = "\"fd95ad4da437370f57ea8c2e2d03f48f\"" - public static let embeddedDataSHA = "f11d34eb516a2ba722c22e15ff8cdee5e5b2570adbf9d1b22d50438b30f57188" + public static let embeddedDataETag = "\"7cf7b71adb62c3cbcbf8b84c61a0004d\"" + public static let embeddedDataSHA = "20e9b59e7e60ccc9ae52853935ebe3d74227234fcf8b46da5a66cff3adc7e6c7" } var embeddedDataEtag: String { diff --git a/DuckDuckGo/ContentBlocker/ContentBlocking.swift b/DuckDuckGo/ContentBlocker/ContentBlocking.swift index 795f5ec581..d935081755 100644 --- a/DuckDuckGo/ContentBlocker/ContentBlocking.swift +++ b/DuckDuckGo/ContentBlocker/ContentBlocking.swift @@ -21,6 +21,7 @@ import WebKit import Combine import BrowserServicesKit import Common +import PixelKit protocol ContentBlockingProtocol { @@ -98,18 +99,18 @@ final class AppContentBlocking { } private let toggleProtectionsEvents = EventMapping { event, _, parameters, _ in - let domainEvent: Pixel.Event + let domainEvent: GeneralPixel switch event { case .toggleProtectionsCounterDaily: domainEvent = .toggleProtectionsDailyCount } - Pixel.fire(domainEvent, withAdditionalParameters: parameters ?? [:]) + PixelKit.fire(domainEvent, withAdditionalParameters: parameters ?? [:]) } private static let debugEvents = EventMapping { event, error, parameters, onComplete in guard NSApp.runType.requiresEnvironment else { return } - let domainEvent: Pixel.Event.Debug + let domainEvent: GeneralPixel switch event { case .trackerDataParseFailed: domainEvent = .trackerDataParseFailed @@ -132,7 +133,7 @@ final class AppContentBlocking { case .contentBlockingCompilationFailed(let listName, let component): let defaultTDSListName = DefaultContentBlockerRulesListsSource.Constants.trackerDataSetRulesListName - let listType: Pixel.Event.CompileRulesListType + let listType: GeneralPixel.CompileRulesListType switch listName { case defaultTDSListName: listType = .tds @@ -154,13 +155,15 @@ final class AppContentBlocking { return } - Pixel.fire(.debug(event: domainEvent, error: error), withAdditionalParameters: parameters, onComplete: onComplete) + PixelKit.fire(DebugEvent(domainEvent, error: error), withAdditionalParameters: parameters) { _, error in + onComplete(error) + } } // MARK: - Ad Click Attribution let attributionEvents: EventMapping? = .init { event, _, parameters, _ in - let domainEvent: Pixel.Event + let domainEvent: GeneralPixel switch event { case .adAttributionDetected: domainEvent = .adClickAttributionDetected @@ -170,11 +173,11 @@ final class AppContentBlocking { domainEvent = .adClickAttributionPageLoads } - Pixel.fire(domainEvent, withAdditionalParameters: parameters ?? [:]) + PixelKit.fire(domainEvent, withAdditionalParameters: parameters ?? [:]) } let attributionDebugEvents: EventMapping? = .init { event, _, _, _ in - let domainEvent: Pixel.Event.Debug + let domainEvent: GeneralPixel switch event { case .adAttributionCompilationFailedForAttributedRulesList: domainEvent = .adAttributionCompilationFailedForAttributedRulesList @@ -198,8 +201,7 @@ final class AppContentBlocking { domainEvent = .adAttributionLogicWrongVendorOnFailedCompilation } - Pixel.fire(.debug(event: domainEvent, error: nil), - includeAppVersionParameter: false) + PixelKit.fire(DebugEvent(domainEvent), includeAppVersionParameter: false) } } diff --git a/DuckDuckGo/ContentBlocker/Mocks/MockPrivacyConfiguration.swift b/DuckDuckGo/ContentBlocker/Mocks/MockPrivacyConfiguration.swift index 60dc35a8e1..d18f6ce82f 100644 --- a/DuckDuckGo/ContentBlocker/Mocks/MockPrivacyConfiguration.swift +++ b/DuckDuckGo/ContentBlocker/Mocks/MockPrivacyConfiguration.swift @@ -61,7 +61,8 @@ final class MockPrivacyConfiguration: PrivacyConfiguration { func isUserUnprotected(domain: String?) -> Bool { false } func isTempUnprotected(domain: String?) -> Bool { false } func isInExceptionList(domain: String?, forFeature featureKey: PrivacyFeature) -> Bool { false } - func settings(for feature: PrivacyFeature) -> PrivacyConfigurationData.PrivacyFeature.FeatureSettings { featureSettings } + func settings(for feature: PrivacyFeature) -> PrivacyConfigurationData.PrivacyFeature.FeatureSettings { + featureSettings } func userEnabledProtection(forDomain: String) {} func userDisabledProtection(forDomain: String) {} } diff --git a/DuckDuckGo/ContentBlocker/macos-config.json b/DuckDuckGo/ContentBlocker/macos-config.json index 216cd4c618..39163097c1 100644 --- a/DuckDuckGo/ContentBlocker/macos-config.json +++ b/DuckDuckGo/ContentBlocker/macos-config.json @@ -1,6 +1,6 @@ { "readme": "https://github.com/duckduckgo/privacy-configuration", - "version": 1712611145027, + "version": 1713542334045, "features": { "adClickAttribution": { "readme": "https://help.duckduckgo.com/duckduckgo-help-pages/privacy/web-tracking-protections/#3rd-party-tracker-loading-protection", @@ -74,12 +74,6 @@ { "domain": "thehustle.co" }, - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -111,7 +105,7 @@ ] }, "state": "enabled", - "hash": "51b76aa7b92d78ad52106b04ac809843" + "hash": "16c6e3fb43797e3ca13a9259569a9e4e" }, "androidBrowserConfig": { "exceptions": [], @@ -286,10 +280,13 @@ "domain": "condell-ltd.com" }, { - "domain": "earth.google.com" + "domain": "leefgemeenschapzilt.nl" }, { - "domain": "iscorp.com" + "domain": "healthline.com" + }, + { + "domain": "sporthoj.com" }, { "domain": "marvel.com" @@ -302,12 +299,12 @@ "disabledCMPs": [ "generic-cosmetic", "termsfeed3", - "strato.de", - "healthline-media" + "healthline-media", + "tarteaucitron.js" ] }, "state": "enabled", - "hash": "44af0b568856ce87b825bb7fc61b6961" + "hash": "f35e24cf85485b441cb9a76146e77e17" }, "autofill": { "exceptions": [ @@ -923,12 +920,6 @@ { "domain": "pocketbook.digital" }, - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -951,16 +942,10 @@ } }, "state": "disabled", - "hash": "36e8971fa9bb204b78a5929a14a108dd" + "hash": "770f7ae0f752e976764771bccec352b2" }, "clickToPlay": { "exceptions": [ - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -978,7 +963,7 @@ } }, "state": "enabled", - "hash": "f1b7de266435cd2e414f50deb2c9234a" + "hash": "2cff3d9b2df1ed9375f362848c8ed5f3" }, "clientBrandHint": { "exceptions": [], @@ -1009,12 +994,6 @@ { "domain": "soranews24.com" }, - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -1022,7 +1001,7 @@ "domain": "sundancecatalog.com" } ], - "hash": "e37447d42ee8194f185e35e40f577f41" + "hash": "593797946074a1f304add65e7543b9be" }, "cookie": { "settings": { @@ -1064,12 +1043,6 @@ { "domain": "news.ti.com" }, - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -1078,7 +1051,7 @@ } ], "state": "disabled", - "hash": "37a27966915571085613911b47e6e2eb" + "hash": "7ade754b885238cd191f1a61b4eeb0b6" }, "customUserAgent": { "settings": { @@ -1245,12 +1218,6 @@ { "domain": "duckduckgo.com" }, - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -2300,6 +2267,15 @@ } ] }, + { + "domain": "doodle.com", + "rules": [ + { + "selector": "[data-testid*='ads-layout-placement']", + "type": "hide" + } + ] + }, { "domain": "dpreview.com", "rules": [ @@ -2875,6 +2851,27 @@ } ] }, + { + "domain": "independent.co.uk", + "rules": [ + { + "selector": "#partners", + "type": "hide-empty" + }, + { + "selector": "#top-banner-wrapper", + "type": "hide-empty" + }, + { + "selector": "[data-mpu1=true]", + "type": "hide-empty" + }, + { + "selector": "#stickyFooterRoot", + "type": "hide" + } + ] + }, { "domain": "indiatimes.com", "rules": [ @@ -4050,6 +4047,15 @@ } ] }, + { + "domain": "woot.com", + "rules": [ + { + "selector": "[data-test-ui*='advertisementLeaderboard']", + "type": "hide-empty" + } + ] + }, { "domain": "wsj.com", "rules": [ @@ -4254,16 +4260,10 @@ ] }, "state": "enabled", - "hash": "ea31ebf0dd3e4831467ed2b2ec783279" + "hash": "765e789c939c6e3307f576bc698fbb9e" }, "exceptionHandler": { "exceptions": [ - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -4272,7 +4272,7 @@ } ], "state": "disabled", - "hash": "5e792dd491428702bc0104240fbce0ce" + "hash": "dc1b4fa301193a03ddcd4bdf7ee3e610" }, "fingerprintingAudio": { "state": "disabled", @@ -4280,12 +4280,6 @@ { "domain": "litebluesso.usps.gov" }, - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -4293,19 +4287,13 @@ "domain": "sundancecatalog.com" } ], - "hash": "f25a8f2709e865c2bd743828c7ee2f77" + "hash": "2037fcd805ece181cfffc482f262941f" }, "fingerprintingBattery": { "exceptions": [ { "domain": "litebluesso.usps.gov" }, - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -4314,7 +4302,7 @@ } ], "state": "disabled", - "hash": "4085f1593faff2feac2093533b819a41" + "hash": "07ee708dc740aab3b1f048d9bb571dac" }, "fingerprintingCanvas": { "settings": { @@ -4405,12 +4393,6 @@ { "domain": "godaddy.com" }, - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -4419,7 +4401,7 @@ } ], "state": "disabled", - "hash": "ea4c565bae27996f0d651300d757594c" + "hash": "d48bfb1151476f49970ffd3b1f778bf9" }, "fingerprintingHardware": { "settings": { @@ -4471,12 +4453,6 @@ { "domain": "proton.me" }, - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -4518,7 +4494,7 @@ } ], "state": "enabled", - "hash": "37e16df501e3e68416a13f991b4e4147" + "hash": "aefca8e7a9a3d9b65370608dd639cd3f" }, "fingerprintingScreenSize": { "settings": { @@ -4558,12 +4534,6 @@ { "domain": "secureserver.net" }, - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -4572,7 +4542,7 @@ } ], "state": "disabled", - "hash": "466b85680f138657de9bfd222c440887" + "hash": "eef4614273c28d50dd298a68ffbac309" }, "fingerprintingTemporaryStorage": { "exceptions": [ @@ -4585,12 +4555,6 @@ { "domain": "tattoogenius.art" }, - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -4599,16 +4563,10 @@ } ], "state": "disabled", - "hash": "f858697949c90842c450daee64a1dc30" + "hash": "2746e6cb6c773e80a36fda03618ef930" }, "googleRejected": { "exceptions": [ - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -4617,7 +4575,7 @@ } ], "state": "disabled", - "hash": "5e792dd491428702bc0104240fbce0ce" + "hash": "dc1b4fa301193a03ddcd4bdf7ee3e610" }, "gpc": { "state": "enabled", @@ -4634,6 +4592,9 @@ { "domain": "crunchyroll.com" }, + { + "domain": "espn.com" + }, { "domain": "eventbrite.com" }, @@ -4652,12 +4613,6 @@ { "domain": "tirerack.com" }, - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -4674,7 +4629,7 @@ "privacy-test-pages.site" ] }, - "hash": "1a1373bcf16647d63220659fce650a83" + "hash": "05bddff3ae61a9536e38a6ef7d383eb3" }, "harmfulApis": { "settings": { @@ -4776,12 +4731,6 @@ "domains": [] }, "exceptions": [ - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -4790,7 +4739,7 @@ } ], "state": "disabled", - "hash": "44d3e707cba3ee0a3578f52dc2ce2aa4" + "hash": "f29eae11500edcda80aa8b32b12869eb" }, "history": { "state": "disabled", @@ -4809,12 +4758,6 @@ { "domain": "jp.square-enix.com" }, - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -4822,7 +4765,7 @@ "domain": "sundancecatalog.com" } ], - "hash": "f772808ed34cc9ea8cbcbb7cdaf74429" + "hash": "ea2c4fc84f27eb3694acd9ccf1023e95" }, "incontextSignup": { "exceptions": [], @@ -4859,12 +4802,6 @@ }, "navigatorInterface": { "exceptions": [ - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -4880,7 +4817,7 @@ ] }, "state": "enabled", - "hash": "698de7b963d7d7942c5c5d1e986bb1b1" + "hash": "bb2ed420e76ecaf31a1f99decd370e55" }, "networkProtection": { "state": "enabled", @@ -4925,23 +4862,25 @@ "exceptions": [], "state": "enabled", "settings": { - "surveyCardDay0": "enabled", + "surveyCardDay0": "disabled", "surveyCardDay7": "disabled", - "surveyCardDay14": "enabled" + "surveyCardDay14": "disabled", + "permanentSurvey": { + "state": "internal", + "localization": "disabled", + "url": "https://selfserve.decipherinc.com/survey/selfserve/32ab/240404?list=2", + "firstDay": 5, + "lastDay": 8, + "sharePercentage": 60 + } }, - "hash": "eb826d9079211f30d624211f44aed184" + "hash": "7f7445d021268ef854b20022d0fb48e6" }, "nonTracking3pCookies": { "settings": { "excludedCookieDomains": [] }, "exceptions": [ - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -4950,17 +4889,11 @@ } ], "state": "disabled", - "hash": "841fa92b9728c9754f050662678f82c7" + "hash": "522e3e42e2612ac2811342d3f6754c5a" }, "performanceMetrics": { "state": "enabled", "exceptions": [ - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -4968,7 +4901,7 @@ "domain": "sundancecatalog.com" } ], - "hash": "38558d5e7b231d4b27e7dd76814387a7" + "hash": "936f00970c108fd646f73d00b3f3f5b5" }, "privacyDashboard": { "exceptions": [], @@ -4980,25 +4913,38 @@ } }, "toggleReports": { - "state": "enabled", - "rollout": { - "steps": [ - { - "percent": 10 - } - ] - } + "state": "enabled" } }, "state": "enabled", - "hash": "b337f9c7cf15e7e4807ef232befaa999" + "hash": "66968d9b69520975185476473cc11824" }, "privacyPro": { "state": "enabled", "exceptions": [], "features": { "isLaunched": { - "state": "disabled" + "state": "enabled", + "rollout": { + "steps": [ + { + "percent": 1 + }, + { + "percent": 10 + }, + { + "percent": 30 + }, + { + "percent": 50 + }, + { + "percent": 100 + } + ] + }, + "minSupportedVersion": "1.82.1" }, "isLaunchedOverride": { "state": "disabled" @@ -5007,13 +4953,33 @@ "state": "enabled" }, "isLaunchedStripe": { - "state": "disabled" + "state": "enabled", + "rollout": { + "steps": [ + { + "percent": 1 + }, + { + "percent": 10 + }, + { + "percent": 30 + }, + { + "percent": 50 + }, + { + "percent": 100 + } + ] + }, + "minSupportedVersion": "1.82.1" }, "allowPurchaseStripe": { "state": "enabled" } }, - "hash": "c9153c5cc3b6b7eba024c6c597e15edb" + "hash": "1a10a68ea8885db0d1d9bab371c0f738" }, "privacyProtectionsPopup": { "state": "disabled", @@ -5040,12 +5006,6 @@ { "domain": "xcelenergy.com" }, - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -5054,17 +5014,11 @@ } ], "state": "disabled", - "hash": "0d3df0f7c24ebde89d2dced4e2d34322" + "hash": "1cfe449de8a4fcb542757383d846c031" }, "requestFilterer": { "state": "disabled", "exceptions": [ - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -5075,17 +5029,11 @@ "settings": { "windowInMs": 0 }, - "hash": "0fff8017d8ea4b5609b8f5c110be1401" + "hash": "3218faa098a2e9da61447fb63e3a5ed9" }, "runtimeChecks": { "state": "disabled", "exceptions": [ - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -5094,16 +5042,10 @@ } ], "settings": {}, - "hash": "800a19533c728bbec7e31e466f898268" + "hash": "ddb64344aa42e9593964f14b6de3d6df" }, "serviceworkerInitiatedRequests": { "exceptions": [ - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -5112,7 +5054,7 @@ } ], "state": "disabled", - "hash": "5e792dd491428702bc0104240fbce0ce" + "hash": "dc1b4fa301193a03ddcd4bdf7ee3e610" }, "sslCertificates": { "state": "enabled", @@ -5298,7 +5240,8 @@ { "rule": "static.adsafeprotected.com/iasPET.1.js", "domains": [ - "corriere.it" + "corriere.it", + "independent.co.uk" ] }, { @@ -5569,6 +5512,12 @@ }, "boldapps.net": { "rules": [ + { + "rule": "mc.boldapps.net/install_assets/bold.multicurrency.js", + "domains": [ + "" + ] + }, { "rule": "option.boldapps.net/js/options.js", "domains": [ @@ -6061,11 +6010,7 @@ { "rule": "cdn.dynamicyield.com/api/", "domains": [ - "asics.com", - "brooklinen.com", - "carters.com", - "otterbox.com", - "seatosummit.com" + "" ] } ] @@ -6972,7 +6917,8 @@ "domains": [ "andieswim.com", "footweartruth.com", - "kmail-lists.com" + "kmail-lists.com", + "usafacts.org" ] } ] @@ -7003,6 +6949,16 @@ } ] }, + "litix.io": { + "rules": [ + { + "rule": "src.litix.io/videojs/", + "domains": [ + "" + ] + } + ] + }, "loggly.com": { "rules": [ { @@ -7175,7 +7131,8 @@ { "rule": "npttech.com/advertising.js", "domains": [ - "blick.ch" + "blick.ch", + "independent.co.uk" ] } ] @@ -7984,6 +7941,12 @@ "domains": [ "winnipegfreepress.com" ] + }, + { + "rule": "platform.twitter.com/_next/static", + "domains": [ + "" + ] } ] }, @@ -8250,12 +8213,6 @@ } }, "exceptions": [ - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -8263,7 +8220,7 @@ "domain": "sundancecatalog.com" } ], - "hash": "936913b03c62ec1861b64a7a2316ddfd" + "hash": "2d5ce26ddae089bcb61e4f4a0b1ae487" }, "trackingCookies1p": { "settings": { @@ -8273,12 +8230,6 @@ } }, "exceptions": [ - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -8287,19 +8238,13 @@ } ], "state": "disabled", - "hash": "4dddf681372a2aea9788090b13db6e6f" + "hash": "dab51f5ad2454727f8bc474cdd3da65b" }, "trackingCookies3p": { "settings": { "excludedCookieDomains": [] }, "exceptions": [ - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -8308,19 +8253,13 @@ } ], "state": "disabled", - "hash": "841fa92b9728c9754f050662678f82c7" + "hash": "522e3e42e2612ac2811342d3f6754c5a" }, "trackingParameters": { "exceptions": [ { "domain": "axs.com" }, - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -8359,19 +8298,13 @@ }, "state": "enabled", "minSupportedVersion": "0.22.3", - "hash": "9a0282376084874f0245c421d6943841" + "hash": "44005192b6dba245e95de042fc224228" }, "userAgentRotation": { "settings": { "agentExcludePatterns": [] }, "exceptions": [ - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -8380,7 +8313,7 @@ } ], "state": "disabled", - "hash": "f65d10dfdf6739feab99a08d42734747" + "hash": "e30277704ddbf20c14136baab08519c5" }, "voiceSearch": { "exceptions": [], @@ -8389,12 +8322,6 @@ }, "webCompat": { "exceptions": [ - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -8663,7 +8590,7 @@ } ] }, - "hash": "151d7ee40451c4aac4badfcc829ea0b5" + "hash": "90687b1a5ac7aec8bf26f24a75cd883f" }, "windowsPermissionUsage": { "exceptions": [], @@ -8672,12 +8599,6 @@ }, "windowsStartupBoost": { "exceptions": [ - { - "domain": "earth.google.com" - }, - { - "domain": "iscorp.com" - }, { "domain": "marvel.com" }, @@ -8686,7 +8607,7 @@ } ], "state": "disabled", - "hash": "5e792dd491428702bc0104240fbce0ce" + "hash": "dc1b4fa301193a03ddcd4bdf7ee3e610" }, "windowsWaitlist": { "exceptions": [], diff --git a/DuckDuckGo/CrashReports/Model/CrashReport.swift b/DuckDuckGo/CrashReports/Model/CrashReport.swift index 773c66cd27..05df42936f 100644 --- a/DuckDuckGo/CrashReports/Model/CrashReport.swift +++ b/DuckDuckGo/CrashReports/Model/CrashReport.swift @@ -17,13 +17,17 @@ // import Foundation +import MetricKit -protocol CrashReport { +protocol CrashReportPresenting { + var content: String? { get } +} + +protocol CrashReport: CrashReportPresenting { static var fileExtension: String { get } var url: URL { get } - var content: String? { get } var contentData: Data? { get } } @@ -91,3 +95,10 @@ struct JSONCrashReport: CrashReport { } } + +@available(macOS 12.0, *) +extension MXDiagnosticPayload: CrashReportPresenting { + var content: String? { + jsonRepresentation().utf8String() + } +} diff --git a/DuckDuckGo/CrashReports/Model/CrashReportPromptPresenter.swift b/DuckDuckGo/CrashReports/Model/CrashReportPromptPresenter.swift index 3d4e17cd2f..313c6a1e95 100644 --- a/DuckDuckGo/CrashReports/Model/CrashReportPromptPresenter.swift +++ b/DuckDuckGo/CrashReports/Model/CrashReportPromptPresenter.swift @@ -31,9 +31,9 @@ final class CrashReportPromptPresenter { // swiftlint:enable force_cast } - func showPrompt(_ delegate: CrashReportPromptViewControllerDelegate, for crashReport: CrashReport) { - viewController.delegate = delegate + func showPrompt(for crashReport: CrashReportPresenting, userDidAllowToReport: @escaping () -> Void) { viewController.crashReport = crashReport + viewController.userDidAllowToReport = userDidAllowToReport windowController.showWindow(self) windowController.window?.center() diff --git a/DuckDuckGo/CrashReports/Model/CrashReportSender.swift b/DuckDuckGo/CrashReports/Model/CrashReportSender.swift deleted file mode 100644 index e6ac958fc3..0000000000 --- a/DuckDuckGo/CrashReports/Model/CrashReportSender.swift +++ /dev/null @@ -1,45 +0,0 @@ -// -// CrashReportSender.swift -// -// Copyright © 2021 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. -// - -import Foundation - -final class CrashReportSender { - - static let reportServiceUrl = URL(string: "https://duckduckgo.com/crash.js")! - - private let session = URLSession(configuration: .ephemeral) - - func send(_ crashReport: CrashReport) { - guard let contentData = crashReport.contentData else { - assertionFailure("CrashReportSender: Can't get the content of the crash report") - return - } - var request = URLRequest(url: Self.reportServiceUrl) - request.setValue("text/plain", forHTTPHeaderField: "Content-Type") - request.setValue("ddg_mac", forHTTPHeaderField: "User-Agent") - request.httpMethod = "POST" - request.httpBody = contentData - - session.dataTask(with: request) { (_, _, error) in - if error != nil { - assertionFailure("CrashReportSender: Failed to send the crash reprot") - } - }.resume() - } - -} diff --git a/DuckDuckGo/CrashReports/Model/CrashReporter.swift b/DuckDuckGo/CrashReports/Model/CrashReporter.swift index 39288b6043..f8e73f87e6 100644 --- a/DuckDuckGo/CrashReports/Model/CrashReporter.swift +++ b/DuckDuckGo/CrashReports/Model/CrashReporter.swift @@ -16,19 +16,20 @@ // limitations under the License. // +import Common +import Crashes import Foundation +import PixelKit final class CrashReporter { private let reader = CrashReportReader() - private lazy var sender = CrashReportSender() + private lazy var sender = CrashReportSender(platform: .macOS, log: .default) private lazy var promptPresenter = CrashReportPromptPresenter() @UserDefaultsWrapper(key: .lastCrashReportCheckDate, defaultValue: nil) private var lastCheckDate: Date? - private var latestCrashReport: CrashReport? - func checkForNewReports() { #if !DEBUG @@ -47,31 +48,19 @@ final class CrashReporter { return } - Pixel.fire(.crash) - - latestCrashReport = latest - promptPresenter.showPrompt(self, for: latest) - -#endif - - } - -} - -extension CrashReporter: CrashReportPromptViewControllerDelegate { + PixelKit.fire(GeneralPixel.crash) - func crashReportPromptViewController(_ crashReportPromptViewController: CrashReportPromptViewController, - userDidAllowToReport: Bool) { - guard userDidAllowToReport else { - return + promptPresenter.showPrompt(for: latest) { + guard let contentData = latest.contentData else { + assertionFailure("CrashReporter: Can't get the content of the crash report") + return + } + Task { + await self.sender.send(contentData) + } } - guard let latestCrashReport = latestCrashReport else { - assertionFailure("CrashReporter: The latest crash report is nil") - return - } +#endif - sender.send(latestCrashReport) } - } diff --git a/DuckDuckGo/CrashReports/View/CrashReportPromptViewController.swift b/DuckDuckGo/CrashReports/View/CrashReportPromptViewController.swift index f8977d640b..4b21d7a222 100644 --- a/DuckDuckGo/CrashReports/View/CrashReportPromptViewController.swift +++ b/DuckDuckGo/CrashReports/View/CrashReportPromptViewController.swift @@ -18,13 +18,6 @@ import Cocoa -protocol CrashReportPromptViewControllerDelegate: AnyObject { - - func crashReportPromptViewController(_ crashReportPromptViewController: CrashReportPromptViewController, - userDidAllowToReport: Bool) - -} - final class CrashReportPromptViewController: NSViewController { @IBOutlet weak var titleLabel: NSTextField! @IBOutlet weak var dontSendButton: NSButton! @@ -33,8 +26,9 @@ final class CrashReportPromptViewController: NSViewController { @IBOutlet weak var descriptionLabel: NSTextField! @IBOutlet var textView: NSTextView! - weak var delegate: CrashReportPromptViewControllerDelegate? - var crashReport: CrashReport? { + var userDidAllowToReport: () -> Void = {} + + var crashReport: CrashReportPresenting? { didSet { updateView() } @@ -58,12 +52,11 @@ final class CrashReportPromptViewController: NSViewController { } @IBAction func sendAction(_ sender: Any) { - delegate?.crashReportPromptViewController(self, userDidAllowToReport: true) + userDidAllowToReport() view.window?.close() } @IBAction func dontSendAction(_ sender: Any) { - delegate?.crashReportPromptViewController(self, userDidAllowToReport: false) view.window?.close() } diff --git a/DuckDuckGo/DBP/DBPHomeViewController.swift b/DuckDuckGo/DBP/DBPHomeViewController.swift index c8d4c2b3ca..55d08d7d62 100644 --- a/DuckDuckGo/DBP/DBPHomeViewController.swift +++ b/DuckDuckGo/DBP/DBPHomeViewController.swift @@ -34,8 +34,15 @@ final class DBPHomeViewController: NSViewController { private var presentedWindowController: NSWindowController? private let dataBrokerProtectionManager: DataBrokerProtectionManager private let pixelHandler: EventMapping = DataBrokerProtectionPixelsHandler() + private var currentChildViewController: NSViewController? + private var observer: NSObjectProtocol? - lazy var dataBrokerProtectionViewController: DataBrokerProtectionViewController = { + private let prerequisiteVerifier: DataBrokerPrerequisitesStatusVerifier + private lazy var errorViewController: DataBrokerProtectionErrorViewController = { + DataBrokerProtectionErrorViewController() + }() + + private lazy var dataBrokerProtectionViewController: DataBrokerProtectionViewController = { let privacyConfigurationManager = PrivacyFeatures.contentBlocking.privacyConfigurationManager let features = ContentScopeFeatureToggles(emailProtection: false, emailProtectionIncontextSignup: false, @@ -64,8 +71,9 @@ final class DBPHomeViewController: NSViewController { }) }() - init(dataBrokerProtectionManager: DataBrokerProtectionManager) { + init(dataBrokerProtectionManager: DataBrokerProtectionManager, prerequisiteVerifier: DataBrokerPrerequisitesStatusVerifier = DefaultDataBrokerPrerequisitesStatusVerifier()) { self.dataBrokerProtectionManager = dataBrokerProtectionManager + self.prerequisiteVerifier = prerequisiteVerifier super.init(nibName: nil, bundle: nil) } @@ -80,9 +88,8 @@ final class DBPHomeViewController: NSViewController { override func viewDidLoad() { super.viewDidLoad() - if !dataBrokerProtectionManager.shouldAskForInviteCode() { - attachDataBrokerContainerView() - } + setupUI() + setupObserver() do { if try dataBrokerProtectionManager.dataManager.fetchProfile() != nil { @@ -95,15 +102,10 @@ final class DBPHomeViewController: NSViewController { } } - private func attachDataBrokerContainerView() { - addChild(dataBrokerProtectionViewController) - view.addSubview(dataBrokerProtectionViewController.view) - } - override func viewDidAppear() { super.viewDidAppear() - if dataBrokerProtectionManager.shouldAskForInviteCode() { + if shouldAskForInviteCode() { presentInviteCodeFlow() } } @@ -111,6 +113,19 @@ final class DBPHomeViewController: NSViewController { override func viewDidLayout() { super.viewDidLayout() dataBrokerProtectionViewController.view.frame = view.bounds + errorViewController.view.frame = view.bounds + } + + private func setupUI() { + if !shouldAskForInviteCode() { + setupUIWithCurrentStatus() + } + } + + private func setupObserver() { + observer = NotificationCenter.default.addObserver(forName: NSApplication.didBecomeActiveNotification, object: nil, queue: nil) { [weak self] _ in + self?.setupUI() + } } private func presentInviteCodeFlow() { @@ -128,13 +143,54 @@ final class DBPHomeViewController: NSViewController { } parentWindowController.window?.beginSheet(newWindow) } + + private func setupUIWithCurrentStatus() { + setupUIWithStatus(prerequisiteVerifier.checkStatus()) + } + + private func setupUIWithStatus(_ status: DataBrokerPrerequisitesStatus) { + switch status { + case .invalidDirectory: + displayWrongDirectoryErrorUI() + pixelHandler.fire(.homeViewShowBadPathError) + case .invalidSystemPermission: + displayWrongPermissionsErrorUI() + pixelHandler.fire(.homeViewShowNoPermissionError) + case .valid: + displayDBPUI() + pixelHandler.fire(.homeViewShowWebUI) + } + } + + private func shouldAskForInviteCode() -> Bool { + prerequisiteVerifier.checkStatus() == .valid && dataBrokerProtectionManager.shouldAskForInviteCode() + } + + private func displayDBPUI() { + replaceChildController(dataBrokerProtectionViewController) + } + + private func replaceChildController(_ childViewController: NSViewController) { + if let child = currentChildViewController { + child.removeCompletely() + } + + addAndLayoutChild(childViewController) + self.currentChildViewController = childViewController + } + + deinit { + if let observer = observer { + NotificationCenter.default.removeObserver(observer) + } + } } extension DBPHomeViewController: DataBrokerProtectionInviteDialogsViewModelDelegate { func dataBrokerProtectionInviteDialogsViewModelDidReedemSuccessfully(_ viewModel: DataBrokerProtectionInviteDialogsViewModel) { presentedWindowController?.window?.close() presentedWindowController = nil - attachDataBrokerContainerView() + setupUIWithCurrentStatus() } func dataBrokerProtectionInviteDialogsViewModelDidCancel(_ viewModel: DataBrokerProtectionInviteDialogsViewModel) { @@ -144,79 +200,54 @@ extension DBPHomeViewController: DataBrokerProtectionInviteDialogsViewModelDeleg } } -public class DataBrokerProtectionPixelsHandler: EventMapping { - - // swiftlint:disable:next function_body_length - public init() { - super.init { event, _, _, _ in - switch event { - case .error(let error, _): - Pixel.fire(.debug(event: .pixelKitEvent(event), error: error)) - case .generalError(let error, _), - .secureVaultInitError(let error), - .secureVaultError(let error): - // We can't use .debug directly because it modifies the pixel name and clobbers the params - Pixel.fire(.pixelKitEvent(DebugEvent(event, error: error))) - case .ipcServerOptOutAllBrokersCompletion(error: let error), - .ipcServerScanAllBrokersCompletion(error: let error), - .ipcServerRunQueuedOperationsCompletion(error: let error): - // We can't use .debug directly because it modifies the pixel name and clobbers the params - Pixel.fire(.pixelKitEvent(DebugEvent(event, error: error))) - case .parentChildMatches, - .optOutStart, - .optOutEmailGenerate, - .optOutCaptchaParse, - .optOutCaptchaSend, - .optOutCaptchaSolve, - .optOutSubmit, - .optOutEmailReceive, - .optOutEmailConfirm, - .optOutValidate, - .optOutFinish, - .optOutSubmitSuccess, - .optOutFillForm, - .optOutSuccess, - .optOutFailure, - .backgroundAgentStarted, - .backgroundAgentRunOperationsAndStartSchedulerIfPossible, - .backgroundAgentRunOperationsAndStartSchedulerIfPossibleNoSavedProfile, - .backgroundAgentRunOperationsAndStartSchedulerIfPossibleRunQueuedOperationsCallbackStartScheduler, - .backgroundAgentStartedStoppingDueToAnotherInstanceRunning, - .ipcServerRegister, - .ipcServerStartScheduler, - .ipcServerStopScheduler, - .ipcServerOptOutAllBrokers, - .ipcServerScanAllBrokers, - .ipcServerRunQueuedOperations, - .ipcServerRunAllOperations, - .scanSuccess, - .scanFailed, - .scanError, - .dataBrokerProtectionNotificationSentFirstScanComplete, - .dataBrokerProtectionNotificationOpenedFirstScanComplete, - .dataBrokerProtectionNotificationSentFirstRemoval, - .dataBrokerProtectionNotificationOpenedFirstRemoval, - .dataBrokerProtectionNotificationScheduled2WeeksCheckIn, - .dataBrokerProtectionNotificationOpened2WeeksCheckIn, - .dataBrokerProtectionNotificationSentAllRecordsRemoved, - .dataBrokerProtectionNotificationOpenedAllRecordsRemoved, - .dailyActiveUser, - .weeklyActiveUser, - .monthlyActiveUser, - .weeklyReportScanning, - .weeklyReportRemovals, - .scanningEventNewMatch, - .scanningEventReAppearance, - .webUILoadingFailed, - .webUILoadingStarted, - .webUILoadingSuccess: - Pixel.fire(.pixelKitEvent(event)) - } +// MARK: - Error UI + +extension DBPHomeViewController { + private func displayWrongDirectoryErrorUI() { + let errorViewModel = DataBrokerProtectionErrorViewModel(title: UserText.dbpErrorPageBadPathTitle, + message: UserText.dbpErrorPageBadPathMessage, + ctaText: UserText.dbpErrorPageBadPathCTA, + ctaAction: { [weak self] in + self?.moveToApplicationFolder() + }) + + errorViewController.errorViewModel = errorViewModel + replaceChildController(errorViewController) + } + + private func displayWrongPermissionsErrorUI() { + let errorViewModel = DataBrokerProtectionErrorViewModel(title: UserText.dbpErrorPageNoPermissionTitle, + message: UserText.dbpErrorPageNoPermissionMessage, + ctaText: UserText.dbpErrorPageNoPermissionCTA, + ctaAction: { [weak self] in + self?.openLoginItemSettings() + }) + + errorViewController.errorViewModel = errorViewModel + replaceChildController(errorViewController) + } +} + +// MARK: - System configuration + +import ServiceManagement + +extension DBPHomeViewController { + func openLoginItemSettings() { + pixelHandler.fire(.homeViewCTAGrantPermissionClicked) + if #available(macOS 13.0, *) { + SMAppService.openSystemSettingsLoginItems() + } else { + let loginItemsURL = URL(string: "x-apple.systempreferences:com.apple.LoginItems-Settings.extension")! + NSWorkspace.shared.open(loginItemsURL) } } - override init(mapping: @escaping EventMapping.Mapping) { - fatalError("Use init()") + func moveToApplicationFolder() { + pixelHandler.fire(.homeViewCTAMoveApplicationClicked) + Task { @MainActor in + await AppLauncher(appBundleURL: Bundle.main.bundleURL).launchApp(withCommand: .moveAppToApplications) + } } } diff --git a/DuckDuckGo/DBP/DataBrokerPrerequisitesStatusVerifier.swift b/DuckDuckGo/DBP/DataBrokerPrerequisitesStatusVerifier.swift new file mode 100644 index 0000000000..f5f5c4d091 --- /dev/null +++ b/DuckDuckGo/DBP/DataBrokerPrerequisitesStatusVerifier.swift @@ -0,0 +1,50 @@ +// +// DataBrokerPrerequisitesStatusVerifier.swift +// +// Copyright © 2024 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. +// + +import Foundation +import Combine +import DataBrokerProtection +import LoginItems + +enum DataBrokerPrerequisitesStatus { + case invalidDirectory + case invalidSystemPermission + case valid +} + +protocol DataBrokerPrerequisitesStatusVerifier: AnyObject { + func checkStatus() -> DataBrokerPrerequisitesStatus +} + +final class DefaultDataBrokerPrerequisitesStatusVerifier: DataBrokerPrerequisitesStatusVerifier { + private let statusChecker: DBPLoginItemStatusChecker + + init(statusChecker: DBPLoginItemStatusChecker = LoginItem.dbpBackgroundAgent) { + self.statusChecker = statusChecker + } + + func checkStatus() -> DataBrokerPrerequisitesStatus { + if !statusChecker.doesHaveNecessaryPermissions() { + return .invalidSystemPermission + } else if !statusChecker.isInCorrectDirectory() { + return .invalidDirectory + } else { + return .valid + } + } +} diff --git a/DuckDuckGo/DBP/DataBrokerProtectionAppEvents.swift b/DuckDuckGo/DBP/DataBrokerProtectionAppEvents.swift index 352e8419ab..05f1584b80 100644 --- a/DuckDuckGo/DBP/DataBrokerProtectionAppEvents.swift +++ b/DuckDuckGo/DBP/DataBrokerProtectionAppEvents.swift @@ -81,9 +81,9 @@ struct DataBrokerProtectionAppEvents { if DataBrokerProtectionWaitlist().readyToAcceptTermsAndConditions { switch source { case .cardUI: - DataBrokerProtectionExternalWaitlistPixels.fire(pixel: .dataBrokerProtectionWaitlistCardUITapped, frequency: .dailyAndCount) + DataBrokerProtectionExternalWaitlistPixels.fire(pixel: GeneralPixel.dataBrokerProtectionWaitlistCardUITapped, frequency: .dailyAndCount) case .localPush: - DataBrokerProtectionExternalWaitlistPixels.fire(pixel: .dataBrokerProtectionWaitlistNotificationTapped, frequency: .dailyAndCount) + DataBrokerProtectionExternalWaitlistPixels.fire(pixel: GeneralPixel.dataBrokerProtectionWaitlistNotificationTapped, frequency: .dailyAndCount) } DataBrokerProtectionWaitlistViewControllerPresenter.show() @@ -96,12 +96,12 @@ struct DataBrokerProtectionAppEvents { private func sendActiveDataBrokerProtectionWaitlistUserPixel() { if DefaultDataBrokerProtectionFeatureVisibility().waitlistIsOngoing { - DataBrokerProtectionExternalWaitlistPixels.fire(pixel: .dataBrokerProtectionWaitlistUserActive, frequency: .dailyOnly) + DataBrokerProtectionExternalWaitlistPixels.fire(pixel: GeneralPixel.dataBrokerProtectionWaitlistUserActive, frequency: .daily) } } private func restartBackgroundAgent(loginItemsManager: LoginItemsManager) { - DataBrokerProtectionLoginItemPixels.fire(pixel: .dataBrokerResetLoginItemDaily, frequency: .dailyOnly) + DataBrokerProtectionLoginItemPixels.fire(pixel: GeneralPixel.dataBrokerResetLoginItemDaily, frequency: .daily) loginItemsManager.disableLoginItems([LoginItem.dbpBackgroundAgent]) loginItemsManager.enableLoginItems([LoginItem.dbpBackgroundAgent], log: .dbp) diff --git a/DuckDuckGo/DBP/DataBrokerProtectionDebugMenu.swift b/DuckDuckGo/DBP/DataBrokerProtectionDebugMenu.swift index 1478151aca..48a458f3cf 100644 --- a/DuckDuckGo/DBP/DataBrokerProtectionDebugMenu.swift +++ b/DuckDuckGo/DBP/DataBrokerProtectionDebugMenu.swift @@ -48,6 +48,7 @@ final class DataBrokerProtectionDebugMenu: NSMenu { private let customURLLabelMenuItem = NSMenuItem(title: "") private let environmentMenu = NSMenu() + private let statusMenuIconMenu = NSMenuItem(title: "Show Status Menu Icon", action: #selector(DataBrokerProtectionDebugMenu.toggleShowStatusMenuItem)) private let webUISettings = DataBrokerProtectionWebUIURLSettings(.dbp) private let settings = DataBrokerProtectionSettings(defaults: .dbp) @@ -147,6 +148,8 @@ final class DataBrokerProtectionDebugMenu: NSMenu { NSMenuItem.separator() + statusMenuIconMenu.targetting(self) + NSMenuItem(title: "Show DB Browser", action: #selector(DataBrokerProtectionDebugMenu.showDatabaseBrowser)) .targetting(self) NSMenuItem(title: "Force Profile Removal", action: #selector(DataBrokerProtectionDebugMenu.showForceOptOutWindow)) @@ -172,6 +175,7 @@ final class DataBrokerProtectionDebugMenu: NSMenu { updateWaitlistItems() updateWebUIMenuItemsState() updateEnvironmentMenu() + updateShowStatusMenuIconMenu() } // MARK: - Menu functions @@ -211,7 +215,7 @@ final class DataBrokerProtectionDebugMenu: NSMenu { } if let operationErrors = errors.operationErrors, operationErrors.count != 0 { - os_log("Queued operations finished, operation errors count: %{public}@", log: .dataBrokerProtection, operationErrors.count) + os_log("Queued operations finished, operation errors count: %{public}d", log: .dataBrokerProtection, operationErrors.count) } } else { os_log("Queued operations finished", log: .dataBrokerProtection) @@ -223,14 +227,14 @@ final class DataBrokerProtectionDebugMenu: NSMenu { os_log("Running scan operations...", log: .dataBrokerProtection) let showWebView = sender.representedObject as? Bool ?? false - DataBrokerProtectionManager.shared.scheduler.scanAllBrokers(showWebView: showWebView) { errors in + DataBrokerProtectionManager.shared.scheduler.startManualScan(showWebView: showWebView) { errors in if let errors = errors { if let oneTimeError = errors.oneTimeError { - os_log("scan operations finished, error: %{public}@", log: .dataBrokerProtection, oneTimeError.localizedDescription) + os_log("scan operations finished, error: %{public}@", log: .dataBrokerProtection, oneTimeError.localizedDescription) } if let operationErrors = errors.operationErrors, operationErrors.count != 0 { - os_log("scan operations finished, operation errors count: %{public}@", log: .dataBrokerProtection, operationErrors.count) + os_log("scan operations finished, operation errors count: %{public}d", log: .dataBrokerProtection, operationErrors.count) } } else { os_log("Scan operations finished", log: .dataBrokerProtection) @@ -249,7 +253,7 @@ final class DataBrokerProtectionDebugMenu: NSMenu { } if let operationErrors = errors.operationErrors, operationErrors.count != 0 { - os_log("Optout operations finished, operation errors count: %{public}@", log: .dataBrokerProtection, operationErrors.count) + os_log("Optout operations finished, operation errors count: %{public}d", log: .dataBrokerProtection, operationErrors.count) } } else { os_log("Optout operations finished", log: .dataBrokerProtection) @@ -366,6 +370,10 @@ final class DataBrokerProtectionDebugMenu: NSMenu { } } + @objc private func toggleShowStatusMenuItem() { + settings.showInMenuBar.toggle() + } + @objc func setSelectedEnvironment(_ menuItem: NSMenuItem) { let title = menuItem.title let selectedEnvironment: DataBrokerProtectionSettings.SelectedEnvironment @@ -448,6 +456,10 @@ final class DataBrokerProtectionDebugMenu: NSMenu { environmentMenu.items.first?.state = selectedEnvironment == .production ? .on: .off environmentMenu.items.last?.state = selectedEnvironment == .staging ? .on: .off } + + private func updateShowStatusMenuIconMenu() { + statusMenuIconMenu.state = settings.showInMenuBar ? .on : .off + } } extension DataBrokerProtectionDebugMenu: NSWindowDelegate { diff --git a/DuckDuckGo/DBP/DataBrokerProtectionExternalWaitlistPixels.swift b/DuckDuckGo/DBP/DataBrokerProtectionExternalWaitlistPixels.swift index 79a6d85bf5..f23a4884a5 100644 --- a/DuckDuckGo/DBP/DataBrokerProtectionExternalWaitlistPixels.swift +++ b/DuckDuckGo/DBP/DataBrokerProtectionExternalWaitlistPixels.swift @@ -17,6 +17,7 @@ // import Foundation +import PixelKit struct DataBrokerProtectionExternalWaitlistPixels { @@ -35,15 +36,11 @@ struct DataBrokerProtectionExternalWaitlistPixels { return (regionCode ?? "US") == "US" } - static func fire(pixel: Pixel.Event, frequency: DailyPixel.PixelFrequency) { + static func fire(pixel: PixelKitEventV2, frequency: PixelKit.Frequency) { if Self.isUserLocaleAllowed { let isInternalUser = NSApp.delegateTyped.internalUserDecider.isInternalUser - DailyPixel.fire(pixel: pixel, - frequency: frequency, - withAdditionalParameters: [ - "isInternalUser": isInternalUser.description - ] - ) + let parameters = ["isInternalUser": isInternalUser.description] + PixelKit.fire(pixel, frequency: frequency, withAdditionalParameters: parameters) } } } diff --git a/DuckDuckGo/DBP/DataBrokerProtectionFeatureDisabler.swift b/DuckDuckGo/DBP/DataBrokerProtectionFeatureDisabler.swift index d66ed38247..83489b21bb 100644 --- a/DuckDuckGo/DBP/DataBrokerProtectionFeatureDisabler.swift +++ b/DuckDuckGo/DBP/DataBrokerProtectionFeatureDisabler.swift @@ -52,7 +52,7 @@ struct DataBrokerProtectionFeatureDisabler: DataBrokerProtectionFeatureDisabling os_log("DataBrokerProtectionFeatureDisabler error: disableAndDelete, error: %{public}@", log: .error, error.localizedDescription) } - DataBrokerProtectionLoginItemPixels.fire(pixel: .dataBrokerDisableAndDeleteDaily, frequency: .dailyOnly) + DataBrokerProtectionLoginItemPixels.fire(pixel: GeneralPixel.dataBrokerDisableAndDeleteDaily, frequency: .daily) NotificationCenter.default.post(name: .dbpWasDisabled, object: nil) } } diff --git a/DuckDuckGo/DBP/DataBrokerProtectionLoginItemPixels.swift b/DuckDuckGo/DBP/DataBrokerProtectionLoginItemPixels.swift index 30e2373a7f..6b10effcf1 100644 --- a/DuckDuckGo/DBP/DataBrokerProtectionLoginItemPixels.swift +++ b/DuckDuckGo/DBP/DataBrokerProtectionLoginItemPixels.swift @@ -17,19 +17,16 @@ // import Foundation +import PixelKit struct DataBrokerProtectionLoginItemPixels { - static func fire(pixel: Pixel.Event, frequency: DailyPixel.PixelFrequency) { + static func fire(pixel: PixelKitEventV2, frequency: PixelKit.Frequency) { DispatchQueue.main.async { // delegateTyped needs to be called in the main thread let isInternalUser = NSApp.delegateTyped.internalUserDecider.isInternalUser - DailyPixel.fire(pixel: pixel, - frequency: frequency, - withAdditionalParameters: [ - "isInternalUser": isInternalUser.description - ] - ) + let parameters = ["isInternalUser": isInternalUser.description] + PixelKit.fire(pixel, frequency: frequency, withAdditionalParameters: parameters) } } } diff --git a/DuckDuckGo/DBP/DataBrokerProtectionLoginItemScheduler.swift b/DuckDuckGo/DBP/DataBrokerProtectionLoginItemScheduler.swift index 34dafab63f..cc0d841ee8 100644 --- a/DuckDuckGo/DBP/DataBrokerProtectionLoginItemScheduler.swift +++ b/DuckDuckGo/DBP/DataBrokerProtectionLoginItemScheduler.swift @@ -36,12 +36,12 @@ final class DataBrokerProtectionLoginItemScheduler { // MARK: - Login Item Management func disableLoginItem() { - DataBrokerProtectionLoginItemPixels.fire(pixel: .dataBrokerDisableLoginItemDaily, frequency: .dailyOnly) + DataBrokerProtectionLoginItemPixels.fire(pixel: GeneralPixel.dataBrokerDisableLoginItemDaily, frequency: .daily) loginItemsManager.disableLoginItems([.dbpBackgroundAgent]) } func enableLoginItem() { - DataBrokerProtectionLoginItemPixels.fire(pixel: .dataBrokerEnableLoginItemDaily, frequency: .dailyOnly) + DataBrokerProtectionLoginItemPixels.fire(pixel: GeneralPixel.dataBrokerEnableLoginItemDaily, frequency: .daily) loginItemsManager.enableLoginItems([.dbpBackgroundAgent], log: .dbp) } } @@ -55,10 +55,10 @@ extension DataBrokerProtectionLoginItemScheduler: DataBrokerProtectionScheduler ipcScheduler.statusPublisher } - func scanAllBrokers(showWebView: Bool, - completion: ((DataBrokerProtectionSchedulerErrorCollection?) -> Void)?) { + func startManualScan(showWebView: Bool, + completion: ((DataBrokerProtectionSchedulerErrorCollection?) -> Void)?) { enableLoginItem() - ipcScheduler.scanAllBrokers(showWebView: showWebView, completion: completion) + ipcScheduler.startManualScan(showWebView: showWebView, completion: completion) } func startScheduler(showWebView: Bool) { @@ -83,6 +83,10 @@ extension DataBrokerProtectionLoginItemScheduler: DataBrokerProtectionScheduler completion: ((DataBrokerProtectionSchedulerErrorCollection?) -> Void)?) { ipcScheduler.runQueuedOperations(showWebView: showWebView, completion: completion) } + + func getDebugMetadata(completion: @escaping (DBPBackgroundAgentMetadata?) -> Void) { + ipcScheduler.getDebugMetadata(completion: completion) + } } #endif diff --git a/DuckDuckGo/DBP/DataBrokerProtectionManager.swift b/DuckDuckGo/DBP/DataBrokerProtectionManager.swift index adb20e4aee..f3b8705674 100644 --- a/DuckDuckGo/DBP/DataBrokerProtectionManager.swift +++ b/DuckDuckGo/DBP/DataBrokerProtectionManager.swift @@ -41,7 +41,12 @@ public final class DataBrokerProtectionManager { return dataManager }() - private lazy var ipcClient = DataBrokerProtectionIPCClient(machServiceName: Bundle.main.dbpBackgroundAgentBundleId, pixelHandler: pixelHandler) + private lazy var ipcClient: DataBrokerProtectionIPCClient = { + let loginItemStatusChecker = LoginItem.dbpBackgroundAgent + return DataBrokerProtectionIPCClient(machServiceName: Bundle.main.dbpBackgroundAgentBundleId, + pixelHandler: pixelHandler, + loginItemStatusChecker: loginItemStatusChecker) + }() lazy var scheduler: DataBrokerProtectionLoginItemScheduler = { diff --git a/DuckDuckGo/DBP/DataBrokerProtectionPixelsHandler.swift b/DuckDuckGo/DBP/DataBrokerProtectionPixelsHandler.swift new file mode 100644 index 0000000000..08c5b74f18 --- /dev/null +++ b/DuckDuckGo/DBP/DataBrokerProtectionPixelsHandler.swift @@ -0,0 +1,118 @@ +// +// DataBrokerProtectionPixelsHandler.swift +// +// Copyright © 2024 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. +// + +import Foundation +import DataBrokerProtection +import PixelKit +import Common + +public class DataBrokerProtectionPixelsHandler: EventMapping { + + // swiftlint:disable:next function_body_length + public init() { + super.init { event, _, _, _ in + switch event { + case .error(let error, _): + PixelKit.fire(DebugEvent(event, error: error)) + case .generalError(let error, _), + .secureVaultInitError(let error), + .secureVaultError(let error): + PixelKit.fire(DebugEvent(event, error: error)) + case .ipcServerStartSchedulerXPCError(error: let error), + .ipcServerStopSchedulerXPCError(error: let error), + .ipcServerScanAllBrokersXPCError(error: let error), + .ipcServerScanAllBrokersCompletedOnAgentWithError(error: let error), + .ipcServerScanAllBrokersCompletionCalledOnAppWithError(error: let error), + .ipcServerOptOutAllBrokersCompletion(error: let error), + .ipcServerRunQueuedOperationsCompletion(error: let error): + PixelKit.fire(DebugEvent(event, error: error), frequency: .dailyAndCount, includeAppVersionParameter: true) + case .ipcServerStartSchedulerCalledByApp, + .ipcServerStartSchedulerReceivedByAgent, + .ipcServerStopSchedulerCalledByApp, + .ipcServerStopSchedulerReceivedByAgent, + .ipcServerScanAllBrokersAttemptedToCallWithoutLoginItemPermissions, + .ipcServerScanAllBrokersAttemptedToCallInWrongDirectory, + .ipcServerScanAllBrokersCalledByApp, + .ipcServerScanAllBrokersReceivedByAgent, + .ipcServerScanAllBrokersCompletedOnAgentWithoutError, + .ipcServerScanAllBrokersCompletionCalledOnAppWithoutError, + .ipcServerScanAllBrokersInterruptedOnAgent, + .ipcServerScanAllBrokersCompletionCalledOnAppAfterInterruption: + PixelKit.fire(event, frequency: .dailyAndCount, includeAppVersionParameter: true) + case .parentChildMatches, + .optOutStart, + .optOutEmailGenerate, + .optOutCaptchaParse, + .optOutCaptchaSend, + .optOutCaptchaSolve, + .optOutSubmit, + .optOutEmailReceive, + .optOutEmailConfirm, + .optOutValidate, + .optOutFinish, + .optOutSubmitSuccess, + .optOutFillForm, + .optOutSuccess, + .optOutFailure, + .backgroundAgentStarted, + .backgroundAgentRunOperationsAndStartSchedulerIfPossible, + .backgroundAgentRunOperationsAndStartSchedulerIfPossibleNoSavedProfile, + .backgroundAgentRunOperationsAndStartSchedulerIfPossibleRunQueuedOperationsCallbackStartScheduler, + .backgroundAgentStartedStoppingDueToAnotherInstanceRunning, + .ipcServerOptOutAllBrokers, + .ipcServerRunQueuedOperations, + .ipcServerRunAllOperations, + .scanSuccess, + .scanFailed, + .scanError, + .dataBrokerProtectionNotificationSentFirstScanComplete, + .dataBrokerProtectionNotificationOpenedFirstScanComplete, + .dataBrokerProtectionNotificationSentFirstRemoval, + .dataBrokerProtectionNotificationOpenedFirstRemoval, + .dataBrokerProtectionNotificationScheduled2WeeksCheckIn, + .dataBrokerProtectionNotificationOpened2WeeksCheckIn, + .dataBrokerProtectionNotificationSentAllRecordsRemoved, + .dataBrokerProtectionNotificationOpenedAllRecordsRemoved, + .dailyActiveUser, + .weeklyActiveUser, + .monthlyActiveUser, + .weeklyReportScanning, + .weeklyReportRemovals, + .scanningEventNewMatch, + .scanningEventReAppearance, + .webUILoadingFailed, + .webUILoadingStarted, + .webUILoadingSuccess, + .emptyAccessTokenDaily, + .generateEmailHTTPErrorDaily: + PixelKit.fire(event) + + case .homeViewShowNoPermissionError, + .homeViewShowWebUI, + .homeViewShowBadPathError, + .homeViewCTAMoveApplicationClicked, + .homeViewCTAGrantPermissionClicked: + PixelKit.fire(event, frequency: .dailyAndCount) + } + } + } + + override init(mapping: @escaping EventMapping.Mapping) { + fatalError("Use init()") + } +} diff --git a/DuckDuckGo/DBP/DataBrokerProtectionSubscriptionEventHandler.swift b/DuckDuckGo/DBP/DataBrokerProtectionSubscriptionEventHandler.swift index 08ec829fb1..57dd6d5c33 100644 --- a/DuckDuckGo/DBP/DataBrokerProtectionSubscriptionEventHandler.swift +++ b/DuckDuckGo/DBP/DataBrokerProtectionSubscriptionEventHandler.swift @@ -15,11 +15,12 @@ // See the License for the specific language governing permissions and // limitations under the License. // -#if DBP && SUBSCRIPTION +#if DBP import Foundation import Subscription import DataBrokerProtection +import PixelKit final class DataBrokerProtectionSubscriptionEventHandler { @@ -42,7 +43,7 @@ final class DataBrokerProtectionSubscriptionEventHandler { @objc private func handleAccountDidSignIn() { guard let token = accountManager.accessToken else { - Pixel.fire(.dataBrokerProtectionErrorWhenFetchingSubscriptionAuthTokenAfterSignIn) + PixelKit.fire(GeneralPixel.dataBrokerProtectionErrorWhenFetchingSubscriptionAuthTokenAfterSignIn) assertionFailure("[DBP Subscription] AccountManager signed in but token could not be retrieved") return } diff --git a/DuckDuckGo/DBP/ErrorView/DataBrokerProtectionErrorViewController.swift b/DuckDuckGo/DBP/ErrorView/DataBrokerProtectionErrorViewController.swift new file mode 100644 index 0000000000..fa628b686e --- /dev/null +++ b/DuckDuckGo/DBP/ErrorView/DataBrokerProtectionErrorViewController.swift @@ -0,0 +1,92 @@ +// +// DataBrokerProtectionErrorViewController.swift +// +// Copyright © 2024 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. +// + +import Foundation +import SwiftUI + +final class DataBrokerProtectionErrorViewController: NSViewController { + private var errorSubview: NSView? + + var errorViewModel: DataBrokerProtectionErrorViewModel? { + didSet { + guard let errorViewModel = errorViewModel else { return } + + errorSubview?.removeFromSuperview() + + let errorView = DataBrokerProtectionErrorView(viewModel: errorViewModel) + errorSubview = NSHostingView(rootView: errorView) + + if let errorSubview = errorSubview { + view.addAndLayout(errorSubview) + } + } + } +} + +struct DataBrokerProtectionErrorView: View { + var viewModel: DataBrokerProtectionErrorViewModel + + var body: some View { + VStack(alignment: .center, spacing: 16) { + + HStack { + Image("DaxLockScreenLogo") + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 32, height: 32) + + Text("Privacy Pro") + .font(.title) + .fontWeight(.light) + } + .padding(.bottom, 25) + + HStack { + Image("dbp-error-info") + .resizable() + .frame(width: 24, height: 24) + + Text(viewModel.title) + .font(.title) + .fontWeight(.light) + } + + Text(viewModel.message) + .font(.body) + .fontWeight(.light) + .multilineTextAlignment(.center) + .padding(.bottom, 10) + + Button(action: { + viewModel.ctaAction() + }) { + Text(viewModel.ctaText) + } + + Spacer() + }.padding() + .frame(maxWidth: 500) + } +} + +struct DataBrokerProtectionErrorViewModel { + let title: String + let message: String + let ctaText: String + let ctaAction: () -> Void +} diff --git a/DuckDuckGo/DBP/LoginItem+DataBrokerProtection.swift b/DuckDuckGo/DBP/LoginItem+DataBrokerProtection.swift index cdbfa623a9..d6fbfa761f 100644 --- a/DuckDuckGo/DBP/LoginItem+DataBrokerProtection.swift +++ b/DuckDuckGo/DBP/LoginItem+DataBrokerProtection.swift @@ -18,6 +18,7 @@ import Foundation import LoginItems +import DataBrokerProtection #if DBP @@ -27,4 +28,28 @@ extension LoginItem { } +extension LoginItem: DBPLoginItemStatusChecker { + + public func doesHaveNecessaryPermissions() -> Bool { + return status != .requiresApproval + } + + public func isInCorrectDirectory() -> Bool { + guard let appPath = Bundle.main.resourceURL?.deletingLastPathComponent() else { return false } + let dirPaths = NSSearchPathForDirectoriesInDomains(.applicationDirectory, .localDomainMask, true) + for path in dirPaths { + let filePath: URL + if #available(macOS 13.0, *) { + filePath = URL(filePath: path) + } else { + filePath = URL(fileURLWithPath: path) + } + if appPath.absoluteString.hasPrefix(filePath.absoluteString) { + return true + } + } + return false + } +} + #endif diff --git a/DuckDuckGo/DBP/RemoteMessaging/DataBrokerProtectionRemoteMessaging.swift b/DuckDuckGo/DBP/RemoteMessaging/DataBrokerProtectionRemoteMessaging.swift index 4359b535e0..b43994834b 100644 --- a/DuckDuckGo/DBP/RemoteMessaging/DataBrokerProtectionRemoteMessaging.swift +++ b/DuckDuckGo/DBP/RemoteMessaging/DataBrokerProtectionRemoteMessaging.swift @@ -18,6 +18,7 @@ import Foundation import Networking +import PixelKit #if DBP @@ -91,7 +92,7 @@ final class DefaultDataBrokerProtectionRemoteMessaging: DataBrokerProtectionRemo try self.messageStorage.store(messages: messages) self.updateLastRefreshDate() // Update last refresh date on success, otherwise let the app try again next time } catch { - Pixel.fire(.debug(event: .dataBrokerProtectionRemoteMessageStorageFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.dataBrokerProtectionRemoteMessageStorageFailed, error: error)) } case .failure(let error): // Ignore 403 errors, those happen when a file can't be found on S3 @@ -100,7 +101,7 @@ final class DefaultDataBrokerProtectionRemoteMessaging: DataBrokerProtectionRemo return } - Pixel.fire(.debug(event: .dataBrokerProtectionRemoteMessageFetchingFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.dataBrokerProtectionRemoteMessageFetchingFailed, error: error)) } } } diff --git a/DuckDuckGo/DataExport/CSVLoginExporter.swift b/DuckDuckGo/DataExport/CSVLoginExporter.swift index 26e9a3f0d2..90062966fe 100644 --- a/DuckDuckGo/DataExport/CSVLoginExporter.swift +++ b/DuckDuckGo/DataExport/CSVLoginExporter.swift @@ -18,6 +18,7 @@ import Foundation import BrowserServicesKit +import PixelKit final class CSVLoginExporter { @@ -49,7 +50,7 @@ final class CSVLoginExporter { } } } catch { - Pixel.fire(.debug(event: .secureVaultError, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.secureVaultError(error: error))) throw error } diff --git a/DuckDuckGo/DataImport/Bookmarks/Safari/SafariDataImporter.swift b/DuckDuckGo/DataImport/Bookmarks/Safari/SafariDataImporter.swift index 005fc26971..0f3daaef5d 100644 --- a/DuckDuckGo/DataImport/Bookmarks/Safari/SafariDataImporter.swift +++ b/DuckDuckGo/DataImport/Bookmarks/Safari/SafariDataImporter.swift @@ -17,7 +17,7 @@ // import AppKit -import Foundation +import PixelKit final class SafariDataImporter: DataImporter { @@ -114,7 +114,7 @@ final class SafariDataImporter: DataImporter { await faviconManager.handleFaviconsByDocumentUrl(faviconsByDocument) case .failure(let error): - Pixel.fire(.dataImportFailed(source: source, sourceVersion: profile.installedAppsMajorVersionDescription(), error: error)) + PixelKit.fire(GeneralPixel.dataImportFailed(source: source, sourceVersion: profile.installedAppsMajorVersionDescription(), error: error)) } } diff --git a/DuckDuckGo/DataImport/Logins/Chromium/ChromiumDataImporter.swift b/DuckDuckGo/DataImport/Logins/Chromium/ChromiumDataImporter.swift index a387ac7d34..1f920dd809 100644 --- a/DuckDuckGo/DataImport/Logins/Chromium/ChromiumDataImporter.swift +++ b/DuckDuckGo/DataImport/Logins/Chromium/ChromiumDataImporter.swift @@ -17,6 +17,7 @@ // import Foundation +import PixelKit internal class ChromiumDataImporter: DataImporter { @@ -139,7 +140,7 @@ internal class ChromiumDataImporter: DataImporter { await faviconManager.handleFaviconsByDocumentUrl(faviconsByDocument) case .failure(let error): - Pixel.fire(.dataImportFailed(source: source, sourceVersion: profile.installedAppsMajorVersionDescription(), error: error)) + PixelKit.fire(GeneralPixel.dataImportFailed(source: source, sourceVersion: profile.installedAppsMajorVersionDescription(), error: error)) } } diff --git a/DuckDuckGo/DataImport/Logins/Chromium/ChromiumKeychainPrompt.swift b/DuckDuckGo/DataImport/Logins/Chromium/ChromiumKeychainPrompt.swift index 4e473eada8..08872a1d78 100644 --- a/DuckDuckGo/DataImport/Logins/Chromium/ChromiumKeychainPrompt.swift +++ b/DuckDuckGo/DataImport/Logins/Chromium/ChromiumKeychainPrompt.swift @@ -17,6 +17,7 @@ // import Foundation +import PixelKit enum ChromiumKeychainPromptResult { case password(String) @@ -45,7 +46,7 @@ final class ChromiumKeychainPrompt: ChromiumKeychainPrompting { var dataFromKeychain: AnyObject? // Fire Pixel to help measure rate of password prompt denied actions - Pixel.fire(.passwordImportKeychainPrompt) + PixelKit.fire(GeneralPixel.passwordImportKeychainPrompt) let status: OSStatus = SecItemCopyMatching(query as CFDictionary, &dataFromKeychain) diff --git a/DuckDuckGo/DataImport/Logins/Firefox/FirefoxDataImporter.swift b/DuckDuckGo/DataImport/Logins/Firefox/FirefoxDataImporter.swift index a6b87ee62b..5eb7ca6353 100644 --- a/DuckDuckGo/DataImport/Logins/Firefox/FirefoxDataImporter.swift +++ b/DuckDuckGo/DataImport/Logins/Firefox/FirefoxDataImporter.swift @@ -18,6 +18,7 @@ import Foundation import SecureStorage +import PixelKit internal class FirefoxDataImporter: DataImporter { @@ -139,7 +140,7 @@ internal class FirefoxDataImporter: DataImporter { await faviconManager.handleFaviconsByDocumentUrl(faviconsByDocument) case .failure(let error): - Pixel.fire(.dataImportFailed(source: source, sourceVersion: profile.installedAppsMajorVersionDescription(), error: error)) + PixelKit.fire(GeneralPixel.dataImportFailed(source: source, sourceVersion: profile.installedAppsMajorVersionDescription(), error: error)) } } diff --git a/DuckDuckGo/DataImport/Logins/SecureVault/SecureVaultLoginImporter.swift b/DuckDuckGo/DataImport/Logins/SecureVault/SecureVaultLoginImporter.swift index 17acb874e0..193806cef0 100644 --- a/DuckDuckGo/DataImport/Logins/SecureVault/SecureVaultLoginImporter.swift +++ b/DuckDuckGo/DataImport/Logins/SecureVault/SecureVaultLoginImporter.swift @@ -23,7 +23,7 @@ import SecureStorage final class SecureVaultLoginImporter: LoginImporter { func importLogins(_ logins: [ImportedLoginCredential], progressCallback: @escaping (Int) throws -> Void) throws -> DataImport.DataTypeSummary { - let vault = try AutofillSecureVaultFactory.makeVault(errorReporter: SecureVaultErrorReporter.shared) + let vault = try AutofillSecureVaultFactory.makeVault(reporter: SecureVaultReporter.shared) var successful: [String] = [] var duplicates: [String] = [] diff --git a/DuckDuckGo/DataImport/Model/DataImportViewModel.swift b/DuckDuckGo/DataImport/Model/DataImportViewModel.swift index 8757194031..7e6211da9d 100644 --- a/DuckDuckGo/DataImport/Model/DataImportViewModel.swift +++ b/DuckDuckGo/DataImport/Model/DataImportViewModel.swift @@ -18,8 +18,8 @@ import AppKit import Common -import Foundation import UniformTypeIdentifiers +import PixelKit struct DataImportViewModel { @@ -253,8 +253,7 @@ struct DataImportViewModel { // switch to file import of the failed data type displaying successful import results nextScreen = .fileImport(dataType: dataType, summary: Set(summary.filter({ $0.value.isSuccess }).keys)) } - - Pixel.fire(.dataImportFailed(source: importSource, sourceVersion: importSource.installedAppsMajorVersionDescription(selectedProfile: selectedProfile), error: error)) + PixelKit.fire(GeneralPixel.dataImportFailed(source: importSource, sourceVersion: importSource.installedAppsMajorVersionDescription(selectedProfile: selectedProfile), error: error)) } } @@ -292,7 +291,7 @@ struct DataImportViewModel { switch error { // chromium user denied keychain prompt error case let error as ChromiumLoginReader.ImportError where error.type == .userDeniedKeychainPrompt: - Pixel.fire(.passwordImportKeychainPromptDenied) + PixelKit.fire(GeneralPixel.passwordImportKeychainPromptDenied) // stay on the same screen return true @@ -316,7 +315,7 @@ struct DataImportViewModel { log("file read no permission for \(url.path)") if url != selectedProfile?.profileURL.appendingPathComponent(SafariDataImporter.bookmarksFileName) { - Pixel.fire(.dataImportFailed(source: importSource, sourceVersion: importSource.installedAppsMajorVersionDescription(selectedProfile: selectedProfile), error: importError)) + PixelKit.fire(GeneralPixel.dataImportFailed(source: importSource, sourceVersion: importSource.installedAppsMajorVersionDescription(selectedProfile: selectedProfile), error: importError)) } screen = .getReadPermission(url) return true diff --git a/DuckDuckGo/DataImport/View/DataImportView.swift b/DuckDuckGo/DataImport/View/DataImportView.swift index 67a8dad11c..2302b54421 100644 --- a/DuckDuckGo/DataImport/View/DataImportView.swift +++ b/DuckDuckGo/DataImport/View/DataImportView.swift @@ -492,8 +492,7 @@ extension DataImportViewModel.ButtonType { profileURL: URL(fileURLWithPath: "/test/Profile 1")), .init(browser: .chrome, profileURL: URL(fileURLWithPath: "/test/Profile 2")), - ], validateProfileData: { _ in - { .init(logins: .available, bookmarks: .available) } // swiftlint:disable:this opening_brace + ], validateProfileData: { _ in { .init(logins: .available, bookmarks: .available) } // swiftlint:disable:this opening_brace }) } dataImporterFactory: { source, type, _, _ in return MockDataImporter(source: source, dataType: type) diff --git a/DuckDuckGo/DataImport/View/ReportFeedbackView.swift b/DuckDuckGo/DataImport/View/ReportFeedbackView.swift index dc35dc0745..86aa8da7c4 100644 --- a/DuckDuckGo/DataImport/View/ReportFeedbackView.swift +++ b/DuckDuckGo/DataImport/View/ReportFeedbackView.swift @@ -150,4 +150,4 @@ private struct InfoItemView: View { } return PreviewView() -} ()} +}()} diff --git a/DuckDuckGo/DeviceAuthentication/DeviceAuthenticationService.swift b/DuckDuckGo/DeviceAuthentication/DeviceAuthenticationService.swift index 307a1bc3bd..3cc09f250d 100644 --- a/DuckDuckGo/DeviceAuthentication/DeviceAuthenticationService.swift +++ b/DuckDuckGo/DeviceAuthentication/DeviceAuthenticationService.swift @@ -21,6 +21,7 @@ import Foundation enum DeviceAuthenticationResult { case success case failure + case noAuthAvailable var authenticated: Bool { return self == .success diff --git a/DuckDuckGo/DeviceAuthentication/LocalAuthenticationService.swift b/DuckDuckGo/DeviceAuthentication/LocalAuthenticationService.swift index 474d53c750..b7ddbe7416 100644 --- a/DuckDuckGo/DeviceAuthentication/LocalAuthenticationService.swift +++ b/DuckDuckGo/DeviceAuthentication/LocalAuthenticationService.swift @@ -24,6 +24,12 @@ final class LocalAuthenticationService: DeviceAuthenticationService { func authenticateDevice(reason: String, result: @escaping DeviceAuthenticationResultHandler) { let context = LAContext() + var error: NSError? + guard context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) else { + result(.noAuthAvailable) + return + } + context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: reason) { authenticated, _ in DispatchQueue.main.async { let authenticationResult: DeviceAuthenticationResult = authenticated ? .success : .failure diff --git a/DuckDuckGo/Email/EmailManagerRequestDelegate.swift b/DuckDuckGo/Email/EmailManagerRequestDelegate.swift index 6b01002a03..43e96115fd 100644 --- a/DuckDuckGo/Email/EmailManagerRequestDelegate.swift +++ b/DuckDuckGo/Email/EmailManagerRequestDelegate.swift @@ -17,6 +17,7 @@ // import BrowserServicesKit +import PixelKit extension EmailManagerRequestDelegate { @@ -67,7 +68,7 @@ extension EmailManagerRequestDelegate { parameters["keychain_operation"] = "save" } - Pixel.fire(.debug(event: .emailAutofillKeychainError), withAdditionalParameters: parameters) + PixelKit.fire(DebugEvent(GeneralPixel.emailAutofillKeychainError), withAdditionalParameters: parameters) } } diff --git a/DuckDuckGo/Favicons/Services/FaviconStore.swift b/DuckDuckGo/Favicons/Services/FaviconStore.swift index 7e2826c27e..2376d29162 100644 --- a/DuckDuckGo/Favicons/Services/FaviconStore.swift +++ b/DuckDuckGo/Favicons/Services/FaviconStore.swift @@ -20,6 +20,7 @@ import Cocoa import CoreData import Combine import Common +import PixelKit protocol FaviconStoring { @@ -230,7 +231,7 @@ fileprivate extension Favicon { let documentUrl = faviconMO.documentUrlEncrypted as? URL, let dateCreated = faviconMO.dateCreated, let relation = Favicon.Relation(rawValue: Int(faviconMO.relation)) else { - Pixel.fire(.debug(event: .faviconDecryptionFailedUnique), limitTo: .dailyFirst) + PixelKit.fire(DebugEvent(GeneralPixel.faviconDecryptionFailedUnique), frequency: .daily) assertionFailure("Favicon: Failed to init Favicon from FaviconManagedObject") return nil } diff --git a/DuckDuckGo/Feedback/Model/FeedbackSender.swift b/DuckDuckGo/Feedback/Model/FeedbackSender.swift index 3e032d36aa..09be2ef5a7 100644 --- a/DuckDuckGo/Feedback/Model/FeedbackSender.swift +++ b/DuckDuckGo/Feedback/Model/FeedbackSender.swift @@ -19,6 +19,7 @@ import Common import Foundation import Networking +import PixelKit final class FeedbackSender { @@ -43,7 +44,7 @@ final class FeedbackSender { request.fetch { _, error in if let error = error { os_log("FeedbackSender: Failed to submit feedback %s", type: .error, error.localizedDescription) - Pixel.fire(.debug(event: .feedbackReportingFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.feedbackReportingFailed, error: error)) } } } diff --git a/DuckDuckGo/FileDownload/Model/WebKitDownloadTask.swift b/DuckDuckGo/FileDownload/Model/WebKitDownloadTask.swift index b263df5915..db56c4d535 100644 --- a/DuckDuckGo/FileDownload/Model/WebKitDownloadTask.swift +++ b/DuckDuckGo/FileDownload/Model/WebKitDownloadTask.swift @@ -22,6 +22,7 @@ import Foundation import Navigation import UniformTypeIdentifiers import WebKit +import PixelKit protocol WebKitDownloadTaskDelegate: AnyObject { func fileDownloadTaskNeedsDestinationURL(_ task: WebKitDownloadTask, suggestedFilename: String, suggestedFileType: UTType?) async -> (URL?, UTType?) @@ -274,7 +275,7 @@ final class WebKitDownloadTask: NSObject, ProgressReporting, @unchecked Sendable self.download.cancel() self.finish(with: .failure(.failedToCompleteDownloadTask(underlyingError: error, resumeData: nil, isRetryable: false))) - Pixel.fire(.debug(event: .fileGetDownloadLocationFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.fileGetDownloadLocationFailed, error: error)) } return nil } @@ -334,7 +335,7 @@ final class WebKitDownloadTask: NSObject, ProgressReporting, @unchecked Sendable self.download.cancel() self.finish(with: .failure(.failedToCompleteDownloadTask(underlyingError: error, resumeData: nil, isRetryable: false))) - Pixel.fire(.debug(event: .fileDownloadCreatePresentersFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.fileDownloadCreatePresentersFailed, error: error)) } } @@ -393,7 +394,7 @@ final class WebKitDownloadTask: NSObject, ProgressReporting, @unchecked Sendable } catch { // fallback: move failed, keep the temp file in the original location os_log(.error, log: log, "🙁 fallback with \(error), will use \(tempURL.path)") - Pixel.fire(.debug(event: .fileAccessRelatedItemFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.fileAccessRelatedItemFailed, error: error)) return tempURL } } @@ -686,7 +687,7 @@ extension WebKitDownloadTask: WKDownloadDelegate { self.finish(with: .success(destinationFile)) } catch { - Pixel.fire(.debug(event: .fileMoveToDownloadsFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.fileMoveToDownloadsFailed, error: error)) os_log(.error, log: log, "fileMoveToDownloadsFailed: \(error)") self.finish(with: .failure(.failedToCompleteDownloadTask(underlyingError: error, resumeData: nil, isRetryable: false))) } diff --git a/DuckDuckGo/FileDownload/Services/DownloadListCoordinator.swift b/DuckDuckGo/FileDownload/Services/DownloadListCoordinator.swift index 70cfda3f2d..55763a2c5c 100644 --- a/DuckDuckGo/FileDownload/Services/DownloadListCoordinator.swift +++ b/DuckDuckGo/FileDownload/Services/DownloadListCoordinator.swift @@ -20,6 +20,7 @@ import Combine import Common import Foundation import Navigation +import PixelKit @MainActor private func getFirstAvailableWebView() -> WKWebView? { @@ -482,7 +483,7 @@ final class DownloadListCoordinator { } } catch { assertionFailure("Resume data coding failed: \(error)") - Pixel.fire(.debug(event: .downloadResumeDataCodingFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.downloadResumeDataCodingFailed, error: error)) } webView.resumeDownload(fromResumeData: resumeData, diff --git a/DuckDuckGo/FileDownload/Services/DownloadListStore.swift b/DuckDuckGo/FileDownload/Services/DownloadListStore.swift index cec1d0e0da..9af9ffb38a 100644 --- a/DuckDuckGo/FileDownload/Services/DownloadListStore.swift +++ b/DuckDuckGo/FileDownload/Services/DownloadListStore.swift @@ -21,6 +21,7 @@ import Common import CoreData import Foundation import UniformTypeIdentifiers +import PixelKit protocol DownloadListStoring { @@ -191,7 +192,7 @@ extension DownloadListItem { let modified = managedObject.modified, let url = managedObject.urlEncrypted as? URL else { - Pixel.fire(.debug(event: .downloadListItemDecryptionFailedUnique), limitTo: .dailyFirst) + PixelKit.fire(DebugEvent(GeneralPixel.downloadListItemDecryptionFailedUnique), frequency: .daily) assertionFailure("DownloadListItem: Failed to init from ManagedObject") return nil } diff --git a/DuckDuckGo/Fire/Model/Fire.swift b/DuckDuckGo/Fire/Model/Fire.swift index 29c2ca70f0..4766d8b6e6 100644 --- a/DuckDuckGo/Fire/Model/Fire.swift +++ b/DuckDuckGo/Fire/Model/Fire.swift @@ -385,7 +385,7 @@ final class Fire { // MARK: - Favicons private func autofillDomains() -> Set { - guard let vault = try? secureVaultFactory.makeVault(errorReporter: SecureVaultErrorReporter.shared), + guard let vault = try? secureVaultFactory.makeVault(reporter: SecureVaultReporter.shared), let accounts = try? vault.accounts() else { return [] } diff --git a/DuckDuckGo/Fire/Model/TabCleanupPreparer.swift b/DuckDuckGo/Fire/Model/TabCleanupPreparer.swift index 798ebc2f7c..30314266da 100644 --- a/DuckDuckGo/Fire/Model/TabCleanupPreparer.swift +++ b/DuckDuckGo/Fire/Model/TabCleanupPreparer.swift @@ -17,6 +17,7 @@ // import Foundation +import PixelKit protocol TabDataClearing { func prepareForDataClearing(caller: TabCleanupPreparer) @@ -65,7 +66,7 @@ final class TabCleanupPreparer: NSObject, WKNavigationDelegate { } func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { - Pixel.fire(.debug(event: .blankNavigationOnBurnFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.blankNavigationOnBurnFailed, error: error)) processedTabs += 1 notifyIfDone() diff --git a/DuckDuckGo/Fire/ViewModel/FirePopoverViewModel.swift b/DuckDuckGo/Fire/ViewModel/FirePopoverViewModel.swift index b10b728212..1221497f5f 100644 --- a/DuckDuckGo/Fire/ViewModel/FirePopoverViewModel.swift +++ b/DuckDuckGo/Fire/ViewModel/FirePopoverViewModel.swift @@ -20,6 +20,7 @@ import Cocoa import BrowserServicesKit import Common import History +import PixelKit @MainActor final class FirePopoverViewModel { @@ -188,7 +189,7 @@ final class FirePopoverViewModel { // MARK: - Burning func burn() { - Pixel.fire(.fireButtonFirstBurn, limitTo: .dailyFirst) + PixelKit.fire(GeneralPixel.fireButtonFirstBurn, frequency: .daily) switch (clearingOption, areAllSelected) { case (.currentTab, _): @@ -197,7 +198,7 @@ final class FirePopoverViewModel { assertionFailure("No tab selected") return } - Pixel.fire(.fireButton(option: .tab)) + PixelKit.fire(GeneralPixel.fireButton(option: .tab)) let burningEntity = Fire.BurningEntity.tab(tabViewModel: tabViewModel, selectedDomains: selectedDomains, parentTabCollectionViewModel: tabCollectionViewModel) @@ -207,17 +208,17 @@ final class FirePopoverViewModel { assertionFailure("FirePopoverViewModel: TabCollectionViewModel is not present") return } - Pixel.fire(.fireButton(option: .window)) + PixelKit.fire(GeneralPixel.fireButton(option: .window)) let burningEntity = Fire.BurningEntity.window(tabCollectionViewModel: tabCollectionViewModel, selectedDomains: selectedDomains) fireViewModel.fire.burnEntity(entity: burningEntity) case (.allData, true): - Pixel.fire(.fireButton(option: .allSites)) + PixelKit.fire(GeneralPixel.fireButton(option: .allSites)) fireViewModel.fire.burnAll() case (.allData, false): - Pixel.fire(.fireButton(option: .allSites)) + PixelKit.fire(GeneralPixel.fireButton(option: .allSites)) fireViewModel.fire.burnEntity(entity: .allWindows(mainWindowControllers: WindowControllersManager.shared.mainWindowControllers, selectedDomains: selectedDomains)) } diff --git a/DuckDuckGo/History/Services/EncryptedHistoryStore.swift b/DuckDuckGo/History/Services/EncryptedHistoryStore.swift index 36838c0539..a62dc501ce 100644 --- a/DuckDuckGo/History/Services/EncryptedHistoryStore.swift +++ b/DuckDuckGo/History/Services/EncryptedHistoryStore.swift @@ -21,6 +21,7 @@ import Foundation import CoreData import Combine import History +import PixelKit final class EncryptedHistoryStore: HistoryStoring { @@ -91,7 +92,7 @@ final class EncryptedHistoryStore: HistoryStoring { } os_log("%d items cleaned from history", log: .history, entriesToDelete.count) } catch { - Pixel.fire(.debug(event: .historyRemoveFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.historyRemoveFailed, error: error)) self.context.reset() return .failure(error) } @@ -100,7 +101,7 @@ final class EncryptedHistoryStore: HistoryStoring { do { try context.save() } catch { - Pixel.fire(.debug(event: .historyRemoveFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.historyRemoveFailed, error: error)) context.reset() return .failure(error) } @@ -117,7 +118,7 @@ final class EncryptedHistoryStore: HistoryStoring { let history = BrowsingHistory(historyEntries: historyEntries) return .success(history) } catch { - Pixel.fire(.debug(event: .historyReloadFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.historyReloadFailed, error: error)) return .failure(error) } } @@ -133,7 +134,7 @@ final class EncryptedHistoryStore: HistoryStoring { } try context.save() } catch { - Pixel.fire(.debug(event: .historyCleanEntriesFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.historyCleanEntriesFailed, error: error)) context.reset() return .failure(error) } @@ -149,7 +150,7 @@ final class EncryptedHistoryStore: HistoryStoring { try context.save() return .success(()) } catch { - Pixel.fire(.debug(event: .historyCleanVisitsFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.historyCleanVisitsFailed, error: error)) context.reset() return .failure(error) } @@ -174,8 +175,8 @@ final class EncryptedHistoryStore: HistoryStoring { do { fetchedObjects = try self.context.fetch(fetchRequest) } catch { - Pixel.fire(.debug(event: .historySaveFailed, error: error)) - Pixel.fire(.debug(event: .historySaveFailedDaily, error: error), limitTo: .dailyFirst) + PixelKit.fire(DebugEvent(GeneralPixel.historySaveFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.historySaveFailedDaily, error: error), frequency: .legacyDaily) promise(.failure(error)) return } @@ -203,16 +204,16 @@ final class EncryptedHistoryStore: HistoryStoring { context: self.context) switch insertionResult { case .failure(let error): - Pixel.fire(.debug(event: .historySaveFailed, error: error)) - Pixel.fire(.debug(event: .historySaveFailedDaily, error: error), limitTo: .dailyFirst) + PixelKit.fire(DebugEvent(GeneralPixel.historySaveFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.historySaveFailedDaily, error: error), frequency: .legacyDaily) context.reset() promise(.failure(error)) case .success(let visitMOs): do { try self.context.save() } catch { - Pixel.fire(.debug(event: .historySaveFailed, error: error)) - Pixel.fire(.debug(event: .historySaveFailedDaily, error: error), limitTo: .dailyFirst) + PixelKit.fire(DebugEvent(GeneralPixel.historySaveFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.historySaveFailedDaily, error: error), frequency: .legacyDaily) context.reset() promise(.failure(HistoryStoreError.savingFailed)) return @@ -262,7 +263,7 @@ final class EncryptedHistoryStore: HistoryStoring { context: NSManagedObjectContext) -> Result { let insertedObject = NSEntityDescription.insertNewObject(forEntityName: VisitManagedObject.className(), into: context) guard let visitMO = insertedObject as? VisitManagedObject else { - Pixel.fire(.debug(event: .historyInsertVisitFailed)) + PixelKit.fire(DebugEvent(GeneralPixel.historyInsertVisitFailed)) context.reset() return .failure(HistoryStoreError.savingFailed) } @@ -310,7 +311,7 @@ final class EncryptedHistoryStore: HistoryStoring { context.delete(visit) } } catch { - Pixel.fire(.debug(event: .historyRemoveVisitsFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.historyRemoveVisitsFailed, error: error)) return .failure(error) } } @@ -318,7 +319,7 @@ final class EncryptedHistoryStore: HistoryStoring { do { try context.save() } catch { - Pixel.fire(.debug(event: .historyRemoveVisitsFailed, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.historyRemoveVisitsFailed, error: error)) context.reset() return .failure(error) } @@ -346,7 +347,7 @@ fileprivate extension HistoryEntry { guard let url = historyEntryMO.urlEncrypted as? URL, let identifier = historyEntryMO.identifier, let lastVisit = historyEntryMO.lastVisit else { - Pixel.fire(.debug(event: .historyEntryDecryptionFailedUnique), limitTo: .dailyFirst) + PixelKit.fire(DebugEvent(GeneralPixel.historyEntryDecryptionFailedUnique), frequency: .daily) assertionFailure("HistoryEntry: Failed to init HistoryEntry from HistoryEntryManagedObject") return nil } diff --git a/DuckDuckGo/HomePage/Model/DataImportStatusProviding.swift b/DuckDuckGo/HomePage/Model/DataImportStatusProviding.swift index 7c729d99ad..17efd1a64d 100644 --- a/DuckDuckGo/HomePage/Model/DataImportStatusProviding.swift +++ b/DuckDuckGo/HomePage/Model/DataImportStatusProviding.swift @@ -19,6 +19,7 @@ import Foundation import Bookmarks import BrowserServicesKit +import PixelKit protocol DataImportStatusProviding { var didImport: Bool { get } @@ -30,7 +31,7 @@ final class BookmarksAndPasswordsImportStatusProvider: DataImportStatusProviding let secureVault: (any AutofillSecureVault)? let bookmarkManager: BookmarkManager - init(secureVault: (any AutofillSecureVault)? = try? AutofillSecureVaultFactory.makeVault(errorReporter: SecureVaultErrorReporter.shared), + init(secureVault: (any AutofillSecureVault)? = try? AutofillSecureVaultFactory.makeVault(reporter: SecureVaultReporter.shared), bookmarkManager: BookmarkManager = LocalBookmarkManager.shared) { self.secureVault = secureVault self.bookmarkManager = bookmarkManager @@ -80,7 +81,7 @@ final class BookmarksAndPasswordsImportStatusProvider: DataImportStatusProviding let identitiesDates = try secureVault.identities().map(\.created) dates.append(contentsOf: identitiesDates) } catch { - Pixel.fire(.debug(event: .secureVaultError, error: error)) + PixelKit.fire(DebugEvent(GeneralPixel.secureVaultError(error: error))) } guard dates.count >= 2 else { return false diff --git a/DuckDuckGo/HomePage/Model/HomePageContinueSetUpModel.swift b/DuckDuckGo/HomePage/Model/HomePageContinueSetUpModel.swift index eb693541b9..b99a4a2949 100644 --- a/DuckDuckGo/HomePage/Model/HomePageContinueSetUpModel.swift +++ b/DuckDuckGo/HomePage/Model/HomePageContinueSetUpModel.swift @@ -20,6 +20,8 @@ import AppKit import BrowserServicesKit import Common import Foundation +import PixelKit + import NetworkProtection import NetworkProtectionUI @@ -38,38 +40,18 @@ extension HomePage.Models { let deleteActionTitle = UserText.newTabSetUpRemoveItemAction let privacyConfigurationManager: PrivacyConfigurationManaging let homePageRemoteMessaging: HomePageRemoteMessaging + let permanentSurveyManager: SurveyManager - var isDay0SurveyEnabled: Bool { - let newTabContinueSetUpSettings = privacyConfigurationManager.privacyConfig.settings(for: .newTabContinueSetUp) - if let day0SurveyString = newTabContinueSetUpSettings["surveyCardDay0"] as? String { - if day0SurveyString == "enabled" { - return true - } - } - return false - } - var isDay14SurveyEnabled: Bool { - let newTabContinueSetUpSettings = privacyConfigurationManager.privacyConfig.settings(for: .newTabContinueSetUp) - if let day14SurveyString = newTabContinueSetUpSettings["surveyCardDay14"] as? String { - if day14SurveyString == "enabled" { - return true - } - } - return false - } var duckPlayerURL: String { let duckPlayerSettings = privacyConfigurationManager.privacyConfig.settings(for: .duckPlayer) return duckPlayerSettings["tryDuckPlayerLink"] as? String ?? "https://www.youtube.com/watch?v=yKWIA-Pys4c" } - var day0SurveyURL: String = "https://selfserve.decipherinc.com/survey/selfserve/32ab/240300?list=1" - var day14SurveyURL: String = "https://selfserve.decipherinc.com/survey/selfserve/32ab/240300?list=2" private let defaultBrowserProvider: DefaultBrowserProvider private let dataImportProvider: DataImportStatusProviding private let tabCollectionViewModel: TabCollectionViewModel private let emailManager: EmailManager private let duckPlayerPreferences: DuckPlayerPreferencesPersistor - private let randomNumberGenerator: RandomNumberGenerating @UserDefaultsWrapper(key: .homePageShowAllFeatures, defaultValue: false) var shouldShowAllFeatures: Bool { @@ -90,30 +72,15 @@ extension HomePage.Models { @UserDefaultsWrapper(key: .homePageShowEmailProtection, defaultValue: true) private var shouldShowEmailProtectionSetting: Bool - @UserDefaultsWrapper(key: .homePageShowSurveyDay0, defaultValue: true) - private var shouldShowSurveyDay0: Bool - - @UserDefaultsWrapper(key: .homePageUserInteractedWithSurveyDay0, defaultValue: false) - private var userInteractedWithSurveyDay0: Bool + @UserDefaultsWrapper(key: .homePageShowPermanentSurvey, defaultValue: true) + private var shouldShowPermanentSurvey: Bool @UserDefaultsWrapper(key: .shouldShowDBPWaitlistInvitedCardUI, defaultValue: false) private var shouldShowDBPWaitlistInvitedCardUI: Bool - @UserDefaultsWrapper(key: .homePageShowSurveyDay14, defaultValue: true) - private var shouldShowSurveyDay14: Bool - @UserDefaultsWrapper(key: .homePageIsFirstSession, defaultValue: true) private var isFirstSession: Bool - @UserDefaultsWrapper(key: .homePageShowSurveyDay0in10Percent, defaultValue: nil) - private var isPartOfSurveyDay0On10Percent: Bool? - - @UserDefaultsWrapper(key: .homePageShowSurveyDay14in10Percent, defaultValue: nil) - private var isPartOfSurveyDay14On10Percent: Bool? - - @UserDefaultsWrapper(key: .firstLaunchDate, defaultValue: Calendar.current.date(byAdding: .month, value: -1, to: Date())!) - private var firstLaunchDate: Date - var isMoreOrLessButtonNeeded: Bool { return featuresMatrix.count > itemsRowCountWhenCollapsed } @@ -122,10 +89,6 @@ extension HomePage.Models { return !featuresMatrix.isEmpty } - lazy var statisticsStore: StatisticsStore = LocalStatisticsStore() - - lazy var waitlistBetaThankYouPresenter = WaitlistThankYouPromptPresenter() - lazy var listOfFeatures = isFirstSession ? firstRunFeatures : randomisedFeatures private var featuresMatrix: [[FeatureType]] = [[]] { @@ -143,7 +106,7 @@ extension HomePage.Models { duckPlayerPreferences: DuckPlayerPreferencesPersistor, homePageRemoteMessaging: HomePageRemoteMessaging, privacyConfigurationManager: PrivacyConfigurationManaging = AppPrivacyFeatures.shared.contentBlocking.privacyConfigurationManager, - randomNumberGenerator: RandomNumberGenerating = RandomNumberGenerator()) { + permanentSurveyManager: SurveyManager = PermanentSurveyManager()) { self.defaultBrowserProvider = defaultBrowserProvider self.dataImportProvider = dataImportProvider self.tabCollectionViewModel = tabCollectionViewModel @@ -151,7 +114,7 @@ extension HomePage.Models { self.duckPlayerPreferences = duckPlayerPreferences self.homePageRemoteMessaging = homePageRemoteMessaging self.privacyConfigurationManager = privacyConfigurationManager - self.randomNumberGenerator = randomNumberGenerator + self.permanentSurveyManager = permanentSurveyManager refreshFeaturesMatrix() @@ -159,12 +122,11 @@ extension HomePage.Models { NotificationCenter.default.addObserver(self, selector: #selector(windowDidBecomeKey(_:)), name: NSWindow.didBecomeKeyNotification, object: nil) } - // swiftlint:disable:next cyclomatic_complexity @MainActor func performAction(for featureType: FeatureType) { switch featureType { case .defaultBrowser: do { - Pixel.fire(.defaultRequestedFromHomepageSetupView) + PixelKit.fire(GeneralPixel.defaultRequestedFromHomepageSetupView) try defaultBrowserProvider.presentDefaultBrowserPrompt() } catch { defaultBrowserProvider.openSystemPreferences() @@ -179,10 +141,8 @@ extension HomePage.Models { case .emailProtection: let tab = Tab(content: .url(EmailUrls().emailProtectionLink, source: .ui), shouldLoadInBackground: true) tabCollectionViewModel.append(tab: tab) - case .surveyDay0: - visitSurvey(day: .day0) - case .surveyDay14: - visitSurvey(day: .day14) + case .permanentSurvey: + visitSurvey() case .networkProtectionRemoteMessage(let message): handle(remoteMessage: message) case .dataBrokerProtectionRemoteMessage(let message): @@ -191,18 +151,9 @@ extension HomePage.Models { #if DBP DataBrokerProtectionAppEvents().handleWaitlistInvitedNotification(source: .cardUI) #endif - case .vpnThankYou: - guard let window = NSApp.keyWindow, - case .normal = NSApp.runType else { return } - waitlistBetaThankYouPresenter.presentVPNThankYouPrompt(in: window) - case .pirThankYou: - guard let window = NSApp.keyWindow, - case .normal = NSApp.runType else { return } - waitlistBetaThankYouPresenter.presentPIRThankYouPrompt(in: window) } } - // swiftlint:disable:next cyclomatic_complexity func removeItem(for featureType: FeatureType) { switch featureType { case .defaultBrowser: @@ -213,29 +164,22 @@ extension HomePage.Models { shouldShowDuckPlayerSetting = false case .emailProtection: shouldShowEmailProtectionSetting = false - case .surveyDay0: - shouldShowSurveyDay0 = false - case .surveyDay14: - shouldShowSurveyDay14 = false + case .permanentSurvey: + shouldShowPermanentSurvey = false case .networkProtectionRemoteMessage(let message): homePageRemoteMessaging.networkProtectionRemoteMessaging.dismiss(message: message) - Pixel.fire(.networkProtectionRemoteMessageDismissed(messageID: message.id)) + PixelKit.fire(GeneralPixel.networkProtectionRemoteMessageDismissed(messageID: message.id)) case .dataBrokerProtectionRemoteMessage(let message): #if DBP homePageRemoteMessaging.dataBrokerProtectionRemoteMessaging.dismiss(message: message) - Pixel.fire(.dataBrokerProtectionRemoteMessageDismissed(messageID: message.id)) + PixelKit.fire(GeneralPixel.dataBrokerProtectionRemoteMessageDismissed(messageID: message.id)) #endif case .dataBrokerProtectionWaitlistInvited: shouldShowDBPWaitlistInvitedCardUI = false - case .vpnThankYou: - waitlistBetaThankYouPresenter.didDismissVPNThankYouCard() - case .pirThankYou: - waitlistBetaThankYouPresenter.didDismissPIRThankYouCard() } refreshFeaturesMatrix() } - // swiftlint:disable:next cyclomatic_complexity function_body_length func refreshFeaturesMatrix() { var features: [FeatureType] = [] #if DBP @@ -245,65 +189,42 @@ extension HomePage.Models { for message in homePageRemoteMessaging.dataBrokerProtectionRemoteMessaging.presentableRemoteMessages() { features.append(.dataBrokerProtectionRemoteMessage(message)) - DailyPixel.fire( - pixel: .dataBrokerProtectionRemoteMessageDisplayed(messageID: message.id), - frequency: .dailyOnly - ) + PixelKit.fire(GeneralPixel.dataBrokerProtectionRemoteMessageDisplayed(messageID: message.id), frequency: .daily) } #endif for message in homePageRemoteMessaging.networkProtectionRemoteMessaging.presentableRemoteMessages() { - features.append(.networkProtectionRemoteMessage(message)) - DailyPixel.fire( - pixel: .networkProtectionRemoteMessageDisplayed(messageID: message.id), - frequency: .dailyOnly - ) + PixelKit.fire(GeneralPixel.networkProtectionRemoteMessageDisplayed(messageID: message.id), frequency: .daily) } - if waitlistBetaThankYouPresenter.canShowVPNCard { - features.append(.vpnThankYou) - } + appendFeatureCards(&features) + + featuresMatrix = features.chunked(into: itemsPerRow) + } - if waitlistBetaThankYouPresenter.canShowPIRCard { - features.append(.pirThankYou) + private func appendFeatureCards(_ features: inout [FeatureType]) { + for feature in listOfFeatures where shouldAppendFeature(feature: feature) { + features.append(feature) } + } - for feature in listOfFeatures { - switch feature { - case .defaultBrowser: - if shouldMakeDefaultCardBeVisible { - features.append(feature) - } - case .importBookmarksAndPasswords: - if shouldImportCardBeVisible { - features.append(feature) - } - case .duckplayer: - if shouldDuckPlayerCardBeVisible { - features.append(feature) - } - case .emailProtection: - if shouldEmailProtectionCardBeVisible { - features.append(feature) - } - case .surveyDay0: - if shouldSurveyDay0BeVisible { - features.append(feature) - userInteractedWithSurveyDay0 = true - } - case .surveyDay14: - if shouldSurveyDay14BeVisible { - features.append(feature) - } - case .networkProtectionRemoteMessage, - .dataBrokerProtectionRemoteMessage, - .dataBrokerProtectionWaitlistInvited, - .vpnThankYou, - .pirThankYou: - break // Do nothing, these messages get appended first - } + private func shouldAppendFeature(feature: FeatureType) -> Bool { + switch feature { + case .defaultBrowser: + return shouldMakeDefaultCardBeVisible + case .importBookmarksAndPasswords: + return shouldImportCardBeVisible + case .duckplayer: + return shouldDuckPlayerCardBeVisible + case .emailProtection: + return shouldEmailProtectionCardBeVisible + case .permanentSurvey: + return shouldPermanentSurveyBeVisible + case .networkProtectionRemoteMessage, + .dataBrokerProtectionRemoteMessage, + .dataBrokerProtectionWaitlistInvited: + return false // These are handled separately } - featuresMatrix = features.chunked(into: itemsPerRow) } // Helper Functions @@ -377,69 +298,22 @@ extension HomePage.Models { !emailManager.isSignedIn } - private var shouldSurveyDay0BeVisible: Bool { - let oneDayAgo = Calendar.current.date(byAdding: .weekday, value: -1, to: Date())! - return isDay0SurveyEnabled && - shouldShowSurveyDay0 && - firstLaunchDate >= oneDayAgo && - Bundle.main.preferredLocalizations.first == "en" && - isPartOfSurveyDay0On10Percent ?? calculateIfIn10percent(day: .day0) - } - - private var shouldSurveyDay14BeVisible: Bool { - let fourteenDaysAgo = Calendar.current.date(byAdding: .weekday, value: -14, to: Date())! - let fifteenDaysAgo = Calendar.current.date(byAdding: .weekday, value: -15, to: Date())! - return isDay14SurveyEnabled && - shouldShowSurveyDay0 && - shouldShowSurveyDay14 && - !userInteractedWithSurveyDay0 && - firstLaunchDate >= fifteenDaysAgo && - firstLaunchDate <= fourteenDaysAgo && - Bundle.main.preferredLocalizations.first == "en" && - isPartOfSurveyDay14On10Percent ?? calculateIfIn10percent(day: .day14) - } - - private func calculateIfIn10percent(day: SurveyDay) -> Bool { - let randomNumber0To99 = randomNumberGenerator.random(in: 0..<100) - let isInSurvey10Percent = randomNumber0To99 < 10 - switch day { - case .day0: - isPartOfSurveyDay0On10Percent = isInSurvey10Percent - case .day14: - isPartOfSurveyDay14On10Percent = isInSurvey10Percent - } - return isInSurvey10Percent + private var shouldPermanentSurveyBeVisible: Bool { + return shouldShowPermanentSurvey && + permanentSurveyManager.isSurveyAvailable } - private enum SurveyDay { - case day0 - case day14 - } + @MainActor private func visitSurvey() { + guard let url = permanentSurveyManager.url else { return } - @MainActor private func visitSurvey(day: SurveyDay) { - var surveyURLString: String - switch day { - case .day0: - surveyURLString = day0SurveyURL - case .day14: - surveyURLString = day14SurveyURL - } - - if let url = URL(string: surveyURLString) { - let tab = Tab(content: .url(url, source: .ui), shouldLoadInBackground: true) - tabCollectionViewModel.append(tab: tab) - switch day { - case .day0: - shouldShowSurveyDay0 = false - case .day14: - shouldShowSurveyDay14 = false - } - } + let tab = Tab(content: .url(url, source: .ui), shouldLoadInBackground: true) + tabCollectionViewModel.append(tab: tab) + shouldShowPermanentSurvey = false } @MainActor private func handle(remoteMessage: NetworkProtectionRemoteMessage) { guard let actionType = remoteMessage.action.actionType else { - Pixel.fire(.networkProtectionRemoteMessageDismissed(messageID: remoteMessage.id)) + PixelKit.fire(GeneralPixel.networkProtectionRemoteMessageDismissed(messageID: remoteMessage.id)) homePageRemoteMessaging.networkProtectionRemoteMessaging.dismiss(message: remoteMessage) refreshFeaturesMatrix() return @@ -452,7 +326,7 @@ extension HomePage.Models { if let surveyURL = remoteMessage.presentableSurveyURL() { let tab = Tab(content: .url(surveyURL, source: .ui), shouldLoadInBackground: true) tabCollectionViewModel.append(tab: tab) - Pixel.fire(.networkProtectionRemoteMessageOpened(messageID: remoteMessage.id)) + PixelKit.fire(GeneralPixel.networkProtectionRemoteMessageOpened(messageID: remoteMessage.id)) // Dismiss the message after the user opens the URL, even if they just close the tab immediately afterwards. homePageRemoteMessaging.networkProtectionRemoteMessaging.dismiss(message: remoteMessage) @@ -464,7 +338,7 @@ extension HomePage.Models { @MainActor private func handle(remoteMessage: DataBrokerProtectionRemoteMessage) { #if DBP guard let actionType = remoteMessage.action.actionType else { - Pixel.fire(.dataBrokerProtectionRemoteMessageDismissed(messageID: remoteMessage.id)) + PixelKit.fire(GeneralPixel.dataBrokerProtectionRemoteMessageDismissed(messageID: remoteMessage.id)) homePageRemoteMessaging.dataBrokerProtectionRemoteMessaging.dismiss(message: remoteMessage) refreshFeaturesMatrix() return @@ -477,7 +351,7 @@ extension HomePage.Models { if let surveyURL = remoteMessage.presentableSurveyURL() { let tab = Tab(content: .url(surveyURL, source: .ui), shouldLoadInBackground: true) tabCollectionViewModel.append(tab: tab) - Pixel.fire(.dataBrokerProtectionRemoteMessageOpened(messageID: remoteMessage.id)) + PixelKit.fire(GeneralPixel.dataBrokerProtectionRemoteMessageOpened(messageID: remoteMessage.id)) // Dismiss the message after the user opens the URL, even if they just close the tab immediately afterwards. homePageRemoteMessaging.dataBrokerProtectionRemoteMessaging.dismiss(message: remoteMessage) @@ -495,20 +369,17 @@ extension HomePage.Models { // We ignore the `networkProtectionRemoteMessage` case here to avoid it getting accidentally included - it has special handling and will get // included elsewhere. static var allCases: [HomePage.Models.FeatureType] { - [.duckplayer, .emailProtection, .defaultBrowser, .importBookmarksAndPasswords, .surveyDay0, .surveyDay14] + [.duckplayer, .emailProtection, .defaultBrowser, .importBookmarksAndPasswords, .permanentSurvey] } case duckplayer case emailProtection case defaultBrowser case importBookmarksAndPasswords - case surveyDay0 - case surveyDay14 + case permanentSurvey case networkProtectionRemoteMessage(NetworkProtectionRemoteMessage) case dataBrokerProtectionRemoteMessage(DataBrokerProtectionRemoteMessage) case dataBrokerProtectionWaitlistInvited - case vpnThankYou - case pirThankYou var title: String { switch self { @@ -520,20 +391,14 @@ extension HomePage.Models { return UserText.newTabSetUpDuckPlayerCardTitle case .emailProtection: return UserText.newTabSetUpEmailProtectionCardTitle - case .surveyDay0: - return UserText.newTabSetUpSurveyDay0CardTitle - case .surveyDay14: - return UserText.newTabSetUpSurveyDay14CardTitle + case .permanentSurvey: + return PermanentSurveyManager.title case .networkProtectionRemoteMessage(let message): return message.cardTitle case .dataBrokerProtectionRemoteMessage(let message): return message.cardTitle case .dataBrokerProtectionWaitlistInvited: return "Personal Information Removal" - case .vpnThankYou: - return "Thanks for testing DuckDuckGo VPN!" - case .pirThankYou: - return "Thanks for testing Personal Information Removal!" } } @@ -547,20 +412,14 @@ extension HomePage.Models { return UserText.newTabSetUpDuckPlayerSummary case .emailProtection: return UserText.newTabSetUpEmailProtectionSummary - case .surveyDay0: - return UserText.newTabSetUpSurveyDay0Summary - case .surveyDay14: - return UserText.newTabSetUpSurveyDay14Summary + case .permanentSurvey: + return PermanentSurveyManager.body case .networkProtectionRemoteMessage(let message): return message.cardDescription case .dataBrokerProtectionRemoteMessage(let message): return message.cardDescription case .dataBrokerProtectionWaitlistInvited: return "You're invited to try Personal Information Removal beta!" - case .vpnThankYou: - return "To keep using it, subscribe to DuckDuckGo Privacy Pro." - case .pirThankYou: - return "To keep using it, subscribe to DuckDuckGo Privacy Pro." } } @@ -574,20 +433,14 @@ extension HomePage.Models { return UserText.newTabSetUpDuckPlayerAction case .emailProtection: return UserText.newTabSetUpEmailProtectionAction - case .surveyDay0: - return UserText.newTabSetUpSurveyDay0Action - case .surveyDay14: - return UserText.newTabSetUpSurveyDay14Action + case .permanentSurvey: + return PermanentSurveyManager.actionTitle case .networkProtectionRemoteMessage(let message): return message.action.actionTitle case .dataBrokerProtectionRemoteMessage(let message): return message.action.actionTitle case .dataBrokerProtectionWaitlistInvited: return "Get Started" - case .vpnThankYou: - return "See Special Offer For Testers" - case .pirThankYou: - return "See Special Offer For Testers" } } @@ -603,20 +456,14 @@ extension HomePage.Models { return .cleanTube128.resized(to: iconSize)! case .emailProtection: return .inbox128.resized(to: iconSize)! - case .surveyDay0: - return .qandA128.resized(to: iconSize)! - case .surveyDay14: - return .qandA128.resized(to: iconSize)! + case .permanentSurvey: + return .survey128.resized(to: iconSize)! case .networkProtectionRemoteMessage: return .vpnEnded.resized(to: iconSize)! case .dataBrokerProtectionRemoteMessage: return .dbpInformationRemover.resized(to: iconSize)! case .dataBrokerProtectionWaitlistInvited: return .dbpInformationRemover.resized(to: iconSize)! - case .vpnThankYou: - return .vpnEnded.resized(to: iconSize)! - case .pirThankYou: - return .dbpInformationRemover.resized(to: iconSize)! } } } @@ -665,12 +512,12 @@ struct HomePageRemoteMessaging { } -public protocol RandomNumberGenerating { - func random(in range: Range) -> Int -} - -struct RandomNumberGenerator: RandomNumberGenerating { - func random(in range: Range) -> Int { - return Int.random(in: range) +extension AppVersion { + public var majorAndMinorOSVersion: String { + let components = osVersion.split(separator: ".") + guard components.count >= 2 else { + return majorVersionNumber + } + return "\(components[0]).\(components[1])" } } diff --git a/DuckDuckGo/HomePage/Model/HomePageRecentlyVisitedModel.swift b/DuckDuckGo/HomePage/Model/HomePageRecentlyVisitedModel.swift index 2e627932cc..a22162f63e 100644 --- a/DuckDuckGo/HomePage/Model/HomePageRecentlyVisitedModel.swift +++ b/DuckDuckGo/HomePage/Model/HomePageRecentlyVisitedModel.swift @@ -28,7 +28,7 @@ final class RecentlyVisitedModel: ObservableObject { let f = RelativeDateTimeFormatter() f.unitsStyle = .abbreviated return f - } () + }() private let fire: Fire diff --git a/DuckDuckGo/HomePage/Model/PermanentSurveyManager.swift b/DuckDuckGo/HomePage/Model/PermanentSurveyManager.swift new file mode 100644 index 0000000000..529b3ddf51 --- /dev/null +++ b/DuckDuckGo/HomePage/Model/PermanentSurveyManager.swift @@ -0,0 +1,141 @@ +// +// PermanentSurveyManager.swift +// +// Copyright © 2024 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. +// + +import Foundation +import BrowserServicesKit +import Common +import AppKit + +protocol SurveyManager { + var isSurveyAvailable: Bool { get } + var url: URL? { get } + static var title: String { get } + static var body: String { get } + static var actionTitle: String { get } +} + +final class PermanentSurveyManager: SurveyManager { + static var title: String = "Help Us Improve" + static var body: String = "Take our short survey and help us build the best browser." + static var actionTitle: String = "Share Your Thoughts" + + @UserDefaultsWrapper(key: .firstLaunchDate, defaultValue: Calendar.current.date(byAdding: .month, value: -1, to: Date())!) + private var firstLaunchDate: Date + + @UserDefaultsWrapper(key: .homePageUserInSurveyShare, defaultValue: nil) + private var isUserRegisteredInSurveyShare: Bool? + + private let surveySettings: [String: Any]? + private let userDecider: InternalUserDecider + private let randomNumberGenerator: RandomNumberGenerating + + lazy var statisticsStore: StatisticsStore = LocalStatisticsStore() + + init(privacyConfigurationManager: PrivacyConfigurationManaging = AppPrivacyFeatures.shared.contentBlocking.privacyConfigurationManager, + randomNumberGenerator: RandomNumberGenerating = RandomNumberGenerator()) { + let newTabContinueSetUpSettings = privacyConfigurationManager.privacyConfig.settings(for: .newTabContinueSetUp) + self.surveySettings = newTabContinueSetUpSettings["permanentSurvey"] as? [String: Any] + self.userDecider = NSApp.delegateTyped.internalUserDecider + self.randomNumberGenerator = randomNumberGenerator + } + + public var isSurveyAvailable: Bool { + let firstSurveyDayDate = Calendar.current.date(byAdding: .weekday, value: -firstDay, to: Date())! + let lastSurveyDayDate = Calendar.current.date(byAdding: .weekday, value: -lastDay, to: Date())! + let rightLocale = isLocalized ? true : Bundle.main.preferredLocalizations.first == "en" + + return + isEnabled && + firstLaunchDate >= lastSurveyDayDate && + firstLaunchDate <= firstSurveyDayDate && + rightLocale && + isUserInSurveyShare(sharePercentage) + } + + public var url: URL? { + guard let urlString = surveySettings?["url"] as? String else { return nil } + guard let url = URL(string: urlString) else { return nil } + + var components = URLComponents(url: url, resolvingAgainstBaseURL: true) + var newQueryItems: [URLQueryItem] = [] + if let atb = self.statisticsStore.atb { + newQueryItems.append(URLQueryItem(name: "atb", value: atb)) + } + if let variant = statisticsStore.variant { + newQueryItems.append(URLQueryItem(name: "v", value: variant)) + } + newQueryItems.append(URLQueryItem(name: "ddg", value: AppVersion.shared.versionNumber)) + newQueryItems.append(URLQueryItem(name: "macos", value: AppVersion.shared.majorAndMinorOSVersion)) + let oldQueryItems = components?.queryItems ?? [] + components?.queryItems = oldQueryItems + newQueryItems + + return components?.url ?? url + } + + private func isUserInSurveyShare(_ share: Int) -> Bool { + if isUserRegisteredInSurveyShare ?? false { + return true + } + let randomNumber0To99 = randomNumberGenerator.random(in: 0..<100) + isUserRegisteredInSurveyShare = randomNumber0To99 < share + return isUserRegisteredInSurveyShare! + } + + private var isEnabled: Bool { + if let state = surveySettings?["state"] as? String { + if state == "enabled" { + return true + } + if state == "internal" && userDecider.isInternalUser { + return true + } + } + return false + } + + private var isLocalized: Bool { + if let state = surveySettings?["localization"] as? String { + if state == "enabled" { + return true + } + } + return false + } + + private var firstDay: Int { + return surveySettings?["firstDay"] as? Int ?? 0 + } + + private var lastDay: Int { + return surveySettings?["lastDay"] as? Int ?? 365 + } + + private var sharePercentage: Int { + return surveySettings?["sharePercentage"] as? Int ?? 0 + } +} + +public protocol RandomNumberGenerating { + func random(in range: Range) -> Int +} + +struct RandomNumberGenerator: RandomNumberGenerating { + func random(in range: Range) -> Int { + return Int.random(in: range) + } +} diff --git a/DuckDuckGo/HomePage/View/HomePageViewController.swift b/DuckDuckGo/HomePage/View/HomePageViewController.swift index 96fb2aca47..9769333182 100644 --- a/DuckDuckGo/HomePage/View/HomePageViewController.swift +++ b/DuckDuckGo/HomePage/View/HomePageViewController.swift @@ -20,6 +20,7 @@ import Cocoa import Combine import SwiftUI import History +import PixelKit @MainActor final class HomePageViewController: NSViewController { @@ -106,8 +107,8 @@ final class HomePageViewController: NSViewController { override func viewWillAppear() { super.viewWillAppear() - if OnboardingViewModel.isOnboardingFinished && Pixel.isNewUser { - Pixel.fire(.newTabInitial, limitTo: .initial) + if OnboardingViewModel.isOnboardingFinished && AppDelegate.isNewUser { + PixelKit.fire(GeneralPixel.newTabInitial, frequency: .legacyInitial) } subscribeToHistory() } @@ -158,7 +159,7 @@ final class HomePageViewController: NSViewController { func createDefaultBrowserModel() -> HomePage.Models.DefaultBrowserModel { return .init(isDefault: DefaultBrowserPreferences.shared.isDefault, wasClosed: defaultBrowserDismissed, requestSetDefault: { [weak self] in - Pixel.fire(.defaultRequestedFromHomepage) + PixelKit.fire(GeneralPixel.defaultRequestedFromHomepage) let defaultBrowserPreferencesModel = DefaultBrowserPreferences.shared defaultBrowserPreferencesModel.becomeDefault { [weak self] isDefault in _ = defaultBrowserPreferencesModel diff --git a/DuckDuckGo/Localizable.xcstrings b/DuckDuckGo/Localizable.xcstrings index 578c6d0b12..2b07fcd86f 100644 --- a/DuckDuckGo/Localizable.xcstrings +++ b/DuckDuckGo/Localizable.xcstrings @@ -480,6 +480,12 @@ } } } + }, + "1." : { + + }, + "2. Open the downloaded DMG file and drag the Bitwarden application to\nthe /Applications folder." : { + }, "about.app_name" : { "comment" : "Application name to be displayed in the About dialog", @@ -6253,6 +6259,42 @@ } } }, + "bitwarden.incompatible" : { + "comment" : "Message that warns user that specific Bitwarden app vesions are not compatible with this app", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "The following Bitwarden versions are incompatible with DuckDuckGo: v2024.3.0, v2024.3.2, v2024.4.0, v2024.4.1. Please revert to an older version by following these steps:" + } + } + } + }, + "bitwarden.incompatible.step.1" : { + "comment" : "First step to downgrade Bitwarden", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Download v2014.2.1" + } + } + } + }, + "bitwarden.incompatible.step.2" : { + "comment" : "Second step to downgrade Bitwarden", + "extractionState" : "extracted_with_value", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "2. Open the downloaded DMG file and drag the Bitwarden application to\nthe /Applications folder." + } + } + } + }, "bitwarden.install" : { "comment" : "Button to install Bitwarden app", "extractionState" : "extracted_with_value", @@ -7432,6 +7474,66 @@ } } }, + "bookmark.all.tabs" : { + "comment" : "Menu item for bookmarking all the open tabs", + "extractionState" : "extracted_with_value", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Alle Tabs mit Lesezeichen versehen…" + } + }, + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Bookmark All Tabs…" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Añadir todas las pestañas a marcadores…" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ajouter tous les onglets aux signets…" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Crea un segnalibro con tutte le schede…" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Alle tabbladen toevoegen als bladwijzer…" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dodaj wszystkie karty do zakładek…" + } + }, + "pt" : { + "stringUnit" : { + "state" : "translated", + "value" : "Marcar todos os separadores…" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Добавить все вкладки в закладки…" + } + } + } + }, "bookmark.dialog.add" : { "comment" : "Button to confim a bookmark creation", "extractionState" : "extracted_with_value", @@ -7559,55 +7661,55 @@ "de" : { "stringUnit" : { "state" : "translated", - "value" : "Diese Seite als Lesezeichen markieren" + "value" : "Diese Seite mit einem Lesezeichen versehen…" } }, "en" : { "stringUnit" : { "state" : "new", - "value" : "Bookmark This Page" + "value" : "Bookmark This Page…" } }, "es" : { "stringUnit" : { "state" : "translated", - "value" : "Marcar esta página" + "value" : "Marcar esta página…" } }, "fr" : { "stringUnit" : { "state" : "translated", - "value" : "Ajouter cette page aux signets" + "value" : "Ajouter cette page aux signets…" } }, "it" : { "stringUnit" : { "state" : "translated", - "value" : "Crea un segnalibro per questa pagina" + "value" : "Crea un segnalibro per questa pagina…" } }, "nl" : { "stringUnit" : { "state" : "translated", - "value" : "Bladwijzer toevoegen aan deze pagina" + "value" : "Bladwijzer toevoegen voor deze pagina…" } }, "pl" : { "stringUnit" : { "state" : "translated", - "value" : "Dodaj tę stronę do zakładek" + "value" : "Dodaj tę stronę do zakładek…" } }, "pt" : { "stringUnit" : { "state" : "translated", - "value" : "Marcar esta página" + "value" : "Marcar esta página…" } }, "ru" : { "stringUnit" : { "state" : "translated", - "value" : "Сохранить в закладках" + "value" : "Сохранить страницу в закладках…" } } } @@ -8618,6 +8720,66 @@ } } }, + "bookmarks.dialog.action.addAllBookmarks" : { + "comment" : "CTA title for saving multiple Bookmarks at once", + "extractionState" : "extracted_with_value", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Lesezeichen speichern" + } + }, + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Save Bookmarks" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Guardar marcadores" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enregistrer les signets" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Salva segnalibri" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bladwijzers opslaan" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Zapisz zakładki" + } + }, + "pt" : { + "stringUnit" : { + "state" : "translated", + "value" : "Guardar marcadores" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Сохранение закладок" + } + } + } + }, "bookmarks.dialog.action.addBookmark" : { "comment" : "CTA title for adding a Bookmark", "extractionState" : "extracted_with_value", @@ -8738,6 +8900,246 @@ } } }, + "bookmarks.dialog.allTabs.message.add" : { + "comment" : "Bookmark creation for all open tabs dialog title", + "extractionState" : "extracted_with_value", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Diese Lesezeichen werden in einem neuen Ordner gespeichert:" + } + }, + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "These bookmarks will be saved in a new folder:" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Estos marcadores se guardarán en una nueva carpeta:" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ces signets seront enregistrés dans un nouveau dossier:" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Questi segnalibri verranno salvati in una nuova cartella:" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Deze bladwijzers worden opgeslagen in een nieuwe map:" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Te zakładki zostaną zapisane w nowym folderze:" + } + }, + "pt" : { + "stringUnit" : { + "state" : "translated", + "value" : "Estes marcadores serão guardados numa nova pasta:" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Эти закладки будут сохранены в новой папке:" + } + } + } + }, + "bookmarks.dialog.allTabs.title.add" : { + "comment" : "Title of dialog to bookmark all open tabs. E.g. 'Bookmark Open Tabs (42)'", + "extractionState" : "extracted_with_value", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Offene Tabs mit Lesezeichen versehen (%d)" + } + }, + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Bookmark Open Tabs (%d)" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Añadir pestañas abiertas (%d)" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ajouter les onglets ouverts (%d) aux signets" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Aggiungere ai segnalibri le schede aperte (%d)" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "%d geopende tabbladen toevoegen als bladwijzer" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Dodaj otwarte karty (%d) do zakładek" + } + }, + "pt" : { + "stringUnit" : { + "state" : "translated", + "value" : "Marcar separadores abertos (%d)" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Добавить открытые вкладки (%d) в закладки" + } + } + } + }, + "bookmarks.dialog.field.folderName" : { + "comment" : "Folder name field label for Bookmarks folder", + "extractionState" : "extracted_with_value", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ordnername" + } + }, + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Folder Name" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nombre de la carpeta" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nom du dossier" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nome della cartella" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Naam van de map" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nazwa folderu" + } + }, + "pt" : { + "stringUnit" : { + "state" : "translated", + "value" : "Nome da pasta" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Название папки" + } + } + } + }, + "bookmarks.dialog.field.folderName.value" : { + "comment" : "The suggested name of the folder that will contain the bookmark tabs. Eg. 2024-02-12 - Tabs (42)", + "extractionState" : "extracted_with_value", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@ – Tabs (%2$d)" + } + }, + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "%1$@ - Tabs (%2$d)" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@ - Pestañas (%2$d)" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@ - Onglets (%2$d)" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@ - Schede (%2$d)" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@ - Tabbladen (%2$d)" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@ - Karty (%2$d)" + } + }, + "pt" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@ - Separadores (%2$d)" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "%1$@ - Вкладки (%2$d)" + } + } + } + }, "bookmarks.dialog.field.location" : { "comment" : "Location field label for Bookmark folder", "extractionState" : "extracted_with_value", @@ -13288,6 +13690,9 @@ } } } + }, + "Download v2014.2.1" : { + }, "download.finishing" : { "comment" : "Download being finished information text", @@ -20015,6 +20420,7 @@ }, "Hide" : { "comment" : "Main Menu > View > Home Button > None item\n Preferences > Home Button > None item", + "extractionState" : "extracted_with_value", "localizations" : { "de" : { "stringUnit" : { @@ -30323,7 +30729,7 @@ }, "newTab.setup.survey.day.0.action" : { "comment" : "Action title of the Day 0 survey of the Set Up section in the home page", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "de" : { "stringUnit" : { @@ -30383,7 +30789,7 @@ }, "newTab.setup.survey.day.0.summary" : { "comment" : "Summary of the card on the new tab page that invites users to partecipate to a survey", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "de" : { "stringUnit" : { @@ -30443,7 +30849,7 @@ }, "newTab.setup.survey.day.0.title" : { "comment" : "Title of the Day 0 durvey of the Set Up section in the home page", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "de" : { "stringUnit" : { @@ -30683,7 +31089,7 @@ }, "newTab.setup.survey.day.14.action" : { "comment" : "Action title of the Day 14 survey of the Set Up section in the home page", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "de" : { "stringUnit" : { @@ -30743,7 +31149,7 @@ }, "newTab.setup.survey.day.14.summary" : { "comment" : "Summary of the card on the new tab page that invites users to partecipate to a survey", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "de" : { "stringUnit" : { @@ -30803,7 +31209,7 @@ }, "newTab.setup.survey.day.14.title" : { "comment" : "Title of the Day 14 durvey of the Set Up section in the home page", - "extractionState" : "extracted_with_value", + "extractionState" : "stale", "localizations" : { "de" : { "stringUnit" : { @@ -45698,6 +46104,9 @@ } } } + }, + "Privacy Pro" : { + }, "private.search.explenation" : { "comment" : "feature explanation in settings", @@ -47964,6 +48373,7 @@ }, "Show left of the back button" : { "comment" : "Preferences > Home Button > left position item", + "extractionState" : "extracted_with_value", "localizations" : { "de" : { "stringUnit" : { @@ -48017,6 +48427,7 @@ }, "Show Left of the Back Button" : { "comment" : "Main Menu > View > Home Button > left position item", + "extractionState" : "extracted_with_value", "localizations" : { "de" : { "stringUnit" : { @@ -48282,6 +48693,7 @@ }, "Show right of the reload button" : { "comment" : "Preferences > Home Button > right position item", + "extractionState" : "extracted_with_value", "localizations" : { "de" : { "stringUnit" : { @@ -48335,6 +48747,7 @@ }, "Show Right of the Reload Button" : { "comment" : "Main Menu > View > Home Button > right position item", + "extractionState" : "extracted_with_value", "localizations" : { "de" : { "stringUnit" : { @@ -49823,6 +50236,66 @@ } } }, + "tab.empty.title" : { + "comment" : "Title for an empty tab without a title", + "extractionState" : "extracted_with_value", + "localizations" : { + "de" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ohne Titel" + } + }, + "en" : { + "stringUnit" : { + "state" : "new", + "value" : "Untitled" + } + }, + "es" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sin título" + } + }, + "fr" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sans titre" + } + }, + "it" : { + "stringUnit" : { + "state" : "translated", + "value" : "Ohne Titel" + } + }, + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Naamloos" + } + }, + "pl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bez tytułu" + } + }, + "pt" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sem título" + } + }, + "ru" : { + "stringUnit" : { + "state" : "translated", + "value" : "Без названия" + } + } + } + }, "tab.error.title" : { "comment" : "Tab error title", "extractionState" : "extracted_with_value", diff --git a/DuckDuckGo/LoginItems/LoginItemsManager.swift b/DuckDuckGo/LoginItems/LoginItemsManager.swift index e0a44a4fb4..076c75f2b8 100644 --- a/DuckDuckGo/LoginItems/LoginItemsManager.swift +++ b/DuckDuckGo/LoginItems/LoginItemsManager.swift @@ -19,10 +19,15 @@ import Common import Foundation import LoginItems +import PixelKit + +protocol LoginItemsManaging { + func throwingEnableLoginItems(_ items: Set, log: OSLog) throws +} /// Class to manage the login items for the VPN and DBP /// -final class LoginItemsManager { +final class LoginItemsManager: LoginItemsManaging { private enum Action: String { case enable case disable @@ -42,6 +47,20 @@ final class LoginItemsManager { } } + /// Throwing version of enableLoginItems + /// + func throwingEnableLoginItems(_ items: Set, log: OSLog) throws { + for item in items { + do { + try item.enable() + os_log("🟢 Enabled successfully %{public}@", log: log, String(describing: item)) + } catch let error as NSError { + handleError(for: item, action: .enable, error: error) + throw error + } + } + } + func restartLoginItems(_ items: Set, log: OSLog) { for item in items { do { @@ -66,17 +85,12 @@ final class LoginItemsManager { } private func handleError(for item: LoginItem, action: Action, error: NSError) { - let event = Pixel.Event.Debug.loginItemUpdateError( - loginItemBundleID: item.agentBundleID, - action: "enable", - buildType: AppVersion.shared.buildType, - osVersion: AppVersion.shared.osVersion - ) - DailyPixel.fire(pixel: .debug(event: event, error: error), frequency: .dailyAndCount) - - os_log("🔴 Could not enable %{public}@: %{public}@", - item.debugDescription, - error.debugDescription) + let event = GeneralPixel.loginItemUpdateError(loginItemBundleID: item.agentBundleID, + action: "enable", + buildType: AppVersion.shared.buildType, + osVersion: AppVersion.shared.osVersion) + PixelKit.fire(DebugEvent(event, error: error), frequency: .dailyAndCount) + os_log("🔴 Could not enable %{public}@: %{public}@", item.debugDescription, error.debugDescription) } // MARK: - Debug Interactions diff --git a/DuckDuckGo/MainWindow/MainViewController.swift b/DuckDuckGo/MainWindow/MainViewController.swift index 04b5810087..118116eaad 100644 --- a/DuckDuckGo/MainWindow/MainViewController.swift +++ b/DuckDuckGo/MainWindow/MainViewController.swift @@ -93,7 +93,8 @@ final class MainViewController: NSViewController { serverInfoObserver: ipcClient.ipcServerInfoObserver, connectionErrorObserver: ipcClient.ipcConnectionErrorObserver, connectivityIssuesObserver: connectivityIssuesObserver, - controllerErrorMessageObserver: controllerErrorMessageObserver + controllerErrorMessageObserver: controllerErrorMessageObserver, + dataVolumeObserver: ipcClient.ipcDataVolumeObserver ) }() @@ -188,7 +189,6 @@ final class MainViewController: NSViewController { updateReloadMenuItem() updateStopMenuItem() browserTabViewController.windowDidBecomeKey() - presentWaitlistThankYouPromptIfNecessary() refreshNetworkProtectionMessages() @@ -303,13 +303,20 @@ final class MainViewController: NSViewController { } private func subscribeToTitleChange(of selectedTabViewModel: TabViewModel?) { - guard let window = self.view.window else { return } - selectedTabViewModel?.$title + guard let selectedTabViewModel else { return } + + // Only subscribe once the view is added to the window. + let windowPublisher = view.publisher(for: \.window).filter({ $0 != nil }).prefix(1).asVoid() + + windowPublisher + .combineLatest(selectedTabViewModel.$title) { $1 } .map { $0.truncated(length: MainMenu.Constants.maxTitleLength) } .receive(on: DispatchQueue.main) - .assign(to: \.title, onWeaklyHeld: window) + .sink { [weak self] title in + self?.view.window?.title = title + } .store(in: &tabViewModelCancellables) } @@ -430,16 +437,6 @@ final class MainViewController: NSViewController { NSApp.mainMenuTyped.stopMenuItem.isEnabled = selectedTabViewModel.isLoading } - func presentWaitlistThankYouPromptIfNecessary() { - guard let window = self.view.window else { - assertionFailure("Couldn't get main view controller's window") - return - } - - let presenter = WaitlistThankYouPromptPresenter() - presenter.presentThankYouPromptIfNecessary(in: window) - } - // MARK: - First responder func adjustFirstResponder(selectedTabViewModel: TabViewModel? = nil, tabContent: Tab.TabContent? = nil, force: Bool = false) { diff --git a/DuckDuckGo/Menus/MainMenu.swift b/DuckDuckGo/Menus/MainMenu.swift index 44c8b76408..66e026dc1d 100644 --- a/DuckDuckGo/Menus/MainMenu.swift +++ b/DuckDuckGo/Menus/MainMenu.swift @@ -25,11 +25,8 @@ import SwiftUI import WebKit import Configuration import NetworkProtection - -#if SUBSCRIPTION import Subscription import SubscriptionUI -#endif // swiftlint:disable:next type_body_length @MainActor final class MainMenu: NSMenu { @@ -294,6 +291,7 @@ import SubscriptionUI func buildBookmarksMenu() -> NSMenuItem { NSMenuItem(title: UserText.bookmarks).submenu(bookmarksMenu.buildItems { NSMenuItem(title: UserText.bookmarkThisPage, action: #selector(MainViewController.bookmarkThisPage), keyEquivalent: "d") + NSMenuItem(title: UserText.bookmarkAllTabs, action: #selector(MainViewController.bookmarkAllOpenTabs), keyEquivalent: [.command, .shift, "d"]) manageBookmarksMenuItem bookmarksMenuToggleBookmarksBarMenuItem NSMenuItem.separator() @@ -322,6 +320,7 @@ import SubscriptionUI NSMenuItem(title: UserText.zoom, action: #selector(NSWindow.performZoom)) NSMenuItem.separator() + NSMenuItem(title: UserText.duplicateTab, action: #selector(MainViewController.duplicateTab)) NSMenuItem(title: UserText.pinTab, action: #selector(MainViewController.pinOrUnpinTab)) NSMenuItem(title: UserText.moveTabToNewWindow, action: #selector(MainViewController.moveTabToNewWindow)) NSMenuItem(title: UserText.mainMenuWindowMergeAllWindows, action: #selector(NSWindow.mergeAllWindows)) @@ -559,6 +558,14 @@ import SubscriptionUI let debugMenu = NSMenu(title: "Debug") { NSMenuItem(title: "Open Vanilla Browser", action: #selector(MainViewController.openVanillaBrowser)).withAccessibilityIdentifier("MainMenu.openVanillaBrowser") NSMenuItem.separator() + NSMenuItem(title: "Tab") { + NSMenuItem(title: "Append Tabs") { + NSMenuItem(title: "10 Tabs", action: #selector(MainViewController.addDebugTabs(_:)), representedObject: 10) + NSMenuItem(title: "50 Tabs", action: #selector(MainViewController.addDebugTabs(_:)), representedObject: 50) + NSMenuItem(title: "100 Tabs", action: #selector(MainViewController.addDebugTabs(_:)), representedObject: 100) + NSMenuItem(title: "150 Tabs", action: #selector(MainViewController.addDebugTabs(_:)), representedObject: 150) + } + } NSMenuItem(title: "Reset Data") { NSMenuItem(title: "Reset Default Browser Prompt", action: #selector(MainViewController.resetDefaultBrowserPrompt)) NSMenuItem(title: "Reset Default Grammar Checks", action: #selector(MainViewController.resetDefaultGrammarChecks)) @@ -567,17 +574,16 @@ import SubscriptionUI NSMenuItem(title: "Reset Pinned Tabs", action: #selector(MainViewController.resetPinnedTabs)) NSMenuItem(title: "Reset YouTube Overlay Interactions", action: #selector(MainViewController.resetDuckPlayerOverlayInteractions)) NSMenuItem(title: "Reset MakeDuckDuckYours user settings", action: #selector(MainViewController.resetMakeDuckDuckGoYoursUserSettings)) - NSMenuItem(title: "Survey 10% on", action: #selector(MainViewController.in10PercentSurveyOn)) - NSMenuItem(title: "Survey 10% off", action: #selector(MainViewController.in10PercentSurveyOff)) + NSMenuItem(title: "Permanent Survey share on", action: #selector(MainViewController.inPermanentSurveyShareOn(_:))) + NSMenuItem(title: "Permanent Survey share off", action: #selector(MainViewController.inPermanentSurveyShareOff(_:))) NSMenuItem(title: "Change Activation Date") { NSMenuItem(title: "Today", action: #selector(MainViewController.changeInstallDateToToday), keyEquivalent: "N") - NSMenuItem(title: "Less Than a 1 days Ago", action: #selector(MainViewController.changeInstallDateToLessThan1DayAgo(_:))) - NSMenuItem(title: "More Than 1 Days Ago", action: #selector(MainViewController.changeInstallDateToMoreThan1DayAgoButLessThan14(_:))) - NSMenuItem(title: "More Than 14 Days Ago", action: #selector(MainViewController.changeInstallDateToMoreThan14DaysAgoButLessThan15(_:))) - NSMenuItem(title: "More Than 15 Days Ago", action: #selector(MainViewController.changeInstallDateToMoreThan15DaysAgo(_:))) + NSMenuItem(title: "Less Than a 5 days Ago", action: #selector(MainViewController.changeInstallDateToLessThan5DayAgo(_:))) + NSMenuItem(title: "More Than 5 Days Ago", action: #selector(MainViewController.changeInstallDateToMoreThan5DayAgoButLessThan9(_:))) + NSMenuItem(title: "More Than 9 Days Ago", action: #selector(MainViewController.changeInstallDateToMoreThan9DaysAgo(_:))) } NSMenuItem(title: "Reset Email Protection InContext Signup Prompt", action: #selector(MainViewController.resetEmailProtectionInContextPrompt)) - NSMenuItem(title: "Reset Daily Pixels", action: #selector(MainViewController.resetDailyPixels)) + NSMenuItem(title: "Reset Pixels Storage", action: #selector(MainViewController.resetDailyPixels)) }.withAccessibilityIdentifier("MainMenu.resetData") NSMenuItem(title: "UI Triggers") { NSMenuItem(title: "Show Save Credentials Popover", action: #selector(MainViewController.showSaveCredentialsPopover)) @@ -613,7 +619,6 @@ import SubscriptionUI NSMenuItem(title: "Trigger Fatal Error", action: #selector(MainViewController.triggerFatalError)) -#if SUBSCRIPTION let currentEnvironmentWrapper = UserDefaultsWrapper(key: .subscriptionEnvironment, defaultValue: SubscriptionPurchaseEnvironment.ServiceEnvironment.default) let isInternalTestingWrapper = UserDefaultsWrapper(key: .subscriptionInternalTesting, defaultValue: false) @@ -632,7 +637,6 @@ import SubscriptionUI }, subscriptionAppGroup: Bundle.main.appGroup(bundle: .subs) ) -#endif NSMenuItem(title: "Logging").submenu(setupLoggingMenu()) } diff --git a/DuckDuckGo/Menus/MainMenuActions.swift b/DuckDuckGo/Menus/MainMenuActions.swift index 4f2befbe8b..ec129e39df 100644 --- a/DuckDuckGo/Menus/MainMenuActions.swift +++ b/DuckDuckGo/Menus/MainMenuActions.swift @@ -215,7 +215,7 @@ extension AppDelegate { savePanel.beginSheetModal(for: window) { response in guard response == .OK, let selectedURL = savePanel.url else { return } - let vault = try? AutofillSecureVaultFactory.makeVault(errorReporter: SecureVaultErrorReporter.shared) + let vault = try? AutofillSecureVaultFactory.makeVault(reporter: SecureVaultReporter.shared) let exporter = CSVLoginExporter(secureVault: vault!) do { try exporter.exportVaultLogins(to: selectedURL) @@ -507,6 +507,11 @@ extension MainViewController { .openBookmarkPopover(setFavorite: false, accessPoint: .init(sender: sender, default: .moreMenu)) } + @objc func bookmarkAllOpenTabs(_ sender: Any) { + let websitesInfo = tabCollectionViewModel.tabs.compactMap(WebsiteInfo.init) + BookmarksDialogViewFactory.makeBookmarkAllOpenTabsView(websitesInfo: websitesInfo).show() + } + @objc func favoriteThisPage(_ sender: Any) { guard let tabIndex = getActiveTabAndIndex()?.index else { return } if tabCollectionViewModel.selectedTabIndex != tabIndex { @@ -601,6 +606,12 @@ extension MainViewController { WindowsManager.openNewWindow(with: tab) } + @objc func duplicateTab(_ sender: Any?) { + guard let (_, index) = getActiveTabAndIndex() else { return } + + tabCollectionViewModel.duplicateTab(at: index) + } + @objc func pinOrUnpinTab(_ sender: Any?) { guard let (_, selectedTabIndex) = getActiveTabAndIndex() else { return } @@ -650,6 +661,14 @@ extension MainViewController { // MARK: - Debug + @objc func addDebugTabs(_ sender: AnyObject) { + let numberOfTabs = sender.representedObject as? Int ?? 1 + (1...numberOfTabs).forEach { _ in + let tab = Tab(content: .url(.duckDuckGo, credential: nil, source: .ui)) + tabCollectionViewModel.append(tab: tab) + } + } + @objc func resetDefaultBrowserPrompt(_ sender: Any?) { UserDefaultsWrapper.clear(.defaultBrowserDismissed) } @@ -664,7 +683,7 @@ extension MainViewController { } @objc func resetSecureVaultData(_ sender: Any?) { - let vault = try? AutofillSecureVaultFactory.makeVault(errorReporter: SecureVaultErrorReporter.shared) + let vault = try? AutofillSecureVaultFactory.makeVault(reporter: SecureVaultReporter.shared) let accounts = (try? vault?.accounts()) ?? [] for accountID in accounts.compactMap(\.id) { @@ -713,9 +732,7 @@ extension MainViewController { UserDefaults.standard.set(true, forKey: UserDefaultsWrapper.Key.homePageShowImport.rawValue) UserDefaults.standard.set(true, forKey: UserDefaultsWrapper.Key.homePageShowDuckPlayer.rawValue) UserDefaults.standard.set(true, forKey: UserDefaultsWrapper.Key.homePageShowEmailProtection.rawValue) - UserDefaults.standard.set(true, forKey: UserDefaultsWrapper.Key.homePageShowSurveyDay0.rawValue) - UserDefaults.standard.set(true, forKey: UserDefaultsWrapper.Key.homePageShowSurveyDay14.rawValue) - UserDefaults.standard.set(false, forKey: UserDefaultsWrapper.Key.homePageUserInteractedWithSurveyDay0.rawValue) + UserDefaults.standard.set(true, forKey: UserDefaultsWrapper.Key.homePageShowPermanentSurvey.rawValue) } @objc func internalUserState(_ sender: Any?) { @@ -740,47 +757,40 @@ extension MainViewController { UserDefaults.netP.networkProtectionEntitlementsExpired = false // Clear pixel data - DailyPixel.clearLastFireDate(pixel: .privacyProFeatureEnabled) - Pixel.shared?.clearRepetitions(for: .privacyProBetaUserThankYouDBP) - Pixel.shared?.clearRepetitions(for: .privacyProBetaUserThankYouVPN) + PixelKit.shared?.clearFrequencyHistoryFor(pixel: PrivacyProPixel.privacyProFeatureEnabled) + PixelKit.shared?.clearFrequencyHistoryFor(pixel: PrivacyProPixel.privacyProBetaUserThankYouDBP) + PixelKit.shared?.clearFrequencyHistoryFor(pixel: PrivacyProPixel.privacyProBetaUserThankYouVPN) } @objc func resetDailyPixels(_ sender: Any?) { - UserDefaults.standard.removePersistentDomain(forName: DailyPixel.Constant.dailyPixelStorageIdentifier) + PixelKit.shared?.clearFrequencyHistoryForAllPixels() } - @objc func in10PercentSurveyOn(_ sender: Any?) { - UserDefaults.standard.set(true, forKey: UserDefaultsWrapper.Key.homePageShowSurveyDay14in10Percent.rawValue) - UserDefaults.standard.set(true, forKey: UserDefaultsWrapper.Key.homePageShowSurveyDay0in10Percent.rawValue) + @objc func inPermanentSurveyShareOn(_ sender: Any?) { + UserDefaults.standard.set(true, forKey: UserDefaultsWrapper.Key.homePageUserInSurveyShare.rawValue) } - @objc func in10PercentSurveyOff(_ sender: Any?) { - UserDefaults.standard.set(false, forKey: UserDefaultsWrapper.Key.homePageShowSurveyDay14in10Percent.rawValue) - UserDefaults.standard.set(false, forKey: UserDefaultsWrapper.Key.homePageShowSurveyDay0in10Percent.rawValue) + @objc func inPermanentSurveyShareOff(_ sender: Any?) { + UserDefaults.standard.set(false, forKey: UserDefaultsWrapper.Key.homePageUserInSurveyShare.rawValue) } @objc func changeInstallDateToToday(_ sender: Any?) { UserDefaults.standard.set(Date(), forKey: UserDefaultsWrapper.Key.firstLaunchDate.rawValue) } - @objc func changeInstallDateToLessThan1DayAgo(_ sender: Any?) { - let lessThanOneDaysAgo = Calendar.current.date(byAdding: .hour, value: -23, to: Date()) - UserDefaults.standard.set(lessThanOneDaysAgo, forKey: UserDefaultsWrapper.Key.firstLaunchDate.rawValue) - } - - @objc func changeInstallDateToMoreThan1DayAgoButLessThan14(_ sender: Any?) { - let between1And4DaysAgo = Calendar.current.date(byAdding: .day, value: -13, to: Date()) - UserDefaults.standard.set(between1And4DaysAgo, forKey: UserDefaultsWrapper.Key.firstLaunchDate.rawValue) + @objc func changeInstallDateToLessThan5DayAgo(_ sender: Any?) { + let lessThanFiveDaysAgo = Calendar.current.date(byAdding: .day, value: -4, to: Date()) + UserDefaults.standard.set(lessThanFiveDaysAgo, forKey: UserDefaultsWrapper.Key.firstLaunchDate.rawValue) } - @objc func changeInstallDateToMoreThan14DaysAgoButLessThan15(_ sender: Any?) { - let twentyEightDaysAgo = Calendar.current.date(byAdding: .day, value: -14, to: Date()) - UserDefaults.standard.set(twentyEightDaysAgo, forKey: UserDefaultsWrapper.Key.firstLaunchDate.rawValue) + @objc func changeInstallDateToMoreThan5DayAgoButLessThan9(_ sender: Any?) { + let between5And9DaysAgo = Calendar.current.date(byAdding: .day, value: -5, to: Date()) + UserDefaults.standard.set(between5And9DaysAgo, forKey: UserDefaultsWrapper.Key.firstLaunchDate.rawValue) } - @objc func changeInstallDateToMoreThan15DaysAgo(_ sender: Any?) { - let twentyEightDaysAgo = Calendar.current.date(byAdding: .day, value: -16, to: Date()) - UserDefaults.standard.set(twentyEightDaysAgo, forKey: UserDefaultsWrapper.Key.firstLaunchDate.rawValue) + @objc func changeInstallDateToMoreThan9DaysAgo(_ sender: Any?) { + let nineDaysAgo = Calendar.current.date(byAdding: .day, value: -9, to: Date()) + UserDefaults.standard.set(nineDaysAgo, forKey: UserDefaultsWrapper.Key.firstLaunchDate.rawValue) } @objc func showSaveCredentialsPopover(_ sender: Any?) { @@ -947,6 +957,8 @@ extension MainViewController: NSMenuItemValidation { case #selector(MainViewController.bookmarkThisPage(_:)), #selector(MainViewController.favoriteThisPage(_:)): return activeTabViewModel?.canBeBookmarked == true + case #selector(MainViewController.bookmarkAllOpenTabs(_:)): + return tabCollectionViewModel.canBookmarkAllOpenTabs() case #selector(MainViewController.openBookmark(_:)), #selector(MainViewController.showManageBookmarks(_:)): return true @@ -1045,7 +1057,7 @@ extension AppDelegate: NSMenuItemValidation { } private var areTherePasswords: Bool { - let vault = try? AutofillSecureVaultFactory.makeVault(errorReporter: SecureVaultErrorReporter.shared) + let vault = try? AutofillSecureVaultFactory.makeVault(reporter: SecureVaultReporter.shared) guard let vault else { return false } diff --git a/DuckDuckGo/NavigationBar/View/AddressBarButtonsViewController.swift b/DuckDuckGo/NavigationBar/View/AddressBarButtonsViewController.swift index e17e162d79..566a7c413f 100644 --- a/DuckDuckGo/NavigationBar/View/AddressBarButtonsViewController.swift +++ b/DuckDuckGo/NavigationBar/View/AddressBarButtonsViewController.swift @@ -49,6 +49,7 @@ final class AddressBarButtonsViewController: NSViewController { return permissionAuthorizationPopover ?? { let popover = PermissionAuthorizationPopover() self.permissionAuthorizationPopover = popover + popover.setAccessibilityIdentifier("AddressBarButtonsViewController.permissionAuthorizationPopover") return popover }() } @@ -289,7 +290,7 @@ final class AddressBarButtonsViewController: NSViewController { bookmarkButton.isHidden = !showBookmarkButton } - func openBookmarkPopover(setFavorite: Bool, accessPoint: Pixel.Event.AccessPoint) { + func openBookmarkPopover(setFavorite: Bool, accessPoint: GeneralPixel.AccessPoint) { let result = bookmarkForCurrentUrl(setFavorite: setFavorite, accessPoint: accessPoint) guard let bookmark = result.bookmark else { assertionFailure("Failed to get a bookmark for the popover") @@ -919,7 +920,7 @@ final class AddressBarButtonsViewController: NSViewController { } } - private func bookmarkForCurrentUrl(setFavorite: Bool, accessPoint: Pixel.Event.AccessPoint) -> (bookmark: Bookmark?, isNew: Bool) { + private func bookmarkForCurrentUrl(setFavorite: Bool, accessPoint: GeneralPixel.AccessPoint) -> (bookmark: Bookmark?, isNew: Bool) { guard let tabViewModel, let url = tabViewModel.tab.content.url else { assertionFailure("No URL for bookmarking") diff --git a/DuckDuckGo/NavigationBar/View/AddressBarTextField.swift b/DuckDuckGo/NavigationBar/View/AddressBarTextField.swift index b68ce5a6ee..21bb3b0bfa 100644 --- a/DuckDuckGo/NavigationBar/View/AddressBarTextField.swift +++ b/DuckDuckGo/NavigationBar/View/AddressBarTextField.swift @@ -349,7 +349,6 @@ final class AddressBarTextField: NSTextField { } #endif -#if SUBSCRIPTION if DefaultSubscriptionFeatureAvailability().isFeatureAvailable { if providedUrl.isChild(of: URL.subscriptionBaseURL) || providedUrl.isChild(of: URL.identityTheftRestoration) { self.updateValue(selectedTabViewModel: nil, addressBarString: nil) // reset @@ -357,7 +356,6 @@ final class AddressBarTextField: NSTextField { return } } -#endif self.window?.makeFirstResponder(nil) selectedTabViewModel.tab.setUrl(providedUrl, source: .userEntered(userEnteredValue, downloadRequested: downloadRequested)) diff --git a/DuckDuckGo/NavigationBar/View/AddressBarViewController.swift b/DuckDuckGo/NavigationBar/View/AddressBarViewController.swift index 04cd4cb362..43ff508e66 100644 --- a/DuckDuckGo/NavigationBar/View/AddressBarViewController.swift +++ b/DuckDuckGo/NavigationBar/View/AddressBarViewController.swift @@ -168,12 +168,7 @@ final class AddressBarViewController: NSViewController { return true } - // If the webview doesn't have content it doesn't handle becoming the first responder properly - if tabViewModel?.tab.webView.url != nil { - tabViewModel?.tab.webView.makeMeFirstResponder() - } else { - view.superview?.becomeFirstResponder() - } + view.window?.makeFirstResponder(nil) return true } @@ -496,12 +491,16 @@ extension AddressBarViewController { return event } + private static let maxClickReleaseDistanceToResignFirstResponder: CGFloat = 4 + func mouseUp(with event: NSEvent) -> NSEvent? { // click (same position down+up) outside of the field: resign first responder guard event.window === self.view.window, self.view.window?.firstResponder === addressBarTextField.currentEditor(), - self.clickPoint == event.locationInWindow - else { return event } + let clickPoint, + clickPoint.distance(to: event.locationInWindow) <= Self.maxClickReleaseDistanceToResignFirstResponder else { + return event + } self.view.window?.makeFirstResponder(nil) diff --git a/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift b/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift index e784fccf14..ed7bb58e86 100644 --- a/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift +++ b/DuckDuckGo/NavigationBar/View/MoreOptionsMenu.swift @@ -20,15 +20,15 @@ import Cocoa import Combine import Common import BrowserServicesKit -import NetworkProtection +import PixelKit -#if SUBSCRIPTION +import NetworkProtection import Subscription -#endif protocol OptionsButtonMenuDelegate: AnyObject { func optionsButtonMenuRequestedBookmarkThisPage(_ sender: NSMenuItem) + func optionsButtonMenuRequestedBookmarkAllOpenTabs(_ sender: NSMenuItem) func optionsButtonMenuRequestedBookmarkPopover(_ menu: NSMenu) func optionsButtonMenuRequestedBookmarkManagementInterface(_ menu: NSMenu) func optionsButtonMenuRequestedBookmarkImportInterface(_ menu: NSMenu) @@ -43,10 +43,8 @@ protocol OptionsButtonMenuDelegate: AnyObject { #if DBP func optionsButtonMenuRequestedDataBrokerProtection(_ menu: NSMenu) #endif -#if SUBSCRIPTION func optionsButtonMenuRequestedSubscriptionPurchasePage(_ menu: NSMenu) func optionsButtonMenuRequestedIdentityTheftRestoration(_ menu: NSMenu) -#endif } @MainActor @@ -174,6 +172,10 @@ final class MoreOptionsMenu: NSMenu { actionDelegate?.optionsButtonMenuRequestedBookmarkThisPage(sender) } + @objc func bookmarkAllOpenTabs(_ sender: NSMenuItem) { + actionDelegate?.optionsButtonMenuRequestedBookmarkAllOpenTabs(sender) + } + @objc func openBookmarks(_ sender: NSMenuItem) { actionDelegate?.optionsButtonMenuRequestedBookmarkPopover(self) } @@ -222,7 +224,6 @@ final class MoreOptionsMenu: NSMenu { actionDelegate?.optionsButtonMenuRequestedAppearancePreferences(self) } -#if SUBSCRIPTION @objc func openSubscriptionPurchasePage(_ sender: NSMenuItem) { actionDelegate?.optionsButtonMenuRequestedSubscriptionPurchasePage(self) } @@ -230,7 +231,6 @@ final class MoreOptionsMenu: NSMenu { @objc func openIdentityTheftRestoration(_ sender: NSMenuItem) { actionDelegate?.optionsButtonMenuRequestedIdentityTheftRestoration(self) } -#endif @objc func findInPage(_ sender: NSMenuItem) { tabCollectionViewModel.selectedTabViewModel?.showFindInPage() @@ -289,15 +289,11 @@ final class MoreOptionsMenu: NSMenu { private func addSubscriptionItems() { var items: [NSMenuItem] = [] -#if SUBSCRIPTION if DefaultSubscriptionFeatureAvailability().isFeatureAvailable && !accountManager.isUserAuthenticated { items.append(contentsOf: makeInactiveSubscriptionItems()) } else { items.append(contentsOf: makeActiveSubscriptionItems()) // this adds NETP and DBP only if conditionally enabled } -#else - items.append(contentsOf: makeActiveSubscriptionItems()) // this adds NETP and DBP only if conditionally enabled -#endif if !items.isEmpty { items.forEach { addItem($0) } @@ -309,9 +305,7 @@ final class MoreOptionsMenu: NSMenu { private func makeActiveSubscriptionItems() -> [NSMenuItem] { var items: [NSMenuItem] = [] -#if SUBSCRIPTION let subscriptionFeatureAvailability = DefaultSubscriptionFeatureAvailability() -#endif if networkProtectionFeatureVisibility.isNetworkProtectionBetaVisible() { let networkProtectionItem: NSMenuItem @@ -319,7 +313,7 @@ final class MoreOptionsMenu: NSMenu { networkProtectionItem = makeNetworkProtectionItem() items.append(networkProtectionItem) -#if SUBSCRIPTION + if subscriptionFeatureAvailability.isFeatureAvailable && accountManager.isUserAuthenticated { Task { let isMenuItemEnabled: Bool @@ -334,7 +328,6 @@ final class MoreOptionsMenu: NSMenu { networkProtectionItem.isEnabled = isMenuItemEnabled } } -#endif } else { networkProtectionFeatureVisibility.disableForWaitlistUsers() } @@ -349,8 +342,7 @@ final class MoreOptionsMenu: NSMenu { .withImage(.dbpIcon) items.append(dataBrokerProtectionItem) -#if SUBSCRIPTION - if subscriptionFeatureAvailability.isFeatureAvailable && accountManager.isUserAuthenticated { + if subscriptionFeatureAvailability.isFeatureAvailable && accountManager.isUserAuthenticated { Task { let isMenuItemEnabled: Bool @@ -364,16 +356,14 @@ final class MoreOptionsMenu: NSMenu { dataBrokerProtectionItem.isEnabled = isMenuItemEnabled } } -#endif - DataBrokerProtectionExternalWaitlistPixels.fire(pixel: .dataBrokerProtectionWaitlistEntryPointMenuItemDisplayed, frequency: .dailyAndCount) + DataBrokerProtectionExternalWaitlistPixels.fire(pixel: GeneralPixel.dataBrokerProtectionWaitlistEntryPointMenuItemDisplayed, frequency: .dailyAndCount) } else { DefaultDataBrokerProtectionFeatureVisibility().disableAndDeleteForWaitlistUsers() } #endif // DBP -#if SUBSCRIPTION if accountManager.isUserAuthenticated { let identityTheftRestorationItem = NSMenuItem(title: UserText.identityTheftRestorationOptionsMenuItem, action: #selector(openIdentityTheftRestoration), @@ -382,7 +372,7 @@ final class MoreOptionsMenu: NSMenu { .withImage(.itrIcon) items.append(identityTheftRestorationItem) - if subscriptionFeatureAvailability.isFeatureAvailable && accountManager.isUserAuthenticated { + if subscriptionFeatureAvailability.isFeatureAvailable && accountManager.isUserAuthenticated { Task { let isMenuItemEnabled: Bool @@ -397,12 +387,10 @@ final class MoreOptionsMenu: NSMenu { } } } -#endif return items } -#if SUBSCRIPTION private func makeInactiveSubscriptionItems() -> [NSMenuItem] { let shouldHidePrivacyProDueToNoProducts = SubscriptionPurchaseEnvironment.current == .appStore && SubscriptionPurchaseEnvironment.canPurchase == false if shouldHidePrivacyProDueToNoProducts { @@ -417,7 +405,6 @@ final class MoreOptionsMenu: NSMenu { return [privacyProItem] } -#endif private func addPageItems() { guard let url = tabCollectionViewModel.selectedTabViewModel?.tab.content.url else { return } @@ -536,7 +523,7 @@ final class EmailOptionsButtonSubMenu: NSMenu { let pixelParameters = self.emailManager.emailPixelParameters self.emailManager.updateLastUseDate() - Pixel.fire(.emailUserCreatedAlias, withAdditionalParameters: pixelParameters) + PixelKit.fire(GeneralPixel.emailUserCreatedAlias, withAdditionalParameters: pixelParameters) NSPasteboard.general.copy(address) NotificationCenter.default.post(name: NSNotification.Name.privateEmailCopiedToClipboard, object: nil) @@ -645,6 +632,12 @@ final class BookmarksSubMenu: NSMenu { bookmarkPageItem.isEnabled = tabCollectionViewModel.selectedTabViewModel?.canBeBookmarked == true + let bookmarkAllTabsItem = addItem(withTitle: UserText.bookmarkAllTabs, action: #selector(MoreOptionsMenu.bookmarkAllOpenTabs(_:)), keyEquivalent: "d") + .withModifierMask([.command, .shift]) + .targetting(target) + + bookmarkAllTabsItem.isEnabled = tabCollectionViewModel.canBookmarkAllOpenTabs() + addItem(NSMenuItem.separator()) addItem(withTitle: UserText.bookmarksShowToolbarPanel, action: #selector(MoreOptionsMenu.openBookmarks(_:)), keyEquivalent: "") diff --git a/DuckDuckGo/NavigationBar/View/NavigationBar.storyboard b/DuckDuckGo/NavigationBar/View/NavigationBar.storyboard index 357dbe0d25..a656539f29 100644 --- a/DuckDuckGo/NavigationBar/View/NavigationBar.storyboard +++ b/DuckDuckGo/NavigationBar/View/NavigationBar.storyboard @@ -724,6 +724,7 @@ +