From ca180eb31b7e409db4f158e320295ce8fa9b2db5 Mon Sep 17 00:00:00 2001 From: niutrans Date: Tue, 14 Nov 2023 15:29:11 +0800 Subject: [PATCH 01/15] NiuTrans Support --- Easydict.xcodeproj/project.pbxproj | 185 ++- Easydict/App/AppDelegate+EZURLScheme.m | 51 +- Easydict/App/AppDelegate.m | 1 + .../toolbar_setting.imageset/Contents.json | 21 - .../toolbar_setting.png | Bin 1081 -> 0 bytes Easydict/App/Base.lproj/Main.storyboard | 14 +- Easydict/App/EZConst.h | 2 +- Easydict/App/Localizable.xcstrings | 39 +- Easydict/App/main.m | 6 +- Easydict/App/mul.lproj/Main.xcstrings | 1052 +---------------- .../Feature/Configuration/EZConfiguration.m | 169 ++- .../Feature/EventMonitor/EZEventMonitor.h | 2 +- .../Libraries/DictionaryKit/TTTDictionary.m | 198 ++-- Easydict/Feature/MMKit/Log/MMLog.m | 5 +- .../PerferenceWindow/EZAboutViewController.m | 2 +- .../EZSettingViewController.m | 246 ++-- .../Feature/Service/Apple/EZAppleService.m | 47 +- .../Service/Bing/EZBingLanguageVoice.swift | 27 - Easydict/Feature/Service/Bing/EZBingRequest.m | 2 +- Easydict/Feature/Service/Model/EZConstKey.h | 1 + .../Feature/Service/Model/EZDetectManager.m | 3 +- Easydict/Feature/Service/Model/EZEnumTypes.h | 9 +- Easydict/Feature/Service/Model/EZEnumTypes.m | 1 + .../Feature/Service/Model/EZServiceTypes.m | 4 +- .../Feature/StatusItem/EZMenuItemManager.m | 9 +- .../NSString/NSString+EZHandleInputText.h | 8 +- .../NSString/NSString+EZHandleInputText.m | 78 +- .../EZDeviceSystemInfo/EZDeviceSystemInfo.h | 3 + .../EZDeviceSystemInfo/EZDeviceSystemInfo.m | 17 +- .../Utility/EZLinkParser/EZSchemeParser.m | 7 +- Easydict/Feature/Utility/EZLog/EZLog.h | 2 + Easydict/Feature/Utility/EZLog/EZLog.m | 9 + .../ViewController/Model/EZQueryModel.m | 4 +- .../ViewController/Storage/EZLocalStorage.m | 6 +- .../EZQueryMenuTextView/EZQueryMenuTextView.m | 8 +- .../View/WordResultView/EZWordResultView.m | 5 +- .../EZBaseQueryViewController.m | 13 +- .../BaseQueryWindow/EZBaseQueryWindow.h | 2 +- .../Window/WindowManager/EZWindowManager.h | 7 +- .../Window/WindowManager/EZWindowManager.m | 321 ++--- EasydictHelper/Base.lproj/Main.storyboard | 6 +- Podfile.lock | 4 +- .../AFNetworking/AFURLResponseSerialization.m | 4 +- Pods/Manifest.lock | 4 +- Pods/Pods.xcodeproj/project.pbxproj | 514 ++++---- README.md | 111 +- README_EN.md | 111 +- 47 files changed, 1324 insertions(+), 2016 deletions(-) delete mode 100644 Easydict/App/Assets.xcassets/setting/toolbar_setting.imageset/Contents.json delete mode 100644 Easydict/App/Assets.xcassets/setting/toolbar_setting.imageset/toolbar_setting.png delete mode 100644 Easydict/Feature/Service/Bing/EZBingLanguageVoice.swift diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index 952b8d96a..46ca544cf 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -60,6 +60,7 @@ 037852B329583F5200D0E2CF /* EZServiceCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 037852B229583F5200D0E2CF /* EZServiceCell.m */; }; 037852B629588EDE00D0E2CF /* EZCustomTableRowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 037852B529588EDE00D0E2CF /* EZCustomTableRowView.m */; }; 037852B9295D49F900D0E2CF /* EZTableRowView.m in Sources */ = {isa = PBXBuildFile; fileRef = 037852B8295D49F900D0E2CF /* EZTableRowView.m */; }; + 037BEFCD2A98FDF700D0F17F /* EZBingLanguageVoice.m in Sources */ = {isa = PBXBuildFile; fileRef = 037BEFCC2A98FDF700D0F17F /* EZBingLanguageVoice.m */; }; 0383914C292FBE120009828C /* Main.strings in Resources */ = {isa = PBXBuildFile; fileRef = 03839140292FBE120009828C /* Main.strings */; }; 0383914D292FBE120009828C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 03839143292FBE120009828C /* Assets.xcassets */; }; 0383914E292FBE120009828C /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 03839144292FBE120009828C /* ViewController.m */; }; @@ -206,13 +207,17 @@ 03F14A3B2956016B00CB7379 /* EZVolcanoTranslate.m in Sources */ = {isa = PBXBuildFile; fileRef = 03F14A3A2956016B00CB7379 /* EZVolcanoTranslate.m */; }; 03F25CB329327BC200E66A12 /* EZShortcut.m in Sources */ = {isa = PBXBuildFile; fileRef = 03F25CB229327BC200E66A12 /* EZShortcut.m */; }; 03F639952AA6CFBB009B9914 /* EZBingConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 03F639942AA6CFBB009B9914 /* EZBingConfig.m */; }; + 17FD9A002B01B9F200A528A6 /* EZNiuTransTranslateResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 17FD99FD2B01B9F200A528A6 /* EZNiuTransTranslateResponse.m */; }; + 17FD9A012B01B9F200A528A6 /* EZNiuTransTranslate.m in Sources */ = {isa = PBXBuildFile; fileRef = 17FD99FE2B01B9F200A528A6 /* EZNiuTransTranslate.m */; }; + 17FD9A022B01B9F200A528A6 /* EZQueryResult+EZNiuTransTranslateResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 17FD99FF2B01B9F200A528A6 /* EZQueryResult+EZNiuTransTranslateResponse.m */; }; + 27B7919E2AEC36A1006E07C6 /* Easydict.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 27B7919C2AEC36A1006E07C6 /* Easydict.xcconfig */; }; + 27B7919F2AEC36A1006E07C6 /* Easydict-debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 27B7919D2AEC36A1006E07C6 /* Easydict-debug.xcconfig */; }; 6220AD5B2A82812300BBFB52 /* EZBingService.m in Sources */ = {isa = PBXBuildFile; fileRef = 6220AD5A2A82812300BBFB52 /* EZBingService.m */; }; 6295DE312A84D82E006145F4 /* EZBingTranslateModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6295DE302A84D82E006145F4 /* EZBingTranslateModel.m */; }; 6295DE342A84EF76006145F4 /* EZBingLookupModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 6295DE332A84EF76006145F4 /* EZBingLookupModel.m */; }; 62A2D03F2A82967F007EEB01 /* EZBingRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = 62A2D03E2A82967F007EEB01 /* EZBingRequest.m */; }; A0B65CA0F31AC8ECFB8347CC /* Pods_EasydictTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 378E73A7EA8FC8FB9C975A63 /* Pods_EasydictTests.framework */; }; B87AC7E36367075BA5D13234 /* Pods_Easydict.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6372B33DFF803C7096A82250 /* Pods_Easydict.framework */; }; - C4BA2E1B2AE9D3A70017EFE2 /* EZBingLanguageVoice.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4BA2E1A2AE9D3A70017EFE2 /* EZBingLanguageVoice.swift */; }; C4DE3D6D2AC00EB500C2B85D /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = C4DE3D6C2AC00EB500C2B85D /* Localizable.xcstrings */; }; C98CAE75239F4619005F7DCA /* EasydictHelper.app in CopyFiles */ = {isa = PBXBuildFile; fileRef = C90BE309239F38EB00ADE88B /* EasydictHelper.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ @@ -345,6 +350,8 @@ 037852B529588EDE00D0E2CF /* EZCustomTableRowView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZCustomTableRowView.m; sourceTree = ""; }; 037852B7295D49F900D0E2CF /* EZTableRowView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EZTableRowView.h; sourceTree = ""; }; 037852B8295D49F900D0E2CF /* EZTableRowView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZTableRowView.m; sourceTree = ""; }; + 037BEFCB2A98FDF700D0F17F /* EZBingLanguageVoice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EZBingLanguageVoice.h; sourceTree = ""; }; + 037BEFCC2A98FDF700D0F17F /* EZBingLanguageVoice.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZBingLanguageVoice.m; sourceTree = ""; }; 03839141292FBE120009828C /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Main.strings"; sourceTree = ""; }; 03839142292FBE120009828C /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 03839143292FBE120009828C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -625,6 +632,15 @@ 03F639932AA6CFBB009B9914 /* EZBingConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EZBingConfig.h; sourceTree = ""; }; 03F639942AA6CFBB009B9914 /* EZBingConfig.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZBingConfig.m; sourceTree = ""; }; 06E15747A7BD34D510ADC6A8 /* Pods-Easydict.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Easydict.debug.xcconfig"; path = "Target Support Files/Pods-Easydict/Pods-Easydict.debug.xcconfig"; sourceTree = ""; }; + 17FD99FA2B01B9F200A528A6 /* EZNiuTransTranslateResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZNiuTransTranslateResponse.h; sourceTree = ""; }; + 17FD99FB2B01B9F200A528A6 /* EZNiuTransTranslate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZNiuTransTranslate.h; sourceTree = ""; }; + 17FD99FC2B01B9F200A528A6 /* EZQueryResult+EZNiuTransTranslateResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "EZQueryResult+EZNiuTransTranslateResponse.h"; sourceTree = ""; }; + 17FD99FD2B01B9F200A528A6 /* EZNiuTransTranslateResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZNiuTransTranslateResponse.m; sourceTree = ""; }; + 17FD99FE2B01B9F200A528A6 /* EZNiuTransTranslate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZNiuTransTranslate.m; sourceTree = ""; }; + 17FD99FF2B01B9F200A528A6 /* EZQueryResult+EZNiuTransTranslateResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "EZQueryResult+EZNiuTransTranslateResponse.m"; sourceTree = ""; }; + 27B7919C2AEC36A1006E07C6 /* Easydict.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Easydict.xcconfig; sourceTree = ""; }; + 27B7919D2AEC36A1006E07C6 /* Easydict-debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Easydict-debug.xcconfig"; sourceTree = ""; }; + 27B791A02AEC3A5C006E07C6 /* Easydict-debug.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = "Easydict-debug.entitlements"; sourceTree = ""; }; 357E179B303EF855EF4561FB /* Pods-EasydictTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EasydictTests.release.xcconfig"; path = "Target Support Files/Pods-EasydictTests/Pods-EasydictTests.release.xcconfig"; sourceTree = ""; }; 378E73A7EA8FC8FB9C975A63 /* Pods_EasydictTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_EasydictTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 6220AD592A82812300BBFB52 /* EZBingService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EZBingService.h; sourceTree = ""; }; @@ -638,7 +654,6 @@ 6372B33DFF803C7096A82250 /* Pods_Easydict.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Easydict.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 91E3E579C6DB88658B4BB102 /* Pods-Easydict.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Easydict.release.xcconfig"; path = "Target Support Files/Pods-Easydict/Pods-Easydict.release.xcconfig"; sourceTree = ""; }; A230E9A2358C7FBC7FB26189 /* Pods-EasydictTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EasydictTests.debug.xcconfig"; path = "Target Support Files/Pods-EasydictTests/Pods-EasydictTests.debug.xcconfig"; sourceTree = ""; }; - C4BA2E1A2AE9D3A70017EFE2 /* EZBingLanguageVoice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EZBingLanguageVoice.swift; sourceTree = ""; }; C4DE3D6C2AC00EB500C2B85D /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = Localizable.xcstrings; path = Easydict/App/Localizable.xcstrings; sourceTree = SOURCE_ROOT; }; C4DE3D6E2AC00EB500C2B85D /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/Main.xcstrings; sourceTree = ""; }; C90BE309239F38EB00ADE88B /* EasydictHelper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EasydictHelper.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -934,6 +949,7 @@ 03B0221F29231FA6001C7E63 /* Main.storyboard */, 03B0221D29231FA6001C7E63 /* Assets.xcassets */, 03B0221E29231FA6001C7E63 /* Easydict.entitlements */, + 27B791A02AEC3A5C006E07C6 /* Easydict-debug.entitlements */, 03B0222129231FA6001C7E63 /* main.m */, 03B0222229231FA6001C7E63 /* EZConst.h */, 03B0221C29231FA6001C7E63 /* AppDelegate.h */, @@ -1137,6 +1153,7 @@ 03B0222B29231FA6001C7E63 /* Service */ = { isa = PBXGroup; children = ( + 17FD99F92B01B9F200A528A6 /* Niutrans */, 6220AD582A8280E800BBFB52 /* Bing */, 0399C6A929A8608000B4AFCC /* OpenAI */, 03F14A382956011400CB7379 /* Volcano */, @@ -1803,6 +1820,19 @@ path = Volcano; sourceTree = ""; }; + 17FD99F92B01B9F200A528A6 /* Niutrans */ = { + isa = PBXGroup; + children = ( + 17FD99FA2B01B9F200A528A6 /* EZNiuTransTranslateResponse.h */, + 17FD99FB2B01B9F200A528A6 /* EZNiuTransTranslate.h */, + 17FD99FC2B01B9F200A528A6 /* EZQueryResult+EZNiuTransTranslateResponse.h */, + 17FD99FD2B01B9F200A528A6 /* EZNiuTransTranslateResponse.m */, + 17FD99FE2B01B9F200A528A6 /* EZNiuTransTranslate.m */, + 17FD99FF2B01B9F200A528A6 /* EZQueryResult+EZNiuTransTranslateResponse.m */, + ); + path = Niutrans; + sourceTree = ""; + }; 6220AD582A8280E800BBFB52 /* Bing */ = { isa = PBXGroup; children = ( @@ -1810,11 +1840,12 @@ 6220AD5A2A82812300BBFB52 /* EZBingService.m */, 62A2D03D2A82967F007EEB01 /* EZBingRequest.h */, 62A2D03E2A82967F007EEB01 /* EZBingRequest.m */, - C4BA2E1A2AE9D3A70017EFE2 /* EZBingLanguageVoice.swift */, 6295DE2F2A84D82E006145F4 /* EZBingTranslateModel.h */, 6295DE302A84D82E006145F4 /* EZBingTranslateModel.m */, 6295DE322A84EF76006145F4 /* EZBingLookupModel.h */, 6295DE332A84EF76006145F4 /* EZBingLookupModel.m */, + 037BEFCB2A98FDF700D0F17F /* EZBingLanguageVoice.h */, + 037BEFCC2A98FDF700D0F17F /* EZBingLanguageVoice.m */, 03F639932AA6CFBB009B9914 /* EZBingConfig.h */, 03F639942AA6CFBB009B9914 /* EZBingConfig.m */, ); @@ -1852,6 +1883,8 @@ C99EEB0F2385796700FEE666 = { isa = PBXGroup; children = ( + 27B7919C2AEC36A1006E07C6 /* Easydict.xcconfig */, + 27B7919D2AEC36A1006E07C6 /* Easydict-debug.xcconfig */, 03B0221829231FA6001C7E63 /* Easydict */, 0383913F292FBE120009828C /* EasydictHelper */, 0313F86E2AD5577400A5CFB0 /* EasydictTests */, @@ -1959,7 +1992,7 @@ }; buildConfigurationList = C99EEB132385796700FEE666 /* Build configuration list for PBXProject "Easydict" */; compatibilityVersion = "Xcode 13.0"; - developmentRegion = en; + developmentRegion = "zh-Hans"; hasScannedForEncodings = 0; knownRegions = ( en, @@ -2001,11 +2034,13 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 27B7919E2AEC36A1006E07C6 /* Easydict.xcconfig in Resources */, 0310C8272A94F5DF00B1D81E /* apple-dictionary.html in Resources */, 03BFBB802923A2FA00C48725 /* white-black-icon@2x.png in Resources */, 031DBD792AE01E130071CF85 /* easydict in Resources */, 03BFBB7329239E9F00C48725 /* blue-white-icon@2x.png in Resources */, 03882F9229D95044005B5A52 /* Info.plist in Resources */, + 27B7919F2AEC36A1006E07C6 /* Easydict-debug.xcconfig in Resources */, 03BFBB7C2923A1D900C48725 /* cyan-white-icon@3x.png in Resources */, 03882F9029D95044005B5A52 /* ToastWindowController.xib in Resources */, 03BFBB652923998300C48725 /* black-white-icon@2x.png in Resources */, @@ -2136,6 +2171,7 @@ 03991158292927E000E1B06D /* EZTitlebar.m in Sources */, 03D8A65C2A433B4100D9A968 /* EZConfiguration+EZUserData.m in Sources */, 03BD282229486CF200F5891A /* EZBlueTextButton.m in Sources */, + 037BEFCD2A98FDF700D0F17F /* EZBingLanguageVoice.m in Sources */, 03BDA7C22A26DA280079D04F /* NSString+Indenter.m in Sources */, 03542A462937B4C300C34C33 /* EZBaiduTranslateResponse.m in Sources */, 0309E1F0292B4A5E00AFB76A /* NSView+EZGetViewController.m in Sources */, @@ -2148,6 +2184,7 @@ 03BDA7C12A26DA280079D04F /* XPMArgumentParser.m in Sources */, 03B0231329231FA6001C7E63 /* NSView+HiddenDebug.m in Sources */, 03008B2B2940D3230062B821 /* EZDeepLTranslate.m in Sources */, + 17FD9A012B01B9F200A528A6 /* EZNiuTransTranslate.m in Sources */, 03991166292A8A4400E1B06D /* EZTitleBarMoveView.m in Sources */, 03542A582937CC3200C34C33 /* EZConfiguration.m in Sources */, 035E37E72A0953120061DFAF /* EZToast.m in Sources */, @@ -2165,7 +2202,6 @@ 03542A522937B69200C34C33 /* EZYoudaoTranslateResponse.m in Sources */, 03B0230129231FA6001C7E63 /* EZQueryView.m in Sources */, 03542A3D2937AF4F00C34C33 /* EZQueryResult.m in Sources */, - C4BA2E1B2AE9D3A70017EFE2 /* EZBingLanguageVoice.swift in Sources */, 03262C1F29EF8EE500EFECA0 /* EZPrivacyViewController.m in Sources */, 03BDA7BF2A26DA280079D04F /* NSScanner+EscapedScanning.m in Sources */, 03542A4C2937B5F100C34C33 /* EZYoudaoTranslate.m in Sources */, @@ -2197,6 +2233,7 @@ 03BDA7BC2A26DA280079D04F /* XPMArgumentSignature.m in Sources */, 03B0230229231FA6001C7E63 /* EZWordResultView.m in Sources */, 0399C6A529A747E600B4AFCC /* EZDeepLTranslateResponse.m in Sources */, + 17FD9A002B01B9F200A528A6 /* EZNiuTransTranslateResponse.m in Sources */, 039F5506294B6E29004AB940 /* EZSettingViewController.m in Sources */, 03BD281E29481C0400F5891A /* EZAudioPlayer.m in Sources */, 03E02A2629250D1D00A10260 /* EZEventMonitor.m in Sources */, @@ -2238,6 +2275,7 @@ 0396D611292C932F006A11D9 /* EZSelectLanguageCell.m in Sources */, 036196752A000F5900806370 /* FWEncryptorAES.m in Sources */, 0399C6A829A74E0F00B4AFCC /* EZQueryResult+EZDeepLTranslateResponse.m in Sources */, + 17FD9A022B01B9F200A528A6 /* EZQueryResult+EZNiuTransTranslateResponse.m in Sources */, 039B694F2A9D9F370063709D /* EZWebViewManager.m in Sources */, 03D747432A07FB150006CD77 /* EZError.m in Sources */, 03B0231629231FA6001C7E63 /* SnipFocusView.m in Sources */, @@ -2355,9 +2393,11 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_IDENTITY = $CODE_SIGN_IDENTITY; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + CODE_SIGN_STYLE = $CODE_SIGN_STYLE; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 79NQA2XYHM; + DEVELOPMENT_TEAM = ""; ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu17; GCC_PREFIX_HEADER = "$(SRCROOT)/Easydict/App/PrefixHeader.pch"; @@ -2378,9 +2418,11 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_IDENTITY = $CODE_SIGN_IDENTITY; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + CODE_SIGN_STYLE = $CODE_SIGN_STYLE; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 79NQA2XYHM; + DEVELOPMENT_TEAM = ""; ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu17; GCC_PREFIX_HEADER = "$(SRCROOT)/Easydict/App/PrefixHeader.pch"; @@ -2400,13 +2442,13 @@ ASSETCATALOG_COMPILER_APPICON_NAME = "white-black-icon"; "ASSETCATALOG_COMPILER_APPICON_NAME[sdk=macosx*]" = "white-black-icon"; CODE_SIGN_ENTITLEMENTS = EasydictHelper/EasydictHelper.entitlements; - CODE_SIGN_IDENTITY = "-"; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_IDENTITY = $CODE_SIGN_IDENTITY; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + CODE_SIGN_STYLE = $CODE_SIGN_STYLE; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 22; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = 79NQA2XYHM; + DEVELOPMENT_TEAM = ""; ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = EasydictHelper/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -2426,13 +2468,13 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = "white-black-icon"; CODE_SIGN_ENTITLEMENTS = EasydictHelper/EasydictHelper.entitlements; - CODE_SIGN_IDENTITY = "-"; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_IDENTITY = $CODE_SIGN_IDENTITY; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + CODE_SIGN_STYLE = $CODE_SIGN_STYLE; COMBINE_HIDPI_IMAGES = YES; CURRENT_PROJECT_VERSION = 22; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = 79NQA2XYHM; + DEVELOPMENT_TEAM = ""; ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = EasydictHelper/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -2449,6 +2491,7 @@ }; C99EEB2A2385796900FEE666 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 27B7919D2AEC36A1006E07C6 /* Easydict-debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; @@ -2507,12 +2550,14 @@ MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; + OTHER_LDFLAGS = ""; SDKROOT = macosx; }; name = Debug; }; C99EEB2B2385796900FEE666 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 27B7919C2AEC36A1006E07C6 /* Easydict.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; @@ -2564,6 +2609,7 @@ MACOSX_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; + OTHER_LDFLAGS = ""; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; }; @@ -2577,15 +2623,15 @@ ASSETCATALOG_COMPILER_APPICON_NAME = "white-black-icon"; ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CLANG_ENABLE_MODULES = YES; - CODE_SIGN_ENTITLEMENTS = Easydict/App/Easydict.entitlements; - CODE_SIGN_IDENTITY = "-"; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_ENTITLEMENTS = "Easydict/App/Easydict-debug.entitlements"; + CODE_SIGN_IDENTITY = $CODE_SIGN_IDENTITY; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + CODE_SIGN_STYLE = $CODE_SIGN_STYLE; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 22; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = 79NQA2XYHM; + DEVELOPMENT_TEAM = ""; ENABLE_HARDENED_RUNTIME = YES; ENABLE_TESTING_SEARCH_PATHS = NO; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; @@ -2598,6 +2644,93 @@ ); MACOSX_DEPLOYMENT_TARGET = 11.0; MARKETING_VERSION = 2.0.1; + OTHER_CFLAGS = ( + "$(inherited)", + "-isystem", + "\"${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers\"", + "-isystem", + "\"${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack/CocoaLumberjack.framework/Headers\"", + "-isystem", + "\"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore/FirebaseCore.framework/Headers\"", + "-isystem", + "\"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal/FirebaseCoreInternal.framework/Headers\"", + "-isystem", + "\"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations/FirebaseInstallations.framework/Headers\"", + "-isystem", + "\"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities/GoogleUtilities.framework/Headers\"", + "-isystem", + "\"${PODS_CONFIGURATION_BUILD_DIR}/JLRoutes/JLRoutes.framework/Headers\"", + "-isystem", + "\"${PODS_CONFIGURATION_BUILD_DIR}/KVOController/KVOController.framework/Headers\"", + "-isystem", + "\"${PODS_CONFIGURATION_BUILD_DIR}/MASPreferences/MASPreferences.framework/Headers\"", + "-isystem", + "\"${PODS_CONFIGURATION_BUILD_DIR}/MASShortcut/MASShortcut.framework/Headers\"", + "-isystem", + "\"${PODS_CONFIGURATION_BUILD_DIR}/MJExtension/MJExtension.framework/Headers\"", + "-isystem", + "\"${PODS_CONFIGURATION_BUILD_DIR}/Masonry/Masonry.framework/Headers\"", + "-isystem", + "\"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC/FBLPromises.framework/Headers\"", + "-isystem", + "\"${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC/ReactiveObjC.framework/Headers\"", + "-isystem", + "\"${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive/SSZipArchive.framework/Headers\"", + "-isystem", + "\"${PODS_CONFIGURATION_BUILD_DIR}/nanopb/nanopb.framework/Headers\"", + "-iframework", + "\"${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking\"", + "-iframework", + "\"${PODS_ROOT}/AppCenter/AppCenter-SDK-Apple\"", + "-iframework", + "\"${PODS_XCFRAMEWORKS_BUILD_DIR}/AppCenter/Analytics\"", + "-iframework", + "\"${PODS_XCFRAMEWORKS_BUILD_DIR}/AppCenter/Core\"", + "-iframework", + "\"${PODS_XCFRAMEWORKS_BUILD_DIR}/AppCenter/Crashes\"", + "-iframework", + "\"${PODS_CONFIGURATION_BUILD_DIR}/CocoaLumberjack\"", + "-iframework", + "\"${PODS_ROOT}/FirebaseAnalytics/Frameworks\"", + "-iframework", + "\"${PODS_XCFRAMEWORKS_BUILD_DIR}/FirebaseAnalytics/AdIdSupport\"", + "-iframework", + "\"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCore\"", + "-iframework", + "\"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseCoreInternal\"", + "-iframework", + "\"${PODS_CONFIGURATION_BUILD_DIR}/FirebaseInstallations\"", + "-iframework", + "\"${PODS_ROOT}/GoogleAppMeasurement/Frameworks\"", + "-iframework", + "\"${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/AdIdSupport\"", + "-iframework", + "\"${PODS_XCFRAMEWORKS_BUILD_DIR}/GoogleAppMeasurement/WithoutAdIdSupport\"", + "-iframework", + "\"${PODS_CONFIGURATION_BUILD_DIR}/GoogleUtilities\"", + "-iframework", + "\"${PODS_CONFIGURATION_BUILD_DIR}/JLRoutes\"", + "-iframework", + "\"${PODS_CONFIGURATION_BUILD_DIR}/KVOController\"", + "-iframework", + "\"${PODS_CONFIGURATION_BUILD_DIR}/MASPreferences\"", + "-iframework", + "\"${PODS_CONFIGURATION_BUILD_DIR}/MASShortcut\"", + "-iframework", + "\"${PODS_CONFIGURATION_BUILD_DIR}/MJExtension\"", + "-iframework", + "\"${PODS_CONFIGURATION_BUILD_DIR}/Masonry\"", + "-iframework", + "\"${PODS_CONFIGURATION_BUILD_DIR}/PromisesObjC\"", + "-iframework", + "\"${PODS_CONFIGURATION_BUILD_DIR}/ReactiveObjC\"", + "-iframework", + "\"${PODS_CONFIGURATION_BUILD_DIR}/SSZipArchive\"", + "-iframework", + "\"${PODS_ROOT}/Sparkle\"", + "-iframework", + "\"${PODS_CONFIGURATION_BUILD_DIR}/nanopb\"", + ); PRODUCT_BUNDLE_IDENTIFIER = "com.izual.Easydict-debug"; PRODUCT_MODULE_NAME = Easydict; PRODUCT_NAME = "Easydict-Debug"; @@ -2617,14 +2750,14 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = NO; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Easydict/App/Easydict.entitlements; - CODE_SIGN_IDENTITY = "-"; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_IDENTITY = $CODE_SIGN_IDENTITY; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + CODE_SIGN_STYLE = $CODE_SIGN_STYLE; COMBINE_HIDPI_IMAGES = YES; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 22; DEAD_CODE_STRIPPING = YES; - DEVELOPMENT_TEAM = 79NQA2XYHM; + DEVELOPMENT_TEAM = ""; ENABLE_HARDENED_RUNTIME = YES; ENABLE_TESTING_SEARCH_PATHS = NO; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; diff --git a/Easydict/App/AppDelegate+EZURLScheme.m b/Easydict/App/AppDelegate+EZURLScheme.m index 45816be40..408f7932e 100644 --- a/Easydict/App/AppDelegate+EZURLScheme.m +++ b/Easydict/App/AppDelegate+EZURLScheme.m @@ -10,44 +10,57 @@ #import #import "EZWindowManager.h" #import "EZSchemeParser.h" +#import "EZConfiguration.h" @implementation AppDelegate (EZURLScheme) - (void)registerRouters { // Reigster URL Scheme handler. NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager]; - [appleEventManager setEventHandler:self andSelector:@selector(handleURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL]; - - EZWindowManager *windowManager = [EZWindowManager shared]; + [appleEventManager setEventHandler:self + andSelector:@selector(handleURLEvent:withReplyEvent:) + forEventClass:kInternetEventClass + andEventID:kAEGetURL]; JLRoutes *routes = [JLRoutes globalRoutes]; [routes addRoute:@"/:action" handler:^BOOL(NSDictionary *parameters) { NSString *action = parameters[@"action"]; NSString *queryText = parameters[@"text"]; + NSURL *URL = parameters[JLRouteURLKey]; + /** + Recommend use easydict://query?text=xxx, easydict://xxx is a bit ambiguous and complex. + easydict://good easydict://query?text=good - - easydictd://good - easydictd://query?text=good - easydictd://good%2Fgirl (easydictd://good/girl) + easydict://good%2Fgirl (easydict://good/girl) */ if (!([action isEqualToString:EZQueryKey] && queryText.length)) { - queryText = action; + // Ukraine may get another Patriot battery. + if (action.length == 0) { + /** + !!!: action may be nil if URL contains '.' + FIX https://github.com/tisfeng/Easydict/issues/207#issuecomment-1786267017 + */ + queryText = [self extractQueryTextFromURL:URL]; + } else { + queryText = action; + } } - [windowManager showFloatingWindowType:EZWindowTypeFixed queryText:queryText actionType:EZActionTypeInvokeQuery]; + [self showFloatingWindowAndAutoQueryText:queryText]; return YES; // return YES to say we have handled the route }]; + // good / girl [routes addRoute:@"*" handler:^BOOL(NSDictionary *parameters) { NSLog(@"parameters: %@", parameters); NSURL *URL = parameters[JLRouteURLKey]; NSLog(@"URL: %@", URL); -// NSString *queryText = [URL.resourceSpecifier stringByReplacingOccurrencesOfString:@"//" withString:@"" options:NSLiteralSearch range:NSMakeRange(0, 2)]; -// [windowManager showFloatingWindowType:EZWindowTypeFixed queryText:queryText]; + NSString *queryText = [self extractQueryTextFromURL:URL]; + [self showFloatingWindowAndAutoQueryText:queryText]; return YES; }]; @@ -55,6 +68,22 @@ - (void)registerRouters { #pragma mark - +- (void)showFloatingWindowAndAutoQueryText:(NSString *)text { + EZWindowManager *windowManager = [EZWindowManager shared]; + EZWindowType windowType = EZConfiguration.shared.shortcutSelectTranslateWindowType; + + [windowManager showFloatingWindowType:windowType + queryText:text.trim + autoQuery:YES + actionType:EZActionTypeInvokeQuery]; +} + +/// Get query text from url scheme, easydict://good%2Fgirl --> good%2Fgirl +- (NSString *)extractQueryTextFromURL:(NSURL *)URL { + NSString *queryText = [URL.resourceSpecifier stringByReplacingOccurrencesOfString:@"//" withString:@"" options:NSLiteralSearch range:NSMakeRange(0, 2)]; + return queryText.decode; +} + - (void)handleURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent { NSURL *URL = [NSURL URLWithString:[[event paramDescriptorForKeyword:keyDirectObject] stringValue]]; diff --git a/Easydict/App/AppDelegate.m b/Easydict/App/AppDelegate.m index 638056518..fddd46bda 100644 --- a/Easydict/App/AppDelegate.m +++ b/Easydict/App/AppDelegate.m @@ -25,6 +25,7 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { // Capturing crash logs must be placed first. [MMCrash registerHandler]; [EZLog setupCrashLogService]; + [EZLog logAppInfo]; [self setupAppLanguage]; diff --git a/Easydict/App/Assets.xcassets/setting/toolbar_setting.imageset/Contents.json b/Easydict/App/Assets.xcassets/setting/toolbar_setting.imageset/Contents.json deleted file mode 100644 index 276cbae7d..000000000 --- a/Easydict/App/Assets.xcassets/setting/toolbar_setting.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x" - }, - { - "filename" : "toolbar_setting.png", - "idiom" : "universal", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Easydict/App/Assets.xcassets/setting/toolbar_setting.imageset/toolbar_setting.png b/Easydict/App/Assets.xcassets/setting/toolbar_setting.imageset/toolbar_setting.png deleted file mode 100644 index 5359c9910bf70fc2e1f29da0f6b02c4986a418ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1081 zcmV-91jhS`P)Px&^GQTORA@u(TkUb%Fbt*K37YE)o+HjUO^0YaMALEN%;6P!=>)ZUkVS=s0Pukn zt@@n&tSJ%?c=#mSg&X_pZVYeu0NmQ*Uw$5U@r++zw};l}@%@`wI0F0AhwpS~7s3Qo z0@;Uf==$(VzrB6iKDAOrGr)I0j!&UGgZ2Iq_}`D)2k&>t`euMXKObLmR@DT&O2Bu| z$36u_AO>oWw2i;@UAUJhzv;q53myZew9a z=eNf#bPjg|^gAS2#Wj#1aWT=3e9lTAC3KGa&jOv|3dDvf-Sy!$=Ps#2V8B|MiTQK0 z2?r8l7MTJ6jRJ965C7hWJ?(uuh25ZRDW5yefB@IzRK$Nxz$jlq&=_Fmlc)@29S_}T z-`2{_0_FmwC7@bK6#(T*v|NbRe(J)WyAV>an1H22rN}v~BX{eXQ6$}AJG(I%%l?6+*^s1DW zA~oW}Lo)zQD`%A&F!gK_w7hAlNeynqf<@Dk7c5z+q;N>BTQb4$f?m9|&H!?^*)4h6G_47+`d<32WLQ^Y-E4cv+q4=h zdzFH&M{h^se(tLl4w^qtLUJw&W*Yk#&zZdQ^KA2=6%ywAtAdm=tEa7JPyP9xX*Tr) z&dmZ=r;v!500AVR=J?h)7im_qfQPoP;*puh?=PWT2(Se@eexjXTn}KaCZ@P>(I*dS zK8+=z7MyC*89Mb$@1vE(4g|8b*O)JQz#9f8J9gDW(K`6Tl?M%{?Ek0gR4z{woVlxmzj$1xe#Yx%51# z1eo?sGfG=RuK6E5Rsp=E#k_lc0QPF^+SdOCNv^DF`w7b&00000NkvXXu0mjfEB*D2 diff --git a/Easydict/App/Base.lproj/Main.storyboard b/Easydict/App/Base.lproj/Main.storyboard index 577da7fcc..1523dfd2a 100644 --- a/Easydict/App/Base.lproj/Main.storyboard +++ b/Easydict/App/Base.lproj/Main.storyboard @@ -1,8 +1,8 @@ - + - + @@ -22,9 +22,9 @@ - + - + @@ -718,10 +718,10 @@ DQ - + @@ -772,9 +772,9 @@ DQ - + - + diff --git a/Easydict/App/EZConst.h b/Easydict/App/EZConst.h index 3e67abe68..680fc22b4 100644 --- a/Easydict/App/EZConst.h +++ b/Easydict/App/EZConst.h @@ -39,7 +39,7 @@ static NSString *const EZUserAgent = @"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 // ???: If value is not 0.2, it seems will block animation, because default animationResizeTime is 0.2 ? static NSTimeInterval const EZUpdateTableViewRowHeightAnimationDuration = 0.2; -static NSTimeInterval const EZNetWorkTimeoutInterval = 15.0; +static NSTimeInterval const EZNetWorkTimeoutInterval = 150.0; // !!!: This floating window level shouldn't be higher than kCGModalPanelWindowLevel, otherwise it will cover system modal alert window. static NSTimeInterval const EZFloatingWindowLevel = kCGModalPanelWindowLevel; diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index d8c6414aa..68495f3bf 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -1,5 +1,5 @@ { - "sourceLanguage" : "en", + "sourceLanguage" : "zh-Hans", "strings" : { "about" : { "comment" : "about", @@ -109,7 +109,7 @@ "en" : { "stringUnit" : { "state" : "translated", - "value" : "System Dictionary" + "value" : "Apple Dictionary" } }, "zh-Hans" : { @@ -125,7 +125,7 @@ "en" : { "stringUnit" : { "state" : "translated", - "value" : "System Translation" + "value" : "Apple Translation" } }, "zh-Hans" : { @@ -924,7 +924,7 @@ "en" : { "stringUnit" : { "state" : "translated", - "value" : "Center of Screen" + "value" : "Center of screen" } }, "zh-Hans" : { @@ -956,7 +956,7 @@ "en" : { "stringUnit" : { "state" : "translated", - "value" : "Mouse Position" + "value" : "Mouse position" } }, "zh-Hans" : { @@ -972,7 +972,7 @@ "en" : { "stringUnit" : { "state" : "translated", - "value" : "Right Side of Screen" + "value" : "Right side of screen" } }, "zh-Hans" : { @@ -1042,12 +1042,12 @@ } } }, - "Github:" : { + "GitHub:" : { "localizations" : { "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "" + "value" : "GitHub:" } } } @@ -1379,6 +1379,22 @@ } } }, + "niuTrans_translate" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "小牛翻译" + } + } + } + }, "no_results_found" : { "localizations" : { "en" : { @@ -1856,19 +1872,18 @@ } } }, - "setting" : { - "comment" : "setting", + "setting_general" : { "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Settings" + "value" : "General" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "设置" + "value" : "通用" } } } diff --git a/Easydict/App/main.m b/Easydict/App/main.m index 332c39766..a6457f563 100644 --- a/Easydict/App/main.m +++ b/Easydict/App/main.m @@ -22,7 +22,11 @@ static void delay_block(dispatch_block_t block) { void queryText(NSString *text) { // ???: need to wait AppDelegate loaded. delay_block(^{ - [EZWindowManager.shared showFloatingWindowType:EZWindowTypeFixed queryText:text actionType:EZActionTypeInvokeQuery]; + EZWindowManager *windowManager = [EZWindowManager shared]; + [windowManager showFloatingWindowType:EZWindowTypeFixed + queryText:text.trim + autoQuery:YES + actionType:EZActionTypeInvokeQuery]; }); } diff --git a/Easydict/App/mul.lproj/Main.xcstrings b/Easydict/App/mul.lproj/Main.xcstrings index fefa7d868..cdb0d1642 100644 --- a/Easydict/App/mul.lproj/Main.xcstrings +++ b/Easydict/App/mul.lproj/Main.xcstrings @@ -1,16 +1,9 @@ { - "sourceLanguage" : "en", + "sourceLanguage" : "zh-Hans", "strings" : { "0cE-0y-BcT.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Text Replacement\"; ObjectID = \"0cE-0y-BcT\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Text Replacement" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -21,14 +14,7 @@ }, "0sa-UX-oa3.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Easydict\"; ObjectID = \"0sa-UX-oa3\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Easydict" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -39,14 +25,7 @@ }, "00y-6C-LDt.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Customize Toolbar…\"; ObjectID = \"00y-6C-LDt\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Customize Toolbar…" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -57,14 +36,7 @@ }, "1eD-Dp-YEe.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Ligatures\"; ObjectID = \"1eD-Dp-YEe\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Ligatures" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -75,14 +47,7 @@ }, "1hf-nd-d37.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Show Fonts\"; ObjectID = \"1hf-nd-d37\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Show Fonts" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -93,14 +58,7 @@ }, "1y8-d6-Wtj.ibShadowedToolTip" : { "comment" : "Class = \"NSMenuItem\"; ibShadowedToolTip = \"Play Sound\"; ObjectID = \"1y8-d6-Wtj\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Play Sound" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -111,14 +69,7 @@ }, "1y8-d6-Wtj.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Play\"; ObjectID = \"1y8-d6-Wtj\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Play" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -129,14 +80,7 @@ }, "2cy-ys-bxL.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Find Previous\"; ObjectID = \"2cy-ys-bxL\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Find Previous" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -149,7 +93,7 @@ "comment" : "Class = \"NSMenuItem\"; ibShadowedToolTip = \"Copy First Translated Text\"; ObjectID = \"2kP-aF-pja\";", "extractionState" : "extracted_with_value", "localizations" : { - "en" : { + "zh-Hans" : { "stringUnit" : { "state" : "new", "value" : "Copy First Translated Text" @@ -161,7 +105,7 @@ "comment" : "Class = \"NSMenuItem\"; title = \"Copy First Result\"; ObjectID = \"2kP-aF-pja\";", "extractionState" : "extracted_with_value", "localizations" : { - "en" : { + "zh-Hans" : { "stringUnit" : { "state" : "new", "value" : "Copy First Result" @@ -171,14 +115,7 @@ }, "2pt-do-viE.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"2pt-do-viE\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Use Default" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -206,14 +143,7 @@ }, "2xC-XV-qeX.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Show Toolbar\"; ObjectID = \"2xC-XV-qeX\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Show Toolbar" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -224,14 +154,7 @@ }, "4PD-8L-PDj.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Clear All\"; ObjectID = \"4PD-8L-PDj\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Clear All" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -242,14 +165,7 @@ }, "5Wf-Zh-efw.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Paste Style\"; ObjectID = \"5Wf-Zh-efw\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Paste Style" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -260,14 +176,7 @@ }, "6oP-eF-qCh.title" : { "comment" : "Class = \"NSMenu\"; title = \"Services\"; ObjectID = \"6oP-eF-qCh\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Services" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -278,14 +187,7 @@ }, "6V6-U7-iWA.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Check Spelling While Typing\"; ObjectID = \"6V6-U7-iWA\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Check Spelling While Typing" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -296,14 +198,7 @@ }, "7Wy-ws-99E.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"View\"; ObjectID = \"7Wy-ws-99E\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "View" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -314,14 +209,7 @@ }, "8og-eW-YaH.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Window\"; ObjectID = \"8og-eW-YaH\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Window" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -332,14 +220,7 @@ }, "9k9-E7-lZ9.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"\\tRight to Left\"; ObjectID = \"9k9-E7-lZ9\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "\tRight to Left" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -350,14 +231,7 @@ }, "9vV-36-7Ry.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Hide Easydict\"; ObjectID = \"9vV-36-7Ry\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Hide Easydict" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -368,14 +242,7 @@ }, "61z-6q-qH5.title" : { "comment" : "Class = \"NSMenu\"; title = \"Find\"; ObjectID = \"61z-6q-qH5\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Find" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -386,14 +253,7 @@ }, "a4o-M9-LLq.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Paste Ruler\"; ObjectID = \"a4o-M9-LLq\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Paste Ruler" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -404,14 +264,7 @@ }, "acX-uy-p1U.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"\\tDefault\"; ObjectID = \"acX-uy-p1U\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "\tDefault" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -422,14 +275,7 @@ }, "AdF-Vq-aXV.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Jump to Selection\"; ObjectID = \"AdF-Vq-aXV\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Jump to Selection" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -440,14 +286,7 @@ }, "AJi-ur-lQe.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Check Grammar With Spelling\"; ObjectID = \"AJi-ur-lQe\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Check Grammar With Spelling" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -458,14 +297,7 @@ }, "anL-uV-VBZ.title" : { "comment" : "Class = \"NSMenu\"; title = \"File\"; ObjectID = \"anL-uV-VBZ\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "File" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -476,14 +308,7 @@ }, "ATD-km-qzd.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Find\"; ObjectID = \"ATD-km-qzd\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Find" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -511,14 +336,7 @@ }, "AXS-J4-86G.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Font\"; ObjectID = \"AXS-J4-86G\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Font" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -529,14 +347,7 @@ }, "AYu-sK-qS6.title" : { "comment" : "Class = \"NSMenu\"; title = \"Main Menu\"; ObjectID = \"AYu-sK-qS6\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Main Menu" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -547,14 +358,7 @@ }, "AZi-Ze-aTH.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Show Colors\"; ObjectID = \"AZi-Ze-aTH\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Show Colors" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -565,14 +369,7 @@ }, "b6H-cv-tjV.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Show Substitutions\"; ObjectID = \"b6H-cv-tjV\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Show Substitutions" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -583,14 +380,7 @@ }, "B46-gX-dqX.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"B46-gX-dqX\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Use Default" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -618,14 +408,7 @@ }, "bMP-wz-pIO.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Use Default\"; ObjectID = \"bMP-wz-pIO\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Use Default" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -636,14 +419,7 @@ }, "Bmv-mF-MbD.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Show Sidebar\"; ObjectID = \"Bmv-mF-MbD\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Show Sidebar" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -654,14 +430,7 @@ }, "BoU-uf-4hi.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Kern\"; ObjectID = \"BoU-uf-4hi\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Kern" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -672,14 +441,7 @@ }, "BRC-If-Fmo.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Quit Easydict\"; ObjectID = \"BRC-If-Fmo\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Quit Easydict" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -690,14 +452,7 @@ }, "C6n-7r-dtT.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Delete\"; ObjectID = \"C6n-7r-dtT\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Delete" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -708,14 +463,7 @@ }, "CKv-e7-TUD.title" : { "comment" : "Class = \"NSMenu\"; title = \"Spelling\"; ObjectID = \"CKv-e7-TUD\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Spelling" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -726,14 +474,7 @@ }, "cKy-v3-ja6.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Speech\"; ObjectID = \"cKy-v3-ja6\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Speech" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -744,14 +485,7 @@ }, "D5K-HC-eYd.title" : { "comment" : "Class = \"NSMenu\"; title = \"Window\"; ObjectID = \"D5K-HC-eYd\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Window" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -762,14 +496,7 @@ }, "d82-cy-RVu.ibShadowedToolTip" : { "comment" : "Class = \"NSMenuItem\"; ibShadowedToolTip = \"Toggle Translation Languages\"; ObjectID = \"d82-cy-RVu\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Toggle Translation Languages" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -780,14 +507,7 @@ }, "d82-cy-RVu.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Toggle\"; ObjectID = \"d82-cy-RVu\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Toggle" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -798,14 +518,7 @@ }, "DaJ-fK-CDq.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Start Speaking\"; ObjectID = \"DaJ-fK-CDq\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Start Speaking" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -816,14 +529,7 @@ }, "DeD-3q-hio.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Undo\"; ObjectID = \"DeD-3q-hio\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Undo" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -834,14 +540,7 @@ }, "dFr-S6-9m0.ibShadowedToolTip" : { "comment" : "Class = \"NSMenuItem\"; ibShadowedToolTip = \"Hide Window\"; ObjectID = \"dFr-S6-9m0\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Hide Window" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -852,14 +551,7 @@ }, "dFr-S6-9m0.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Hide\"; ObjectID = \"dFr-S6-9m0\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Hide" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -870,14 +562,7 @@ }, "dgN-f3-ebA.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Capitalize\"; ObjectID = \"dgN-f3-ebA\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Capitalize" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -905,14 +590,7 @@ }, "DNl-wA-6Sa.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"File\"; ObjectID = \"DNl-wA-6Sa\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "File" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -923,14 +601,7 @@ }, "dtP-tJ-UZV.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Enter Full Screen\"; ObjectID = \"dtP-tJ-UZV\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Enter Full Screen" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -941,14 +612,7 @@ }, "ehZ-YL-v7x.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Show Ruler\"; ObjectID = \"ehZ-YL-v7x\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Show Ruler" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -959,14 +623,7 @@ }, "eIi-Yp-9Iw.title" : { "comment" : "Class = \"NSMenu\"; title = \"Shortcut\"; ObjectID = \"eIi-Yp-9Iw\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Shortcut" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -977,14 +634,7 @@ }, "fbP-W7-rZr.title" : { "comment" : "Class = \"NSMenu\"; title = \"Format\"; ObjectID = \"fbP-W7-rZr\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Format" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -995,14 +645,7 @@ }, "FCw-Hu-PgK.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Smart Dashes\"; ObjectID = \"FCw-Hu-PgK\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Smart Dashes" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1013,14 +656,7 @@ }, "fdh-pr-pKq.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Use None\"; ObjectID = \"fdh-pr-pKq\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Use None" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1031,14 +667,7 @@ }, "FEQ-lS-XY2.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Copy Style\"; ObjectID = \"FEQ-lS-XY2\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Copy Style" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1049,14 +678,7 @@ }, "Fju-GT-JhG.title" : { "comment" : "Class = \"NSMenu\"; title = \"Edit\"; ObjectID = \"Fju-GT-JhG\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Edit" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1067,14 +689,7 @@ }, "fLW-HH-8Jl.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Clear Menu\"; ObjectID = \"fLW-HH-8Jl\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Clear Menu" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1085,14 +700,7 @@ }, "fmz-2f-99L.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Italic\"; ObjectID = \"fmz-2f-99L\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Italic" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1102,32 +710,25 @@ } }, "Fzj-Rh-cL0.title" : { - "comment" : "Class = \"NSMenuItem\"; title = \"偏好设置\"; ObjectID = \"Fzj-Rh-cL0\";", + "comment" : "Class = \"NSMenuItem\"; title = \"设置...\"; ObjectID = \"Fzj-Rh-cL0\";", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "Preferences" + "value" : "Settings..." } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "偏好设置" + "value" : "设置..." } } } }, "g1Y-HC-Hcm.ibShadowedToolTip" : { "comment" : "Class = \"NSMenuItem\"; ibShadowedToolTip = \"Pin Window\"; ObjectID = \"g1Y-HC-Hcm\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Pin Window" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1138,14 +739,7 @@ }, "g1Y-HC-Hcm.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Pin\"; ObjectID = \"g1Y-HC-Hcm\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Pin" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1156,14 +750,7 @@ }, "gGk-gP-JTi.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Copy\"; ObjectID = \"gGk-gP-JTi\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Copy" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1174,14 +761,7 @@ }, "gMd-iF-vmG.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Subscript\"; ObjectID = \"gMd-iF-vmG\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Subscript" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1209,14 +789,7 @@ }, "h3E-8k-Kcu.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Redo\"; ObjectID = \"h3E-8k-Kcu\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Redo" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1227,14 +800,7 @@ }, "H59-hx-Liq.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Find and Replace…\"; ObjectID = \"H59-hx-Liq\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Find and Replace…" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1245,14 +811,7 @@ }, "hBq-I4-3GU.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Smart Links\"; ObjectID = \"hBq-I4-3GU\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Smart Links" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1263,14 +822,7 @@ }, "hfb-pI-P93.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Transformations\"; ObjectID = \"hfb-pI-P93\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Transformations" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1281,14 +833,7 @@ }, "Hk7-HT-5mY.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"\\tDefault\"; ObjectID = \"Hk7-HT-5mY\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "\tDefault" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1299,14 +844,7 @@ }, "hrx-hU-Stg.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Show Spelling and Grammar\"; ObjectID = \"hrx-hU-Stg\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Show Spelling and Grammar" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1317,14 +855,7 @@ }, "HWT-Jw-PfX.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Superscript\"; ObjectID = \"HWT-Jw-PfX\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Superscript" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1335,14 +866,7 @@ }, "I7U-ax-TZQ.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Lower\"; ObjectID = \"I7U-ax-TZQ\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Lower" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1353,14 +877,7 @@ }, "I8A-qR-Op7.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Cut\"; ObjectID = \"I8A-qR-Op7\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Cut" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1388,14 +905,7 @@ }, "IWX-7r-RUj.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Find Next\"; ObjectID = \"IWX-7r-RUj\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Find Next" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1406,14 +916,7 @@ }, "iXN-BE-e7t.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Smaller\"; ObjectID = \"iXN-BE-e7t\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Smaller" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1424,14 +927,7 @@ }, "J5J-YV-4ty.title" : { "comment" : "Class = \"NSMenu\"; title = \"Kern\"; ObjectID = \"J5J-YV-4ty\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Kern" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1442,15 +938,8 @@ }, "jbe-2v-aJG.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Spelling and Grammar\"; ObjectID = \"jbe-2v-aJG\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Spelling and Grammar" - } - }, - "zh-Hans" : { + "zh-Hans" : { "stringUnit" : { "state" : "translated", "value" : "Spelling and Grammar" @@ -1479,7 +968,7 @@ "comment" : "Class = \"NSMenuItem\"; ibShadowedToolTip = \"Open in Eudic\"; ObjectID = \"KbN-5H-9z5\";", "extractionState" : "extracted_with_value", "localizations" : { - "en" : { + "zh-Hans" : { "stringUnit" : { "state" : "new", "value" : "Open in Eudic" @@ -1491,7 +980,7 @@ "comment" : "Class = \"NSMenuItem\"; title = \"Apple Dictionary\"; ObjectID = \"KbN-5H-9z5\";", "extractionState" : "extracted_with_value", "localizations" : { - "en" : { + "zh-Hans" : { "stringUnit" : { "state" : "new", "value" : "Apple Dictionary" @@ -1501,14 +990,7 @@ }, "KJd-o4-nm1.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Baseline\"; ObjectID = \"KJd-o4-nm1\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Baseline" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1519,14 +1001,7 @@ }, "kw1-qQ-nI8.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Smart Copy/Paste\"; ObjectID = \"kw1-qQ-nI8\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Smart Copy/Paste" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1537,14 +1012,7 @@ }, "LaS-Ex-XQs.title" : { "comment" : "Class = \"NSMenu\"; title = \"Writing Direction\"; ObjectID = \"LaS-Ex-XQs\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Writing Direction" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1555,14 +1023,7 @@ }, "lFU-de-f4a.title" : { "comment" : "Class = \"NSMenu\"; title = \"Substitutions\"; ObjectID = \"lFU-de-f4a\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Substitutions" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1573,14 +1034,7 @@ }, "Lki-tx-Lq5.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Format\"; ObjectID = \"Lki-tx-Lq5\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Format" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1593,7 +1047,7 @@ "comment" : "Class = \"NSMenuItem\"; ibShadowedToolTip = \"Copy Query Text\"; ObjectID = \"Lq3-CB-sQ6\";", "extractionState" : "extracted_with_value", "localizations" : { - "en" : { + "zh-Hans" : { "stringUnit" : { "state" : "new", "value" : "Copy Query Text" @@ -1605,7 +1059,7 @@ "comment" : "Class = \"NSMenuItem\"; title = \"Copy\"; ObjectID = \"Lq3-CB-sQ6\";", "extractionState" : "extracted_with_value", "localizations" : { - "en" : { + "zh-Hans" : { "stringUnit" : { "state" : "new", "value" : "Copy" @@ -1632,14 +1086,7 @@ }, "Lze-X3-X4H.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Paste\"; ObjectID = \"Lze-X3-X4H\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Paste" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1650,14 +1097,7 @@ }, "M5e-02-Qvj.title" : { "comment" : "Class = \"NSMenu\"; title = \"Easydict\"; ObjectID = \"M5e-02-Qvj\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Easydict" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1668,14 +1108,7 @@ }, "MfP-Gx-Wn8.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Smart Quotes\"; ObjectID = \"MfP-Gx-Wn8\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Smart Quotes" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1686,14 +1119,7 @@ }, "mnj-j0-7uG.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Open…\"; ObjectID = \"mnj-j0-7uG\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Open…" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1704,14 +1130,7 @@ }, "n5Z-fW-q2A.title" : { "comment" : "Class = \"NSMenu\"; title = \"Font\"; ObjectID = \"n5Z-fW-q2A\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Font" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1722,14 +1141,7 @@ }, "N8G-VW-gCf.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Center\"; ObjectID = \"N8G-VW-gCf\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Center" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1740,14 +1152,7 @@ }, "nlT-56-GWa.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Justify\"; ObjectID = \"nlT-56-GWa\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Justify" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1758,14 +1163,7 @@ }, "NuA-WI-yNk.ibShadowedToolTip" : { "comment" : "Class = \"NSMenuItem\"; ibShadowedToolTip = \"Foucs Input\"; ObjectID = \"NuA-WI-yNk\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Foucs Input" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1776,14 +1174,7 @@ }, "NuA-WI-yNk.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Focus\"; ObjectID = \"NuA-WI-yNk\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Focus" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1794,14 +1185,7 @@ }, "nWO-3y-d80.title" : { "comment" : "Class = \"NSMenu\"; title = \"Ligatures\"; ObjectID = \"nWO-3y-d80\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Ligatures" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1812,14 +1196,7 @@ }, "O8g-2J-P7F.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"\\tLeft to Right\"; ObjectID = \"O8g-2J-P7F\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "\tLeft to Right" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1830,14 +1207,7 @@ }, "OaB-i7-GKE.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Use All\"; ObjectID = \"OaB-i7-GKE\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Use All" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1848,14 +1218,7 @@ }, "ojC-fT-Nd9.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Paragraph\"; ObjectID = \"ojC-fT-Nd9\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Paragraph" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1866,14 +1229,7 @@ }, "omU-aR-9Dn.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Open Recent\"; ObjectID = \"omU-aR-9Dn\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Open Recent" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1884,14 +1240,7 @@ }, "oz1-ny-V93.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"About Easydict\"; ObjectID = \"oz1-ny-V93\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "About Easydict" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1902,14 +1251,7 @@ }, "P4l-Nh-yAL.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Stop Speaking\"; ObjectID = \"P4l-Nh-yAL\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Stop Speaking" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1920,14 +1262,7 @@ }, "p8l-cp-Ck7.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Underline\"; ObjectID = \"p8l-cp-Ck7\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Underline" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1938,14 +1273,7 @@ }, "P23-w4-X2h.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Copy Ruler\"; ObjectID = \"P23-w4-X2h\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Copy Ruler" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1956,14 +1284,7 @@ }, "pBe-oc-b5O.ibShadowedToolTip" : { "comment" : "Class = \"NSMenuItem\"; ibShadowedToolTip = \"Retry Query\"; ObjectID = \"pBe-oc-b5O\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Retry Query" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1974,14 +1295,7 @@ }, "pBe-oc-b5O.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Retry\"; ObjectID = \"pBe-oc-b5O\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Retry" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1992,14 +1306,7 @@ }, "pdu-F1-8Tf.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Zoom\"; ObjectID = \"pdu-F1-8Tf\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Zoom" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2010,14 +1317,7 @@ }, "PkP-25-JBw.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Easydict\"; ObjectID = \"PkP-25-JBw\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Easydict" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2045,14 +1345,7 @@ }, "PwY-WS-D9w.title" : { "comment" : "Class = \"NSMenu\"; title = \"Help\"; ObjectID = \"PwY-WS-D9w\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Help" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2063,14 +1356,7 @@ }, "PyB-Zr-Vwk.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Help\"; ObjectID = \"PyB-Zr-Vwk\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Help" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2098,14 +1384,7 @@ }, "q9d-pu-sQs.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Show All\"; ObjectID = \"q9d-pu-sQs\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Show All" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2116,14 +1395,7 @@ }, "qfO-cp-Tz9.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Writing Direction\"; ObjectID = \"qfO-cp-Tz9\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Writing Direction" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2134,14 +1406,7 @@ }, "QGo-r1-cSg.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Services\"; ObjectID = \"QGo-r1-cSg\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Services" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2152,14 +1417,7 @@ }, "qiF-2J-X2C.ibShadowedToolTip" : { "comment" : "Class = \"NSMenuItem\"; ibShadowedToolTip = \"Open in Google\"; ObjectID = \"qiF-2J-X2C\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Open in Google" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2170,14 +1428,7 @@ }, "qiF-2J-X2C.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Google\"; ObjectID = \"qiF-2J-X2C\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Google" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2188,17 +1439,10 @@ }, "qJD-6c-AHu.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Substitutions\"; ObjectID = \"qJD-6c-AHu\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { + "zh-Hans" : { "stringUnit" : { - "state" : "new", - "value" : "Substitutions" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", + "state" : "translated", "value" : "Substitutions" } } @@ -2206,14 +1450,7 @@ }, "qVV-ik-aTy.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"New\"; ObjectID = \"qVV-ik-aTy\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "New" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2224,14 +1461,7 @@ }, "qW5-1c-IcG.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Tighten\"; ObjectID = \"qW5-1c-IcG\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Tighten" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2242,14 +1472,7 @@ }, "Qy8-pe-t8t.title" : { "comment" : "Class = \"NSMenu\"; title = \"Transformations\"; ObjectID = \"Qy8-pe-t8t\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Transformations" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2260,14 +1483,7 @@ }, "Rcs-Bz-EcV.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Selection\"; ObjectID = \"Rcs-Bz-EcV\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Selection" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2278,14 +1494,7 @@ }, "rfD-Xp-c2P.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Loosen\"; ObjectID = \"rfD-Xp-c2P\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Loosen" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2296,14 +1505,7 @@ }, "rI6-hF-f35.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Correct Spelling Automatically\"; ObjectID = \"rI6-hF-f35\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Correct Spelling Automatically" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2314,14 +1516,7 @@ }, "RNR-lM-tup.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Make Upper Case\"; ObjectID = \"RNR-lM-tup\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Make Upper Case" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2332,14 +1527,7 @@ }, "rr4-Iy-d6B.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Clear Input\"; ObjectID = \"rr4-Iy-d6B\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Clear Input" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2350,14 +1538,7 @@ }, "sBq-3U-c6D.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"\\tRight to Left\"; ObjectID = \"sBq-3U-c6D\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "\tRight to Left" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2368,14 +1549,7 @@ }, "Sk8-za-Z9A.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Data Detectors\"; ObjectID = \"Sk8-za-Z9A\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Data Detectors" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2386,14 +1560,7 @@ }, "SLj-GC-V01.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Hide Others\"; ObjectID = \"SLj-GC-V01\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Hide Others" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2404,14 +1571,7 @@ }, "soH-H3-gGE.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Raise\"; ObjectID = \"soH-H3-gGE\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Raise" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2422,14 +1582,7 @@ }, "SS3-CB-TLd.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Bring All to Front\"; ObjectID = \"SS3-CB-TLd\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Bring All to Front" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2440,14 +1593,7 @@ }, "sXT-M2-L5C.ibShadowedToolTip" : { "comment" : "Class = \"NSMenuItem\"; ibShadowedToolTip = \"Open in Eudic\"; ObjectID = \"sXT-M2-L5C\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Open in Eudic" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2458,14 +1604,7 @@ }, "sXT-M2-L5C.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Eudic\"; ObjectID = \"sXT-M2-L5C\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Eudic" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2476,14 +1615,7 @@ }, "T2j-FN-Qwc.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Bigger\"; ObjectID = \"T2j-FN-Qwc\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Bigger" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2494,14 +1626,7 @@ }, "tbU-fG-HxE.title" : { "comment" : "Class = \"NSMenu\"; title = \"Text\"; ObjectID = \"tbU-fG-HxE\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Text" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2512,14 +1637,7 @@ }, "TD1-rx-lx9.title" : { "comment" : "Class = \"NSMenu\"; title = \"View\"; ObjectID = \"TD1-rx-lx9\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "View" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2530,14 +1648,7 @@ }, "tDT-UH-FV1.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Align Left\"; ObjectID = \"tDT-UH-FV1\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Align Left" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2548,14 +1659,7 @@ }, "Tef-15-EkB.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Text\"; ObjectID = \"Tef-15-EkB\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Text" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2566,14 +1670,7 @@ }, "Tsl-tH-rJ8.title" : { "comment" : "Class = \"NSMenu\"; title = \"Open Recent\"; ObjectID = \"Tsl-tH-rJ8\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Open Recent" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2584,14 +1681,7 @@ }, "uaR-x8-DoB.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Minimize\"; ObjectID = \"uaR-x8-DoB\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Minimize" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2602,14 +1692,7 @@ }, "ujd-ZP-XzB.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Use Selection for Find\"; ObjectID = \"ujd-ZP-XzB\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Use Selection for Find" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2620,14 +1703,7 @@ }, "V6P-CY-xNs.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"\\tLeft to Right\"; ObjectID = \"V6P-CY-xNs\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "\tLeft to Right" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2638,14 +1714,7 @@ }, "V8b-cO-hn4.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Bold\"; ObjectID = \"V8b-cO-hn4\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Bold" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2656,14 +1725,7 @@ }, "VKd-zQ-pt5.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Make Lower Case\"; ObjectID = \"VKd-zQ-pt5\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Make Lower Case" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2673,19 +1735,12 @@ } }, "wgy-yj-uSV.title" : { - "comment" : "Class = \"NSMenuItem\"; title = \"Preferences…\"; ObjectID = \"wgy-yj-uSV\";", - "extractionState" : "extracted_with_value", + "comment" : "Class = \"NSMenuItem\"; title = \"Settings…\"; ObjectID = \"wgy-yj-uSV\";", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Preferences…" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "Preferences…" + "value" : "Settings…" } } } @@ -2709,14 +1764,7 @@ }, "Xq7-tZ-u65.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Align Right\"; ObjectID = \"Xq7-tZ-u65\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Align Right" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2727,14 +1775,7 @@ }, "xui-oA-tFk.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Use None\"; ObjectID = \"xui-oA-tFk\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Use None" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2745,14 +1786,7 @@ }, "xuj-Ac-VOd.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Paste and Match Style\"; ObjectID = \"xuj-Ac-VOd\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Paste and Match Style" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2763,14 +1797,7 @@ }, "xUx-7p-l0h.title" : { "comment" : "Class = \"NSMenu\"; title = \"Speech\"; ObjectID = \"xUx-7p-l0h\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Speech" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2781,14 +1808,7 @@ }, "Y6z-wn-ElJ.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Select All\"; ObjectID = \"Y6z-wn-ElJ\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Select All" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2799,14 +1819,7 @@ }, "Yd4-Cr-52d.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Edit\"; ObjectID = \"Yd4-Cr-52d\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Edit" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2817,14 +1830,7 @@ }, "YF0-bI-c58.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Shortcut\"; ObjectID = \"YF0-bI-c58\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Shortcut" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2835,14 +1841,7 @@ }, "YgC-B4-90f.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Check Document Now\"; ObjectID = \"YgC-B4-90f\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Check Document Now" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2853,14 +1852,7 @@ }, "yMd-CK-UoO.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Easydict Help\"; ObjectID = \"yMd-CK-UoO\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Easydict Help" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2888,14 +1880,7 @@ }, "zJj-ya-zFA.title" : { "comment" : "Class = \"NSMenu\"; title = \"Baseline\"; ObjectID = \"zJj-ya-zFA\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Baseline" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -2906,14 +1891,7 @@ }, "zJn-Z1-IWk.title" : { "comment" : "Class = \"NSMenuItem\"; title = \"Find…\"; ObjectID = \"zJn-Z1-IWk\";", - "extractionState" : "extracted_with_value", "localizations" : { - "en" : { - "stringUnit" : { - "state" : "new", - "value" : "Find…" - } - }, "zh-Hans" : { "stringUnit" : { "state" : "translated", diff --git a/Easydict/Feature/Configuration/EZConfiguration.m b/Easydict/Feature/Configuration/EZConfiguration.m index b1e52f250..9ee2d7c8b 100644 --- a/Easydict/Feature/Configuration/EZConfiguration.m +++ b/Easydict/Feature/Configuration/EZConfiguration.m @@ -14,6 +14,7 @@ #import "EZWindowManager.h" #import "EZScriptExecutor.h" #import "EZLog.h" +#import "EZLanguageManager.h" static NSString *const kEasydictHelperBundleId = @"com.izual.EasydictHelper"; @@ -77,9 +78,11 @@ + (instancetype)allocWithZone:(struct _NSZone *)zone { } - (void)setup { - self.firstLanguage = [NSUserDefaults mm_read:kFirstLanguageKey]; - self.secondLanguage = [NSUserDefaults mm_read:kSecondLanguageKey]; - + EZLanguage defaultFirstLanguage = [EZLanguageManager.shared systemPreferredLanguages][0]; + self.firstLanguage = [NSUserDefaults mm_readString:kFirstLanguageKey defaultValue:defaultFirstLanguage]; + EZLanguage defaultSecondLanguage = [EZLanguageManager.shared systemPreferredLanguages][1]; + self.secondLanguage = [NSUserDefaults mm_readString:kSecondLanguageKey defaultValue:defaultSecondLanguage]; + self.from = [NSUserDefaults mm_readString:kFromKey defaultValue:EZLanguageAuto]; self.to = [NSUserDefaults mm_readString:kToKey defaultValue:EZLanguageAuto]; @@ -127,235 +130,276 @@ - (BOOL)automaticallyChecksForUpdates { - (void)setFirstLanguage:(EZLanguage)firstLanguage { _firstLanguage = firstLanguage; - + [NSUserDefaults mm_write:firstLanguage forKey:kFirstLanguageKey]; if (firstLanguage) { - NSDictionary *parameters = @{ @"first_language" : firstLanguage }; - [EZLog logEventWithName:@"preferred_language" parameters:parameters]; + [self logSettings:@{@"first_language" : firstLanguage}]; } } - (void)setSecondLanguage:(EZLanguage)secondLanguage { _secondLanguage = secondLanguage; - + [NSUserDefaults mm_write:secondLanguage forKey:kSecondLanguageKey]; if (secondLanguage) { - NSDictionary *parameters = @{ @"second_language" : secondLanguage }; - [EZLog logEventWithName:@"preferred_language" parameters:parameters]; + [self logSettings:@{@"second_language" : secondLanguage}]; } } - (void)setFrom:(EZLanguage)from { _from = from; - + [NSUserDefaults mm_write:from forKey:kFromKey]; } - (void)setTo:(EZLanguage)to { _to = to; - + [NSUserDefaults mm_write:to forKey:kToKey]; } - (void)setAutoSelectText:(BOOL)autoSelectText { _autoSelectText = autoSelectText; - + [NSUserDefaults mm_write:@(autoSelectText) forKey:kAutoSelectTextKey]; + + [self logSettings:@{@"auto_select_sext" : @(autoSelectText)}]; } - (void)setForceAutoGetSelectedText:(BOOL)forceGetSelectedText { _forceAutoGetSelectedText = forceGetSelectedText; - + [NSUserDefaults mm_write:@(forceGetSelectedText) forKey:kForceAutoGetSelectedText]; + + [self logSettings:@{@"force_get_selected_text" : @(forceGetSelectedText)}]; } - (void)setDisableEmptyCopyBeep:(BOOL)disableEmptyCopyBeep { _disableEmptyCopyBeep = disableEmptyCopyBeep; - + [NSUserDefaults mm_write:@(disableEmptyCopyBeep) forKey:kDisableEmptyCopyBeepKey]; + + [self logSettings:@{@"disableEmptyCopyBeep" : @(disableEmptyCopyBeep)}]; } - (void)setClickQuery:(BOOL)clickQuery { _clickQuery = clickQuery; - + [NSUserDefaults mm_write:@(clickQuery) forKey:kClickQueryKey]; - + [EZWindowManager.shared updatePopButtonQueryAction]; + + [self logSettings:@{@"click_query" : @(clickQuery)}]; } - (void)setLaunchAtStartup:(BOOL)launchAtStartup { BOOL oldLaunchAtStartup = self.launchAtStartup; - + [NSUserDefaults mm_write:@(launchAtStartup) forKey:kLaunchAtStartupKey]; - + // Avoid redundant calls, run AppleScript will ask for permission, trigger notification. if (launchAtStartup != oldLaunchAtStartup) { [self updateLoginItemWithLaunchAtStartup:launchAtStartup]; } + + [self logSettings:@{@"launch_at_startup" : @(launchAtStartup)}]; } - (void)setAutomaticallyChecksForUpdates:(BOOL)automaticallyChecksForUpdates { [NSUserDefaults mm_write:@(automaticallyChecksForUpdates) forKey:kAutomaticallyChecksForUpdatesKey]; - + [[SUUpdater sharedUpdater] setAutomaticallyChecksForUpdates:automaticallyChecksForUpdates]; + + [self logSettings:@{@"automatically_checks_for_updates" : @(automaticallyChecksForUpdates)}]; } - (void)setHideMainWindow:(BOOL)hideMainWindow { _hideMainWindow = hideMainWindow; - + [NSUserDefaults mm_write:@(hideMainWindow) forKey:kHideMainWindowKey]; - + EZWindowManager *windowManager = EZWindowManager.shared; [windowManager updatePopButtonQueryAction]; if (hideMainWindow) { [windowManager closeMainWindowIfNeeded]; } + + [self logSettings:@{@"hide_main_window" : @(hideMainWindow)}]; } - (void)setAutoQueryOCRText:(BOOL)autoSnipTranslate { _autoQueryOCRText = autoSnipTranslate; - + [NSUserDefaults mm_write:@(autoSnipTranslate) forKey:kAutoQueryOCTTextKey]; + + [self logSettings:@{@"auto_query_ocr_text" : @(autoSnipTranslate)}]; } - (void)setAutoQuerySelectedText:(BOOL)autoQuerySelectedText { _autoQuerySelectedText = autoQuerySelectedText; - + [NSUserDefaults mm_write:@(autoQuerySelectedText) forKey:kAutoQuerySelectedTextKey]; + + [self logSettings:@{@"auto_query_selected_text" : @(autoQuerySelectedText)}]; } - (void)setAutoQueryPastedText:(BOOL)autoQueryPastedText { _autoQueryPastedText = autoQueryPastedText; - + [NSUserDefaults mm_write:@(autoQueryPastedText) forKey:kAutoQueryPastedTextKey]; + + [self logSettings:@{@"auto_query_pasted_text" : @(autoQueryPastedText)}]; } - (void)setAutoCopyFirstTranslatedText:(BOOL)autoCopyFirstTranslatedText { _autoCopyFirstTranslatedText = autoCopyFirstTranslatedText; - + [NSUserDefaults mm_write:@(autoCopyFirstTranslatedText) forKey:kAutoCopyFirstTranslatedTextKey]; + + [self logSettings:@{@"auto_copy_first_translated_text" : @(autoCopyFirstTranslatedText)}]; } - (void)setAutoPlayAudio:(BOOL)autoPlayAudio { _autoPlayAudio = autoPlayAudio; - + [NSUserDefaults mm_write:@(autoPlayAudio) forKey:kAutoPlayAudioKey]; + + [self logSettings:@{@"auto_play_word_audio" : @(autoPlayAudio)}]; } - (void)setAutoCopySelectedText:(BOOL)autoCopySelectedText { _autoCopySelectedText = autoCopySelectedText; - + [NSUserDefaults mm_write:@(autoCopySelectedText) forKey:kAutoCopySelectedTextKey]; + + [self logSettings:@{@"auto_copy_selected_text" : @(autoCopySelectedText)}]; } - (void)setAutoCopyOCRText:(BOOL)autoCopyOCRText { _autoCopyOCRText = autoCopyOCRText; - + [NSUserDefaults mm_write:@(autoCopyOCRText) forKey:kAutoCopyOCRTextKey]; + + [self logSettings:@{@"auto_copy_ocr_text" : @(autoCopyOCRText)}]; } - (void)setLanguageDetectOptimize:(EZLanguageDetectOptimize)languageDetectOptimizeType { _languageDetectOptimize = languageDetectOptimizeType; - + [NSUserDefaults mm_write:@(languageDetectOptimizeType) forKey:kLanguageDetectOptimizeTypeKey]; + + [self logSettings:@{@"detect_optimize" : @(languageDetectOptimizeType)}]; } - (void)setDefaultTTSServiceType:(EZServiceType)defaultTTSServiceType { _defaultTTSServiceType = defaultTTSServiceType; [NSUserDefaults mm_write:defaultTTSServiceType forKey:kDefaultTTSServiceTypeKey]; - NSDictionary *parameters = @{ @"new" : defaultTTSServiceType }; - [EZLog logEventWithName:@"tts" parameters:parameters]; + [self logSettings:@{@"tts" : defaultTTSServiceType}]; } - (void)setShowGoogleQuickLink:(BOOL)showGoogleLink { _showGoogleQuickLink = showGoogleLink; - + [NSUserDefaults mm_write:@(showGoogleLink) forKey:kShowGoogleLinkKey]; [self postUpdateQuickLinkButtonNotification]; - + EZMenuItemManager.shared.googleItem.hidden = !showGoogleLink; + + [self logSettings:@{@"show_google_link" : @(showGoogleLink)}]; } - (void)setShowEudicQuickLink:(BOOL)showEudicLink { _showEudicQuickLink = showEudicLink; - + [NSUserDefaults mm_write:@(showEudicLink) forKey:kShowEudicLinkKey]; [self postUpdateQuickLinkButtonNotification]; - + EZMenuItemManager.shared.eudicItem.hidden = !showEudicLink; + + [self logSettings:@{@"show_eudic_link" : @(showEudicLink)}]; } - (void)setShowAppleDictionaryQuickLink:(BOOL)showAppleDictionaryQuickLink { _showAppleDictionaryQuickLink = showAppleDictionaryQuickLink; - + [NSUserDefaults mm_write:@(showAppleDictionaryQuickLink) forKey:kShowAppleDictionaryLinkKey]; [self postUpdateQuickLinkButtonNotification]; EZMenuItemManager.shared.appleDictionaryItem.hidden = !showAppleDictionaryQuickLink; + + [self logSettings:@{@"show_apple_dictionary_link" : @(showAppleDictionaryQuickLink)}]; } - (void)setHideMenuBarIcon:(BOOL)hideMenuBarIcon { _hideMenuBarIcon = hideMenuBarIcon; - + [NSUserDefaults mm_write:@(hideMenuBarIcon) forKey:kHideMenuBarIconKey]; - + [self hideMenuBarIcon:hideMenuBarIcon]; + + [self logSettings:@{@"hide_menu_bar_icon" : @(hideMenuBarIcon)}]; } - (void)setFixedWindowPosition:(EZShowWindowPosition)showFixedWindowPosition { _fixedWindowPosition = showFixedWindowPosition; - + [NSUserDefaults mm_write:@(showFixedWindowPosition) forKey:kShowFixedWindowPositionKey]; - NSDictionary *parameters = @{ @"fixed_window" : @(showFixedWindowPosition) }; - [EZLog logEventWithName:@"window_position" parameters:parameters]; + [self logSettings:@{@"show_fixed_window_position" : @(showFixedWindowPosition)}]; } - (void)setMouseSelectTranslateWindowType:(EZWindowType)mouseSelectTranslateWindowType { _mouseSelectTranslateWindowType = mouseSelectTranslateWindowType; - + [NSUserDefaults mm_write:@(mouseSelectTranslateWindowType) forKey:(kMouseSelectTranslateWindowTypeKey)]; - NSDictionary *parameters = @{ @"mouse_window" : @(mouseSelectTranslateWindowType) }; - [EZLog logEventWithName:@"show_window_type" parameters:parameters]; + [self logSettings:@{@"show_mouse_window_type" : @(mouseSelectTranslateWindowType)}]; } - (void)setShortcutSelectTranslateWindowType:(EZWindowType)shortcutSelectTranslateWindowType { _shortcutSelectTranslateWindowType = shortcutSelectTranslateWindowType; - + [NSUserDefaults mm_write:@(shortcutSelectTranslateWindowType) forKey:(kShortcutSelectTranslateWindowTypeKey)]; - NSDictionary *parameters = @{ @"shortcut_window" : @(shortcutSelectTranslateWindowType) }; - [EZLog logEventWithName:@"show_window_type" parameters:parameters]; + [self logSettings:@{@"show_shortcut_window_type" : @(shortcutSelectTranslateWindowType)}]; } - (void)setAdjustPopButtomOrigin:(BOOL)adjustPopButtomOrigin { _adjustPopButtomOrigin = adjustPopButtomOrigin; - + [NSUserDefaults mm_write:@(adjustPopButtomOrigin) forKey:kAdjustPopButtomOriginKey]; + + [self logSettings:@{@"adjust_pop_buttom_origin" : @(adjustPopButtomOrigin)}]; } - (void)setAllowCrashLog:(BOOL)allowCrashLog { _allowCrashLog = allowCrashLog; - + [NSUserDefaults mm_write:@(allowCrashLog) forKey:kAllowCrashLogKey]; + + [self logSettings:@{@"allow_crash_log" : @(allowCrashLog)}]; + [EZLog setCrashEnabled:allowCrashLog]; } - (void)setAllowAnalytics:(BOOL)allowAnalytics { _allowAnalytics = allowAnalytics; - + [NSUserDefaults mm_write:@(allowAnalytics) forKey:kAllowAnalyticsKey]; + + [self logSettings:@{@"allow_analytics" : @(allowAnalytics)}]; } - (void)setClearInput:(BOOL)clearInput { _clearInput = clearInput; - + [NSUserDefaults mm_write:@(clearInput) forKey:kClearInputKey]; + + [self logSettings:@{@"clear_input" : @(clearInput)}]; } @@ -385,7 +429,7 @@ - (void)updateLoginItemWithLaunchAtStartup:(BOOL)launchAtStartup { // ???: name is CFBundleExecutable, or CFBundleName ? NSString *appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleExecutable"]; NSString *appBundlePath = [[NSBundle mainBundle] bundlePath]; - + NSString *script = [NSString stringWithFormat:@"\ tell application \"System Events\" to get the name of every login item\n\ tell application \"System Events\"\n\ @@ -399,9 +443,9 @@ - (void)updateLoginItemWithLaunchAtStartup:(BOOL)launchAtStartup { make login item at end with properties {path:\"%@\", hidden:false}\n\ end if\n\ end tell", appName, - launchAtStartup ? @"true" : @"false", - appBundlePath]; - + launchAtStartup ? @"true" : @"false", + appBundlePath]; + EZScriptExecutor *exeCommand = [[EZScriptExecutor alloc] init]; [exeCommand runAppleScriptWithTask:script completionHandler:^(NSString *_Nonnull result, NSError *_Nonnull error) { if (error) { @@ -458,12 +502,12 @@ - (void)updateLoginItemWithLaunchAtStartup:(BOOL)launchAtStartup { - (BOOL)isLoginItemEnabled { BOOL enabled = NO; - + #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" CFArrayRef loginItems = SMCopyAllJobDictionaries(kSMDomainUserLaunchd); #pragma clang diagnostic pop - + NSString *helperBundleId = [self helperBundleId]; for (id item in (__bridge NSArray *)loginItems) { if ([[[item objectForKey:@"Label"] description] isEqualToString:helperBundleId]) { @@ -508,6 +552,12 @@ - (void)setIntelligentQueryMode:(BOOL)enabled windowType:(EZWindowType)windowTyp NSString *key = [EZConstKey constkey:EZIntelligentQueryModeKey windowType:windowType]; NSString *stringValue = [NSString stringWithFormat:@"%d", enabled]; [NSUserDefaults mm_write:stringValue forKey:key]; + + NSDictionary *parameters = @{ + @"enabled" : @(enabled), + @"window_type" : @(windowType), + }; + [EZLog logEventWithName:@"intelligent_query_mode" parameters:parameters]; } - (BOOL)intelligentQueryModeForWindowType:(EZWindowType)windowType { NSString *key = [EZConstKey constkey:EZIntelligentQueryModeKey windowType:windowType]; @@ -569,8 +619,11 @@ - (BOOL)isBeta { - (void)enableBetaFeaturesIfNeeded { if ([self isBeta]) { - } } +- (void)logSettings:(NSDictionary *)parameters { + [EZLog logEventWithName:@"settings" parameters:parameters]; +} + @end diff --git a/Easydict/Feature/EventMonitor/EZEventMonitor.h b/Easydict/Feature/EventMonitor/EZEventMonitor.h index f07caa1af..ece0afd8d 100644 --- a/Easydict/Feature/EventMonitor/EZEventMonitor.h +++ b/Easydict/Feature/EventMonitor/EZEventMonitor.h @@ -18,7 +18,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, copy) EZSelectTextType selectTextType; @property (nonatomic, assign) EZTriggerType triggerType; -@property (nonatomic, strong) NSRunningApplication *frontmostApplication; +@property (nonatomic, strong, nullable) NSRunningApplication *frontmostApplication; @property (nonatomic, copy, nullable) NSString *browserTabURLString; @property (nonatomic, assign) CGRect selectedTextFrame; diff --git a/Easydict/Feature/Libraries/DictionaryKit/TTTDictionary.m b/Easydict/Feature/Libraries/DictionaryKit/TTTDictionary.m index 0e1517a0c..9267e8fd6 100644 --- a/Easydict/Feature/Libraries/DictionaryKit/TTTDictionary.m +++ b/Easydict/Feature/Libraries/DictionaryKit/TTTDictionary.m @@ -36,55 +36,55 @@ // Simplified Chinese -NSString *const DCSSimplifiedChineseDictionaryName = @"现代汉语规范词典"; // 简体中文 -NSString *const DCSSimplifiedChineseIdiomDictionaryName = @"汉语成语词典"; // 简体中文成语 -NSString *const DCSSimplifiedChineseThesaurusDictionaryName = @"现代汉语同义词典"; // 简体中文同义词词典 -NSString *const DCSSimplifiedChinese_EnglishDictionaryName = @"牛津英汉汉英词典"; // 简体中文-英文 +NSString *const DCSSimplifiedChineseDictionaryName = @"现代汉语规范词典"; // 简体中文 +NSString *const DCSSimplifiedChineseIdiomDictionaryName = @"汉语成语词典"; // 简体中文成语 +NSString *const DCSSimplifiedChineseThesaurusDictionaryName = @"现代汉语同义词典"; // 简体中文同义词词典 +NSString *const DCSSimplifiedChinese_EnglishDictionaryName = @"牛津英汉汉英词典"; // 简体中文-英文 NSString *const DCSSimplifiedChinese_JapaneseDictionaryName = @"超級クラウン中日辞典 / クラウン日中辞典"; // 简体中文-日文 // Traditional Chinese -NSString *const DCSTraditionalChineseDictionaryName = @"五南國語活用辭典"; // 繁体中文 -NSString *const DCSTraditionalChineseHongkongDictionaryName = @"商務新詞典(全新版)"; // 繁体中文(香港) -NSString *const DCSTraditionalChinese_EnglishDictionaryName = @"譯典通英漢雙向字典"; // 繁体中文-英文 +NSString *const DCSTraditionalChineseDictionaryName = @"五南國語活用辭典"; // 繁体中文 +NSString *const DCSTraditionalChineseHongkongDictionaryName = @"商務新詞典(全新版)"; // 繁体中文(香港) +NSString *const DCSTraditionalChinese_EnglishDictionaryName = @"譯典通英漢雙向字典"; // 繁体中文-英文 NSString *const DCSTraditionalChinese_EnglishIdiomDictionaryName = @"漢英對照成語詞典"; // 繁体中文-英文习语 // English -NSString *const DCSNewOxfordAmericanDictionaryName = @"New Oxford American Dictionary"; // 美式英文 +NSString *const DCSNewOxfordAmericanDictionaryName = @"New Oxford American Dictionary"; // 美式英文 NSString *const DCSOxfordAmericanWritersThesaurus = @"Oxford American Writer’s Thesaurus"; // 美式英文同义词词典 -NSString *const DCSOxfordDictionaryOfEnglish = @"Oxford Dictionary of English"; // 英式英文 -NSString *const DCSOxfordThesaurusOfEnglish = @"Oxford Thesaurus of English"; // 英式英文同义词词典 +NSString *const DCSOxfordDictionaryOfEnglish = @"Oxford Dictionary of English"; // 英式英文 +NSString *const DCSOxfordThesaurusOfEnglish = @"Oxford Thesaurus of English"; // 英式英文同义词词典 // Japanese -NSString *const DCSJapaneseDictionaryName = @"スーパー大辞林"; // 日文 +NSString *const DCSJapaneseDictionaryName = @"スーパー大辞林"; // 日文 NSString *const DCSJapanese_EnglishDictionaryName = @"ウィズダム英和辞典 / ウィズダム和英辞典"; // 日文-英文 // French -NSString *const DCSFrenchDictionaryName = @"Multidictionnaire de la langue française"; // 法文 -NSString *const DCSFrench_EnglishDictionaryName = @"Oxford-Hachette French Dictionary"; // 法文-英文 +NSString *const DCSFrenchDictionaryName = @"Multidictionnaire de la langue française"; // 法文 +NSString *const DCSFrench_EnglishDictionaryName = @"Oxford-Hachette French Dictionary"; // 法文-英文 NSString *const DCSFrench_GermanDictionaryName = @"ONS Großwörterbuch Französisch Deutsch"; // 法文-德文 // German NSString *const DCSGermanDictionaryName = @"Duden-Wissensnetz deutsche Sprache"; // 德文 -NSString *const DCSGerman_EnglishDictionaryName = @"Oxford German Dictionary"; // 德文-英文 +NSString *const DCSGerman_EnglishDictionaryName = @"Oxford German Dictionary"; // 德文-英文 // Italian -NSString *const DCSItalianDictionaryName = @"Dizionario italiano da un affiliato di Oxford University Press"; // 意大利文 +NSString *const DCSItalianDictionaryName = @"Dizionario italiano da un affiliato di Oxford University Press"; // 意大利文 NSString *const DCSItalian_EnglishDictionaryName = @"Oxford Paravia Il Dizionario inglese - italiano/italiano - inglese"; // 意大利文-英文 // Spanish -NSString *const DCSSpanishDictionaryName = @"Diccionario General de la Lengua Española Vox"; // 西班牙文 +NSString *const DCSSpanishDictionaryName = @"Diccionario General de la Lengua Española Vox"; // 西班牙文 NSString *const DCSSpanish_EnglishDictionaryName = @"Gran Diccionario Oxford - Español-Inglés • Inglés-Español"; // 西班牙文-英文 // Portugues -NSString *const DCSPortugueseDictionaryName = @"Dicionário de Português licenciado para Oxford University Press";// 葡萄牙文 +NSString *const DCSPortugueseDictionaryName = @"Dicionário de Português licenciado para Oxford University Press"; // 葡萄牙文 NSString *const DCSPortuguese_EnglishDictionaryName = @"Oxford Portuguese Dictionary - Português-Inglês • Inglês-Português"; // 葡萄牙文-英文 // Dutch -NSString *const DCSDutchDictionaryName = @"Prisma woordenboek Nederlands"; // 荷兰文 +NSString *const DCSDutchDictionaryName = @"Prisma woordenboek Nederlands"; // 荷兰文 NSString *const DCSDutch_EnglishDictionaryName = @"Prisma Handwoordenboek Engels"; // 荷兰文-英文 // Korean -NSString *const DCSKoreanDictionaryName = @"New Ace Korean Language Dictionary"; // 韩文 +NSString *const DCSKoreanDictionaryName = @"New Ace Korean Language Dictionary"; // 韩文 NSString *const DCSKorean_EnglishDictionaryName = @"뉴에이스 영한사전 / 뉴에이스 한영사전"; // 韩文-英文 NSString *const DCSWikipediaDictionaryName = @"维基百科"; @@ -103,7 +103,7 @@ typedef NS_ENUM(NSInteger, TTTDictionaryRecordVersion) { extern CFStringRef DCSDictionaryGetName(DCSDictionaryRef dictionary); extern CFStringRef DCSDictionaryGetShortName(DCSDictionaryRef dictionary); extern DCSDictionaryRef DCSDictionaryCreate(CFURLRef url); -//extern CFArrayRef DCSCopyRecordsForSearchString(DCSDictionaryRef dictionary, CFStringRef string, void *, void *); +// extern CFArrayRef DCSCopyRecordsForSearchString(DCSDictionaryRef dictionary, CFStringRef string, void *, void *); extern CFDictionaryRef DCSCopyDefinitionMarkup(DCSDictionaryRef dictionary, CFStringRef record); extern CFStringRef DCSRecordCopyData(CFTypeRef record, long version); @@ -119,12 +119,12 @@ typedef NS_ENUM(NSInteger, TTTDictionaryRecordVersion) { // Ref: https://discussions.apple.com/thread/6616776?answerId=26923349022#26923349022 and https://github.com/lipidity/CLIMac/blob/master/src/dictctl.c#L12 extern CFArrayRef DCSGetActiveDictionaries(void); -//extern CFSetRef DCSCopyAvailableDictionaries(void); +// extern CFSetRef DCSCopyAvailableDictionaries(void); extern DCSDictionaryRef DCSGetDefaultDictionary(void); extern DCSDictionaryRef DCSGetDefaultThesaurus(void); extern DCSDictionaryRef DCSDictionaryCreate(CFURLRef); extern CFURLRef DCSDictionaryGetURL(DCSDictionaryRef); -//extern CFStringRef DCSDictionaryGetName(DCSDictionaryRef); +// extern CFStringRef DCSDictionaryGetName(DCSDictionaryRef); extern CFStringRef DCSDictionaryGetIdentifier(DCSDictionaryRef); /** @@ -155,23 +155,22 @@ @interface TTTDictionaryEntry () @implementation TTTDictionaryEntry - (instancetype)initWithRecordRef:(CFTypeRef)record - dictionaryRef:(DCSDictionaryRef)dictionary -{ + dictionaryRef:(DCSDictionaryRef)dictionary { self = [self init]; if (!self && record) { return nil; } - + // ???: __bridge_transfer will cause crash, but why? self.headword = (__bridge NSString *)DCSRecordGetHeadword(record); if (self.headword) { - self.text = (__bridge_transfer NSString*)DCSRecordCopyData(record, TTTDictionaryVersionText); + self.text = (__bridge_transfer NSString *)DCSRecordCopyData(record, TTTDictionaryVersionText); } self.HTML = (__bridge_transfer NSString *)DCSRecordCopyData(record, (long)TTTDictionaryVersionHTML); self.HTMLWithAppCSS = (__bridge_transfer NSString *)DCSRecordCopyData(record, (long)TTTDictionaryVersionHTMLWithAppCSS); self.HTMLWithPopoverCSS = (__bridge_transfer NSString *)DCSRecordCopyData(record, (long)TTTDictionaryVersionHTMLWithPopoverCSS); - + return self; } @@ -197,17 +196,17 @@ @implementation TTTDictionary + (instancetype)dictionaryNamed:(NSString *)name { static NSDictionary *_availableDictionariesKeyedByName = nil; - + static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSMutableDictionary *mutableAvailableDictionariesKeyedByName = [NSMutableDictionary dictionaryWithCapacity:[[self availableDictionaries] count]]; for (TTTDictionary *dictionary in [self availableDictionaries]) { mutableAvailableDictionariesKeyedByName[dictionary.name] = dictionary; } - + _availableDictionariesKeyedByName = [NSDictionary dictionaryWithDictionary:mutableAvailableDictionariesKeyedByName]; }); - + return _availableDictionariesKeyedByName[name]; } @@ -227,7 +226,6 @@ + (instancetype)dictionaryNamed:(NSString *)name { /// Active dictionaries are dictionaries that are currently enabled in Dictionary.app + (NSArray *)activeDictionaries { - // !!!: DCSGetActiveDictionaries() can only invoke once, otherwise it will crash. So we must use static variable to cache the result. static NSArray *_activeDictionaries = nil; @@ -240,7 +238,7 @@ + (instancetype)dictionaryNamed:(NSString *)name { } _activeDictionaries = [NSArray arrayWithArray:mutableActiveDictionaries]; }); - + return _activeDictionaries; } @@ -252,55 +250,22 @@ + (NSURL *)userDictionaryDirectoryURL { /// key: EZLanguage, value: language dict name + (MMOrderedDictionary *)languageToDictionaryNameMap { -// static NSDictionary *_languageToDictionaryNameMap = nil; static MMOrderedDictionary *_languageToDictionaryNameMap = nil; - - /** - MMOrderedDictionary *orderedDict = [[MMOrderedDictionary alloc] initWithKeysAndObjects: - EZLanguageSimplifiedChinese, @"zh-Hans", - EZLanguageTraditionalChinese, @"zh-Hant", - EZLanguageEnglish, @"en-US", - EZLanguageJapanese, @"ja-JP", - EZLanguageKorean, @"ko-KR", - EZLanguageFrench, @"fr-FR", - EZLanguageSpanish, @"es-ES", - EZLanguagePortuguese, @"pt-BR", - EZLanguageItalian, @"it-IT", - EZLanguageGerman, @"de-DE", - EZLanguageRussian, @"ru-RU", - EZLanguageUkrainian, @"uk-UA", - nil]; - */ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ -// _languageToDictionaryNameMap = @{ -// EZLanguageSimplifiedChinese : DCSSimplifiedChineseDictionaryName, -// EZLanguageTraditionalChinese : DCSTraditionalChineseDictionaryName, -// EZLanguageEnglish: DCSNewOxfordAmericanDictionaryName, -// EZLanguageJapanese : DCSJapaneseDictionaryName, -// EZLanguageKorean : DCSKoreanDictionaryName, -// EZLanguageFrench : DCSFrenchDictionaryName, -// EZLanguageGerman : DCSGermanDictionaryName, -// EZLanguageItalian : DCSItalianDictionaryName, -// EZLanguageSpanish : DCSSpanishDictionaryName, -// EZLanguagePortuguese : DCSPortugueseDictionaryName, -// EZLanguageDutch : DCSDutchDictionaryName, -// }; - _languageToDictionaryNameMap = [[MMOrderedDictionary alloc] initWithKeysAndObjects: - EZLanguageSimplifiedChinese,DCSSimplifiedChineseDictionaryName, - EZLanguageTraditionalChinese,DCSTraditionalChineseDictionaryName, - EZLanguageEnglish,DCSNewOxfordAmericanDictionaryName, - EZLanguageJapanese,DCSJapaneseDictionaryName, - EZLanguageKorean,DCSKoreanDictionaryName, - EZLanguageFrench,DCSFrenchDictionaryName, - EZLanguageGerman,DCSGermanDictionaryName, - EZLanguageItalian,DCSItalianDictionaryName, - EZLanguageSpanish,DCSSpanishDictionaryName, - EZLanguagePortuguese,DCSPortugueseDictionaryName, - EZLanguageDutch,DCSDutchDictionaryName, - nil]; - + EZLanguageSimplifiedChinese, DCSSimplifiedChineseDictionaryName, + EZLanguageTraditionalChinese, DCSTraditionalChineseDictionaryName, + EZLanguageEnglish, DCSNewOxfordAmericanDictionaryName, + EZLanguageJapanese, DCSJapaneseDictionaryName, + EZLanguageKorean, DCSKoreanDictionaryName, + EZLanguageFrench, DCSFrenchDictionaryName, + EZLanguageGerman, DCSGermanDictionaryName, + EZLanguageItalian, DCSItalianDictionaryName, + EZLanguageSpanish, DCSSpanishDictionaryName, + EZLanguagePortuguese, DCSPortugueseDictionaryName, + EZLanguageDutch, DCSDutchDictionaryName, + nil]; }); return _languageToDictionaryNameMap; } @@ -310,38 +275,38 @@ + (NSURL *)userDictionaryDirectoryURL { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ _allBuildInDictNames = @[ - DCSSimplifiedChineseDictionaryName, - DCSSimplifiedChineseIdiomDictionaryName, - DCSSimplifiedChineseThesaurusDictionaryName, - DCSSimplifiedChinese_EnglishDictionaryName, - DCSSimplifiedChinese_JapaneseDictionaryName, - DCSTraditionalChineseDictionaryName, - DCSTraditionalChineseHongkongDictionaryName, - DCSTraditionalChinese_EnglishDictionaryName, - DCSTraditionalChinese_EnglishIdiomDictionaryName, - DCSNewOxfordAmericanDictionaryName, - DCSOxfordAmericanWritersThesaurus, - DCSOxfordDictionaryOfEnglish, - DCSOxfordThesaurusOfEnglish, - DCSJapaneseDictionaryName, - DCSJapanese_EnglishDictionaryName, - DCSFrenchDictionaryName, - DCSFrench_EnglishDictionaryName, - DCSGermanDictionaryName, - DCSGerman_EnglishDictionaryName, - DCSItalianDictionaryName, - DCSItalian_EnglishDictionaryName, - DCSSpanishDictionaryName, - DCSSpanish_EnglishDictionaryName, - DCSPortugueseDictionaryName, - DCSPortuguese_EnglishDictionaryName, - DCSDutchDictionaryName, - DCSDutch_EnglishDictionaryName, - DCSKoreanDictionaryName, - DCSKorean_EnglishDictionaryName, - DCSWikipediaDictionaryName, - DCSAppleDictionaryName, - ]; + DCSSimplifiedChineseDictionaryName, + DCSSimplifiedChineseIdiomDictionaryName, + DCSSimplifiedChineseThesaurusDictionaryName, + DCSSimplifiedChinese_EnglishDictionaryName, + DCSSimplifiedChinese_JapaneseDictionaryName, + DCSTraditionalChineseDictionaryName, + DCSTraditionalChineseHongkongDictionaryName, + DCSTraditionalChinese_EnglishDictionaryName, + DCSTraditionalChinese_EnglishIdiomDictionaryName, + DCSNewOxfordAmericanDictionaryName, + DCSOxfordAmericanWritersThesaurus, + DCSOxfordDictionaryOfEnglish, + DCSOxfordThesaurusOfEnglish, + DCSJapaneseDictionaryName, + DCSJapanese_EnglishDictionaryName, + DCSFrenchDictionaryName, + DCSFrench_EnglishDictionaryName, + DCSGermanDictionaryName, + DCSGerman_EnglishDictionaryName, + DCSItalianDictionaryName, + DCSItalian_EnglishDictionaryName, + DCSSpanishDictionaryName, + DCSSpanish_EnglishDictionaryName, + DCSPortugueseDictionaryName, + DCSPortuguese_EnglishDictionaryName, + DCSDutchDictionaryName, + DCSDutch_EnglishDictionaryName, + DCSKoreanDictionaryName, + DCSKorean_EnglishDictionaryName, + DCSWikipediaDictionaryName, + DCSAppleDictionaryName, + ]; }); return _allBuildInDictNames; @@ -352,14 +317,14 @@ - (instancetype)initWithDictionaryRef:(DCSDictionaryRef)dictionary { if (!self || !dictionary) { return nil; } - + self.dictionary = dictionary; self.name = (__bridge_transfer NSString *)DCSDictionaryGetName(self.dictionary); self.shortName = (__bridge_transfer NSString *)DCSDictionaryGetShortName(self.dictionary); self.identifier = (__bridge_transfer NSString *)(DCSDictionaryGetIdentifier(dictionary)); self.dictionaryURL = (__bridge_transfer NSURL *)DCSDictionaryGetURL(dictionary); - + return self; } @@ -372,7 +337,8 @@ - (BOOL)isUserDictionary { - (NSArray *)entriesForSearchTerm:(NSString *)term { - return [self entriesForSearchTerm:term searchType:TTTDictionarySearchTypeExactMatch];; + return [self entriesForSearchTerm:term searchType:TTTDictionarySearchTypeExactMatch]; + ; } - (NSArray *)entriesForSearchTerm:(NSString *)term searchType:(TTTDictionarySearchType)searchType { @@ -382,7 +348,7 @@ - (BOOL)isUserDictionary { } term = [term substringWithRange:NSMakeRange(termRange.location, termRange.length)]; - + NSArray *records = (__bridge_transfer NSArray *)DCSCopyRecordsForSearchString(self.dictionary, (__bridge CFStringRef)term, searchType, 0); NSMutableArray *mutableEntries = [NSMutableArray arrayWithCapacity:[records count]]; if (records) { @@ -393,7 +359,7 @@ - (BOOL)isUserDictionary { } } } - + return [NSArray arrayWithArray:mutableEntries]; } @@ -407,11 +373,11 @@ - (BOOL)isEqual:(id)object { if (self == object) { return YES; } - + if (![object isKindOfClass:[TTTDictionary class]]) { return NO; } - + return [self.name isEqualToString:[(TTTDictionary *)object name]]; } diff --git a/Easydict/Feature/MMKit/Log/MMLog.m b/Easydict/Feature/MMKit/Log/MMLog.m index 48917918f..8b611f2a0 100644 --- a/Easydict/Feature/MMKit/Log/MMLog.m +++ b/Easydict/Feature/MMKit/Log/MMLog.m @@ -82,12 +82,11 @@ + (DDLog *)createADDLogWithName:(NSString *)name { DDLog *log = [[DDLog alloc] init]; [self configDDLog:log name:name]; NSString *identifier = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIdentifier"]; - NSString *version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; - NSString *build = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]; NSDictionary *deviceSystemInfo = [EZDeviceSystemInfo getDeviceSystemInfo]; - MMDDLogInfo(log, @"\n=========>\n🚀 %@(%@)[%@] 启动 MMLog(%@)...\n\n%@\n\n日志文件夹:\n%@\n<=========\n", identifier, version, build, name, deviceSystemInfo, [self logDirectoryWithName:name]); + MMDDLogInfo(log, @"\n=========>\n🚀 %@ 启动 MMLog(%@)...\n%@\n日志文件夹:\n%@\n<=========\n", identifier, name, deviceSystemInfo, [self logDirectoryWithName:name]); + return log; } diff --git a/Easydict/Feature/PerferenceWindow/EZAboutViewController.m b/Easydict/Feature/PerferenceWindow/EZAboutViewController.m index b0bfd4ab5..67fc4d277 100644 --- a/Easydict/Feature/PerferenceWindow/EZAboutViewController.m +++ b/Easydict/Feature/PerferenceWindow/EZAboutViewController.m @@ -102,7 +102,7 @@ - (void)setupUI { authorLinkButton.openURL = authorURL; // https://github.com/tisfeng authorLinkButton.closeWindowAfterOpeningURL = YES; - NSTextField *githubTextField = [NSTextField labelWithString:NSLocalizedString(@"Github:", nil)]; + NSTextField *githubTextField = [NSTextField labelWithString:NSLocalizedString(@"GitHub:", nil)]; [self.contentView addSubview:githubTextField]; self.githubTextField = githubTextField; diff --git a/Easydict/Feature/PerferenceWindow/EZSettingViewController.m b/Easydict/Feature/PerferenceWindow/EZSettingViewController.m index cae44357b..e12d1a6d7 100644 --- a/Easydict/Feature/PerferenceWindow/EZSettingViewController.m +++ b/Easydict/Feature/PerferenceWindow/EZSettingViewController.m @@ -114,7 +114,7 @@ @implementation EZSettingViewController EZLanguageClassicalChinese, ]; if (![disableLanguages containsObject:language]) { - NSString *showingLanguageName = [EZLanguageManager.shared showingLanguageName:language]; + NSString *showingLanguageName = [EZLanguageManager.shared showingLanguageNameWithFlag:language]; [languageDict setObject:showingLanguageName forKey:language]; } } @@ -141,71 +141,71 @@ @implementation EZSettingViewController - (void)viewDidLoad { [super viewDidLoad]; // Do view setup here. - + self.config = [EZConfiguration shared]; - + [self setupUI]; - + self.leftMargin = 110; self.rightMargin = 100; self.maxViewHeightRatio = 0.7; - + [self updateViewSize]; } - (void)setupUI { NSFont *font = [NSFont systemFontOfSize:13]; - + NSTextField *inputLabel = [NSTextField labelWithString:NSLocalizedString(@"input_translate", nil)]; inputLabel.font = font; [self.contentView addSubview:inputLabel]; self.inputLabel = inputLabel; self.inputShortcutView = [[MASShortcutView alloc] init]; [self.contentView addSubview:self.inputShortcutView]; - + NSTextField *snipLabel = [NSTextField labelWithString:NSLocalizedString(@"snip_translate", nil)]; snipLabel.font = font; [self.contentView addSubview:snipLabel]; self.snipLabel = snipLabel; self.snipShortcutView = [[MASShortcutView alloc] init]; [self.contentView addSubview:self.snipShortcutView]; - + NSTextField *selectLabel = [NSTextField labelWithString:NSLocalizedString(@"select_translate", nil)]; selectLabel.font = font; [self.contentView addSubview:selectLabel]; self.selectLabel = selectLabel; self.selectionShortcutView = [[MASShortcutView alloc] init]; [self.contentView addSubview:self.selectionShortcutView]; - + NSTextField *showMiniLabel = [NSTextField labelWithString:NSLocalizedString(@"show_mini_window", nil)]; showMiniLabel.font = font; [self.contentView addSubview:showMiniLabel]; self.showMiniLabel = showMiniLabel; self.showMiniShortcutView = [[MASShortcutView alloc] init]; [self.contentView addSubview:self.showMiniShortcutView]; - + if ([EZLanguageManager.shared isSystemEnglishFirstLanguage]) { self.leftmostView = self.showMiniLabel; } - + NSTextField *screenshotOCRLabel = [NSTextField labelWithString:NSLocalizedString(@"silent_screenshot_ocr", nil)]; screenshotOCRLabel.font = font; [self.contentView addSubview:screenshotOCRLabel]; self.screenshotOCRLabel = screenshotOCRLabel; self.screenshotOCRShortcutView = [[MASShortcutView alloc] init]; [self.contentView addSubview:self.screenshotOCRShortcutView]; - - + + [self.inputShortcutView setAssociatedUserDefaultsKey:EZInputShortcutKey]; [self.snipShortcutView setAssociatedUserDefaultsKey:EZSnipShortcutKey]; [self.selectionShortcutView setAssociatedUserDefaultsKey:EZSelectionShortcutKey]; [self.showMiniShortcutView setAssociatedUserDefaultsKey:EZShowMiniShortcutKey]; [self.screenshotOCRShortcutView setAssociatedUserDefaultsKey:EZScreenshotOCRShortcutKey]; - - + + NSColor *separatorLightColor = [NSColor mm_colorWithHexString:@"#D9DADA"]; NSColor *separatorDarkColor = [NSColor mm_colorWithHexString:@"#3C3C3C"]; - + NSView *separatorView = [[NSView alloc] init]; [self.contentView addSubview:separatorView]; self.separatorView = separatorView; @@ -215,72 +215,72 @@ - (void)setupUI { } dark:^(NSView *view) { view.layer.backgroundColor = separatorDarkColor.CGColor; }]; - + NSTextField *firstLanguageLabel = [NSTextField labelWithString:NSLocalizedString(@"first_language", nil)]; firstLanguageLabel.font = font; [self.contentView addSubview:firstLanguageLabel]; self.firstLanguageLabel = firstLanguageLabel; - + self.firstLanguagePopUpButton = [[NSPopUpButton alloc] init]; [self.contentView addSubview:self.firstLanguagePopUpButton]; [self.firstLanguagePopUpButton addItemsWithTitles:[self.allLanguageDict sortedValues]]; self.firstLanguagePopUpButton.target = self; self.firstLanguagePopUpButton.action = @selector(firstLangaugePopUpButtonClicked:); - + NSTextField *secondLanguageLabel = [NSTextField labelWithString:NSLocalizedString(@"second_language", nil)]; secondLanguageLabel.font = font; [self.contentView addSubview:secondLanguageLabel]; self.secondLanguageLabel = secondLanguageLabel; - + self.secondLanguagePopUpButton = [[NSPopUpButton alloc] init]; [self.contentView addSubview:self.secondLanguagePopUpButton]; [self.secondLanguagePopUpButton addItemsWithTitles:[self.allLanguageDict sortedValues]]; self.secondLanguagePopUpButton.target = self; self.secondLanguagePopUpButton.action = @selector(secondLangaugePopUpButtonClicked:); - - + + NSTextField *showQueryIconLabel = [NSTextField labelWithString:NSLocalizedString(@"auto_get_selected_text", nil)]; showQueryIconLabel.font = font; [self.contentView addSubview:showQueryIconLabel]; self.autoGetSelectedTextLabel = showQueryIconLabel; - + NSString *showQueryIconTitle = NSLocalizedString(@"auto_show_query_icon", nil); self.showQueryIconButton = [NSButton checkboxWithTitle:showQueryIconTitle target:self action:@selector(autoSelectTextButtonClicked:)]; [self.contentView addSubview:self.showQueryIconButton]; - + NSString *forceGetSelectedText = NSLocalizedString(@"force_auto_get_selected_text", nil); self.forceGetSelectedTextButton = [NSButton checkboxWithTitle:forceGetSelectedText target:self action:@selector(forceGetSelectedTextButtonClicked:)]; [self.contentView addSubview:self.forceGetSelectedTextButton]; - - + + NSTextField *disableEmptyCopyBeepLabel = [NSTextField labelWithString:NSLocalizedString(@"disable_empty_copy_beep", nil)]; disableEmptyCopyBeepLabel.font = font; [self.contentView addSubview:disableEmptyCopyBeepLabel]; self.disableEmptyCopyBeepLabel = disableEmptyCopyBeepLabel; - + NSString *disableEmptyCopyBeepTitle = NSLocalizedString(@"disable_empty_copy_beep_msg", nil); self.disableEmptyCopyBeepButton = [NSButton checkboxWithTitle:disableEmptyCopyBeepTitle target:self action:@selector(disableEmptyCopyBeepButtonClicked:)]; [self.contentView addSubview:self.disableEmptyCopyBeepButton]; - + NSTextField *clickQueryLabel = [NSTextField labelWithString:NSLocalizedString(@"click_icon_query", nil)]; clickQueryLabel.font = font; [self.contentView addSubview:clickQueryLabel]; self.clickQueryLabel = clickQueryLabel; - + NSString *clickQueryTitle = NSLocalizedString(@"click_icon_query_info", nil); self.clickQueryButton = [NSButton checkboxWithTitle:clickQueryTitle target:self action:@selector(clickQueryButtonClicked:)]; [self.contentView addSubview:self.clickQueryButton]; - - + + NSTextField *adjustQueryIconPostionLabel = [NSTextField labelWithString:NSLocalizedString(@"adjust_pop_button_origin", nil)]; adjustQueryIconPostionLabel.font = font; [self.contentView addSubview:adjustQueryIconPostionLabel]; self.adjustQueryIconPostionLabel = adjustQueryIconPostionLabel; - + NSString *adjustQueryIconPostionTitle = NSLocalizedString(@"avoid_conflict_with_PopClip_display", nil); self.adjustQueryIconPostionButton = [NSButton checkboxWithTitle:adjustQueryIconPostionTitle target:self action:@selector(adjustQueryIconPostionButtonClicked:)]; [self.contentView addSubview:self.adjustQueryIconPostionButton]; - + // language detect NSTextField *usesLanguageCorrectionLabel = [NSTextField labelWithString:NSLocalizedString(@"language_detect_optimize", nil)]; usesLanguageCorrectionLabel.font = font; @@ -288,7 +288,7 @@ - (void)setupUI { self.languageDetectLabel = usesLanguageCorrectionLabel; self.languageDetectOptimizePopUpButton = [[NSPopUpButton alloc] init]; [self.contentView addSubview:self.languageDetectOptimizePopUpButton]; - + NSArray *languageDetectOptimizeItems = @[ NSLocalizedString(@"language_detect_optimize_none", nil), NSLocalizedString(@"language_detect_optimize_baidu", nil), @@ -297,13 +297,13 @@ - (void)setupUI { [self.languageDetectOptimizePopUpButton addItemsWithTitles:languageDetectOptimizeItems]; self.languageDetectOptimizePopUpButton.target = self; self.languageDetectOptimizePopUpButton.action = @selector(languageDetectOptimizePopUpButtonClicked:); - + // default tts service NSTextField *defaultTTSServiceLabel = [NSTextField labelWithString:NSLocalizedString(@"default_tts_service", nil)]; defaultTTSServiceLabel.font = font; [self.contentView addSubview:defaultTTSServiceLabel]; self.defaultTTSServiceLabel = defaultTTSServiceLabel; - + self.defaultTTSServicePopUpButton = [[NSPopUpButton alloc] init]; [self.contentView addSubview:self.defaultTTSServicePopUpButton]; @@ -316,12 +316,12 @@ - (void)setupUI { [self.defaultTTSServicePopUpButton addItemsWithTitles:localizedTTSTitles]; self.defaultTTSServicePopUpButton.target = self; self.defaultTTSServicePopUpButton.action = @selector(defaultTTSServicePopUpButtonClicked:); - + NSTextField *mouseSelectTranslateWindowTypeLabel = [NSTextField labelWithString:NSLocalizedString(@"mouse_select_translate_window_type", nil)]; mouseSelectTranslateWindowTypeLabel.font = font; [self.contentView addSubview:mouseSelectTranslateWindowTypeLabel]; self.mouseSelectTranslateWindowTypeLabel = mouseSelectTranslateWindowTypeLabel; - + self.mouseSelectTranslateWindowTypePopUpButton = [[NSPopUpButton alloc] init]; [self.contentView addSubview:self.mouseSelectTranslateWindowTypePopUpButton]; MMOrderedDictionary *mouseSelectTranslateWindowTypeDict = [EZEnumTypes translateWindowTypeDict]; @@ -334,7 +334,7 @@ - (void)setupUI { shortcutSelectTranslateWindowTypeLabel.font = font; [self.contentView addSubview:shortcutSelectTranslateWindowTypeLabel]; self.shortcutSelectTranslateWindowTypeLabel = shortcutSelectTranslateWindowTypeLabel; - + self.shortcutSelectTranslateWindowTypePopUpButton = [[NSPopUpButton alloc] init]; [self.contentView addSubview:self.shortcutSelectTranslateWindowTypePopUpButton]; MMOrderedDictionary *shortcutSelectTranslateWindowTypeDict = [EZEnumTypes translateWindowTypeDict]; @@ -342,13 +342,13 @@ - (void)setupUI { [self.shortcutSelectTranslateWindowTypePopUpButton addItemsWithTitles:shortcutSelectTranslateWindowTypeItems]; self.shortcutSelectTranslateWindowTypePopUpButton.target = self; self.shortcutSelectTranslateWindowTypePopUpButton.action = @selector(shortcutSelectTranslateWindowTypePopUpButtonClicked:); - + NSTextField *fixedWindowPositionLabel = [NSTextField labelWithString:NSLocalizedString(@"fixed_window_position", nil)]; fixedWindowPositionLabel.font = font; [self.contentView addSubview:fixedWindowPositionLabel]; self.fixedWindowPositionLabel = fixedWindowPositionLabel; - + self.fixedWindowPositionPopUpButton = [[NSPopUpButton alloc] init]; [self.contentView addSubview:self.fixedWindowPositionPopUpButton]; MMOrderedDictionary *fixedWindowPostionDict = [EZEnumTypes fixedWindowPositionDict]; @@ -356,80 +356,80 @@ - (void)setupUI { [self.fixedWindowPositionPopUpButton addItemsWithTitles:fixedWindowPositionItems]; self.fixedWindowPositionPopUpButton.target = self; self.fixedWindowPositionPopUpButton.action = @selector(fixedWindowPositionPopUpButtonClicked:); - + NSTextField *playAudioLabel = [NSTextField labelWithString:NSLocalizedString(@"play_word_audio", nil)]; playAudioLabel.font = font; [self.contentView addSubview:playAudioLabel]; self.playAudioLabel = playAudioLabel; - + NSString *autoPlayAudioTitle = NSLocalizedString(@"auto_play_word_audio", nil); self.autoPlayAudioButton = [NSButton checkboxWithTitle:autoPlayAudioTitle target:self action:@selector(autoPlayAudioButtonClicked:)]; [self.contentView addSubview:self.autoPlayAudioButton]; - + NSTextField *clearInputLabel = [NSTextField labelWithString:NSLocalizedString(@"clear_input", nil)]; clearInputLabel.font = font; [self.contentView addSubview:clearInputLabel]; self.clearInputLabel = clearInputLabel; - + NSString *clearInputTitle = NSLocalizedString(@"clear_input_when_translating", nil); self.clearInputButton = [NSButton checkboxWithTitle:clearInputTitle target:self action:@selector(clearInputButtonClicked:)]; [self.contentView addSubview:self.clearInputButton]; - + NSTextField *autoQueryLabel = [NSTextField labelWithString:NSLocalizedString(@"auto_query", nil)]; autoQueryLabel.font = font; [self.contentView addSubview:autoQueryLabel]; self.autoQueryLabel = autoQueryLabel; - + NSString *autoQueryOCTText = NSLocalizedString(@"auto_query_ocr_text", nil); self.autoQueryOCRTextButton = [NSButton checkboxWithTitle:autoQueryOCTText target:self action:@selector(autoQueryOCRTextButtonClicked:)]; [self.contentView addSubview:self.autoQueryOCRTextButton]; - + NSString *autoQuerySelectedText = NSLocalizedString(@"auto_query_selected_text", nil); self.autoQuerySelectedTextButton = [NSButton checkboxWithTitle:autoQuerySelectedText target:self action:@selector(autoQuerySelectedTextButtonClicked:)]; [self.contentView addSubview:self.autoQuerySelectedTextButton]; - + NSString *autoQueryPastedTextButton = NSLocalizedString(@"auto_query_pasted_text", nil); self.autoQueryPastedTextButton = [NSButton checkboxWithTitle:autoQueryPastedTextButton target:self action:@selector(autoQueryPastedTextButtonClicked:)]; [self.contentView addSubview:self.autoQueryPastedTextButton]; - - + + NSTextField *autoCopyTextLabel = [NSTextField labelWithString:NSLocalizedString(@"auto_copy_text", nil)]; autoCopyTextLabel.font = font; [self.contentView addSubview:autoCopyTextLabel]; self.autoCopyTextLabel = autoCopyTextLabel; - + NSString *autoCopyOCRText = NSLocalizedString(@"auto_copy_ocr_text", nil); self.autoCopyOCRTextButton = [NSButton checkboxWithTitle:autoCopyOCRText target:self action:@selector(autoCopyOCRTextButtonClicked:)]; [self.contentView addSubview:self.autoCopyOCRTextButton]; - + NSString *autoCopySelectedText = NSLocalizedString(@"auto_copy_selected_text", nil); self.autoCopySelectedTextButton = [NSButton checkboxWithTitle:autoCopySelectedText target:self action:@selector(autoCopySelectedTextButtonClicked:)]; [self.contentView addSubview:self.autoCopySelectedTextButton]; - + NSString *autoCopyFirstTranslatedText = NSLocalizedString(@"auto_copy_first_translated_text", nil); self.autoCopyFirstTranslatedTextButton = [NSButton checkboxWithTitle:autoCopyFirstTranslatedText target:self action:@selector(autoCopyFirstTranslatedTextButtonClicked:)]; [self.contentView addSubview:self.autoCopyFirstTranslatedTextButton]; - - + + NSTextField *showQuickLinkLabel = [NSTextField labelWithString:NSLocalizedString(@"quick_link", nil)]; showQuickLinkLabel.font = font; [self.contentView addSubview:showQuickLinkLabel]; self.showQuickLinkLabel = showQuickLinkLabel; - + NSString *showGoogleQuickLink = NSLocalizedString(@"show_google_quick_link", nil); self.showGoogleQuickLinkButton = [NSButton checkboxWithTitle:showGoogleQuickLink target:self action:@selector(showGoogleQuickLinkButtonClicked:)]; [self.contentView addSubview:self.showGoogleQuickLinkButton]; - + NSString *showEudicQuickLink = NSLocalizedString(@"show_eudic_quick_link", nil); self.showEudicQuickLinkButton = [NSButton checkboxWithTitle:showEudicQuickLink target:self action:@selector(showEudicQuickLinkButtonClicked:)]; [self.contentView addSubview:self.showEudicQuickLinkButton]; - + NSString *showAppleDictionaryQuickLink = NSLocalizedString(@"show_apple_dictionary_quick_link", nil); self.showAppleDictionaryQuickLinkButton = [NSButton checkboxWithTitle:showAppleDictionaryQuickLink target:self action:@selector(showAppleDictionaryQuickLinkButtonClicked:)]; [self.contentView addSubview:self.showAppleDictionaryQuickLinkButton]; - - + + NSView *separatorView2 = [[NSView alloc] init]; [self.contentView addSubview:separatorView2]; self.separatorView2 = separatorView2; @@ -439,37 +439,37 @@ - (void)setupUI { } dark:^(NSView *view) { view.layer.backgroundColor = separatorDarkColor.CGColor; }]; - + NSTextField *hideMainWindowLabel = [NSTextField labelWithString:NSLocalizedString(@"show_main_window", nil)]; hideMainWindowLabel.font = font; [self.contentView addSubview:hideMainWindowLabel]; self.hideMainWindowLabel = hideMainWindowLabel; - + NSString *hideMainWindowTitle = NSLocalizedString(@"hide_main_window", nil); self.hideMainWindowButton = [NSButton checkboxWithTitle:hideMainWindowTitle target:self action:@selector(hideMainWindowButtonClicked:)]; [self.contentView addSubview:self.hideMainWindowButton]; - + NSTextField *launchLabel = [NSTextField labelWithString:NSLocalizedString(@"launch", nil)]; launchLabel.font = font; [self.contentView addSubview:launchLabel]; self.launchLabel = launchLabel; - + NSString *launchAtStartupTitle = NSLocalizedString(@"launch_at_startup", nil); self.launchAtStartupButton = [NSButton checkboxWithTitle:launchAtStartupTitle target:self action:@selector(launchAtStartupButtonClicked:)]; [self.contentView addSubview:self.launchAtStartupButton]; - + NSTextField *menubarIconLabel = [NSTextField labelWithString:NSLocalizedString(@"menu_bar_icon", nil)]; menubarIconLabel.font = font; [self.contentView addSubview:menubarIconLabel]; self.menuBarIconLabel = menubarIconLabel; - + NSString *hideMenuBarIcon = NSLocalizedString(@"hide_menu_bar_icon", nil); self.hideMenuBarIconButton = [NSButton checkboxWithTitle:hideMenuBarIcon target:self action:@selector(hideMenuBarIconButtonClicked:)]; [self.contentView addSubview:self.hideMenuBarIconButton]; - - + + [self updatePreferredLanguagesPopUpButton]; - + self.showQueryIconButton.mm_isOn = self.config.autoSelectText; self.forceGetSelectedTextButton.mm_isOn = self.config.forceAutoGetSelectedText; self.disableEmptyCopyBeepButton.mm_isOn = self.config.disableEmptyCopyBeep; @@ -481,12 +481,12 @@ - (void)setupUI { MMOrderedDictionary *translateWindowTypeDict = [EZEnumTypes translateWindowTypeDict]; NSString *mouseWindowTitle = [translateWindowTypeDict objectForKey:@(self.config.mouseSelectTranslateWindowType)]; NSString *shortcutWindowTitle = [translateWindowTypeDict objectForKey:@(self.config.shortcutSelectTranslateWindowType)]; - + [self.mouseSelectTranslateWindowTypePopUpButton selectItemWithTitle:mouseWindowTitle]; [self.shortcutSelectTranslateWindowTypePopUpButton selectItemWithTitle:shortcutWindowTitle]; - + [self.fixedWindowPositionPopUpButton selectItemAtIndex:self.config.fixedWindowPosition]; - + self.autoPlayAudioButton.mm_isOn = self.config.autoPlayAudio; self.clearInputButton.mm_isOn = self.config.clearInput; self.launchAtStartupButton.mm_isOn = self.config.launchAtStartup; @@ -505,7 +505,7 @@ - (void)setupUI { - (void)updateViewConstraints { CGFloat separatorMargin = 40; - + [self.inputLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.selectLabel); make.top.equalTo(self.contentView).offset(self.topMargin).priorityLow(); @@ -515,7 +515,7 @@ - (void)updateViewConstraints { make.centerY.equalTo(self.inputLabel); make.height.equalTo(self.selectionShortcutView); }]; - + [self.snipLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.selectLabel); make.top.equalTo(self.inputShortcutView.mas_bottom).offset(self.verticalPadding); @@ -525,7 +525,7 @@ - (void)updateViewConstraints { make.centerY.equalTo(self.snipLabel); make.height.equalTo(self.selectionShortcutView); }]; - + [self.selectLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.contentView).offset(self.leftMargin).priorityLow(); make.top.equalTo(self.snipShortcutView.mas_bottom).offset(self.verticalPadding); @@ -535,7 +535,7 @@ - (void)updateViewConstraints { make.centerY.equalTo(self.selectLabel); make.height.mas_equalTo(25); }]; - + [self.showMiniLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.selectLabel); make.top.equalTo(self.selectionShortcutView.mas_bottom).offset(self.verticalPadding); @@ -545,7 +545,7 @@ - (void)updateViewConstraints { make.centerY.equalTo(self.showMiniLabel); make.height.equalTo(self.selectionShortcutView); }]; - + [self.screenshotOCRLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.selectLabel); make.top.equalTo(self.showMiniShortcutView.mas_bottom).offset(self.verticalPadding); @@ -555,32 +555,32 @@ - (void)updateViewConstraints { make.centerY.equalTo(self.screenshotOCRLabel); make.height.equalTo(self.selectionShortcutView); }]; - - + + [self.separatorView mas_remakeConstraints:^(MASConstraintMaker *make) { make.left.right.inset(separatorMargin); make.top.equalTo(self.screenshotOCRLabel.mas_bottom).offset(1.5 * self.verticalPadding); make.height.mas_equalTo(1); }]; - + [self.firstLanguageLabel mas_remakeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(self.selectLabel); + make.right.equalTo(self.selectLabel); make.top.equalTo(self.separatorView.mas_bottom).offset(1.5 * self.verticalPadding); }]; [self.firstLanguagePopUpButton mas_remakeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.firstLanguageLabel.mas_right).offset(self.horizontalPadding); make.centerY.equalTo(self.firstLanguageLabel); }]; - + [self.secondLanguageLabel mas_remakeConstraints:^(MASConstraintMaker *make) { - make.left.equalTo(self.selectLabel); + make.right.equalTo(self.selectLabel); make.top.equalTo(self.firstLanguagePopUpButton.mas_bottom).offset(self.verticalPadding); }]; [self.secondLanguagePopUpButton mas_remakeConstraints:^(MASConstraintMaker *make) { make.left.equalTo(self.secondLanguageLabel.mas_right).offset(self.horizontalPadding); make.centerY.equalTo(self.secondLanguageLabel); }]; - + [self.autoGetSelectedTextLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.selectLabel); make.top.equalTo(self.secondLanguagePopUpButton.mas_bottom).offset(1.5 * self.verticalPadding); @@ -593,7 +593,7 @@ - (void)updateViewConstraints { make.left.equalTo(self.showQueryIconButton); make.top.equalTo(self.showQueryIconButton.mas_bottom).offset(self.verticalPadding); }]; - + [self.disableEmptyCopyBeepLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.autoGetSelectedTextLabel); make.top.equalTo(self.forceGetSelectedTextButton.mas_bottom).offset(self.verticalPadding); @@ -602,7 +602,7 @@ - (void)updateViewConstraints { make.left.equalTo(self.disableEmptyCopyBeepLabel.mas_right).offset(self.horizontalPadding); make.centerY.equalTo(self.disableEmptyCopyBeepLabel); }]; - + [self.clickQueryLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.autoGetSelectedTextLabel); make.top.equalTo(self.disableEmptyCopyBeepButton.mas_bottom).offset(self.verticalPadding); @@ -611,8 +611,8 @@ - (void)updateViewConstraints { make.left.equalTo(self.clickQueryLabel.mas_right).offset(self.horizontalPadding); make.centerY.equalTo(self.clickQueryLabel); }]; - - + + [self.adjustQueryIconPostionLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.clickQueryLabel); make.top.equalTo(self.clickQueryButton.mas_bottom).offset(self.verticalPadding); @@ -621,7 +621,7 @@ - (void)updateViewConstraints { make.left.equalTo(self.adjustQueryIconPostionLabel.mas_right).offset(self.horizontalPadding); make.centerY.equalTo(self.adjustQueryIconPostionLabel); }]; - + [self.languageDetectLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.autoGetSelectedTextLabel); make.top.equalTo(self.adjustQueryIconPostionButton.mas_bottom).offset(self.verticalPadding); @@ -630,7 +630,7 @@ - (void)updateViewConstraints { make.left.equalTo(self.languageDetectLabel.mas_right).offset(self.horizontalPadding); make.centerY.equalTo(self.languageDetectLabel); }]; - + [self.defaultTTSServiceLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.autoGetSelectedTextLabel); make.top.equalTo(self.languageDetectOptimizePopUpButton.mas_bottom).offset(self.verticalPadding); @@ -639,8 +639,8 @@ - (void)updateViewConstraints { make.left.equalTo(self.defaultTTSServiceLabel.mas_right).offset(self.horizontalPadding); make.centerY.equalTo(self.defaultTTSServiceLabel); }]; - - + + [self.mouseSelectTranslateWindowTypeLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.autoGetSelectedTextLabel); make.top.equalTo(self.defaultTTSServicePopUpButton.mas_bottom).offset(self.verticalPadding); @@ -658,7 +658,7 @@ - (void)updateViewConstraints { make.left.equalTo(self.shortcutSelectTranslateWindowTypeLabel.mas_right).offset(self.horizontalPadding); make.centerY.equalTo(self.shortcutSelectTranslateWindowTypeLabel); }]; - + [self.fixedWindowPositionLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.autoGetSelectedTextLabel); make.top.equalTo(self.shortcutSelectTranslateWindowTypePopUpButton.mas_bottom).offset(self.verticalPadding); @@ -667,7 +667,7 @@ - (void)updateViewConstraints { make.left.equalTo(self.fixedWindowPositionLabel.mas_right).offset(self.horizontalPadding); make.centerY.equalTo(self.fixedWindowPositionLabel); }]; - + [self.playAudioLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.autoGetSelectedTextLabel); make.top.equalTo(self.fixedWindowPositionPopUpButton.mas_bottom).offset(self.verticalPadding); @@ -676,8 +676,8 @@ - (void)updateViewConstraints { make.left.equalTo(self.playAudioLabel.mas_right).offset(self.horizontalPadding); make.centerY.equalTo(self.playAudioLabel); }]; - - + + [self.clearInputLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.autoGetSelectedTextLabel); make.top.equalTo(self.autoPlayAudioButton.mas_bottom).offset(self.verticalPadding); @@ -686,8 +686,8 @@ - (void)updateViewConstraints { make.left.equalTo(self.clearInputLabel.mas_right).offset(self.horizontalPadding); make.centerY.equalTo(self.clearInputLabel); }]; - - + + [self.autoQueryLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.autoGetSelectedTextLabel); make.top.equalTo(self.clearInputButton.mas_bottom).offset(self.verticalPadding); @@ -704,8 +704,8 @@ - (void)updateViewConstraints { make.left.equalTo(self.autoQuerySelectedTextButton); make.top.equalTo(self.autoQuerySelectedTextButton.mas_bottom).offset(self.verticalPadding); }]; - - + + [self.autoCopyTextLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.autoGetSelectedTextLabel); make.top.equalTo(self.autoQueryPastedTextButton.mas_bottom).offset(self.verticalPadding); @@ -722,8 +722,8 @@ - (void)updateViewConstraints { make.left.equalTo(self.autoCopySelectedTextButton); make.top.equalTo(self.autoCopySelectedTextButton.mas_bottom).offset(self.verticalPadding); }]; - - + + [self.showQuickLinkLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.autoGetSelectedTextLabel); make.top.equalTo(self.autoCopyFirstTranslatedTextButton.mas_bottom).offset(self.verticalPadding); @@ -740,13 +740,13 @@ - (void)updateViewConstraints { make.left.equalTo(self.showEudicQuickLinkButton); make.top.equalTo(self.showEudicQuickLinkButton.mas_bottom).offset(self.verticalPadding); }]; - + [self.separatorView2 mas_remakeConstraints:^(MASConstraintMaker *make) { make.left.right.equalTo(self.separatorView); make.top.equalTo(self.showAppleDictionaryQuickLinkButton.mas_bottom).offset(1.5 * self.verticalPadding); make.height.equalTo(self.separatorView); }]; - + [self.hideMainWindowLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.autoGetSelectedTextLabel); make.top.equalTo(self.separatorView2.mas_bottom).offset(1.5 * self.verticalPadding); @@ -755,7 +755,7 @@ - (void)updateViewConstraints { make.left.equalTo(self.hideMainWindowLabel.mas_right).offset(self.horizontalPadding); make.centerY.equalTo(self.hideMainWindowLabel); }]; - + [self.launchLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.autoGetSelectedTextLabel); make.top.equalTo(self.hideMainWindowButton.mas_bottom).offset(self.verticalPadding); @@ -764,7 +764,7 @@ - (void)updateViewConstraints { make.left.equalTo(self.launchLabel.mas_right).offset(self.horizontalPadding); make.centerY.equalTo(self.launchLabel); }]; - + [self.menuBarIconLabel mas_remakeConstraints:^(MASConstraintMaker *make) { make.right.equalTo(self.autoGetSelectedTextLabel); make.top.equalTo(self.launchAtStartupButton.mas_bottom).offset(self.verticalPadding); @@ -773,20 +773,20 @@ - (void)updateViewConstraints { make.left.equalTo(self.menuBarIconLabel.mas_right).offset(self.horizontalPadding); make.centerY.equalTo(self.menuBarIconLabel); }]; - + self.topmostView = self.inputLabel; self.bottommostView = self.hideMenuBarIconButton; - + if ([EZLanguageManager.shared isSystemChineseFirstLanguage]) { self.leftmostView = self.adjustQueryIconPostionLabel; self.rightmostView = self.forceGetSelectedTextButton; } - + if ([EZLanguageManager.shared isSystemEnglishFirstLanguage]) { self.leftmostView = self.adjustQueryIconPostionLabel; self.rightmostView = self.forceGetSelectedTextButton; } - + [super updateViewConstraints]; } @@ -795,13 +795,13 @@ - (void)updateViewConstraints { - (BOOL)checkAppIsTrusted { BOOL isTrusted = AXIsProcessTrustedWithOptions((__bridge CFDictionaryRef) @{(__bridge NSString *)kAXTrustedCheckOptionPrompt : @YES}); NSLog(@"isTrusted: %d", isTrusted); - + return isTrusted == YES; } - (void)autoSelectTextButtonClicked:(NSButton *)sender { self.config.autoSelectText = sender.mm_isOn; - + if (sender.mm_isOn) { [self checkAppIsTrusted]; } @@ -948,14 +948,14 @@ - (void)firstLangaugePopUpButtonClicked:(NSPopUpButton *)button { NSInteger selectedIndex = button.indexOfSelectedItem; EZLanguage language = self.allLanguageDict.sortedKeys[selectedIndex]; self.config.firstLanguage = language; - + [self checkIfEqualFirstLanguage:YES]; } - (void)secondLangaugePopUpButtonClicked:(NSPopUpButton *)button { NSInteger selectedIndex = button.indexOfSelectedItem; EZLanguage language = self.allLanguageDict.sortedKeys[selectedIndex]; self.config.secondLanguage = language; - + [self checkIfEqualFirstLanguage:NO]; } @@ -963,7 +963,7 @@ - (void)checkIfEqualFirstLanguage:(BOOL)fistLanguageFlag { if ([self.config.firstLanguage isEqualToString:self.config.secondLanguage]) { NSAlert *alert = [[NSAlert alloc] init]; [alert addButtonWithTitle:NSLocalizedString(@"ok", nil)]; - + NSString *warningText = NSLocalizedString(@"equal_first_and_second_language", nil); NSString *showingLanguage = [EZLanguageManager.shared showingLanguageName:self.config.firstLanguage]; alert.messageText = [NSString stringWithFormat:@"%@: %@", warningText, showingLanguage]; @@ -972,13 +972,13 @@ - (void)checkIfEqualFirstLanguage:(BOOL)fistLanguageFlag { // If isFistLanguage is YES, means we need to auto correct second language according to first language. EZLanguage sourceLanguage = fistLanguageFlag ? self.config.firstLanguage : self.config.secondLanguage; EZLanguage autoTargetLanguage = [EZLanguageManager.shared userTargetLanguageWithSourceLanguage:sourceLanguage]; - + if (fistLanguageFlag) { self.config.secondLanguage = autoTargetLanguage; } else { self.config.firstLanguage = autoTargetLanguage; } - + [self updatePreferredLanguagesPopUpButton]; } }]; @@ -986,10 +986,10 @@ - (void)checkIfEqualFirstLanguage:(BOOL)fistLanguageFlag { } - (void)updatePreferredLanguagesPopUpButton { - NSInteger firstLanguageIndex = [self.allLanguageDict.sortedKeys indexOfObject:EZLanguageManager.shared.userFirstLanguage]; + NSInteger firstLanguageIndex = [self.allLanguageDict.sortedKeys indexOfObject:self.config.firstLanguage]; [self.firstLanguagePopUpButton selectItemAtIndex:firstLanguageIndex]; - - NSInteger secondLanguageIndex = [self.allLanguageDict.sortedKeys indexOfObject:EZLanguageManager.shared.userSecondLanguage]; + + NSInteger secondLanguageIndex = [self.allLanguageDict.sortedKeys indexOfObject:self.config.secondLanguage]; [self.secondLanguagePopUpButton selectItemAtIndex:secondLanguageIndex]; } @@ -1000,11 +1000,11 @@ - (NSString *)viewIdentifier { } - (NSString *)toolbarItemLabel { - return NSLocalizedString(@"setting", nil); + return NSLocalizedString(@"setting_general", nil); } - (NSImage *)toolbarItemImage { - return [NSImage imageNamed:@"toolbar_setting"]; + return [NSImage imageNamed:@"toolbar_setting_general"]; } - (BOOL)hasResizableWidth { diff --git a/Easydict/Feature/Service/Apple/EZAppleService.m b/Easydict/Feature/Service/Apple/EZAppleService.m index 924bbccfc..404f887c7 100644 --- a/Easydict/Feature/Service/Apple/EZAppleService.m +++ b/Easydict/Feature/Service/Apple/EZAppleService.m @@ -490,25 +490,36 @@ - (EZLanguage)detectTextLanguage:(NSString *)text printLog:(BOOL)logFlag { if ([self.languageManager isChineseLanguage:mostConfidentLanguage]) { // Correct 勿 --> zh-Hant --> zh-Hans - EZLanguage chineseLanguage = [self chineseLanguageTypeOfText:text]; - return chineseLanguage; + mostConfidentLanguage = [self chineseLanguageTypeOfText:text]; } else { // Try to detect Chinese language. if ([self.languageManager isUserChineseFirstLanguage]) { - // test: 開門 open, 使用1 OCR --> 英文, --> 中文 + // test: 開門 open, 使用1 OCR --> 英文 --> 中文 EZLanguage chineseLanguage = [self chineseLanguageTypeOfText:text fromLanguage:mostConfidentLanguage]; if (![chineseLanguage isEqualToString:EZLanguageAuto]) { mostConfidentLanguage = chineseLanguage; } } - - // TODO: Maybe we can use this way to detect other language. - // If not detected as English, try to query System English Dictioanry. Such as delimiter - if (![self.languageManager isEnglishLangauge:mostConfidentLanguage]) { - // If has result, then most likely English. Cost about ~10ms - if ([self.appleDictionary queryDictionaryForText:text language:EZLanguageEnglish]) { - mostConfidentLanguage = EZLanguageEnglish; - NSLog(@"Apple Dictionary Detect: %@ is English", text); + } + + + // TODO: Maybe we can use this way to detect other language. + + NSArray *needCorrectedLanguages = @[ + EZLanguageEnglish, // si + EZLanguageSimplifiedChinese, // 浦 + ]; + + BOOL isWordLength = text.length <= EZEnglishWordMaxLength; + + // For example, if not detected as English, try to query System English Dictioanry. eg. 'si' + if (isWordLength && ![needCorrectedLanguages containsObject:mostConfidentLanguage]) { + for (EZLanguage language in needCorrectedLanguages) { + BOOL success = [self correctTextLanguage:text + designatedLanguage:language + originalLanguage:&mostConfidentLanguage]; + if (success) { + break; } } } @@ -516,6 +527,20 @@ - (EZLanguage)detectTextLanguage:(NSString *)text printLog:(BOOL)logFlag { return mostConfidentLanguage; } +/// Using dictionary to correct text langauge, return YES if corrected successfully. +- (BOOL)correctTextLanguage:(NSString *)text + designatedLanguage:(EZLanguage)designatedLanguage + originalLanguage:(EZLanguage *)originalLanguage +{ + // Cost about ~1ms + if ([self.appleDictionary queryDictionaryForText:text language:designatedLanguage]) { + *originalLanguage = designatedLanguage; + NSLog(@"Apple Dictionary Detect: %@ is %@", text, designatedLanguage); + return YES; + } + return NO; +} + /// Apple original detect language. - (EZLanguage)appleDetectTextLanguage:(NSString *)text { EZLanguage mostConfidentLanguage = [self appleDetectTextLanguage:text printLog:NO]; diff --git a/Easydict/Feature/Service/Bing/EZBingLanguageVoice.swift b/Easydict/Feature/Service/Bing/EZBingLanguageVoice.swift deleted file mode 100644 index 8815f345b..000000000 --- a/Easydict/Feature/Service/Bing/EZBingLanguageVoice.swift +++ /dev/null @@ -1,27 +0,0 @@ -// -// EZBingLanguageVoice.swift -// Easydict -// -// Created by Jerry on 2023-10-25. -// Copyright © 2023 izual. All rights reserved. -// - -import Foundation - -// Docs: https://learn.microsoft.com/zh-cn/azure/ai-services/speech-service/language-support?tabs=tts - -@objc class EZBingLanguageVoice: NSObject { - - @objc var lang: String // BCP-47, en-US - @objc var voiceName: String // en-US-JennyNeural - - init(lang: String, voiceName: String) { - self.lang = lang - self.voiceName = voiceName - } - - @objc class func voice(withLanguage language: String, voiceName: String) -> - EZBingLanguageVoice { - return EZBingLanguageVoice(lang: language, voiceName: voiceName) - } -} diff --git a/Easydict/Feature/Service/Bing/EZBingRequest.m b/Easydict/Feature/Service/Bing/EZBingRequest.m index 856fe4a95..5f97ca874 100644 --- a/Easydict/Feature/Service/Bing/EZBingRequest.m +++ b/Easydict/Feature/Service/Bing/EZBingRequest.m @@ -6,9 +6,9 @@ // Copyright © 2023 izual. All rights reserved. // -#import "Easydict-Swift.h" #import "EZBingRequest.h" #import "EZTranslateError.h" +#import "EZBingLanguageVoice.h" #import "NSString+EZRegex.h" static NSString *const kAudioMIMEType = @"audio/mpeg"; diff --git a/Easydict/Feature/Service/Model/EZConstKey.h b/Easydict/Feature/Service/Model/EZConstKey.h index f222a128f..b094da26a 100644 --- a/Easydict/Feature/Service/Model/EZConstKey.h +++ b/Easydict/Feature/Service/Model/EZConstKey.h @@ -28,6 +28,7 @@ static NSString *const EZOpenAIModelKey = @"EZOpenAIModelKey"; static NSString *const EZDeepLAuthKey = @"EZDeepLAuthKey"; +static NSString *const EZNiuTransAuthKey = @"EZNiuTransAuthKey"; static NSString *const EZBingCookieKey = @"EZBingCookieKey"; diff --git a/Easydict/Feature/Service/Model/EZDetectManager.m b/Easydict/Feature/Service/Model/EZDetectManager.m index cd2ac003c..ac47a07fd 100644 --- a/Easydict/Feature/Service/Model/EZDetectManager.m +++ b/Easydict/Feature/Service/Model/EZDetectManager.m @@ -91,8 +91,7 @@ - (void)ocrAndDetectText:(void (^)(EZQueryModel *_Nonnull, NSError *_Nullable))c } /// Detect text language. Apple System detect, Google detect, Baidu detect. -- (void)detectText:(NSString *)queryText completion:(void (^)(EZQueryModel *_Nonnull queryModel, NSError *_Nullable error))completion { - if (queryText.length == 0) { +- (void)detectText:(NSString *)queryText completion:(void (^)(EZQueryModel *_Nonnull queryModel, NSError *_Nullable error))completion { if (queryText.length == 0) { NSString *errorString = @"detectText cannot be nil"; NSLog(@"%@", errorString); completion(self.queryModel, [EZTranslateError errorWithString:errorString]); diff --git a/Easydict/Feature/Service/Model/EZEnumTypes.h b/Easydict/Feature/Service/Model/EZEnumTypes.h index 4579b3cd0..6e6129fd4 100644 --- a/Easydict/Feature/Service/Model/EZEnumTypes.h +++ b/Easydict/Feature/Service/Model/EZEnumTypes.h @@ -38,7 +38,7 @@ FOUNDATION_EXPORT EZServiceType const EZServiceTypeVolcano; FOUNDATION_EXPORT EZServiceType const EZServiceTypeOpenAI; FOUNDATION_EXPORT EZServiceType const EZServiceTypeAppleDictionary; FOUNDATION_EXPORT EZServiceType const EZServiceTypeBing; - +FOUNDATION_EXPORT EZServiceType const EZServiceTypeNiuTrans; FOUNDATION_EXPORT NSString *const EZQueryTextTypeKey; FOUNDATION_EXPORT NSString *const EZIntelligentQueryTextTypeKey; @@ -65,6 +65,13 @@ typedef NS_ENUM(NSUInteger, EZDeepLTranslationAPI) { EZDeepLTranslationAPIOnlyOfficical = 2, }; +FOUNDATION_EXPORT NSString *const EZNiuTransTranslationAPIKey; +typedef NS_ENUM(NSUInteger, EZNiuTransTranslationAPI) { + EZNiuTransTranslationAPIWebFirst = 0, + EZNiuTransTranslationAPIOfficialFirst = 1, + EZNiuTransTranslationAPIOnlyOfficical = 2, +}; + typedef NSString *EZActionType NS_STRING_ENUM; FOUNDATION_EXPORT EZActionType const EZActionTypeAutoSelectQuery; diff --git a/Easydict/Feature/Service/Model/EZEnumTypes.m b/Easydict/Feature/Service/Model/EZEnumTypes.m index bb64ee6ca..d6ecf5ec5 100644 --- a/Easydict/Feature/Service/Model/EZEnumTypes.m +++ b/Easydict/Feature/Service/Model/EZEnumTypes.m @@ -18,6 +18,7 @@ NSString *const EZServiceTypeVolcano = @"Volcano"; NSString *const EZServiceTypeOpenAI = @"OpenAI"; NSString *const EZServiceTypeBing = @"Bing"; +NSString *const EZServiceTypeNiuTrans = @"NiuTrans"; NSString *const EZServiceTypeAppleDictionary = @"AppleDictionary"; diff --git a/Easydict/Feature/Service/Model/EZServiceTypes.m b/Easydict/Feature/Service/Model/EZServiceTypes.m index 11fe1270f..e0f6d1515 100644 --- a/Easydict/Feature/Service/Model/EZServiceTypes.m +++ b/Easydict/Feature/Service/Model/EZServiceTypes.m @@ -17,6 +17,7 @@ #import "EZBingService.h" #import "EZConfiguration.h" #import "EZAppleDictionary.h" +#import "EZNiuTransTranslate.h" @interface EZServiceTypes () @@ -55,8 +56,9 @@ + (instancetype)allocWithZone:(struct _NSZone *)zone { EZServiceTypeGoogle, [EZGoogleTranslate class], EZServiceTypeApple, [EZAppleService class], EZServiceTypeBaidu, [EZBaiduTranslate class], - EZServiceTypeVolcano, [EZVolcanoTranslate class], EZServiceTypeBing, [EZBingService class], + EZServiceTypeVolcano, [EZVolcanoTranslate class], + EZServiceTypeNiuTrans, [EZNiuTransTranslate class], nil]; return allServiceDict; } diff --git a/Easydict/Feature/StatusItem/EZMenuItemManager.m b/Easydict/Feature/StatusItem/EZMenuItemManager.m index e65e73865..2535dca35 100644 --- a/Easydict/Feature/StatusItem/EZMenuItemManager.m +++ b/Easydict/Feature/StatusItem/EZMenuItemManager.m @@ -27,8 +27,7 @@ @interface EZMenuItemManager () @property (weak) IBOutlet NSMenuItem *inputItem; @property (weak) IBOutlet NSMenuItem *showMiniItem; @property (weak) IBOutlet NSMenuItem *screenshotOCRItem; - -@property (weak) IBOutlet NSMenuItem *preferencesItem; +@property (weak) IBOutlet NSMenuItem *settingsItem; @property (weak) IBOutlet NSMenuItem *checkForUpdateItem; @property (weak) IBOutlet NSMenuItem *helpItem; @property (weak) IBOutlet NSMenuItem *quitItem; @@ -93,7 +92,7 @@ - (void)setup { self.appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; self.versionItem.title = self.versionTitle; - NSArray *items = @[self.versionItem, self.preferencesItem, self.checkForUpdateItem, self.helpItem, self.quitItem]; + NSArray *items = @[self.versionItem, self.settingsItem, self.checkForUpdateItem, self.helpItem, self.quitItem]; [self increaseMenuItemsHeight:items lineHeightRatio:kTitleMenuItemHeightRatio]; [self updateVersionItem]; @@ -175,8 +174,8 @@ - (IBAction)screenshotOCRAction:(NSMenuItem *)sender { } -- (IBAction)preferenceAction:(NSMenuItem *)sender { - NSLog(@"偏好设置"); +- (IBAction)settingAction:(NSMenuItem *)sender { + NSLog(@"设置..."); if (Snip.shared.isSnapshotting) { [Snip.shared stop]; } diff --git a/Easydict/Feature/Utility/EZCategory/NSString/NSString+EZHandleInputText.h b/Easydict/Feature/Utility/EZCategory/NSString/NSString+EZHandleInputText.h index 7400da743..2425219ce 100644 --- a/Easydict/Feature/Utility/EZCategory/NSString/NSString+EZHandleInputText.h +++ b/Easydict/Feature/Utility/EZCategory/NSString/NSString+EZHandleInputText.h @@ -12,13 +12,17 @@ NS_ASSUME_NONNULL_BEGIN @interface NSString (EZHandleInputText) +/// Split code text by snake case and camel case. - (NSString *)splitCodeText; -- (NSString *)removeCommentSymbols; +/// Remove comment block symbols, /* */ +- (NSString *)removeCommentBlockSymbols; +/// Remove adjacent comment symbol prefix, // and #, and try to join texts. - (NSString *)removeCommentSymbolPrefixAndJoinTexts; -- (NSString *)removeCommentSymbolPrefix; +/// Remove comment symbols, # and // +- (NSString *)removeCommentSymbols; /// Is start with comment symbol prefix, // and # - (BOOL)hasCommentSymbolPrefix; diff --git a/Easydict/Feature/Utility/EZCategory/NSString/NSString+EZHandleInputText.m b/Easydict/Feature/Utility/EZCategory/NSString/NSString+EZHandleInputText.m index 9a1e0b17f..c3aed2485 100644 --- a/Easydict/Feature/Utility/EZCategory/NSString/NSString+EZHandleInputText.m +++ b/Easydict/Feature/Utility/EZCategory/NSString/NSString+EZHandleInputText.m @@ -14,6 +14,7 @@ @implementation NSString (EZHandleInputText) +/// Split code text by snake case and camel case. - (NSString *)splitCodeText { NSString *queryText = [self splitSnakeCaseText]; queryText = [queryText splitCamelCaseText]; @@ -33,31 +34,72 @@ - (NSString *)splitCodeText { } /** - Remove comment symbols + * Creates a {@code UUID} from the string standard representation as + * described in the {@link #toString} method. + * + * @param name + * A string that specifies a {@code UUID} + * + * @return A {@code UUID} with the specified value + * + * @throws IllegalArgumentException + * If name does not conform to the string representation as + * described in {@link #toString} + * */ -- (NSString *)removeCommentSymbols { - // good # girl /*** boy */ --> good girl boy - - // match /* - NSString *pattern1 = @"/\\*+"; - - // match */ - NSString *pattern2 = @"[/*]+"; + +/// Remove comment block symbols, /* */ +- (NSString *)removeCommentBlockSymbols { + NSMutableString *mutableSelf = [self mutableCopy]; + + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"/\\*+(.*?)\\*+/" options:NSRegularExpressionDotMatchesLineSeparators error:nil]; + NSArray *results = [regex matchesInString:self options:0 range:NSMakeRange(0, self.length)]; + + for (NSTextCheckingResult *result in [[results reverseObjectEnumerator] allObjects]) { + NSRange range = [result rangeAtIndex:1]; + NSString *content = [self substringWithRange:range].trim; + NSArray *lines = [content componentsSeparatedByCharactersInSet:[NSCharacterSet newlineCharacterSet]]; + NSMutableArray *mutableLines = [NSMutableArray array]; + for (NSString *line in lines) { + NSString *trimmedLine = [line trim]; + // Remove all prefix * + NSString *newText = [trimmedLine stringByReplacingOccurrencesOfString:@"\\*+" + withString:@"" + options:NSRegularExpressionSearch + range:NSMakeRange(0, trimmedLine.length)]; + [mutableLines addObject:newText.trim]; + } + + NSString *modifiedBlock = [mutableLines componentsJoinedByString:@"\n"]; + [mutableSelf replaceCharactersInRange:result.range withString:modifiedBlock]; + } + return mutableSelf; +} + +/** + Remove comment symbols, # and // + */ +- (NSString *)removeCommentSymbols2 { // match // and # - NSString *pattern3 = @"//|#"; - - NSString *combinedPattern = [NSString stringWithFormat:@"%@|%@|%@", pattern1, pattern2, pattern3]; - - NSString *cleanedText = [self stringByReplacingOccurrencesOfString:combinedPattern + NSString *pattern = @"//|#"; + NSString *cleanedText = [self stringByReplacingOccurrencesOfString:pattern withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, self.length)]; - return cleanedText; } +- (NSString *)removeCommentSymbols { + // match // and #, # abc #ddd # fff '#' ggg # +// NSString *pattern = @"(^\\s*[//|#]\\s+)|(\\s+[//|#]\\s*$)|(\\s+[//|#]\\s+)"; + NSString *pattern = @"(^|\\s)(\\/\\/|\\#)(\\s|$)"; // replace // and # with white space + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:nil]; + NSString *cleanedText = [regex stringByReplacingMatchesInString:self options:0 range:NSMakeRange(0, self.length) withTemplate:@"$1"]; + return cleanedText; +} + /** // These values will persist after the process is killed by the system // and remain available via the same object. @@ -68,10 +110,10 @@ - (NSString *)removeCommentSymbols { // good boy. hello - */ + +/// Remove adjacent comment symbol prefix, // and #, and try to join texts. - (NSString *)removeCommentSymbolPrefixAndJoinTexts { - // 分割文本为行数组 NSArray *lines = [self componentsSeparatedByString:@"\n"]; NSMutableString *resultText = [NSMutableString string]; @@ -79,8 +121,6 @@ - (NSString *)removeCommentSymbolPrefixAndJoinTexts { for (int i = 0; i < lines.count; i++) { NSString *line = lines[i]; - - // 去除行首和行尾的空格和换行符 NSString *trimmedLine = [line stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; if ([trimmedLine hasCommentSymbolPrefix]) { diff --git a/Easydict/Feature/Utility/EZDeviceSystemInfo/EZDeviceSystemInfo.h b/Easydict/Feature/Utility/EZDeviceSystemInfo/EZDeviceSystemInfo.h index ac5c3f745..32191bbf6 100644 --- a/Easydict/Feature/Utility/EZDeviceSystemInfo/EZDeviceSystemInfo.h +++ b/Easydict/Feature/Utility/EZDeviceSystemInfo/EZDeviceSystemInfo.h @@ -14,6 +14,9 @@ NS_ASSUME_NONNULL_BEGIN + (NSDictionary *)getDeviceSystemInfo; +/// Get system version, eg 14.0.0 ++ (NSString *)getSystemVersion; + @end NS_ASSUME_NONNULL_END diff --git a/Easydict/Feature/Utility/EZDeviceSystemInfo/EZDeviceSystemInfo.m b/Easydict/Feature/Utility/EZDeviceSystemInfo/EZDeviceSystemInfo.m index 3f62cb2f1..79e11eb56 100644 --- a/Easydict/Feature/Utility/EZDeviceSystemInfo/EZDeviceSystemInfo.m +++ b/Easydict/Feature/Utility/EZDeviceSystemInfo/EZDeviceSystemInfo.m @@ -13,8 +13,11 @@ @implementation EZDeviceSystemInfo + (NSDictionary *)getDeviceSystemInfo { + + NSDictionary *infoDictionary = NSBundle.mainBundle.infoDictionary; // 1.3.4 - NSString *appVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; + NSString *appVersion = infoDictionary[@"CFBundleShortVersionString"]; + NSString *buildVersion = infoDictionary[@"CFBundleVersion"]; NSProcessInfo *processInfo = [NSProcessInfo processInfo]; // 版本13.5(版号22G5059d) @@ -28,15 +31,16 @@ + (NSDictionary *)getDeviceSystemInfo { NSString *deviceModel = [self getDeviceModel]; NSString *uuidString = [self getDeviceUUID]; - NSDictionary *infoDictionary = @{ + NSDictionary *infoDict = @{ @"Version" : appVersion, + @"Build" : buildVersion, @"System" : systemVersion, @"Device" : deviceModel, @"Machine" : machine, @"UUID" : uuidString }; - return infoDictionary; + return infoDict; } @@ -61,4 +65,11 @@ + (NSString *)getDeviceUUID { return uuid; } +/// Get system version, eg 14.0.0 ++ (NSString *)getSystemVersion { + NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion]; + NSString *versionString = [NSString stringWithFormat:@"%ld.%ld.%ld", (long)version.majorVersion, (long)version.minorVersion, (long)version.patchVersion]; + return versionString; +} + @end diff --git a/Easydict/Feature/Utility/EZLinkParser/EZSchemeParser.m b/Easydict/Feature/Utility/EZLinkParser/EZSchemeParser.m index 35fe9e0eb..68666353c 100644 --- a/Easydict/Feature/Utility/EZLinkParser/EZSchemeParser.m +++ b/Easydict/Feature/Utility/EZLinkParser/EZSchemeParser.m @@ -14,6 +14,7 @@ #import "EZConfiguration+EZUserData.h" #import "EZConfiguration.h" #import "EZLocalStorage.h" +#import "EZNiuTransTranslate.h" @implementation EZSchemeParser @@ -176,6 +177,8 @@ - (NSArray *)allowedReadWriteKeys { easydict://writeKeyValue?EZDeepLAuthKey=xxx easydict://writeKeyValue?EZDeepLTranslationAPIKey=1 + easydict://writeKeyValue?EZNiuTransAuthKey=xxx + // Youdao TTS easydict://writeKeyValue?EZDefaultTTSServiceKey=Youdao @@ -199,10 +202,12 @@ - (NSArray *)allowedReadWriteKeys { EZOpenAIModelKey, EZYoudaoTranslationKey, - EZYoudaoDictionaryKey, + EZYoudaoDictionaryKey, EZDeepLAuthKey, EZDeepLTranslationAPIKey, + + EZNiuTransAuthKey, EZIntelligentQueryModeKey, diff --git a/Easydict/Feature/Utility/EZLog/EZLog.h b/Easydict/Feature/Utility/EZLog/EZLog.h index 361a98773..cef8f48e5 100644 --- a/Easydict/Feature/Utility/EZLog/EZLog.h +++ b/Easydict/Feature/Utility/EZLog/EZLog.h @@ -22,6 +22,8 @@ NS_ASSUME_NONNULL_BEGIN + (void)logQueryService:(EZQueryService *)service; + (void)logQuery:(EZQueryModel *)model; ++ (void)logAppInfo; + + (NSString *)textLengthRange:(NSString *)text; @end diff --git a/Easydict/Feature/Utility/EZLog/EZLog.m b/Easydict/Feature/Utility/EZLog/EZLog.m index 8f4607d80..04de662f9 100644 --- a/Easydict/Feature/Utility/EZLog/EZLog.m +++ b/Easydict/Feature/Utility/EZLog/EZLog.m @@ -9,6 +9,7 @@ #import "EZLog.h" #import "EZConfiguration.h" #import "FWEncryptorAES.h" +#import "EZDeviceSystemInfo.h" @import FirebaseCore; @import FirebaseAnalytics; @@ -109,4 +110,12 @@ + (NSString *)textLengthRange:(NSString *)text { } } ++ (void)logAppInfo { + NSString *version = [EZDeviceSystemInfo getSystemVersion]; + NSDictionary *dict = @{ + @"system_version" : version + }; + [EZLog logEventWithName:@"app_info" parameters:dict]; +} + @end diff --git a/Easydict/Feature/ViewController/Model/EZQueryModel.m b/Easydict/Feature/ViewController/Model/EZQueryModel.m index 412c2e15f..4853a81c6 100644 --- a/Easydict/Feature/ViewController/Model/EZQueryModel.m +++ b/Easydict/Feature/ViewController/Model/EZQueryModel.m @@ -199,8 +199,10 @@ - (NSString *)handleInputText:(NSString *)inputText { } if (EZConfiguration.shared.isBeta) { + // Remove prefix // && #, and join texts. queryText = [queryText removeCommentSymbolPrefixAndJoinTexts]; - queryText = [queryText removeCommentSymbols]; + // Remove /* */ + queryText = [queryText removeCommentBlockSymbols]; } return [queryText trim]; diff --git a/Easydict/Feature/ViewController/Storage/EZLocalStorage.m b/Easydict/Feature/ViewController/Storage/EZLocalStorage.m index 962b55624..9362c240e 100644 --- a/Easydict/Feature/ViewController/Storage/EZLocalStorage.m +++ b/Easydict/Feature/ViewController/Storage/EZLocalStorage.m @@ -58,12 +58,12 @@ - (void)setup { serviceInfo.type = serviceType; serviceInfo.enabled = YES; - // Mini type should keep concise. + // Mini type should keep concise, services <= 4 if (windowType == EZWindowTypeMini) { NSArray *defaultEnabledServices = @[ - EZServiceTypeOpenAI, - EZServiceTypeDeepL, + EZServiceTypeAppleDictionary, EZServiceTypeYoudao, + EZServiceTypeDeepL, EZServiceTypeGoogle, ]; serviceInfo.enabled = [defaultEnabledServices containsObject:serviceType]; diff --git a/Easydict/Feature/ViewController/View/EZQueryMenuTextView/EZQueryMenuTextView.m b/Easydict/Feature/ViewController/View/EZQueryMenuTextView/EZQueryMenuTextView.m index 4df94de67..6a88cde89 100644 --- a/Easydict/Feature/ViewController/View/EZQueryMenuTextView/EZQueryMenuTextView.m +++ b/Easydict/Feature/ViewController/View/EZQueryMenuTextView/EZQueryMenuTextView.m @@ -66,12 +66,10 @@ - (void)queryInApp:(id)sender { floatingWindow.titleBar.pin = YES; EZBaseQueryWindow *anotherFloatingWindow = [windowManager windowWithType:anotherWindowType]; - if (anotherFloatingWindow.isVisible) { - EZBaseQueryViewController *anotherQueryViewController = anotherFloatingWindow.queryViewController; - + if (anotherFloatingWindow.isPin) { // Focus query view controller, make sure floating window type is current query window. - [anotherFloatingWindow makeKeyAndOrderFront:nil]; - [anotherQueryViewController focusInputTextView]; + [windowManager orderFrontWindowAndFocusInputTextView:anotherFloatingWindow]; + EZBaseQueryViewController *anotherQueryViewController = anotherFloatingWindow.queryViewController; [anotherQueryViewController startQueryText:self.queryText actionType:actionType]; } else { NSScreen *screen = EZLayoutManager.shared.screen; diff --git a/Easydict/Feature/ViewController/View/WordResultView/EZWordResultView.m b/Easydict/Feature/ViewController/View/WordResultView/EZWordResultView.m index 3b9b1ab94..42587aee4 100644 --- a/Easydict/Feature/ViewController/View/WordResultView/EZWordResultView.m +++ b/Easydict/Feature/ViewController/View/WordResultView/EZWordResultView.m @@ -910,10 +910,7 @@ - (void)updateTagButton:(NSButton *)tagButton tagColor:(NSColor *)tagColor { - (CGSize)labelSize:(EZLabel *)label exceptedWidth:(CGFloat)exceptedWidth { // ???: 很奇怪,比如实际计算结果为 364,但界面渲染却是 364.5 😑 - - NSWindow *window = [self windowOfType:self.result.service.windowType]; - CGFloat selfWidth = window ? window.width - EZHorizontalCellSpacing_10 * 2 : self.width; - CGFloat width = selfWidth - exceptedWidth; + CGFloat width = self.width - exceptedWidth; // NSLog(@"text: %@, width: %@", label.text, @(width)); // NSLog(@"self.width: %@, selfWidth: %@", @(self.width), @(selfWidth)); diff --git a/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m b/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m index 42bb36806..abb8ac5d6 100644 --- a/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m +++ b/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m @@ -434,8 +434,9 @@ - (void)startOCRImage:(NSImage *)image actionType:(EZActionType)actionType { mm_weakify(self); [self.detectManager ocrAndDetectText:^(EZQueryModel *_Nonnull queryModel, NSError *_Nullable error) { mm_strongify(self); - NSString *queryText = queryModel.queryText; - NSLog(@"ocr result: %@", queryText); + // !!!: inputText should be used here, not queryText, queryText may be modified, such as easydict://query?text=xxx + NSString *inputText = queryModel.inputText; + NSLog(@"ocr result: %@", inputText); NSDictionary *dict = @{ @"detectedLanguage" : queryModel.detectedLanguage, @@ -445,7 +446,7 @@ - (void)startOCRImage:(NSImage *)image actionType:(EZActionType)actionType { if (actionType == EZActionTypeScreenshotOCR) { - [queryText copyToPasteboardSafely]; + [inputText copyToPasteboardSafely]; [EZToast showSuccessToast]; @@ -456,12 +457,12 @@ - (void)startOCRImage:(NSImage *)image actionType:(EZActionType)actionType { if (actionType == EZActionTypeOCRQuery) { [self.queryView startLoadingAnimation:NO]; - self.inputText = queryText; + self.inputText = inputText; // Show detected language, even auto self.queryModel.showAutoLanguage = YES; - [self updateQueryTextAndParagraphStyle:queryText actionType:actionType]; + [self updateQueryTextAndParagraphStyle:inputText actionType:actionType]; if (error) { NSString *errorMsg = [error localizedDescription]; @@ -470,7 +471,7 @@ - (void)startOCRImage:(NSImage *)image actionType:(EZActionType)actionType { } if (EZConfiguration.shared.autoCopyOCRText) { - [queryText copyToPasteboardSafely]; + [inputText copyToPasteboardSafely]; } [self.queryView highlightAllLinks]; diff --git a/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryWindow.h b/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryWindow.h index 5588d92c4..a89c8bf80 100644 --- a/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryWindow.h +++ b/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryWindow.h @@ -16,7 +16,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, assign) EZWindowType windowType; @property (nonatomic, strong) EZTitlebar *titleBar; -@property (nonatomic, assign) BOOL pin; +@property (nonatomic, assign, getter=isPin) BOOL pin; @property (nonatomic, strong) EZBaseQueryViewController *queryViewController; diff --git a/Easydict/Feature/ViewController/Window/WindowManager/EZWindowManager.h b/Easydict/Feature/ViewController/Window/WindowManager/EZWindowManager.h index fcf49206e..77ee2d2df 100644 --- a/Easydict/Feature/ViewController/Window/WindowManager/EZWindowManager.h +++ b/Easydict/Feature/ViewController/Window/WindowManager/EZWindowManager.h @@ -61,16 +61,19 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - URL scheme /// Show floating window. -- (void)showFloatingWindowType:(EZWindowType)type +- (void)showFloatingWindowType:(EZWindowType)windowType queryText:(nullable NSString *)text + autoQuery:(BOOL)autoQuery actionType:(EZActionType)actionType; - (void)showFloatingWindowType:(EZWindowType)windowType - queryText:(NSString *)text + queryText:(nullable NSString *)text actionType:(EZActionType)actionType atPoint:(CGPoint)point completionHandler:(nullable void (^)(void))completionHandler; +- (void)orderFrontWindowAndFocusInputTextView:(EZBaseQueryWindow *)window; + - (void)detectQueryText:(NSString *)text completion:(nullable void (^)(NSString *language))completion; #pragma mark - diff --git a/Easydict/Feature/ViewController/Window/WindowManager/EZWindowManager.m b/Easydict/Feature/ViewController/Window/WindowManager/EZWindowManager.m index 0a1d46242..69f226f97 100644 --- a/Easydict/Feature/ViewController/Window/WindowManager/EZWindowManager.m +++ b/Easydict/Feature/ViewController/Window/WindowManager/EZWindowManager.m @@ -69,47 +69,47 @@ - (void)setup { self.screen = NSScreen.mainScreen; self.floatingWindowTypeArray = [NSMutableArray arrayWithArray:@[ @(EZWindowTypeNone) ]]; self.actionType = EZActionTypeInvokeQuery; - + self.eventMonitor = [EZEventMonitor shared]; [self setupEventMonitor]; - + // NSLog(@"%@", self.floatingWindowTypeArray); } - (void)setupEventMonitor { [self.eventMonitor startMonitor]; - + mm_weakify(self); [self.eventMonitor setSelectedTextBlock:^(NSString *_Nonnull selectedText) { mm_strongify(self); - + // if ([self hasEasydictRunningInDebugMode]) { // return; // } - + self.selectedText = selectedText ?: @""; self.actionType = self.eventMonitor.actionType; - + // !!!: Record current selected start and end point, eventMonitor's startPoint will change every valid event. self.startPoint = self.eventMonitor.startPoint; self.endPoint = self.eventMonitor.endPoint; - + CGPoint point = [self getPopButtonWindowLocation]; // This is top-left point CGPoint bottomLeftPoint = CGPointMake(point.x, point.y - self.popButtonWindow.height); CGPoint safePoint = [EZCoordinateUtils getFrameSafePoint:self.popButtonWindow.frame moveToPoint:bottomLeftPoint inScreen:self.screen]; [self.popButtonWindow setFrameOrigin:safePoint]; - + [self.popButtonWindow orderFrontRegardless]; // Set a high level to make sure it's always on top of other windows, such as PopClip. self.popButtonWindow.level = kCGScreenSaverWindowLevel; - + if ([EZMainQueryWindow isAlive]) { [self.mainWindow orderBack:nil]; } }]; - + [self updatePopButtonQueryAction]; - + [self.eventMonitor setLeftMouseDownBlock:^(CGPoint clickPoint) { mm_strongify(self); self.startPoint = clickPoint; @@ -122,30 +122,30 @@ - (void)setupEventMonitor { self.screen = [EZCoordinateUtils screenForPoint:clickPoint]; EZLayoutManager.shared.screen = self.screen; }]; - + [self.eventMonitor setDismissPopButtonBlock:^{ mm_strongify(self); // NSLog(@"dismiss pop button"); [self.popButtonWindow close]; }]; - + [self.eventMonitor setDismissMiniWindowBlock:^{ mm_strongify(self); if (!self.floatingWindow.pin && self.floatingWindow.visible) { [self closeFloatingWindow]; } }]; - + [self.eventMonitor setDismissFixedWindowBlock:^{ mm_strongify(self); if (!self.floatingWindow.pin) { [self closeFloatingWindow]; } }]; - + [self.eventMonitor setDoubleCommandBlock:^{ NSLog(@"double command"); - + // TODO: Let users customize double-click shortcuts later on #if DEBUG mm_strongify(self); @@ -158,17 +158,17 @@ - (void)setupEventMonitor { /// Update pop button query action. - (void)updatePopButtonQueryAction { mm_weakify(self); - + EZButton *popButton = self.popButtonWindow.popButton; EZConfiguration *config = [EZConfiguration shared]; - + if (config.hideMainWindow) { // FIXME: Click pop button will also show preferences window. [popButton setClickBlock:^(EZButton *button) { mm_strongify(self); [self popButtonWindowClicked]; }]; - + if (config.clickQuery) { popButton.mouseEnterBlock = nil; } else { @@ -179,7 +179,7 @@ - (void)updatePopButtonQueryAction { } } else { popButton.clickBlock = nil; - + [popButton setMouseEnterBlock:^(EZButton *button) { mm_strongify(self); [self popButtonWindowClicked]; @@ -290,35 +290,47 @@ - (CGPoint)floatingWindowLocationWithType:(EZWindowType)type { } /// Show floating window. -- (void)showFloatingWindowType:(EZWindowType)windowType queryText:(nullable NSString *)text { - [self showFloatingWindowType:windowType queryText:text actionType:self.actionType]; +- (void)showFloatingWindowType:(EZWindowType)windowType queryText:(nullable NSString *)queryText { + [self showFloatingWindowType:windowType queryText:queryText actionType:self.actionType]; } -- (void)showFloatingWindowType:(EZWindowType)windowType queryText:(NSString *)text actionType:(EZActionType)actionType { +- (void)showFloatingWindowType:(EZWindowType)windowType + queryText:(nullable NSString *)queryText + actionType:(EZActionType)actionType { + BOOL autoQuery = [EZConfiguration.shared autoQuerySelectedText]; + [self showFloatingWindowType:windowType queryText:queryText autoQuery:autoQuery actionType:actionType]; +} + +- (void)showFloatingWindowType:(EZWindowType)windowType + queryText:(nullable NSString *)queryText + autoQuery:(BOOL)autoQuery + actionType:(EZActionType)actionType { CGPoint point = [self floatingWindowLocationWithType:windowType]; - [self showFloatingWindowType:windowType queryText:text actionType:actionType atPoint:point]; + [self showFloatingWindowType:windowType queryText:queryText autoQuery:autoQuery actionType:actionType atPoint:point completionHandler:nil]; } - (void)showFloatingWindowType:(EZWindowType)windowType - queryText:(NSString *)text + queryText:(nullable NSString *)queryText actionType:(EZActionType)actionType - atPoint:(CGPoint)point { - [self showFloatingWindowType:windowType queryText:text actionType:actionType atPoint:point completionHandler:nil]; + atPoint:(CGPoint)point + completionHandler:(nullable void (^)(void))completionHandler { + BOOL autoQuery = [EZConfiguration.shared autoQuerySelectedText]; + [self showFloatingWindowType:windowType queryText:queryText autoQuery:autoQuery actionType:actionType atPoint:point completionHandler:completionHandler]; } - (void)showFloatingWindowType:(EZWindowType)windowType - queryText:(NSString *)text + queryText:(nullable NSString *)queryText + autoQuery:(BOOL)autoQuery actionType:(EZActionType)actionType atPoint:(CGPoint)point - completionHandler:(nullable void (^)(void))completionHandler -{ - self.selectedText = text; + completionHandler:(nullable void (^)(void))completionHandler { + self.selectedText = queryText; self.actionType = actionType; - + EZBaseQueryWindow *window = [self windowWithType:windowType]; - + // If text is nil, means we don't need to query anything, just show the window. - if (!text) { + if (!queryText) { // !!!: location is top-left point, so we need to change it to bottom-left point. CGPoint newPoint = CGPointMake(point.x, point.y - window.height); [self showFloatingWindow:window atPoint:newPoint]; @@ -329,33 +341,56 @@ - (void)showFloatingWindowType:(EZWindowType)windowType return; } - + // Log selected text when querying. [self logSelectedTextEvent]; - - // Reset tableView and window height first, avoid being affected by previous window height. - + EZBaseQueryViewController *queryViewController = window.queryViewController; - [queryViewController resetTableView:^{ - [queryViewController updateQueryTextAndParagraphStyle:text actionType:self.actionType]; + + void (^updateQueryTextAndStartQueryBlock)(BOOL) = ^(BOOL needFocus){ + // Update input text and detect. + [queryViewController updateQueryTextAndParagraphStyle:queryText actionType:self.actionType]; [queryViewController detectQueryText:nil]; - - // !!!: window height has changed, so we need to update location again. - CGPoint newPoint = CGPointMake(point.x, point.y - window.height); - [self showFloatingWindow:window atPoint:newPoint]; - - if ([EZConfiguration.shared autoQuerySelectedText]) { - [queryViewController startQueryText:text actionType:self.actionType]; + + if (needFocus) { + // Order front and focus floating window. + [self orderFrontWindowAndFocusInputTextView:window]; } - + + if (autoQuery) { + [queryViewController startQueryText:queryText actionType:self.actionType]; + } + + // TODO: Maybe we should remove this option, it seems useless. if ([EZConfiguration.shared autoCopySelectedText]) { - [text copyToPasteboard]; + [queryText copyToPasteboard]; } if (completionHandler) { completionHandler(); } - }]; + }; + + if (!window.isPin) { + // Reset tableView and window height first, avoid being affected by previous window height. + [queryViewController resetTableView:^{ + // !!!: window height has changed, so we need to update location again. + CGPoint newPoint = CGPointMake(point.x, point.y - window.height); + [self showFloatingWindow:window atPoint:newPoint]; + updateQueryTextAndStartQueryBlock(NO); + }]; + } else { + // If window is pinned, we don't need to reset tableView. + updateQueryTextAndStartQueryBlock(YES); + } +} + +- (void)orderFrontWindowAndFocusInputTextView:(EZBaseQueryWindow *)window { + [self saveFrontmostApplication]; + + // Focus floating window. + [window makeKeyAndOrderFront:nil]; + [window.queryViewController focusInputTextView]; } - (void)detectQueryText:(NSString *)text completion:(nullable void (^)(NSString *language))completion { @@ -366,41 +401,41 @@ - (void)detectQueryText:(NSString *)text completion:(nullable void (^)(NSString - (void)showFloatingWindow:(EZBaseQueryWindow *)window atPoint:(CGPoint)point { // NSLog(@"show floating window: %@, %@", window, @(point)); - + [self saveFrontmostApplication]; - + if (Snip.shared.isSnapshotting) { return; } - + EZPreferencesWindowController *preferencesWindowController = [EZPreferencesWindowController shared]; if (preferencesWindowController.isShowing) { [preferencesWindowController.window close]; } - + // get safe window position CGPoint safeLocation = [EZCoordinateUtils getFrameSafePoint:window.frame moveToPoint:point inScreen:self.screen]; [window setFrameOrigin:safeLocation]; window.level = EZFloatingWindowLevel; - + // FIXME: need to optimize. we have to remove it temporary, and orderBack: when close floating window. if ([EZMainQueryWindow isAlive]) { [self.mainWindow orderOut:nil]; } - + // NSLog(@"window frame: %@", @(window.frame)); - + // ???: This code will cause warning: [Window] Warning: Window EZFixedQueryWindow 0x107f04db0 ordered front from a non-active application and may order beneath the active application's windows. [window makeKeyAndOrderFront:nil]; - + /// ???: orderFrontRegardless will cause OCR show blank window when window has shown. // [window orderFrontRegardless]; - + // !!!: Focus input textView should behind makeKeyAndOrderFront:, otherwise it will not work in the first time. [window.queryViewController focusInputTextView]; - + [self updateFloatingWindowType:window.windowType]; - + // mainWindow has been ordered out before, so we need to order back. if ([EZMainQueryWindow isAlive]) { [self.mainWindow orderBack:nil]; @@ -415,7 +450,7 @@ - (void)updateFloatingWindowType:(EZWindowType)floatingWindowType { - (NSScreen *)getMouseLocatedScreen { NSPoint mouseLocation = [NSEvent mouseLocation]; // ???: self.endPoint - + // 找到鼠标所在屏幕 NSScreen *screen = [NSScreen.screens mm_find:^id(NSScreen *_Nonnull obj, NSUInteger idx) { return NSPointInRect(mouseLocation, obj.frame) ? obj : nil; @@ -426,7 +461,7 @@ - (NSScreen *)getMouseLocatedScreen { return MMPointInRect(mouseLocation, obj.frame) ? obj : nil; }]; } - + return screen; } @@ -435,40 +470,40 @@ - (NSScreen *)getMouseLocatedScreen { - (CGPoint)getPopButtonWindowLocation { NSPoint location = [NSEvent mouseLocation]; // NSLog(@"mouseLocation: (%.1f, %.1f)", location.x, location.y); - + if (CGPointEqualToPoint(location, CGPointZero)) { return CGPointZero; } - + NSPoint startLocation = self.startPoint; NSPoint endLocation = self.endPoint; - + // Direction from left to right. BOOL isDirectionRight = endLocation.x >= startLocation.x; // Direction from top to bottom. BOOL isDirectionDown = YES; - + CGFloat minLineHeight = 20; - + CGFloat deltaY = endLocation.y - startLocation.y; // Direction up. if (deltaY > minLineHeight / 2) { isDirectionDown = NO; isDirectionRight = NO; } - + CGFloat x = location.x; CGFloat y = location.y; - + // self.offsetPoint is (15, -15) - + x += self.offsetPoint.x; y += self.offsetPoint.y; - + // FIXME: If adjust y when Direction is Up, it will cause some UI bugs 😢 // TODO: This codo is too ugly, need to optimize. - - + + // if (isDirectionDown) { // x += self.offsetPoint.x; // y += self.offsetPoint.y; @@ -477,29 +512,29 @@ - (CGPoint)getPopButtonWindowLocation { // // Direction up, show pop button window above the selected text. // y = location.y - self.offsetPoint.y + self.popButtonWindow.height + 5; // } - + // CGRect selectedTextFrame = self.eventMonitor.selectedTextFrame; // NSLog(@"selected text frame: %@", NSStringFromRect(selectedTextFrame)); // NSLog(@"start point: %@", NSStringFromPoint(startLocation)); // NSLog(@"end point: %@", NSStringFromPoint(endLocation)); - + if (EZConfiguration.shared.adjustPopButtomOrigin) { // Since the pop button may cover selected text, we need to move it to the left. CGFloat horizontalOffset = 20; - + x = location.x; if (isDirectionRight) { x += horizontalOffset; } else { x -= (horizontalOffset + self.popButtonWindow.width); } - + y = location.y - self.offsetPoint.y; } - + NSPoint popLocation = CGPointMake(x, y); // NSLog(@"popLocation: %@", NSStringFromPoint(popLocation)); - + return popLocation; } @@ -514,7 +549,7 @@ - (CGPoint)getMiniWindowLocation { CGRect formerFrame = [EZLayoutManager.shared windowFrameWithType:EZWindowTypeMini]; position = [EZCoordinateUtils getFrameTopLeftPoint:formerFrame]; } - + return position; } @@ -528,24 +563,24 @@ - (CGPoint)getMouseLocation:(BOOL)offsetFlag { if (CGPointEqualToPoint(popButtonLocation, CGPointZero)) { return CGPointZero; } - + CGPoint mouseLocation = NSEvent.mouseLocation; CGPoint showingPosition = mouseLocation; - + if (offsetFlag) { CGFloat x = popButtonLocation.x + 5; // Move slightly to the right to avoid covering the cursor. - - + + // if pop button is left to selected text, we need to move showing mouse location to a bit right, to show query window properly. if (mouseLocation.x > popButtonLocation.x) { x = NSEvent.mouseLocation.x + 5; } - + CGFloat y = popButtonLocation.y + 0; - + showingPosition = CGPointMake(x, y); } - + return showingPosition; } @@ -579,29 +614,29 @@ - (CGPoint)getFixedWindowLocation { - (CGPoint)getFloatingWindowInRightSideOfScreenPoint:(NSWindow *)floatingWindow { CGPoint position = CGPointZero; - + NSScreen *targetScreen = self.screen; NSRect screenRect = [targetScreen visibleFrame]; - + CGFloat x = screenRect.origin.x + screenRect.size.width - floatingWindow.width; CGFloat y = screenRect.origin.y + screenRect.size.height; position = CGPointMake(x, y); - + return position; } /// Get the position of floatingWindow that make sure floatingWindow show in the center of self.screen. - (CGPoint)getFloatingWindowInCenterOfScreenPoint:(NSWindow *)floatingWindow { CGPoint position = CGPointZero; - + NSScreen *targetScreen = self.screen; NSRect screenRect = [targetScreen visibleFrame]; - + // top-left point CGFloat x = screenRect.origin.x + (screenRect.size.width - floatingWindow.width) / 2; CGFloat y = screenRect.origin.y + (screenRect.size.height - floatingWindow.height) / 2 + floatingWindow.height; position = CGPointMake(x, y); - + return position; } @@ -612,7 +647,7 @@ - (void)saveFrontmostApplication { if ([frontmostApplication.bundleIdentifier isEqualToString:identifier]) { return; } - + self.lastFrontmostApplication = frontmostApplication; } @@ -620,10 +655,10 @@ - (void)showMainWindowIfNedded { BOOL showFlag = !EZConfiguration.shared.hideMainWindow; NSApplicationActivationPolicy activationPolicy = showFlag ? NSApplicationActivationPolicyRegular : NSApplicationActivationPolicyAccessory; [NSApp setActivationPolicy:activationPolicy]; - + if (showFlag) { [self.floatingWindowTypeArray insertObject:@(EZWindowTypeMain) atIndex:0]; - + EZMainQueryWindow *mainWindow = [EZWindowManager shared].mainWindow; [mainWindow center]; [mainWindow makeKeyAndOrderFront:nil]; @@ -632,9 +667,9 @@ - (void)showMainWindowIfNedded { - (void)closeMainWindowIfNeeded { [NSApp setActivationPolicy:NSApplicationActivationPolicyAccessory]; - + [self.floatingWindowTypeArray removeObject:@(EZWindowTypeMain)]; - + if ([EZMainQueryWindow isAlive]) { [EZMainQueryWindow destroySharedInstance]; } @@ -644,17 +679,17 @@ - (void)closeMainWindowIfNeeded { - (void)selectTextTranslate { MMLogInfo(@"selectTextTranslate"); - + if (![self.eventMonitor isAccessibilityEnabled]) { NSLog(@"App is not trusted"); return; } - + [self saveFrontmostApplication]; if (Snip.shared.isSnapshotting) { return; } - + EZWindowType windowType = EZConfiguration.shared.shortcutSelectTranslateWindowType; NSLog(@"selectTextTranslate windowType: %@", @(windowType)); self.eventMonitor.actionType = EZActionTypeShortcutQuery; @@ -668,26 +703,26 @@ - (void)selectTextTranslate { - (void)snipTranslate { MMLogInfo(@"snipTranslate"); - + // if ([self hasEasydictRunningInDebugMode]) { // return; // } - + [self saveFrontmostApplication]; - + if (Snip.shared.isSnapshotting) { return; } - + // Since ocr detect may be inaccurate, sometimes need to set sourceLanguage manually, so show Fixed window. EZWindowType windowType = EZConfiguration.shared.shortcutSelectTranslateWindowType; EZBaseQueryWindow *window = [self windowWithType:windowType]; - + // FIX https://github.com/tisfeng/Easydict/issues/126 if (!self.floatingWindow.pin) { [self closeFloatingWindow]; } - + // Wait to close floating window if need. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [Snip.shared startWithCompletion:^(NSImage *_Nullable image) { @@ -695,9 +730,9 @@ - (void)snipTranslate { NSLog(@"not get screenshot"); return; } - + NSLog(@"get screenshot: %@", image); - + // 缓存最后一张图片,统一放到 MMLogs 文件夹,方便管理 static NSString *_imagePath = nil; static dispatch_once_t onceToken; @@ -707,7 +742,7 @@ - (void)snipTranslate { [[NSFileManager defaultManager] removeItemAtPath:_imagePath error:nil]; [image mm_writeToFileAsPNG:_imagePath]; NSLog(@"已保存图片: %@", _imagePath); - + // Reset window height first, avoid being affected by previous window height. [window.queryViewController resetTableView:^{ [self showFloatingWindowType:windowType queryText:nil]; @@ -719,24 +754,24 @@ - (void)snipTranslate { - (void)inputTranslate { MMLogInfo(@"inputTranslate"); - + [self saveFrontmostApplication]; if (Snip.shared.isSnapshotting) { return; } - + EZWindowType windowType = EZConfiguration.shared.shortcutSelectTranslateWindowType; - + if (self.floatingWindowType == windowType) { [self closeFloatingWindow]; return; } - + NSString *queryText = nil; if ([EZConfiguration.shared clearInput]) { queryText = @""; } - + self.actionType = EZActionTypeInputQuery; [self showFloatingWindowType:windowType queryText:queryText]; } @@ -744,35 +779,35 @@ - (void)inputTranslate { /// Show mini window at last positon. - (void)showMiniFloatingWindow { MMLogInfo(@"showMiniFloatingWindow"); - + EZWindowType windowType = EZConfiguration.shared.mouseSelectTranslateWindowType; if (self.floatingWindowType == windowType) { [self closeFloatingWindow]; return; } - + self.actionType = EZActionTypeInputQuery; [self showFloatingWindowType:windowType queryText:nil]; } - (void)screenshotOCR { MMLogInfo(@"screenshotOCR"); - + [self saveFrontmostApplication]; - + if (Snip.shared.isSnapshotting) { return; } - + [Snip.shared startWithCompletion:^(NSImage *_Nullable image) { if (!image) { NSLog(@"not get screenshot"); return; } - + NSLog(@"get screenshot: %@", image); - + // 缓存最后一张图片,统一放到 MMLogs 文件夹,方便管理 static NSString *_imagePath = nil; static dispatch_once_t onceToken; @@ -782,7 +817,7 @@ - (void)screenshotOCR { [[NSFileManager defaultManager] removeItemAtPath:_imagePath error:nil]; [image mm_writeToFileAsPNG:_imagePath]; NSLog(@"已保存图片: %@", _imagePath); - + [self.backgroundQueryViewController startOCRImage:image actionType:EZActionTypeScreenshotOCR]; }]; } @@ -793,7 +828,7 @@ - (void)rerty { if (Snip.shared.isSnapshotting) { return; } - + if ([[NSApplication sharedApplication] keyWindow] == self.floatingWindow) { // 执行重试 [self.floatingWindow.queryViewController retryQuery]; @@ -802,13 +837,13 @@ - (void)rerty { - (void)clearInput { NSLog(@"Clear input"); - + [self.floatingWindow.queryViewController clearInput]; } - (void)clearAll { NSLog(@"Clear All"); - + [self.floatingWindow.queryViewController clearAll]; } @@ -822,14 +857,14 @@ - (void)copyFirstTranslatedText { - (void)pin { NSLog(@"Pin"); - + EZBaseQueryWindow *queryWindow = EZWindowManager.shared.floatingWindow; queryWindow.titleBar.pin = !queryWindow.titleBar.pin; } - (void)closeWindowOrExitSreenshot { NSLog(@"Close window, or exit screenshot"); - + if (Snip.shared.isSnapshotting) { [Snip.shared stop]; } else { @@ -858,28 +893,28 @@ - (void)playOrStopQueryTextAudio { /// Close floating window, and record last floating window type. - (void)closeFloatingWindow { NSLog(@"close floating window: %@", self.floatingWindow); - + if (!self.floatingWindow) { return; } - + // stop playing audio [self.floatingWindow.queryViewController stopPlayingQueryText]; - + self.floatingWindow.titleBar.pin = NO; [self.floatingWindow close]; - + if (![EZPreferencesWindowController.shared isShowing]) { // recover last app. [self activeLastFrontmostApplication]; } - + if ([EZMainQueryWindow isAlive]) { [self.mainWindow orderBack:nil]; } - + // Move floating window type to second. - + NSNumber *windowType = @(self.floatingWindowType); [self.floatingWindowTypeArray removeObject:windowType]; [self.floatingWindowTypeArray insertObject:windowType atIndex:1]; @@ -925,17 +960,17 @@ - (BOOL)isAppRunningWithBundleId:(NSString *)bundleID { - (void)logSelectedTextEvent { NSString *text = self.selectedText; - + if (!text) { return; } - + NSRunningApplication *application = self.eventMonitor.frontmostApplication; - NSString *appName = application.localizedName; - NSString *bundleID = application.bundleIdentifier; + NSString *appName = application.localizedName ?: @""; + NSString *bundleID = application.bundleIdentifier ?: @""; NSString *textLength = [EZLog textLengthRange:text]; NSString *triggerType = [EZEnumTypes stringValueOfTriggerType:self.eventMonitor.triggerType]; - + NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:@{ @"actionType" : self.actionType, @"selectTextType" : self.eventMonitor.selectTextType, @@ -944,14 +979,14 @@ - (void)logSelectedTextEvent { @"appName" : appName, @"bundleID" : bundleID, }]; - + NSString *browserTabURLString = self.eventMonitor.browserTabURLString; if (browserTabURLString.length) { NSURL *tabURL = [NSURL URLWithString:browserTabURLString]; NSString *host = tabURL.host ?: browserTabURLString; dict[@"host"] = host; } - + [EZLog logEventWithName:@"getSelectedText" parameters:dict]; } diff --git a/EasydictHelper/Base.lproj/Main.storyboard b/EasydictHelper/Base.lproj/Main.storyboard index c96ab9e9e..0f468c018 100644 --- a/EasydictHelper/Base.lproj/Main.storyboard +++ b/EasydictHelper/Base.lproj/Main.storyboard @@ -1,8 +1,8 @@ - + - + @@ -25,7 +25,7 @@ - + diff --git a/Podfile.lock b/Podfile.lock index bc9962f6a..b88d6353a 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -167,6 +167,6 @@ SPEC CHECKSUMS: Sparkle: 270cd27377bf04e9c128af06e3a22d0f572d6ee3 SSZipArchive: 62d4947b08730e4cda640473b0066d209ff033c9 -PODFILE CHECKSUM: 851af542ac1369ffd80ab7b91dc95f158ee0d3d6 +PODFILE CHECKSUM: 3e98cd87eb9495431dc2cd105c1571edc8f60360 -COCOAPODS: 1.13.0 +COCOAPODS: 1.14.2 diff --git a/Pods/AFNetworking/AFNetworking/AFURLResponseSerialization.m b/Pods/AFNetworking/AFNetworking/AFURLResponseSerialization.m index b7be3d403..d723243f9 100755 --- a/Pods/AFNetworking/AFNetworking/AFURLResponseSerialization.m +++ b/Pods/AFNetworking/AFNetworking/AFURLResponseSerialization.m @@ -223,7 +223,7 @@ - (instancetype)init { return nil; } - self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil]; + self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/javascript", @"text/html", nil]; return self; } @@ -657,7 +657,7 @@ - (instancetype)init { return nil; } - self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"image/tiff", @"image/jpeg", @"image/gif", @"image/png", @"image/ico", @"image/x-icon", @"image/bmp", @"image/x-bmp", @"image/x-xbitmap", @"image/x-win-bitmap", nil]; + self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"image/tiff", @" image/jpeg", @"image/gif", @"image/png", @"image/ico", @"image/x-icon", @"image/bmp", @"image/x-bmp", @"image/x-xbitmap", @"image/x-win-bitmap", nil]; #if TARGET_OS_IOS || TARGET_OS_TV self.imageScale = [[UIScreen mainScreen] scale]; diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock index bc9962f6a..b88d6353a 100644 --- a/Pods/Manifest.lock +++ b/Pods/Manifest.lock @@ -167,6 +167,6 @@ SPEC CHECKSUMS: Sparkle: 270cd27377bf04e9c128af06e3a22d0f572d6ee3 SSZipArchive: 62d4947b08730e4cda640473b0066d209ff033c9 -PODFILE CHECKSUM: 851af542ac1369ffd80ab7b91dc95f158ee0d3d6 +PODFILE CHECKSUM: 3e98cd87eb9495431dc2cd105c1571edc8f60360 -COCOAPODS: 1.13.0 +COCOAPODS: 1.14.2 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj index f1b168f7f..e1c73e0a8 100644 --- a/Pods/Pods.xcodeproj/project.pbxproj +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -25,7 +25,7 @@ ); dependencies = ( 20000DB20840BFBA5AE529DA48FF7827 /* PBXTargetDependency */, - 0E9A554FD59787BBD43C562B29547AFF /* PBXTargetDependency */, + 457A6020E71E493D7145A8EC8874C5BB /* PBXTargetDependency */, ); name = GoogleAppMeasurement; }; @@ -40,15 +40,14 @@ 07D22584E25EDB0A225731330D00A425 /* PBXTargetDependency */, 6ACAC02FCBB6D79C8016BF7675A3799A /* PBXTargetDependency */, E19D64E08124C4DFCCA75D76A682B22B /* PBXTargetDependency */, - D36C03805994F45C53E4C284CBBE56F5 /* PBXTargetDependency */, + 8EC725E4A839B10DADF46962FFDE9610 /* PBXTargetDependency */, ); name = FirebaseAnalytics; }; ED77B4B88587C894E85C361023D67C53 /* Sparkle */ = { isa = PBXAggregateTarget; - buildConfigurationList = 31C3FA8CADE61CE3FE2492EDBA06C452 /* Build configuration list for PBXAggregateTarget "Sparkle" */; + buildConfigurationList = 2C8D06A2289713323892B3638F08AC0B /* Build configuration list for PBXAggregateTarget "Sparkle" */; buildPhases = ( - 9A181939804C9F1E56224ACF31BF086B /* [CP] Copy dSYMs */, ); dependencies = ( ); @@ -97,6 +96,8 @@ 0BF18B665E2ADAFC886CBBAE9F11E32E /* MJProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = 3F166DB3916BB220B8952CF070CDBE32 /* MJProperty.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; 0C75B7610A836CB47FC792FA040328F7 /* GULHeartbeatDateStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = CFDADC5BB855150A19290E1B218A5187 /* GULHeartbeatDateStorage.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0C77FEA47061F0AAB68984C1903C4CE5 /* GULAppEnvironmentUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = F1864F83FB4E0BF32A91AB2E9F203BBF /* GULAppEnvironmentUtil.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 0CEDC7F18D7506B918B3F22F0ADB21A9 /* pb_decode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BAC6E1228C2BC6DC8163D4450D098F8 /* pb_decode.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 0DEDE904281DC1C3CAF904942D3BA558 /* nanopb-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = ADDFC9C6E037798606CD7579475357F6 /* nanopb-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0E46664EDBC71B73AE76CE43D601F40D /* GoogleUtilities-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = F788C3B67D5F686ADA5AF1630B6BDFF7 /* GoogleUtilities-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0EF3774AC45C05C24674C6F390E4B571 /* mz_strm_os.h in Headers */ = {isa = PBXBuildFile; fileRef = B38D254CC9A8D51D6661C7A6AC04DD5E /* mz_strm_os.h */; settings = {ATTRIBUTES = (Project, ); }; }; 0F20999DB2E6867904A912A5F83573F5 /* NSUserDefaults+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = C4963F661B4B843765DA415C02F225E9 /* NSUserDefaults+RACSupport.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; @@ -127,6 +128,7 @@ 184DD69E04094297A9FEE0BA04218F3D /* AFURLSessionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C53C69754E1A847202EFD2940DF79AB1 /* AFURLSessionManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; 18BB4AA49E7FA865F60007629982D492 /* FBLPromise+Testing.h in Headers */ = {isa = PBXBuildFile; fileRef = D657A3525078E4AE22C81B0817E0BCFC /* FBLPromise+Testing.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1A3A48510F5EADB9FB14E0DF45B3AD2F /* MASShortcut.h in Headers */ = {isa = PBXBuildFile; fileRef = B7B427520F0F45EC9F584F255074718C /* MASShortcut.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1AA3ACEE6E158494C354432838B25195 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 555050235D41CC95CBC15C8F5B25D14D /* Cocoa.framework */; }; 1ABBC099E33F25724DAFE23F85E06E68 /* FIRInstallationsIIDTokenStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 85E544E15C6D4898D783481318662BB4 /* FIRInstallationsIIDTokenStore.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; 1ABD3DA2DE56DBF1B91D47EE8511B71D /* JLRRouteRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = 7FFBF21C8D953F108DC5DEB82E276A76 /* JLRRouteRequest.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1B5A31225D23E3AD1FB450E37C130687 /* nl.lproj in Resources */ = {isa = PBXBuildFile; fileRef = 9274004E6372E1BC63EB46B6569A659A /* nl.lproj */; }; @@ -145,6 +147,7 @@ 1E834DACD7F50CBDB21E0C1A3E2DA8C3 /* _ObjC_HeartbeatsPayload.swift in Sources */ = {isa = PBXBuildFile; fileRef = A998B4AE16A49A8EF97BFA5720B58271 /* _ObjC_HeartbeatsPayload.swift */; }; 1F4432060B2C404E90F912576F2A65D9 /* RACValueTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1D3587A44371B64EC5CAE2B8D1A3BED8 /* RACValueTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1F609B958FF08B165ED0228D2CD8C95B /* RACUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = 247656FC449EC2D8C54E08A4E700D4E2 /* RACUnit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F833B128D16D4283D4298CBD2F72EE1 /* pb_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = F1884EC7CD367AE54A3C417269B5E781 /* pb_decode.c */; settings = {COMPILER_FLAGS = "-fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; 1F9D460616DC9526B323BC29E7F14CC8 /* RACTupleSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = 8891BF3B3683C49FA71FFB325DEBFF6D /* RACTupleSequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1FA3A6F0773C5D86C7DFEF86BCF54070 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A60CFC28EFE537D195AC6987A41C114 /* AppKit.framework */; }; 200E7C29E35EDDB6AFC2F22B1CA06D93 /* MASConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 6515AB09C36030222828E0B13B254666 /* MASConstraint.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0 -w -Xanalyzer -analyzer-disable-all-checks"; }; }; @@ -200,8 +203,8 @@ 3355B8D221BF86265D6F9558952DE40F /* NSObject+RACKVOWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 08C75F289777D446F2516C12C22FEF18 /* NSObject+RACKVOWrapper.h */; settings = {ATTRIBUTES = (Public, ); }; }; 336B781E5AF19CF4F84DA9462E41429D /* RACStream+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A155C805D48F8F1E03B62E805D5737E /* RACStream+Private.h */; settings = {ATTRIBUTES = (Private, ); }; }; 33DC154CACD614244DE45A53CE08EF0D /* MJExtension.h in Headers */ = {isa = PBXBuildFile; fileRef = 13AF741D62AF13BDD2EA87C8BE0D11F2 /* MJExtension.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 33E8837FC20992C9A379ED1663E2F9CA /* nanopb-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = F03A8343AEC33641155CBCF83CB6111C /* nanopb-dummy.m */; }; 340497E83F9DF147F7354194E48F9A2C /* RACEmptySequence.h in Headers */ = {isa = PBXBuildFile; fileRef = 737D9C0CD6F98CBE71654A04138E8E12 /* RACEmptySequence.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 34CC3C8F7DC8C7CA75166D30152331FC /* pb_decode.c in Sources */ = {isa = PBXBuildFile; fileRef = F1884EC7CD367AE54A3C417269B5E781 /* pb_decode.c */; settings = {COMPILER_FLAGS = "-fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; 350423AE3CB377B274531C3FF631FD12 /* DDFileLogger+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 452E1A4FE091791F5ADB3CA87F551D1B /* DDFileLogger+Internal.h */; settings = {ATTRIBUTES = (Private, ); }; }; 35B8EEF818BC5B8190F182868D50305F /* NSData+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 9E028DCE9A3EA887179E94DF87E56258 /* NSData+RACSupport.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; 35C7EA5B31465C4197892CE66A24D9AB /* NSArray+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 662AEB9E02E4E53C52E4F78AF209267F /* NSArray+MASAdditions.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0 -w -Xanalyzer -analyzer-disable-all-checks"; }; }; @@ -219,7 +222,6 @@ 3DE8FB64DEB97ADE429F462C3CE503DB /* FBLPromise+Then.h in Headers */ = {isa = PBXBuildFile; fileRef = B54293899303830EC464E44B649FE7C0 /* FBLPromise+Then.h */; settings = {ATTRIBUTES = (Public, ); }; }; 3DFFF00FCF7A4C591FE7D4238EAC6C40 /* FIRComponentType.m in Sources */ = {isa = PBXBuildFile; fileRef = ED43EC7574843F4999A91CA8A25908AB /* FIRComponentType.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; 3E2B0D8663D86A451DBE8376606EF4C4 /* FIRInstallationsStoredAuthToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 78992508A3ECC1AF9D4E22ADF5CBADEE /* FIRInstallationsStoredAuthToken.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 3F05B632C059859E35DEB5D315E8A3EF /* pb_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 6F97DC66284EA026A97232DDBD1C1133 /* pb_common.c */; settings = {COMPILER_FLAGS = "-fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; 40022140671799C4C6FBA913DABF6B2E /* DDLegacyMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C99331E0049EBB16378F2F386C7AFD /* DDLegacyMacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; 408D761794E02E208E2531B6E284F9AF /* FIRHeartbeatLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 077ABAAE4198D3B7E21F87EFB1272EC5 /* FIRHeartbeatLogger.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; 41EAD9BE1E86DC6479E027599636A56B /* GULSecureCoding.m in Sources */ = {isa = PBXBuildFile; fileRef = 5578640E5E4D969B31C79F02D8697E32 /* GULSecureCoding.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; @@ -229,7 +231,6 @@ 442981BF0CC47AB4EF87B9830A539047 /* GULSceneDelegateSwizzler_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = B3EC852AC9D86C01C24C8141A8AE789C /* GULSceneDelegateSwizzler_Private.h */; settings = {ATTRIBUTES = (Project, ); }; }; 4454EEE74707A4645C03835CBED33F97 /* NSControl+RACCommandSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = DADDA26FCE04729DD95BC53E9BE728B5 /* NSControl+RACCommandSupport.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; 44A145033020E857348F2CF287D18EBB /* RACScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E33FBB49CBB5CF720D4FE0BC05E67DF /* RACScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4506B1E2DE87A24C96A173ED89058137 /* nanopb-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = ADDFC9C6E037798606CD7579475357F6 /* nanopb-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 45B0F1C3F3965E69C8F71044B1397D54 /* RACQueueScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = 30EE743B5F59349A58B1C77C7A3F6C26 /* RACQueueScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; 45F70F0D6C2F6A152EFBF37A83A76FD4 /* GULKeychainStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 2987B4FD8C265E57D3D1B37196AB8997 /* GULKeychainStorage.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; 46D6446DA8450AF0B1C24CA52C55D9BA /* NSIndexSet+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 002700A5E3A26AFFEF9FA3D9447BD74C /* NSIndexSet+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -282,7 +283,6 @@ 5857D7331F535E55BE0260651348CEC3 /* RACEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 04D6BC90F9F2DCD614401D099AF899A7 /* RACEvent.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; 5864A26625028DA54B66904E1F3CB559 /* RACQueueScheduler+Subclass.h in Headers */ = {isa = PBXBuildFile; fileRef = F39C47275451994773A2D0EE364AAD24 /* RACQueueScheduler+Subclass.h */; settings = {ATTRIBUTES = (Public, ); }; }; 586B1D7E92AEC3C2462B5BA36B2D413B /* RACSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = 601F342219CFA499210D954E8CB5EE3E /* RACSequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 591D96FE65EAEBD515E6C50490972439 /* pb_encode.h in Headers */ = {isa = PBXBuildFile; fileRef = A3C79DC69E81B1CE7ECA7AD5B49B1628 /* pb_encode.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5943324F179C6C962816A4712A889E0C /* AFHTTPSessionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B3AC5795904C3555AF1A7B53DD4A42D /* AFHTTPSessionManager.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; 5991FB507FDD0F6C4D2EA204337EF426 /* RACTargetQueueScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = CB8A3335A3C3BA9BEB2F6E1E4B233B81 /* RACTargetQueueScheduler.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; 5994C8E04CC0078771E6950F217AD483 /* FIROptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 25A8D3EAB6362C8FB46EACFC7D1FCE65 /* FIROptions.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; @@ -357,11 +357,11 @@ 77E89ABBF0B14D029D55072153F36336 /* NSArray+MASShorthandAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = CBE9305D5D3D5B335957A7E2DF3EC0B5 /* NSArray+MASShorthandAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; 783048675A8F832219D5E37DD1797B04 /* GULSwizzler.m in Sources */ = {isa = PBXBuildFile; fileRef = 035BB1678916C7E9EC7BE3DB4F1020AE /* GULSwizzler.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; 7832A6027EBBD38DD23FBC88E12C864A /* FIRInstallationsAuthTokenResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 523D9D60B8B30EFAA6FC57CFA782B37E /* FIRInstallationsAuthTokenResult.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 785562D852A727625DF8315AF53FFBBE /* pb.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E8A5F92084780FED2D8EC2EF1F2DB53 /* pb.h */; settings = {ATTRIBUTES = (Public, ); }; }; 78B9EA159FEAC6F5B749C00380637F2A /* GULSceneDelegateSwizzler.h in Headers */ = {isa = PBXBuildFile; fileRef = FF204AB024C09C5779BD814668737DB1 /* GULSceneDelegateSwizzler.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7901FA1662128AEBB3D287565CC12E4F /* FIRInstallations.m in Sources */ = {isa = PBXBuildFile; fileRef = 37BB97A6A6F13B0DD0AF35A3561F413E /* FIRInstallations.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; 793A7928DEEC23B10E8E44EF180745E6 /* DDLog+LOGV.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BE4208C690F7B121BF91F6E3E065CB5 /* DDLog+LOGV.h */; settings = {ATTRIBUTES = (Public, ); }; }; 79CAC0A0F92732E566C161D4E4EE7B14 /* NSNotificationCenter+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BDBBCE4878A068F0E0E8F54B1DEC1BD /* NSNotificationCenter+RACSupport.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; + 7A32A35D58EE070D44E2E6B739824659 /* pb.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E8A5F92084780FED2D8EC2EF1F2DB53 /* pb.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7A8493AC6E362F13BDBE7542797EB9BD /* FirebaseInstallations.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A9EAC78069207C58D52E4061D01B118 /* FirebaseInstallations.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7B5C7A4EC7E01CC8A4B8AF8E4485F651 /* FIRConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 63EDCA4ACB2154E1FEF06D75C6B03062 /* FIRConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7B835D47DE258886D4DE32448092B2E0 /* MASShortcutView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EEC6F934214FD9C57792B274116C93B /* MASShortcutView.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -376,7 +376,6 @@ 7F58BE8838D03B2D5B30E68952FF1E4D /* SSZipArchive-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = C34B254399E2C87BA33C46A1E6D67A51 /* SSZipArchive-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; 7F59999179584A86DC8922AF1D751E96 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 555050235D41CC95CBC15C8F5B25D14D /* Cocoa.framework */; }; 7FF9376D0BD3159E82F3AA26178EBA07 /* DDASLLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = C2AFAB93615753004172C02DFD7E0EDA /* DDASLLogger.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - 80AB2580823D59D868F36A0CCFD33686 /* nanopb-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = F03A8343AEC33641155CBCF83CB6111C /* nanopb-dummy.m */; }; 80E10C83F426C4FBE5037C7F4C15B769 /* GULHeartbeatDateStorage.m in Sources */ = {isa = PBXBuildFile; fileRef = 98100DB3772CBFF026818DEAF0DBE7E4 /* GULHeartbeatDateStorage.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; 80FCB7EE2EE27D080683489C770D4C13 /* es.lproj in Resources */ = {isa = PBXBuildFile; fileRef = D163FDD1B558E63DE884AB82772B3BF9 /* es.lproj */; }; 819514AA5070A695D85E2741E0FDC6DE /* FirebaseCoreInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 648B32621572E2561BE61FAECB4BC6EA /* FirebaseCoreInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; @@ -389,6 +388,7 @@ 8397678AB6D393CF7947A446ADBEB6B7 /* FBLPromise+Recover.h in Headers */ = {isa = PBXBuildFile; fileRef = 060D7ADC94C54460581B653B784B3932 /* FBLPromise+Recover.h */; settings = {ATTRIBUTES = (Public, ); }; }; 83F1B5B477C366CEB687307042F60FD3 /* RACReturnSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = 2483C6C89E65B26D955834BCB52191AC /* RACReturnSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8446927339C7A62EB92C205ACB1EA409 /* FBLPromise+Validate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B6877A0D069DEE803E04AC3746F8A5D /* FBLPromise+Validate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 84534802D7D479A0B0664DA5FA438892 /* pb_encode.h in Headers */ = {isa = PBXBuildFile; fileRef = A3C79DC69E81B1CE7ECA7AD5B49B1628 /* pb_encode.h */; settings = {ATTRIBUTES = (Public, ); }; }; 84B3C612462D52E39AE51394202A7A84 /* FBLPromise.m in Sources */ = {isa = PBXBuildFile; fileRef = F30D45B29902BBE08A37108EAEB9EC10 /* FBLPromise.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; 8590AC8670A3A6156B48C56C3C2C9A8E /* View+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D1520B8B7428274B5806B3E72D2B36EA /* View+MASAdditions.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0 -w -Xanalyzer -analyzer-disable-all-checks"; }; }; 865AF9D290E6170F37B1EFC3D530B9C9 /* MASViewConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = 98A240BF4BCFD94AB552AEB9181A813A /* MASViewConstraint.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -441,6 +441,7 @@ 9BA289B9A97387364A7B455D8E6452B8 /* RACEXTKeyPathCoding.h in Headers */ = {isa = PBXBuildFile; fileRef = 7810783FE149CCE9B96A2591974554EC /* RACEXTKeyPathCoding.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9C575E12FFAA9968E137985FA7531DF9 /* GULNetworkURLSession.h in Headers */ = {isa = PBXBuildFile; fileRef = D8AB5962AFA18EB37DC037D1E0CCED3A /* GULNetworkURLSession.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9C833CC525D852B80C82F3F4CFC7E889 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 790BD6248FBDA5CB1CA516A6BB81FAAF /* Security.framework */; }; + 9D937CED1882BE56C77CEFFEE7B7F34F /* pb_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = 55F9522DAEEE52ADB037B4E21C736E78 /* pb_encode.c */; settings = {COMPILER_FLAGS = "-fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; 9E0F4BFEB3736B96D2E36B0E31B37F5B /* MASConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = F1395D5ADF94917C0B8C1D952FA9334B /* MASConstraint.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9E69E807DDFDC08CAD98511CF6D60AA3 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6B48B2773780C74CAA27A937A23281B /* Storage.swift */; }; 9E75571BABA8A9EF2AA615B065BEF700 /* RACScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = 137DA7F10F29FA6757D8FA1A7EF953F4 /* RACScheduler.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; @@ -475,7 +476,6 @@ A60C18305C35802FCC00D5E69B018D95 /* mz_strm_split.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E29A6B96CBC8289057B011296595ECE /* mz_strm_split.c */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; A6A6DD308EF1383CF3739A4431B6BC99 /* RACSubscriber.m in Sources */ = {isa = PBXBuildFile; fileRef = CBA8DB6C9274D3F9A904AFEF620B6007 /* RACSubscriber.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; A6D530F09BAAAC240CB7B3878C32EC46 /* FIRInstallationsLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = D6793E75B8262FD75ADBFF70566C7227 /* FIRInstallationsLogger.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - A6E237A6EBE5E875DF5AFFC3880D2068 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 555050235D41CC95CBC15C8F5B25D14D /* Cocoa.framework */; }; A738020AB3235279D1841EC22F39D215 /* FIRInstallationsItem.m in Sources */ = {isa = PBXBuildFile; fileRef = B98A02E060A69B7AF8B9C58F9FC5201C /* FIRInstallationsItem.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; A938F21CAC87C5F8AADEF955F9127E3A /* MASPreferencesWindowController.h in Headers */ = {isa = PBXBuildFile; fileRef = 514F27C44E4E2C298F81A393112CC15F /* MASPreferencesWindowController.h */; settings = {ATTRIBUTES = (Public, ); }; }; A9B6C5BB3BBDA9138B560342263FC7B8 /* AFNetworking-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 6D351AA138F225C01DA05C7FEAB87AF9 /* AFNetworking-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -539,7 +539,6 @@ C99ECD2FD1B6436D3A464CCDBFFCDFA6 /* FIRInstallationsStore.h in Headers */ = {isa = PBXBuildFile; fileRef = A8178439DC550016FAE8D118C6FEFA94 /* FIRInstallationsStore.h */; settings = {ATTRIBUTES = (Project, ); }; }; CB3641B63BD1821D1896B3EBE4AF599D /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 790BD6248FBDA5CB1CA516A6BB81FAAF /* Security.framework */; }; CB96DD5B6FCE2C32103DFB6178837A93 /* AFURLResponseSerialization.m in Sources */ = {isa = PBXBuildFile; fileRef = 60EF24D279FDC5F409E355627D317881 /* AFURLResponseSerialization.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; - CC4B1789BE5CA206D906F1625EB9518C /* pb_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A2506EA3EFD3291BA6977408A84CD1F /* pb_common.h */; settings = {ATTRIBUTES = (Public, ); }; }; CC98B80E4E01EEE45C3DE01882693891 /* RACKVOTrampoline.m in Sources */ = {isa = PBXBuildFile; fileRef = FEF0499F272806EF773783FD0578D2D5 /* RACKVOTrampoline.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; CCB94376B769F5D1AE4E6F1C903A6C81 /* FIRInstallationsHTTPError.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DC9531128AC0380110E114394D4FD14 /* FIRInstallationsHTTPError.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; CCD4362E8522B5BC2820666098E91B93 /* NSObject+MJCoding.h in Headers */ = {isa = PBXBuildFile; fileRef = D1CA8EC9B89F69A56B3764C7BBB69C8C /* NSObject+MJCoding.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -598,6 +597,7 @@ E04EF19B8D61D83DFE848F3C441C9E48 /* MASCompositeConstraint.h in Headers */ = {isa = PBXBuildFile; fileRef = AB3AF03337EBC8F64E6ADF645069112E /* MASCompositeConstraint.h */; settings = {ATTRIBUTES = (Public, ); }; }; E05517D106CB783CF2A2F25AE5C7E0A5 /* FIRComponentType.h in Headers */ = {isa = PBXBuildFile; fileRef = CA487D8BC512545D170F148A39EC8EC1 /* FIRComponentType.h */; settings = {ATTRIBUTES = (Project, ); }; }; E0599F5B16B5FEAFE22991A67B2A03B3 /* RACChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 92DA1A2029DA7DF544E7655D81AF9AEF /* RACChannel.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E1223A4175D23FD57B88D5CF870171C1 /* pb_common.c in Sources */ = {isa = PBXBuildFile; fileRef = 6F97DC66284EA026A97232DDBD1C1133 /* pb_common.c */; settings = {COMPILER_FLAGS = "-fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; E15140790FAE035434C8995CF5FB75D4 /* RACSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = AF97AD50A1E582BB875383CE1994FD63 /* RACSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; E15CA15970D3B85AE90E3AD925D411EA /* RACCompoundDisposableProvider.d in Sources */ = {isa = PBXBuildFile; fileRef = 16D5AE6E4B98E6D336196969D483CE12 /* RACCompoundDisposableProvider.d */; }; E1A65E122DDC1E06FAC465C08F5807A2 /* NSString+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = F47BF9931C473D9548E9AA1776864175 /* NSString+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -619,6 +619,7 @@ E8905332E322AA8C20CF95B0FD2FC6F3 /* NSObject+RACDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C591A65213D29351022D733C16707FE /* NSObject+RACDescription.h */; settings = {ATTRIBUTES = (Public, ); }; }; E8AAA24C9F66564417097D22434E91B8 /* FIRInstallationsLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = D7B1C940996703033A73BE58AD54ECB5 /* FIRInstallationsLogger.h */; settings = {ATTRIBUTES = (Project, ); }; }; E8BA7D85CDCE36F37054F638D67D0203 /* CocoaLumberjack-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 3EF29D13FE3FD265AF7C3E941196A9F7 /* CocoaLumberjack-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E8D65DB9D74862EA4DEE4B7F178E74B7 /* pb_common.h in Headers */ = {isa = PBXBuildFile; fileRef = 0A2506EA3EFD3291BA6977408A84CD1F /* pb_common.h */; settings = {ATTRIBUTES = (Public, ); }; }; E915F2E1B315C91CD81CE7D06883DF77 /* NSArray+MASAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = E660398AA51A37D27BB0F4E60D4D6E9D /* NSArray+MASAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; E9AE0C8455FB34BD22F122828231B916 /* NSObject+RACAppKitBindings.h in Headers */ = {isa = PBXBuildFile; fileRef = 9563E97D378D80D140F80097B24E8BF4 /* NSObject+RACAppKitBindings.h */; settings = {ATTRIBUTES = (Public, ); }; }; EA819967C6E6F1B5E07557BF9328CCCC /* RACCompoundDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = A65E46342B6ED4FB6110FF7F5020AB04 /* RACCompoundDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -634,7 +635,6 @@ EF97DAD218C088FBED655073542DD1AE /* NSOrderedSet+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 991D8018FF33353C241D5870DEB2F63D /* NSOrderedSet+RACSequenceAdditions.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; EF9C00E340B33BA67D9CEF5A2262D15E /* mz_strm_zlib.h in Headers */ = {isa = PBXBuildFile; fileRef = 11AA6AF9C4AD7257AF6EF8BB8B344EA7 /* mz_strm_zlib.h */; settings = {ATTRIBUTES = (Project, ); }; }; F04000A157F4A60BBE08879421963D9E /* MASDictionaryTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = 5EA145FC429C6AF6C22EEAD909E61CFB /* MASDictionaryTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - F0A7D11A89528FD43D72B18659A369F5 /* pb_decode.h in Headers */ = {isa = PBXBuildFile; fileRef = 3BAC6E1228C2BC6DC8163D4450D098F8 /* pb_decode.h */; settings = {ATTRIBUTES = (Public, ); }; }; F0B205C4ABAB8204F518AA04E394351F /* FIRInstallationsBackoffController.m in Sources */ = {isa = PBXBuildFile; fileRef = A200108EEA4BECDA9DD5EC834F317BC9 /* FIRInstallationsBackoffController.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; F0F35CB0146A6B9234FAB55A9D8EAE61 /* GULReachabilityChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = F90B4C68243182A79BFB2F4F27D0E2D7 /* GULReachabilityChecker.h */; settings = {ATTRIBUTES = (Public, ); }; }; F118E4643057EB9F24B8DCD574EE476D /* GULNSData+zlib.h in Headers */ = {isa = PBXBuildFile; fileRef = 38C90477E6350DD076C939E7CDD1B832 /* GULNSData+zlib.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -658,7 +658,6 @@ FB14029FF3F8FAE3A726A0340CBEBC70 /* FIRAnalyticsConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = C41B134A2D7DA30DD7B0FCFCB0FA0C09 /* FIRAnalyticsConfiguration.h */; settings = {ATTRIBUTES = (Project, ); }; }; FB47863E0EB625ACB20647FA758ABFB9 /* MJPropertyKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DEB804EFCC4BF4D4F2F08CDC17108858 /* MJPropertyKey.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; FB8AFC91637879CDC139F8453DE87F29 /* MASCompositeConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = EA41F630B811EE7C802FC50E9812A3D3 /* MASCompositeConstraint.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0 -w -Xanalyzer -analyzer-disable-all-checks"; }; }; - FBC73635225EE559463755D289764259 /* pb_encode.c in Sources */ = {isa = PBXBuildFile; fileRef = 55F9522DAEEE52ADB037B4E21C736E78 /* pb_encode.c */; settings = {COMPILER_FLAGS = "-fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks -fno-objc-arc -w -Xanalyzer -analyzer-disable-all-checks"; }; }; FBD272BE5EA05F5FF4553A864B196C78 /* JLRoutes-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E33B8BF343E7448A6CF96E0D66DB9A9 /* JLRoutes-dummy.m */; }; FD68516225C24EB2327FB1AD595B4DAF /* NSInvocation+RACTypeParsing.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4314246FC626734E85B63C723FA710 /* NSInvocation+RACTypeParsing.m */; settings = {COMPILER_FLAGS = "-w -Xanalyzer -analyzer-disable-all-checks"; }; }; FDE9F7D0CF7E9A3B28E12BF7F210E1F1 /* ViewController+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = E8B21EB38FD9C94E43E486388AB6817C /* ViewController+MASAdditions.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0 -w -Xanalyzer -analyzer-disable-all-checks"; }; }; @@ -711,6 +710,13 @@ remoteGlobalIDString = 2BBF7206D7FAC92C82A042A99C4A98F8; remoteInfo = PromisesObjC; }; + 1C4A2F9D15644458CE86B6A5A34B22C6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2B5E7DCCBBFB32341D857D01211A1A3; + remoteInfo = nanopb; + }; 273A4366EFC2732A8CDE6A5F942CFC37 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; @@ -760,6 +766,13 @@ remoteGlobalIDString = 25E9E9A17BC3F670357D7385C521E48E; remoteInfo = FirebaseCoreInternal; }; + 4F8CE3325D33821A561FDB1CE7D04943 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2B5E7DCCBBFB32341D857D01211A1A3; + remoteInfo = nanopb; + }; 51C2685ACBEB310A4F10D753053F2ED7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; @@ -872,13 +885,6 @@ remoteGlobalIDString = 0130B3724283586C0E9D2A112D4F2AA1; remoteInfo = AFNetworking; }; - C52B91CFFD0D3AA5DE574B13A2AFED63 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D2B5E7DCCBBFB32341D857D01211A1A3; - remoteInfo = nanopb; - }; C8235256E786EF08A12B5216B1EC2FAC /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; @@ -907,6 +913,13 @@ remoteGlobalIDString = 8D7F5D5DD528D21A72DC87ADA5B12E2D; remoteInfo = GoogleUtilities; }; + DC734C5132D5128FB9893600B8BDECC3 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D2B5E7DCCBBFB32341D857D01211A1A3; + remoteInfo = nanopb; + }; DD0477B693E3F764542F6D59771E5DF4 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; @@ -928,13 +941,6 @@ remoteGlobalIDString = C49E7A4D59E5C8BE8DE9FB1EFB150185; remoteInfo = FirebaseAnalytics; }; - E0E3CDD0B8D83034668FCA926A36F173 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D2B5E7DCCBBFB32341D857D01211A1A3; - remoteInfo = nanopb; - }; E4BA97B3239BC4A13DB03C818E035901 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; @@ -956,13 +962,6 @@ remoteGlobalIDString = 4D3BA58D0583DF37575CACAB3DDADC85; remoteInfo = MJExtension; }; - ED546F592AAEDD40903298BAB4D5F3F6 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D2B5E7DCCBBFB32341D857D01211A1A3; - remoteInfo = nanopb; - }; F4180EFA7F346C0F302280B9F69DBC8E /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BFDFE7DC352907FC980B868725387E98 /* Project object */; @@ -994,12 +993,12 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 00065392AED1AF258139F87F6624E422 /* SUVersionDisplayProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUVersionDisplayProtocol.h; path = Sparkle.framework/Versions/A/Headers/SUVersionDisplayProtocol.h; sourceTree = ""; }; 002700A5E3A26AFFEF9FA3D9447BD74C /* NSIndexSet+RACSequenceAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSIndexSet+RACSequenceAdditions.h"; path = "ReactiveObjC/NSIndexSet+RACSequenceAdditions.h"; sourceTree = ""; }; 002EB494D800703B4E51554F00D4E0E3 /* FBLPromise+Race.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Race.m"; path = "Sources/FBLPromises/FBLPromise+Race.m"; sourceTree = ""; }; 003B117E66D812AAA6D53846EE8FD758 /* RACTestScheduler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RACTestScheduler.m; path = ReactiveObjC/RACTestScheduler.m; sourceTree = ""; }; 0086026DEFC67029299796D36F9E056C /* NSString+RACSupport.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSString+RACSupport.m"; path = "ReactiveObjC/NSString+RACSupport.m"; sourceTree = ""; }; 00D2912F9A273E9B7DF1BF0ABA05A534 /* JLRRouteRequest.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = JLRRouteRequest.m; path = JLRoutes/Classes/JLRRouteRequest.m; sourceTree = ""; }; - 0107F48BA943EA4C4E19D1B5102C4CCE /* SUErrors.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUErrors.h; path = Sparkle.framework/Versions/A/Headers/SUErrors.h; sourceTree = ""; }; 013F6411A37C931433D77CEE841568F2 /* FIRAppInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRAppInternal.h; path = FirebaseCore/Extension/FIRAppInternal.h; sourceTree = ""; }; 02681F27E793C6BB6C96965AA6919CA0 /* FirebaseCore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseCore.h; path = FirebaseCore/Sources/Public/FirebaseCore/FirebaseCore.h; sourceTree = ""; }; 02938AC0D974756C5F2162C99273B860 /* MASShortcut-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "MASShortcut-Info.plist"; sourceTree = ""; }; @@ -1008,7 +1007,6 @@ 03BB3776CE49B7A00C01FC2B2A36A346 /* FIRInstallationsStore.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsStore.m; path = FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStore.m; sourceTree = ""; }; 04D6BC90F9F2DCD614401D099AF899A7 /* RACEvent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RACEvent.m; path = ReactiveObjC/RACEvent.m; sourceTree = ""; }; 051AA439490EDE8D8B13BAAAD9127FDD /* KVOController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = KVOController.h; path = FBKVOController/KVOController.h; sourceTree = ""; }; - 051FA5EDC1016ED519B5FF4105090CA1 /* SPUDownloaderDeprecated.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPUDownloaderDeprecated.h; path = Sparkle.framework/Versions/A/Headers/SPUDownloaderDeprecated.h; sourceTree = ""; }; 0597EC3FCEA8AF6F01036EEBCFA02EB2 /* MASPreferences-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "MASPreferences-umbrella.h"; sourceTree = ""; }; 060D7ADC94C54460581B653B784B3932 /* FBLPromise+Recover.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Recover.h"; path = "Sources/FBLPromises/include/FBLPromise+Recover.h"; sourceTree = ""; }; 061C269C7D919849E7FB15978B5DD771 /* MJExtensionConst.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJExtensionConst.m; path = MJExtension/MJExtensionConst.m; sourceTree = ""; }; @@ -1022,8 +1020,10 @@ 08C75F289777D446F2516C12C22FEF18 /* NSObject+RACKVOWrapper.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSObject+RACKVOWrapper.h"; path = "ReactiveObjC/NSObject+RACKVOWrapper.h"; sourceTree = ""; }; 0909DEA53874CCEFD93D7186E8F56957 /* FBLPromise+Await.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Await.h"; path = "Sources/FBLPromises/include/FBLPromise+Await.h"; sourceTree = ""; }; 096333BDE317D2BFC5571E1B6C7B6674 /* MASViewAttribute.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASViewAttribute.m; path = Masonry/MASViewAttribute.m; sourceTree = ""; }; + 09B96E945C01D1E10989870F68470BA7 /* SUAppcastItem.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUAppcastItem.h; path = Sparkle.framework/Versions/A/Headers/SUAppcastItem.h; sourceTree = ""; }; 09C725FB5CD261C45CF643942DCBD2BD /* PromisesObjC-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "PromisesObjC-umbrella.h"; sourceTree = ""; }; 09EED26F58E5C892F9FB7D69F1272158 /* RACEvent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RACEvent.h; path = ReactiveObjC/RACEvent.h; sourceTree = ""; }; + 0A211D270F1128D61964DE9513342225 /* SPUDownloaderProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPUDownloaderProtocol.h; path = Sparkle.framework/Versions/A/Headers/SPUDownloaderProtocol.h; sourceTree = ""; }; 0A2506EA3EFD3291BA6977408A84CD1F /* pb_common.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb_common.h; sourceTree = ""; }; 0B5093B65B54E5B4F0EFB8C4391FFE41 /* GULReachabilityMessageCode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULReachabilityMessageCode.h; path = GoogleUtilities/Reachability/GULReachabilityMessageCode.h; sourceTree = ""; }; 0B55699240BE2BAC89ADFF65A25E886C /* MASLocalization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASLocalization.h; path = Framework/UI/MASLocalization.h; sourceTree = ""; }; @@ -1038,6 +1038,7 @@ 0D6DAF8D2203810EA0CFD25FFF782A1D /* RACGroupedSignal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RACGroupedSignal.h; path = ReactiveObjC/RACGroupedSignal.h; sourceTree = ""; }; 0E25207DDDD8CE6F992CA20474F545C9 /* DDAssertMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = DDAssertMacros.h; path = Sources/CocoaLumberjack/include/CocoaLumberjack/DDAssertMacros.h; sourceTree = ""; }; 0E29A6B96CBC8289057B011296595ECE /* mz_strm_split.c */ = {isa = PBXFileReference; includeInIndex = 1; name = mz_strm_split.c; path = SSZipArchive/minizip/mz_strm_split.c; sourceTree = ""; }; + 0ED505B20168C30B58A8650464610202 /* SUUpdater.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUUpdater.h; path = Sparkle.framework/Versions/A/Headers/SUUpdater.h; sourceTree = ""; }; 0F1C25F44128BF7424E93AA5262DC85E /* Pods-Easydict.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-Easydict.release.xcconfig"; sourceTree = ""; }; 0F8E57EF154CF66B911255FABA0AA9B1 /* NSString+RACSequenceAdditions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSString+RACSequenceAdditions.m"; path = "ReactiveObjC/NSString+RACSequenceAdditions.m"; sourceTree = ""; }; 1081E6F67F995F77C746EF165A8B01EE /* RACKVOProxy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RACKVOProxy.m; path = ReactiveObjC/RACKVOProxy.m; sourceTree = ""; }; @@ -1061,7 +1062,6 @@ 147A22C4DDA86BEBA3E0ECF190C36321 /* FIRDependency.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRDependency.h; path = FirebaseCore/Extension/FIRDependency.h; sourceTree = ""; }; 148D0F9E8C7373FEAF40D800FC5F1BAA /* FirebaseCoreInternal */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = FirebaseCoreInternal; path = FirebaseCoreInternal.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 14E2C2C94AD59F3C0E45E772B3360F35 /* RACUnarySequence.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RACUnarySequence.h; path = ReactiveObjC/RACUnarySequence.h; sourceTree = ""; }; - 1539C997098CE0EC59133D405A57E9E1 /* SUExport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUExport.h; path = Sparkle.framework/Versions/A/Headers/SUExport.h; sourceTree = ""; }; 153C7590A66990441DB66F361EFE5834 /* AFNetworking-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "AFNetworking-Info.plist"; sourceTree = ""; }; 15BE2BCEDD7F670B933EF9C7A9BC85F7 /* FIRLoggerLevel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLoggerLevel.h; path = FirebaseCore/Sources/Public/FirebaseCore/FIRLoggerLevel.h; sourceTree = ""; }; 16CC4C7D911982A841F71BD0F5819334 /* MASShortcut.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = MASShortcut.modulemap; sourceTree = ""; }; @@ -1079,7 +1079,6 @@ 1C5656B309EC272D3DB3636CD2FC93CF /* FBLPromise+Await.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Await.m"; path = "Sources/FBLPromises/FBLPromise+Await.m"; sourceTree = ""; }; 1C591A65213D29351022D733C16707FE /* NSObject+RACDescription.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSObject+RACDescription.h"; path = "ReactiveObjC/NSObject+RACDescription.h"; sourceTree = ""; }; 1CED184B88249205935D2E864A765B02 /* JLRoutes-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "JLRoutes-prefix.pch"; sourceTree = ""; }; - 1D3130D5F3D0CF78A6DFD143C68C25D4 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Sparkle.framework; sourceTree = ""; }; 1D3587A44371B64EC5CAE2B8D1A3BED8 /* RACValueTransformer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RACValueTransformer.h; path = ReactiveObjC/RACValueTransformer.h; sourceTree = ""; }; 1D5AC857D7BADDDB6D8ECB1848BC2572 /* FirebaseCoreInternal-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "FirebaseCoreInternal-Info.plist"; sourceTree = ""; }; 1D71E77D81DA3902E36A293F5899ACBD /* RACDelegateProxy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RACDelegateProxy.m; path = ReactiveObjC/RACDelegateProxy.m; sourceTree = ""; }; @@ -1106,6 +1105,7 @@ 24A2436EE2A8FF6C349C0B84A7FAF740 /* RACTuple.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RACTuple.m; path = ReactiveObjC/RACTuple.m; sourceTree = ""; }; 24ACF3DEEAAE820F09372F7CAD455190 /* GULNetworkMessageCode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkMessageCode.h; path = GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkMessageCode.h; sourceTree = ""; }; 24EAE1AB23E0E81A377180B23B50F9A7 /* FirebaseInstallations-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "FirebaseInstallations-Info.plist"; sourceTree = ""; }; + 255B849B0C00A4C884C5DA5A2954FF46 /* SUErrors.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUErrors.h; path = Sparkle.framework/Versions/A/Headers/SUErrors.h; sourceTree = ""; }; 2561BB224DAFC4241BEC2A3EDAE50DFB /* NSEnumerator+RACSequenceAdditions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSEnumerator+RACSequenceAdditions.m"; path = "ReactiveObjC/NSEnumerator+RACSequenceAdditions.m"; sourceTree = ""; }; 25A8D3EAB6362C8FB46EACFC7D1FCE65 /* FIROptions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIROptions.m; path = FirebaseCore/Sources/FIROptions.m; sourceTree = ""; }; 26A8810424438A12E7ADBFB3E068C658 /* MASShortcut */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = MASShortcut; path = MASShortcut.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -1127,6 +1127,7 @@ 2BEF6106C4EDE99941F1244642BC5E9C /* FBLPromisePrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBLPromisePrivate.h; path = Sources/FBLPromises/include/FBLPromisePrivate.h; sourceTree = ""; }; 2D6EEA90ED9D3F8760C1E70A8F12F141 /* RACSubject.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RACSubject.m; path = ReactiveObjC/RACSubject.m; sourceTree = ""; }; 2D7862B3109AA9F6285DAF56EE0505BD /* FirebaseAnalytics.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseAnalytics.debug.xcconfig; sourceTree = ""; }; + 2D9BEA613483DB734927C29098453941 /* SUUpdaterDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUUpdaterDelegate.h; path = Sparkle.framework/Versions/A/Headers/SUUpdaterDelegate.h; sourceTree = ""; }; 2DFE1EF58FC53B1929EF027924208458 /* RACUnit.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RACUnit.m; path = ReactiveObjC/RACUnit.m; sourceTree = ""; }; 2E1BCA1721C5818EF10F0F6BD9572125 /* FirebaseCoreInternal-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FirebaseCoreInternal-dummy.m"; sourceTree = ""; }; 303B631DCE461B0EF4A5695F78B9DC32 /* NSObject+RACDeallocating.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSObject+RACDeallocating.m"; path = "ReactiveObjC/NSObject+RACDeallocating.m"; sourceTree = ""; }; @@ -1147,7 +1148,6 @@ 3472FECD92FFD660DD4FB223A1814F9D /* DDAssert.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DDAssert.swift; path = Sources/CocoaLumberjackSwift/DDAssert.swift; sourceTree = ""; }; 34CB45701B6EA0DFF5880C53D9204148 /* FirebaseInstallations-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FirebaseInstallations-umbrella.h"; sourceTree = ""; }; 34D941334F74A82B52F01C92389C2A8F /* MASPreferences.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MASPreferences.release.xcconfig; sourceTree = ""; }; - 35A368BC505EC6C1A5632EC7438C4B58 /* Sparkle.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Sparkle.debug.xcconfig; sourceTree = ""; }; 36A4A62A1CCA6B9F3C0381439421C36C /* Pods-EasydictTests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-EasydictTests.modulemap"; sourceTree = ""; }; 3743207240D54CEFFE648B7D626F359E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; 37BB97A6A6F13B0DD0AF35A3561F413E /* FIRInstallations.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallations.m; path = FirebaseInstallations/Source/Library/FIRInstallations.m; sourceTree = ""; }; @@ -1168,7 +1168,6 @@ 3BAC6E1228C2BC6DC8163D4450D098F8 /* pb_decode.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = pb_decode.h; sourceTree = ""; }; 3BD0EF0E8058556E9E4154876BCA6403 /* FIRInstallations.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallations.h; path = FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FIRInstallations.h; sourceTree = ""; }; 3CC11FBDD4514DD62185F66FA1BB59DA /* GULAppEnvironmentUtil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULAppEnvironmentUtil.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULAppEnvironmentUtil.h; sourceTree = ""; }; - 3D1F2ADA25ED6F49C1E8AF57AF33809C /* SUAppcastItem.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUAppcastItem.h; path = Sparkle.framework/Versions/A/Headers/SUAppcastItem.h; sourceTree = ""; }; 3D714385EE98AA96B6466D97FCF75BBD /* FIRInstallationsItem.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsItem.h; path = FirebaseInstallations/Source/Library/FIRInstallationsItem.h; sourceTree = ""; }; 3D8AF91AB8FD9A6A5BBDD47639B307A6 /* JLRoutes-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "JLRoutes-Info.plist"; sourceTree = ""; }; 3DEBA70364007ADB0E299F01E120926C /* DDFileLogger+Buffering.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "DDFileLogger+Buffering.h"; path = "Sources/CocoaLumberjack/include/CocoaLumberjack/DDFileLogger+Buffering.h"; sourceTree = ""; }; @@ -1177,7 +1176,6 @@ 3EF29D13FE3FD265AF7C3E941196A9F7 /* CocoaLumberjack-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "CocoaLumberjack-umbrella.h"; sourceTree = ""; }; 3F166DB3916BB220B8952CF070CDBE32 /* MJProperty.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MJProperty.m; path = MJExtension/MJProperty.m; sourceTree = ""; }; 3F43105E45B8B34020C641CE5E80DBB5 /* MJPropertyType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJPropertyType.h; path = MJExtension/MJPropertyType.h; sourceTree = ""; }; - 3FDFCBF4D9644C260C5130511117845F /* SUVersionDisplayProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUVersionDisplayProtocol.h; path = Sparkle.framework/Versions/A/Headers/SUVersionDisplayProtocol.h; sourceTree = ""; }; 407A5D4768F7D9959807ADE376E04A48 /* JLRRouteHandler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = JLRRouteHandler.m; path = JLRoutes/Classes/JLRRouteHandler.m; sourceTree = ""; }; 40CEDC5DC626DF80FC5B97453D847E6C /* CocoaLumberjack-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "CocoaLumberjack-dummy.m"; sourceTree = ""; }; 4112E77985AC668857F5361C9DBAEFB7 /* NSArray+RACSequenceAdditions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSArray+RACSequenceAdditions.m"; path = "ReactiveObjC/NSArray+RACSequenceAdditions.m"; sourceTree = ""; }; @@ -1207,6 +1205,7 @@ 49F057D8FB318FE106254E54B6742A7B /* GULKeychainStorage.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULKeychainStorage.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULKeychainStorage.h; sourceTree = ""; }; 4A9EAC78069207C58D52E4061D01B118 /* FirebaseInstallations.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FirebaseInstallations.h; path = FirebaseInstallations/Source/Library/Public/FirebaseInstallations/FirebaseInstallations.h; sourceTree = ""; }; 4B230625037F0D9D4765AEC7532DF289 /* RACEagerSequence.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RACEagerSequence.m; path = ReactiveObjC/RACEagerSequence.m; sourceTree = ""; }; + 4B5D71ABA6E16D23ED0378C3160F3AF1 /* SPUDownloadData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPUDownloadData.h; path = Sparkle.framework/Versions/A/Headers/SPUDownloadData.h; sourceTree = ""; }; 4B9AEE8F2B1D49DD6CB76F20F855DB89 /* KVOController.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = KVOController.debug.xcconfig; sourceTree = ""; }; 4BE17F938C1539972A20E1B100916333 /* _ObjC_HeartbeatController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = _ObjC_HeartbeatController.swift; path = FirebaseCore/Internal/Sources/HeartbeatLogging/_ObjC_HeartbeatController.swift; sourceTree = ""; }; 4BE4208C690F7B121BF91F6E3E065CB5 /* DDLog+LOGV.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "DDLog+LOGV.h"; path = "Sources/CocoaLumberjack/include/CocoaLumberjack/DDLog+LOGV.h"; sourceTree = ""; }; @@ -1219,7 +1218,6 @@ 4E4676902CB3321864A88D3381CF2A98 /* RACStringSequence.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RACStringSequence.m; path = ReactiveObjC/RACStringSequence.m; sourceTree = ""; }; 4E751B045981CF3D87FC06CDD929455C /* GULNetworkInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkInternal.h; path = GoogleUtilities/Network/GULNetworkInternal.h; sourceTree = ""; }; 4E8F89C2BFEBDBA91E858C7D14C96FDC /* GULReachabilityChecker+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "GULReachabilityChecker+Internal.h"; path = "GoogleUtilities/Reachability/GULReachabilityChecker+Internal.h"; sourceTree = ""; }; - 4EBC236DB0FD81B2ABCDA87E7BA5101B /* SUUpdaterDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUUpdaterDelegate.h; path = Sparkle.framework/Versions/A/Headers/SUUpdaterDelegate.h; sourceTree = ""; }; 4EEC6F934214FD9C57792B274116C93B /* MASShortcutView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcutView.h; path = Framework/UI/MASShortcutView.h; sourceTree = ""; }; 4EF6E0323C061F409F19E009102D4490 /* MASShortcut.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MASShortcut.release.xcconfig; sourceTree = ""; }; 4F40C9BEAB46AEB233EBA0E2971A0373 /* SSZipArchive.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SSZipArchive.debug.xcconfig; sourceTree = ""; }; @@ -1243,11 +1241,9 @@ 578D4A9645A2982C92A3431909C635E2 /* mz_compat.c */ = {isa = PBXFileReference; includeInIndex = 1; name = mz_compat.c; path = SSZipArchive/minizip/mz_compat.c; sourceTree = ""; }; 5795811E106ED74D63F65B1D6628A679 /* FBLPromise+Any.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Any.h"; path = "Sources/FBLPromises/include/FBLPromise+Any.h"; sourceTree = ""; }; 57B018BC921A0DB6EC09028D17AEA059 /* ReactiveObjC-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "ReactiveObjC-prefix.pch"; sourceTree = ""; }; - 57D48B562A16327B447692577E7F875B /* Sparkle.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Sparkle.release.xcconfig; sourceTree = ""; }; 5854B160154EEE49D045997AB6B21DAF /* RACBlockTrampoline.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RACBlockTrampoline.h; path = ReactiveObjC/RACBlockTrampoline.h; sourceTree = ""; }; 58F8F860EA8DF1085E93D2D8544AD638 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = DEVELOPER_DIR; }; 5960A4D422B3E941A9B2F309D16D41E7 /* RACErrorSignal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RACErrorSignal.h; path = ReactiveObjC/RACErrorSignal.h; sourceTree = ""; }; - 5AEE2A17A277030472A888651CCFA2C0 /* SUStandardVersionComparator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUStandardVersionComparator.h; path = Sparkle.framework/Versions/A/Headers/SUStandardVersionComparator.h; sourceTree = ""; }; 5B6F58E3163B3696A74B53BF7DCD30A5 /* RACSubscriptionScheduler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RACSubscriptionScheduler.h; path = ReactiveObjC/RACSubscriptionScheduler.h; sourceTree = ""; }; 5B785E62EB64A1E691BD780BD2081F58 /* MJExtension.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = MJExtension.modulemap; sourceTree = ""; }; 5C755A8F8ED3426D88B28875CF5F337D /* PromisesObjC.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = PromisesObjC.modulemap; sourceTree = ""; }; @@ -1287,7 +1283,7 @@ 66AD0671C7EE5E43469AB7AA0062390F /* FBLPromise+Reduce.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Reduce.m"; path = "Sources/FBLPromises/FBLPromise+Reduce.m"; sourceTree = ""; }; 678297DCF73BB0CE0DB101986C8135E4 /* GoogleUtilities.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleUtilities.release.xcconfig; sourceTree = ""; }; 6784EEF35A9F591AD64489394B18D777 /* GULLoggerLevel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULLoggerLevel.h; path = GoogleUtilities/Logger/Public/GoogleUtilities/GULLoggerLevel.h; sourceTree = ""; }; - 678BF00416399FEABCC8525FDFE0ED89 /* SUCodeSigningVerifier.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUCodeSigningVerifier.h; path = Sparkle.framework/Versions/A/Headers/SUCodeSigningVerifier.h; sourceTree = ""; }; + 678DACAF032936A044B7AD6008F132E3 /* SPUDownloaderSession.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPUDownloaderSession.h; path = Sparkle.framework/Versions/A/Headers/SPUDownloaderSession.h; sourceTree = ""; }; 679F131F2401A653DE0EAE02E389284C /* FIRInstallationsSingleOperationPromiseCache.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsSingleOperationPromiseCache.m; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.m; sourceTree = ""; }; 681F18DD8A5E84CBDC9093C68E5B7864 /* FirebaseCoreInternal.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseCoreInternal.debug.xcconfig; sourceTree = ""; }; 694AAE9E85756E4B2655551A39BA2970 /* nanopb-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "nanopb-prefix.pch"; sourceTree = ""; }; @@ -1312,7 +1308,6 @@ 6FD09E857D84EEBAD81E17EDC3AEBE60 /* JLRParsingUtilities.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = JLRParsingUtilities.m; path = JLRoutes/Classes/JLRParsingUtilities.m; sourceTree = ""; }; 7044BF9285B919F37AD8622A64C71125 /* MJExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = MJExtension.release.xcconfig; sourceTree = ""; }; 707EBD112D64DD65062A4BF5369361AA /* GULSecureCoding.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULSecureCoding.h; path = GoogleUtilities/Environment/Public/GoogleUtilities/GULSecureCoding.h; sourceTree = ""; }; - 71A2FC9B1D951CE359CDE09684AE3F0E /* SPUDownloaderProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPUDownloaderProtocol.h; path = Sparkle.framework/Versions/A/Headers/SPUDownloaderProtocol.h; sourceTree = ""; }; 71A826823EBB787C7191D41B45AF48D5 /* NSNotificationCenter+RACSupport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSNotificationCenter+RACSupport.h"; path = "ReactiveObjC/NSNotificationCenter+RACSupport.h"; sourceTree = ""; }; 72865204D09046E96CF341A031283861 /* FIRComponentType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentType.h; path = FirebaseCore/Extension/FIRComponentType.h; sourceTree = ""; }; 737D9C0CD6F98CBE71654A04138E8E12 /* RACEmptySequence.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RACEmptySequence.h; path = ReactiveObjC/RACEmptySequence.h; sourceTree = ""; }; @@ -1358,6 +1353,7 @@ 85E544E15C6D4898D783481318662BB4 /* FIRInstallationsIIDTokenStore.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsIIDTokenStore.m; path = FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.m; sourceTree = ""; }; 85EDCA82CEE3AE6311165FB6983E596F /* GULMutableDictionary.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULMutableDictionary.m; path = GoogleUtilities/Network/GULMutableDictionary.m; sourceTree = ""; }; 85EE622218B33D4B7F605D2DD553DB9D /* NSObject+MJProperty.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSObject+MJProperty.m"; path = "MJExtension/NSObject+MJProperty.m"; sourceTree = ""; }; + 8605B24A177B577CE5069C5A1CD2A8CB /* SUCodeSigningVerifier.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUCodeSigningVerifier.h; path = Sparkle.framework/Versions/A/Headers/SUCodeSigningVerifier.h; sourceTree = ""; }; 862B743B01A17CA1BFE816296E2C5E6F /* DDTTYLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = DDTTYLogger.h; path = Sources/CocoaLumberjack/include/CocoaLumberjack/DDTTYLogger.h; sourceTree = ""; }; 864E4A5E5ABC03FD6FA5E3FAA116861E /* RACBehaviorSubject.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RACBehaviorSubject.h; path = ReactiveObjC/RACBehaviorSubject.h; sourceTree = ""; }; 8683BCEDCE264F53BFE45EC386CB13BC /* FIRLogger.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRLogger.m; path = FirebaseCore/Sources/FIRLogger.m; sourceTree = ""; }; @@ -1369,6 +1365,7 @@ 886C5C9E7C5B3C7448EE41901847B5BB /* AFURLSessionManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = AFURLSessionManager.m; path = AFNetworking/AFURLSessionManager.m; sourceTree = ""; }; 8891BF3B3683C49FA71FFB325DEBFF6D /* RACTupleSequence.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RACTupleSequence.h; path = ReactiveObjC/RACTupleSequence.h; sourceTree = ""; }; 88967A2A5B806D0966E6C95FC2E6389B /* FIRBundleUtil.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRBundleUtil.m; path = FirebaseCore/Sources/FIRBundleUtil.m; sourceTree = ""; }; + 8901881EA91BADC51C5154625E3ACC70 /* SUVersionComparisonProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUVersionComparisonProtocol.h; path = Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h; sourceTree = ""; }; 8968976128A9B71ECAAD9589893BCE20 /* ZipArchive.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ZipArchive.h; path = SSZipArchive/ZipArchive.h; sourceTree = ""; }; 8A2B5D1F89B9940ACAADA2B9870DF528 /* KVOController-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "KVOController-dummy.m"; sourceTree = ""; }; 8A60CFC28EFE537D195AC6987A41C114 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/AppKit.framework; sourceTree = DEVELOPER_DIR; }; @@ -1389,7 +1386,6 @@ 8D861BF8C4641B97F0EB1A65BB0534B7 /* Masonry.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Masonry.release.xcconfig; sourceTree = ""; }; 8DDDE5CEA8BD66BD88B22E4C34613773 /* mz_strm_pkcrypt.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = mz_strm_pkcrypt.h; path = SSZipArchive/minizip/mz_strm_pkcrypt.h; sourceTree = ""; }; 8E3D8CDA984D7BD0B92511BCAEEE07CE /* MASPreferences.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASPreferences.h; path = Framework/MASPreferences.h; sourceTree = ""; }; - 8E909A1270B604F410F07C855F2A727E /* SUAppcast.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUAppcast.h; path = Sparkle.framework/Versions/A/Headers/SUAppcast.h; sourceTree = ""; }; 8EC08C5E30C59BF8822C4FE99BD48BEF /* NSObject+RACKVOWrapper.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSObject+RACKVOWrapper.m"; path = "ReactiveObjC/NSObject+RACKVOWrapper.m"; sourceTree = ""; }; 8F1B8DEAC644F17AB93908848C017CB4 /* NSURLSession+GULPromises.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSURLSession+GULPromises.m"; path = "GoogleUtilities/Environment/URLSessionPromiseWrapper/NSURLSession+GULPromises.m"; sourceTree = ""; }; 8F336D99ADED6F8867E7778A7CC20DAF /* mz_os_posix.c */ = {isa = PBXFileReference; includeInIndex = 1; name = mz_os_posix.c; path = SSZipArchive/minizip/mz_os_posix.c; sourceTree = ""; }; @@ -1407,6 +1403,7 @@ 92A9D4C36CF260DD5F9056E943E8A72F /* mz_strm_buf.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = mz_strm_buf.h; path = SSZipArchive/minizip/mz_strm_buf.h; sourceTree = ""; }; 92DA1A2029DA7DF544E7655D81AF9AEF /* RACChannel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RACChannel.h; path = ReactiveObjC/RACChannel.h; sourceTree = ""; }; 9312CC9A36808D0478AE8052EF3DF43A /* Pods-EasydictTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-EasydictTests-acknowledgements.plist"; sourceTree = ""; }; + 93D451915512BB5B8129407CEEC8AF87 /* SPUURLRequest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPUURLRequest.h; path = Sparkle.framework/Versions/A/Headers/SPUURLRequest.h; sourceTree = ""; }; 94F390C0ED3B13D8CD73C99B415EFD25 /* FIRLibrary.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRLibrary.h; path = FirebaseCore/Extension/FIRLibrary.h; sourceTree = ""; }; 9557017CFFCCA6BDFC4839A96EFD0115 /* Pods-EasydictTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-EasydictTests-dummy.m"; sourceTree = ""; }; 9563E97D378D80D140F80097B24E8BF4 /* NSObject+RACAppKitBindings.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSObject+RACAppKitBindings.h"; path = "ReactiveObjC/NSObject+RACAppKitBindings.h"; sourceTree = ""; }; @@ -1438,6 +1435,7 @@ 9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 9E028DCE9A3EA887179E94DF87E56258 /* NSData+RACSupport.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSData+RACSupport.m"; path = "ReactiveObjC/NSData+RACSupport.m"; sourceTree = ""; }; 9E40A7C1D74D0AEA54AB5370FBDEE580 /* View+MASShorthandAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "View+MASShorthandAdditions.h"; path = "Masonry/View+MASShorthandAdditions.h"; sourceTree = ""; }; + 9F2C619FDB31A0132BC2E6622A757468 /* SUExport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUExport.h; path = Sparkle.framework/Versions/A/Headers/SUExport.h; sourceTree = ""; }; 9F6145CAE82A98B9ADB59B032BD9EFD2 /* NSObject+RACLifting.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSObject+RACLifting.h"; path = "ReactiveObjC/NSObject+RACLifting.h"; sourceTree = ""; }; 9F7148FB9A09BD5EF6B134155A5D69E7 /* JLRRouteDefinition.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = JLRRouteDefinition.h; path = JLRoutes/Classes/JLRRouteDefinition.h; sourceTree = ""; }; A103FFA7723FBD56B2CDDB706727DF50 /* AFSecurityPolicy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = AFSecurityPolicy.h; path = AFNetworking/AFSecurityPolicy.h; sourceTree = ""; }; @@ -1446,8 +1444,6 @@ A1487C738DEFFD6A5AA3A34D054043A3 /* fr.lproj */ = {isa = PBXFileReference; includeInIndex = 1; name = fr.lproj; path = Resources/fr.lproj; sourceTree = ""; }; A16F275651655CBF3D2D4BFF8FE55BB2 /* FIRInstallationsErrorUtil.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsErrorUtil.h; path = FirebaseInstallations/Source/Library/Errors/FIRInstallationsErrorUtil.h; sourceTree = ""; }; A200108EEA4BECDA9DD5EC834F317BC9 /* FIRInstallationsBackoffController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsBackoffController.m; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsBackoffController.m; sourceTree = ""; }; - A284A6FA4E942BA4AECC95F8A932C043 /* Sparkle.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Sparkle.h; path = Sparkle.framework/Versions/A/Headers/Sparkle.h; sourceTree = ""; }; - A2B124B39390721248F66BAA3CCAC3B9 /* SUUpdater.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUUpdater.h; path = Sparkle.framework/Versions/A/Headers/SUUpdater.h; sourceTree = ""; }; A2BB0B88CD9218949B3C7259ED21E673 /* RACTestScheduler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RACTestScheduler.h; path = ReactiveObjC/RACTestScheduler.h; sourceTree = ""; }; A3086231093078E1EE914935090CE3F6 /* SSZipArchive.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = SSZipArchive.m; path = SSZipArchive/SSZipArchive.m; sourceTree = ""; }; A3255CB3442A19936274DC8ED49454C9 /* JLRoutes.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = JLRoutes.h; path = JLRoutes/JLRoutes.h; sourceTree = ""; }; @@ -1462,7 +1458,6 @@ A5B9D0824FEE61B2D8BBA3E7DD4EAFB1 /* RACSubscriber+Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "RACSubscriber+Private.h"; path = "ReactiveObjC/RACSubscriber+Private.h"; sourceTree = ""; }; A65E46342B6ED4FB6110FF7F5020AB04 /* RACCompoundDisposable.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RACCompoundDisposable.h; path = ReactiveObjC/RACCompoundDisposable.h; sourceTree = ""; }; A692206057C1045A20BFB0D1DBCB8CD8 /* MJPropertyKey.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MJPropertyKey.h; path = MJExtension/MJPropertyKey.h; sourceTree = ""; }; - A6FA51AB1837B5F082EB68AE3D49F666 /* SPUDownloaderDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPUDownloaderDelegate.h; path = Sparkle.framework/Versions/A/Headers/SPUDownloaderDelegate.h; sourceTree = ""; }; A6FECFC0BA3B8818991BDC609B375C8C /* RACSubscriber.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RACSubscriber.h; path = ReactiveObjC/RACSubscriber.h; sourceTree = ""; }; A74972643EE588BE754BB7B04E350B85 /* ReactiveObjC-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ReactiveObjC-Info.plist"; sourceTree = ""; }; A7B279796DC8D7B5C4A33595A7534E32 /* CocoaLumberjack.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CocoaLumberjack.swift; path = Sources/CocoaLumberjackSwift/CocoaLumberjack.swift; sourceTree = ""; }; @@ -1504,6 +1499,7 @@ B3EC852AC9D86C01C24C8141A8AE789C /* GULSceneDelegateSwizzler_Private.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULSceneDelegateSwizzler_Private.h; path = GoogleUtilities/AppDelegateSwizzler/Internal/GULSceneDelegateSwizzler_Private.h; sourceTree = ""; }; B43874C6CBB50E7134FBEC24BABFE14F /* GoogleUtilities */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = GoogleUtilities; path = GoogleUtilities.framework; sourceTree = BUILT_PRODUCTS_DIR; }; B45EF83BEC99EF94E831B46C706E0FD4 /* NSLayoutConstraint+MASDebugAdditions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSLayoutConstraint+MASDebugAdditions.m"; path = "Masonry/NSLayoutConstraint+MASDebugAdditions.m"; sourceTree = ""; }; + B46B4288DFEE6F2DE0EA310BFD6B1157 /* Sparkle.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Sparkle.release.xcconfig; sourceTree = ""; }; B5357AF6A41ACAAFEB4D3C588B07E767 /* FBLPromise+Delay.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Delay.h"; path = "Sources/FBLPromises/include/FBLPromise+Delay.h"; sourceTree = ""; }; B54293899303830EC464E44B649FE7C0 /* FBLPromise+Then.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Then.h"; path = "Sources/FBLPromises/include/FBLPromise+Then.h"; sourceTree = ""; }; B5BBBFB9269F33112C801C5503267CBE /* ResourceBundle-MASPreferences-MASPreferences-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-MASPreferences-MASPreferences-Info.plist"; sourceTree = ""; }; @@ -1522,10 +1518,11 @@ B98A02E060A69B7AF8B9C58F9FC5201C /* FIRInstallationsItem.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRInstallationsItem.m; path = FirebaseInstallations/Source/Library/FIRInstallationsItem.m; sourceTree = ""; }; B9B634FD4B7190E722747B5144C81739 /* NSString+MJExtension.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSString+MJExtension.h"; path = "MJExtension/NSString+MJExtension.h"; sourceTree = ""; }; BA05935B53D544259CA41CA187B649E6 /* FIRFirebaseUserAgent.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRFirebaseUserAgent.m; path = FirebaseCore/Sources/FIRFirebaseUserAgent.m; sourceTree = ""; }; + BA2E2C2C382C96A6109B7CC5071D7A46 /* Sparkle.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Sparkle.debug.xcconfig; sourceTree = ""; }; + BA7D157AE2829DB2C7C2DBD57D6BDEC6 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Sparkle.framework; sourceTree = ""; }; BAFAE84213058BB8FA3401CED621E9B2 /* KVOController-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "KVOController-Info.plist"; sourceTree = ""; }; BB0A2F30D0F9C083494674E5388D4657 /* MASShortcutValidator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = MASShortcutValidator.h; path = Framework/Model/MASShortcutValidator.h; sourceTree = ""; }; BB166CAAE8A0A25718195F193514D8BB /* RACValueTransformer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RACValueTransformer.m; path = ReactiveObjC/RACValueTransformer.m; sourceTree = ""; }; - BB6EF68747645B634C7A67CA98A42BB5 /* Sparkle-copy-dsyms.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Sparkle-copy-dsyms.sh"; sourceTree = ""; }; BB8367FF47DE19159DCAE0DA91FFFF5F /* FBLPromises.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBLPromises.h; path = Sources/FBLPromises/include/FBLPromises.h; sourceTree = ""; }; BBB1BC03F8D20BF11FA9A90365E0CF01 /* NSObject+MJKeyValue.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSObject+MJKeyValue.m"; path = "MJExtension/NSObject+MJKeyValue.m"; sourceTree = ""; }; BC871A19C3776780E99434A9EEF838F8 /* ReactiveObjC-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "ReactiveObjC-dummy.m"; sourceTree = ""; }; @@ -1560,11 +1557,13 @@ C60A1B3007FB60DB85962874C2E0CBF4 /* Masonry.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Masonry.h; path = Masonry/Masonry.h; sourceTree = ""; }; C61EB377CEDD00BEDA29B1F839C717C1 /* FBLPromise+Timeout.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Timeout.m"; path = "Sources/FBLPromises/FBLPromise+Timeout.m"; sourceTree = ""; }; C628921959EE4F6AEE21F9CD228BE561 /* FBLPromise+Reduce.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Reduce.h"; path = "Sources/FBLPromises/include/FBLPromise+Reduce.h"; sourceTree = ""; }; + C6E15CD5D5DEEE230B32CFD4979B92A8 /* SUStandardVersionComparator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUStandardVersionComparator.h; path = Sparkle.framework/Versions/A/Headers/SUStandardVersionComparator.h; sourceTree = ""; }; C71B3F9996F6DF1106CF326D97F8C0EB /* FBLPromise+Always.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Always.h"; path = "Sources/FBLPromises/include/FBLPromise+Always.h"; sourceTree = ""; }; C737832F5A9F9AD64F2622C28785B944 /* FBLPromise+Timeout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "FBLPromise+Timeout.h"; path = "Sources/FBLPromises/include/FBLPromise+Timeout.h"; sourceTree = ""; }; C8F32C12CAF2099498C4EC43743F16DB /* SwiftLogLevel.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SwiftLogLevel.h; path = Sources/CocoaLumberjackSwiftSupport/include/CocoaLumberjackSwiftSupport/SwiftLogLevel.h; sourceTree = ""; }; C92AA3B32FE450191A39C3467ED52F84 /* GULKeychainUtils.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = GULKeychainUtils.m; path = GoogleUtilities/Environment/SecureStorage/GULKeychainUtils.m; sourceTree = ""; }; C9AE494AF363E50EB2867C25AD3624D0 /* FIRInstallationsIIDTokenStore.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsIIDTokenStore.h; path = FirebaseInstallations/Source/Library/IIDMigration/FIRInstallationsIIDTokenStore.h; sourceTree = ""; }; + C9DC968D10EAE258248B27BCE8561158 /* SPUDownloaderDelegate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPUDownloaderDelegate.h; path = Sparkle.framework/Versions/A/Headers/SPUDownloaderDelegate.h; sourceTree = ""; }; CA1722A4A8AFDE544795CCD44D4675EE /* FirebaseInstallations.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = FirebaseInstallations.release.xcconfig; sourceTree = ""; }; CA487D8BC512545D170F148A39EC8EC1 /* FIRComponentType.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRComponentType.h; path = FirebaseCore/Extension/FIRComponentType.h; sourceTree = ""; }; CA48F53B8E696B504B9729AF1EA2BA25 /* NSSet+RACSequenceAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSSet+RACSequenceAdditions.h"; path = "ReactiveObjC/NSSet+RACSequenceAdditions.h"; sourceTree = ""; }; @@ -1590,12 +1589,10 @@ D1520B8B7428274B5806B3E72D2B36EA /* View+MASAdditions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "View+MASAdditions.m"; path = "Masonry/View+MASAdditions.m"; sourceTree = ""; }; D163FDD1B558E63DE884AB82772B3BF9 /* es.lproj */ = {isa = PBXFileReference; includeInIndex = 1; name = es.lproj; path = Resources/es.lproj; sourceTree = ""; }; D1CA8EC9B89F69A56B3764C7BBB69C8C /* NSObject+MJCoding.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSObject+MJCoding.h"; path = "MJExtension/NSObject+MJCoding.h"; sourceTree = ""; }; - D1CB75F2E99554F034FE568FB001ACC3 /* SPUURLRequest.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPUURLRequest.h; path = Sparkle.framework/Versions/A/Headers/SPUURLRequest.h; sourceTree = ""; }; D204FF4A66E13434DF38C8CDE384CDA2 /* CLIColor.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = CLIColor.m; path = Sources/CocoaLumberjack/CLI/CLIColor.m; sourceTree = ""; }; D2F35D6C8E8BD884AEAE243B2C8D5F48 /* FIRComponentContainer.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRComponentContainer.m; path = FirebaseCore/Sources/FIRComponentContainer.m; sourceTree = ""; }; D343F407C96A8BB06B6E6E7F6487613C /* FIRHeartbeatLogger.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRHeartbeatLogger.h; path = FirebaseCore/Extension/FIRHeartbeatLogger.h; sourceTree = ""; }; D39D19A446F112B7C5289EB57FEA1E2D /* RACStream.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RACStream.h; path = ReactiveObjC/RACStream.h; sourceTree = ""; }; - D3AC3423C785239B3C245FD145A93709 /* SUVersionComparisonProtocol.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUVersionComparisonProtocol.h; path = Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h; sourceTree = ""; }; D41925A270C555B7F208323C8B98E8D6 /* NSObject+RACDeallocating.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSObject+RACDeallocating.h"; path = "ReactiveObjC/NSObject+RACDeallocating.h"; sourceTree = ""; }; D438035AA21542136BE5990CEFA21202 /* AFNetworkReachabilityManager.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = AFNetworkReachabilityManager.m; path = AFNetworking/AFNetworkReachabilityManager.m; sourceTree = ""; }; D4577EDD80EE21A830A0D562EA93FACB /* Pods-Easydict-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-Easydict-acknowledgements.markdown"; sourceTree = ""; }; @@ -1617,6 +1614,7 @@ D8AB5962AFA18EB37DC037D1E0CCED3A /* GULNetworkURLSession.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkURLSession.h; path = GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkURLSession.h; sourceTree = ""; }; D8F0219016AB4A36AAAF4B2E6940E6CD /* NSControl+RACTextSignalSupport.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSControl+RACTextSignalSupport.h"; path = "ReactiveObjC/NSControl+RACTextSignalSupport.h"; sourceTree = ""; }; DADDA26FCE04729DD95BC53E9BE728B5 /* NSControl+RACCommandSupport.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSControl+RACCommandSupport.m"; path = "ReactiveObjC/NSControl+RACCommandSupport.m"; sourceTree = ""; }; + DB349D85CAF7F3B744DA98A490114112 /* SPUDownloader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPUDownloader.h; path = Sparkle.framework/Versions/A/Headers/SPUDownloader.h; sourceTree = ""; }; DB8642AA1B0F69006926C5261D52EDE2 /* RACSignalSequence.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RACSignalSequence.m; path = ReactiveObjC/RACSignalSequence.m; sourceTree = ""; }; DB92D2B8B64A1DDFB9EB37D05CA928FC /* PromisesObjC-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "PromisesObjC-Info.plist"; sourceTree = ""; }; DCD032F5C98F2C5606E635EF3F74C9CA /* GoogleAppMeasurement.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = GoogleAppMeasurement.release.xcconfig; sourceTree = ""; }; @@ -1626,9 +1624,8 @@ DEF3CD5C60EF3A8E37CEE79315A984EF /* FIRInstallationsSingleOperationPromiseCache.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsSingleOperationPromiseCache.h; path = FirebaseInstallations/Source/Library/InstallationsIDController/FIRInstallationsSingleOperationPromiseCache.h; sourceTree = ""; }; DF4E5A3A4936F5AADDA17D5D17BACFBC /* NSText+RACSignalSupport.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSText+RACSignalSupport.m"; path = "ReactiveObjC/NSText+RACSignalSupport.m"; sourceTree = ""; }; DF8EA64480E422C360961E1144C10003 /* HeartbeatLoggingTestUtils.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HeartbeatLoggingTestUtils.swift; path = FirebaseCore/Internal/Sources/HeartbeatLogging/HeartbeatLoggingTestUtils.swift; sourceTree = ""; }; - DFFB77922F4A1F972D9060C9C9C9AF02 /* SPUDownloadData.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPUDownloadData.h; path = Sparkle.framework/Versions/A/Headers/SPUDownloadData.h; sourceTree = ""; }; E0AB6323A3B9F9FC20B53F1C455F6752 /* MASShortcutView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcutView.m; path = Framework/UI/MASShortcutView.m; sourceTree = ""; }; - E0D3ECFED462ABA37249B41F340769A8 /* SPUDownloader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPUDownloader.h; path = Sparkle.framework/Versions/A/Headers/SPUDownloader.h; sourceTree = ""; }; + E0B81CF94971676B125E38CBA1C416C6 /* Sparkle.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = Sparkle.h; path = Sparkle.framework/Versions/A/Headers/Sparkle.h; sourceTree = ""; }; E20765094E8DAA7ECB6186CAEE21BB60 /* FirebaseCoreInternal-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FirebaseCoreInternal-umbrella.h"; sourceTree = ""; }; E22D14539E9436A17F56B2A810CF1926 /* NSObject+MJKeyValue.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSObject+MJKeyValue.h"; path = "MJExtension/NSObject+MJKeyValue.h"; sourceTree = ""; }; E2395D2C9456CD1F598E1CBC11BC06BE /* pl.lproj */ = {isa = PBXFileReference; includeInIndex = 1; name = pl.lproj; path = Resources/pl.lproj; sourceTree = ""; }; @@ -1637,6 +1634,7 @@ E2B63D462DB7F827C4B11FD51E4F8E2D /* FirebaseCore */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = FirebaseCore; path = FirebaseCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; E2D0E5EB6A754865357285C9435A05D2 /* AFURLResponseSerialization.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = AFURLResponseSerialization.h; path = AFNetworking/AFURLResponseSerialization.h; sourceTree = ""; }; E39136CD44C88B45976196E8D0D5FC50 /* FIRInstallationsStoredItem.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsStoredItem.h; path = FirebaseInstallations/Source/Library/InstallationsStore/FIRInstallationsStoredItem.h; sourceTree = ""; }; + E39AE2C44FEB5EC4152E706DCB1CF154 /* SUAppcast.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SUAppcast.h; path = Sparkle.framework/Versions/A/Headers/SUAppcast.h; sourceTree = ""; }; E4017CBA53BEED387AB8151BAAD76B7C /* GULNetworkConstants.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULNetworkConstants.h; path = GoogleUtilities/Network/Public/GoogleUtilities/GULNetworkConstants.h; sourceTree = ""; }; E414749DA1B41A7087909D60A80C4D05 /* NSLayoutConstraint+MASDebugAdditions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSLayoutConstraint+MASDebugAdditions.h"; path = "Masonry/NSLayoutConstraint+MASDebugAdditions.h"; sourceTree = ""; }; E46780643C2964561A52B1495E348FB3 /* GoogleUtilities.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = GoogleUtilities.modulemap; sourceTree = ""; }; @@ -1671,6 +1669,7 @@ EEA8379139998EE02E3226C8D88696A8 /* RACQueueScheduler.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = RACQueueScheduler.m; path = ReactiveObjC/RACQueueScheduler.m; sourceTree = ""; }; EEE28DC923B30AB4043C26F84C34B0E5 /* FIROptions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIROptions.h; path = FirebaseCore/Sources/Public/FirebaseCore/FIROptions.h; sourceTree = ""; }; EEEADA72724E304B319782E1557B5BDD /* RACTargetQueueScheduler.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = RACTargetQueueScheduler.h; path = ReactiveObjC/RACTargetQueueScheduler.h; sourceTree = ""; }; + EF2F4DFAA9D9F8746CDA36E884C850B2 /* SPUDownloaderDeprecated.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPUDownloaderDeprecated.h; path = Sparkle.framework/Versions/A/Headers/SPUDownloaderDeprecated.h; sourceTree = ""; }; EF732C8CEE6AEE702C2AC90788417241 /* FIRInstallationsAuthTokenResultInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FIRInstallationsAuthTokenResultInternal.h; path = FirebaseInstallations/Source/Library/FIRInstallationsAuthTokenResultInternal.h; sourceTree = ""; }; EF9B9CA9D2B51683AE8C3F3F49DC07D6 /* MASShortcutValidator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = MASShortcutValidator.m; path = Framework/Model/MASShortcutValidator.m; sourceTree = ""; }; EFF2413A5DDAD4038CCD665218B813E3 /* SSZipCommon.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SSZipCommon.h; path = SSZipArchive/SSZipCommon.h; sourceTree = ""; }; @@ -1696,7 +1695,6 @@ F47C5B0FDA937D3AC1B501A11E094A02 /* GULOriginalIMPConvenienceMacros.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = GULOriginalIMPConvenienceMacros.h; path = GoogleUtilities/MethodSwizzler/Public/GoogleUtilities/GULOriginalIMPConvenienceMacros.h; sourceTree = ""; }; F499235A0E4DF235B3A310438AE716E5 /* FBLPromise+Retry.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FBLPromise+Retry.m"; path = "Sources/FBLPromises/FBLPromise+Retry.m"; sourceTree = ""; }; F615DE50A6ED9C72DB4394EFA9A32358 /* FIRDependency.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FIRDependency.m; path = FirebaseCore/Sources/FIRDependency.m; sourceTree = ""; }; - F63554006364546D2F2500248C78D27C /* SPUDownloaderSession.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = SPUDownloaderSession.h; path = Sparkle.framework/Versions/A/Headers/SPUDownloaderSession.h; sourceTree = ""; }; F677A0AEBCCF071B6EB8C8BEB3667CCF /* NSIndexSet+RACSequenceAdditions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSIndexSet+RACSequenceAdditions.m"; path = "ReactiveObjC/NSIndexSet+RACSequenceAdditions.m"; sourceTree = ""; }; F6A5B055A1464C2AA50802D86157814D /* ReactiveObjC.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = ReactiveObjC.h; path = ReactiveObjC/ReactiveObjC.h; sourceTree = ""; }; F6AC3A4C0F4CF68BC61D5D70CB9B9971 /* Pods-EasydictTests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-EasydictTests-frameworks.sh"; sourceTree = ""; }; @@ -1846,14 +1844,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 9BF1C63B66BE8950B2DF22A1370D928C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - A6E237A6EBE5E875DF5AFFC3880D2068 /* Cocoa.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; A084F7FDACBE0CEF9283FC54DDF38EC9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -1892,6 +1882,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + E4456191509539D24F16F70E6DA61B98 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1AA3ACEE6E158494C354432838B25195 /* Cocoa.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; FFCC46F8B3D4BD9BCDE0FF8D3191A4EE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -2050,6 +2048,14 @@ name = Frameworks; sourceTree = ""; }; + 1DDF00C48501AFB817EB92C2C31D9CFC /* Frameworks */ = { + isa = PBXGroup; + children = ( + BA7D157AE2829DB2C7C2DBD57D6BDEC6 /* Sparkle.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; 215ED34E61E8B6023745DAF7D65B88D6 /* GoogleUtilities */ = { isa = PBXGroup; children = ( @@ -2275,17 +2281,6 @@ name = AdIdSupport; sourceTree = ""; }; - 4886932CEAA2576F483D8A40C8AAC0F0 /* Support Files */ = { - isa = PBXGroup; - children = ( - BB6EF68747645B634C7A67CA98A42BB5 /* Sparkle-copy-dsyms.sh */, - 35A368BC505EC6C1A5632EC7438C4B58 /* Sparkle.debug.xcconfig */, - 57D48B562A16327B447692577E7F875B /* Sparkle.release.xcconfig */, - ); - name = "Support Files"; - path = "../Target Support Files/Sparkle"; - sourceTree = ""; - }; 4B6DDE16EB4A6532422CB5B3E026EFB3 /* PromisesObjC */ = { isa = PBXGroup; children = ( @@ -2468,6 +2463,16 @@ name = "NSData+zlib"; sourceTree = ""; }; + 659E75A915A4100769EBDA4BA792C65C /* Support Files */ = { + isa = PBXGroup; + children = ( + BA2E2C2C382C96A6109B7CC5071D7A46 /* Sparkle.debug.xcconfig */, + B46B4288DFEE6F2DE0EA310BFD6B1157 /* Sparkle.release.xcconfig */, + ); + name = "Support Files"; + path = "../Target Support Files/Sparkle"; + sourceTree = ""; + }; 6600DE2E11E3EE520D53041041514366 /* Pods */ = { isa = PBXGroup; children = ( @@ -2489,7 +2494,7 @@ 2B50A2662D560163E9B19C455DDF9A93 /* nanopb */, 4B6DDE16EB4A6532422CB5B3E026EFB3 /* PromisesObjC */, D7A968777E36E7723C1AB85BA7933912 /* ReactiveObjC */, - FDB06A369DCBA34A6390A721FA04AFCE /* Sparkle */, + 8A53421800A094117E35FDCB4C1245D9 /* Sparkle */, D82525C095E75CABFC9362C0EB7E6298 /* SSZipArchive */, ); name = Pods; @@ -2518,14 +2523,6 @@ name = Frameworks; sourceTree = ""; }; - 71D09B38653408F4538CB24E4088D19B /* Frameworks */ = { - isa = PBXGroup; - children = ( - 1D3130D5F3D0CF78A6DFD143C68C25D4 /* Sparkle.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; 74D939E277EB7559941C65454414A687 /* Support Files */ = { isa = PBXGroup; children = ( @@ -2603,6 +2600,34 @@ path = "../Target Support Files/ReactiveObjC"; sourceTree = ""; }; + 8A53421800A094117E35FDCB4C1245D9 /* Sparkle */ = { + isa = PBXGroup; + children = ( + E0B81CF94971676B125E38CBA1C416C6 /* Sparkle.h */, + 4B5D71ABA6E16D23ED0378C3160F3AF1 /* SPUDownloadData.h */, + DB349D85CAF7F3B744DA98A490114112 /* SPUDownloader.h */, + C9DC968D10EAE258248B27BCE8561158 /* SPUDownloaderDelegate.h */, + EF2F4DFAA9D9F8746CDA36E884C850B2 /* SPUDownloaderDeprecated.h */, + 0A211D270F1128D61964DE9513342225 /* SPUDownloaderProtocol.h */, + 678DACAF032936A044B7AD6008F132E3 /* SPUDownloaderSession.h */, + 93D451915512BB5B8129407CEEC8AF87 /* SPUURLRequest.h */, + E39AE2C44FEB5EC4152E706DCB1CF154 /* SUAppcast.h */, + 09B96E945C01D1E10989870F68470BA7 /* SUAppcastItem.h */, + 8605B24A177B577CE5069C5A1CD2A8CB /* SUCodeSigningVerifier.h */, + 255B849B0C00A4C884C5DA5A2954FF46 /* SUErrors.h */, + 9F2C619FDB31A0132BC2E6622A757468 /* SUExport.h */, + C6E15CD5D5DEEE230B32CFD4979B92A8 /* SUStandardVersionComparator.h */, + 0ED505B20168C30B58A8650464610202 /* SUUpdater.h */, + 2D9BEA613483DB734927C29098453941 /* SUUpdaterDelegate.h */, + 8901881EA91BADC51C5154625E3ACC70 /* SUVersionComparisonProtocol.h */, + 00065392AED1AF258139F87F6624E422 /* SUVersionDisplayProtocol.h */, + 1DDF00C48501AFB817EB92C2C31D9CFC /* Frameworks */, + 659E75A915A4100769EBDA4BA792C65C /* Support Files */, + ); + name = Sparkle; + path = Sparkle; + sourceTree = ""; + }; 8A65F1B77DDC6B6B6191BC2D66503063 /* Support Files */ = { isa = PBXGroup; children = ( @@ -3279,34 +3304,6 @@ name = Swift; sourceTree = ""; }; - FDB06A369DCBA34A6390A721FA04AFCE /* Sparkle */ = { - isa = PBXGroup; - children = ( - A284A6FA4E942BA4AECC95F8A932C043 /* Sparkle.h */, - DFFB77922F4A1F972D9060C9C9C9AF02 /* SPUDownloadData.h */, - E0D3ECFED462ABA37249B41F340769A8 /* SPUDownloader.h */, - A6FA51AB1837B5F082EB68AE3D49F666 /* SPUDownloaderDelegate.h */, - 051FA5EDC1016ED519B5FF4105090CA1 /* SPUDownloaderDeprecated.h */, - 71A2FC9B1D951CE359CDE09684AE3F0E /* SPUDownloaderProtocol.h */, - F63554006364546D2F2500248C78D27C /* SPUDownloaderSession.h */, - D1CB75F2E99554F034FE568FB001ACC3 /* SPUURLRequest.h */, - 8E909A1270B604F410F07C855F2A727E /* SUAppcast.h */, - 3D1F2ADA25ED6F49C1E8AF57AF33809C /* SUAppcastItem.h */, - 678BF00416399FEABCC8525FDFE0ED89 /* SUCodeSigningVerifier.h */, - 0107F48BA943EA4C4E19D1B5102C4CCE /* SUErrors.h */, - 1539C997098CE0EC59133D405A57E9E1 /* SUExport.h */, - 5AEE2A17A277030472A888651CCFA2C0 /* SUStandardVersionComparator.h */, - A2B124B39390721248F66BAA3CCAC3B9 /* SUUpdater.h */, - 4EBC236DB0FD81B2ABCDA87E7BA5101B /* SUUpdaterDelegate.h */, - D3AC3423C785239B3C245FD145A93709 /* SUVersionComparisonProtocol.h */, - 3FDFCBF4D9644C260C5130511117845F /* SUVersionDisplayProtocol.h */, - 71D09B38653408F4538CB24E4088D19B /* Frameworks */, - 4886932CEAA2576F483D8A40C8AAC0F0 /* Support Files */, - ); - name = Sparkle; - path = Sparkle; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -3481,18 +3478,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 5049A5C1CF76AC5D92C3008C90EBBCD2 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 4506B1E2DE87A24C96A173ED89058137 /* nanopb-umbrella.h in Headers */, - 785562D852A727625DF8315AF53FFBBE /* pb.h in Headers */, - CC4B1789BE5CA206D906F1625EB9518C /* pb_common.h in Headers */, - F0A7D11A89528FD43D72B18659A369F5 /* pb_decode.h in Headers */, - 591D96FE65EAEBD515E6C50490972439 /* pb_encode.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 5CC842F78D1E94341EA5A08C95B66443 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -3532,6 +3517,18 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 659CA20B96D89C51587E2A3FAAC8597C /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 0DEDE904281DC1C3CAF904942D3BA558 /* nanopb-umbrella.h in Headers */, + 7A32A35D58EE070D44E2E6B739824659 /* pb.h in Headers */, + E8D65DB9D74862EA4DEE4B7F178E74B7 /* pb_common.h in Headers */, + 0CEDC7F18D7506B918B3F22F0ADB21A9 /* pb_decode.h in Headers */, + 84534802D7D479A0B0664DA5FA438892 /* pb_encode.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 678D46A2A979B059B3F172AD8C01A280 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -4004,7 +4001,7 @@ ADAADCA08821C1874001C1968D6CD2C3 /* PBXTargetDependency */, 1202B36D0022CB76133AA8A0BBDBFF22 /* PBXTargetDependency */, 6D1BB1F5AF9494F2675A5A1F779F30A6 /* PBXTargetDependency */, - F7BA034235DD60DC917A1CE10F2226C5 /* PBXTargetDependency */, + D39FC97C15458EDDE28755D1F8CCEBAC /* PBXTargetDependency */, ); name = "Pods-Easydict"; productName = Pods_Easydict; @@ -4090,12 +4087,12 @@ }; D2B5E7DCCBBFB32341D857D01211A1A3 /* nanopb */ = { isa = PBXNativeTarget; - buildConfigurationList = 64C0A73B1B1F90374066E2CC62577AF3 /* Build configuration list for PBXNativeTarget "nanopb" */; + buildConfigurationList = F107942DDEA0E39C480DDD0618D06470 /* Build configuration list for PBXNativeTarget "nanopb" */; buildPhases = ( - 5049A5C1CF76AC5D92C3008C90EBBCD2 /* Headers */, - 398A42ACCF755DDE0629A0477FA7B5C6 /* Sources */, - 9BF1C63B66BE8950B2DF22A1370D928C /* Frameworks */, - 9172693D1A1BCECCE278704F99A5C34A /* Resources */, + 659CA20B96D89C51587E2A3FAAC8597C /* Headers */, + A768DE5C12E29AC6DA8B92F5B533FCAE /* Sources */, + E4456191509539D24F16F70E6DA61B98 /* Frameworks */, + DC1D6B3874F18F1F3409CD6E09E30048 /* Resources */, ); buildRules = ( ); @@ -4299,13 +4296,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 9172693D1A1BCECCE278704F99A5C34A /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; 9A01F4331891131499B095412DD98450 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -4343,6 +4333,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DC1D6B3874F18F1F3409CD6E09E30048 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; E420804F27DACB76E420C2CAA565E1C5 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -4402,23 +4399,6 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/FirebaseAnalytics/FirebaseAnalytics-xcframeworks.sh\"\n"; showEnvVarsInLog = 0; }; - 9A181939804C9F1E56224ACF31BF086B /* [CP] Copy dSYMs */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Sparkle/Sparkle-copy-dsyms-input-files.xcfilelist", - ); - name = "[CP] Copy dSYMs"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Sparkle/Sparkle-copy-dsyms-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Sparkle/Sparkle-copy-dsyms.sh\"\n"; - showEnvVarsInLog = 0; - }; AAD7D4593ED3B713FDA455F0E36487CE /* [CP] Copy XCFrameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -4481,17 +4461,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 398A42ACCF755DDE0629A0477FA7B5C6 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 80AB2580823D59D868F36A0CCFD33686 /* nanopb-dummy.m in Sources */, - 3F05B632C059859E35DEB5D315E8A3EF /* pb_common.c in Sources */, - 34CC3C8F7DC8C7CA75166D30152331FC /* pb_decode.c in Sources */, - FBC73635225EE559463755D289764259 /* pb_encode.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 480165B36C06A1FA1D8EFEDB30BA45F5 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -4616,6 +4585,17 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + A768DE5C12E29AC6DA8B92F5B533FCAE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33E8837FC20992C9A379ED1663E2F9CA /* nanopb-dummy.m in Sources */, + E1223A4175D23FD57B88D5CF870171C1 /* pb_common.c in Sources */, + 1F833B128D16D4283D4298CBD2F72EE1 /* pb_decode.c in Sources */, + 9D937CED1882BE56C77CEFFEE7B7F34F /* pb_encode.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; A9A4A428411D7908E31BD7DE3790322A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -4840,12 +4820,6 @@ target = 87803597EB3F20FC46472B85392EC4FD /* FirebaseInstallations */; targetProxy = FD01A0F12E3992985C708E72601AC91C /* PBXContainerItemProxy */; }; - 0E9A554FD59787BBD43C562B29547AFF /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = nanopb; - target = D2B5E7DCCBBFB32341D857D01211A1A3 /* nanopb */; - targetProxy = ED546F592AAEDD40903298BAB4D5F3F6 /* PBXContainerItemProxy */; - }; 0F908F84E158D199221C13667F23C606 /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = MJExtension; @@ -4906,6 +4880,12 @@ target = 94C1BAA17BCEBC27586488A205D2E0CB /* JLRoutes */; targetProxy = E4BA97B3239BC4A13DB03C818E035901 /* PBXContainerItemProxy */; }; + 457A6020E71E493D7145A8EC8874C5BB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = nanopb; + target = D2B5E7DCCBBFB32341D857D01211A1A3 /* nanopb */; + targetProxy = DC734C5132D5128FB9893600B8BDECC3 /* PBXContainerItemProxy */; + }; 5AFD1B2EBF5C1BFB853A62D69204757B /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = FirebaseCoreInternal; @@ -4972,6 +4952,12 @@ target = 8D7F5D5DD528D21A72DC87ADA5B12E2D /* GoogleUtilities */; targetProxy = 315A1A3428DA85D4B4611BC030BC2F29 /* PBXContainerItemProxy */; }; + 8EC725E4A839B10DADF46962FFDE9610 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = nanopb; + target = D2B5E7DCCBBFB32341D857D01211A1A3 /* nanopb */; + targetProxy = 1C4A2F9D15644458CE86B6A5A34B22C6 /* PBXContainerItemProxy */; + }; 915F292C60D2EAA73CAEE0D4CDDC82DF /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = MJExtension; @@ -5026,11 +5012,11 @@ target = 4402AFF83DBDC4DD07E198685FDC2DF2 /* FirebaseCore */; targetProxy = 273A4366EFC2732A8CDE6A5F942CFC37 /* PBXContainerItemProxy */; }; - D36C03805994F45C53E4C284CBBE56F5 /* PBXTargetDependency */ = { + D39FC97C15458EDDE28755D1F8CCEBAC /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = nanopb; target = D2B5E7DCCBBFB32341D857D01211A1A3 /* nanopb */; - targetProxy = C52B91CFFD0D3AA5DE574B13A2AFED63 /* PBXContainerItemProxy */; + targetProxy = 4F8CE3325D33821A561FDB1CE7D04943 /* PBXContainerItemProxy */; }; D4FC194AFCFC8847D8DA9CB1E295A4CC /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -5092,12 +5078,6 @@ target = CCE0F64E83CEAFEE20D04DC7BD57303E /* MASPreferences */; targetProxy = 1367C70A1E67FE6053CF879E51E9F75C /* PBXContainerItemProxy */; }; - F7BA034235DD60DC917A1CE10F2226C5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = nanopb; - target = D2B5E7DCCBBFB32341D857D01211A1A3 /* nanopb */; - targetProxy = E0E3CDD0B8D83034668FCA926A36F173 /* PBXContainerItemProxy */; - }; F8D41A4E02603E99A353CE2E6E3941EC /* PBXTargetDependency */ = { isa = PBXTargetDependency; name = CocoaLumberjack; @@ -5286,6 +5266,23 @@ }; name = Release; }; + 1F96F4C0C4BB0F23A0A2EC0AD68FF010 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B46B4288DFEE6F2DE0EA310BFD6B1157 /* Sparkle.release.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + COMBINE_HIDPI_IMAGES = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 11.0; + SDKROOT = macosx; + }; + name = Release; + }; 20D2F6C90D38F8D08A280432BCDF2260 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 42706C333A9D5B9B5B52706D36D035DF /* MASShortcut.debug.xcconfig */; @@ -5446,11 +5443,12 @@ }; name = Release; }; - 3F61D7A7A72FB23E3B0CDC59F02C42BE /* Release */ = { + 3F7EC0EEDA0FA79BAEEFD18E6B60EC59 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 96A3BD686E9C3B833CB822B035E8C7B1 /* nanopb.release.xcconfig */; + baseConfigurationReference = 42706C333A9D5B9B5B52706D36D035DF /* MASShortcut.debug.xcconfig */; buildSettings = { ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -5460,8 +5458,8 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/nanopb/nanopb-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/nanopb/nanopb-Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/MASShortcut/MASShortcut-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/MASShortcut/MASShortcut-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -5469,9 +5467,9 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 11.0; - MODULEMAP_FILE = "Target Support Files/nanopb/nanopb.modulemap"; - PRODUCT_MODULE_NAME = nanopb; - PRODUCT_NAME = nanopb; + MODULEMAP_FILE = "Target Support Files/MASShortcut/MASShortcut.modulemap"; + PRODUCT_MODULE_NAME = MASShortcut; + PRODUCT_NAME = MASShortcut; SDKROOT = macosx; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; @@ -5479,14 +5477,13 @@ VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Release; + name = Debug; }; - 3F7EC0EEDA0FA79BAEEFD18E6B60EC59 /* Debug */ = { + 42A2ECE63FF10847F7F58EC06AAFB1EE /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 42706C333A9D5B9B5B52706D36D035DF /* MASShortcut.debug.xcconfig */; + baseConfigurationReference = 5D13CE08C2C2E5762F5CA6E633018A0D /* nanopb.debug.xcconfig */; buildSettings = { ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_ENABLE_OBJC_WEAK = NO; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; @@ -5496,8 +5493,8 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/MASShortcut/MASShortcut-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/MASShortcut/MASShortcut-Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/nanopb/nanopb-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/nanopb/nanopb-Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -5505,9 +5502,9 @@ "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 11.0; - MODULEMAP_FILE = "Target Support Files/MASShortcut/MASShortcut.modulemap"; - PRODUCT_MODULE_NAME = MASShortcut; - PRODUCT_NAME = MASShortcut; + MODULEMAP_FILE = "Target Support Files/nanopb/nanopb.modulemap"; + PRODUCT_MODULE_NAME = nanopb; + PRODUCT_NAME = nanopb; SDKROOT = macosx; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; @@ -5586,6 +5583,41 @@ }; name = Debug; }; + 4F9F94016BE16BE392D53285E22F12BF /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 96A3BD686E9C3B833CB822B035E8C7B1 /* nanopb.release.xcconfig */; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/nanopb/nanopb-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/nanopb/nanopb-Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 11.0; + MODULEMAP_FILE = "Target Support Files/nanopb/nanopb.modulemap"; + PRODUCT_MODULE_NAME = nanopb; + PRODUCT_NAME = nanopb; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; 5514564CAA23842906E959FB0AFF2AA2 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 9B03860033D4E77E2A17C8CEDAA65BA7 /* Pods-EasydictTests.release.xcconfig */; @@ -5692,23 +5724,6 @@ }; name = Release; }; - 64C065F5D8E00A7569B9220163F6A238 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 57D48B562A16327B447692577E7F875B /* Sparkle.release.xcconfig */; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - COMBINE_HIDPI_IMAGES = YES; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 11.0; - SDKROOT = macosx; - }; - name = Release; - }; 67E8C2E2367A74CD700607B537760F66 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 770F085549DE8FC555C08C8C6B2701E2 /* PromisesObjC.release.xcconfig */; @@ -6263,23 +6278,6 @@ }; name = Release; }; - 95AC6B34604C895BE85469E05EA5A6C3 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 35A368BC505EC6C1A5632EC7438C4B58 /* Sparkle.debug.xcconfig */; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - COMBINE_HIDPI_IMAGES = YES; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 11.0; - SDKROOT = macosx; - }; - name = Debug; - }; 9D56C7C807BEF554AE693FC1C147A3D6 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = F29A63BF6384034998E80500115BEAC1 /* JLRoutes.debug.xcconfig */; @@ -6653,38 +6651,20 @@ }; name = Debug; }; - EB459C6BF6BDB8309D850B80D588CE42 /* Debug */ = { + FC4C46FBE45535F945D697E1CA2DAB67 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 5D13CE08C2C2E5762F5CA6E633018A0D /* nanopb.debug.xcconfig */; + baseConfigurationReference = BA2E2C2C382C96A6109B7CC5071D7A46 /* Sparkle.debug.xcconfig */; buildSettings = { ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_PREFIX_HEADER = "Target Support Files/nanopb/nanopb-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/nanopb/nanopb-Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", - "@loader_path/Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 11.0; - MODULEMAP_FILE = "Target Support Files/nanopb/nanopb.modulemap"; - PRODUCT_MODULE_NAME = nanopb; - PRODUCT_NAME = nanopb; SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; }; name = Debug; }; @@ -6789,20 +6769,20 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 2D268A7665B36CDB9436B0809E0E3055 /* Build configuration list for PBXNativeTarget "MJExtension" */ = { + 2C8D06A2289713323892B3638F08AC0B /* Build configuration list for PBXAggregateTarget "Sparkle" */ = { isa = XCConfigurationList; buildConfigurations = ( - 62F6FD063953FA192F4B3A673FE97AFC /* Debug */, - 80FE3E30DE35C00EEF289734BD6835A1 /* Release */, + FC4C46FBE45535F945D697E1CA2DAB67 /* Debug */, + 1F96F4C0C4BB0F23A0A2EC0AD68FF010 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 31C3FA8CADE61CE3FE2492EDBA06C452 /* Build configuration list for PBXAggregateTarget "Sparkle" */ = { + 2D268A7665B36CDB9436B0809E0E3055 /* Build configuration list for PBXNativeTarget "MJExtension" */ = { isa = XCConfigurationList; buildConfigurations = ( - 95AC6B34604C895BE85469E05EA5A6C3 /* Debug */, - 64C065F5D8E00A7569B9220163F6A238 /* Release */, + 62F6FD063953FA192F4B3A673FE97AFC /* Debug */, + 80FE3E30DE35C00EEF289734BD6835A1 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -6888,15 +6868,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 64C0A73B1B1F90374066E2CC62577AF3 /* Build configuration list for PBXNativeTarget "nanopb" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - EB459C6BF6BDB8309D850B80D588CE42 /* Debug */, - 3F61D7A7A72FB23E3B0CDC59F02C42BE /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 793C5A144CA4A6198EA476896CBA91F8 /* Build configuration list for PBXAggregateTarget "GoogleAppMeasurement" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -6969,6 +6940,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + F107942DDEA0E39C480DDD0618D06470 /* Build configuration list for PBXNativeTarget "nanopb" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 42A2ECE63FF10847F7F58EC06AAFB1EE /* Debug */, + 4F9F94016BE16BE392D53285E22F12BF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */; diff --git a/README.md b/README.md index 7e689b807..cdfeabfb3 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ - [目录](#目录) - [安装](#安装) - [1. 手动下载安装](#1-手动下载安装) - - [2. Homebrew 安装(感谢 BingoKingo)](#2-homebrew-安装-感谢-bingokingo) + - [2. Homebrew 安装](#2-homebrew-安装) - [开发者构建](#开发者构建) - [签名问题 ⚠️](#签名问题-️) - [使用](#使用) @@ -79,8 +79,8 @@ - [应用内查询](#应用内查询) - [URL Scheme](#url-scheme) - [配合 PopClip 使用](#配合-popclip-使用) -- [偏好设置](#偏好设置) - - [设置](#设置) +- [设置](#设置) + - [通用](#通用) - [服务](#服务) - [应用内快捷键](#应用内快捷键) - [Tips](#tips) @@ -100,7 +100,9 @@ [下载](https://github.com/tisfeng/Easydict/releases) 最新版本的 Easydict。 -### 2. Homebrew 安装(感谢 [BingoKingo](https://github.com/tisfeng/Easydict/issues/1#issuecomment-1445286763)) +### 2. Homebrew 安装 + +感谢 [BingoKingo](https://github.com/tisfeng/Easydict/issues/1#issuecomment-1445286763) 提供的最初安装版本。 ```bash brew install easydict @@ -114,20 +116,20 @@ brew install easydict

-只需要下载这个 Repo,然后使用 [Xcode](https://developer.apple.com/xcode/) 打开 `Easydict.xcworkspace` 文件(⚠️ 不是 `Easydict.xcodeproj`!),`Cmd + R` 编译运行即可。 - -如果编译出现签名错误,请在 target 的 `Signing & Capabilities` 页面改用你自己的开发者账号。如果你还不是苹果开发者,只要去 https://developer.apple.com/ 免费注册一下就可以。 - -如果不想注册苹果开发者,也可以用自动签名方式运行,参考下面截图,将 `Team` 改为 None,`Signing Certificate` 设置为 Sign to Run Locally,注意两个 target 都要改。 +1. 下载这个 Repo,然后使用 [Xcode](https://developer.apple.com/xcode/) 打开 `Easydict.xcworkspace` 文件(注意不是 `Easydict.xcodeproj`)。 +2. 将 Easydict-debug.xcconfig 文件中的 DEVELOPMENT_TEAM 改为你自己的 Apple Team ID(你可以登录苹果开发者网站找到它),或者将 DEVELOPMENT_TEAM 和 CODE_SIGN_IDENTITY 的值设置为空。(注意,PR 时不要提交 Easydict-debug.xcconfig 文件) +3. 使用 `Cmd + R` 编译运行即可。 -

- -
+``` +DEVELOPMENT_TEAM = 79NQA2XYHM +CODE_SIGN_IDENTITY = Apple Development +CODE_SIGN_STYLE = Automatic +``` 构建环境:Xcode 13+, macOS Big Sur 11.3+。为避免不必要的问题,建议使用最新的 Xcode 和 macOS 版本 https://github.com/tisfeng/Easydict/issues/79 -> ⚠️ 由于最新代码使用了 String Catalog 功能,因此需要 Xcode 15+ 才能编译。 -> +>[!NOTE] +> 由于最新代码使用了 String Catalog 功能,因此需要 Xcode 15+ 才能编译。 > 如果你的 Xcode 版本较低,请使用 [xcode-14](https://github.com/tisfeng/Easydict/tree/xcode-14) 分支,注意这是一个固定版本分支,不受维护。 如果运行遇到下面错误,请尝试更新 CocoaPods,然后 `pod install`。 @@ -244,7 +246,8 @@ Easydict 启动之后,除了应用主界面(默认隐藏),还会有一 目前支持有道词典,🍎 苹果系统词典,🍎 苹果系统翻译,ChatGPT,DeepL,Google,Bing,百度和火山翻译。 -> 注意 ⚠️:Google 翻译中国版已无法使用,只能使用国际版,因此需要走代理才能使用 Google 翻译。 +> [!NOTE] +> Google 翻译中国版已无法使用,只能使用国际版,因此需要走代理才能使用 Google 翻译。
各个服务支持的语言 @@ -307,7 +310,7 @@ Easydict 启动之后,除了应用主界面(默认隐藏),还会有一 ### 🍎 苹果系统词典 -Easydict 自动支持词典 App 中系统自带的词典,如牛津英汉汉英词典(简体中文-英语),现代汉语规范词典(简体中文)等,只需在词典 App 设置页启用相应的词典即可。 +Easydict 自动支持词典 App 中系统自带的词典,如牛津英汉汉英词典(简体中文 - 英语),现代汉语规范词典(简体中文)等,只需在词典 App 设置页启用相应的词典即可。 另外,苹果词典也支持自定义导入词典,因此我们可以通过导入 .dictionary 格式的词典来添加第三方词典,如简明英汉字典,朗文当代高级英语辞典等。 @@ -321,16 +324,18 @@ Easydict 自动支持词典 App 中系统自带的词典,如牛津英汉汉英 ### OpenAI(ChatGPT)翻译 -1.3.0 版本开始支持 OpenAI 翻译,也支持 Azure OpenAI 接口,暂时还没写界面,需要通过命令方式启用。 +1.3.0 版本开始支持 OpenAI 翻译,也支持 Azure OpenAI 接口,暂时还未写界面,需要在 Easydict 的输入框中使用如下命令方式配置。 请先确保你有 APIKey。 - #### 配置 APIKey + ``` easydict://writeKeyValue?EZOpenAIAPIKey=sk-xxx ``` - +
+ +
查看 APIKey (其他 key 类似),如果查询成功,会将结果写到剪贴板。 ``` @@ -388,7 +393,8 @@ DeepL 免费版网页 API 对用户单个 IP 有频率限制,频繁使用会 如果你有 DeepL AuthKey,建议使用个人的 AuthKey,这样可以避免频率限制,用户体验会更好。如果没有,可以使用切换代理来规避 429 报错。 -> Note: 切换代理 IP,这是通用的解决方案,对其他有频率限制的服务同样有效。 +> [!NOTE] +> 切换代理 IP,这是通用的解决方案,对其他有频率限制的服务同样有效。 #### 配置 AuthKey @@ -434,8 +440,8 @@ cookieStore.get("MUID").then(result => console.log(encodeURIComponent("MUID=" + // xxx 是前面获取的 cookie easydict://writeKeyValue?EZBingCookieKey=xxx ``` - -> 注意,Bing TTS 用的也是网页接口,同样容易触发接口限制,且不会报错提示,因此如果将 Bing 设为默认的 TTS,建议设置 cookie。 +> [!NOTE] +> Bing TTS 用的也是网页接口,同样容易触发接口限制,且不会报错提示,因此如果将 Bing 设为默认的 TTS,建议设置 cookie。 ## 智能查询模式 @@ -475,7 +481,8 @@ easydict://writeKeyValue?IntelligentQueryMode-window2=1 ``` window1 代表迷你窗口,window2 代表侧悬浮窗口,后面的 0 表示关闭,1 表示开启。 -> 注意:智能查询模式,只表示是否智能启用该查询服务,用户可随时手动点击服务右侧箭头展开查询。 +> [!NOTE] +> 智能查询模式,只表示是否智能启用该查询服务,用户可随时手动点击服务右侧箭头按钮展开查询。
@@ -493,32 +500,38 @@ window1 代表迷你窗口,window2 代表侧悬浮窗口,后面的 0 表示 ## URL Scheme -Easydict 支持 URL scheme 快速查询:`easydict://xxx`,如 easydict://good。 +Easydict 支持 URL scheme 快速查询:`easydict://query?text=xxx`,如 easydict://query?text=good。 -如果查询内容 xxx 包含特殊字符,需进行 URL encode,如 easydict://good%2Fgirl +如果查询内容 xxx 包含特殊字符,需进行 URL encode,如 easydict://query?text=good%20girl -## 配合 PopClip 使用 - -你需要先安装 [PopClip](https://pilotmoon.com/popclip/),然后为 `Easydict`设置一个快捷键,默认是 `Opt + D`,那么你就可以通过 `PopClip` 快速打开 `Easydict` 啦! +> [!WARNING] +> 旧版本的 easydict://xxx 在某些场景下可能会出现问题,因此建议使用完整的 URL Scheme easydict://query?text=xxx -使用方法:选中以下代码块,`PopClip` 会显示 "安装 Easydict",点击它即可。 +## 配合 PopClip 使用 -> 注意 ⚠️: 如果你修改了默认的快捷键,你需要跟着修改下面脚本中的快捷键 `key combo`。 +你需要先安装 [PopClip](https://pilotmoon.com/popclip/),然后选中以下代码块,`PopClip` 会显示 "安装扩展 Easydict",点击它即可。(By **[liziqiang](https://github.com/liziqiang)**) -``` - # popclip - name: Easydict - icon: square E - key combo: option D +```shell +# popclip +name: Easydict +icon: iconify:ri:translate +interpreter: zsh +shell script: | + result=$(ps aux | grep Easydict.app | wc -l) + if [[ $result -lt 2 ]];then + open /Applications/Easydict.app + sleep 1 + fi + open "easydict://query?text=$POPCLIP_TEXT" ``` -> 参考:https://github.com/pilotmoon/PopClip-Extensions#key-combo-string-format +> 参考:https://www.popclip.app/dev/shell-script-actions -## 偏好设置 +## 设置 -设置页提供了一些偏好设置修改,如开启查询后自动播放单词发音,修改翻译快捷键,开启、关闭服务,或调整服务顺序等。 +设置页提供了一些设置修改,如开启查询后自动播放单词发音,修改翻译快捷键,开启、关闭服务,或调整服务顺序等。 -### 设置 +### 通用 ![dYtfPh-1684758870](https://raw.githubusercontent.com/tisfeng/ImageBed/main/uPic/dYtfPh-1684758870.png) @@ -596,13 +609,15 @@ Easydict 有一些应用内快捷键,方便你在使用过程中更加高效 如果您对本项目感兴趣,我们非常欢迎参与到项目的贡献中,我们会尽可能地提供帮助。 -目前项目主要有两个分支,dev 和 master,dev 分支代码通常是最新的,可能包含一些正在开发中的功能。master 分支代码是稳定的,会定期合并 dev 分支代码。 +目前项目主要有 dev 和 main 两个分支,dev 分支代码通常是最新的,可能包含一些正在开发中的功能。main 分支代码是稳定的,会定期合并 dev 分支的代码。 + +另外,我们计划将项目从 objc 向 Swift 迁移,未来逐步使用 Swift 来写新功能模块,参见 https://github.com/tisfeng/Easydict/issues/194 如果您认为项目有需要改进的地方,或者有新的功能想法,欢迎提交 PR: 如果 PR 是对已存在的 issue 进行 bug 修复或者功能实现,请提交到 dev 分支。 -如果 PR 是关于某个新功能或者涉及 UI 变动,建议先开个 issue 讨论一下,避免功能重复或者冲突。 +如果 PR 是关于某个新功能或者涉及 UI 等较大的变动,建议先开个 issue 讨论一下,避免功能重复或者冲突。 ## 致谢 @@ -628,7 +643,11 @@ Easydict 作为一个免费开源的非盈利项目,目前主要是作者个 ### 赞助列表 -如果不希望用户名显示在列表中,请选择匿名方式。 +如果不希望用户名显示在列表中,请选择匿名方式。感谢大家的支持! + +
赞助列表 + +

| **日期** | **用户** | **金额** | **留言** | | :--------: | :---------------: | :------: | :-------------------------------------------------------------------------------------------------------------------------: | @@ -656,4 +675,10 @@ Easydict 作为一个免费开源的非盈利项目,目前主要是作者个 | 2023-09-24 | Austen | 10 | 支持开源作者 | | 2023-10-19 | DANIELHU | 7.3 | 感谢开源,希望能加入生词本功能。(后面会加,请等待 [33](https://github.com/tisfeng/Easydict/issues/33)) | | 2023-10-25 | tzcsky | 10 | 非常好的软件 | -| 2023-10-26 | | 10 | 开源万岁🎉尽点绵薄之力,感谢! | \ No newline at end of file +| 2023-10-26 | | 10 | 开源万岁🎉尽点绵薄之力,感谢! | +| 2023-11-06 | 周樹人不能沒有魯迅 | 10.66 | 有点穷,绵薄之力 | +| 2023-11-07 | ㅤ HDmoli | 5 | zhihui.xiong | + +

+ +
\ No newline at end of file diff --git a/README_EN.md b/README_EN.md index bacf9d19d..7deaabc63 100644 --- a/README_EN.md +++ b/README_EN.md @@ -55,7 +55,7 @@ - [Table of contents](#table-of-contents) - [Installation](#installation) - [1. Manual Installation](#1-manual-installation) - - [2. Homebrew (Thanks BingoKingo)](#2-homebrew-thanks-bingokingo) + - [2. Homebrew](#2-homebrew) - [Developer Build](#developer-build) - [Signature Problem ⚠️](#signature-problem-️) - [Usage](#usage) @@ -78,8 +78,8 @@ - [Query in App](#query-in-app) - [URL Scheme](#url-scheme) - [Use with PopClip](#use-with-popclip) -- [Preferences](#preferences) - - [Settings](#settings) +- [Settings](#settings) + - [General](#general) - [Services](#services) - [In-App Shortcuts](#in-app-shortcuts) - [Tips](#tips) @@ -99,7 +99,9 @@ You can install it using one of the following two methods. Support macOS 11.0+ [Download](https://github.com/tisfeng/Easydict/releases) the latest release of the app. -### 2. Homebrew (Thanks [BingoKingo](https://github.com/tisfeng/Easydict/issues/1#issuecomment-1445286763)) +### 2. Homebrew + +Thanks to [BingoKingo](https://github.com/tisfeng/Easydict/issues/1#issuecomment-1445286763) for the initial installation version. ```bash brew install easydict @@ -113,18 +115,22 @@ If you are a developer, or you are interested in this project, you can also try

-Just download this Repo, then use [Xcode](https://developer.apple.com/xcode/) to open the `Easydict.xcworkspace` file(⚠️ Not `Easydict.xcodeproj`!), `Cmd + R` to compile and run. - -If a signature error occurs during compilation, please use your own developer account on the `Signing & Capabilities` page of the target. If you are not an Apple developer yet, just go to https://developer.apple.com/ and register for free. +1. Download this Repo, and then open the `Easydict.xcworkspace` file with [Xcode](https://developer.apple.com/xcode/) (note that it is not `Easydict.xcodeproj`). +2. Change the DEVELOPMENT_TEAM in the Easydict-debug.xcconfig file to your own Apple Team ID (you can find it by logging into the Apple Developer website), or set the values of DEVELOPMENT_TEAM and CODE_SIGN_IDENTITY to empty. +3. Use `Cmd + R` to compile and run. -If you don't want to register as an Apple developer, you can also run with automatic signature, refer to the screenshot below, change `Team` to None and `Signing Certificate` to Sign to Run Locally, note that both targets should be changed. - -

- -
+``` +DEVELOPMENT_TEAM = 79NQA2XYHM +CODE_SIGN_IDENTITY = Apple Development +CODE_SIGN_STYLE = Automatic +``` Build environment: Xcode 13+, macOS Big Sur 11.3+. To avoid unnecessary problems, it is recommended to use the latest Xcode and macOS version https://github.com/tisfeng/Easydict/issues/79 +> [!NOTE] +> Since the latest code uses the String Catalog feature, Xcode 15+ is required to compile. +> If your Xcode version is lower, please use the [xcode-14](https://github.com/tisfeng/Easydict/tree/xcode-14) branch, note that this is a fixed version branch, not maintained. + If the run encounters the following error, try updating CocoaPods and then `pod install`. > [DT_TOOLCHAIN_DIR cannot be used to evaluate LD_RUNPATH_SEARCH_PATHS, use TOOLCHAIN_DIR instead](https://github.com/CocoaPods/CocoaPods/issues/12012) @@ -238,7 +244,8 @@ It's worth noting that, apart from the system TTS, all other TTS services are un Currently supports YouDao Dictionary, 🍎 Apple System Dictionary, 🍎 Apple System Translator, ChatGPT, DeepL, Google, Bing, Baidu and Volcano Translator. -> Note ⚠️: Since the Chinese version of Google Translate is currently unavailable, you can only use the international version, so you need to use a proxy to use Google Translate. +> [!NOTE] +> Since the Chinese version of Google Translate is currently unavailable, you can only use the international version, so you need to use a proxy to use Google Translate.
Supported languages: @@ -315,16 +322,19 @@ For detailed information, please see [How to use macOS system dictionary in Easy ### OpenAI (ChatGPT) Translation -Starting with version 1.3.0, Easydict supports OpenAI translation. Additionally, it is now compatible with Azure OpenAI. Please note that the interface for Azure OpenAI is not yet built and requires enabling via commands. +Version 1.3.0 starts to support OpenAI translation, also supports Azure OpenAI interface, the interface has not been written yet, you need to configure it in the input box of Easydict using the following command method. Please make sure you have an APIKey. - #### Configure APIKey + ``` easydict://writeKeyValue?EZOpenAIAPIKey=sk-xxx ``` - + +
+ +
Lookup for APIKey (similar to other keys), if the query succeeds, the result will be written to the clipboard. ``` @@ -382,7 +392,8 @@ DeepL free version web API has a frequency limit for single IP, frequent use wil If you have DeepL AuthKey, it is recommended to use personal AuthKey, so as to avoid frequency limits and improve user experience. If not, you can use the way of switching proxy IP to avoid 429 error. -> Note: Using a new proxy IP is a generic solution that works for other frequency-limited services. +> [!NOTE] +> Using a new proxy IP is a generic solution that works for other frequency-limited services. #### Configure AuthKey @@ -428,8 +439,8 @@ Finally, use the command to write the cookie in Easydict // xxx is the obtained cookie easydict://writeKeyValue?EZBingCookieKey=xxx ``` - -> Note that Bing TTS also uses a web interface, which is also easy to trigger interface restrictions and does not report errors, so if you set Bing to the default TTS, it is recommended to set cookies. +> [!NOTE] +> Bing TTS also uses a web API, which is also easy to trigger interface restrictions and does not report errors, so if you set Bing to the default TTS, it is recommended to set cookies. ## Smart query mode @@ -469,7 +480,8 @@ easydict://writeKeyValue?IntelligentQueryMode-window2=1 ``` window1 represents the mini window, while window2 represents hover window, 0 represents disabled, while 1 represents enabled. -> Attention: Smart query mode only indicates whether this query service is enabled or not, and the user can manually click on the arrow to the right in the service view to expand the query at any time. +> [!NOTE] +> Smart query mode only indicates whether this query service is enabled or not, and the user can manually click on the arrow to the right in the service view to expand the query at any time.
@@ -484,35 +496,40 @@ Easydict in-app lookup is supported. In the input box or translation result, if - ## URL Scheme -Easydict supports fast lookup for URL scheme: `easydict://xxx`, such as easydict://good. - -If the query content xxx contains special characters, URL encoding is needed, such as easydict://good%2Fgirl +Easydict supports fast lookup for URL scheme: `easydict://query?text=xxx`, such as easydict://query?text=good. -## Use with PopClip +If the query content xxx contains special characters, URL encoding is needed, such as easydict://query?text=good%20girl -You need to install [PopClip](https://pilotmoon.com/popclip/) first, then set a shortcut key for `Easydict`, default is `Opt + D`, then you can open `Easydict` quickly with `PopClip`! +> [!WARNING] +> The old version of easydict://xxx may cause problems in some scenarios, so it is recommended to use the complete URL Scheme easydict://query?text=xxx -Usage: Select the following code block, `PopClip` will show "Install Easydict", just click it. +## Use with PopClip -> Note ⚠️: If you have modified the default shortcut key, you need to modify the shortcut `key combo` in the script below accordingly. +You need to install [PopClip](https://pilotmoon.com/popclip/) first, then select the following code block, `PopClip` will show "Install Extension Easydict", just click it. (By [liziqiang](https://github.com/liziqiang)) -``` - # popclip - name: Easydict - icon: square E - key combo: option D +```shell +# popclip +name: Easydict +icon: iconify:ri:translate +interpreter: zsh +shell script: | + result=$(ps aux | grep Easydict.app | wc -l) + if [[ $result -lt 2 ]];then + open /Applications/Easydict.app + sleep 1 + fi + open "easydict://query?text=$POPCLIP_TEXT" ``` -> Ref: https://github.com/pilotmoon/PopClip-Extensions#key-combo-string-format +> Ref: https://www.popclip.app/dev/shell-script-actions -## Preferences +## Settings The settings page provides some preference setting modifications, such as automatically playing word pronunciation after turning on a query, modifying translation shortcut keys, turning on and off services, or adjusting the order of services, etc. -### Settings +### General Prefences @@ -591,13 +608,15 @@ Open source makes the world better. If you are interested in this project, we welcome you to contribute to the project, and we will provide help as much as possible. -Currently, the project has two main branches, dev and master. The dev branch code is usually the latest, and may contain some features that are under development. The master branch code is stable and will be merged with the dev branch code regularly. +Currently, the project has two main branches, dev and main. The dev branch code is usually the latest, and may contain some features that are under development. The main branch code is stable and will be merged with the dev branch code regularly. + +In addition, we plan to migrate the project from objc to Swift, and gradually use Swift to write new feature modules in the future, see https://github.com/tisfeng/Easydict/issues/194 If you think there is room for improvement in the project, or if you have new ideas for features, please submit a PR: If the PR is a bug fix or feature implementation for an existing issue, please submit it to the dev branch. -If the PR is about a new feature or involves UI changes, it is recommended to open an issue first to discuss it, to avoid duplicate or conflicting features. +If the PR is about a new feature or involves major changes to the UI, it is recommended to open an issue for discussion first to avoid duplicate or conflicting features. ## Acknowledgements @@ -623,7 +642,11 @@ If sponsorship is enough to cover Apple's $99 annual fee, I will sign up for a d ### Sponsor List -If you don't want your username to be displayed in the list, please choose anonymous. +If you don't want your username to be displayed in the list, please choose anonymous. Thank you for your support. + +
Sponsor List + +

| **Date** | **User** | **Amount sponsored** | **Message** | | :--------: | :---------------: | :------: | :-------------------------------------------------------------------------------------------------------------------------: | @@ -635,7 +658,7 @@ If you don't want your username to be displayed in the list, please choose anony | 2023-06-01 | 梦遇 | 10 | 感谢 | | 2023-06-05 | 挨揍的免子 | 1 | 谢谢 🙏 | | 2023-06-17 | 妙才 | 5 | ❤️ | -| 2023-06-19 | 1 | 20 | 加油,有没有可能调用 chatgpt 来翻译呀?(参见[#28](https://github.com/tisfeng/Easydict/issues/28#issuecomment-1527827829)) | +| 2023-06-19 | 1 | 20 | 加油,有没有可能调用 chatgpt 来翻译呀?(参见 [#28](https://github.com/tisfeng/Easydict/issues/28#issuecomment-1527827829)) | | 2023-06-19 | 许冠英 | 6.6 | 感谢开发这么好用的软件,很喜欢。 | | 2023-06-20 | lidashuang | 10 | 感谢 | | 2023-07-03 | 小阳 | 2 | | @@ -651,4 +674,10 @@ If you don't want your username to be displayed in the list, please choose anony | 2023-09-24 | Austen | 10 | 支持开源作者 | | 2023-10-19 | DANIELHU | 7.3 | 感谢开源,希望能加入生词本功能。(后面会加,请等待 [33](https://github.com/tisfeng/Easydict/issues/33)) | | 2023-10-25 | tzcsky | 10 | 非常好的软件 | -| 2023-10-26 | | 10 | 开源万岁🎉尽点绵薄之力,感谢! | \ No newline at end of file +| 2023-10-26 | | 10 | 开源万岁🎉尽点绵薄之力,感谢! | +| 2023-11-06 | 周樹人不能沒有魯迅 | 10.66 | 有点穷,绵薄之力 | +| 2023-11-07 | ㅤ HDmoli | 5 | zhihui.xiong | + +

+ +
From 33b2dc6def7a1fbbdc180ddf0cc4d51860dfcfdb Mon Sep 17 00:00:00 2001 From: niutrans Date: Tue, 14 Nov 2023 17:04:39 +0800 Subject: [PATCH 02/15] NiuTrans Support --- .DS_Store | Bin 0 -> 8196 bytes Easydict-debug.xcconfig | 3 + Easydict.xcconfig | 3 + Easydict/.DS_Store | Bin 0 -> 6148 bytes Easydict/App/.DS_Store | Bin 0 -> 10244 bytes Easydict/App/Assets.xcassets/.DS_Store | Bin 0 -> 10244 bytes .../App/Assets.xcassets/menu-icon/.DS_Store | Bin 0 -> 6148 bytes .../Assets.xcassets/service-icon/.DS_Store | Bin 0 -> 8196 bytes .../NiuTrans.imageset/Contents.json | 21 ++ ...7\347\211\233\347\277\273\350\257\221.png" | Bin 0 -> 140926 bytes .../App/Assets.xcassets/setting/.DS_Store | Bin 0 -> 8196 bytes .../Contents.json | 21 ++ .../toolbar_setting.png | Bin 0 -> 1081 bytes Easydict/App/Easydict-debug.entitlements | 12 + Easydict/App/Icons/.DS_Store | Bin 0 -> 8196 bytes Easydict/Feature/.DS_Store | Bin 0 -> 8196 bytes Easydict/Feature/Service/.DS_Store | Bin 0 -> 8196 bytes Easydict/Feature/Service/DeepL/.DS_Store | Bin 0 -> 6148 bytes Easydict/Feature/Service/Niutrans/.DS_Store | Bin 0 -> 6148 bytes .../Service/Niutrans/EZNiuTransTranslate.h | 17 ++ .../Service/Niutrans/EZNiuTransTranslate.m | 247 ++++++++++++++++++ .../Niutrans/EZNiuTransTranslateResponse.h | 44 ++++ .../Niutrans/EZNiuTransTranslateResponse.m | 52 ++++ ...ZQueryResult+EZNiuTransTranslateResponse.h | 20 ++ ...ZQueryResult+EZNiuTransTranslateResponse.m | 26 ++ Easydict/Feature/Utility/.DS_Store | Bin 0 -> 6148 bytes Pods/.DS_Store | Bin 0 -> 8196 bytes Pods/AFNetworking/.DS_Store | Bin 0 -> 6148 bytes 28 files changed, 466 insertions(+) create mode 100644 .DS_Store create mode 100644 Easydict-debug.xcconfig create mode 100644 Easydict.xcconfig create mode 100644 Easydict/.DS_Store create mode 100644 Easydict/App/.DS_Store create mode 100644 Easydict/App/Assets.xcassets/.DS_Store create mode 100644 Easydict/App/Assets.xcassets/menu-icon/.DS_Store create mode 100644 Easydict/App/Assets.xcassets/service-icon/.DS_Store create mode 100644 Easydict/App/Assets.xcassets/service-icon/NiuTrans.imageset/Contents.json create mode 100644 "Easydict/App/Assets.xcassets/service-icon/NiuTrans.imageset/\345\260\217\347\211\233\347\277\273\350\257\221.png" create mode 100644 Easydict/App/Assets.xcassets/setting/.DS_Store create mode 100644 Easydict/App/Assets.xcassets/setting/toolbar_setting_general.imageset/Contents.json create mode 100644 Easydict/App/Assets.xcassets/setting/toolbar_setting_general.imageset/toolbar_setting.png create mode 100644 Easydict/App/Easydict-debug.entitlements create mode 100644 Easydict/App/Icons/.DS_Store create mode 100644 Easydict/Feature/.DS_Store create mode 100644 Easydict/Feature/Service/.DS_Store create mode 100644 Easydict/Feature/Service/DeepL/.DS_Store create mode 100644 Easydict/Feature/Service/Niutrans/.DS_Store create mode 100644 Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.h create mode 100644 Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m create mode 100644 Easydict/Feature/Service/Niutrans/EZNiuTransTranslateResponse.h create mode 100644 Easydict/Feature/Service/Niutrans/EZNiuTransTranslateResponse.m create mode 100644 Easydict/Feature/Service/Niutrans/EZQueryResult+EZNiuTransTranslateResponse.h create mode 100644 Easydict/Feature/Service/Niutrans/EZQueryResult+EZNiuTransTranslateResponse.m create mode 100644 Easydict/Feature/Utility/.DS_Store create mode 100644 Pods/.DS_Store create mode 100644 Pods/AFNetworking/.DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..7c9a3bfb8c041f0253859d2dd7ea1c9e7b08eb1d GIT binary patch literal 8196 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 RzR+0L2a0D6KCdkP{{t*$&r<*Z literal 0 HcmV?d00001 diff --git a/Easydict/App/Assets.xcassets/menu-icon/.DS_Store b/Easydict/App/Assets.xcassets/menu-icon/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..2db5737c4703590f27c659bf6c3e1316c8c0316c GIT binary patch literal 6148 zcmeHKL2J}N6n@jLZq`!RLxmy;0k37o6Jmxh}2-5ZWDEh$b&Mr?xFaFa69XQtXNMQ zs3b>5CDl|>k3KH+b`HmYW8i;dfY^my-NmA$py?Bdw4(FPCQ*0eK$mr#m)S@H@-#!2x5s&z>d8Ql%e0c% z&@^}*uM>4Qr_=4H{VjiYXK%LUPxp3UKiPdYn{~YVj~?&8j6M~orT!w!kiw2AvTpGL zzQXup-adz;ve4xaF`VzgHGD^ug5?CWFvQ;bTkh!_@?4(7rE=bqd06V*ugnSPyrE*h zP;c#qj^7R2G2j^ZdkpaY;6oV$i;Y3qI#9?J0N8?C1UCODaExy;u-F(x3q+Yvpb1s> zilIz6{J!lMSZoZMa8ma2q3n~Dy`d<1I`aF{om61Zm5u?&z&r!1rrPE6|Hbw9|M?(S za|}2JZWRNnbr>EF@JjY;R?QEr(2qJN-riffnE6=$MJU@e?E3{Tp|+9q`OJ9Mno1e>*^}RjKudj zpGpg9%?)S)JdsZ|3aCde?VoCGDhvaL0mFb{z%XDKxCjj3oz2NQn%thL%YAXEqdy@YC&P(~b}Fm|dNsUB;sps=Z<2a!TW8e#|y$9^|!XgGkpAuN1^MBOxd3w$b)Wv@&vV0>`@q^MWL{I?AA z6?%*wBt|>WyfM#NbeVQAR{?n#_sN;f%sEm#XR%d0t>!sVPhW&*wzK%F^c46G{6i|1 z-h;Cu8_apu#ua)78ws^x#Rcok`Q+qj<|vqZQO@u;hXrpm?5Do}!|R8^Fy7esDHax& zE?r)>maSFmt@A;SoY;+%VbdMF=Bu`pp*JbJ-frNJ_Nv#mWfZ$Xs5?|xN8hkktd+g$+Tr2my^VFdUaudm+lLSCpnSJ}|LADNx_;~S!xwv>!d@i5 zfEOf@z80yZua6~jKgUQvJA){c5&I`ws?c-zBzyA~{A3Phr{<;r{g1F(Fv=XGCAGi0 zbL@!NVW<4GN)AvxtW=4WUW2EfT+P~{vC?z+wwlR~lEo_xyJ`-A!f5>hf!(h{Q}0@6c+QqnMhq=eEUjRHeTC?Sp@IdljD(jq0&AtBu@ z-5mq(9(yNh$+4{T>mc^RyNF1ls#1+JyEiZm8hQRMYA)2mom7vB{hN^5%}dch9}pa7OWEn2C_;q`SA!|V=?_P=DRyez=v{VcZ?Ytp5J6^3!8H^Lk?dkPSU77 zr;~XQcWn7U)vhigoG&zqYz&u9^coRvNy0DcqTwrnZlx1>o`o($8$QXk*@fTpP`M{b z`7s-dr^lr)lF}EC#k)mZZA6R);Qpr6LI3}+|1Wu<8TH|$gNLYrN14!TQ4&4go=gX` z*Q2n`8ZaRal4t)jbqE#Ogg?4GH76{!Z#0;{O=s4PeD~g%@3Dd3blw%ec#TM{dQ9=i za%fFtBB^9CCoLzZE}au4X`XW7A)l{asO-T_wr-S>@88iH*?V#8Wn&Lt(?DOpg%(9roW}btX(MJ`HeaiRPZ;jzx*x56@ z7;Kkm(Wx|CxsyCJ=53a4xUmt>AU3y`{Rs&%B5Wtgzb-SJ0(lYImElRCEvfGA^xR`+ zt9O^Qb>YpMg6)yxN%>5b&)O3GL*m|rUl{2|FV=z%Hz)6Y!t5?9X@)=u*w(T#KFYHn zdV5vm2A#)a*TIVKudNIQhD5htixAKm?T^#opds&c6WFF%A@ME&`WEz8o!0v91lT1x+VKywTpxAUGebq*e-07ME8Sh=9D=OdEQW!om#s|MK!tdu+msg^- zQEZMVloa809qk>dJU3c!8j5_JbY1l1d$t=93H>bR0_Jd2|1os8Y^y-9i=SN5J0U%UBe!`qywf5+lIo0;4vAp=pOqxc{cLJb*@sh9OMN-ni|GmJpH$^%Sg1LbIt>8M|*2qNk&F}c;6qF zOfl-!?4E~v<-x#_AaOi?{sM-CADw4?cPsloUQ|}+uoIu^C!3z9Q#+n_UPUn1mVuj} zjz5~pd$&i7Oq`$edKFm?BZU^)=%);4V5&}yu(-IUgqYjpd0b^Gw0)u78Alv>xbrX( zgta0q>LnlWmK@z#%YFiTL^5Kbziq~+w@=*riO=TzDBqx1P4z)?YhbR@3$O?N`;U4^ z`k@$C$*jvTAs*7-b;x;SmP3(ilar&?m~9!fc`uq090FaX`)=K$K_4c%B)0++Fs3XH zxeO{Ill9OsZ=4nrPCTK;b@~!$PpOOLshe@i-|fvbQ(iH>wqgjOCs*@d(%SByVkat7 z0KblL>u`d(ZzaSVm!}&pd!%GL?@Yc!tZt7D`0#?Yhw=VRn0UQ-L)~2DDk^knh|!qx zx&hp|uONN7;y7WWXE<~&kjLHHGW>5cUh2oP-k zQ4|I)Pba<1`BCau21heR;SQ+eRm5YT&3*yeAxUzSA+m((%2OH0Raj~u6s2I85PLHO z^(MxVF|PUH+~+zKYMUr(n>V@Ybx(~_43h(O)ly&3uZcQs{<-*3k&bb7@1;Ak!aZj4 z#tOtm__ktD8*$0Tg4I5Kxp2SWI6ovg`E?U;sExPp&pvL>klK~n!>65-keOAKLO-Ry z8)+34fg7ZsAvP;7^1&>7*n9eSO$lFv`@w#MkHgoCrZK^Dm}G1?@c5HJ=r}OQ)jsUq zp|dvO-CKt;SweJ3VYbr6T41b2tt=e#bxQ!HuH^6fRGHu80sGYt!Jl;~Tpomv3P_Lm zx~6hm&nE-6_-FBk-}4XCiS5J}eMWZJ>elP#dmL{Hd3hYF?wbG`$_e$57eS`6l&OOC zlLkpoyAP^8N48S)1_zU=3wTicN}5}bps=k#{4m;LS@ZvX&_^174_YP#@z5xTaR2(C z2IA%oL`y`nxU<*FUJ?dug~eVTQPvVC0i^Pt#vqllbQEMQ;I!)^`i;|JmCk*iV`5I- zwPoFlGW-WoA^ydW>xY&D$-_cVWW0m__*p4lacf4iNSmc0{9u~5dT-MckV%3h$1ANq zFe&qLdY*B%5|!WmEBe)yE*_%3mA?nXbkC?BwfX9BCskILt7aEQI6Kc6&#&}8RQ4ui zZ5Q<8zelfgCla5lzks0q+L!C_CsuEy&hTk9Z*8a3DHdUcFq%3$z0UBmuy682lU^-(fmijTaxh#|h_ZN2W z2i Lp8EXuw~KDV8Nc1@4pOb`UQEvBW8VK!5wBhq!y|}4PH{X;`ShWIqunlZlv+nxJ>40hwZ0} zt(ZO^@3TkyQ<&%@xddV5cDia?be6fi5aO%m=d%tK%ZWNTyd@y9QC@mjBuQA#bmpC^ z8f>I_&|>7K1J$rWw+Wo`4U1qJl|&HEZhl6j3l*=92fV1nCj_hFgRt{UsgM z{v-BxAu7Z??6a%YQ)J>luhGlr7(qS~UlL~&6C#lKZupT#M1~%g)R;o{TUFJ*7Do+}jO1wod}=<6;N}dhQsrHlF=7z0e?5zR)Ej}VUMEElHi|9Cnv?7o z^DdEuVWAC!9Qv1jltX4I9*7Vl?S4UKvLKf8fltzCSa3}rqkd?`HVf|O`K#XlCr%vx zi4#j|($6fJH@JRBVQsUl$iQ<edvuQ^P+0eDX|o5}-({pO;+1u_HbLf$Cfwx~?)*c|Cnvj058hm+7lmo*&T)BManu zMb6mBUhszd0pK}i1?8S@>tq_6)OER&_y3pc2;j^x`0tG>vOpCbks7Dz9eU@52yT-T zPtvp0Tr(iG%`Tm1-%(#R=m7I@+1*5y&qC|I+U)gv7Ta2(0)u+C+}&pH6>YIWU);Pu z=Z~;>@sPg%(^KWfA&gC$!*JZt(7!~6B{|BAH7h^-{&xuDg2LOYSf$}ExfV%%p~#MQ zya?kxb@#*2Zo|FLEe^VuX^n-6^*)_`#3%F$8{^tC>Lfgzmf=ZuuC=n76T^|Vu+^P_AaiOmr1Go1dY-}Oq`qWCLRIUqKE@J>AUvw2>6IioOU(b=4h$sEWd*VrtSv9GA`;@cNYS0y_ zl6ah*o_(=Zw+#nAA0@s#Z}NNMSoQ;I2-BOdu=FXcKCtqN(d4Htk9|aDQ>&1<#qC{R z3RZoc5{gd^X`@)-!(>smHw3qzWH9P?2<5VZ@6ms_|BQ@Y@kiGaRZ3W>x#ZRb_j=We z-$nr>xpK+1Dd>;P8jbP=vq+@Js3&jh2suzx7)Dt4JlX^$(zm2Di?lp-~&p@P?p zlDlg1-P3uKz^>q>-IuM<@H(fLW66o-D{oBj&jm#(XB)|2Pd=)r$v(o_DVr5^#+oy>SNY%L$j8A_lt9mf`OP+fl|DUvaDhudCKTsup^~05#{OVAt z<4m-!I8T2^-9Ff;z~$+_F{1hx24+pmPpS{XRk6%@6mTMz4Jl4rIzMB9f(6l)rP zQmxRo@ZK3$NbwkLe`PD39w!AO8ew{h)TwCND?Nh0 zKbw`_XA5CWdB#5zgS%oOYAk+$5ydRYm3wt!TfrD1l(lsk+2bX1v<_9KR$D#Lp#pTT zQy=mt8@|B~Yy404@+=1}Rg@XO^zf@qDp^U)3jTUM?DTpMJF{KbX)_Olro7T$_4Qv# z&DZZ3gG`O+AaGB@2qN!blhf!vxuY83@SBX7&_X^YnXE(f)dwtIY&=#)3lzoB!o(aCXsGhtM9;e1S)1?x`s1>V=pi2zTsJwsIP)u0G-%gURkL9{2 zY28Ml4k>!eoK~_;O~{g({o?Y>JKw9(PI)dBtL5wO&qdy=5v3KL(f2QYgeF!yun~@+ zUHmu4)$6{65u8N5y1GJ^a0|m;Pkb<%h<^0X`y^Ab-FAM>kzmr1E5|EaSW z$Q_7hk`A#ZMw105IVS5hKJ;p<4uR#6`e9Htrw)VX?*-G*R9AY~K`DDFJ>I7f=Rg2m zC+;V(>RIL>555z9XbP-~(j~E*>K)-d9HT-*&y#?#Iu5`{gp8m>D@GBonO_Or;m6+P zxZ=wnu%M1nWNukdF9EUROE`yMi*9blVsC=Jx1j^ivvxvVP+{(`yHhdr5|RP9D}p4-`s=N(PA z0IjWE#^GcXsm$t9{6)#Wr9`bXoGl>HMKNvd-dQR{0z_hc#a%|y6J~tTbmY@eYvrEE zPEPgU;eIJIe?-?whdSQhEC30384RF|lLd_eUt)sUV5_Tk)4UA00Q16{#b(SiSgdns z6NEkg3^&r$xi9-H;COJz+ zi6>PJaQYI{!rqM%fjRz3E?_vB@tM0^2F2wvL_}YBj}bS>21``Btw+Xm6qg`Rgzp%< z6Yfz=Zgd>KGnM5fwiL{?mY9UEg~8!wsyNYUd9z#G_|F0Wu{wqHNUz6Bd4+ser@$~R z!6+6i;~u6Vz=Q~b$*pSmA7Sf%K98XNr7@t=eV=nvbZ4}13;ByCsO<^{k>-d*dX39= zn$)<(9jpDakay+-b4hGyor|OKP4SZU6zN*RcLZQ@gFU36NE5%2g+Js&bNRAf`|??(RCoPsZz)$-2C^;}ubQE(mOG23`t3IJTA11yYgR2U zIQ#CNAx|G_ke4@HnME5sav1wfLMSn6SY-VZQ;ORi=zc}$Q?^`sTwwmP`X-PbNpY3F zBDi!y;&+4%dldU}=+db5rHBoC5^ohLs9b8U8UqZPt;wX6e@uE)xE-3@7*IF_@gn?5 zvI6Og#VD&p^79FZMmY`^i5Li^gnRa=W$b7R4O6xE5QO;YQU&~-w_$8R2w6U|A|P<@#ESX zE^9j$GqAD4;5$dtr4K*;>cFd*s<0Vw-kdrr+NPqi1=@Q22S&_4jbR^E)CF#E3RA^r z6Lh1j?Ex7Ux*=6y{6KUXiaR~sS?;-0j4Jbb^6s7{zS|W(TEz4ZH=aq`Y zY?@dy9b$8dgC$5)LSPyC4*>(9qre%K1rmR+m1Ww-PP&bbs0#J{ z)wa^;S$GzH_yFa>M`V6k_Jy*#rA>s?E2{PpP&mo378R9j2}m3xJ+@p2-9xxd=k_dO zfA(;Hqyhl=f|_(Y;N)$w^r}CuUCM!u^hpHn_H`iWufbUV1s)ar_G|gq$-hbuxrd~L zr>f>De_LHZmWXWwlwrUm8N_T+(!Q$vyZg~@iJ(NWDx59-Ra&2m423z>m9l}(Y#_3h z37D=vqncUWXHCBS)N-7Pym9DX*u$D-MyR$Br#%`@nY&tMdu5v$6u2Rb&mg$HQMfA# z%TL)%E&46V8%cW!hkwk8;?Lr(utvOM(n*s`N}*3t`7qrA0R;57XYlx*N@=%EtQ8BC z^TVAg>WeHS$C$A69Z}HIgh&z0<}GJWxW}IWk*n?#+swbm;`~IdGGzOeKA?R;HjI#vDU~!qJnV*e?)lF8*Y~? zcX-3|W)}A|;(-dwuC)sMOFo!WP&Y~4CNAwc2wEdD8^F4B{a>uPgt{02bwRK$rw9Gk zBLo$!>J=FF%Zsji-McA?sKS)81Q@8ZmTg9Svui>bjh$P}o#0K1@(2&4=2C^iM5I;q zS(ifJ{aj)-nZ29Le#NbaAf?f?Q@9R80YU(OMVYgBF3%*z5wB79EUbkXqmG!?-<$+q zxeQ7S^!`u}#x%(i$UcUL0w2jo2tB+WO1hMBGR@B~58;x^HXhea^59v{bY9i3jH6>^dJN2uJr_;VGgjujm(2$CgMb@I}Z5SoS6 zFH>YDKbw~ccmV_KU0--~#4M;T*3+F+D78*z<<;25%5dv3+UUx5x}850>;vd7(0^eK z3p-K96bAquje_wk zdObn~V?k-79*#5}2_+ehG!w{-FxLi#Z!4xW@;v{T+#6aOgb49X>Vuep+qSJoCvQ6G zw^(??sRE0!OF@HK-7}BL`ycJ{mhI<&7@Dg3)#ml-FfFju=N*6Zu&JSL&S&z=ed zS-WFcgsU}G(r9-uqTtPiINvv?<9Kk@DGTS8Nz&G4&imYs??a9Wa83~5^s|qLrJ#P~ z!My1JOKHGY)JbHI#ZIC`FpS#6jXP~A_8iNe{O2`m?tbXa5KPBau!kAc?+NM@DFG1` zWFg6^5xuW701INRZ)NPjQgfx6Qqv1*5)xKlZ9Yn#!OP=SuEMaZHFJcw+pj0lPRBml zk%ya_aI>wlxwOSF8n`ACl-M=rB7~nLWqHiS=@}$IhVK(QzNjVCUjujD?5y-Oyjc1S z+y~__US@r2HNNBncce#%Dn&Xkj!m%Cto%}nn+lTzkX)4iIu2AKswc{`3V651ZYp?5 z1w+TNb6u-QUyKzwy}YQKopR?>KD|so>;PCeWtyHr9jziQLl*_rcD@?h-KR7x&&khPZ>YRck9cwoRY&HHc!#2ET4m)7sYd?fEbjoV}j-`^+4#s z&PwuyHrlIHN8{P~kM!B2p+b13)$1;?yVtlA)iXKf<76JXHWJ_jW;ygJ#;6bx{xXbV zvP(n}X{x*3s8v1b>@Otjrz)8BL!>5xz;U-pkB_NOkRdNV> z{F-k(>S>M!v9%x4i04Y)0wd$pNLR%OTV8+=*mcc2U1;5L#7Vnl!Q5CUO_sp2whs-s zO&MrAIDM4q6?`Xp@=LCb3sF8KGlGG);!pxETk^8H%Es`<1m_=0PP;lMS@hj1>M6~+ zi;+J|gtsHJ#9Uh+C-`S1>5ifoOS~Tqu;YiXew+(#g(2cgl?oRS zhE5#jX!6T`iU{54eFD#wNu-WiRMLL-TMr%~yO>G~Yxa#DJ|pm1PC&Vkg(W#@c;@+izatGnX(HEub+zzs-gbFRb#a!l zgB7A$_9D6ZS9O8|pJl8LrXQ_^^<0hab#0Z8O9_XZW?T|k>t^NS2@2lo^`+0yPg;10 zeIeX^#;9g&e(wa;()ZM;9Xr9WaKS3sKdDca6!e{nbj$t^Q6I;aRyz%Q3*A}0 zb%NVunZ4RjRI*~C-D4&32D2l}+Am7I+JBVHR+ddQP`Xo$DW6<53 zk|!+{KGv&O-K!mz4Yr~$^x|L10otexQ>tA4c=b0?S;qUMkBBV9+eZC%0VWY*}H=k&kJ?-c>^AjG{YVj%lz|Y#V zXAi?J3cc}=FY;2Jq&D(r1tq)rSX%|-gYuA<#B7Pm^~xANhU2J;nY|MCk*TV85SMN6 zSx64cGh!Fe0shIZeRb)_+#Q9>w1cjyo24`qUeoefWrFbv_LX#WoJJTQMcezhT%2Nx zl)HqWP>xOHIcRvsd9YcxcfgfU=l&)a_6W@+wnw0$j}FcyQ+wrfq?)tsGRHRIMb5Sz#{K1~{YcpljX)53WyQZ-ET+xno2m*hLi$tych)jz&VpWv=>I_o6&I|8hL-zu21_~B0gSoL zJWYNe{*gGw-{!c63XM(!xQU2VU3=s=IC5)CH=r_mcKY{Nc`8=#^KR$QkM$%lq{%fx zwbD4!ok-IFACmhwZhdSa4@#2vvMpASQqwmr)nQ1VW3|7l=fG3uqKx18sq6`4OqrFZ#NkIiq(ZwZl!{ zVoCCcn?A5u!^^gRJrj|K5;?5)tkX-ddz@B#O=~}zC0Wl9YiZJ>Y^myqCHH2ySIFo* zq=Sm_p9L$*Ug_`pSiMr!$tjc9L+aSqWNA>c(c-2bDIt9lb^4t~*E`0w?)zKPC5ztv z6WIaO`8?ZDE=Q25lhR<7Y>>49>i9rF$bNil+Tp%RX~09TJR|dc`!xPQM)Syvb5)Rm=9{b` zsUZQ%UYTuTd*BC!d*J%`N2D9k(-hhEE3nBEWwVs4;kIumF7b&M@w(8@31p23r#2ifu zPGmZhZ+WQd;PF7cb*?6zn1zglv8;6c8?;(x`1nAao>A9YZS}g zl~dws@40$%sS+dhx^Mg_2RcgVn@RZ6D*dXk^L~Sg*DU0dc*!bXhfWTl87HjGL2CA^ zHo9d{+5#J`DLwfcyX$V&Xl&;1swVfa5&{ z{uKUcr;zSA^4)bNw8K%((yf|@(P`GNL*fZ?5;hCZyjJ=0Ct99V5Qmxsp5r;$Etpya zrjxXtbcJir?K0`7xs{!k2G<=mwjA34h{T>0=M954qa^J6iqb8osx(wfqa41>g=}*t zZ9m*!dcAFi{d8t&clJo=oOsW3V^p^PKD}*OGZKA{W26KQ@Y{2N~b3K|vs z-6GJ5d(o-MLlP-=Sd#O(H_UJr?qHv#AY^7~m!$0T$&2|y;5gt)g=Qs?ryp~v{DU3$ z*_;A&)r-7EYpnkBQ)WW38VcU^VE zd=|EXsi>r2x-V`7IGlLH-&&q46bf%&*?KBCcHqZv#O3&TQ@!KpZN%KU6Xtx33vG`3 zc~$gWXMu=H5?`CRREjUQCdFVjm5E=*<%DrNx!H zw&EIJNPtvEoXVOVWE#NlqUwht-k}8ea&JaC86p$`3VWYAq%%Hb2?i9mWE0llp@A6n z&P<)aHAUJmGD*N?L~bDd21ZnBM9De6%m|iihRav-0TQ!+a<@}Gn9h=2KL{2l@i}p4 zJ43ep){;UB@56zs1jAt}iQ-_Or>U-HDGS`-!a>6uGa%Z0gL`~GW_2k4w4Ul@b#p+D z^nI&ziRwq6mXtgBl6t4_FzRH^#54Gg+S$W_hgzN?qtE0YE%tm4&WW;4C|Bz%T()S` zmJE4L@|a9e4jM$>f>1pn*aqVwJHPS5nV?1gu9&2MkOSO5hNyv}NuY=MQa#c;)qF6+ z#Np!`3V*B6w9sbBP)dZ> zUvVD~lJb7_z5vd-CaKY^lqqOF1u=rJ6uY00qQahI_FX6WENt>d92Q@8A)j(Z5 z7h(HC^x{ku=_4FINfhOAt(Ms9R1&4Q;M(ik|^#@J6%6y-V*feIb_vl@nmr=tp|HS@%%Dl>FFpqo~j>*qDNy=DUTmOJvtz zjO^!ccDi9EeFOw)o6NyL9d)Ua{Igb*TyLzS_s3*^E9?~We)*4)p{f)a`RYEnsdn!% zg<}wmnaCB>MS^vK!Ob9;bwL9dG$!#~x?Co45)x1WUPSUmTgUlPs-)o;Q|ji+>jPp` z&0Ktfpq8eLf0~V$G>r#~cKM2R4OT^JQf|JG3raD(T;4FzBcX93 z9Cc5gQE`XY&pWQVBfOUDtzag)8s%0=_njj{+B42+CBF+9bDi8j58-GkIU*~&;X|r{ z)4FrmhX3lA-W?*cmR;_DT1S&1X*j||gj0mr>&Rb*)BFD>Z_BV`I zAqwqNLyDj4L3-}MO#_C`NHtcBGHqt#Ci=LalkVke;@lrw$%{<8ql8jE^$p|F6;$3< zbgs^@nw#&Cm3!x`T6f_sdDggkxOUQ6OaUqhY8;Fm+#SlDPa9*ki)Yt2J(6?v17Xu+ zDBNMI<`Mdfzyn~cO!tj_m2~unxRaR&8mJ}h%tZ6=1$IM@bP{Fn2!BH#EeSEnqaIq| z7bE(o^vKfr?WvoYZFMDz3e2-yj@r}=Kb+}M2AL`lI>mJIEHgVWo0OmZfTU;FRV#!0 zI23NCW3hImMjRx~kUX=#B9Ab!ppTpKda%zu%4U?Vz;-A7I)%8U@;l8rhNjZ|TL=|o zH2;YXWUlSz>|#lc#O{5pp4YZfbef3)n(dTTvb2G zog7~L?ly8+7)kcAIuwEnfcg3e!AC*X#Hh2DI9)Xu|hw|8mt)ffI% z(3)&?6S{9)^Am5#I#BDfy~!37_`S!kt7ZQ-B`H;K&%&s^xsm%P^kabRIvIAA_82$z z+52->1+qB_^tWUSv@ngq<|v@TsB3P8^$3jW zu==`T{xSM9&>n+Vd3%}dR*vaV-=>$OHhVh+&$9!#?+=2mHZDe(!RNW=C65>L4rGz* zcX|p74Sjw+S{CSsM|jC_Ei?Ociv#G^$+Y+rdGL0b3QzlP%h6eUZ?>S!Loa9rSA|m@ z#f=TVAkzm=U5-Yg>COJMsGYM%MchLWW*~D==v~O^YP6ysLj9Sw?2YIvG zP0)MF{qVDAdhU;9YJDh&GoRV{50+eZ)N#6an&*J>I(l3{d3R{*@p}1AnvG=`vJJuT zav*}zct{!HSWX|mqOJ=^PTR9p^uOR`9KLug={^%}>2q#c+mvYfVS0k5Z?HA{eey;8 zkAPkmRiZlv{fzsrsY7LQ9|t#euZqv-FF>ZwUh(=IIl>`opQ~=m-Iu(rgtqx@Kgv#A zmu0Z2Toz!}=-~gA_d7B9c9bt*&eoo8gVVbhQ49sGhHve?IXce$iTB;zQkZ?@nP`S(3MkfdE+|w zSBLMY?9T$W%`vq&7RF^UVe9(kvzezAn*=K5Y}VeykD9hAJkNb|lqU-aU-z3(1Zl=` zhPGwPX@~M=P1KP*8lBqkw(!qGsPuu0>hWT?0mv%s_2b~=xi8hg+@P}?|g-faFQJa6;j$ehu04qb(?93cd^ z0Lm1)3EU0ysKt$AszZm#of^)RDX{@*`@5n;wIRkIOfYh3?5;^^KF8i2wGGIeN!2w3 zJoZfdaEmtLZA9u-c%SdP1OA@9(+67XOt-cZ@Q0=9L_gxLgS(OtApPa9A=FRln{u&_ z-ZGi_*L48=)v+VFw0$BANcDY=WZM95axv5~1dFA<;P+P%AtuB=yq!Vs>!u z^!I!}tEP~wcs_HsTKid~l(`de{lcoH;hg|c-{cm>i>w72&y!LWPe$)wML-D8&e^gn z@x3c7`C!(bH{NotN3jPog)^w&SPQNs2UN~VoT)~f!{+9}D0=0A3D@%&tU*5hn}*?^ z_;*bcJjiIX$i5h#ckV>_d6SAA6s-^CaRgc00*Ef<7iAoFvvjrjgnDn98auQVz4q6!IVUyGjS z^0b96$~FG9$mW1Mj{ISIVtX34`Sx~cI{XAPO%*QUJdkdXP1)rYWkTOv$_a8rpYRy5 zUL*N!YxvLZrv6!tTheXRM=g>Q3m4bMUN4`wu=hU-X=spp+5&sN+g>gwxOpN~ccb*K<&+0CDpot{RB)tL>{BH#l= zt|<>mQG#x-#HF~!bdvEuw1&FmXJ4dHP7_z85(u95za2BsU39S?`7!BUv-p!USmLmCLsVO!p;XN4O@cLn z&E}AVbBin*r*X6F-4)lD0^-wYh!%+)%1)YUxy?bR^(kjd@87-tP;s471s^78Nmngv z+mn0cia(;lO9+sh^jZ4~j$&07bIXT5XGK%r&Jb{m*cfn0p*%CGLf8k5fOfHR8S*QFJaDRz4!KyZFdqdJl~ndse62D^c%CC&@?HLt+V0 z3eOo4)&}QROuvko16uwD&X)Lb-b5*DI23C_1f3>^OWDVAN|UG+BH4kb6cq< zPx~$nLJ~}QfRRHXZ*g;a7W5g9KvvmIa2D^I^n;hB3wS8QA{(FGhTa_sg7yYhvA1!a zkF4j@;S&t-)JQM5p8R1-tmlF%9NGEvVa1ZZAQX0uQkxjb(JDO4O$Fw-r4z*X!+W#y z%(qQ#Fx(}Zya-mxg%7#{giX$ehTaWZxm1ixjEPw-_hBL_Yj$4mWVAOT3Y-oBY~~wu zuxY7rL!v_lDj!Cj8dB-nhxa%hh<24q?d*?Rs$|eyua8olX}+o@>=DMRnCLxvxVg4Nzg4 zn~dD&;FH%@d62|XV&*Xx%kju}FEmZ_qK-O&jf^%_?u-pTA#;58Tc6;75tTUJ^VE#-Z!9gwl+Wfl?DWnN41l5n=L(alO9u^c55>CsJ3Fb}Tfkurh1 z>G1YyVIg45Cdg{mpDwTMmSnv;ML6%}Ge4y5JhIgUVReeyz5i{M5FSms^OEc!s-a&+ zrjt?osxwCNzwSbO;xO%8yLEF{o*yCG1(g}8_wMF7mn!Gh6$}%vzF+|e6L!Dap^dcqzRaF`q$|mFqe=(GBdG_4G%T?y{2w) zYnM|FN9}euBnz*$nvrLbfh_afhwI_cEx4)N=Mr6)e3(h+`OzkvSgMkhGQvF+#rItM zQN#?A1;~d-J!s|~+NVL*DOJwjOTAupkNKPnd`dn$WAQxlvr%TA;T%`q7~bD1w+)sz z1`ju^zT=?2s=Eo+zG7_>=-*1gDB%goMjn`b9+Y)2^Ekz#Embl|Hp6LHmnhP6qbHNo@B?`6Wp8 zYf0kyrpU}r6yaYR<_C9{lVr_IKREm_jU_86f7O5{S97BdYI_@=$N1eJI-z_6+`}Vj zQ8kAk#J%c`gmP!^_CUni3tFMUG>aQ692IR^nDpVIiWVtRomRwd5XKsbz*J^^@xqhm z3mK zk-J$adL6cICiIL|l1SAfntJ#>-D4i*n_?t1S>CQNdgLcAX|H|+Jsj)nk+o>yx9EU#w8N3Qn!)~)A~Hn>Y$1^3_(gVXtM<|zbwn2H%%~)WfHr;J|kiGWIn@leW%62b8pH7 z5s+&ZYY48#+2JH&Wv-rwTdA_CZGx|v>@snlM~%*Iaa1g8by&I)zkRcPA8r;)Gy`$R zNaP~N0a>A)jD$9pvor&Cfq4s0i>5BT6Ff_^x+O=a=mfP8r1VM73oX>mv{mA?{;DVN z;oizKx}ujyEoP=`uiyc^K40X)T@9DgtK(etY*KqgK1w7>b#3g&wlm7Zx8NZ-N^i1m zab41l14L5hhF{uWr3MNb7*Zl zh`GM;U4x=8nDqIEqgS+nnUk$Z9Y+{=sb?C?Dj0!rD`tAk*uyX0t|}3$qTS+_wS2rF z{tk!xDUU`N-wdM! z4s%qRwGdrJ-jir^Za8uft!d|?sXkFFb>RA>jDGoQozmHsjDSIMaEpRA$h36YTTX0T zk|$3d^`r~=f*sQ`5uQs0;Mb?4TOK#7j&eanSD9PoQxCfZaLlyozDe?Wr5+s{^%*C!IkX&OsbP{T_f|X zLH8Bt@m6#35~a7@0m=6f0F8NgqMbwSbOfh%lr@!@;X+KSL5E80N$&%pikQW#C(2aiiCvyL7oVa&xBjyK)Af&*A3GlGrs}qzvV&&(%i*5ScR-SCVVQvmc zMV`MX=6-zZSF#S9c$NtrWi-uX)8*O%>X9#+@w^1vrK-242ZXBs%sO1?0x`=YFOfkx z{`K)+LM8RiwcDK#;G8Z#SuV9^p-RD7sf-d#0aKnssDwGuO0h#@jYw*YWZihfB6 zyij#b`?JdDoI1=Z8>GH4j9?7XfLJ!0X%kF;lbtudGq~etFO>6vp^uv+bVoaz<8omQ ztSr!p!U&`3MWri!I>1h7qgC-Q-M-(hfh zxJy%d-RomC*t{J0DP}+Ru`HxSquPk}tlh5Qa=(@CtmO*$K@jAH)HMkP5BBXOUT{U$ zI0u+g(@n;J=a&Q`%ZM!;U4#Jz&9xxtcqh42v3Rl9A`Uv>Y{#sb{8hB)N;15jYX{p# z*5QINHv?}<-ttD$)Z13!vpq4QfeC()k z>s2Jjw@h=ZBt79X^CF&u>fHJ`$w8LaI%>Mm4Zr%3FcpTn!L0%BYj1*;uA3EWzG7-@ zKqFxtCx_K&aVlfP&aUKeLq#kf891-T;euzJxuR=~;a`LY^K;V_&07l0JVbcq`H!a; zf+`mSsgH)z`pe|t-!fOj9yfJ5SKt@D)Et=ZWZa~zvCW2un#T6epzS<=t|nREpoC70 zS=iDpYTR?M66iW75c78LkDk^WWQwr zV>to{A@}vc9V0JWFu+HIG&zb$@hUNGViA(q-7J5h`zRMGSUhbO6F|kG*LX%>gW$M?2!0S+sWnQ#qJxU)u69>;#3#b`{w=jgy>H%~m zoygYcW{Yb19Q!DF5&@S@-kQ^X{tJ}T-P;U>PLHom+7%>!%8ubvW|+>iCPLn>t|`N< zF_IVc`2CBu9Vk9(+=&WU_Nxo zuTR0Bb-8qX^V$<|xO**9M&HTG_JQ+V3qo|DF~lX3qIL=;*futQ+=K!LGxrKK&Q z+IS&m^ACep-)7zi380pA9*eO5+HcChDdc8hnD zK1bmd;D3U_M?h6+nV@4VETW9m)Jl$msU;;&-emj(kH@+x6wbal8=58EAvVm4nds}4 zcOTgR`XXVl_Hlp9#%jLOX!Wh(bKr%H~+4Jwk(&dfbA z7tp%j4Cs#w)(Z;e4i8BGxD-!F&8mKF#aq!4X_FegVaazOI$7v6CMKmasW0JEDjyBt z*32pz4QnVR6d7X|`r7Hw{#!zQUGDYZWGEUj2wGjlMo@H?+P@q_bMw5G9M8a?)4C^0E{ z#@&TaZ03dOL5lz?ED!&u#K?7WRY!N>&hKlbY1uw8(m0+e-~SO6$?kx+^HMg7WuZw z`L7s>N=QP9*$g2t;TMAo9w%rrqhoc1&M=p=LUH3y`yXdt*z2RX0@QsL>Oo7a5X%qH zBI>i-mqh7UMg4T!#JF9JcgEvQEINoCfF$8qjtJoORq;H>x{lsE4F=6}bi16H`n0d( z?l(x2qMv)@B#USj*4ESn>JdU`qUp6ouS3*5d%ImSj>Y zCGv+4w@Ri|jnur_(VYePwYeB!x;PnJO#m$Zy;b5KbqU@-lfGL+pD+%2rVH%B_y*$6 z_8lwRv#ik8bP&({e`;w2g;j99*K)u|;Nf1Bfd(L37IXhF{M$ijE0H$)N3#55AL zn$XuM{Bds$lv0c3{pj7N|2V%*uY*DH=|i6gm5{wP_$}u3W9mOmsRQzig|547d$`ak zK7WDPqUL6~2=~{4qz~L7&cSgA(GcqEKfo^!C239d+pN(N|y8JIC(19!&Gfc)L`%n_2PI5;gE^&n+S6~||j+k;cn!X<0YXkzcRxTX*!o$VsuYh^sgYtB$t5jrh~ znd6$i+%3%TqGzofN4*ZW^XHk73nIjY)}%1}_st*!_g5;2c7%;#+tsJrZcvK;`X3K>G^Ip+)A%BA20rgW;VmEff<5AE)5kzf*)%yX z1t6|rhcS_1iz8jKr9@*3{LwfC+!4!@l9ub5nnHJWB;RH2S?Od@kB7_P?!IRbLFPfR&#JE8KaCUAJ{AmOK9WXP}HH$B29@| zzIl4S)p>Sc^^DSy_em}$&%hI~wE2{I8KLLT52@H$OPJ(RT~BCBIeNbJ(IGAuPaLn~ z*?2fGB=VauxkT+7nrFS1#E+**q>EI1(}$Lb`qMk!jPP~Zv4nf?9r~!3uoe6|AlWqG;KM60m)M-U2^zL9j z?%X_3HeC!Ys(vK8G$5o(pvb=5Q>Z$i+0u}f*c|=H){Y8fr{dx^+u6HnimjQc#e56! z_Z-z0onadaV_KMU2K#bdx~7c6O(uY$OikR}5iX<6sqv@F(fjndEyLWT?v`WHahme; zn>5iS_BKT*IP>nWYkVwsVkG}a?t}-Z?Iq!8Qrs4>ofldiHI|zY>wViJ8EwSU>EV9U zO6qA;#SWXGfO`Rde(dCC|HxiG)Z?Xu;Lmk;U5m$$)$3e({psxIS{#t=rW$`A#{_ET zI|_T$m9tWH;dF&7B|gH!FtdhV9-IZ2nb&MbSF)DZ{JJRh$+W(*yHDZ@OAyJWJJuTu z^u~q?HH>gdO8`i(3KJIX(_~5p_-^NiR^lD48=L^wG4LGA1k#SQn~?ZvMC!DPUwpWN zOXsxgs$y2xi|ZdA+*x}l_vR;E&a3{VbFy)1;bYTNZeT;M(JQ`k0cuEhTbr! zjWU@e#za4}wTp*x8Lh_$y6dWWYk&O)EsFQOv)%qks1`G?TGOj|I5$!7Aa%sh4d1=X zK+u^=X~H%c1XfenH2n&!?l`#=ZH~(h)srib1Vo?;-3wsT^M*V3`Z#d5c*om2o}`@# z0t}R_I4iH=3se5#un-}ByK}lai{`}%^#H#7v14I1MCfP+ijk|1?O3=vp7!3Ip@+kRB{*f~{%*q^NxwvIPMx%zudBVW=NwLb0qWV$` z4DcXHxm%Dp1VHcn=lZE5@7Z$6OGrjBMVx$pT0F0`o$$;=A=2x6l$V0AXCGETtx!mq z#h=A_!;7=oJI%Gw;&h|$cEP`>6lr=K)^|O@O?u=juvH=ymKiN(X_wYYFl40S!gAg8 z+V{G(IQW=+>c-HvCvpaJEP7+{o-OC0P>YZ42A)0`Tqtf%UI6a#)=ya%H)PZUVz)=v zUVAyei1#AnS`qWkzda-}>*9KD;lAPb(|)Qp=3Kj;xbCXDl*?S?x{=geEq$`wfy-DeuHRY-)x3RLmkjI8tUl79BNr`l>lR<>GzF~Q4X9nLJAj%Z5FAmoeo*FrYgc)h5ooXRON#7Lp~7=;fO-DMAiAQ1^fV<^i}P-+cy#x|nqA z*D#|N%Ut|mh@H!CW|Zoa;%~mUhQXp^ROg=>`le{qpAQV`m;yCJ!e90LO20`k;E@rR z1YhO{8TK9VafZu^oKTJE(JK7u8vo*;Np<5K{=xdP0pEi<16a6?Z)ztgibNNU$k%qz zYl%6r@t;mKMn*42$3MCGxnvU;e#n8Z5L?Gfq|VT0V+X5*fdBw~ANu?CUW?O+5R~J`cIaPrni0Cv3HJPy{Er z*WKTW;RC0#XwB_?7OSO=o*?7Hcll^uiF9>WTj*=u7@!kfQi~(o^Xxm>aBLn$COlZ{ ze0ysV45yAiR$1PgMq zUDEvCrc{I%w1oS8OKyoak#XO;&O`IaeeU!JPbGG!j~<;V9C90nvOq*l$U9RleE_#; z`68tmRS!B7D=tZm1mbn9PWFQr>Y_hlltl;x)3hsKvI-qbx)AIjqF;JL8yw+@^wp zq$)V~?ksUzjsv*j{7_-SQA>`+9DoA%2j`voRjCF&KWDJMIRMsu(QNYB;us)Sl?>)d!-@mOj_ARb#)4>2GqRiVs*PZ+L7P zhcesZRxN5EpoqS zI0v{ob>%>i2iNWV_|TmjQ}O%o5UDZPB;74FMP>7FCO#{R?(Q7>fmlMz@0s!OmdVy z#=>!Uk)hZUpacaOJUFpFbO!rfmxt{079&Z?nPE0CSl91llxHRB15cI_(ZZ5`uq7_A zxD`h&;K`O#w}nef-6xC$w43+x91O=WqZJKRxlf`{qvN@|#y06W3EG5h(XOh+98nOHh^j)mX=0lr{lVX?klRJucXs2IC`7kh{%{x$Wt|SE0t~gtt@Jw0W60^&`XLK z{jgC41-!csySBsLq1RsPYOBVE*NCui7vTEHYHtO zmwT9$hF^APIHGf9a-m_Z_%#(O=oj{`cki^(R#sL+%W`8tue!iSaM)kk%!#`w>|Hp_ zBILXM;I1YdM_D@8v4{&)#eKs2$6VB6Wa&i7XvW9pew=xcdN^SHvuMgk#-!Ua79vY; zBwbO@`gFxrqAbx|r>OF^X`rY^Xt!ZcC>DW_F)1=mgfcxtb#CFLi^TAjzQDlAbJKQv zdvjB}rs3kD6dFflWLzP-fx2&f$>ynmem$0~CCiF&MZ4R?2=SzQOpM>^+aP!PI$OKa zW2|UUHRXq>x7dZxeXXx3{}S%`%a&fbmswNFOBo&rd_MVmrLcjYP_D|5UpI; zh88b}_o_oK*~SK2*9#gNAB2%nH8Y5h=GA>LJG6Um$%Yf=tgN<2sipj|-SxYrn7B{p zU;`M#q?N?!VZ1rf%+ljM0$_nFY!C9e4$9ZIfP1UZ^l8u#w%|JNW2oyy(SJY{}CcN1WsL`SAyzY%jB798fFdp~Rw zF0E2vwDhx_wmREwOl@ZvG&>2Hix`IEZ>7`-8}C za{6F5%l4|*j6PTTw<8b#_ZpDL0D2iLV27`;)H}}dXD{+AFw45K#S1hHPGTI5I>L?w zh5>wAUihk~kci+Wk4ZPIv*s`=NAx+H`Lw90>WJ@j*I2v|?n<-S&D$8Z{IB2zfyI-K zsa$u>qY%kutM7~?;yVzP1b18Z1e#xh$|tyfet25}n^m~@mjR9(>I9je45jClXhUZu zD`!58neRX7QV9Nr`_$s zuluu$R=9VXw4>=}PQx4K1FDonFq$B74`SWCL&6?Vq{BKLqs$94C< zrO4avZ*Wp}5-Y}-bHxZrtyZXyJm`r-45w9%epx&Gy&Ckpg%P@D*oOv=uZ;VAEplek z=s3eeaE?N$+7XBjBtkgq$wqghz;wrHG_9n6U3vc~@~L4zig1`yx(PSMx{Duffc`<`8(1%53T5 zt(9%Iv)vZ|Kc%yj>>?U&0_!LV%17u_-17vVWt%g` z*f>puhr)bNmy^b&;gJA*0RL(UOqpu}(iDCXaFllAO`OOZPQFA9{L-f)R2@xqnrS%E ztQ&Gl!o8m#);WCqy1t>=!s8`^%f{GvEpwi?Na<0Q&$Es(E--4UCC8RHNKFGcG7LNC z7{!n!-3PHZ2h&!tD$iyfH=`(PEiZ|-Sk;_c=b z!>~dPIzd>pUAoF^tJv^EB4i{2>ggTCu$s#7&XE^eBixT@Oplf>Qo*)1S-lKRtZP9H z?6K-IC7Oj|4kqOB>h0A$_k=kgWP}At9ZSwH)Nvt?hAN7tQ}0aK=B=p%1x5HXT**6& zs9R+?ECcUEV-yE$9wngsf{Kw-%r&F zk`1a8UzS57>-xWi_eL^Gsv=j?QA-P&%F~OxY-gqDrP5i&R9O0V_~_qmb6p6kuxazjpn+YAzn5t^5LSr-f=MPu7TmZ=6RM@H7f%>^Mp|jnEQAm&t!p$7T^&S~?5zz~|!3 zLi;ZQ`G9P1G_MKYiag0e@`}o?<6zJWJxZ_)9cT*?D5Wxb~AF2Pp=nJ?2Ch;k%-`x@%)(K0aVyCn`5{eyZkYYaZO)9p`+jdxG}1R< zskry%9pY`GZ{){OMRrP&PMGK++4%H!BAcbm!j5=W@^0!h@sY`%{161!Y+L`mvydVx zHDU6UVdmYL2koRstX@wAHqsjOIfMJru{+HkIaCNqrxRBJgpP5#JsjYMXMtQr4AHZm z*&;t0z#@AGu86%HXgr_FEm!ypI%5tp;h=Io$_61TMNerRmX^ZD(?j*n5t}Awdb&Iy zKwj_+fAYg~*zWZE8F46jq}M0Y31Q$PxbZmaXVe)NOpl2G+b34s#j^dg)m&v)jkxRF zsYfw``91YI;;Gu(%JeHNVh83JnLR#NcWSpQz4__Xs$pFylT8P@Rq^^ifq4jW6-}+@krHy9t8Ov6vU`I0x2Jk2W*L{lNpyS8GPgM{jWT^4hL1Xq3qUyz@N;>4hDp z=$vshp||Z-UXdr}DylD?{!KJTQ}p-W=%N@YXdLG({2Q-OkF>g;vt7&kHs*B-Fls_;J#Kj9|>d&hy5R$w2wpl+E{)4&HxZ~%&s9ZaN6tqY^ zGYsZDxJ#j>jDOJVpbG54<0EE2byO;Gz+lro>a$jliy9b*R{LYBJi>QAYq5r zbAfrXlpzyF(wGZ5nZy$ucqmx^?gdHHmq$Xf-XHLIKrEq1@;plEJOsuk#V zQg*Iy`LjwHleN9OlPfD#Zhv2PBlA5j>K z`N}4Xfxl)9cwkWSGeQj98dTaj-l}}YHd|Bat6_w>2v?ppb_gRX1IRp)BCX5?*!q9; zCZMS974wi?VG|hdYPp)zS+F$m?EXy}0tB+^NOY;P=T>+fFec2`O*!*$M)Uv?G}(Yb z58%-QJSQHIfjBN;FD!77RV6=^A(Hp4OYdlTW#SQ z$!a+Fok*j<$h%X$*_B@TQO#|#L1nIc5<)=&6g!z9v(hwjdW5q<(rJGExAq|ugtkkT zaFp6GAB~M1(^HT{fX+&Z5_s7!?%AdR@0+HV#!N$~ctYKWo?8Whp_c+9U%XABWs)n5 z?)=EFN3Vwg=Y2dJSo>^X?F$?rx@q_Uk8TPQK{r}or!h+sX}%e+IXpmmr0jtHxY5YX z5a*4xK9KCr^obFk6wOqQMby`EQjUSBu?Zt{1K` zUekPTE1#;}uS~~!G#)sz>ZeY5{52}iA#{p|PuS<{RJMU;$3@zv{KclN+>}CZ>S{P) z?vBrW>FK*vyoK!K%6!M2!BS?CkEi$5UkV^ysElA%DF)bbhc0id8;=32zkW$F`1?yQ zNgjGup{Gilj^bFMk>I($;ME9I=f^z9-JiB`_W;r~seM17>1q&S&?3#?&l*0OQVi_doY^Sm5;b663tbe$k9xO4u5e1(_(fhgE>>h zPC70$`^FJ7AtA3KH{5(G+{tAT=GRRQP*n_}f)=rjC_S4{cB2!lvr_Hklh&!LMK04D zW?hS?cXMDQw(7clc5nJkK3)U&Bv|vxUAop$!%&AST+o*MgA@W*EBd3%WkmTOWYQPsXNjFE1~Frf;>SgcOzJk<3ZumjQ) zo@9KG=PcL2X^7UdDFx=Ckbb;F(JtZ1B_WBIiv-OM`fPyrg|Bu)CyUMaoL8hgOoXWn z=1jT@$6o<)2owDjhJghg1b?ACLsgY@T{lRcQCxmUx5pwV_^Jp@gc>KL{lx%aO|r$6vjS}m1Gnq zZE2K0wba68fY}mg?7^^MFEq0#B8@2h4pbJrXL+d19-& z&P}R`!YSzv`vC8F$lbutT`=&foq+brtvy@;{u$LU8SIYM^c~Zg}le0k)rN&cIh%hN&4Tp6*H{-(k0u%)I4)y zQ17HHZyQLfSI!<2ZzU|c*fit8t(N6mpkNVzi$a@vjWfM8Dz!op;3LSrW4k{C9zL?R&+ga%~FX#OeaI^k01e5Es3W z`*?cff5cJf(Sq}iKvGwMg8Z#k2jkr$x@nXig4ZU5_f1C9zJr1*LP2MI)|BU;P<32x<_b?1| z_-7c|hFuQTQZ7gS&ihz9wuK*B+^);fbFgQXh5O3{#mpiM(6PZD4R`UirgKXvyPB+#?V2Buq*cQOmI%sOU*&C4uLDny^rGn=Scgt>WuZb!-S&SB4j3E`RZH9q zU83Bb&W zbb?T=%g#TTr5KYiGr*DZw}*};!Mj`HJIH?$=iOAXS6Rs=S!lT_Pg5x8iO zjaxtCi*wWU^&01k@E`v)Med2}t`QdiA%}W0epa)?d#@0*&RMO}BZH4EzOq(9@V2qJ zyJ5k=viUg@dy1rH>k$}?#sAXxI2;7`nkx>~=0)-@%^zlzI+D})FyDwPyS6KuuM~GF zvS&JuI1o^F@u%bo7F-fRDwc9?WCXCtgl%TF&xu#JYEYRR5{1dT-=+op&hS2LY?tUV z(N0)0svQlMK9er(k~#RMO^b+#b(=3ZO>1->l6wy}v{7mBuDsM^yyUEogA>K&ytskZfIo zcotErFZ_7Y4kbMCv5-R zY4gP%>XdS|>jIs5m(W%7T*xv*VB@W5UAd}j;(ANYGel-G^iy9c!m8YNvALuuhFW9u zQJ(ou`WMa?aZgDQnZ74zYpUbxK~z%YrTUyGP>%$ZCF}$SbD*hQ;M7+Q2ECaBNrtj# z4YeilG;3id6`v}VlNg4!6!hyNzx{A1?*X<=a~Y6C#kwy%U;WVxt9fmnQ8uYPaY*zp z^o034kLDrxYI8Aqjo=nlL#0zuZgYWimZ|>)=AhmEI~xDI0W2jDYm|$q<(!m>kGA=q zN^Q=Zdo#)xLysf;O|8ZadZX%b7vIQZ>YFM9dpm zCI21Uz@Blxk#T2=#*CiIg@h`5vp?s5l;qKcinImw0?X1eSbd*=2RdJ@wxf&S3hPHcH#{g8DuD6^&CRYnZ8SKZ#~~tkC`#49T&B|`in!q zazOqL6xKm7wOVP4H#2-Hd)!rdL*{kC<`JP@7eo7{zdtZgyO5TH1uL)=FAo;Hy*0!8 z(PzCfhKM8mEq6;rrRJ?od_=b1XjrC$5sg>x#E8T;Q#B7H)Swp&P3Efsq`duf)Zh?m zb8oJbHb+y&>2m~8uV%U@5UIGZ?XFIM%Bup5?{%CBCliLhnh%d*Fm8I1(E9Z zta7^$U(~!ikku6r0EKbnQHzHhSdt0vaYyF^s<{Sulsv7|FsI?|3qn;y9k4MYPTZ=f zFqGm@Wt#ntw9QTj?_Um&+N6IPqrutV{@VKWVK@HjU+}Ib9_4u@RPVKs~w@W@}PSsIrp3YehX^<(pQ+94aJ54u5bWz{rCS6?=na z(H#9aHkbGD%*1OMq*qeo8q2J*el6?Jy=}YLiE86b0b9*G14boLQ#Y0)Sq)wRb%Z6w zT&X8C<#@YRd(SlXa$|gPPOC-qGIN>|@q2xW-Bmtc&8YloBp^Rkb?>)_h-&rA8JbF$ zRLr1aD63o#@oy_N@hetj%U|KbDg+f%%ns8VddS39EJ-$8m@qaZDyq`re<(h$$~u1aWYy>$Rc8=+epu% zQv7amUk?k@*tFL~fw4`m7B4BRaa;@X=_>rk^Xe+>Sqc6f1s9r4>6+h`D$;#hVOqde zgnt+DJNz>6!O;1ewq{QQR|Fx{MFp?0i*c}OM|Uqd?Gwmkt{^s$WbVZ%_0Y-ZC}>W+ zrQy(L7)ojAD|#Q;|9*~Mf+1YwFI5-GgS>J#Lamy$6<^klwlTBkplI0KPQo>;&3DkO zohifB`XC30)cu>J!^SZ!@mM(aPV=I$Zl%@7+hz8)#RQICPCQd>(XPMOOt0~bYPgX% zJW(6GgQDveO6hBfUF!u(6EqkdTpi-mOkJWieZMcQyGmy{c$fGa8dRTS;Rye7v-i;& z#6)Llv^YV_hI`sA2XKVLJ}f^`afw7>9vfH!X-*ihNFQyEwa}JHA4!gB?aWQmqo1TVW#L1?z&rsU^Q%4 zmskDuL|BvtApRh*r>Jjjk_V8}*C5ZO$?Wy`Z2-XNH$zHKQY>P#=)&?pT6e+IL)pD(Xy#I1C<(*>i3osZJY4M7^DWUg6P~iPV1OX3=`AC<1~WVu0cO{S9D>t}{eE z#y_0}%N~(X&8Y5P+ueit>3AMYqr$f%4s)@wRJr=AAc2_{_B;XD^yni@K0}+za<|27 zd#Y{Q+N6!xd0dDh$8>_=(g62Cp0<@rU7Mu}F0jTTz#3Pff%uT9_MW;mT{_@Je$$>o zswR{n^nzNzNz}Zy3XMiG(s7F}4WUSdS3udA0TM~I26JPR zHSt$9opbwZ&Pv&!S*+8h8{gtTl+H9Dm{oVTUjr=6Jr^G4t62fAjdFbI$4MgGL$666 zB4{cpP^CTA|0k&#lLiFhP3){dj7vlABw_zDt9HN50l?}pe)Y|e(~{ZsSVa#e2F;FI z4Gvypd;Q;09rm>rrGM-UYRW{r4*FMeCfV&OV(1poFa=3Q-?iZ^e`c86rdHQ=*Wy6P z%ICIFrvk^iOp(zvuo4C?S=d}SXJykdT_q?)mDkzU;DW<~kL>jzBnQ{7KIHLA)o%1-?Vx#ogCyZv#4s z?XBM!FUUp8mv^e0WH~3$85-Hj-P@M=sQBpp%XmQvjnOZaU}>Ev8B;_x2E@+ zmMACPZUPt(G4m=i<*0r>mO4ZOa&% z*2-hk29ozrx}R|0Hb zZhw+I!I~Kax>hzYZEJ`KTBX!QhSg+9+BJUia}pdxKa6uW{np8AQfO04Kz~wmz8hF} zm4cX<$ZLiR-0!KdWrRB~+#aRW?mE`v3N6i7AE6fP8X7qCKej!7sPfDok47UV>EmDF z-&4QU(=3RnA|HNxE+4D$#Hqy(Hp?37{`WuAOYgv6T$RMM*6EahC!>PyJrK_HDCUI_SUazw9RpsEvd_rz>KdQ9hxyA0+&QzN&wS=;nA|hfnjvnl1;q*Op zLo5VuScLBMhm9k{{v#M}>@JORYaKDVtP*vQ&ogbq5Y2B~#afuww}@lzP23pES1|3$ z?)H30gw3}CjErB}b@sf{GoH`#eXzx^=wm#|{L2u@wJrH5R!KUFeF;*#kW7QKDX!K% z16_O8#{x_9P6&hpxiMO)!^^&;J1OeP;}icO9(NTn_m#pI8ufkZGu9o!szfrcJ~BDo zyt!t}&Y;^Qlb!_i&c{Vhs2K~e{80t-}3R$_|?1 z5{ZcKIxzuowVUYkyF*TYgcRC2#{t|43CIFKpG@(P*tRtvL4jU>!ZV-T4Dr+Q`~#BV&0^uDyLw;U6JCglvn5(wSKCi|A&u(^r!capmsj1j1sY!Lu|Jzxd?F|K)u} zEU%HcXcU0ls4!y$$X0kB@erhN8>;kKKJGNL`F{t=1f>7Yj;tEY5inU1yyz53onhkg z)4-l0+%33~#3}t=!^pkH1`39EG6;XC=yl;C9tFG)zsZ-cUmweed`M_Ay1WY-*wGoO z%n-_0<_K>MJpXs!-!?NmK}z%v6zt=eer^lvtUi4Ghed!8gn*C)C08_UG^ucl`@2ok z22~xsRJtNWO<~E6%VT$Ve8aD5{y0}FzQSlhL+9V^gsxP8TLbP<2eC7%XK&xcdwwQL zy(KGrIE!P%y50#yTHt~E^|zXA-^17L6}-wL80Nnc;+c#t1;<8&Dcs}Kf7O^zpX8X2 zlIgOV{;y_grPV=Od(N1y9)KUjA6`+={5+U?w35@(339cjc^Iz{^vss*KF}BUji(I9 zQ<-uN(rv66pcD4L-jsG~PbEtOb{|WEtq>$YHRk_zv;qo+$5i43Y`(z&=eiAPaJsqa zM~oBCW~o|*zHoCbmVPi&SZb^7{3)PpS$}=~85z^>@03M<|CZ!`WOF%^{)-tXTBQ2t zzWviHiS1j=lTLHo3gFLlaMps(<)(Hi8?XBuuMwg1aNEb~9}0p*9J~-{L;eMyU^bS( z8kL_|ks@WU#4@yt@SaK{@Z4Vg1-u868i`w zNu)L~m2{Ch9uj>CH28w(sGNA<{I_p< z(ZeX-$3WjC2Ky$MzHDK5DNgMnKhW#$zfC1^Y-P;DOK^dfHT?Pbnl`B<9NUd+ptF;Jrx?ZA>|^u0-C#;_GNMZeuq6Albsb zEZA9?`=tSHMEtx*xogq${=-pFpS9Ey4!+>jN3>11RjRqU@Ecju6G_9OY2pbQ{jZsW zgtnMtk_Z~NAAjw_m}sH|ht$Y^cW@0T=ySD+A1;o)Ni1iK8c_9!7;*N1FFVUwx=Tm; zST+{@rPh4yo+!+2cJMk>hxJhj{8x)S!9XY0;S2laM^Zqn zhZW<|k7rXg3-dR%G1u8_&(hRR1SXqqO-&9#rTVR(E7;Pqf5L}nxrC;ps;^pNXRu!n zCl5J&id}fBXz>2!`TOYi%VZn5rDPunpjm&GG;+tP6%&)2Eh}Ofl`@)hL~knp3H&PZ zw4UbAdk#;xX0c%xK^|Vs^n3w77{_#R&xAf#t91&0d8`VMRRJHGL?dNhgyxh{X#*Cn zL@i5B!2{f8w7m`A+bAX8*^_#{>b(EygqKN4EHGzmuJ(LuyF7E;V^TandLW-by=JtK z$q~L^a@u-*tT(B!uv}>VL*4ZW2Six^$%Hsf-y_*BN%$r?3^tirqH3x>Zgr^qbjvio zZeuM=2UPB=)a-ckvoIRn!bX}VZ68b=L%<3238?q{m97?n_od4wv}Rj;WGTd!DSu_v zxiCI2p9pXd>%vUG$G}X2nokdz0gnhasBtExhrI}8}E(A$Y{O3W(FraNxbWj{jVwD(4ri3o(O#}3beKqy$Q^M`01_J zCMXBE6&U#O0~@Z%uebx($x!KAkmfS+-y=+l|4ywBvSn^z=npFXn<8iFkj?*tjW?pU zF-85Q2{YW71FMtCi0r{o$Z7T) z?A@wfE`QltoQ1!BSpDIh8FTT(GRCPRN?*{3UUgjNBdK@8a@wC-Bufzw-pUXr?TioPl5Y>JOrkx#`OpK zxaWy3D+@m*w~a&jJrf-W$by6zm>fyFmK^NYmOfyYLK>utd?|6+0DfHDc=_(T&QVa> zVet2_eTEZu#LgEU2J>wu-1PSR2V2A7Tm3->NJ$1#guFWLa~oSC?B|X<^Oj8qulPlHTZh2EOH3=yT}o^T z&&|yquD|Kaah(CmL~?!1yopb3*ss;?$%G|=lI0|C9%l_zQog zqb$P&7kr$Add;VJ?CZP^W}4hzn!iv-z`$wt%B$g7da2smxu6ff zy1gK_T6s@I|Aq1}QXQK$cJ{@xx9bVR?ovXfu;yulFbNUmnz^aI@ug|;Vt<- zaZ>OvMaFTi_r4-DT{VPGQJ{zMO;!CaD*LKDPZs&Ow7Gi+tHd~6UOnjj{Xw+QK#Ka< zs#v&!)2(|!kpO47x~!qym{oSrX1tZX#AR=7{L+8B5N^u|-R(~Rv-r9`agB)1rX8-g zm2@qqAey5}4$C}}mm9n&41?jZ%T9jlliS#g-F&M@(}g)+F~9UF&AP&e?jLk``LceV zQ4}3jE75ckAW~Dz5Eb(*)mpeWcg}ryAR5jhJrE$^XKmZzCN6cS!Uc=grN zU;Hp%%3Gwn3CsM`uKKE8rtdS+Wv@tGGvAQPYV*Plar8+FS~MXnUx>sHaK70+nPG83 zl7DG@agvd5i;^q0lKfZqt|t@K<1qa5a@EX#o9xqE_KHwx1xD9Hg#T#-UiNqGuM~iT zor2!fVkfBEy{q;1LaRHQ!4Wfscqba-c>({TCt7)4o9kH7a_Y5XwD6?&l?kg`VoAER z)yen5Qup8{mv^Sf$DSM8Qp4P{hGKLjkX7w*kyX1brE10cQM6hZYd4 zVzo-;ah%#~U!X98ZNkA)=Ju+Wq^l!2(OkOT*LhrZVzCVv$(&X6SJ-HXEwQuE2ZHSS zey$x66jAltH_l#%uFDm_gZ=L<>%O<{6gT`>I>(k$=40-Kaq5YoQ2pBF6QmNnO|@Z_ zL$Q+U<4ge<74xEsL_4dKU#LsKX{FQl@Rj~6y0ZsTuMREDzyY8%2F+xg`MqOMMbsR2 z8deUo)X|S0fbr1e9$#PyNGcK!&VI&9aQ<;P^f@*a-1E7xuF;$tr&A61xo~{i-17L= zA4J>#(e)qxRKM{XIBpdsTPQ0dM}%b0lf92UvN?%x$lhedv9tFsCGkbk5% z{ar>09Uo;kw*%0}QIWUP>B0Gm%CG!jcezv$V{kQ>+U)ubuOQi+0{5iU&MPtc|&_7Pg{S*le;H=?)*0$I9z?14@Lh zl?OYSqS+=l=w;94}lN2ciE3BTUb zQy)G?Ok0$z#{z^xh~Vi;Jty|W#k4t8WxXoy#6>rMwn{yg2z02F|1|?a^IFiXTB~Q6 z#-li}Zn@%5C@gqs^`X?Szha4E6melm!xg{wms;Gfnl~0YmG7bkhk*k>RYquckB2`A z)2QMeW4PJOP;k&|gJ%7Ap@ap|Q}8-%xhP5e^crG}Ny_LQ0NAY~jg#MvoDgW92*8(Rdd3SHvMA#li3&?u2bMo8 z9`=FK=HTd_3kk!@5eo_#{VKCI4%g+Ad^FKzn*K2PD3y7gr%0e4@5t15oTe8U9uo-${QM`Zd%1`GWjq!2!IT(e9?oSfRi<~kuZ~Q%a)7J>s2wk@= zvR^Q!6C7{RNsFXY8zY}&U&H6~Z3C8U?lkNr8F#pVGC7l#xB3YL`RiTDONibv;5*O77l;Y@z+<;qjpT;?7=Hd zWdd}{|Av?wfc|9CUbNBOnhS^W8?MB(s^rl|Q#a@N-}ojaNZ+f3R6Ef)<8D{S%MdjC91T~WZH{R$m%mp8q<7T}9}_ia z9}PymhshpqGgf>w^n-)#v+D?mVJ70qEYkO9vI7tkq8`t=S!Q$Jnt-)z69tR?T-XY1A zW%i)Rq1mh!XcY=n($1&h^vVXcl&g+0$3x6D5{=iw;4`IQgM_vj8Izky9p z`TS5j1H7N_x@`@1$jeCciRnw=KGh3BKrHEW?`#}tT-APo+WZD7qzmoess+D=v1@N~ z@}CYEaa<44bPLq6uDs5&N)3uj*j95r#vB=svejnryy#kO0&~8!YB5aPs*sV!njikH zCmA?|Ocr^oVXWcYQo^D)vJ;C~7KjZ!``4)*?iBMI*cB;-oluLGN*BJLSYiwFCU0b|=I2^(TyXM$C;wF^)#FtSW?ylRB7pM*dj+23%8sl2hil9Y zc+wIouZBdL=SZhn(!IA=zWr2Xe=3sitKk`h%hc6OqKQ`a#4<)pKd&8g?p6j3&HzWD zkaQ!ZzHVCW3JPh4q`G8xYKU`?UKyDu(*hOAj5kNXk0o3FXxK>75YLL*Fh2$^1WNP2 z7eYo=uK)!uwFP@V&AM(o{O@qXND>FIJ=%(IpPz1lGXQSekui1^DN z%6=V`s4uXwK-X^p1jVsQk^LGFsv#8q61 zhMpuR5Jjg)l#?131s7V7OpfaCQurxZF7gXlc2yf(?F|BKr?6!pe-8lPIrwI13$7yR zPuzsCbr}rYX+CSEFYxJW0a@uNd9a(>%Iv1kI{p>#i#&kOmc z4DJ)Fa|L|SJ~b#TVfV!c$W({N;uS43CRo96HKn%3y!jwPo8B`)GxjpR-w?j3a!a>N zq&d2h!WKwmlb;8*%UI+3x$kr6s0=YW{*NaX8}>SZO&!+QYV>Kg^+XELtEP~8rxfQ8 z34w*rkLMANJN4s^B${ufa8E%~2nD&70NR#lDVU~)FSoSJY5oKX}M!S)A#nMft z2J0%mbrwpN?c2cHwV>w@``$fFJ|*uZSgL1C3Jf~szu?wxyvJpAPJAfV^dcC0c)}4* zN=T^BJR$@i_i&$Tg;+MkC{k%hn6E!}E6OOfxzEuxx)~w(&l)VnT!+6bW=0Ew@k{x9c{%6wt1WJuH(zNt%JSvLkuz;LX|@#V?7 z5&#h1&|?AI*k^QUi}^MJ(ug~rrIzU0mfRnj$1YpgJEK5vg*4^3wY6EWTdbDvW12Z9 z9{nP1vhcc)un+0P?RHcPsgDg~S6km{&Ll&VXl_|BIdbKvwvH@C=8xt=18L59V#L7~ zKe*3`m{BPUk`b_(^&R-ny`~C1S+^jw=0K3o71v7Mg5s580)37b{;6ZUp)jif&5wQn zut2Ny8ieG08Y8tSy7n(4q|}O2(cPgR^1Ko?XwHC8(45!mw;wH|ZDCe}y-%vTIv=H} z1H@#_91~_k2;%HSM6dn;A(8)AxpIt>!%#T0-xJXy!E|0NHJzs26tQw9Mlk>1!h2HW zO#PM1>H=!txRm2+c13B{Ko~C(Esw(2g@*S!wfWZQXPVM704~=(&kUY>z|`*WVI^rc zMK*_xii;GTf0p&c&5VAL?5Df z=jyvvY+7fq&Yez-lSWh2{)-%&7%e}S(~T)x{=u#JiooNev6$VGN{0BvJ2b+1mWM8- zY1Ia0@Zpr?n*iN#FY%MWp%s4%zrRk}9y}2_)M}JR z*&e^M%5|#Zlnk$?(4k?ek;Iue6bBVe*~^7_J7@v|mtz^;T+ae;G3v35SK7Ay2tQ3? zv4OTF(46z6p$Ff#S+q%xyKL~z0TXM}9WPeRda{hHx8H{tX*}o&wmkv?ecDS&<9x%j z*`GlP$bC{mqg3_xf(^O6Pjd)lJ%$05PKm1#fJ=+}X*N+nPTWgn-Jt?kM zyB6qEXN53V+bgB()f)hz&FOSG=MFGjx_ApmzjJb^P0}}CGO|RMM~9wDHFKO2=bI=V zx+ZZ;6|=B>c95m>e+@PeWI+JwI^m8@5q-COEC7G#1p{47q3cJ(-ZjbUR0N0yJ-D*h zxa+MbtJJoUTkt&Bx~AP6=*A4MzC8(kl(<8;2K_-Xn2$UzQV!>{6bnu9<-FDKgPTbpL?w*?@L``%O^5BlVNpH?5zVJs&eps9Y);qF$EQ)qiciT|D)q?o{5&wqQ2 zm8I#wyTm`f2h_vY-T?sgr9z=aERQH0?;St927VlwhX=i|90ff5HO@`<4wr0v3NFZl ziAAA+iuV^2@xKa&)VAIm6^Jgp3~*$&DoQH%2e&P1*49Y z(oGAgBK5LpCMg4%7Km`*a&4@m>E^p;#m#$(#z4$cdHa7MKr)Dh;85v+gb}q+DVnC9 zQU3jSDmZ7+C1vZ>a4X;AS635U2>!iu?_z#w4=yO!c{SL(25qfO*|2DUy}7X{1Vfw@5{q7CdTWwRo|xQv=FYemNh+vefYh<&+)JeoE`h#RRzGXyFeG~_RIsfU@jo_7Kv{5CDwt^ z8tsgVGrh4*v1|8$2%>S?#6-<(@gvVRu#S>=)3rf6daq$j@r+V!x1b5A!yJ9g;cOUquHFR#yq*vP&LB4x7= zF-rZyOsP@hHBw9Za(0slqY2~2>(qgyis}*1Zf^7T+mB?;of-=m`6S~wQeLfuwu(U# ztADK>sVKjyFD*~mp?l~SWklTYxy$R0;;87$IPgLfEwCBZLgzmg%9g-=#*nu?vqN8O zAJ4N!!+K2<%1FOBY;OSH41mjph~hgs##`x3aH-^VJOSMFKj&1Tt|x3z^_!&s4`_ZB z9~CJJh$nR}*&XLzRL^tfgv2fa6lH)ny5Y<=&@cR*jlFF7Y9L_4v(BtMpGiPQ+(m;5 zX-pH%YE8%-l4N37h{D%XnIpn)h<7JwV8l4amRk`mSdwjy$NMd)2qB_Jw(j{3De`fWCRZ+<`Nc>%{5Ui{pQeCwF~3qP%L4jz{VU zfUFAF(+>?v#fH=GJ5e!-lA2qT_Y7BZ|hylsHEA_H~vrro1J{y zt!PGF&aqEU;22d;3D%J!`c1rJ9PV}V+6?KfM|X!=W-ombEh}Q0*$!oJ37sLxiyX1* zSI_)z6|Pr}5FtA4uc%OOllaYfOXoV(P7xuTdrNXK_P7zpm)5WaUA20RX;5G+enC| zcqhr3uK;srq#$tkcJ|4d8BI_0H{4y`ne$d~gKZdD@Am}b@Lfb+U(lMs$cGNwtAJzOr1@YDfv0?PVdZR?A%RD>F>$SHJA}x z@cs=GH?e0JeJ`37z@dA^S{`+ZSNl%KOAZfaFM!b%-KAD=wztiz`FU+GP)h8Y}h zj|S~mVn!DaE(9upcH!ypp2^F5t(!EvJ(71}hotORO#l>j4mI%b;g zpQ5eGNIFqRZf1TJu8;#@m^1Bu;VHy^@y(?v^xltKQ;PfWF(H=L|8+6ja+RTQQ^^Y! zp!Lv0sPl>WiI{Z^A+)Mr4oBr5TK;7jZ`h8P9^`)zYmBg>@|e1HC=US6t?untg1WMP ziq9YGF>ZGWYQuO9Ebtr{l^a5RlUS`4)|rXmhP}^Obwp|3SaE~Y87nkCRq(M((i-N> z!`7NsF^vF~zMJ+H7RlQ2`&_DV>bAoRt9$D<1Q@ocdeHjVh!Q<(cFV~S{*>2Uuw1|6 zMK3NJt&GD5V#$MBu_y7g%RUR#0!?WJJ|?Lx!<7cTjoOb|NvwROOR`1%4F>|FB_|Vz z4⪼-7J8|0#8k&7pa4MCIH1f_Iu2tH*GBd5k&jt9X_iP7WlQ1;8|iAt zufvEX34lJZ9NxeJBNWj_Y3j`isrCRU_Wep)Jgjm2AweQ+2*N>rEBpF(7?l6-c4VF^ zeoEdWJXF(JB5EHBJYIpJ_N&f*IR{4?%RbLG@7x=;UH+Of1wTaD+O*j$CB)f(!{Yrq zDsRC{O8@r%;ZuapzjtXlt%bntHg-T1)3#H;=O^XIj&|Ff^;e;`FkMw%Y9b2{xtlziWawMSzxi@#e%WLi^maXbNvI=S0`|G(H*qyh*_ zhkKPW;Fq&jA|TcDt1y&DRRGfW;uh+^1(Uaid?})U5G^Mi`Q;~Xr;~FzTnKzldVrG7pYz{C zE{CaM+p)bubKO`~aKU1BQ~a=5Ux2{L!%GWq?hpMyb!G;H zc!^WVZv3Vng8x)T<1zY5-+=!`3Uy$cnnGmGkVEa-WKK;f1p&wLBOHIwb`rPNZ+&4* zA{(J^skPX+y(uSk&I!=0K!JXw@dsxHH*1t>e6zR33E{Y)dj-!LJy6$XNb(ei470U& zymt-_PEb;y8A5i}P#?CU>( z{I+4$to^;+Jux%H@Z#t`^S4k*)J369o6hQ+M7f~-82blViyYL>%-VMBD3`Gup1~B8jC;01XzS0AIYm6yO<{M<2UBnCG z0B~gskQX$Lau!@4rOUi^H8q_Jbs*UJ=?FRIB^OF4IlOh| zgO+%`V7N}E{}-;gTO-M9p9mSWRxUdJo!asw(fSlV+W)NYv3PaSMbS6kE=k|B5;Vax zQ*xACaH02#|EKX=)1jt--upA86C~8VD$|-qEzXJsxDUzpv*np;-0$iAo%39tpQ|=2 ze2)N~$?_C8Pv{_Z3R6%$>7?dDGY99Z*`C*hWY|@zYme!zO3W9_CQ>h$qwnD7+Bp|7 zbXNdQ@Z;aKUF@CH7T_f!-h_>$bs$j3EOyp``ChktVvl^{ozT-TZ%#7r2I3;EruFc# z6URoYRo74SM+=~rK8w6BL)=M&ZnVDpeWKX^x^TqT%7G!VF0=_;$^T4s*nlzG@SCo* zgUp-x|1JXUsMI5%8s`1)7?A;|POc#*VZbERhnU@yp;AN85=qB==$%V;>!0LSFk-JF zW-0mP1g%_gs|oMyb((9OW;vxE(qeVi#!cp8^!{8ge*x6z65P(yTyp$fa9o1c!>qYa z^5^}lR6bMs8`=61AEv%2qkzihe=dXQH)7(LEj2IKK_Hij7I=ECEmr!Cn7d5UrYcxE z3%b?~pac{s9?~Tsj;%PL6wIHyB)f0Uvu5|D5Mc<`{;PDZ{#7~|n67e)XIRR@f|=a= z=<5zJiKz1rZhY@U4b!$kujXIL2Br{e2ODeax}(&0)b|ICl|@@D1K?_8FG}LO`^3m~ z=;w<#IRDJ{0nB?a#4E`4u&Dnqe<{umeWBgSd;W+MrEetFP3K9!c0v|hwNPXKw7#u_rsqzYbV|V&!#Zc@Qc_V zEuVL_2qq(&7$Z2Dujvinh|U>J037X_2eyGpUiuQjiKatfV82*}uen5;YTwMH@=9}B zmqYThvDWz+)IJM3j(4gKsozLUjESV-;1ill-}$lKdct9g^U{tk@(E4=A<2`BYd7*Q z7~NJ1f(@C@KI;OH(oQ{-7X|fz76rqpgp@#1X>O}v6)nIa@Jn5S%77=2RVOywuZF-U!GM!xfxxR z9p!Pa!QskOSGojQfxgbumxk^tJ1u~*F@32rhswNyQT+dm?L;{U{;z?BN3z@_04h)P z0Q{)?KnME=RV6>O`4D(GB~}_;_d(q6d;1ef1ocjf;65}*!C;&Pfki^q>0;Qq3E1tN*mMaPsO;zZAo;; zi%wuzNcVl9&`}z%lArtq*Ep30uXc3)1ec+j+##E8+0=|~Bd}RQB9-UHSl0k&UelON z`B47SAosz4p}N7T3og1Ox_uKT*>eMDwpDPhaJcWY`fcPlHuri6ITUDds3!kAP|1^R z=(lS#8(s4!dBp|1f4>R3RaeXRmXukmMPjimm}%&dtc1qL_I z`uj#{%elP&6MUlF2GJ{ws&ln)c<@FLjl{3#d%*c;;Hn9pwo2icf)yDYmgCpzIdQ1r zcm+P(T5-qUloi_R{(T>lt5+ zFRx}JuF*|w02DJSd$?hXZnUE8zdVi>55{Q6{;|K5K1Ww`e-*rKgWgCkUbUR`Erjs& z-_mMZPt^^u=WS;-imgDcaSO{ftb;3+7@BR1(s*HL)&k+a+W5PZbyH5n=EqqYRh+^r zUr{VK;7*LAp|W!>&u<1Q^x(v&CoGMJI-UkEt;pkVN^CGY4zlg%6-zHReEB#YWqP4C zhpw)95YY*Nl=7hyPaRh$$m{17&17MLf3?J7)^>tS?wIegD)o<<9)j?40Wp z?m&xFZ2y(c99yQ?>D_HF*D9Hwq>uubGAy|rRnzlb+ePAVzFIj9r3(ERS%?Nkx(h|? zU5Oer-OKNiopXOY6*nR7L4=;*ivr8{s-y>`Q@Q|900d+LuWR&*Xsmi%N6c?87iQLR zv{F);d4HtLhj<4d;9IL)90|rN7uij({|SJ_x**hmGAgWoMY#AL&Ac4u&1Q3SRw;hp z8;WX@Yb;ezb{-S|X{WiHv%)#^{3xntOCzE4!KNuCVNNtsl%qunG5W|1Kzh23?9WZ( zy(YzY8c&fC?_UD_^iv`v>rUb}HbF$Xvr1UHa?<~-w#1)yRN?yqiyK4=8kdHV_nvo@0iv&FBzXpe7g`RsS`^#2h^~sqExG1J# z`JChsy}TcM7tKl8++8GRp)xNSN1>ZIce0Cr7qpEc5I!kX`=BrSs5?h-}5f|ni;7Rc^s1bi(AjmAYZGWccBxB?*^lC%iZ3PY%7ny5( z7SPEWRbkXETBtN1%&#UzY`kl}p6AXg&U_{J(-Mfak}pGa`98$#JAD{k*h}9Kb8YeY z%;Vq8V-}70MXS^hh&p~r*X8ft2Ta| z%isc6YYe0`z3OG90~)r3ken(xtoqUCJ@um{_}*?_<+QD{Qd|S2g9T*|#pK(g#KLqn z@`mCHI=OP0=*FHWEUUzm&E^ziCWH;Z%<`K?zyjAy1-rPYdlJiY3Kl=PqpUjJHSg+o z;iwR=>iFcOv-#~siz~8tZxsX9=RMEu<~Qe{ zT-Z*I+FHBPl4K>^P)DomkE6ke1)Ft_p zXwxhoL$^;e+}pic*R9>SrWjy-R^~_{j{&4UrRQ!YrELA#390jb7;s)AKnr5M3jZ)D zdP}_VL7>z7_+h3y4RNC>F)Q}!Ec?zyxvO8Kp0uxr1O5X^G#w4PsKfviE_M3So-JGT zr^FxfV-pg!@9*CVHoaR}b*Rnq=oB z(V=V^Y10D=fTxRmJRVcuAc`Tc4yEi6C~X_Yf^HRvBJ;gIQEzhYQJ>gm6p%4{ZnLd3 zc6@sDU=NN`m1_@=CE28x!8;^4!{BMx2Rb1T1>8I+_cm8l{ABe>4V zWV3Y;;m)d&!(pp{S=hj?rga1BSTrfXMH%MHU8^ljhlbfT*~d z21okHDiQn0jDcA9s6)Hs`i$2&g<}7}d*JH>+gLtAt&I-yBtEE@jiEz^=&EAFKE;23 zR4n_#^&V>#$G1ZN=sLoK&=G}usVXK&3BL1w@uFru+h zWxL*6Q+Yq~&k4bWYLzu}r4o>5Cgsjl6-ndhKO*jGH4r4hxD!6awkzsIA+_+pe(14&k}Mc`I%jp%x5XGA8YP)=@klvPL7*pk~Nn zdZ9g+{jpQo8D(5MFIEVvgHzq8eD#jw9=lGn_&5vgKC~pVz?rzlK}eYNjFlGDd5p2$ z+DG)P=5;dUJL?ysNJD=)q<(_5CG7nXs-;I%SESjRFrM~pdY zD5-+`&LX&NFKeW6rKUVLEiEaG?248f-K#E-?KBF7s;e6DkR=NN;;@9B6)UGC1QRoU!-h$3_egY~(e;XU}!BWY8gjb?Geld?xe4#2L*wD?G$H z{hJHlg!&}zolKbr9?69r=^Xo3cA~t!Uj(eXF72JKdk|`KQxwziy@yus!ZzY*kIxGm zUVmEt&`3B5M?Ed$>np;!h5?3&O+BjJ2(Y)C#Jtd}VvWz*jW>%OecE!52 zUnbVQNAr1k^?MKedMay5f3HtI<+`6N;^EyJMDhKdbnEbvzUMc5^8K?Foku`ti6a3+ zLhYB`DIybM*suX}WCfirF_xE#?}_E7Y9ryP+s_(%>&c^y33mz6xm8g-I^Z|g?eSNj zh6LKkv-8I*WS@L>JWrn|MG;3M~K*f?P_4=?%-gA6Ax&Uxa<{Fk{`W! zqB3iW6?5J%D-<4YNiF~G1IM9;5e0W6^PTtaVtt2He4_uHfgkpDe)1jmU44<$eVqBQ zJ~y8*)3NzGF9p_3ZT=$3JIAad=*FwzqCbY6#dPhcRn_B#C8aj<$K-Pos>D;+J5u_@ z&H9LtkL4T46PvBq3uPnIBJwg;oOF&+VVkdd;}Q71!Ey%H+f*Pm5}Vs&O;qKIDj>60HiL7d=pajOE7r{woF`swh; zC*stOay}?Wi(4^b8Neln1*v5>)8J)OdV>EIx_oOXi;j;%%P-#pPn?m2W{4m-?2@*e z3n1bukOW?yaXp2ZjEr~J{;bGS#)Ia^2M}|6_zozs0>jp9nUE7IAC!u`gG5?ckMu@? zBtOz&bK~F~!QEVjwO7r??*9^g^7Zxc_@pHx>P5HAQ_oGF28V<#CQq_Sm~H^^Ka1eCGtJ-;V^aW2`plvizK{psSN zJ8ztNNp$be;@sKfsLNt?jAd>9>z&JyNZy(1AfQm1=P-^LiK#%AwLM*feA-3bsK_}O zWHdheuTkSJd*P{g<&xKo3LfU-EydMi5kBZlaG4B$NSVb#RPiAE=N$|892wXEla-WWdEItd)75jsPZAqZ<^jtFz;`soLwkRRHOOBC5sf&LLQ zWVzF6H%vIK(gok0kk!$cukX^G6!G#5TE*8Z$Q2IOlj|Ft0Nr?s!8~|c4cTgG#{^Po z{rK`OsIo|odZQ)_N+a0O2jv9D&uYeli%cjWDF@Dbo@O|BCUVH@RNM}*o`iVUyZ<=K z6$pAN3|4pc0oymJ1-`z(;n?DId_DsbN4ekH!NGO4oM(H^i|HLKyC0l`b^jO&oqIKK zXHR9o$SF4l9oWI*%T`A57y+iH47yx4RcyS~>CK;}-QKS$I#5r88k?#@o((7w zHiuPEgr~G#rtD%^X)OY16^(_wU$8o%BUAxJp@gr#ZHl--e+#Yd4hISd#&qKlsJv~dYV4pMn8)4=TXUk0y$nE<|bPqw*6H$zR>|z){4)+ z*T1{nc5Zl?HFvo0baT9=I-wDsXutaPgDm#;6#bz#f0ExMn43$MJG%Pi*1+ZTB%9h^ z(|F>p2n+bXbtl>6e3J1HxzauWkyLyOkOijnJHj_Ie-=(_#yaG|7oTRI-;ir|ooIpLkyHWX{ zwHLpyChvLvZiH4YnSZ43HuBjr!`3)^7y=`HgP_~$LdDg3+ms$O!##msbruznme}ZA zhs3rsZ^85Gnq9@#q3%oK-qbeOdChd}pA9hY(C2IlIfZcs`;iAgun!lX9CEU39s`)k z@h825U6K_MXZT4$Eaf?-3^imbkUz7LRqmaKit6Vekqo9I4cD1Lr^#ZmEtf|-l(8AoFF=LN zMNou>1yXUTPpp4{Y;djYeG;}J#Itr+X>5G@JBPc4BRUDdocp2y!zpo-%|GCoXkFFx zs0Hf%>2_VdX1nEx?AI!XIfIgTpMDkmIni&te_2}bp6gcObD&rGtfJi8Z6Ij1?}Z*j zoyQ0OUXa!ALW>G%R@V&Pq3`Y9%|nAp0^^#Lp9Ph%dHm#pYBs!Sv;G6LOb=geSl_Ri zy3iDi^YOpZ#{i%Gk!t~A+pUyaw$&0AsOxzk;sMV~ za@KVfj%dTaZDWnzq5!O+;~ck@v7j^b{#jm zayC-mXGU=CksW|Xf@96e)PjoDY|7L8xA~E|Dtg=Wd8p&>ft@qQZj9ProH~~v@}iZO zYV!TlH|gE(i#RthhKfACydy#+TZ2V^jkigVvX40JmiN@X62TpLNf50yDM6qp)B?0>u-|0r3nN!bf|n?tL@(Wf^>GGL^}mO z?p`2C>Nv(m#%ddiSo)QuGfXv~@}D6Ac2@|~w_J8m$yh)piKq_vURb@P=`j9qrgtuzjPS+~{ zGsrKaIJsbM+Ko7?AJ3~1y8rAa@gV}4-6L2em=F72Xms&yQ|_?nd=`*yQ4-6yadFRy zTi_=G#2@e^KUyz-rE zWPFs|v0+}7FjM_xGR(cq**!_>ENgk+XF-`}JKU#gsorsFxFG;3CZAgHkyvCH1=i8% z?ZWJQL7mb*>`rHrBKK5#3{&&5+P#|=NiHbHzf{q#8I5)yPwJeoJR-eXmIm%$?oKqBW3L6&7}<5w(j2xo^Sfa zntCRT>mH6RdxRMA@v||$tluluz6dXL+DY!4tws?yRA}oK%~PL$=_wNpb8)sfyJ_1b zrSO9?IsqY0#js<==@wiqB66rc0RS&@S`O~&3gDQUZN{<*Nz~q2EYb~rQLr*pyum4I^{juGg9ZDUw$gD`0XijGOT593AV^H$-h8Q=Pu-zS>HFq83v#@t)ore3$rq-l= z>ueSq@uq&}2S@Z<@GD2gg5t{OSs4^cX8h}*7@UqUP8MsogM$QgXq$B?ob7^XQDQaJ z`p2b#N=PEdJ7)|t@sy`V{WL^N*zbsR4fio+huk;web9sp2SBWh0MKdlDX5{#g94m`Y=({%Yxa8hLu%#{asWbrvZek;Nzefgv&4UgqynQk%9%a;;_<3 zz@#st6iVlbgCY__vV!>9ZYp0_;J0$15^H$hYk!o0>G%? zEjJFepOdA(I)+xk0{pahtU6JanU0y~e-4}?_#_gTHj@?SP6y=r!O#2}TY*kNH|I4y zncvyT-_dg~WXC$f8*^ej3d?t($M?Kr7Ux9d8}j>UB0vS=mWep*XrfwzY39_Qv7tma ziiT|}2O&Qw{QX#)jv~&!{))Y9FulVO&~V9?#Q30@ik;Iz#TK1$Grsu-xQcvg{S@Sy zx&9Je7QJZsxB>X&>VKci@o%~@L4*-${G0(X@)TtFUnpEFJteD!bSlrH6F3lV^pS75 zUR9>(hrzIhRx}E>m$SElzVa8MTe=TxXzCM~cIZd#&MMP7NC88%iM+4QbXVDkiTeG#(<3ryn6S5ww*tkEh{WcS zqWcE$9lYH2XQro~91e%|nWJR=!iV0St};)UYhB!rUX%sCztErGmaC_3UVzhqabw3M z#nH-dPolwqDexk}403x|$fEKEWa~)b**xZ>6>~_jB`DSCaqo&D*0uwUxIEYm<-LR= z7iIIs$N71FGfdC(Yd)Dx|5!Bt=jn%G(dNnGfp8uJZu(`hux0b5Aq`jNtop~yf^o7p^o$|oHdWFluWQTC& z$yCC=&{&)!)NU&n_`V+!@SNB!j@C~^N5bslly@a@i5%M zZlv+0nr0wbE?~+%I9a->&v2(0%n`@z0hK)6>06T>ea1ncts9gBGq{r83>L{qMLJ7e zD*JmMZJ)j;n+pG6R-gElQB1lH!iQ#KWSp>`lbe?6@xMcpr))(N^1)=b+LdwXCUt*% zI0GA{ma!X+=f|cq@ui5_TFyU?)X2UR0Ys$jxJb*%mgdalul{(-@v;|Ij30$~g;(Bv zki;p^(%~xq>sNq>r~}J`V8aQP$4r5$xhMSvbSXY<3XhpaH)Fi#kued`w_NEZ24`py zC{}_o`{$l)@L|O}4TXpJj*K-(rUM0Z@CRQsA{?Yr5+VzWo{k7O7Gsuf))FlTESa$W zvbLDzn?c$5l0o<&1^;weRVTY!+zeFlqVrMo2gH{*2~(o^r2vn3Sq`mG*sQnFRgJX8 zcQd7+i-guV=?dv$ZLfaXS2ZO?DD6p1ggn%cr?lalNAZ-wlMT${pV zoO9Vn<11s9PMBMfwP)47&~p0YLgQw}Xsi>#Pg(VFb}h3pE7?1+ZB@Y<$C;&yMS#BF zZ~_qeJ&O5rcA1xXavG^cgH?adR~p|tyHB2-vlF;aJwZE)Gh;@EuNn@gGOb#-1>at= z4>C7C@Xj4O!wJ8cj%fXC(A+)z=3Ta6OC2EwXjE&_tomV+qNZ`o)iaU2c|2pYUbMVK zl^7mT%29vDgni-_mE=;VXD`g)r$YzVmKz9(8xj&UZuXjv5HH6_> zYKkqU0Ct7aBc1w2|FRitf7Wo9V(h5n z^P6bbqtyq-)KR8mr+5wVGgaS?USREc2vJX;J;NM?vSwcdO5UvE*#G*qXC?9Ig{`cA zT{U9~AF7S~%-v;6W`^#vyJR+B=sShHi-~D1^5E;97G;Fh>@-yfEWH z^9lt_>D4BsJY-e8OpvO)DnHHivKOIyn7te35UCw)IEk1)j4F;lKW{>!iyS*3{D$vW)LQ2_cTNT3!nnX>3`AL9cNmJUOU@(zX+Cd&# z%OWt+chdlANB$=L@F;85wXz_!HPmH`A$lCa#QQ5{=%IzZWkvb|dq}^n#D6>?kz_UnCv zB^#E%!NYb)nd6e}4)Jtgje(t5f}y6s2m{t}^0yiIv-4%S$p)&R3_m>6X(UuHuJkJLTeyp}8T7Jd zTKh(jo?lbhv71J=3vc3P=YZ@?ZQ{?uF*to%I8X__Bu~Rt&npJlxa%0w5&9VhY-W#6 zTOLjc)*DSViZ&1z2LRMW~CcDn8bP_)flRBIQH5EM*Tn0*i*Gyix0-u8! ze#0`Byvu+W)`=&QmFn@jrQKM)*qqK)?;!|K-Ab7VpCz1lfzo8mRJ4$iv-0-8K&AR` z^(6|Fo9JHCtk50qMsAq=ovrML)Cno6AnjP*q^H0H2A7nWWS1GTk0 z1iy~PwwnKI(-#FQlPO1nn48K93cTiu9Sw+i6{BgFhXT|x_MM2M%9{KiJ4PaWBMUth z#KqVN-#uSmYQgmIBqZ@BChzgyUuGfF3+bdN(Uz?zqI_FZ(b}AuzojaYq&N!R1&iK83 zzW@CG@vrASU(eU``FK7a&*%Gfb>nSAaq#YUYh!1AUst^nlHi{Yf>!ao3r~8c1Yspy z-}ejjuE{ya^B$a%6UBXYY!@y#Te&+tl@mM;V|q%s{HI!uc*=3yX|h*Z_~JIoxD$9l z=h>3~*dtP_2e+yr!D#c{;a{xbxK}jL6*PXZKu3oWQLVr}C|;UgBbi=Z{sjHwPj})b zbsoBV82DVZgUrS%S>p~eGcEZgjy}O3< zn5VApeNSpi$IiU??L7FXx(MrV&T}pY5!PtbC$Rs#JLk|iR3R6nxmDghugjDe|p`WR>x#!C^Ni_lM|GTA7N09d8J9V&BXmE_}cMuMsPxZ zd(ZIZFUi>Xr^1TXqWa_8MLsvWHYb)^2UOPAYnfLXop2Y(%D?_%v@F~#S2CM}atT=upk~TV1xWZ_ZwWDnKx#M-XNVxUC z>{-#y5MfbKbL3yy2y^C#9;<8Fo3;t|M@_Q}n3JxP$Mrt>k35E`i^je2?pb>D_HQo_ zSzrBwr}_}hS^^!;<@yMFG?r0ielvjgg8>wzvULk%%@VXM*JadcvMg@&R9@aKSDejz z=SaL5F+8&)vJB_llh`IdTMTtLW~A+4>wm4iCM#pVNA6zLX@J$K?4KSy(2!m=gB>ct zRwrG&%Yn|6r|HRE<7gckK_} zFE~{VsNnfcazD|Cm@gP#L3?dp6^7t#Uweb`AF}mc zTc^GTU*m(!8jh7#*MnPMoNi7`y2R2b=jVBZ*+jT>DdBOdVD~$18Oz_>N+x4G#mXeZ zIaJrF5x9O&uFJ?wq{fKIwKA%jL#m-G93T7)k*McPx~~tMll@>mC6^PermGk@Zw@{B zXb)9;O+*-_8#AYAy*I8f4!atU316v|gs0Wc9y?Xom9rPy?aB|DDQH>P9X)&CN$2fN ziX2KP$)5_|7!!>>?wgcrE>nEIxH{W+8eMZ=>{Q_tPOv6g)R6C~zUQ&HgZ8e-$1n~b z=XDoj_M|M)niaWMZ`S(xP4s|lP9^uEG8ZPlh>e%fjrC9$<@P^II-h@HM+kXrXN|=m zSxix_=2x~klI-zO7kVu6l?v}lWy@)EOmNi&EK4pswP!62wQ(zMPxzpN`uBwKuQ7?~ z3=0gIdt=r+S2rBf1;!nN0f%-)><$#B8_z<%Jw-w6gDLxorPf1YDfL?L+AF08Jr`){ zzLw*7-@ngG=PVDGmUWVpuC2RcqK1KUa_FpCqlJB^13&lAZ4*li>@y;Cv)Q#)bteZ> zCUq?k?Msx2&lNK+_Vc*ky}_?Cv2(Z|(O(j_6|H;dHS_&JV<)}5lke7tm5#=u_iGZp zX+*_B>5-Gy>HWoB@D6Y5`cAl(n5@9_l@`GjJw^>DN}VCgaq#%tcl3E;(!GX@TNHEGwqA&*R@}aR37S4* zEBW=eS3=e94lj`TuU55Td)7V!b2~)gc@N+>+#Yg@ zZ@~F`NZ6LM`fTLYu;Hivh>ZPKh+45#S1aQ`2G499q_a^B#?g(2O#`k>8TAV_qHd=} z*>)N5DX?+Z;rG*}bvuQ<3UQki`0nIJY#D5}|FEaz`TD6DnBSm@148mH_d4cTC2W^H zh8sAuKT2@8gOrrFnD{7W%Mv!YzQWbKpR{QDZ0>bK6`=$Js<=Cz_6C~I>6~)^`rwS~ zHA_-un~M=7x+3Lnaa-}*yU|H2HZKp$J;yP##mXOmm^RtNQsmcWcS*mzw*Q9j>tJ3- zEfSV;YCf!oog}nQx2BtPK|F>mj>xUB$^91Km@u;FazQPFuprMRt%=IoooVGJ*@@Ia>jtUfsv7G0n%U;OJvNPyf&tvYvOVY^CkzC%8um z2E{{A(b7&YxlMSAQwU`6*JXC3b(5^c)3#@OeaB+IM?2pCkT-yxF3a0Hoo;NXZ~laz ziYR;8*DGA5?FMySBXBuqxp8sGUp@|!1Dn-WdPqAepsi;OKgq>V>#*oeybHPE%|hS( z_2fnQ#UX#6&4t0?W52z7;=nx)04qV&PLtBzb z&VgaodYJ7>bl%n4tl+Pf=q$hcREw4O6oSg9uILs@&o@RI%RA*@AbJXDt%T7l@|sXv zW_AN-+RMm=T{pilL%rRf#~aPZTjIv<-8jfh$L#yeYvU4@w2?!PVP>0gznEjs&E*Em z?L;@HKW+KSFE98Nvl3$5Q0N}n%&~&)noI*OER!AMs|EWs@YO%|8$D0UXTX1D zh$PIexR{^v;iT=cVHFz}Z%om+8jmt;C60b|3~!hC^HH7-?Wtnk-4rOO?-CnZsiPxL zpIMM+1GUqsWxZ6gqKEyzhWXVU_g%Iwr8y_=TdL{p9}%3;_x6s54&wjrPIEU1vR?X2 zHQvl2RR>bykP3`rSr7njqR4PVr#-DEwPX;*^9EftTYD2dn*%=QL9^h8qw_F{`R@)l zCRHaw9uO{vj9YA%?b0_odd{bw*g=+Z$Ejv6%RXJ)-e5x8?O1XJxn4`m;;)vjAisYZ zCui+@`~;FX8e@iFTM+JG=i1tC7TEUN`Yb6=y;c+GNIym$U5uivNpRfSx%h%xK|8%G z4aMm`{KZO<4>!)4cwz3%nguOkj8RUft_pqSN5ZTFk9b13L8E0 zHpP1IT$Kjiv0WGw*?9b{3VpV+jUfE8C#THr3)y~}lD;v-dN`)!ePezMG0G=_W3**$ zSkFt|xr((Im+1`2^)?EQV=n2^eMzf{92!j>S7!M^y$0lq5oSfvBFGTa9G<|SK1YHC zpkEcK%%y1pbIJ!f6q5+)8k~5v=Gh_3e8tQ(T2l_o7cC+fi!nLC4*YR}*VUH^0`^sz z)B7HvNma~M-Z=9RvxZ2pJ8TsDjwe zija%!Hp_zGkVTy2vRCVLm$ z38&19Q{En`8!+dDzPa6uiz-N$;q$i_SM|P}-^QU%y8SvZm!cml-Hb!M)olMND6bWH z)N1+u&Dx{y-uTo4M8M*D?mzV71@=w0kh)hv8o|R8s-fHXqX_irvnrz5>S;-UnY`8? z3?~(AoKSgI|9KR(?#JT9nflmS$eQ%`cKqWPXAU16mK~-5Kt&7?QmfSy2DDc>Si+je zzXyA?a1Iq--TZm{H|$&HoJ(bH{1Xh4R!_#?^aS$?DydW}ClH$xb@$C}nUHLkeq0WD z$Z*h;DBNqJGRg(+zhTwJZ5QAk^ew3WSNuelO>F-71U@2n`~CsdBSD)~>XitZ8YC8Q zW6SFQD@q)yD9GtbSWUo*)Fkt6 zn4D~>wTde!Hj*rWp<_S9;a2rh11EVjiklzYp$`2$ytZog4NysoX<`xj2?PR_n3EYd z;i&R;K9>4ab;0Y#!o4B;3@504g7n%{hfif1P$k2CZW!!E3{3@oJ__Fr9ojr8ZJjXj z7bn%ms)9*w|p(^hc)+}@`~9ZmU>oIz%@?yJ1uc~i1w<= zz8-=!oq;PX&LLjRUU4A_i(8-Vum}zo3J7}S49M`y$BDQa|bIdH1PW{I!j;k%=;^zb_2Ix#tV$R$mW2~Wta4)Q&TJo)}S%g zF%8wzFAxi#3Au6jW3v!r>~>XbZR)_MGH7LNyKqT3i@z&6=_%<#wSPK&cAc;1MmMbM zjrr_4T4q{wPD?xkY;!o^53~hGHN~F=204QJA-KQD$Sx#ocH%$Sn0ZrWqb7a1VNIMirq&+5 zK(b30d;VwAW-V-9%TA%ggb{aMDCeovct6bc2Gn~1iGoT#s;%Qs=Sw*3rr5_;SK!3U zSmVtfV`j$wbNQimoq%>4rO&R(PNmwtBQ(7rJ-=y!x_JIEPHO{}z9iDTo7L##*+@Uf z`xPBVb8ynyI-h++Y^C81SeOY|SB2<0<9Yt^YuoUCB1R5jt33l=L_E(%M6;(0YQc(( z*B=pIR&_Tc%ql=T{(ql{iV!%;(Qn)Z-2>g$Uu}zA15({r|H)9N`bHiO%ht#o+93{I zaJqn>b3NLt`ksfwIsxm6T_%vMtI#gTRn9vXyjT}dAJlGS=VQfl{|1I^G6SDQ`82e5 z-0O3rZ{VcV$Lw*M)3b4Fd_J3-O)2V#@V4f|S$`hkZUsQuU=tncXYp3G0jMI@y9UGA z%trrtJOYZXMp9*MiV*Jv5k{KWG7I|H<@n#1gS^DdpNf3^S?@>R`$f4lL(xO|;D{~E zw|*{{&l;gl>H4-rtp^4}5t_{>K#WvWXCOIx4{d|3b-?L&qj3hYn&LuEo^&+F6#>g4 ztva84nA<6R1&HC73j#NkOB+vzpK%Q;*v z+B1#S>jbMj-NCH(wc3={kOeJv(?Eq5@G5 z0XdV;Jp0`+R%QZp`SIT3L1H0dcn+)Ru4}Q$l{#T8)+0F*8dBRda(cuqLf#|Dz+3I@ z#}1>L-C_R&FTnun-lEB**CZu3^p!hwl<5RMr z@W?Z}bgqiYN|~AMkc+X@Q3D(iNEg3u3MR_`fX|CAFWbvEppPuFXQKwH_6Wtw z+KCRPkW(7kYe5VTjS>P4&w4Jpn8ZanxUK}Csc?rHdE6E-%`g1J^#NO+mEmLy{P$%% zF6K^c1*e}~t)T7iZ_VfxSKcO3Tf0amevSMSy2U6+k1p69Dw(d*Umv}qa_Q4t_b`-24AazjW!x|4W z5o{Y` zG47ypaLDT^XT-3#yC~hehU0EjwqEK3;QnEICtyokK_w+;?1R3uk+t^#ZVdf(_-=q+ z%Wm4|>Q^u&tbMGeq!0=cN^`71TO7*jF!5{G)NwJQ0pd9mF;pN&HA+ud$J;UXVx|p5 z-H!R!%T78r96XPH*8yd4|3>V%!EqDz$I#lA1trGm41#N`=B}bs_1DX`r4#{wGi7!dNMw5fVSH`M^wvU7P;0|5(I=uR2WH!LB~Ot_`PgiJw)CasWhKmhhYvdKzY<<+`k>*adB2AX}Bik*5GOIs_Kt#KLW-36OF&AUa$#BDIE^GkztdYVw{ z`x4>(w1gUuCz4L-*JRjiXne^vY*; z(RY5pUIRIVnj3|F>33*RLIZGr0LtwBNxRv*!1(ny$~ib zeEqTYMHOG_g)~QQEWB1qaxnFn`3VmRI4oRx$jV^}y@IRN?!UY^I%U{v_AUJDAA*M= zH}baSY}GA7xNiwgGpP@m`!}gI7x^z;D>Y2f7AdyFx@g_+?`RJ=H`DKt>w0#xgQF4` zZ1vPG_;hAwi-HOC1Rkvv0BwBRi=E-AkCMq!IaYB&yzxu;BJC%P4ib4sJZMmnr*5kz z-d?cabZD9e+7k38)-3p}rTbdOsx>m&!4{i3vC%;p6!`O=YEMr_@%XXiMp}eBd4LO7 z+u2Xs`%jmU$d3uG@MLp?;xe2wQ!NOMBug`5$akRk)K;I8T9r5CM6RDTB)r>Q9??2PCuY6i&}zgz{EXspHij3Ck3X3-9rVL7=bF&KcTzCB2pX zy^&5KJc_V{d-+@uK@l~xcvKPeGAbA`iS?HN*#ZcJW2T0HdX zJpl-k6~NiDQhv7M@le{i_}%Tfnl?NjR&U05r-eFANy8E&Aium>~#^JZ>OU% zk(Z#_qF8Mca{IJ%W$D>+m~q_(#McR9vDz}=c9ItM4Ht&evp?`%idb(1uG*y$%H_J$ z#!appGvj^qS)M`O)cJPaefwN6lR&XVG5(MVB(_5B=0fONB}1uw!$~Q`^CBj5EZ=uL z98BgOlafFSMmuj?digqtZZf}d3yK|%>MBL2L_*d%VgO2}!zB0a@FS6}vfa3%=DFm2 zmh2_()dR<|f!4kPYQ)o3z=<{QvvVXT5j)e)J9~s0%v4oZhx|A2OoF z`J@;=*rY)61^>>_D>zOta65`68HeQBlUuU$Q4P%mYPY;)!IbsvrxxO>sGuRiBvfZ~ zekNw!U+fGUSdY?c$t&z-0np%Zw{>7Uvl%ZobrRVHB-Pu>I|{kjx69by!&xUybXxIi zAbSv(_dF#1n#oP7eD{-s9tqXsTseL+6yIsIv^wX+N@?b|Evs7ta#Zd9q0a%I)J?)w z7dX`5S?aqCTUr#Z8^TaWGh0M4VS_=nfo5e5^PAQcrykefqZVY`AUcp@E*G@y1m!AE}OGKXxYCowme16sF@=I zhr>;;{x2Htf8x5SOG^9`uteM;u0jLJuiE&7METJS_vJ)}pBNk&DbJZ&V^N!%hMh)> z{>Kk?{^)0vWt(E=oZSO!?RxFEpUwd+zUvodE|||5yUBaFeXx$#+-=-D@n~z9)b5>& z&Jvfkhk-ARNF{Lmt9zF0%AO!M+?!2W_?&XS&C&5wQ?2$PLg`e+T4tru!=T>OdptbY ziLwY=GLDLY>BS1%ed9LqZVcXpdsTG4M*5{)9+}~Ops0lQVuvA_$~wuuu(03g;8XwH z-<&k&_qrfXXLL~cate-XGFBkk`)3m?b5TK?GsvSLB|Fy5~d86M?{Gi&w{ zg1oNMb`J3}4AIZ;NAb{TsiYqQ?7Tj`dFtxuGEXf4{mti-|JJy}#|dGwgx0XV$k-Md z0PzKN?-|9i^r5NhuqZeFG*H{}@J$VjnQ*-Tv4rec5g+?x~fQ5Y7`) zs#wHGY>!hT)ttDagu{MVM3d;oWG44nj+g?eZj7a|>gY<1b3m{I_;rFVk6W*GY*96a zRfqO7yTHyxROm+wY!1%Exim!E+3Tgp@wx6+<7}t=cHDpD@yW|yws9k3 z34+e8F>-&{6P3UiaY#3CdiW*|sFc(96RhtskSIY^vrxlQ7T&X?8)3q18J3Eo}LHo6G^8YRbt&dZ0n_Cz_+RX2K4%` z9Lhnk9l6~t6-~vO$jL|f8C3W&=&11QVIWrraEAcG`H%~jF(xt?ZY{pngiI}))47);Op6tN0@Z>F@58F8_`FWeeiZ_VpCabF-_wV878fDKi$x;Rrj z6fx|$P;F6w=*c<0vn7c-jlzC^Rbaq388#Dbtag5mC+)TP&R9u7=k_~``;I6Hyq5Ee5&VTO=VD!nfNVi5a z2i-$*s_U``Xu);(UCAUT>LMmOJPljVp%3I6jM?%uKB9!SM z5w$9q#H)0W+e));6v7mE9^aJGf{6X&jX}4y=Jw2&zo*3~jDH=C%-1BJ_{^~vz&d5y z3QsayV)Cn>jCg7iS6o2!BFi%B%ih;_{k&{g5BsIG3qtv}9?R9gx~=NaxzjEK0?Y8V zvE`mWH;L-3x3*2GKJ$&hEjB49xb~p{tmt%qMi7wnj46m;Md!Gym(J2&oea91tp^|4 zv;cGqwo~8Y$8_xM@A34TO;SKoS9>i+qjIo2Mbpm~)JEH;-)G83TvwA1%L?RqdF$Gj zM>fjq$N-|T8VsHwu>(ocUUC1!(uVIt$n(~0G>4_^7By`h#kI)KT~!|6tsQz!9uJKeG~I& z{u}Ym3c&tZ~7MC#b|htjnW9aVK%_D$;e5-cY&{yFwQJeMmKavgYC+{#@D?VXU* zSFxbpjzy8Hhnmm-&!%{%>;_cbEtMR0;b;BnwMZ051kRlZ-~{G6wmhH5Qxt|0`a#?> z;Z^u2FP<|96aP z2?$Lw&15}ELpNU@m}`8!h@^GLfcNtI__rM$O1$w#sA_4E7>P)F2^&L|{yj$-b%?-R z&8MN4=%SqCLNtNi^nG>PyGC2&m8P#QOijH>*5@`9@wk#58JE=l!<7C-p%CnBve3NH zlE@aX;$Ec>novG#5ix)dMN*!FkJ0wFU*Mt>(3s#UjtuwLVmk`O7lYiULy`g#IMTQ} z6;?v9C0eo7nslp{Z4ieqV@IjaAQ5Y&xdS*>xy$;{IJvS+Nw17w-oU`soG(f*RRf58 zcg)gnwt}u?Ly5;KJ|tj*sX1rUi`)x;e6t7$e8IM3B3QT%Ns-{Rn}tZ4hM&w9ZTd-nEz>0ssnAb2cl<>U{bWKAOyla7V=zwg<+78~Ws?V9e1G~~w{k|ooY$ta^lCUW1U zKFcU)2g}F<)HO-5z4h~~kiI(eu(*t*Z*s-QeqJ-J^m<^rbA;D(H2RQqhfnePRUm&+ zCjDmgP2RDLYSyPPxBxNuQu)o!aA$sufRyz$-l34)0qkuRc+^p}!RfPlYglzJFdk!` zx+`CeCqtWUqG9Lv6a^(-!XAq`H)f#xZF&QwZNSAfexg}HU#cO&*q?8;H>WM>w>exw z7`Vt$4^uM2zmcqhGm;MPtxfIkaH8x|TG_e2*Vi!(i+EyIERm4SXpCf#5zlt>f)h<;G*G4-ZA_HCs{^_-~|5#z3?0cH9 zn(w64RJ*_4+#fpf>Zp}MH&8JLo<+_LZxCl@zE*Rnz1VwQ4Fl-Mhw7XW&=c-JK`Ike zkUpOg(dV>cP$TI_psYu)N3BHxl{XPLx8cDl?_odDaDYhDQWUycwLdq?@i?8j(=6HV zx-Eh>Rno~M8X@O|zR6#FVSB>8{oJ2lfmMe{-n>kzp7irs76~7tYLvCqkC~sRG(Uun zH#?-$jRH_}HFj2UO1`?`7DeiJDwMbW^5y*lG(A(FL{X7UBCCO-F8FWXyIXfnW9Zw1 zzTltC&T7a<5p?Sk2 zzUg=WF;@m+7{3oaW_YueMyxTomsr!RF1WkD<#2|6B1mPPhnUHKT)4-rbvm(n-}w zquOg-Sl=J-QAZcOj&Y{V>j`fYT_V2SrlTEB{qa>{EW;P}yLRthYt`j*3$ETdCrQpy zDS>+4m(OZDpjUOs{dkw$UP1M@^7 z+9cUG(>ilvjHk*sak%a0TF3dVvSZC#A^I0Qhgmz=XXi>3cM02n`?+cjR#ztfDL`^n zU%zm^0FH3p&hfnJJ#nu;q2VRzicBvC$-dS!lE4`!Gq16obHX8&*4bDQ=sqyFwY$(i zmwhvi6LTb9e*By=sJ5<~$h3H(cEle-wMI|gzGz5wG={jeIsAJ#`vlbD;+01guQf`X zpb5YJ;f1w2im~1Fu9+OpkVP&%I>}eaD@M1Fj+PF21nzuV3li{&sJc8rRGDQOZ}eEZ zr{=I}&5}{wihKRxSkn`E{>xT%V3kBkGb^&_cROg$R+|Hxy?u|ID)dL%p>gN$Fttdp za0uI;sQsR8Y&vFHelVXLq3D`_CHQj_PzW?*3(h;ER>2+UO$Vr#^DK03HwWqTPWmz# z&Ypq40d37kA^qb#JfE2D)#LObN5N+;c<3^c+2`wWzn|DTDS2zv-yh_v^{-Btz$pwq zj;y}?n0cH-H@%N(G#4CEn(#ILmQS`}2=o?_gAnqB>wgB)SkbE{Ar|uo{u;fbzqxSn z>z2P~Uo=d9CRC$}5!kz+`^i?X1wHWc*rakX51bfGDAsfn&EimmU0>n2{=xqP7rfk) z2~CQB6-Ov~$P0|M0QBZM|7+q;_+fWpI%h7f%JRkM{>Ro4F575g4mi3l>ubv05PHK9 z{Nrxls)G-*I&rMXiow1nF;M|-J;e#@Yn#sR;W}N3(qDp`+&(a9gEo^uIlEKNpbzA75{?IYs zM2m^!*q?B^F{!JA!@e=RVJ!ej!q#vX7IDMquP(olH>|D{41xG7>Iq{{$^|rO@(??; zU`ahCWMZ^xh+laZCcmpWi>F*kzNU%KHeM%qWTK7~YtnT%z*VihAHS4D^*k(UJm326 z6is~HXK`w_^`7)!x8BX(rK#PB;f7`uWR6+FB?uPYDg*fvymAZENM+MOg+(X^j5yEJHvOeEmWm zatG8$uk}>RB)Lsc>o!K#&S35Rclan`a5%vA=sD*a_(+9e3 zCG_0vtLHnoITGlJ>zMh={N0a(g)BvXBb3$#D2}vTf%)DgxTmv{cat2*{X_0N!cfT; zXWHGPe#ghh;}NT*W@~VcoJZKSNEp$vhhOy57173cAc0gpL)M+me_X03@4_^xW&Dw5 z;XV}NPg{2|6^HwKmB%|Nm|Rj>N9ocY&g7kV0zN$~FYfr-UdV|4=_7_cu{`eF+lD0M z90SNFDWHu_8&$5n64(&?(EmnNU3kpMiHc+7~OVM{qQ>3&XN@cq#ME_s;r`R9SLe#2-)~|K`Gy+dyj4h=O&sDrAN0U z2bXX-nU?Gk%aDbY6B}D8zNUc*LPqk%Mj~rJ#{t%qwv{jaxCbV?Y8ffC&KR9_E>%ap4PP&eG~S#NyNot^_h}C z91S#dT}A*LO#?jxlER;JAnALx3IyrPejx)eu3vICdliD!(u7LLDBr*`z9J$bGqK)X z&;q5C*wk9uFzERC5%rpwDe!N{Epzr?7j}x2Tnou^= zwfLEl8=JY?GUuZd_T8}0!34p-CyXJjitLp#R8@kT{-aD8m-9$FzVzWkCVcoxK%4qf4>gWmY2hs} zktmpld86sc!{R$9m5@a-txxNyycfO77P_*!6)L>)gZawI?LA-9`0L3h*B(?Ts-{M4 zYWyBYdj-tOee#W38CB{Wn}$iw_QXn~yhITzT}+(>%eyA)Qp)#fFH!oXgmcih-*=A= z$Mieow08ZAqjOuUH@`HvnwAO-YU;?SnwjS5V zI40ALwl}aD>(B!)qn^x!s_z)lK9-;R)>9R&P^{tX;ZgrY%t=9BMs4`5Gvwwi|CH~F zzR*$GH{P{tAY@iCOqjj>!QT&G?wDl>-v1^?!hjUp$-HS%*C&{mRb<@N*D!X_8@W9t zXx|9V{FlIP5qz5o8U3t-rp*-03!~*wMw(xZ)c551#F3Z47kcBL5@*=0Ec#KM{wBVC zr@j2tE30X~x3Fbjw=d0DSvZ|+EQI_<$eCtx*<>wNe_iT}^%DID2b6{gy$a;VlMaj8 zrz|(z94=gYvqVhjp2WvvFXyC74I0YQCdOZwpTGZxBkc-q?3pf_JcP^L9D=wAEtU|~ zjC9P^7@NynGwT#>Tfbe6UTr;T9R|SJi3*|Lo6#^DoO*7nQWl=HA&geN^uQU^-ksmQ zDw-5Ap8sE-$q7a#nv2)NgoT!2JP8lP$n_8?;wYvH%6m5kyw+kuA6H0jb2X;82E}U0&5|IYPpdAOL-u6zGzk` zca-emG{aVxV086o=VqpBnKO+-Qt$HG;?ndUx$-I(kxwQ>k<`;TTQe=xW> z;P}io^B}iQB?Rq}1_-I20ZxoVW-U7ls8OaED*OU1UKZukRFQ!Qo+K;+> ziesqvbavG{^rf}pOl^2+5{W>+1gP{irmXrn&mxK)jd3E5ZQy=x|GnP$?^)#ud|9&f zJ78em@gHV>!pG6Ugl@Ef_mBoy);j*ssP!p$f#XectuiCrlnNV_RV-_NdjhF*i-YT3 zMUCC9tW3^3%36^D&a`Of_6iu{7X#?>f(J4M2&(uNW^nqVXMFhX@ao?n^kG{IWw&%S zzhTIi3O0ee1$4YDz`Sfd+81`s!&eXBE-l#pVK=a^;y{zL)*sTUFz;Snjr|428(F%JJFHfV=uR&%%+vuugbS@@B zS*p;(75Gj6`Fen6QspcLUDLj`M3_AHMNsM>&!lUJ`&AsG2UFmL&`Gdt!*%@M5=rUgR<6dn#bSk z=hf=P(YnQbL<%#`di+UW(_<;9w#IM(t~iM4H*)UYaP53fS^R2%+I!A9paq>~kc!!B zh`K^c_c+y8V|nY4Z<7lo1q>(bR1N=39+hM*>hbM!A?J}MGT@m@!syJb8ERY|*fnj4imZk$m%r#4V8_=4mc(a1B-FTSCFmg5 z6&f4p$3%Dj^n=)ATzb?j+7am9orO|&Nrj~Cxqi<{_bUa7bB~XVR++9T4rko+d6)ND zl|NP{^tWraC~uC;{5Lqcp?VS{JJIxkBS;s<`-GgcdZFK&;{)@c0N?Ty`=CXP6G4qQ zPG#KunIlb+Lk^ZTHO4>~%c^_;+koRW5CBlljq@FrxttKxg6Cr*zFr~3>i?!2gF71{ ze;MlH6?V=x8`9NwCOjc^Yxh1?Yr@3-@NN$0^_%o%ey=EJCExS4Y}|zYe8pWIX0Y-c z{El(Y^^YCRVAfG|f#)iE>uSBLq;Uk^|8GE)urd|e7x%a4XM#jMOk1}JQ)yW4xNSIH z^U=B8EV!ItF(GLx@8O>-n1ItYw81y-kolyX%+oo7`5yPd*K=~vd?zKn%S7IEFfNr=%HXDyH?H-?|>&*J&{jf|5esDVHHtN=wt)g+wDYSsl4a zzjt9r;r~sKf+sh{rDwkBO`@Cj{;lgJ23hXDVc=f_OKE+g(^40Gqq!-UL!U!CtXLp! zC@!V^PMq2p5uLkSZYbZtGXOJru}s$E?n^@vLI-f*gAKQ@`6T=4yWzOYud__+Uq!uW zVAZg%fl3ZVfq&rgt_;#P&@%`bK&|`PP32UzFGPz4W z4XyOXvlV|P7amls+EeTY^Uu8nFsQ9hU*4m4CxbNs&3@-YZrkP=bLWZU#rD7VFoHbJ z`Bs{~i^hLXtiJ2WGtiS?x`TLA?dF&cy>H#LC{5?Ma*IqR$fn+YXE*w;#ls4b2ogR>R-1~7p2aC*1r%NKLBvNqzsljUSH46EhPALF$SnoLO8x|VxQqkKo8*+| zLyrT>gc}A*i3n3reDN4>v%$9K{y}L>%y3(6(6sNW0AE|j!G-!4!l(+N?$`TXx6lvY zmOJvo^mI8*69&I>^MCpqE?x7z2W|KN+?E!dFrl)h+V*YRJjq*W1tD|nX!urD-!2e3{G*g_U*E8?nNV(t)cTBjFF z*n6XtbY`2!nQaeB>7ULX@we5{VffqCprt*D&b!X4)PMPzG8;7GIodkqX9;R6$BQnp z>Xc=_)ko|rylJ?$I72BF=8>AS4!Lp)V&%w5Q^ETET-mAyOXn!Z1rCRve3eo})`E~? zp?=awP1CF!|B25)+c$&{<5oQNfGmbrG)#%F&EA67+MZK#r8+EIh!T4j_E!Ai=N;6w zUMq%Y3sjJ zX~ykb7hLT#=OKT9aY=T41*l3x*0;>|ZeE*rr~Sp`)RBL_L_={wTQRSs7~5f7R*Y>f z8at$%4$pLxnr|ywyZeRhqFUj{seonkgkX`9P{wCA8{Q9dxGw-^tzWIB%dvA#V6acP z4V~{NS`Zn>xzgMe>e|bKOX|MLz4z<+D!m)(gO-RUJhmZUHaY2+s=5NTx#XNj0s0DH z9FNs40gU+hEci+|#QDsg_X8Ie%NCT3nfp792m5!luo5cz&4+tM2=c2_$IuZgK?z?HtL5+Fc zibB@gHrL?6&F*&Kuik%LY2!_!?n#x~0F~GO<(}n0&%)1i>+Eg*6AFJP{BM|d##+HB z0gND;Q9=e@aAgVR08DP)5^$nY<+>c^kRQz^&*_OAcV$)WNuVa0vIsc_kFF0_;Jk-( zF=xX|dUUVhm(DQ@cOFtXG6&jUa(~xF`sLH5K6<~Ac}nvJBO1o_?%z}0#SS5wMzUe! zKZT*%JvyWF87*IIS8ffP)f#>F>2n^D6xVeeE%y0+_`M%RtN8~&*P(gKBc$1`b=a2V zH4f#L5Kmzd4*I(C$P8m^VvG*kzNp`=(*RQro~}`%E`7w0#CDj1? zDPnaVg$=eWk<_^{P+M5uNX=3^1>;{>4S!SNWa_Py2h)PemI!wfO5{ z-}SV&*AoIdeW9!Hm{&oI66S`Mq`1&uP`Tu*+`1x@A1$Uc^h9vG+Ds3Wx0W5ge@A^t zTwFGBVqY8h!)CxzHktR|7)EoSem+ojGYli`GX`7I-cE&4xHZD^8}&Xd&STzU=JP(9 zM!>qi7!wj_2RCJW^(*K18(!F*rTc5HQ3E9LLVZ#Di;u{lw~$D-zbyQwuX4}oOg5T*pEESb zVUE<6NqkHsWT9!)popYbt^_FS1x#F>0~6YH5P2+jM?Jmn$U>l@CKgThH&ehh33$$Q}O27()s6Dp{Ua>SY^O@k1JLGw__#7Csv~$uk{A!+2K9UO*AE8`3ITT*NG)!pZhEXIf;KI*$-UP1HV2ow9UpXbmKW?7 zevg7IGj|(X8=!v|Q=DCKyIziR^;bI~v<;2_N$?Zu5{#T}+#|-d7@*@`*X}aQKP(6+ z$<3g#x9PLHbYOSGCZ}^Qtj@!A$8SNWN{9+E%B62%SN^^U+qVw8xt`>vY9?hrYuWdCEtVf+n4ZyPo1^{eN0CFgDXIqF(M zu+I?;`|=2ZN|ET#XR2zlcQ zQ1?i!bzgO#^5#;DBo^0m^|i=!b`;$xegVPMtf*qzPmde1(G4L*2o#Izi^fG}Jw?ic zq||H3eu`Y*`tjkjX}>kjd^?N4u#A4N^XH4??sm9r*vyclqwvSOGKcaVAG9WqfCyMZ zU@Z?P-`Cg5Ov?i18o!XrFmQMmK=*2lO-ywe)M-{lvXhSqfoi$Aq8^Prv$#OoxdYK;&vLpi9t~;(iR$G-V z;)Y|5Kdg)XV&!H}TApj7b~cbPXP7S6(WQlRgX%6`AQD~&V`tG-eD;el6o3^pny`88 z;yzpfb*XBTQ?)k{oBb|OiZv`hf}Zo^+0&gEqEaPo8`b%Tfo^7Aq5vqc`V|0<`*#b(MheJ*ur1# zs}TNOO#ZY85}bDgr)Vtk(eoe_B4C#)ep9JRF-^&9 zC^ulks8w!Isu|RPbe?-qh8ky5?xT#l{_+|q(%{Xv$fOb(0*-p^`}x`s#qZxQ+nU4o zAum#M*|h==WP%}fVda-~EgcqEAjy!8mkaq%9m7Tb*LjwUK+8AB<)}C0M?xb!mZB~j zy|FR{LgaligZu{}K)HQRO$kh&0REuoS2=GFMzvS*(!C`gwjGnAWupgcO`By?Ea2%X?49FgjcD z#H^909D*au6-Dy};vC$S;5^F>dhN^>qYB_@!Kf!u=$pYTgPQN~%a75A{UM&EzM zw-gkHI^XwJ;(QrJU0f+|Grp7%eM}QPVW7O2<46h}zB47a(jwZ>EK6qKG&PQ~V>;MpHrC;Twtp#cuq532q zVQXwODNd@j>^)|g&UAg<84rJ0d)Vi*-icwlS>fZK^A7D~P4H7^#_m8SGSrdnY;{5i zhhwSFO;aDP%}!ATlxDtMaGnt!uHMy>SE;00%?S)`UH08CYrB%njAg1{Thq-|3-UG% z?5~@XxOY=`qUuM{h1xgOY7}|5Rp*S4AiZp=hEA7NZQtS^7!~nxTY{s)LFI!Ta~z3` z2b@ddx?gc}_{|R&{z>2{lWe^*Jzn;-e7g|t;XCR2w;Dbt)&G)d)4B2${YBZIqf%eQ zV?X2OhF)@U|7GIX(iSn9+xc3jqAK136F1$6t`ChD=ETr{s#Pc1 zZdheC+<(n{_l+Z*(lGfIbEgvis$WJG0Q0Ot!)rXm95cV&<5VfAy5oJM;q&PJPv*>J z)+?*V*ZxV=Bt0qR=LFlbCcQm=G9SNGJc*0}{TH(w9mmmj@jHz`L1`QN!6WuW)MMyTj?4E-|d?Uxle;};62-XB|* z=b?)_50jNs1dD2)ItGfCqb)37`pwLTCt9`Q2Vb|so^3Vkzr2B~8pP&)cv74px&DFE zGnJ#*N#{ir0A86BtVn@z-cBd>ywC)Ca^!)Qd{8Od`s4O5U^UW{6p!jPoh@e?q7GY( zQN|F>j={rMDdh^{S*}a)i67GA+7lH~+=Zrl7A1wKYawXcKe*ws2|C5oJ!G57{TaL}+ZjvYpbXCTG zGpdYH9HYkFb-9xZz6$g|a~{`^15`n(3Uc#gS>oO5wMNNeo~K_2K4yhKmBQ!5~I6{vG@?k}GJfWbFp5QePWCZ~H0m)}>M zR`yRGIYbHUyC_Cg(Uj;~SkqpIu39NZ#cOH}6l+Qvd;+jVJJb7)e3Y=nT4$l<3p3`M zJV`JN<{zPCmUeYFC-2+Ub{w>HGl&we&naBD*N5G6#BXZ&L$!5A2k%B_1AVnQOv^pT zDcH2PM=~t=N>^oS&5qjc{pRg}CT&t@nzu|pE@t-2N&$~#E@CE{mMp3ruBi72#;rRp z8P>vlsgHKgAbUvq72Kx97NDE;>(ued6VYQueb0@tX780p#UBB#3C4%)y01RhGz6}Z zXb}hIy0S#gp?wrmO)gmST-W>E^W48UxsJnU>tZ^ikEH9s{inTwAjM?h`t(ip6idXo z>26`EbvFq^c{|6krIUi(s_MqTt-LYrKEZr#08FZTCK=N*4B#4epB&}=jfXzq%I@i5_S3FLM`@74W$C7hzY zBJNmom>Pt9Yb{S+JG>R|-iT!xlN6_3@sYL|16Fveo8Iru>EsSxFT7DU@r55!HY2XXMbqbkCglu;t)4rl*w$Qa5j;ne&rtQOYL_d zm?+^++jF6{sqd~`4a7ay{KoX~zEa48tvMX=MC0<@q#tZN|3Be*s1(%s-+!An|E3L z7MDkduZ&~K$FDEqEzxd91?X~Ko*wh!|1(zz`AulmjbKS0k(M}?8DbN5xjp!?N_79`7o<92QVk4AZOw?JJ z?Nw}oRb;;Ug+jq$fqtv0H*)bH=bIwGW3*-+21K`HD#+aW=TIgdtXwbP0tg&9g2VrD zMwidVG55J5Bf5ev;Ep+y_htj~FSViWuo-}_V&7SI8@{Pr9oPMVw1NrwgxjxJ5BT~8 z&s&eR51!APEJzrXwTBx%v{kbvFia`xW#n&h7rxv}Eh`KVxp_Bc=?Bfcks>oHeTMBJ zmu95B`)WG5mNt!Oiip1Gz|DmBv(E#uVb-}`ssoTHxzx=MGR#*H`tMk{26D!K;?WWH z)!jqP%}X;)-}_&F1b7OqsV7^J+8M~(84vBcwUd8>1;%i{?7NhY_>&ta=YKd~&npen z$bvn7ghEw)WD(ThEEmZJ&TKgsn96?EkTsR6o5s&1xd6&k!%XVEiYc5g>9OLz>n3}F z4|-#5fv|u}-xi1xJoP1cQ4{AGNdER)BWgH*gsm4->Fw^F_px53#^*HfZ(+`NB*_%m z2WO)eGC|RC{xN+P7j(R_vE#n9b>{{S!FZ>V@Z4a;J1_^wySJF_mr111aWrHV0&M^d zy+}rE7|`$;BJX~=`Q)JBB`TUQuZ~FV!D<7ott1WF-dfv#T3clIV2D}@cQ_-HJS4T9 z6Wu2Ub=x6E{f-Zh{uX7IPUOLTIGF~4*3^A=E17xV<~kT2Q)KY|B~E+a|1!XrHp=4U zdw#ob#u_*1Ycz%qE_QPFSL<0ZJ9u3!lzGIqmQ#r(vWtUKWgs(9O4TS&M@C(aWvi=! zrq-pp8pSZ;FEB@#(u|O?8_!u_G49E7_`w7EZ1GPQ!JXpF%ZEGGBy#1{&IA&f%G2Az ziDn3BG>WIp)k`TOTBWzl;egsI4KE9ZLaJE)0^MbqJ9db*Csa6`;D?VP9B<|bO%zWX zxp<0Q3jYI!-=;G~ZmSKaCv&C>A4Rrxe*vahzY!+uUoyRWTK!W}T)PrwFU;P*VoFq0 z-CmF4QF71NC9bnKLRyzwM%?R0eu#G~XRi_a(J2%MZne3f>uo`KT+3Y^$a9Cl`CHDm7=z^KSW&h%z$ z$s4{HCbA18Q1St=%o&SxaztqIOx=@^@?)mAFzVR}6wi-Y$cZu>Re%-46|2Vgd;s|f z9-i6OOUXZPD^%a(L=|QcZkK|?emI7%|J^*z=4T~5TeVF(d0Qgs#>>{_?$BoULCoMi z!&U2Ofgec1kSj@!xyY|id`UlaO?VD!H&9NlqVvL>Ds)GhE%2=J27#6{!7c>X5ykM&inxZ^T^qxL#B13Wm%IQYHuJZp!>lAJVU-S zT^=oZ8YMO;>_(b_5%rsSw;1M#g$?_Ab$BsiZ)0u8WagKg9#IAmKuDaK=SH5+QQ0}xw;{LdRc_gpICzf5QY}FDoXJgcQ zEJ3~z_6^n3=MO4BOh`Ejeq&bqX&j{m^4SDLq=w+*~(zi80n7jRx+;JgA?pF_WK zK4dGr#G9^AG**s<^V%=>Rl3$O?7Dfm59JE_oanFI8C-i{8k2e9DHAP#rJ%FE!kN=4 zi^;)*G>$tT59cf6;i4R{i zz1aQM!uqpllMZ{vo3I{n)4}fDVXK^0Kff>y+0rivEB(wTC;1*U$TZbSd{DYP+YNpp z7qXNpoSypq%1obqwLSY)^|7oXEiTDcd~LP1qi?G%FyGL3U2TB7lz%#${c;6ERBaP@ zv%r}kg8NS-rBQ0*{8m{M6~tdJpmuq-$Rm1hAieK>my~-PLD!P&5WABOvFRz>FZV!x ztDH33e)f~%k4O$pzik92R;m1wrClw>&h@4$TJA*O8lV#wdV&{w=+CK5=KQtK#rxlS z0PB1!5VF)2X?EX5apU|XDNOAvd&d}<@Abew5S5JDZSGdetc)tT_(pb-{RWCoAuu&P zX%!#gtYTBdpH!VRI?Epdzug+!b>~hWy${!zQ(yqn=~n-r{(1q*d@jWO=ETX9#v^GJ z`#o$+IaoWqh}l`h*&Gr*6oT#np~Mj@XB=f}bR8fg*RDE57*LixgKZjC>$`421~hVE z)(plJ+71(HA#Pb{5f^L05skO&tnb%x#$I?9ZgMyE6jWV!&b#y!)9>q#jKrVr1uVBR z9mnh_e3lbmAMv#)D}opLyfcHj|3T}DQ{)SmN4gu8sYN3^TvP{J^x6~61)PgM&J67% zXTJ{(&VSqhT5!k*AAfo;=Jj1QB?TI{4s2N!yeZ}@r-s#ru46&RCB5*&-vnN>GBWC6 zMRcIg;^p8npr?%lh@eh%v4pfPD&jk>mJkbRwRI2FQq>?tjc#M4ZiY~Ri@Dakaos%8 zIXT?1duX#()=QjJDOAM*OKX5~p!?+PXfp^8FXT*D>^e9dyx=D|bn_h__^u&aae~;k zRtdP}n)y$npQ(M0*1ra?D$JMY4$DmzjFJN!Q7+C@e-ZO7-OP(ZH@(`9=SH##5Dpy( z(GhoTW6(MR+?;+pod_wKnWvn^JSUzt4``D(GqoD^8`;>*gO5|J%;^epcqTeH(C+DC zlhVzb*#SC%gM6<-P^z}HsWkEN zMuc^MOyo+yER#d4jo3SZ6cgKigdmPK)!q0s%-!w`R>)o+KGdp0=j$d$?&2dMG+4^;b?%n2BZtj z${ue$#f0;FxqHk5(Hh;=GQ2IBJC1+vEHbWqsjX6rHY(1VUFeISoUTPc%K?ZVq;dA? z`ZJHw=7}TuO{0nkfCTJ&Y^!L`^sN$`qgH`_5AIh-RlRe^DHw#^VlnWOrx&DdyY8EVjjd*M2fj?--9pJ6ffV)(1$L=gS;s zydtB?f!!KE;8`601AS=+;XymOSa+Ft+@i2GXg19f7^kNQOD6{K6Lz~2{#Vjg?{jGw ziBl#9>~V=ki=07ynm@r)ZzI3Hy_RSS(<*w|<@d*iX!Liv-qCXs^5#S(du6{w!-CNz z!FPPslqp5-)bu@GyRw@8kM0*N6&i4?cQ<8l#GoBj2Vq%G$p;0a>|N3a-X*m_>tbVm z`yYBdn{(xk^T6CLaLt5X&mcjNzG4)NPl@ftSBGo2ieDJq%zUa-!-J&{rr>3=8Cvw^g1RJ7R!^7~?xv^Tc(Q#b*SHntsK;DDPOWk8x0Dhwns75jHMhfnKRb; zO5K_m-zFtwUjJ9mkgmsLVVz>6w{aFHT}z3Coh7lwgAc_{S1BS5xU>`PfyY@tWvWO5 zpN1N!4i~B}eb5eIPwBRDasN~Cgx{Xsg2TG-HZ=`^L2;ykYBv`X37|X%1P6vbyc1O1 zk71@*P)y)7*V$u+b%WfD!NP|LVwkDGyMsgv+|=HsV(huJ`J%-5$Zeytp1_nGkM)qj zpuvPQ`Jg`;q)@>diNnLJ#THuay;-*#fBS-2{{UDbi*iIX2(o4_h_9yb@<`sKN=u%} z`riK;@u}FwKo9#1XT07}Eo*_y>*Gpp!CrE5;5QZEZJi$yYf1iv;VuZc0qs_*PwD(8 z5oH82WOU^Tuo1)OwfqQIb?7cbi9K{n*m}~Eof`bbUq)=Uy~V{C&q$w5;ugLghSuUf z)02?_pfgr}$u}QE`X6k$a&KywvqR?l^|Nj|f7R^XXu6)!HYR6yK=U5WiFS+v+Au`( zb1Qp|I@#*>fM!#g^m)UOs9^RDbI4}Pnzaz3bqMtfPaa2k$UhCCGq z+A!d(86e7`e{ZfW4Dek_z0~&mA-u&8(CgTKW=hn>qZuSyN)LHU9<&%JlYuHWR!?iu zUK%AjsBZnx%qQ)h*E%;uHf?feussuLKKhhYT|Q@F_12(=&f<`x2>Ko%8FNe_RTC>x z9CpR2TLpkk_hlC|XUK?KXS7&+z_>RjL;4zUXHY`F40`+P0JZW&Rc*i;eCZ>}^51!; z;z3*Polk9-GkSNll6mOl=z?TaZ|kZLGGD#RT}KAxQ}3>Zy;4267jEr|uZDl!#G~R* z~*;$gO3 z?fkJBw#sfrD+Y!Ze2c+zlMS^!gB~jod$`m+_fqX<@9`PiWE?jGv*hPwNQ8mt!m?6h zkEIyVYd}ec>|UO14mv*YqVf_QXS|aOdwL|xi4;i@8R>dN>(m?jfIe?|P%I2eA}`iw z=Mi#h=%k5ETJG~(*aH`CCr6g;y#!GATDrm+=8rhCxxO_qW=GA&=RT1dz)IYPvwia< z-xWP3n_m8%qy-n%@_+Pm=`e$e*;3h{Hm9))Xu!yg`$(7X{&0*Yy*-S!k*hj>=f1=^ z4Hz_-SDTi3c(2!lZH4ins{QT~44BlIxcCMN#c8Y(3A7z>K`_hMK_6(|Sqii0# zc}_S(u z6C^jIU2M>+{FZxiYJHfExy9Jyl7#iio4^IuNt3PI(_4ryhTT+AWrPbCb5bN`0RnGt zO*^rf5j_m)b8$b&q0>U%<#wo$({eYN@2mI6sRI9^K!uvKlmJ!uBh!H!uUv@gFqL6D9xVl} z{D(5zkWFX}0w>#ASgRJrsXZJdaXK10U`i@9(Ww1{VojavoMVIQ?SNUue5T+m({kT% zG)cFIEg&Q97f43#w^@y7JhvnAPDs-$Vu-ye2Uj9OsDbCsL`SrFJtLGmR_Oe_HwMYBCKo9m~6_@j;yf zxUTXkY#|C{*mjk7fq_+)mbgzHuXprnZZO)uF)4xBe|oh4x{_10J4_dvW@h;=Lm?vN z?rEuY`}HIWhu)m%4u)@}4Dkc-Sl(FA1|zr7t;=seBsVQDf8g37GRW{3T{)=raNC(q z4g+u9Vs-cnN$2d8uo$cRv0rW5&kx97DxlmC@?LubkqpddemSgbcjrOV+e?*x@Z>yF zsbP4*!)(82ahwdWLNM*6cD+U;;XDt+gVn#AEw8}?rRS!K8RzK|G*#eRyVtQXFIj=6 z!_{1DxJL|Z%0ByPF+i=%=b=sc{ASBQ-N=w>eQN~`L-{Pxl@M)watD^DOaXI$r zzaA~}KxCZ*nB-I!Qle?&BcA~jhaJgJn{T2svDKW9zc}2g{ClxOMMLtMnNul|%F9|6 zh7z#ya=}F#?#{^~h2b^?zXPCBY>GC2=}`F77&~zk!ewwC55xxD9O*Jx++JGW&_zC? zEfKsGCLLq3Ftc5cPoc8s=3v%Rn{Xx) z;B3<2tG{pJB}?9T?X?aNJm-J-HSN%Edj4T20uq)lT}eDZ95A z+YSheThct~P{%C&&tSK3_XxC>>XP{ChJunCZynhHZLcsc7$vbXZ8sxA{Dzc$G zN-yuM->3&Hc7y3b3(PFZ2Ta>8LxkroyM$)Yvnr^2GR;Nl?9*nMtBiU_b{5f;j!KYt znq1OqiX1$kKccbu=%;U;{h(~TO_UrvWUlC=E#;r;@7s9ELz8;O4_0)4n-6U*03H0A zE7u1RpNrn93-l#Y#l}y??K;}9SE3e8`SZWMXWX&(nqk1mg)2@Lcn-=S{rkFNt>a%e78ngz(m^LU7n zrf)^n`OS9`yodZLsC+oFw&w}JyztrVZUT8rvuH0`VDDucRaBubKR?yHt0L#JzB;yH zy0mpeLd?93F?%3GbOguk5^*dU(%AiMf;>=5i%BIu*Qk{(CV0N|NKp6Zg)5tG?T5TR zP8j}Hkkmw#W&!|?EVI?sfQ)P6ug`64Tqt(IHO(azxOrq`SaLx z*{LIjO#79-N*<8rm{7QyssgPo4G*lN0WS;l=;gV(&RLIs?93Srs**?iedcR_>pYC8 zK0y9lTsa!$&(FfcSs4@U=?^wf$WVc9V}>Fy%MA}d(a;*bZF$P!^a#YpQbbmIH}iL` zEP%VwQfTHHH2TMEQkCt_CT#cq_ktv?b-I)Ea)m0CZsFBPw$q>1yN2-{?#Z zzELJXTb=AYtl`s7XX!){?Qn{WWBQDR zsEWXO2#m~+=M^%mKgORZ&)@6Lu4L#&F){3RcbO~AyAv0QUnf*a|I4y@`iTDb7zV$o zTHO++B6Gs61l^AlRRQ{tPhzyUwy|?jZ+=Bj0AepPzvVc!R}1P5Lh?RNFnd^xjVsFX z*KeB!5j4E**TuEticG>Wi~Ylqm}`^zC`ob0N-zuw0>?dAd|+q%W43US?jh_e@N^)` zyHo}`&I{R=pNb@tF@SOHNOflpdV+N-r;%P^?7;=B>>v4@!F`$Tm zh&kI!eDG_zCFp=x8g_SL=900wEi$A9fOCHKR+V!63RNWD2YF-W#{+?)f9BFgk25)- zK95s8rVi8aW5jWDb{l3p54RnZB_vI#ns)Z zCoV8ED#3%(P>2Zk)8Mc$zrjoqOXai1Qu>q}jU~3X=kx)~#G{N%_<9TKfu2s&dZa8+ zIoiJ2b67ul98TdhUBP+WA<#efFgLu&JA4q|4*)*6D+m9L@GNF-rMGxJ_)xk+-tuCa z+;5O&z!}r$`WrLtpq+glRO22+?~90tz-R9dWD#B2Mw*x=yfphvr+)P)-LkoQcDfMG z2+TU`R0&4Ir&FMAE~-mZtMl@G{P}9p014i61q_?doh`61YVS2ol;RAEc(V>${~}$! z37Olow}0kNw}Ic&oe`WoeCx&wXhe_RKOT8)^6ut080QhxqE;bAVIq7IO+|YD|a1ZN=qyl zi0}8yEu|-*sCz$9*fxMF&r-Grnwer*8ge|45hYp|h`%~Qx*sJax8PHMB!WzwyE#QFa^lBBzn*iJ&50Y|9>k1YnUT)Q|dD1>m*VS8w_f3^*P+z7Lh z=$pi}Vot9>Bom=7l)egc^jCs>kw^~biDxhtpw*y>5cNcFN!i+7pj3+m#BBAIK zj3YrBLX9A~qI=X&r#eLUAbY%P7gI3$GwsZ1N$--}a_I;0bCvkW&K(*=Z(QW_|DT1t z`JA*Z6|df7n5DXXd^v^uGLhd>yTxv2 ztiEV#k5&M1&TRnm3fIp<0*gLuZj@kNpI7sv!-E~xk zFE2M2kRL$FuL&1X zrWm=i^kew4jU5Ia`L0u05?l!~Y6sNm_)H`qvp**DT0yYzkO6MuK+)5?dZ$Xn61HBn zsRxVC&;K6xXIZhs%I-Py2z)cP7UpHDee~hab>n2|VmsgHTy~ZFbTnvggHc8fVuJCp?crg&XhO6MJrC#p!C%x5usrNWgE8FY1@HzHVMSP>~(koq-1$k}X@eioP1mw_fz4{2)?p`;I-N;wi0& zMczoI%rp;6x2&~MU9~)hMIOAhU+3ocICU(beP*fu0iX%q6xDlfSnbCE(jCsxsBgi( zd)t{-rX89bnL=|pG0ow<>YyFL#AkrtbaWPx*Y)i4pY3?A`59E>faL9-FZcEZH3{gXxzm-z`iX9w0yYqMgAtD)4 zYkBx4GApt^f%AzKOws(BagjQzB9`hD!?|M6ar;@jZC__|xVell!NL0XKQ7NGxd*Op zjOUusX+3Zp0PW@FH4-1>4>SLF=5?A#fNw~zO@45Oy*m%|pB>hSEyieBCa~Dewq)|nJsCpEX0}Rdp0*$7&T>xyf=7%?XvD0vFAE}pd{i}uk_BTFkx*V1J zp3Yv);AhuHQBS@pz5|-hR24VPO&?^oOai@AP}2rCCe2?XH=rQ|_aNTqz7!zhfTPZ@ zuhzacKX#HY`Ej6UN4eh4Gei0|deD|fI`Pj-OdRl^eqrhcXTP|fT%VVxaQsHbY&HB7NXM$E8DN! zVkglB-!tD;YW)-*W^m-QkKQCGRSdh;{TjtP!%ZkD?Knk>>7Qf>(st&q_J8m!iwg`C znFZYs0EKfUzt2#LLQ9&grSS;|Hve>?Uv~M!j=3QD7kGcSeVS*MQAk;r39lLV6J~z{ zWu*5aUUgBM)u|9l*o0>1Xdb~?VDz2M8FM!j8r;Bgl#zaxL2h4w!S9}+oeqBidXm&z zc(f9*G6%SKsf2sS@U=Hq&{X9`ssk^v1UYh8-$0uL?~KspAadoX@+_zQR;O7vzYs_g zE3zQ?+jsfpbiq(Z-?k$sKz79;V&%rYXm!3qIHHsOuAEH*c+Sx6WtX{)cRJs+r1Aj> z*BgbC#@DwY58iZZ5tcsBvJ94Af) zqL&|b@q3!Jp(%IgyY?RHez<1a_F0(cUJTDoOLj;+El+d9@r}%zN?ET|+%;FJrw@pu z!ezOm!u{9-MI@Xx%q=FK#4IRDu$n1SQF^8v1oe}c{;YQV0y2M%9~qZDd2z8)b>f^* zxc(|D9@nPx&~1co>qFdaZpJ}EP?>bytu!jn2yn-O?`Wibp|H zmSYw@$Nw2ew$PEl?E&3ldA{{q%=mQ!i&t7YnCD0jr}WtMgct{82ucczw%62^XoLVF zC4FyCP{mUMy0g1CWAN=>C7MS0>%#05i@*Q9U+Xc?EXQv4IB~r7vjSzvx?Jrw_giX0 zOqT+XA>Kt8T2kELs#EXBi$<{PTU;=W*iLid8IKhK*J*g<*zv|?9e#A&{{)Uk$EbNz z$xL;abad*y|MX*)_idfSW&Q8`7Y-!F>jYL!!AbBJe&rBtL->+d|B)bXo18Tz9+NU^p- z_m~eLiS3|FlarJu_vlS-e8dq$i(IsR@VrZnH8mi{7xdvX{n@rS{;DUYJ~D#1d^rQh zn*MymRjz&<@1}W*+H!q?Z%g<%@G15mKdR2tYYM2`10pvFbC zxgzTed(tB11eq(&h|tY?EbPG9S};0(o?-Q3eQ~AtdnY~MGpUp8m?ev+-`nws#5#+& zHz^Xo!^8_{Dss#Vl%wR7eVi^A1oA|u24+}l(8vthd2slT+O9n`TJAMYdtAg@;UBsi zx(7?sx3~;@9BFg&rs+Fn9eig`2|u0s3t%KZE~xDNaWCh#W}0#e={NcGXaorFK@PL> zV4%612D-_KTW&lgq=C0KYRAJOhwFSI8|?D;lcXw`Jmk?p*@r~V>|faFG#$~axbdiZ z5E8NoB_p(rf6W0)Y${z~{V0UXVH+=H|LaaKGHTbI*>MEuF2&oY_Zxtsv|iA>`-7Sj z4b}4UQFaGn7-8@}YtJk#@XyP^Pe;u%==rI(!z>`B@hT>pdw@&Mxdnf>0(Ap)8-drt zQMB-uI(99#&Y=6Z9$)IKki9CxBl-TTpuGbkdS4xk*K-@_$^Jq2h%cRVpDNMm{8~4K zlz=@nsOW*7!B4WpYFsC5wNtM@zHKMMTunYtC&e1ZNgK)Zhj#sQdQBFJ@6l}m3SEkm?GJn^AtBqy z_{gsmw-qXj{(Be2e!JKRpVdET5XHfcGqa=9%aygMF?GwmR2{gqJT0K94g1-X2D=BBwvNj z$>|Ph<|ZJ6RmDr-+rS9c$Gv9XtQr(9Jk?pD1v4~O92UKSt-+>T--yctj;!j;O5iBl|Pnrw(J13X{6rxmNZ?|;s2G0TiJhQ9A z;}Q?g*u&Quz2pV4zZiAH4y!V#vWUCQ--=R9QguUI%)22sQkz)U$0^L@-h5HjwJ$~a zwl*~^uxqzq}mWrg$84f-R7isGGn!Nqls`V#n{jV{BipQZIZ};7q)yEwyX(MfN5*%28 zBy8HubZb^=+ZeBsXMS~HTp~l3Xv2qh)eau6s7tYPLbUjPaO;89>kQOhbR%0#dY7f+ z2|HBVnUhwsR|xj&Y>o__d{!%BPvIXD-t(fHrgNzxg-7 zWH6zh>SqA#JmMJusV37!L6ml2hcBVIC<<8q*gYRae?iBLX6#q2d)=vW$UrQY5 zn(avVxLiJauX&d0n$k84{+>LSo1udgD)q>(7(3Fe6oSjJ1R)f5_ju$8a3u6c3WP48j1X^=Z(B~nsYkF&kQ_v zWmo+|F-vs3SrHJDq=%EfIHZvwT6Ghbygz0=_Z_&F4b;kzZs;BR+}7|}sJ`PG?`zgS zJ{0){-r>#e(py*8cJuWVN9PsOQN;5OlIh|L{^RgT?z>l>89{K~8V!#6M zDr|lOzr7>JWJ~BD*@mbBl&0as>->v@=>naASY?VG`xOM~raB5Nv@5wJ*ck08np2P= zt#N+u8g^heQdxQQZ(^28ox^SY?_i@JsgxHs9{y(|@)bbHCMh@Xy(%28CTvNj#*CmS zc1D`9gSQ}?(MJBne|8H1LaVr%qeBF86+pgZG*GM^pEsB31gxEq_I?ZVwo5ms$`ob0 z)!oFuGI|lzE8e>-wW)+N(qJ+KrvJx8icNJt23f@D8>bedV1_UqI3Q>E$VOhZgZwXbl#hXaGzuCL*|tUkPxJe&YOiIU^P|}{u=iB_&VHeGg|@Xr1O}#BvSU< zV@T18`v+xFDnx5+(~e)eUKK~Gd!BiEzJjq+(VAuI6UAsCsY3zh{o| zA12g=v$_j;E>?R0Aj$KOeD(5T=Xln!n#i>Q!rXqD0+C4-T43i<%|t1nBMCAS`!^@Q zQK{dilJ}8YDbnAnoP1y&-JF?TRe1I>UP1?`3vKfCjg1Dzoo@qM?L@=Cwl_rtZ+i-f z?YvwV#kDG*0o}&Ol<r*AJ|aIZXrhY$$+g*{Y5L z>Q)l^cchLTo03%Na68+NQN_};E?dFA_qVI@wg$o8lGy~Ja>PxEioqW49>}UEFt2GG z-t`0iz(8Uv3-`hDPs*(AnMX}N35>3#4| zlCGl?f+yr4x6H{!o(x}v{OYGs&~_4!B?<`aChi35bxp$3F+ezQzDKzDv61+u5Oc;4 z+BM4*_kS-yki+f9!%}yV-MQyCGPeOMIj?j@0ZAOO>|H&X*4$8HsPkQ}0vh`tUhq(_ zH??v9>-?uJCULMq{Geg6ia(sZ*Lo%50R#vr*Ou9UXeZW|#qvK#s;IdsnoJ?>-njybK}C+thVYvLe6QaloCk^|B*oNm|15+i7Nh6|`qlC^TWEi*4R%U85|P5r&2=gZgBIk%dPk{VxuC)1o&RyYsA(b8Be{`w2DmNvOU&VC8L-7qg zvBwXMItv<})UQ;|A`z+1+w>9Yldm~Yl1iH$A-70?=C~s5&D7qjzE)0{=&<(Mi;3;a z>wtTQ&wg7T3{mygh`<@UhuT-5fHZ6c$i=%Ft>)6yIRb5@`2hpx#tW?YXZ|oee$MeViLr3m4$3WWjo>@R~CH3R2T@!a-w<|9?^FHd}fxMYZQ=}zMeKBNT z?}fS2#s4YR+%y`oYdH80%ih&$9|98k><5_-4%z-{CvpI2_at*khubgjb2_0APv-f6 zd{Jes?0(|8V|8KhVS~2cS<lF5zGb-8Wj&C)PP@#mv_=sy{b}gT zKiP$&GKP6nF;?UW=Gz-#>i%g5jmnb?#9!M;tjl40@Zy93K;wD-Q<6O41oE4k2#5F3 zLTn4f8>#)|WPJ5iRTDVt)EeL~Bm>@h2*;Wcs2v|*qPxn=B%@PRiMUI@c0%yaSY-uR zoU0X&ykH5rPePgqv7OJQIvQH`qbh|$FZ<>W`%|D?OZ}@Pue0XwI#fS#(~M#*ar_iE z0Zb1u!TT5TE<%-1dQ)(v7`G&onK1H_{v0QF6t*QjnG5+WmxWBpvi6;PxAyVdt)>M| zZ6neWRH6uVJXU;o!qk>B#wkbCG+NI9-#JeAuZ>GGpl+@~r+jd5#|)$LNn;9+yGemU zvk}Qg==?9!VyVQp;zlSLOers7Med38-2w);b&fIJ-Svvg!$HY)F~_ft6r2$8*c8n4 z4!{=>9EqR8e=XH!EgHw((S7OsNo}H~;nM^oEJB%RcWC*x-CB)>&<*SzW~IF;5~6A31Ks2|VljKU95rJk)K}J`pLqvNg7ZdMc82?4cBi zQrQW`Fl672B|^%UBKwvtd-iRR?AzEz#=edv`#xj%-J|Du-}m>=eCE&dIp6y}_gSv% zI-O+~5SdtOHE-G?LkC+0$8!M$>RE*{UME0(OnAwWC!XENINb@*;f-Y~gQ#@-%h$BY zX7z1p|A8p8sl$5hudM{EUB2~&c10rDeHtjZiWz|6+!EGfvQ^#xj~+=Wj3@$wwKf-< zLKna<<&;}I%z~TE~w5`qNDI;Y=&^I+V&?q|Yjq_S|1ANdMdI)B8RxXD37%aU%UDuC(CnU5#f6G-u}feiIk&Em)IO%06JG zuynSumMJ4j!qEFdQ0zCHC6>T2g5U^7a7y+O$Im153;R9(LF;|H2=9vjB4%a2{Ty{M z()6bL9pOx@lW2IVU|36?OV~BUZ6UR0y%c8^ub2kMHqwPx)1u^t<>onoKseaQn0um5 zAn>DwFIw{gQ!mz@^DDG;wtWs+bn?Uaam;gjuF7@fw!}%HQ;t7>nynw|iX$L}uoR!R z%0o#ivf31R>X4zK6`Vv&4QUr?J~XAq68Ml-WoeQ+L+nO=mP4Jcs(YyOYqdMTLfx5c zSr!4%bh-WOYZA6kCa}5^nR)#VrN1Os*(gI`PwWQ^oZ_DE zdPO4d(D`#I-yL@mL+$HJs;_XrJOeO}2}*IgMHY=Eew0%#D=tUwejh0RAC$4wO84(zZTf z1~+%V;LiTwV-t&)OO^L5)WKi9x%sZ_0J_3zqg0AJc^Qwd7teNM zDj)|)PLi&i*Oj1Mzx%1X7k1@Y-?K0#HtC@9y|Bq<|Ixyesr8TmNaf^_HWx0*2}&#K zoE8MRg zdfZ)}*}z>1(y_?@BPAsUHJ0lgq+1z1q&ud)I@h2sv-QiL$s_sYTV~&q$W-+u;#N|Q z;=WXN$#|(JyB^NKra%LfoX8^lchzCpl9f5V>I!zXce<}<=ZW?UOm=*??p>{`Qri42 zJC2myQJti}MAc!mIf$DmkF=JR#2^EiG>#{e|18Y1_Ok>BB{9(((^}+@O%LuQpznE3 z-9v>r`ZnR}BxDcAmwrf@fWaUk{v_N9ih%ue6t`cb&^sG1^USP=ID+AIs@=TyQqaxk zEzauG8rV}}zq?6czcDA2k!$iBBXzAXy`nxqqC%nkYS0^Ti?iwsA2`dfIPypGB`BFH zh{B_RfQ1N*NU-A_g*B#U1 zu=(NVdWRM%m;$}F=|%^ zC}kz+=fcqu|M^f>$t533k-bEI7do9x1IZR2rnOQcVgL8c(HoLKmN2Cz3cFLdaHPgL zQJTZ*?TVby@_EKmwXcgRqL_d?hfgvz5C=^orVkD-bsFNNqCS5!C=_x<9lm243`|}fpF!of!=ZL<5CHBr(tyLv5r`|rJWqi0YZOvHDBK-wm>|HI3z3xe0%tLtKY+OUr7*IB;bI^(99)% z|L&WoRzmvjXxbQnY%o?yAt45{%6MsaI+=;_k@0UC2jzpuJd-FfyW2>BpRhx=@kEDe zoak)=8sZ;={00*Q@$E}R(&q8)G}M(i@AM92aK;rOZSIVD<(1gn5nJF@6;f<^D=Z|t z)Ko9Sww0}EWt&(92OU1dQlGh9t*fwMsIsNu#g*uL=|WF}yWd5d<|9TtJ1{Xyr)}N< z6s4?oDeIPUv#5F`l>C=_&bXlPiwU_ZH)ZLxH&>GbQW^{7pT-CDSJ*2#K_fgO4V0D@ zHwEajGO-nc7&4)^E(v5D=w9P0AmHV2Taj+8ViKoz!efX_X`i+>H@`H!cSo1}N!$}D z=8x`6L8?F_#eI+)qgJnV`M}RIh{YRfNYnO0?{hx}HvISsiv}X&n0jPQ)xBi@OPR)7 zQ^5O^dQ|^W&+1%=WgKYb2X8;EF-&tX8jxFLN~J;5kiwqj>Mo7SC_6Fu9z?iLZE%`G zjpyt-TC#j!2 z(Tk5&OH@cPF&oaS6r_D?2T2}>>(w5@S~0VPBOLci>yr>6OADM@|3WR>^bFzkYE*Wl z+M<7wgx*at^8e$#Cs3iIZGW<%0-$(@%GMKURYv4?D~0+OlSos1^QPtJtPYa=E#>Dv zgW}wau~G8o&{13TiIceqa{^MZ@qA7*7ooj<)}6Gv}I+wS_sDfJ*KNNs;&4=F_haT|io z`ZeL+5lrgA(K~7&e5&!8^-+&;hyAQ(RyVGP0|9`_x&b}WK3t#2i;rR`x-c|1brm-~ z0j<3;S-qk*F!V?^tiN71!g=mmGaM)Ks^-Rg_XHe`g!CQW5#HE7$6!FlI3Rk~a-JT` z_gyw5#Ulkl5_a8M5Za)pLmq17NaVYL@S;#LA>&3@41!_9^rvu*6Lu5q`JDGn(i)JT zzlAs^0(>TPNT$KQU_z`4r`+c5OLmy4WG*RagU5Ei9VN>j^6gXtOT&8oi)lR=ZNa{v zcP%{Jxbu_hM-8H;Cw-~L({c|^TsGFCp4O%(SO1u<>UnCMDeu{wGww*?E^r-i}E_9{-(7Eyf$xk9)x+Xgqn^7s0)ViaWGg(z6>> zl)tLy4|7blKL?|2*dH8^-}kdj_s`2v7DRqCUhIAMy_C-Z8Ut=`FD9lb?cr*b9O;4k zyS8RlD+Ta{x$_}2waN<=@b5WvtNsavD3-MFaz_&OOj%UcQyc%`2H{tAnn&$T8J;Jk zCuY9g^RjvHSqAm6*GG<&g=2&t$&kI32EFfqz+tmaAefutn9pXZ6Jgdpr#nt9lp5#x zKcr=rUsAcX6EOa_zkJt``?%dzOa8VE5w0_&2{9s2>S~1bv&Za+5cn*^UBqp#KVI(L zoiDOlaCnWI!m|AQbYqwnJkOuxNn!Kn5@S;0e(v;eS>zfv}+-rcUix6_~HFd_AEH7YduHX<&)A$ z_rV6VWNT3Mss4@IKzNkr!?$uIrHcBF@;LiPVFBfMrFhCs3oq9-OfB7`%kRtwGT=8d z4h-aXU*kSxKub&9L+wGYOl<2luB%rBa$35~Tj1jOZ)ftbG`-Z@&nDiW)H?c%(9(4F zb8qjrCD>hS?U#9mGoSV%HFP6L{$>x9W-T%EUEV(qC;iiqt9aQ~GSAkQ>$t`VD)}6| zFtganJp5DpxL?S7P4h4tD?71*60oVW1)aurC5Y0(X2(B8?5lVdA2VsU-+_f!#o7e0 zR2py$m#ieq%lmJPF{{G!mwF>s_h2lhCHv`R0Kwsh8h+{ROZvBngc)6-O0hM)TY+7#`BLOOp1z^U?1lqq`?e0@ zY`HCB^}hE@3@fC<_PWaT{Ic}=B3Z90M|W^!@%@;X^!svv43?nuz&;w+@HO+g6rI22 zcshpfAMCq5rT^~JFX-K61<|kNnGct4TmeeBCiwL5efst=Qpw*xHkXWPJ{Ecw{1#vT zy5TNY?^(F^Zb}tsKGz=>%I(O;2u}Ll)Z%pke%>pJf!D_6<0yQh3Ky8roIs3Ds)dytt=ar=>LK6_5;F%d`yXY0@+R zXtUFgPKemf&jEJ|M9u$>sXd|6rOma{zxWVZ*i4Y8NZ5q*Kuwl@*{}qxv)qM>akw

QV*J*H6>)wPq9^Ua-FqWaIN&}aEQRW&fEF0wBL>ICQVKEHG zidI+>vES8{dFk#tB3!M{5UB^#w40D4&jy$-HzqIbw0`V0E8JSg3!SH z21;2?T--oCTb-l8e6S@jH>d15cec65&sBEn=2CI;Xsa+gc zulGN$du{A;07Cmkf#zu3)jNm+EHAAZ$4d}46IB!vl0m|gEgx(tZ+A{=!^=S#_8`UC zQF&0Jlqe1z*mX8&|B`V-3`bK$nL{O9^~A+w)H-Ol)phb9=ihW!C3V>kUm)$hSu-$S znsV>6HJ~XZe?^FU<-|#9?`>6~&&n&2%^{u)2^JzfXmWPsW(S0*fH@@+ zr_?H6FFz&j&nw>qcWSYDUx*>oa~AqrYM}modUMXE5y|6c|0NYfB(p|FP%i1Mr|o~k zdU*$V*t;a18uPa^dY8|u$%(dnQhJFksL0IiHal3K>ZwhvEzRsXe(HvFd{|J=omA%o zKCcXv?+)nXWG_mc-jHx#N%^u-$7ek>tM9L^X1kCpNPm0tEFCoI24Pdga3d&Li`4YW zP?DjXy)X_cQuPVp5xSNAiJiGcArfs_JErc@j=BpHVlWx@Qz}nFK2zgty1+m|Y)WOp zzy0GIQ0HD-4ej{m&533wu{&{M&U-8sk9z#TwCGH;=LkkS?S9Xr2s+F59yfCA7bmB z=3r70@;+}XAn={5val{cfj`A|g;rwWlMVYA?dV!XqC;TFe&&m-@EZ4Hn_DK3=3MIh6rZGVT7* zqO%RtUFPJvWplXRBTM(KrF&+vN~M4391M*fF+T6Qq(w|7d_a^&K=b0NJnq;pV2hsK zf}mN67B)Ya!;$}jhFA%ps{a`#U;U6E^qnh`r7z;E>iEA$&?;Ao1(G0iab5OzCh-Ye z^F03^`%=sgYV!53jc?B2N*&_<0IjV&vM+n$vUm5osheGFV0l%y?4xB!x_P8IO5d-R zxZVQfyV)Vi%PoD)({y9q+Hb$0D@rNP6EZf^{407{xTn{6DXmEca zu>$^*Do<9)^|a^XQV@~b_jdbSXn)0!94Rf|7xNH(^Efmx6;b8VH%#=THfc?!W`UoP zVKk~mDGsD;k49%>vNl~DOe4rD@B7s(dDSeuodG>!^ii~=8uibo z6|%7Xkt+NRfM&Em7$d%QVU7|(=5!ZvYSV&<<<1?Jb^NFDOSuKby+=p<&G&|{l}dEK ze56#Mp^%WC?Q$kR*Fk+P+4EMm_cLk5fIVM!-S+c`?4bXdtblB|QJ_$lP~b_ekZ&!x zujA)NE6DjZDyKFvfpxB7+*{B6chsv3OZMU-BIIKeycYu2Vv#`Uq9F8L83ka3QoPO? zM~KDG4tDxj0NgZKGh|)O9+rP^-L_I+6`xY1eSZ8krMgexA4gv;{a@+uKO(ZjKqK7YMUdWw%#OOd z?1q;wXmCtahU`p=C(RDl5s4<@{@ck9w3Yfjsbvzcdx1Nb zXh;7@rWhc#gS7dLP+mtJm-)BBcP=7xU9*`l&B48(>F*ioGH+b+Bnyy^_O)X5_Qoelw> z-6x&};i;AsX6z1#Gc%BT3o0uic@If2mnjg@+4lDad0`EBzowkN%Aq`evdu5PTbq<- z%#T^x<|kJEes9W;Se+J)C9s9^CFL6r{X>fkjT;szGz~y|LZ!$2#f3LCH80rS&_%sd zkV0I(tZ@si1Baa3vT{k*a;+CLwBe-G@DeqodFUZsWo}G#T7Y?5bw&q5?99kZMz09nzurtToHwKB+5?E zG0K6RLW-8*y7es9%Kd(qm%EUq`dSQL@h*4qNk(@BI}~`HoeU#b1^wH2;jiG~ax%IY0JWOq_9S;#7@l^w|db73d7JZPdnf+v6q* z)wSbWS&ga6CFLHmP>0AqGuZp&Um{<#o=u!Z#YqgSyux+uf8|RqzMoT=BP$i-E2$BA z*jKITbEb=CHJlg(hr&p#g1SPr0A^J5swB-rmi8c6FtUM^zVEeN;dSj?lFuKSV(ZP1 zdeEEoFhTxbDW{)x7Rz;@x$VpU9khnk`9`j$R*N_CpQ}*O%cZc~w^4P2Z~xMty?N77 z8Q598y;Z0R>}-qzkn}(^I1i-q0zSKPD1=tcf$;8N#!{Ms(IXyF#93)Fjaq1{iD z15$fyA6Ll*{z+08rBb6l1@B?F0zG~%T(SWvR|@8?O>y1n(|m4&X7mQ4mQsOgzwr(s z*KhO7KAjc|5W`g@R2__`ONV>o@p8xV89`AdC^CuS5(H@L%s+&kf##mGsZQw5V;N(2 z1)JY{M+Sqldx_Lh-GyLpF}zfCT-KV$im5#gJqR$`>$33$fwPq-=POL*FU8c)X?8s6 zDC~>5HsA9kBp+qrjm+1)fKgE&!DJx$HbbWR2GW$@`{1^mY3vYE z_UBlDn!9I3e|ovA6M|mvpOBNxK;JIQ*SoF{vA77dOaV0H$!-u5+p)I#8~#9aI)R2{ zoP;kvmSPOEV?$Kq(&GF6I6P1QtuUk{-pAGno<*a&-be3y-N-G6xR!BpaDsq z5*BetkEo+;*eN^%>n$-uak&tx`s>+iHz9coA7+h>+J*jvwM~JvyF>#yFT2!FsV-$f zrWDUoOjHq_x3;?`V4)@O-Ka230R8ihh9|0kLL^Bm{%C)+S3bIcV!E%SpO&{uW@-h78kIW3Dp!*aY?%Aeg@8TmxwOqeBWO;w2uc{kpi*_7ty?}B^Haj`HskZKo_1#Mu4Ch;C}PH;XgpvY z+}U#O>t6GJ<~kh1XhkJdo)KWHkd*TBy_W8rKKc}fAJI%3&V@JZbat_-CswT2j~7;1 zjvrSiK!8u*U+6{7BxiP7-n|f45YOCck+fGD&7YI@(GKMz%K`dPA z+Dbo#9^1Eryprh0=DMZsAj;O9AndgQ=y9Tk_md zALPmExfJog*QYmAaXEry`GT%mUktS2ML%dV9Xf!t!wt%R(Z}ROtk-Kq!+W`DX?l(o z==*(=_TC1qwA`~cYg~Ylu8N7G(d2_1^7M!P#;m1 zRTuKRym>@K&s8ozSPBLbOyPPE_4RuJeeW8tts&EgdMCSqt6&l2>r%4)++*W#nWM|t ziQ^kf(;kYKf0@Rgk#GsMIWN}2nZc53@;cTLrBv?n@#9HP9kF6)pLXP}{fY3h+f9C@ ztNNHdQqgBqVS2SU@KyDbz43chJ!mG~QJX zMh2-TVh;b^6IjDaJCD_EN}a1*DVNLF@wbs%38b_0Uv-XVwI??It5*fuvnkgqyjt<~ z+go3HTpb2p?c11}CuUc*@&X#+M+51Xbnb2Fg(nBLxJg?snaw^Yv77o!m)=D7v$LSf ze%F7iG_E5+RY7e0SiIml7^(HA)ABq*J?f&84xaqSHs9_%rtd2x`Uny`hVpJdJda58 zUUi|;6nN#0+T#q3*GeZHdWlg&Ywf(I^$gcfT&m~GyZSB;5!J*QpC@xEk4|0OLPSI>aJ1yr6J@xHm9Fl>D(8<}Gd7{A`X!%w#LgJ+l9f(aMt8cdw1qt3 z=~u$NSey)jueJ&d0#VZ`AH*zjPSXn-dzvaazdzGF!>y5>$tzL89m(x9t1+Mr8Ix!X z`X^MHlm*FTL&2!~!P!b@*gx1E%!)?Doi%i^Ap@z<{z%BLbu37MC z9v}%X@QieI(c5_zmOZdqR9OM$Azj)y(`Y-tHnOr)j%1z?_WGI`Xve_D?6|TUhu1_y z@WZ3Y>Cch{Tr&&DSNK0d)4|R7z+Z-)0rlz+G`C4MO^;a{>8WLuy|&M4$g`PV$Wx~D z0Uk3W5P@)fd!P!`ZbtD4R%7>`uVm7n;U1eBt94sJ{qx`02n~kw(p8q5lJT*{4Xb=V z*athblm8c^^yjbEX;-MNWa-W-`nZnkszOx> ze5%DsW3h6>b?`2>@nKPYQAc66U(gQ)jZe7%%#jNt5{V-!6V#(PU&s&B9*C<4my@UQ z9K?ZvRvHCx8-~;n2JtOe>}+gSD{@vBIYuW696zm25KRXNOn_>dNfwV9)w@*GRW4Q~Gt2zW9K5${HO8RjD8ONe-3oU>uDR~ds!-&I ztkbKD_M&5P3i<<&%aF9{-DRW4-ppcQiz4ebYol9@#o+h=ha_cJrOfd*QeBI0l|q5n z`mtnfkoFlO@!}rHGR-nF+I77 z0gg;ogJv8XaG5N^TezEb9beO9yFT5hmJwa_& zOf5+J8*PJx^~t`8*L>Ztk8B;!d5qo;T$&N$8b8<{n4crsc`U#GXP|y_akO(?{@cAN zBDm?(-zW{ZjvCAlZ4ftdqQ5|2F}Ii%? zxIyh@7StMo*{sJjc~EFatotdo$tnQh#q!1Q@l%3tJy~mkd*w6*4YP^~?w=0+&XIFA zKYp8X#TR{X(44B>bxV^~B+Qc2MK`6ozuwUIV7y5>e64Q&$Tce{%7T${E!P@hQQeSw z_LDW(k|0`s-Og9<_Vu^7zlo9b1K@0;3Qd{NRl>jee(Nbg3Cp$*wBtJ) z4>iDK9lH7DWt_9nPVSx`7_X}&gU%G&&3y%b0b4uc0R!G-1(%+ih{oMUck07w1XC

@V&5J1S0%Uidz?hzEKEHw7kLy43;Dco1CW*XCkkCRgy7*(l=&xxlP+gPtBS2BO zdI{Ve&3?_fwwWQJ`JSDcwRca|GrXyk{xj|y0Nd_9oWorONRFcomSTm*m;*5X}@agM^A$rqR9jD8vWvq&GKm?#p!x4fl#51soQHgcgAAWl-X#er6 z(@)>?Y}s}!fn8U@243s+5RU-IJrrBM_cz0>FXvFS@hr4UQxt=(_^oObLbKa-uIUGPJg6K}5=Wooi%O&0 zIV!mhR=7O(2Uu=+xv}5<@TKJWyUU%d<=^ehmN5T(vP$kEjfY_eo(2g=w~XmIM?)VY zrltG+yXU78*3?z|ij1l5uNdig4jrR*V!Tw{tgg)qfrA?U)abpUdNeWDuS4 zv;3ilcc&3Aa7X1?&ASKra+g|10mbGV>=yO&;Y(0!HJ}rwqijqtiS3qn*L25W3j1=V z#;nf7{!qVvURAh?Ov3*7C(H4w6ZB?j3SYeLtxB;!qf$i>l@q&La))&Hr0erjSFyktBQpRP7}LCWs}L3^5&IW|=~$X9$QZIKv=-@taJ;tl>iRrt2ipcLWeVwR_P|jW ztC#Q;@C*w?B-SiSIS4cMxq~l$qP(Cm3S?bhz8NrD^0&IZs?PMi$BZT3x}2( zTy{>y_vkBS2yZwhh5J~o?_wvm29l45cI+~~&iUal7#$a{S9{Ix%@>=zMN#x&h;YJa zYYyG8mFgyEsh1jO*2gZ-S{~)ooY9(%9riM-##sMt1ICqdcVTv}uU&c<*pU^$uM%e9 zlM0^pnS8ahL4h3!v(3e~7x%*gGI}+Q-8fU}CX^zfD3_m%O{B{KVRtX2_leRZl-z{{ zVc#hYlF)`}${j1Tg`I5|;1FdqcArQv6NI=FD)rC5bjQ}>}q(^89HOhsdqV`{65cQ4t}AKjQ4L5 z-nMDvVx#vAe-GTL>reWF7kj6wEv$xKFT(r3%zQfr>SCsHRB9YhSt>XUqas&r&=tp& zs`uA!X;N}3J@X6)1(-d}FXIiGSe8DCsi|vaA`1J8Vv|&m=tweoN~X!g(YkbL+Q~gF zE_~09-8^t_eC2ctR(nepXM*C_w}^+fI~egJD*3D7u>5WYjqN@Rcd7F~TZz^Cxd7Eb z6eL`-dKnfip++&3)R$Lc%Ju4fTjYw+V$E9O+wv?yHRAzDp6(TC*J$J-JLPv$qD!gu z>_EgP3r~GoGlz~?eWd_5Id^)Ys4Tzv;4jh!3^$gMRWqXMu=%7N8C+z>+R)>iI&H%G zk^^5XQ2Gd+JibtmTa2PhQlqmlM^k$I(8bIFFMi*R)3vig)s~90zRb^BCm=dc#^N|_ z1cR_X*9~bxy{2BQ#($!#G*#lKM@7##&vJu zHms5OjLHNSV;Igj1g>%^Q})p#5-C-w9>(-V><_jDy{77630@E1M{8*uh5t1$zS3zv z`Xtqp+miXb?w{CL;fMILnxM<+ooiAdogFQ^O1-g}^95%JL~;xJ%Wyrwl*JYMYkN z(%$|n!DIKx`Q@+UbkN7tactsy=9yjLeUm+zaRSogJzV##{nm8oYuHuC>MFS_;M$L? zRe4nzpyjB5;6BBKn$jFM*c1XD)Alu%un^+C_b0Jxa%|$UB8SNMNu|_<4BkBWarjNR z1i3URcZs(1N*k+3!pH<3zvS>bb_d{YPPzz_Uj$1~=GJ*Wi>Z@Mu*gUnQIP?@RjxO- zW%xI*ADC5{b0$a)uZ_I&zgwlJL~jbNl4s;;bDhl5YxmNdA-R7J&#h3W_GOQ)S7*so z-S{QmjZPShSz&4GnM4sah(Iew5`bQeIu7+69w5Lr=9DnWKn6@a|1*^{n=D>U3xQ-% zH`QS0gu%eppQMmysrbUDG^+f?8==p7~Lty4I@u6j02zNAP0$n#6M>k5^}9BN%()=Bvy^{~6+52CWYP_*9GM z{NlnFALsb5M*#hP<K3(ZIHkZ?puWqQbW5u=^Q-%{q zpDe^Uq`8l>z8(XoLK}K?lr=Ea0O88KK-#T$X5|*xfjVcmSF=|96p?{E4;}-RVFef3 zbo@uLxE)}q_rHdoy{iUMSv@U=XW2=mOgzu^QT0vHeM7l@KRh4wIxGjB^3i8)3OWA# z_@5#{;8Ujku^oM|`y=ek_{-ss(nZdBBRZftlPc0W#%^FS7iFFQV79)emV7Bx4r@br z;BD5m7hA)ewRVEYF)4xmh^yoej$*S{`4Y|IlK7r*(Sn0S0+ zc%*}(iMgO|(IT7a6ya5yZQOeH9wa4NGOQTGn{9XjONXVFbUWj$wDJ)gT*ZCvIsK)g zE*u!7+RfHg`s|;?3Th{Pk+iE{9_4aBkl@5G8$YBIpt1Q1Z{Z+egNwhKM01#Tjg1xE zN4AT<6_p>3jZx@c^Y~cK|G7ep+@cGlSnER{Vw)SIcoBR$IQ;4gD(`yr8iX&j$B4lm zIJW93BF>x2%o;S};3-H0Fx8R)10yfyI!GS?N^c|q2lq-)Vv@)P8C!)FJqH4o?NZnk zrDY@_Y4;ma=}=*8AC6OQV9i7$F#m8w*KIe1y6!Lbr0a*t@7pX*ca$)K&g@Rl{0YBd z0Y_=yV^&vG-mC7=J9dxXbX}(FCbeK7w|Zlp3PivDv$S_10+)ty^wk?dG(9P< zvs84ZS6D5onpU6yj=ELPxSC|DREA-A{I z+UqmYyko~t?_nC?)7JAlwQAvJ$jen1pN~LA$Q6DqTIXKZ=~11isg$fffG_nGK?Ypy z;OG~#={#4$OC}Lq3q%@DaufaNH|yg8nYrS<*KIwsATXTTi6kCb_h+88nre{NbHoV7 z>j#!+4PgU$mHp+Z75DG?3dPewi`2xZ-E^3p*$y@ZnJW@JtOn%;!pvWTq;-Bg{)F~N zu!u;yqUVsvW^}CnKzjGW-)t2s2Vlxy9ArPhoNCL6 zr}Wib`B9b6rZgCJ$Ft*%BkquDjh}$44$x(8#`8z-rpzxKH>8 z)~=lFR0SNe)+Ov9ur}Pi6er(S(PJ{A?=Lzb;4-<9^Kb31SM-!}jq)TY2)VuVp>V>6 z`D+Pyzoz!C=+gW%mnu+O5K23QVh<5R(>w0b0MNCV<0-81cAUnw{j`zGd|dhWDfa7@ z+5s}u`~4&90fW00$}WOIYf<0^!F~6mdBQDw`dlu&q_v0e5+xqO$iFkC5-*YH8RsT= zH_uQPtnH9BGy(%EXsaQTg7KVH|N1!2e3~21Q~W*hh!fY0&M4Fsz-?(cUy-Z_po2j- zNj#peV-_`O43&yo^kx~e)(CMO17n zH&Zze#g);kDN=eRFTwn6_cwC4?89o!&wgYRH_I@fE5KG<&T!O_pp&Tl*^UjR?-FfR=))rZc#od!BmbU zuAD?N*-8pn$t)Fk{Z|{YWUbv#h*3#(^ASxI_8p;l$>)>caL5(3&d`_QJl3|N1(Y1;*NWgdlqej~P_9-c#F)?G?eSymc-Z@@+QmDdT`Vud}|&x{rL zp2(|s8I&i%hdY$xU%deMpv{kijq+KcH|K->Du2Ao-;8wd$BVo%zj(JLLzZKQlBu>d zmA-|cQ}$4_HLQ|d??OOQ3SJzVor%8bHX~bnzQ?Ow0_a^9%iRvG1R#2b&rYKFoVj#h zWoL$)hCGq85hn4Q(9G}=t2 zE9WI%{5l0^okvA!P4ZI>4T)Vya?`lkfR3$MsEBf9T_GFzNjn-R`}do#KBZwGKm(5N zqtg>tZk!r;_1gWA3k6N3^=aD=5HO-}Rnc68LfM(qWaNqh<%9+dWP9wH-F`4$F*Tqf z+?Opzn-VydKVvYy@-ml1+ZBE(RUjRy&ip+e z&Rol$r1SYR_79wB)rgN%0$ByXd+Ukf@2^BDrA{Mzd9Au4SF+?%>n+7w#OH8#UL{M* zLi33+G20NZCw1=UHh%i|I|uQoxX{@XH3>91sGbR^CM$KZ+1sg~>@k#%>@tgi;UBs2 zVp4$DyQ})oZ}8hRkk%an5^yysF|B`u=RX~Xg~3{E#{e|72<%KBim?K&ZwDa zSTZxT*`iOs)i(-);PkpixcR9XAHIAI+INBY zs=JX*L&p8RI}+V3zXL(ZIg>y;{vW2S|`6-8O8N&Cog+Y&9_FQC-6{Vp>wAv{w)2sPQ}QL0wV_QO%H zKfmu^s)TYT-2|M^C$(Pk1af+FZo}T2v8598imRF&sddLk7BL-4 zW{dGb=km|dTtFwNog{irCUJJr2WfY$V#!FB45XRjny$KQg9>i}IJg zp>Pj}(p57?6naB~3(UjTr3eQ;$%4aiLq6}~7i&9g-ig0!ImO37^>4sr5ZjEzAz))% z1(WMu*<|T&DM$E#jN_M6W@Xb4=LC1q3k~J<>PNOQY#q(y^QIZ6EPelGctyIf44}&x z%d8lD_w}7PK_It(we<=wNv$_hY?rbMwZaw+4mNoe?lQEJbC#zjOqs;P>9X~ESnN>q zqRNv11ODpRk6qO9==WMYr^i%XxJ&|Pff(F=3XSaGAhqHCcZw>0hTUTLN^t+j{^FP2 zH-060cOSWI2?nvqMHSqiihzQYOzQL_YXI4z<44DtHwGp(mpgYYuJx>f2ZkcAxfJ_R zEZF^~M+>_Swcdsf%H>S3W!z1uB-nn7gS451pKG(k)FV*U(0@3b?xlc?f*m3@=CGWz zr7crPwX%6$f??wySJ72Eh1~obV>%3@IfHEZEyG^9G9=Ynj?BY&0&ZeF%;i+;NI?>-k!03QbLzc)IUGj_niW<@;8;#S4@( zARZ^rO&tNg8UsvDH1xO*r>R_pWRT+Nwat*p@J@T`6IFevu^pi@V0%@%qRgsecRsj> zC|qROt81lmW#I=%yIu;z8qI{~6#f>lLkyUvg$LGjl7H0i>2G|&Y8LX8J1QW5LhRWa zBunw;QAXqZXzZmorf&-!db?hw3UK$F(pt7&<~OoR)F&QY#fQrQ5YGJ9iN^)H^7$I= z8mVBTrQcM(Kh9Au>^Kv8>KN3RId*tJU>A#1{p{c{xAl7G5nhnRto?PL2)e-(^|sZt z&F|j?khe6bJMuRzWbdki&7$|+74ryS6o6EKGD=JVxo2;U0l`9#qjGrj`C6=)Uy`-t zhi`%2rAe1GI7sccN81arZtF9DCE3XwogxIuMd2KCO7)s|>wnpQ-ujGtA3{*q7EA(D zi2FYrSK0yRCNei`P#_Y>v)3#dFw2_J+@!eWb~6z2fLI?rNRd+X{0(`(`tvT$&@_Fi zx@RSwo&;qY587IO(a3**o){$}+|4oKt3x)Xbw<xB8)xmg^aU~ zS!|^UuuQ{l@3k0nev?J=R*1}+9tS}^hF?x4M_$RrTh?8+nvuw1 zn5t7b?)&cuWfnh3(R=itO*NLb_Q9)Dsh2EOX#JFZ%fB@)D7W@J(eful4Xq`rdpXDJ z)R4Ju|FaL;VsLS)AEXxMqNVtdlE34`kgVunoj{So#L34K*o`BBfuVCd_5S)L3+!BJ zQ@~dZ^%0;<%Ql{kYU-PGa^J}*yeOmz7G8u5kT1+^IF$zo&UH9@hz zx(W0W{<^E?5IOLcley1@!fl+?rd>ih9Ptmjv78sqy___tu;9)Fr1#M4m)^`&ZvP{3 z%caNMyxPw58(eI9D-y_xjfPYtbrkDctjA40?zxSgw3R3=w1W>Du4rxed%yprIrn52 z>jeSc;zjZdYo|!IqH6(M!RWo-?rqdqgJ;oPayy^tQpvJCYw52|o#peycRf+~F8p2# zeFn$ocN^dG+Tkn9W}>KKI|U@t-Wo`+{?g+F?Rou%Nr!>JYa?AA4f!^cfxew;#Bm|r zM4Zg#%ReK--m^z84uOB8rNb)m`e$uw9ekygf=uYC5(3iem$nwQjIYZnZANG>#}w_& zXFt)nKTvw2DjaP9XbGUU1%(6%<}%UM#B{BFQc*#jTt>qVzd>obhy=&{XdXHUZ*aEb zW>2#PVB9;s@x*j3snCvTT)V0cW!{hJDzbxfkD%=`qiB1X#%Ljud%q3DDjwzzvv_OEoB&U{B^7@eg9Qk%gv-lE)Q<;P^te6IO(FbG^gWb)yW9eaS@zqH0j*=m6-);&OHKC0+ZFTLJ0G^(c_*kb|o#KQx5U!0fS z#@GVpfgx?r$y4CVS+WJDj6uT9p{E0{vDR6WM*uu~^;I{l8uu>EZL#dFXBjoob8JqrV$ z`KQ#6S!So+^|~$N`a`m0gcQ+ETmvDxepiH!urO=uvpIl(@q#L>WNJ@g60DKAdP?$k zh7`x4L<-}<{SbZ+wE0Tmg&XO{kYC1e^cSn15g6FdsB7ONFg8~S?z)@i54OdE$kxnW z^$oemN~OeUFGGkB@6~N+6oa0cDVU(&*Ou#N4wlb@*_}r3Z zk6s`H?7|P(I@Y)h(!=Jv%8_cTQR&|zmu#ycn=~260850Pi{ALP(6;2^V2+z2EM_Zp zeHkd71F(A5tyitQel66IN>{S^-NI8JP&TLF_z*CIl=8)1VP_iJmvSk1Yc?NmAF#n% z2M=&hNJ3;#q30Lr^BA4r?t`fXQ46!ip?=JFdfkdsf!3nHiH%J8!~*kbh|C@+7S4d; zIl7+uN~jA>mWc!g~8eG0XyXFS_x(0 z?_}d~WCw<;lFH)?erqkUP5eX950#Pc4MT6rt~U-1W4<%U2A;d6;w5pBcAY%QeO5w3 zU1ZqN?pSNdioCke&hZ*cqW8m&J7cOEkQKL-pO;K7`1}re) z8LVo^gv<;f7G9G!CaEOu{LJ>WWa^QGes1 z=x`@{l60l(zRmi{Z`aJ|PzzqrK2v*h*lb(#!xjI;-F2Y=#^JHeuxd16*Db=2CQ&M;*({lc0A$9MPW9w|?WMFGQ76mNQ;(`y`Prz?XO z*uF=$O12n!?Qux=E<=ml0P^NMBd&XeXIFRkDz(SV*PCT$EydKCZ-re;KaV_1?hC3VKiBw~A`sU8R6pXyz^lF)1p*ZhMbeE*4jJqF zOOAsDiM*yqW`jV0yvXwbWD-4-Qzs-PQD2Ra1@`fK<0la(6*AjLxvm3EQYea2Oy0p&wv_qk+vLgK?fNXE704^HaZ5jZPUAR=GLs=>_nR^G4@zqCdvawOv|0C= zjQX$bG65!dv%AoI;U)c_T2bV?R6r6iwh!L6b7@#vak*sq;oR0a#LQQR!#-BcT+1J@ zRA1;+6`=gm#*=5$jVs+PYn^)pkfD0KuL=sStT{MNMixvL*e`>wUlQ_QYYExxC%(&% zp{A42e#M}?LSb2TwYo7|A*5>hmd_Gckj?ZFw?9hh*({b}d_KjP+Tj}^g0Ejd-)z>|euw~E(I`-Xv2F#M{TO8aHYBQB3V@iPfp()3VM_eK zyvs%1ODVe#%j^d8{7K_ho{`m66Q(HT4%ZeMyTruT8VFO9h(+mSFPvKPLokSJ2}-Jz z{BTuI`a$olSt@f=jk-OeXoy@C9=}REBXss!9iib)X}H3F{sJ*kXnue2MSst9pV(gP z9_)HcoW^p=FZwDuDkYl#J#|!I-PZqO>npsX{DXHT1ZkF*T1rA%x|;dpVBK(cHCZkM88?XFlyU?mp*rfmcWDPK!?(eax2~hCsQU)7Ge^y}}vkI?b2Xkyh z!;-qc8^U!J7%0l?X(0tBX_;l4c4$+t>(zql+RQ?q3yOoJNB8z?$8(3eoYlLOop*&U z9u*8^r?wVt6?9iX)c8O9phN~7!Jx9~icv*}p;acaMgc+PQAP6U3|07YkLMI%zuWY-gefE9WF;8~p+JtsVm{qn7l$mN{bW}+X& ze_I4iyxqYVjhln`#&_%v(LqGO>FEos>}7F4x$M*^EoI@5&oVeIoaNj7FHu}UujYt3 zO7BrM`JV2gGMigKiUU9ol&+?F`Y%LG*`^1`!EJb^FJ_WczH+cKvx4)j+T~x;;Y+-JDzVF`K*f7X@1;bKE}MNYQ1@X>6DyY7cuB*hB&X}B(4=co|L0Nw1*s~3BB z>(x170{ArEi>#(DGi=tvXxdt z<#W?x?ASM#ND*&nFMCe-HL%y^J|ng`?QC}q7X0y>a9oc&dL`S#|t<&g4TkA?fI z@f4+H$_?hh5L+P^X=)gHd*Rvfmrc%hYx~w;fFb_862nNu>c`6hsR_2Yt&e=05z9Z; z|3wXy{fg|N5hCa$7w>PhUdh_5p-lLMuy)YnvCZoV zS0+P^b@;9>g&LJ}9Y^UOP3|-$`Mjk!VisV4P&II;Fhg1Tw<4Yox>|N zgB|mV$>PR+Cf`)seU^r`fD>eVx1+Z6ao^vHb^xQ?q)8|6L&g+wb@!HhIn?Y5!|k6j z?Q&ok@IdV8G)XS7QSOhAv-Kg)O~Sx&k26dfC)m`D9<}H4#5ut8pXq+;M%%-v@l_|9 ziI;&)((;LG0Y_<6f*Y~6TZnvIZY8jQl z=KJ+_+ebA4u!hjxk9_N2JA{BOKz|JZIFcrYXA2j%&hx)|aOu4KYcp(j1-M1V)PZ4B zW~p!8YlacZ53V7tUPx+WjTZh2RE7zv-=h8@Z>oG%)CGx9UKjnd5vFFF-(-EeyF+Vv zdn3$Ed`36RmDG@Nz?fBmE3N)Tk1b3&``#6v{ujg*6lno8B6;IBY|~|4J>~z9!lZDf zN_G5fnVKOFh@gPi_)7aH<^F0S*?vtB;S6x7@zG-&*#S!_*oAE~-ztWCP$TQMKKLSa zA({Sjrh4RbG=T$;nlP)e)NAs^;n>;;3fQ2t^&ruwaYHu;@3}w6wzpBo)}fYrOTZ*b zE429H%6`Xh@G{{V-6v`HUaCb?(5;knkao=UjhNsxNzCN7&k8#*%By^)<;|nd!vVg2EW*8DJB|rqw#?0%f4>$+jxO448$K$^i=>DdgxU-eeH<5c@K|gDUTU&LAL&vuVT9Cs&awfEfo46@?o1Fb**DsFM4ly!5V^-^A4u;Ioo^|cV*2; zPutcO&L@UjHxxuV$n3|KIz}shJ8^XXDqy6~q|A_$Q8eUqUWF~B0JQ&?$%SS60*|2z zZ-wPB>rd>~LMEVETu(u=Jvd5o|0eO1))Gh)EO0N{QbrwifFxvv5BYdkCgz{`LX_0j zdv@=WX>o4G0x^ntz10%qL=2fC2W{4JmQ=8jth&lG`zpguU?uHz=CQvgbDX-C_7t2k zKHcjzXfl#QfcYhfD}fq^Nhp>2SfSk3u)lFPHEPGmERG&HkD7i3EIcO(OT`c=DS7KF z0aR@)kwjueWb$$&#aZPaawht$nry5Q-^U5vZKz%%JXCofS9K5)%L(>oEFlO;3% z>u+|BUozBfD}kkdcqQuhz88-dX$ic{aR878tfTfSRK30}t9W7w{KOD+>t|Fxp6c3{ zb$|z?OeVvOPo*c?whMN@BCgc_uJHtxH@QkpAj?)!?fC+>m_9?ZSW}cEDYM4$U6tx$ ztiq<!;buA}5?~pe{=|oCU@&`D%S6aBvis`)TT~53Huo?A&~P<3?$2ubFY6Q1L`? zj+(m!{_#(PPEod-KMt%hgn9hBUMDisuO&ZGpbkC_btdT$Z$rF1E|5|wMR^vKl1Kak zX4YEWFvN)f^>(iVYas4X>&G};j{wFy^_6HA{TR(=tzTx}YNYk6(1$eJr@{}6Eq(yM zePC}45&c3fEEs>1;yH3{{_YVf92{I#lW)yr9N-Px)Cn1CN#EB!8=Sm(l#09jg2lT7An7Inh^3rcsXmccYTJ zlI#jlUhA%9O<+xipc{Nwv~J`0gG>T_KNTRs`wlW!$cen3tqkA)@y(BoGJ zr%k)g1^!n#g2uC2p^ZDajrM za(Af5(H9r1OOpXLF<>#XXV^a%^XvZ=WN54Ta{!*)`!blonq36w zM)ZSJ$;QvA!_7jKm9xoLvSnQdJZ(8pFKm*u>m)z4v1{i97m^S4Ou2x$pc>pCHw0h< ziFiZVd3g`RIV^@qF6GzM?FMMO97o+3@#%R~>H|d~`Z2kG;U2K_s z)fs)3ffSSsJs0Jwuo`vYwG>aA zK-U{-mDQd9K64)o|1ZcqU-NEW&?n0g!kKtN2yobA-_y$G<)!JQ|AxPi|C$@uQ6Nn~ zWAar5p5wLchB@7O-Xx0=dCl}sU}+fmCGj!loRCP)kPxSw__6uB{N1a~V{6vV`Bs_u z@5)&>xAr?p*cT>Sgo8GN=j_ktK7uMefG}tCcZ@zceS*E?tA0+7Nj7hooPb0rRzoO5 zgRMG+6e@|)pQWMAyVeTpJ$3}kf#)gz1`=2j_Vci8H*VUD4xKBr_q&`j`v-eKbs`9e z#|%Wb!N6b_BA*`h`Yy&eey#h1aq%$z{_t)5=s%2F;!+ORJN{xOeMnK%gq-Ld;@BGV zbMk?Qzvtq3af2J2?E1Sas&zHbZ`roEe z*BW(t$S8J)p!zX5Dh-v^2=t|L_>Z>mpqx16f6UBYWmE}cE}(EDlqK-uyqMA%C^HL_ zT(*>UqN%wFWoxQBA3yx+oXPgETt0Gfe%P>o zfZDkb1pLX~oXDgd4NR!*KD)>!{0dZcy8_`|V}>8gJPV3j(SX$2{p*3GConZ-b=$uq z-iz&kaXdE*_u1{c%c*6&z1wN8n1_S*|D{ zMG@DZi`PAKnAP%s4s0|ws5R{#zZ>(rp?@*vdummZUia;EexYGY-?hm0+s|)8t^3*5 zJhfVnlunM7nHFD5NM_v=Z)FZK5SQ08cD5DfZ|LWKNY=;3c`JIce^!khM=yZhG^>=w zc7T@Sho9AC6d^SV$!cLN3}niX-a7(kCzHlk+tGZ;e|x+WRq&(MoNIBNjzaz^ntt7au&TN{fFX;WsBGAX;>Lv-8WnCbtvT z%9Hu5<2t=}BN-|!gu-^6sh&0A)xi)h47VQh4+waa|JV97Mi=ki^x)&hBNiW9tP+tFyrXT6(q(7XH2gOoX zAx1^_L~F2V95xP^_j^p3HY0p6!*BB*)#gZ(kr2dC2|Xuv8#1;~Ieb#9B}(%)-|pTU z0P69y@_@0SQR8oYB8;emE>hoJJ_{jN`r09T-O|#6sqsxREjjK>&(3NqN9dN6zD(Jb zd9^i5GxhGh@7JkwM0-j>k6Y2rD}Ro*GLr;H4yy_G^g_2 zYR470wy%Vr#GJsLp|p1Ec7~9C>d8kiax%~%CtGB1SPQKo>T^~c<{%wCze?sqbghBW zsV`PNyjP6Xubl+buM@oWKz(`JiH|2IT9G{HO|%i|x@rOId#3TcpRv|j8N1~`)@RaT zPY+3?Uz@TDN5F!L!paac;h>q&;sO1u)nCuYV}mE_R|hy*^>o(gqkz-xGX#rOBOH1G*g^gUo_G=OB)jUW2(K2e&7_8t*kBEWZlM+>-K=&bxJdE zqu_F_`A~+Tc!^^BY*uOU3+W78&c|=jhvh`YS01MiC8-5@V_63`v(QN&OAbk)kM@=z zdj1QWr|{vnjAK6Hf|M^d$UyeHafWr1knWy#>Rpxk z)$iDj5+3iPcE7JEa|e)8i9AI+B!f*R#I=5T;9631U2>}P3b*K1tW2Y4Zx>k`bu1dO z!zTNFJ{I|L^SR2QlM{8sj@+6Bk47xbhX{fnT5h-lDcf!quY^%nifiY~0hYoAOSP>E z`J3{`Q7g!P#h6n*@tPA}^knW+ntP8sI3Q&b1qj9%5KLDV{4>obbT-xvcDk;Yg4)mZ z=*=ufg>w*_m3twTp|M5&gmy!Fj%TOLa=T3XJ%53i#v!9NNadqx1KswH1lw|Z>9Xju zqR^bv>P%-;SB{1-aP4khNZ0Z)D1U>rc?^KDs7Vo-I;*nPS`DVP1cebo`Gu~L`^D|j zPfexAogg`9LoT8m=BmxHP;~*7AR6*(+gh_u-#g!RnD( zLP|pIRF(H_vX!6y?x&P57XKj5xs%_lt9t`|bpiGqg8atrau+LKxN18kWf0d_J!&6} zTg{4H&3sUSoqG4E76<%9gtTY+FIT2^+St24qul)d5VJ-7>L4ep1+=g?&>>sX0iOkH zAhoLHWIEKGX)G)4jtR?W=N}$)01p&)Vqa~5yN~^Hg^Kf)ca0X7lBfCT*Tl-luB-!% zl16R^gw?NAP~^pJYMRS!+RD9>0mO4q%d2OCaB)`I%bTrcDWDfn=BnmQuwV{0f^ZMVU9H=3K^3+dhJE>u9X8 zme1!noT^mpI8saaLx8Y<@mr$jtIgL3v%fD2k~KhxRq(fV=Q7v!`Q%;yW4CJSglM7J zh?-p@aJ}zBi~gQ#l=9=nw(N&5v~=;JwV2=D@K+dbBkOv~$&LK}9E&R`Zfy+ISdl;R zzYKkMqmXeI!dR6~e8}`4xM4}Mlu(8+YlkReYpC>V2Mw7QT=#Q(kgu!BTiL)?oD62L z_In8gt^di43jS6jSw^oMn;rV<*27`NCpuCCZS%s)=3T`^b^e#WSs$7W|iq}6QWfnqXh^q zka`F&gFZfm1kCW65E3mJ=r%NKq4MVeSXd-~j|T6rHrZ-R%H}6Rm&|+guWT&N*FpTI zop_b>l^n@pvZ+m?*tIaKxGD@8WoDu3>?|EcS?;T3UhlPWe;)_9k>Fz>{)HGH^sk-L zCe?0Q&1TV_Grz>OOkgkacZwG0sN(ocpDloJu@t`9G<&ZWny~sY{r$jWbU(spUd9Yp zxA-}J@?EUCVS@Rika*q%Do;@YIl@vrZ`q8#i||uUtn3~8<^9n|)swAga8hbyFJ~e0Y6hkH5sv za7v0!DVY_OW>DFF7)Sh#0=I)FZGnl!Ip~`G)$%qKBZ3UAZoA4N;q_MOuRrW4xA|*T z2yQCGjuPBL_E1y;#t{T+yJp$uy6@=(C&BVr%0_+@hd8=KDSt3%H9@Btm+>3vjnEgI z&C!Z_sboc@I{(C% zMFpzmL>+A+*+gY*XYCgut*pXz|I5cRZ%13zDj)Le;C3x9GHI_6f>ek>X`d2OO9UDq z-t=P#gJ}h@hKrL#c!KqomII|{3VGm|K(pP}tVq*gpcTAMDOCK$!&YRutTg` z&n=$n&8vQ&4sDhd$+l5g?ikFZ_GIlxce&}N9+h^I_hTU1e7M+^QIIf$K2x~~k>x<% z2QZpO5E1u;DQFX|F^@42_wgz}yx@@dBE$0emjIimWUH5^2`^1NFObx92DW=5E!IG- zoE_Pvj(se9d?%#$dCzKKJW0703RU= zjOW7m;Vpk8UGDc;f?h}eV8pEOtboxIb6~G(u6C#x>j=`_Uzfxjbpdj(x1AX9#%^wE zA;3CFJo~^>9y6I=xdj~f3HGt|SNVpu1Q+-$;^k%X=rhZGMu=YPtog!?p5#=dT~>JO z(OsNX3w4Hd=-)G54Cgt`@w9xWdgKgfTXAr|E@PLmPxHJCkYu*{^gRG)?3da3q{+jv z#w4mnuW;^5$#{NxSc)*w=U^s1LK_Lb3PXfV(bN3!0K-M^nU6b#B7lBb0rEZ3;e?xs zOc*b?MTI(FD!vr7`1ly|O#Q?7=EQBN_giag>6bg5-GTin`=2R-mSr)FRict)- z!M2z-(VtSXTHChGwQJd)%A6Z}mDg`#jA+|$5|C00^=^D%IQBEuZfdprqKp>I z_X`i(#!p5K-EM7vyy2Z&`i#$!x@z}d;+Hz!+}RzqFG?@En5F#QoVkzlV8pteL0KvV zF00^*CKfH5eq?@DsR+ifW1J>StCO2CiYL%p`Q|Ic?{oZ0$|6b{4yZ5=qr$U{)@0Bg z_6g%?FKA8A238Z}1t#N1;>n=7joiTJcPU`hK>mE+?y5Cx*XQjWfy7)EKVh>foVt+x z_kCsxge&t#iC5p3e}_Dyz%MS<~yZDR`$VK)?DC61|e;o1XAT^+Utc0VG{e3>{;%`WhzkHYtbA-S`xZKq7SkPf)iBezWrfy3(xA= zWw0pKS~f`B+`RdHpk9-QFAVTyr`UZ2BNEr4svRDJE`Um*p$@ifvDV#L|8PAxFD#3AbL8k0rTnQ`HHzkqRsxN(oi;MO0Ebs4*fLf~W~pzX z{qk25V2-dG@d`%;4slc5xYd{qwy{6qpVT%L7}6Z^Rf{vQNPZJmJ^#szR)-XxX!~4x zI+oM?=atkOh5aP80plTRv3oE%m-lkjFB<3v0^1jBnftoK*VoSii_;qVO3o%V1IB1< zYdBx`>}~sS~gGj&|9 zegR7FYqF)UoQBNU8T=|SJVweK{3-hy zW+rLB=6pMu!p|WF7fjaHcW(z|NjM7vS=tDN`*+o3O_0LSs#t?)bR(HhrL4+kHTMRL zO^-InN9>a7le2e< zj){4SKD2?FFZ}ppfs|i?_^>*exg>Dk-1gNUB{$rD4bXGSpM6wlVwF|5kImHa%}~)Z z-IV_lOURA>z0ug#$xP51PbOl_ro9Mfh!HNvai99MVP^<%7S#6^)*LGI=C&zX17&_c z=@8YaXlTvGk39Spu8QvK;rx)6-{2(4teZ7&qV|zO>#w-Z^1r^HTKwqfJr&0Yq3B3yW=yH^G8}WNE3M9S3KO;(YvB7^e3y`#SKubZCGd=NTn5RQC0p*wz3DC zWcfYxGj;~G;rU_yn1iUU!SuqFfFsQ)|0Ai|Hzv9p zKfneTX6U5=-vHY8-DNYY*@$u&S_~kKb<1@FZ)4H519lVyrd zO3}cOm^v+8OUE1*XK9ZiD%v-edk$e*QSgtgknS*le;PU0l)&`1>c=uTBqb!iL3bUG z4xZ6%^EbCa5LYA_+|v&D{S;c&yldZ7m$FscSds^r%0h8uEoXtpwCCW?$?sBIm4n%~ z`d8MK6*FH903^u&MS|s%{!?JebGfkgWapa5-ng?stAYTKg_4-LBBm)zC}eE%=Ztyp z-VNJXu{>s9)usoAOoZbLKN1$hN0*p)4R|id2b&Cq(;A=*bqA42QHjt}9t%|J2UHUR zkv&Ux54KY*p4UF78Pe7EqWZt!fYy{=>bwxYykRI^t6ly4bK83+J3?qy2(xjZ0T`mZ zNiq`D#$Xe2NKn=Cqlycp{II0OnUS`eIDh#u{|f;xHT>oiprzD~6mK`yBFh0fQmz*l zs)I;m_#)|wqnRQ0Qs;O}8(TFL)4F^{eTilZNaR~(47gCyMACj98adSkyv-g3bSx6k z{|{*-{?xPE7CrqdpKV9e%B#F9aKjuoHFGF{>&*;U>OFAerL^QW3<@C^eW?l|CmS20 z!C7x$Ac~nr6C#M=`DS_nokG^BY4B3nOtYQ7ISO;D&D~t@O})6WKX4X(|14H_g^lrT zzlwCrTHue(f@$Cwt*)fG?Jx-?1CKT!QmXb%ZvIu(2T5TQ8Fzz&wxOI1a3zl?xjpLI}gP|ebm`zAF zHbxV%ZqiHuH$-J#>4?>wo znWG$sGLrs7r6xDcyJ0{y$pX?nV7AmIEXL%(u(|-_)=4KiS9Zva2u`wYqKFTVySGV8 z`xHRMXLICysPiiwV}zFNKUBjh+Tae}^LoavIOc-j;txHoQ-OmXkpZ(=_MP|s(`2hm zV;z}vk|OtfCn;rEradNFDRn|09k368LSaq6pP+8uGKQaIBBUP@V(;CESZSo$U2x4e z5>y6)3najH{-movpJ=-VCCxfe`7)s&XW_|5iZupO5${Ayi zlG;{>9#{y&B~53x;;^GKk2u$`Ou*2Xk#Q6xFT$$tlRuXOAqz+f7^sta7qnF8F6D70 zfbB53K|yd&wiksG>PT-$>OTx@E<83Mz}b{ zwE<^!M;5nb3sQr62CRWvoih5IPbGvls+85-a*e#T6APw2syrw~k!imh5bjwL`X{)oLtb-{ivhhq0?b*M;Ce} z5&Zdsh8OxXKW8%ECzYSnOL(^2DyuGi8%iJ+aO6toX<4H&r|*Zn-;FZQ_Ysu{W067s zc>`2SC@_Y0N>?p>_s3Z5$@yq$%llY|j^P)2?po5vz^sLuTBRSB3l(&2IQ`Dt5sgfZYEw z;m;c1HqvSs89$UN>&W-kQ*(zdLgVr%I^ZS1|60fgRXR==4<%}ENbI8rC(#eb80*Ly zlR{vrM)a+awL}Q_b=}l%6G8mFTh1y_aShgVvY>U?2b({_p2= zYo{Iyihb;u8fo$TZq333a4O98@3j|AQ$J@w*1LtbY}XQfdgCwGcYQW)ztD3^$-o@B zEY@H-FOVLiTn9cfs>P#J)O!O9>RejsHc4? z+ z>LA({x0ry-$s15cDwD9;4yY5|*`PRI{k@3xT5^~{&YG!3mMh_#wnMatgzfkykcBj7}P`=gca)yqRZ*N(I0 zHXA9M!n2W?{nMw>4u1SPP?LB;RH#Fq04AVk)Q~T*541x80bd>5*6j3$y*zq z@vuhGpnO=W8PH4;RFQ@yJMv(@Pi9_gu~-+=@7H{2$ba@QD|eplcT!sNjLXDns@eBj z|85u(a6(vrGuu6xstX8Es?uK!iGu0o^pdMi%+JL@mJv-rODlV1_jPLMl^7pkAA-~) zg`8=uxS5FOxC`$Uhc=ArBp~&0XK_N6Nf^1L3g$<#9JOTibXF2!81-O zAmner#!ggRK4rFm3N%F?IlNNYrb(jt&4ST;5Lgd&Z_5PJeQgACj$n0DUC8 z3|~#!yW#eBmmn$0m)=Qxp$5<{>{KeMLqAftoJpo?DV7+)S`b#EYQd`z928}>y)F4% zI3Vg|OxXfuXJ$UGI5ZMXiK*r0&(&!juF;1b^nP%t)+e~M&ssB?Q1t2x)a$Wo;;0R;T!D)Fp5mX)*2;El17LVf2f)=yX(2A z*x)-t-;@+lto{J8xAk#0dPry};VEpNKoH#Z!9k=D1#gnoYu;5oXM)zc(&x+w6#m&OoxQq*zo}7b z3Lz2Cs|2`ig?^)plO1fUs@|IRT%45cob1PuHXAUqoZjV3ygdgR=YpQjZVBkz+n+mx z_u3H|hhq$5C0#^3yIoPHIKPa=ekG}}TmT*2l+@sFfr#>}&(I zBTBaz{(5^*vT!pqrKjBm^6)=U1GEK|7P}%AO=MXmI0x7_I(Re=6#yu86e!`F7DRTc zp4*hMW!s)HAshFC7Ix$&HSNE852)gcNm(DjdKD9Cjd?MldWfl1BBPljXRL`9`=UJ82)X1yn< zV;#0495tk$DHxMqYs+U1pqa0F_w}j`Meo@hChc5r7 zcg-(YZHY_DN9r}TfU=0A+r0(sFbMrhpk98gZW384bY*d zl8~T$R^Jt~^l%0UC!D|ZzW_uRLHPs7^eWMQ6-To8y^=W?Q$Ze4gq-dES7tjYVjVn% zZ@F{4Alqq)>XS4Yx7|8`O=`rpHJypv?mK?x&D$?zmMNMrQixeBIdlZUt=U|WF0J9} zMYIY@J!S_OQ$N(US5puLeVyG#M=!0?&Y$-!Iunz^0Dw+%ox%@ELM~YRvXU^xEx@=D zSddo)S+yA%+dzSxEL_Trt_TLoQk(4Z%yaRYIaYrc1BY1~PVMlZo(zU8ge5IjF+R4O zS@_&Leh~(w*Vhv;B59XoBf-z?fP)YNBF%nSnzXeHC3^d;U>jKqP272?awzs7% zP^Al^om(5Y0f?~<$X2ZI9g`uCl$nWE={l4ZGWWS zJ@GPVZNLmj$MfE7hMm>6AE0SCP5&DQc^v7|68=HkeMLydcFzIw*5RxZ<=}e>1OW#x z5Bm=fvYux(6tvm{I*;5WSr6al_Yq|gd!PuF16g3xSn*~wO*89-l=4gxOL)&dLU;ymd+2YfaH|#Y?74^{a6A#*HZjp>vpn zD1SS(YfeG`yo&l}3g}pW;acOYH@xM4%O~REc)$b++nFSfqIE@XW8BSThkPWTSxmFO z?iX3ewgThO;-VlxG4L}VGKu>Z1Nvb$mLcmT!b8qsOZG?BENH!}U!$ZtBKNzM+A@UB zd$oF}e-CC=ffT-dI0rkLj3#cT)Q$Sx_NsZk?{Ng%@?O>r_bneW`mh zvw}{%m%ddkq^W=Z$zo>JmU#e60*po%MIWdtBB#S@%I zd|}qo?Ap^Udaw3MPs7Pu+MPW?L95d*$IW}CZ`_V17*JoEsMV!WG7-JepQa%x{1m}Q+0P;mTUF%RB%@x}-647H=J;z} zEUPY8&GvYx_}~34t#GGO#_c&?4NHWxN9zbnuEF+ef3n716Ti)@x4FMbY zg1JXcWgDjj^f2?czJ5uueL68SZXa3D5kB0;U=N}ZZ)T$e1y2M_z&6{9OYln)uasYs z3eKDw%_xJ$op|{dMd~J=N%?Q|MwMFEyjaFgc_8$kD6IB>TSoSMHp0zWoRm{t;ym60@9`6__C~x&X2~B7lh0}aWyUOC#7=TZ zRvwKpPSfggSt)F9AAA8`Q;O(uM{zUsVwB{;6N~(sC}KrTDxWlJjbmPh8ByLO3H^g6 zm$Bhcr8g%zVXS!_s@dL*)8{@Kk#*_C{0QfeJAUi-W0S`TR?FyRPx)Bs6|X~gxYAK~ z6Lg^H5m4S_4_YqJ#5Kz_yQ_f*@>!u+mMqIwq{$xW8om}1^y9D4WTK;Tx5oDyRz-h?^O_{dope5jq8O{AYkY9HJ#=OLV>q<(B!?cg=t|vfc{y{ zj_<)To~&)8dZ%EI8I#DL+fn^c$A?_PO79 zL`o-1DlMmx+5~{-$bj`LMGW0c%N`xLg(W_0Og1cu*#c!k=y*&6xhWC(z&jnMx-?Iv zBN)mIn9#s9NcqFK8DKOrcu-*rXz6b$9~X_wH?Orz5oQ z*dN(GZLncgZ$4b$ zg%NR7*G~)KYlB*nrj~xY4t1>ooB!vC`8z6B_(|Vql`BgWS7hN;t=$)gCE3 za?@Mw4m2i4?y-G0$o@_?CN9cUuF`m=>B#k@O)<0K6y}did&vJz>gFLJwJ!KaycoFj zujNAcsD9?m-OmV=eGKaBrYoxb!Ds`v;K#CgnEo!K93)z{;E=%1hqWNd`@}-4`?5DM zNRSHEVAMnz+@AR?5ONegvBST|Z+kSzbfyU!6=tG+=aBR=j&5d?f*`n^+97+u_3ox+ zCS9t`*UC@(DZg@RmOV8+jwrMGS^B)e>+rs^MyAfByA}8HZr3k0kC<7ZX14)AM78os zG4@V5KYw~nUU$=!O~ror)K}>Qr?O2t-X~MBtF>P}gtl<|!sa|Ia;<_xzT#`W9CR13 zj>`bdi@_auDxO8Gs27;niz>0tYTj~uH8Xc!hJNNj->L4}Xl|*`;#9W7C-X8ucwB#` z&m=3Br-JA5ygAU=UUaMUX1$;D_p(G}N?7P5V1%-L{3iVN+xNRSfZNOQwJ;O*xBg;O z^!fJZ%=EI-a(Y+wT{Ss|l4)USjdUT=8f6beK16bRHe^-h^B}WEQ8%P zfAt!U{PlD>>^9?#%Lw_7x zfN6&KWS+T=e=b?P-dw80t}?w^W0Q~3J-xMgOmCMWeLr7aZgR?UScLc8mau~E$Iy1K znSGya{xG@eaC?P}t--B0XkcJRO(#>u|4`1+($dd&Cds~)(zXUB|Jbo^DP&FJaaIAD z2WTB85Y55y8=ILT{PYK2X?Z%DTG#9@yw+-rsZrvh8PW3OJs0AEFXatEhiswS#x)QFR6PeC8R0JcvpUkP`8SYbXM6qh{d zy5t+AIx`5V5+>sIahP4^`>W8x4+J8H<@VSryMMsE*EpHF3nl6}HqyPRi# zucEG{LB+4No_^Bm{?kg?jv_`ftd&ZI;BA2_YQ;B1^x zG=s}#Kb9!&SJ(Af=>AA-|Eq&OIi*ixJbMW+1ia~6Cdq1o66RCmi}g59;)Za;^Vu2* zaH_g=s_`;#j_Bu$(98~Mhv3(Jhikl29`!Tt;T%qW+_ZE4p^!|=mt-rUpyU8rz@NSQ zdi5K7uG~g$Pvg6!sqQUGfwo*^wSWStKX_Sy`!$o`3Q1A2f)L-suW}$oj_ji`ih%~j0#1NICFsn) zxa9FGU%Lh-S-g=E8?V>&tTcwl+XCxxINb{oYwaH~H3N5=7BO97Tm9+FA*C z%8Gh(`-E2y%R&U3E+UHm#-&{Ua=||SoP)g!+?y-^tN#m)Kq zSn)V%7h?_pq`5hC19=h|jHhhEQRM2BlNXetv&B20XI~9aTNOI608o3lNum~WhreLo zzo*Gqp;SgfER^$JEIaPG#g4~T{rPdVoq8_n+7|w%GM)6PHTR? zAfQslry5X^{9<)=vgX{@=c3&GpEIr2aHS72#&(FlKnf*4z!Pa?ru~L16ty!BfzHd0 zSo#!N-eFE2jiDVd)l34V_lwR4U0Y)rX!F97U@>gOksLk=WMYZmtntJ=!}E6`K`NMt zn+waupxi#Enc6`?Y5sjFRXI&zON9OtU_=IsO30#}b3V4D=8&TLbxy{~Xg<)3l%sLj zIVe01i()vm(2aV65=Z`X-lBBfC}wS*A>$9LOWOhY4ZL(k19I(WQ7C_Sjcq+r<$!@4 z$w2XCQmlEu8`3uDO6+A|jJ({Jq`w-@7Jlz1Sy4vSb?|F;Rib!G7#QcS&dfVi7fE?0 zl>Ibva{~riECydd&w5pq{*{q(_m`2=mM@lwC}kQz1WLEGnN5H+Om%?{H|9Ha%&c1U zpKW1Gg4pH*`q*tzvFnz62tXXKD&EnIq?jWjT;h)wErX4Jvl5|vpl4qgoSwhhBifq_ zedwQh0%-^B7RsO#sX+Kp1mat3R1ScKSV1|Jy~q*xTk@OZ^^2cch8BQ+)`)go)W(MW z-Hp7jAKxtf3ah_&A{QqES?B%!qJVM?7ztq1mUjDYfsC_x&T!iJzCaqAe1R7|u$y}t zn<@oX;Vozt;Hc3B5p-IYj7@SNTdMU%-aZ$GiM`pluq%bwBmI6ocVI)70fd18gb}&P zn^}{X8>M;_xe2DVl;1Y+J~;0!M*rCEsfBGq zL)L>~Wl^VSSlQ|`i56tkhW5UXx>vo{+b7ioBND(vp=BI$ll@`Ug6O9&o!$#=G0yi#mFW$q}R&0PAVxue7 z)q%gNFn<0Pa$Y1 zg}`95>u6|VQ=TY;8C9JCdG-S{N&h@7z|sdsM6W6t`A;Qgl*s{QC}P;xE#**pQ++t* z`4I}?8uz=~n}!WP&CqLVkh*qu5ltiO)ZMl$ga06eHPyWRkk_SIl;7RMI7D(DzWOYK zH2X6#3`kD*fDT822ak*;Q(+O&jTi>9`eFX8G}l704Lz`bS-JJw-4=DbzRcW306%)&@=c!sJXR^EI$8dEm> zm&&98sSHMEU;;~L4up={-?>k_FAco*Z7eDf=+`kP2?WMWhB3)zgC9ryt(U9%VIDL# zKZtyjB)L$ZCf4n#5(|&awmldu4yJ#&4Ac>)%s{r~Z)XZffTU#|sebmGzdp{e`lgoM^#bE9~!Sj#3m<0S~QZ}I*S6O@Ls;@4T*3+FG} zM<1SuDp%JHQPWCzB;kCLBT=C*;`6q)fxNP9tOjGKW>y2K&5#SBhdVTJ$C|)t@7wUhzN5yQ8%zULObJv}(hiPB$l>HR1PH3gp_;2d9 z%KcD~P)*OU{TQ<5CX?9kv95XC&GMS-3!!$XT6x6 zJbcde3`m<^BHZGux`1-#N2aKLxiJe0hjiR)MqC2hg&ynfw}V!O)ZA}1-L55(`u{G% zhBMZ5JBv^Q7m1ozRk7XBW=1mZMKSUKN*sL{cT4hWh&tO9Gtpa1^}KB{w=6B*eknn^ z{&KhPIv#+fqH#|CZYf#Qz4t+ZLSQz~WE`KvNBF~>0%iTQr5diel)Dp}v)L&N8?t`}a&B+7LR)Gf#_!CFD!w=+g(=kW)RYE|7=?0AsfuPU+ z;j&|{T8c9+?)Z%md{`USp^2m9{B~8*qYpQ4?~%#Iba7~Lz4pSRu}k%qq>HJ{xh5x- z@CRo+?yp~8^kDeZ0x+{E#`c;eG?F6FuQm&D~*ynm5qe=hsY8yQvhD3-y%5CU#s7bF^5V`j+3g#DATK4g{*O3BK4?8`JE=q744L$ z4R449Y;6$`f#}}!?wM^)SFPY3&iH8Qnk!d$!kmi_t}-pK;4DfJ6>dz5bpnQ*XN47e zx|WjPcokov{%*V-IgyeKgAuvIZFFwMebN}bJ;PJTRJ}XrI}p+JsGYDS30-dZSH!XC zI}48(DSYJ=xYv`>%~^LOgdC7@LKPo1-^-+QGNPq!d|n!0Fs(GZ;Zj*eX=c~z7e`b| zh#=xLrd`jox;m=U2G2aSrTfQj|$IyJLF+D?BE3@ePM#Zibzg zv{Ni-)Y!Bv z14q_}eqlFL8P-~z7{k1Piq5|nl`mRuD;#EWL#c>?b|NXwa(aRe*D@5kjcnJ+cJ#WO z$S)$pmrh@)s@Uz6x3JnXHQ#=1!6p9g^VG!6hOIO=c=oVjKfxtOasf^V&=a*U;f-)0YtL;KnwmzBs4At)4g=24~Wr%ac@m&bWVJ z?IkmEb@?%eLyh2vU7T*;g0-ET?zdkp)3PqMRU!)R6!_uU5C3!HBt z_JC=JfLa$iu$GO->+C1|YQMGBYQv)If>W=gr^1}cfyAS}D1tIWZ*1voHR;U=9JK7` zSBg^129_V>A@sG@^7p@Q$&LQD99LTupTDE;)JTC7vEtzO!k2#1_5$&Aj^n?+JcW#1 zuYvGzw6~+JKDL5&u+4U3VO;QTu>cVMB4w>9>Nn#_Y2#cvAl=WD8d?#vrGHb45pl|>mSocpHplH67a zyBE1;Y{ibWc(_-v_Vz~q#hs|x$G?qgE(5T;%D$Gr8eBai>gA<$6D6LEFhFR+c*~92 zXg*8+Nv-GfPzXpJTMzyE_6c|PZ1wV+&0%Lp_Q@a$%Tk?|;d5QX>hu96Xxavd%ip@6 z-sdg)CM%rR-Jkx`p-WE`Y_$U6Ba_CVG5^&JL)3Ce>-~FLJv;Xk?av;xuixtV5tVmo zjv{jY(&$t7F8lz2_tqmfx!x(gRS-e-;@D(FKu$vEwn#fug@;1DdPRIZ?_--3NoK#f zr!9UAjUV67rf#v1V0}PfsSh8wX=BT%HsX}W$ly4B!bL9pPs#5Z7(D~cwl-?j>md3)ugG)SKYtt!Z`xK#VjfDQ-ciCgV1GV&tqY6(z#YK2KF*ni#-$GI&X7Fei1AfGy_Gl8cc&Ah&!0c?{JGQa{ zrAH-cdD+V__|=%HFbAgl{%-?snG2j*i&mEjD3Pv15@Wo_c{V?efBzn{ zZj0per?9R#DqsIp$!mqY)^MgdKMKsRnDstl$PnRb40(Ul9YAze+J70#0CXld^?~7b z|MKB4t#!HgZTG-VM~cqWr`px%=tjlAHu^f6tTdk4AG);~96mBRv?$3s6}E6q;jr(B zSpxHrd5RTRuBSEq?K&Qa8*gg?gH3Ytbd+Ai-10RZ+96Fis&3V3KB#AuZc%K}X`S?} zp0it~G={hRxof86$MtDb5~B;>8n%5+kgPL>tpx#}n42Stld+m7es$ty>*;fKA^-4NHc3Z&(bN<^H=;e z5z@K7{1AFP#!^Df>uhm0^{pR5sjTOJsXJ0|^g=sbSUn~6Lxi3Br$qT0g^g%SN(H zGdr${G(`6tHSPdh+iNA--vW1e@;3o#CkA|xkhu2{UkKXAT>sTj(agCZ;%Xc$t zgE1`AbJ-$Hh1~gB3Cfmy2(|qfJROP!$Ey7GWRzQ_dlJ9MC5^$}{@hfx+wZDQ+gkd- z(DC`lN8B~ObhR?6#HdjS#r;rcs}0@V*vLLdK}=LSo7UBRe&0<{K~FOw-bUKjz*#$| zP7jJUHc8q&cyd&cI8Pyk$wz@zDv5xruMA0QI~$2RF74mBd!BD6D|3%_NthcnwCku$ zUB=PV*e%RV)m#ZK?Rb<_b}2_VwH@(meVQ}k`bN0b_>64?TXIteEYAA&>By$1Z4e>O z-Q7X?oiFYfpB&Stgo_Oj7-HWDbRI^h?9RpgTL6$bu&#kNQiut>@Styl{^KU?!ysjw6^iTlr2Y-Vf*!QTqKZwpe<#D62E|ZV=Hh9ys@{lryC&%ftp$)@}zB|8l0VU?uFyDw?a`;(Rw>G{wa|KmA)_jf`dNSo{ zwV3I)m6y?4v0c`XQHeFXZB_!&p=ZJ8d{p9ij>y-73pBNnmn0p709{xgox6tEV`dhL zihl)Uh6|6el5h(lt39Hoq>-w6>xOxel~yjut4vyhJkE@)D$}R5A0)@R=g{e}gjP+A z#C2UU;>IeUN0_q%sNiZU41n_m(fZ`m?GEoUL2v&mxIo;wiz=4&6EPgp{7#TMcn9X# zY5ui;Z+4(=>x$ksgqE`NJuO?o@-M!w! zNJjU_muA@32R--Sj%<;zox17@{Uz)$6+Ypx)~l`WkRgGWiP4)}-Hl-@FahmFX*pN4 zuKX_lDvAxwP+BLTMdX%`Q0T8adLo)H|1-^{rmceFcWLd-xMg;^2v z(c>JjEUPE%kJK*+u$hI4__ip;_DSWN^OTKV73b0@eHt5Yd+e&HFY#WhDuL~!d#`pG zy#1QhA!-a88HvwZX zR>ES8Tq}9|k$+h42}(IsSvLRCoM+mJ+~&G#%hB`Gg`WP(G7Zg3>cUa8hBS$w*u3?J z6&~8b?olm&EZ-EJ@r%sg4rsT3^*&g72eajAzC+Lg718q`n{l(XWDK={v9`j!{YY9^ zLKgEE=SjUvKb++10%Pm#LRTLD@>wh&t@P_rRGjsEFl}pvShGEpw5_^?ahbRU>wA@I zX^!Ng&FPoY=wapt!*^G>@QPC&(sIp&sPJ=i1K#m>8F5#dyO?Yy-9QG}LpxTOCP`eA zwM`?bIB7VUUs3Wxd-Ha+x$V#0zpf;l@@1QwLj!I71%1ibH&a>JT&JUEZ1D=i3ta%9*) zN~M1;h%^|!?BEYX zD`AHp028g31UCt+8CZmO`VrZQIcrjqhxatW?-iyo2C??BIzmreW1hV?e)Uh<6|m_e z{tcw=l;UrH&FkOWMpkF|`HV>lmZG>TGP>96sB6+b6_se&?Zdhuwti$SdqrAHN(fy= z8idALMmBl0L7Xv1F=^%I(Ego+y?%H;@fPR&*W$C`^TR9W%)h^DJgA0s6ut%pcDcQl zPU1s__s3hV2Nay6OCj`Z{$b^XGGNVj+5IGN8*ba8$hYyUOyo|8VrfR*sdIpNkOu)? znf!3zsJ?Tm5eupL_6Vh(I);N{m4CY9guIC!$A5!E(Qt~czS;S1dnv$YdR~=PF>s1N z+&vfZ!azlzqfxAx5V&bxHvEYRS>C_A-7O~qC5qF!-L3#=TGzzS3nC_NJns8I_0X({ zi_tV`<&TzH&%^5-tQ{IvBC6{yUP1ORPTZrv7`!_?6I*Ge{LF$y>ij-xuBg*lH%M5$ zBXzE!#jg)LNT;+b*<0&@mK+IJQ9Y2ng8elSqXci`f)Q49o8~WfhWSxl`mzY(3i{(! zCe(|*;FS2K?}SR-+PwK-@0tk?*zzQfPq?*0`(wY+P7GTm=R?vh$umtD0WX~kQ93+a z_@mf~HekIz{nbQMHnRfloS(^KNT@Ql{@aaH^nCZvnlWhmje!_7gl!ubkw(fW4f<-rdGD@oPL% zEOHNVUPy^Y&=Gi=>2lrbkp@hz@dbn?!asLZ^y(mDJTYT9de_}t+6(s#b)Tl;gg&>} z!WaT2IU<<@Q#w76;@p|$lw~!@ryc{1Xk`_C01wS8C|RA>EQ(4<kIAuMz4DvlOX`zuk17ym!S2x$PnVm%`2!5H`? zyuxF6w}!*p+-oV+**j*_a{Q~C-$L2&u+pw8;04u=z~_Il6vO2UncpwRWqN3x)?h2#=0fb=BV%kl=)IDj-X%=8W9nNzl(zvHwN)4^<-5sv`xENel3lR zeRi-&ell4RUz_LGLvZI`xLrm3b)wbEiAhn+q)O(^(SWVE?fhiqTix+TCOPyjiUvui zKNnm{=Q(kL*Ycj4ioxm<6SrufUJm`MDI3c_;bPC9`FjpKQ4-zre)fKnBOz>L;i+&Y z8uyw1V)Jm~$Fsw;S7i~q)FKMAcpU8U)k4<0*V&JIjVg=QQS~=-F7&MeGXN~*ZlgG? zD5krDb;9RTHZEtyNOCv`Yd&upY)!h2@9q1>RCII|tI^;r(?nPOnf^MX3Fzy*m*xc9 zk21yxW5m=}%Ti+9;~@ebXS6+zm9_TWW>wAlzg55tp-JBQj1~M3DMuO-jEZ6`>~h8d&Rh)2fof z3dZ!?kxa(aq@H?>^FO+rlybBOE`KzWBA!a!7_IwugARvn-P@YjjR_!!@Bhsug)`B) zW5v!}y^kQ(90p<#ld7oNuT$qSA9Owu-e>Fwk}H;-1`}kDE)KO$Bn`J_v%sQ)>P2Is zpz*)V`(Dw1T-BXm*ROQeNla7yc&S69A>L|=#qN{@O!z;$! zgO7UQP0XnpscF{lgyejQ|8{-6gs7idt^vovH+3R`V6>ZoJXtVWd2)Pc9{FZxN`H^_uk+dn@Rww(GFWPBr&n4Au!NkYA=hy29cUF{nk8S?9v zH1|2U>QF<^4K@I=htrNI?yNKpKV2A|wfRIO8zycDBR*fJ!k`)#r^`LH)HB|LV$8p; zA6haCuC({5i`E6{0Y7d@g8UCcRiIL_pC5)fkjwl`tTXB7&Sv5sWw?^jHfpO;o66TPn0k8}2M_)KyCp;MAsW)h3Wc?VU+?_?KFw2kC7rNSZ1(=SA zJ_Kgj!spAM?os;w3oZ2hT~6D=XJgd)JI(#fYG(FHf8NE`<9!ybmY(>}HKFOhnLFoV z`I3K`A4=un%L%Aijh!uAtT|Uv)~ok2r-2>jXro;$Wx#)?x&dGV_Q2U;zspdw+Y}`H zq&jKNo=xxiq7>xZQYx>Ro!4QhWT}3=K3i1R0_m*BIhf?d_X1pEk<>Ae!3 zJ-wiW+TB}P7$tr6L9t^{PFy$3MZmHN=sJF(QfKnB=_3XcT~5XI{SmPb!b_rW#HPN! zWD+8%y(xgEL{C*IAgI4oC`ijTNxWxB9N-SuhjEAF6?IAZeOpZUKZuXd;k?onqPM;OZm zJ~5oNPAeCB9;aHhkgsKnb*v(rIkgqiZgIfcG{2W9uDsnh^qLVt%&d6rawwxk3Kz)R zH4eJ#X<3D4mGn|t>#&-MJD;Q^eA=5&=haS}tdfy9QZO%TI)z06hxu|g7?8s!&4AS9 zcB8UjrY=f9JN4EzL!pZg=od#_B|m#vbH4ZSYND~F9YpHC6+Vd$6gw+1VMbQ3Ik*or zMUG#jc$5W1?8yd9YPB^b(0P9o>=LLKhcCz5lr?6#Yi&NC=;>IJo_KdkkJaTOr|U;v zhXmPOjV&@dw^${_08CNzF>_E?%rj3jKRx-iFr|9ka|KrlZ>K8@j%2W}qPnH1mWBj& z)!+kr$#9K#HGNLNklbjvK69ftI!iXPX{6C@!L)3clWJyL=^+}#!CdZ5joMVKu*U2b z?hC@#;Ht6zX*@jsj`3#=cIHBspDN01*DbuMNRz9Wo~5bLbL#$@p5hJq`U_r5wO30U z)3S<#qinVvf}nQP(oSdpD=!cplJ^|;j}^JvP~~?sV#N7?kf}ZdOXdY4b`e)<85QL;?y%l2on0-`>BmIn`<|(9>tSy0i?jTl)Ft zikSpndy8pCE#Funb8q%C%AuNd5x428)D(lhYxF$$S{PC7z3`k()a%HyPr0RieUoVq zOk_vcKT7ar>HoRta50;=p`@|AVmEF9vr?T5Iv63F;nJOuaDAE#omnz5V$ahRdj(A9 z4*%3B@0LZj!L${OcebJ&C%)f9@w}=p$_TTv&tf-Axo9M$|PBl{A zT$li`E=as9ZGr?q{h_j_!$kLL*B7smvg_l*%uEfbj>_z_Ng6CkA2KmoKV*3{ zCAs&C;?6}mOK`R1X~#ZgvS-3s*m8^_L|5;nkr|z!0}7WDi)RuJg?j#0Ze*JF1{}C{ zSa)@iY~lJcTZwLMh3^`Pt0M(jY@V}y$)x4X{)hu_R1rvk{q|F(dJ5SJkA5bsonGD~ zfi=qdKp}U|Dkwt4F7hb~^Z4Nr_1aOniP5h+6)frOEoKu+LaW6kMOPO|fgb`~$QRS0 z>b5vgWd9X5hfrhO`~OQk(vp+P9FMMSUs7BONqF7?9S&-4TKf>L!F(`?u@XN zW#7f3cjMM+e_wl#-RYXzUpAj0CRmRI%y)`nY4QpV`BE4AS(^QBu`(%>Fq)6W~Fp2xNh`bGnoArr@?cXBxL`CU12tV zCn4sCQ>=SY@o(P;+~8_?sa5rKDKVr-Ln1z%!GXb+pTjZ3Anw*ec`@wHAR52qmb<%_ zvemklRkdu#j`e9tpFZDK_!`#Rh}l2EC4P)Ugz3w!?{js;1^&K_GT;Jn*kT+D?2OGK z11Y31zHDz6pr*(j-zz z?n6hAVeX5Qli^}OczD`G=ao^b0lwQ*uwpNFOe;T97K5gjX!4ZqG&u+RBj+PE6r}5D zX7%dGUkZuQJ!F2^cWt9meWYcV4v5Olv~LQQuO!~Y<>I!a?ZxXcxGhYbkldih1)^nB zkrQO{oVy{AQXLQW<&k=Z6)|^ok;$3=PxX<9t)a)Gv8I;78`20X|KC+&QEs>0@KYdF z9bzD*QubDY5Y!&;kbWXD4xSsSrz-%S@=MR_9>JFS`krS$ugC7LN4)A)yGBI5f-@JF zRBT=lQ35Bb4q$V}Cz*YWd^Cv&OMLSvew3Wq9}~u1uolxWrbjIXtPYaa&GyNobg9#1E2ceNwqui%wxeGN8vMyh|L7#tFof|kZxqapL z)9^3T$R{(i_A~dp=C2-XZ>_qv8JkdStJuc}4<5)9IY=Y^d*$fK6hs~qvab9n3~nfL z`NE3S{RL`P|Hka=5;~#K{MqjI4Ku((2@IQrr>#BX-W_+w>fy^Xmv&XG+9b7uG&}!2 zmegLa0%l{1?TE^7Ar>^nU+c}}Db@$C@ob_0F%#(ttUPufJ) zgM-m2ZJ(FDX@A*uS&MTuDpJ}oBsZ@e3w(CwSW>JZrd}_MQNBPj&Z>PS<}c-RAuE-~ z)`MjyI?Yk}w_rcZ{uyCa%l?~d6AMg|gsY|MI}HYay#kx6Rn+qXOZ$`StWv2N{itXA zGW&D27Pnu5%xxQlnwOW?x_%N>uWR1Vu{|Y7@62YtA48BFQQjXKO~FB*j&Fuv{@ z4&*9pqREn#_6s;^{{CEz%-nVSo1GJuO|VDYcB#^3wu%Uak21)|=T7HbFL{&@dP9xN zvdCwEvk*yD{|YKopy~@J^^WZg^BGah9F03x^1Ri>KOV9x`tG*PWb(@Qzr>e`-j4K9?X08A?IcH>);wGyu{IPnnuhu4X=7TV^z>ioK>}|K+nN=d^ z88)&S=3_WxWQKXVkx>9g?Z3m6z{{2lJBoCut0eHAwDVtMJXWPIZPO*pcMukFlHQD&g z_j3mg{u(2q=P$HeA&JJi{s#6tuy<{}{BWo5^x(5`!z*$17_>r@H`G+x?}re5vzg1o z9V~C$0(y69wM;w2&~#E{qpS)~!xQjYote?DP9sj!^R8WuRo{)C=MLJ#r6)ZH7L!_LSMh_~q1Od9%dj@x;1=93 zKX1NSVLAbX70WjvK+?4`ZSbIL5=X z)g5(YLMa}4zKyjdWf(kbrf=|=L^7}Vv)LqDH*@e3*8h5H=Uaeino?D#P=7>NTfvuI z|4LW~_0q{pIj?FlCAz|-yR1W#X*pec!Gyk1=;g(( z$#9ETE$PJbZN|5L`cGPMJw5t0c-Z&Qv0-*w={3i3yAZ7CnFN;-VsB}Rtu{tCmihPI zC&fC%Lej_n!5u+Fk_6$N#OY*4u?3dh70Lc$JPjmcT%G+n*ds!d%$*l-$LR|`JZs0^ zIL8U1E*(-?WdYHO!lI6vjw=pcl8$HcJT%sa;eqlF}zIPIo+2P8V)*TXIb< zwH&>XnYZ%D(lfvty?Jr<(eu$T{xIj#8?eL@T}%Qw>BHZz#OSg1sbm0lhzUZdg%(aFs1EtXz_Co*5ik4FW554MUNnh~DSq$r4>C!N!xF zto!%Ih*RYkz>Phz)vKR2(Ieg6)=oPDqD#MDw@Mja8T1wr$YLuCxO4o2-AOy(9`zYb z39A9VLM{33bn{$49$80RHu6@2tj7IAW%9(XlNUQVbikH9T>oT<(HS6ry|Jc~W+UDx z(~Q#HAr(~aD>VOCJ?th?>&I*uGy-d0RAyiGXs1{rERevAd%t;Rff?s1!IjS&tnQLS z{~4?h;`WfUFLkCo{4uw53_G}}^;NcI%07yJxfRQa<_^bz<1;9pAT$IVE#$V{@yE1) z#wqUAQ86!j&yJS=S>d#9@ZLWAQ;8&8Na-JSm7@W@ju!P1b^VN|S2%~rcEQK&N z`aqCsW+1+I+#_e&6fE^*mPU+Xd%Vl^PHIoP0C+VNyf_>)` za_$_qsKdQ14xL9=cFnvqpIL!8iT>vmyy$t=u0n}13f6XaCQ5sar5l^gJRb5}vDWR+ z&=(nnLUk6dEBvcYIaprIuX_4GHRan8nFpig9)PD zv}s05PM+_MqbN7;JKZu&1V7O|Dy6v9GA-gy)YbkZ6PRN9_?-RW(pF4a>84sUALmWh zPU_okM%b-YWbf}J4fg*@XDfx3=cX)Nr~D}RcA(@Z@U$uJ!h0Xu2Cj1J#*)wA^ec{n zv2WpgU%I-@_v-@dxi==#-78JuDq7>IPqE}l z_JXf`@lf?Y&PcE1_W`YY*e@WmO*05uzY=!!O$L4pZr|Be-Fe|?zwCHtloL$Xp3gC) zd-nKzn`mpwesX++|M2O-qnSP|Zh=_*t7siPva1_RzI<@;{nT%t$bd)<$E*ZnA;MF| zY5~hWZRm$6Fx+j&29J~^a!0i58k<+CvqwH=&0)#I(|{-wu-_n;6eJgi65gGAlC&TA zjm-)8#Bt-X&X8~>2HOU{LGwMWPLVNJKsL7O0Pp>};ZpypH>PZN+$oZ2*5kPE7)7O|wSeL_1&r5AzdX&y7pw0Pd)mAet zbeQ8CeH(=7luZDTxt;XAwSDJQ+1W4Kx6$K!C7rb`1kFaYP#uKRQa@4yL3xy7-TlZ4 z^^xnFZ+FfB95nJ5z;hG&ZuTS|(o!V}VxeD$GJCF`*pFl$X z%n^qX^C3pdn!5_ivQ6klm+=?SrsY?ruPf*3-=ZV)=%V_6r)jYlY#2!m2l4V!9wC1> zpn}VM@-+;=j88pN|GU@+1}=7`zJ|H%>PK6Lj==Y0Zz&0~fT+tf(+|AMKu?!dG|ieV zc%xXyiR3ooCp3AWXQSNcChND0*{ddqH9ISLw?cOE8?f(kqSHJ2z)}f={l)I2{Gazp zp_(l~rYs6O)cPXgkzCFh>zOg#vODmt3g8N1sal>801lp726m$dmSJ2OoikZ7OYgc~ z;5~17uMLzruV?|d53}oqOF7a~%7Dykm&S2o%U!r#9 z7OjB!ie(Qm;sV6C|K2p)xb>Puzgz1IWSk~7o})_^c^c)BdUvqk^*PJf1h9j~?cK#3 zSks^jk3YG2E2=N2zXN{TNXIx<Iv(PgW5yR~L7m3k|9ILv{%WhN!>}#&$ufSNS1DP9 zTi5nNYXIWtH8y75CeVI!s>Qt8yAqhJ`*h}Sf#}Vj9wj0yH?_v<7DE;SEaw-EO5I9W z^#QYWtG*1NOSiPJ3ssTOaGo@Pxe7tW?jUz$|fUn=-c0iLVR!iT)ktpzSPw| zWj1o`Iv6oZarbV9t@L*Q?qV)BE|~3mqq1CHJ-m={gr#G5P$Pbd@a@~%@0NZK7Yq)B4!HAu2~*_*<;mAE za|Syz!eXD^07C|*G{bNXI?=KQsb5Sq>hLt6KS~1@qF*Z?eRU;q)vIPPGsci>C+H9c zY$Z13`!j98Q}y?%%L>ai9ge?+hz{*i=*Mp>=7>%mVXpTP>&cMW{uk7Q+BZk7*y{NE zBMNRjg{T@N^jc5JV^HRVww#z{5s2`AF$(m4+{)WdkgeH}*|TA7XlU&5)q>)E;oh#j zf2ybdYdZd?0E$m^oc3h8`OR07@Uq?ZAP;x_!!OTxP^F4C$$^6CTh}B@*^}o!2p3s1G6Ap< zo9@ZNObI1rEY>V}+Wd-7Pu^OpnYzKzCN&`bsfME2^(8*Z+;ZCHSD7y<^u8xSP<}!$ z%Gh&idjcVkDj0mB```svRn{7?N^}}W(ZKB%o4IW=#kRv`Ta3uIp_UtaO6pj zoT;H-lzd9gmQh1&e(7Cs9_lr)6a710Oirq$h?mpRi8h*TsX*t&dVDwc1x$L!NIM1} zBNRn-EO*F~1Cz8LAe^^PZra$>oTSzB#`2xBZUDEyju(F~d)g zk^cVAydc2ILA)q$2f{#ecJvStpa|ccda(~j8&xmJolBB>!NOvs`=F+vg>wUZmZ!BT zGTPFC2rve*=uOQT@QP%Q-BQ^ zrZe{kdg8p0#`3c!jH}xw1KEEuL{JvD_)S>eVbI#9HSy{5N3Ysx+lBw|vg<9NHO|~J ze?qKwuA&Og^pUfaXbSpXko#0ElN;A*ts`98=#5)rJzkvG9ntl<0=%%OmB-znTol>D z8hFsJM6}aA{Q0CeqFe#K*Kxq%g8wRYR}-P^SOj2!T<_p^qJi7G@vOfcbVPblF$*Q? zR@XgyKLQq3RxD;#3t|qXOqDi)ZvkvdTOnk(1cVmhOmE8%(r|-KLnhnj9FjTU>sZP7 zGVc=KTpW$Ma)Wmg{Z9KkrW{*i_rAR){g59<&rl62Kv3FKTV+rCRXbJ%Lw40R5q#aN zyIO4DW~C6;|C#Q*^5>#ZAM@S33_vFKh5R}T_!4N~dPo-enSRr5=_Seo^5EO(h>cb* z?rQ5Z9rWIvS&(aXa;+IXbdFrqq~Op`QE)?mnK{7+kHP6} z{K($rfbu%e=@;vy%%&|tR&>8xuJ-8=$>9r5ac_>I3EzOLqc*}UZc~b2a^tXjc7gOY zpn2>o035{ZjS(j}O8t_&-$Fl1Laz7N0{3M&4f;u4F+jMkS%c30GZo1v3(SAibkOw4 zjOLtrTi)Q+ulQiX0Tkj+x^ZL$KC$vTTGXg?TpNoqy!~@G@%f12dX`%sq25J{o3Q3xOQ4N+r=YYebPCf6RU^ zg}C?=D6gmb&yW-s-&3_W$TZ0;2&#J@1ao%k4frL=q4kWSCbP=LKJyV>FMyF)B~Bw= z%4;&NI5sEiR((Q0$0ZB9@G9jZJ46*-$LijQ*bwA94yQLoI{pgxN#-WH-8d9xoyiqW z3rJ~Y_p#xQ7`VGS)6NASD~tXz!Q>3T!(qWKGwH^~@m%ps+)hu!1;lkmfOyCY9G1Yo z1Yg`dEBUPguh_G*)QH>KNap3ctXN^O*E3swFjc85n*@+mp|)CU^7mMd+H-qP-N`s& z*95NQUB*y@MILFp**zE61@4zK_JTU6&(>kav{2?35;|TrPFzSjXG2cu&Oh?Lg&Zwb~1M9s~>qa>e%jCm)VBo&FUH)`zC%C^e&a4LJ*ZrGxl1q&+cYYG2r75}}o56FcoC=ZudFoL%PfA_RweB()U>cUQ870LrTe-Q=b>Pr+?`l4Ly;%C zwn=*|_}}m#xm$2vHk!+je zzh^bEu=UfXlQSjL_GmM@h&%p?yAyb9d;8=M%7LPn*WaRG7!3YdoiC>H_Y5%2P9@2L zWAx@B+EBe+^l&q?T~!*{eMB6W+^o^sB!T}k+GJT=J%agr%p1yD0sxNxI1dMnNdJ*i z#u^f|Vd3hC-M*q2Xe&Jd0W3i8gOetK${AL%>`r0UH<3`$aqoueA~DqG8AgeL;TK!T zKc&07?#W#KF1>tN3iD6Ftu{rYvU>rSb|*nvns!CE;dYniq*Mn72liUShMIuI<-mTOf3^ti)ioBUyz92W zKdQaEP4erUPUgrmUMH>~vK2hX5b!4`6(wABX|ZeVKX1aqFKV)g)L&d@+7t z=j1KmSZ<+aYo?Z!w-3gpigcA0o=JPiq9=q&D~KlpvOb%nr2uIuilBtM(omXYz#p{7 z2l+9ES&n9Ib*78G_T>$=DMILWp-k%*1+ORX-y07)nKX3@h4(5Rii(Mejr993Zafro z$k&yh%G`P)heu5GXYKt`LD^DHRhRg(cue~vnCrf=^%dR|;NQKwI%=QpJP-MQk!{1E literal 0 HcmV?d00001 diff --git a/Easydict/App/Assets.xcassets/setting/.DS_Store b/Easydict/App/Assets.xcassets/setting/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..371c0021ed33a039f9a0c9f384565d46548284d5 GIT binary patch literal 8196 zcmeHM%We}f6unLhovKhpeLz?gjl{MpDFGzJCZuJ-3W-#(02F4DkWM=tS2L4FsH&7T z`~$zhmM`I7Si!mW6wRY$k_9LTdt_h7<9lqM>&IM&h(v4H+a{_Jk%h>zx`gC{!0$O0 zLM16#gA~vw^5}>h8c?62LTyuE7%&VN1`Gp+0mHy7Fn}|ggLTQduiu)~Fkl$?FB#zd z!A4}+OypQgwRIp-E&${_id8@!et^=k6WL7USWBe}Ozl00L{%g%hS2JGZ*z6XW+KO0 zYIPD?okY^INIVpwT8Eyks*`AHX;Q<0VW7wW`|j7^v-j|9W&HO(#m{`%b$#ig4lk=G zh+98YK#u4-?U1B^V)*-jf02Q zhpP4T{X?Pu;!{p{6*?nm$JC{L^g+^lJY_xjoSH%K%o1OR;%wrLk8ETux?> zsWIG9beyb?ukNw$MRC3UO;qOQuUuWQ7OW-fZF^si+OZQ4qm~oC=3jeK`tEt&abJ4< zQK!1LBZJuSf_|tJyj~ww-n{aHo*cF0Fz7`}x2<1Ti`HVNT01@6eo)`E8;!=Px&^GQTORA@u(TkUb%Fbt*K37YE)o+HjUO^0YaMALEN%;6P!=>)ZUkVS=s0Pukn zt@@n&tSJ%?c=#mSg&X_pZVYeu0NmQ*Uw$5U@r++zw};l}@%@`wI0F0AhwpS~7s3Qo z0@;Uf==$(VzrB6iKDAOrGr)I0j!&UGgZ2Iq_}`D)2k&>t`euMXKObLmR@DT&O2Bu| z$36u_AO>oWw2i;@UAUJhzv;q53myZew9a z=eNf#bPjg|^gAS2#Wj#1aWT=3e9lTAC3KGa&jOv|3dDvf-Sy!$=Ps#2V8B|MiTQK0 z2?r8l7MTJ6jRJ965C7hWJ?(uuh25ZRDW5yefB@IzRK$Nxz$jlq&=_Fmlc)@29S_}T z-`2{_0_FmwC7@bK6#(T*v|NbRe(J)WyAV>an1H22rN}v~BX{eXQ6$}AJG(I%%l?6+*^s1DW zA~oW}Lo)zQD`%A&F!gK_w7hAlNeynqf<@Dk7c5z+q;N>BTQb4$f?m9|&H!?^*)4h6G_47+`d<32WLQ^Y-E4cv+q4=h zdzFH&M{h^se(tLl4w^qtLUJw&W*Yk#&zZdQ^KA2=6%ywAtAdm=tEa7JPyP9xX*Tr) z&dmZ=r;v!500AVR=J?h)7im_qfQPoP;*puh?=PWT2(Se@eexjXTn}KaCZ@P>(I*dS zK8+=z7MyC*89Mb$@1vE(4g|8b*O)JQz#9f8J9gDW(K`6Tl?M%{?Ek0gR4z{woVlxmzj$1xe#Yx%51# z1eo?sGfG=RuK6E5Rsp=E#k_lc0QPF^+SdOCNv^DF`w7b&00000NkvXXu0mjfEB*D2 literal 0 HcmV?d00001 diff --git a/Easydict/App/Easydict-debug.entitlements b/Easydict/App/Easydict-debug.entitlements new file mode 100644 index 000000000..3ec06c59a --- /dev/null +++ b/Easydict/App/Easydict-debug.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.automation.apple-events + + com.apple.security.cs.allow-jit + + com.apple.security.cs.disable-library-validation + + + diff --git a/Easydict/App/Icons/.DS_Store b/Easydict/App/Icons/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6b00d0de34791e1ac2df4f924dc2fcb519f6124f GIT binary patch literal 8196 zcmeI1L2uJA6vv;p!ctABIe^p)QY5Y$bQ>T|yM%5WxDo^hKqYA_7A?e6n-Za_QqJSU zaOIQmT{yw>vpc0pHzQObD9@7pcOC!T`lrP9O94Q1CxbnJHUK!7mAczlEJ^CR%C)p% zT3V=0|DH#RdTM__w`jSnE(^`FA1pi!NaW7 zH(F?=r2`8J0Z<#*ObP242av}z>KiSzk`>3)(StBnVL}X{?Rec&-BEp`g;s3`q3s~d zHwzP?2>N#PdDI<*ua!$Czy#_9RP63T1PO%DUx?p_7|X}lCLw*6$bOW_i24FNLB0Qj z5)EkeNBQ{N_`gQyNj%Ovoo`}evvK3*mb2w-J8y$inFm>zO~&1D^jdv-A!QQH>tXaV z9_Bsw_OVQ}FiwXfGQ@)+c6swEP6smY%1JsHlQ+;8oTk(4x$Wt6?@?#RJJ>&*?Re9} zeXKt`cs!dmojdm)96j%yB_C3GK{EkimKV6CKVO!gv1Xm;$6%BuGJTJI)i^EUIsrv; z{#N8_s$bAirfPAo2~*1~Yef6-3GdYOSBQ$cHKNzL*M{h|v#bzx7w*jRI!qhU$3Q}`t?mEiqZWl&(8WFbPrE4uDG2hAmnaS83V`Rh4>% z|G;11$}i!+aDwmI-jt-9I81^{_(}G2?eB~0?>R}IOGKhI9@L4dMC72buWX>Y#CV*` zk`+u(1zvzp6won^DW)DJOK96+6|f3e1*`&A0jt0&D1di1n{&l`Uys__Dqt1(FBRbD zgNwqxY5YQa_2@vQQULfOx|N~L=>T(F3X@_8O-H|La82VE+G{!q zlY9s>voINoP_yIuu7ZsLNM?Fd3O{<137KUaWohyZbuI|WvAS&RA;mLliH@+*xH$Iy0e`v zv>!LN=kv02@4=&|uezt7#@z%iQRi%98qq%5KAq(_ zyj#+o61@Q~pb#aYPdPO2jWqfW9Rlam)I1#$tU-bsa>TP-wJ$EX_Wchftyu+DU4b?I z1*@F@?_GWVzv|1d-_I&w6}W~1qS)@VTe!ga&(8d{IM;SjKA^BMZlS%Rpi=2Lyh_L6 eFa9t@+Xa+4P2(5ZqX%XW0+bB4vI_iF1%3nDsx;dG literal 0 HcmV?d00001 diff --git a/Easydict/Feature/Service/.DS_Store b/Easydict/Feature/Service/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..573ba90141c60e10e72be0099bf2c88d4c4e1025 GIT binary patch literal 8196 zcmeHM-D(p-6h4zC&6XlmP>C19g11GJMq7$ENsLIL{$NUrsKnjwnl5g3LVgTV0=d?A z@D;r63-}7Yg3sWUe)E&EKSnQV8^JkY=4@uZGqd}hIWsvMB4Uk^S0O49k%c1k+A6AF zi0Bt3BRSo29h$+O$lnS1p&N2HgEb9?0mFb{z%XDKFbw<~4B*TbV$C`CRj;WH1BQYB zk^!+l*eF8Rw4N$0w+>V?1%S?@SqiR^2S^)R>zdY6rKKsxRM`X5rc9?8OqrwK7I5gA z)>EaGIWc8UOwY`8hQj3Ru(KtcSWRhD8wLymSq4PzUZ6Vl@Cg(7y9lH@%B>$#r0FVJ zM&waIoSp*j(0lT!AItiM)#sE|ff_&tup1?j>_!Ti2Qr|DIw{=8c{q1G=;`+jCvGnc z2E%gsE6XkA3(G~TXsueWT1R}`8al(#pyBjih;MtGhwkj!arXm%++MqKpGQL{i2S}Z z2s|H6dO#nTny_qNE&N#$Kshv^!BtF72JqJqcs1BuOlPhU1cG153OZ#5p`BQ!a z*+$Nlfh9G1N#y?z=D+_x*LyI78wLymi)Dc2o2_O8_b~g3n!X*8YuhNVQG^KGRB35~ zN~Yt`G98CL{lgH~HlV_$ru9^5v_LNWMZoO;N&Nbf`A7VWHRu1u<~`>8moc!2>L-P5 BHrN0F literal 0 HcmV?d00001 diff --git a/Easydict/Feature/Service/DeepL/.DS_Store b/Easydict/Feature/Service/DeepL/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..9ef9b40ee68872a0d366493f335f0de1a8207788 GIT binary patch literal 6148 zcmeH~u}T9$5QhKJ6akxHWw}of@C}xj6gCRlSxMAFNIW5=zs|?;5%r&$RXk3?%0m7L zv;W@Q%x>;0Zf*hCVt;=M%m7U3u6XfbY<}N;WCtx`R65t#;}U1M;_qRU{e8e|kFmlH zF7P<0-{Bb@p0MLub8OEy-Q9ZAt(otC_LV+=3*$^C0wN#+A|L`H@LK}jduh|7RE;7a z0wVB9z~2vr?pmAnsqyOI5Jv#&gyAsG<19ff9-!8yeJUd~%Tj8VT03G`mNQ;jUTxZ^ zW;rZ&<~nU>YbO+o-5D>D4y&meML-0G1P=3Z=KX&~|Ka>UEYg(-h`_%hV3Xzba=}Mx zy>;|(-fIi}mi}SPjdTvtimB0xdEu@2bY5PcJa1Z~m?Hi7GffdAkONns=SQCVp;sBn5>OksDuKgQo@rEg{yHJ3;f zB&f{5%-h@DnVo&GJGTI&H#y%1+5lQq#pW8#9MN&r8EK@RRiapo365}wQ`}%YGdnth zfneabF`#F60|Ojm4_Ekje&0`W!4rLt5xThCEy}ZDQ4Z;)SH=#t`(nb@cOqTaB0be2 zb-tL>0rMK;7Ny-eb8?iY%#}+_w&4zRcm`~ zT+~+OXUHFCfHhmCweA=;7zhS}fj0*9e#oebdBV!kt_~V|0uY<*Hep+T4Adt}m?x|p zIYJS4CAzDmCx*B?`?EAJPgps+J0v|mB&{szg(9{(<7YM *)supportLanguagesDictionary { + MMOrderedDictionary *orderedDict = [[MMOrderedDictionary alloc] initWithKeysAndObjects: + EZLanguageAuto, @"auto", + EZLanguageSimplifiedChinese, @"zh", + EZLanguageTraditionalChinese, @"cht", + EZLanguageEnglish, @"en", + EZLanguageJapanese, @"ja", + EZLanguageKorean, @"ko", + EZLanguageFrench, @"fr", + EZLanguageSpanish, @"es", + EZLanguagePortuguese, @"pt", + EZLanguageItalian, @"it", + EZLanguageGerman, @"de", + EZLanguageRussian, @"ru", + EZLanguageArabic, @"ar", + EZLanguageSwedish, @"sv", + EZLanguageRomanian, @"ro", + EZLanguageThai, @"th", + EZLanguageSlovak, @"sk", + EZLanguageDutch, @"nl", + EZLanguageHungarian, @"hu", + EZLanguageGreek, @"el", + EZLanguageDanish, @"da", + EZLanguageFinnish, @"fi", + EZLanguagePolish, @"pl", + EZLanguageCzech, @"cs", + EZLanguageTurkish, @"tr", + EZLanguageLithuanian, @"lt", + EZLanguageLatvian, @"lv", + EZLanguageUkrainian, @"uk", + EZLanguageBulgarian, @"bg", + EZLanguageIndonesian, @"id", + EZLanguageMalay, @"ms", + EZLanguageSlovenian, @"sl", + EZLanguageEstonian, @"et", + EZLanguageVietnamese, @"vi", + EZLanguagePersian, @"fa", + EZLanguageHindi, @"hi", + EZLanguageTelugu, @"te", + EZLanguageTamil, @"ta", + EZLanguageUrdu, @"ur", + EZLanguageFilipino, @"fil", + EZLanguageKhmer, @"km", + EZLanguageLao, @"lo", + EZLanguageBengali, @"bn", + EZLanguageBurmese, @"my", + EZLanguageNorwegian, @"no", + EZLanguageSerbian, @"sr", + EZLanguageCroatian, @"hr", + EZLanguageMongolian, @"mn", + EZLanguageHebrew, @"et", + nil]; + return orderedDict; +} + +- (void)translate:(NSString *)text from:(EZLanguage)from to:(EZLanguage)to completion:(void (^)(EZQueryResult *_Nullable, NSError *_Nullable))completion { + if ([self prehandleQueryTextLanguage:text autoConvertChineseText:YES from:from to:to completion:completion]) { + return; + } + + mm_weakify(self); + [self setDidFinishBlock:^(EZQueryResult *result, NSError *error) { + mm_strongify(self); + NSArray *texts = result.translatedResults; + if ([self.queryModel.queryTargetLanguage isEqualToString:EZLanguageTraditionalChinese]) { + texts = [texts toTraditionalChineseTexts]; + } + result.translatedResults = texts; + }]; + + void (^callback)(EZQueryResult *result, NSError *error) = ^(EZQueryResult *result, NSError *error) { + self.didFinishBlock(result, error); + completion(result, error); + }; + + [self niuTransTranslate:text from:from to:to completion:callback]; +} + +- (void)ocr:(EZQueryModel *)queryModel completion:(void (^)(EZOCRResult *_Nullable, NSError *_Nullable))completion { + NSLog(@"NiuTrans not support ocr"); +} + +- (NSInteger)getICount:(NSString *)translateText { + return [[translateText componentsSeparatedByString:@"i"] count] - 1; +} + +- (NSInteger)getRandomNumber { + NSInteger rand = arc4random_uniform(89999) + 100000; + return rand * 1000; +} + +- (NSInteger)getTimeStampWithIcount:(NSInteger)iCount { + NSInteger ts = [[NSDate date] timeIntervalSince1970] * 1000; + if (iCount != 0) { + iCount = iCount + 1; + return ts - (ts % iCount) + iCount; + } else { + return ts; + } +} + +#pragma mark - NiuTrans API + +- (void)niuTransTranslate:(NSString *)text from:(EZLanguage)from to:(EZLanguage)to completion:(void (^)(EZQueryResult *_Nullable, NSError *_Nullable))completion{ + + NSString *souceLangCode = [self languageCodeForLanguage:from]; + NSString *targetLangCode = [self languageCodeForLanguage:to]; + + // NiuTrans api free and NiuTrans pro api use different url host + NSString *host = @"https://api.niutrans.com"; + NSString *url = [NSString stringWithFormat:@"%@/NiuTransServer/translation", host]; + + NSDictionary *params = @{ + @"apikey" : self.authKey , + @"src_text" : text, + @"from" : souceLangCode, + @"to" : targetLangCode + }; + + AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; + + manager.session.configuration.timeoutIntervalForRequest = EZNetWorkTimeoutInterval; + + CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent(); + + NSURLSessionTask *task = [manager POST:url parameters:params progress:nil success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) { + CFAbsoluteTime endTime = CFAbsoluteTimeGetCurrent(); + NSLog(@"NiuTransTranslate cost: %.1f ms", (endTime - startTime) * 1000); + + NSString *tgt_text=[responseObject objectForKey:@"tgt_text"]; + NSArray *results = [tgt_text toParagraphs]; + self.result.translatedResults = results; + self.result.raw = responseObject; + completion(self.result, nil); + } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) { + NSLog(@"NiuTransTranslate error: %@", error); + if ([self.queryModel isServiceStopped:self.serviceType]) { + return; + } + + if (error.code == NSURLErrorCancelled) { + return; + } + + NSLog(@"NiuTransTranslate error: %@", error); + + completion(self.result, error); + }]; + + [self.queryModel setStopBlock:^{ + [task cancel]; + } serviceType:self.serviceType]; +} + +@end + diff --git a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslateResponse.h b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslateResponse.h new file mode 100644 index 000000000..ddc257d59 --- /dev/null +++ b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslateResponse.h @@ -0,0 +1,44 @@ +// +// EZNiuTransTranslateResponse.h +// Easydict +// +// Created by tisfeng on 2023/2/23. +// Copyright © 2023 izual. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + + +@class EZNiuTransTranslateResponse; +@class EZNiuTransTranslateResponseResult; +@class EZNiuTransTranslateResponseText; +@class EZNiuTransTranslateResponseAlternative; + +#pragma mark - Object interfaces + +@interface EZNiuTransTranslateResponse : NSObject +@property (nonatomic, assign) NSInteger identifier; +@property (nonatomic, copy) NSString *jsonrpc; +@property (nonatomic, strong) EZNiuTransTranslateResponseResult *result; +@end + +@interface EZNiuTransTranslateResponseResult : NSObject +@property (nonatomic, copy) NSDictionary *detectedLanguages; +@property (nonatomic, copy) NSString *lang; +@property (nonatomic, assign) BOOL isLangIsConfident; +@property (nonatomic, copy) NSArray *texts; +@end + +@interface EZNiuTransTranslateResponseText : NSObject +@property (nonatomic, copy) NSArray *alternatives; +@property (nonatomic, copy) NSString *text; +@end + +@interface EZNiuTransTranslateResponseAlternative : NSObject +@property (nonatomic, copy) NSString *text; +@end + + +NS_ASSUME_NONNULL_END diff --git a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslateResponse.m b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslateResponse.m new file mode 100644 index 000000000..879f68a53 --- /dev/null +++ b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslateResponse.m @@ -0,0 +1,52 @@ +// +// EZNiuTransTranslateResponse.m +// Easydict +// +// Created by tisfeng on 2023/2/23. +// Copyright © 2023 izual. All rights reserved. +// + +#import "EZNiuTransTranslateResponse.h" + + +@implementation EZNiuTransTranslateResponse + ++ (NSDictionary *)mj_replacedKeyFromPropertyName { + return @{ + @"identifier" : @"id", + }; +} + +@end + +@implementation EZNiuTransTranslateResponseResult + ++ (NSDictionary *)mj_replacedKeyFromPropertyName { + return @{ + @"isLangIsConfident" : @"lang_is_confident", + }; +} + ++ (NSDictionary *)mj_objectClassInArray { + return @{ + @"texts" : [EZNiuTransTranslateResponseText class], + }; +} + +@end + +@implementation EZNiuTransTranslateResponseText + ++ (NSDictionary *)mj_objectClassInArray { + return @{ + @"alternatives" : [EZNiuTransTranslateResponseAlternative class], + }; +} + +@end + +@implementation EZNiuTransTranslateResponseAlternative + +@end + + diff --git a/Easydict/Feature/Service/Niutrans/EZQueryResult+EZNiuTransTranslateResponse.h b/Easydict/Feature/Service/Niutrans/EZQueryResult+EZNiuTransTranslateResponse.h new file mode 100644 index 000000000..9f3add6de --- /dev/null +++ b/Easydict/Feature/Service/Niutrans/EZQueryResult+EZNiuTransTranslateResponse.h @@ -0,0 +1,20 @@ +// +// EZQueryResult+EZNiuTransTranslateResponse.h +// Easydict +// +// Created by tisfeng on 2023/2/23. +// Copyright © 2023 izual. All rights reserved. +// + +#import "EZQueryResult.h" +#import "EZNiuTransTranslateResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface EZQueryResult (EZNiuTransTranslateResponse) + +- (instancetype)setupWithNiuTransTranslateResponse:(EZNiuTransTranslateResponse *)niuTransTranslateResponse; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Easydict/Feature/Service/Niutrans/EZQueryResult+EZNiuTransTranslateResponse.m b/Easydict/Feature/Service/Niutrans/EZQueryResult+EZNiuTransTranslateResponse.m new file mode 100644 index 000000000..3254af6bb --- /dev/null +++ b/Easydict/Feature/Service/Niutrans/EZQueryResult+EZNiuTransTranslateResponse.m @@ -0,0 +1,26 @@ +// +// EZQueryResult+EZNiuTransTranslateResponse.m +// Easydict +// +// Created by tisfeng on 2023/2/23. +// Copyright © 2023 izual. All rights reserved. +// + +#import "EZQueryResult+EZNiuTransTranslateResponse.h" + + +@implementation EZQueryResult (EZNiuTransTranslateResponse) + +- (instancetype)setupWithNiuTransTranslateResponse:(EZNiuTransTranslateResponse *)niuTransTranslateResponse { + NSString *translatedText = niuTransTranslateResponse.result.texts.firstObject.text; + if (translatedText) { + self.translatedResults = [translatedText.trim toParagraphs]; + } + self.raw = niuTransTranslateResponse; + + return self; +} + +@end + + diff --git a/Easydict/Feature/Utility/.DS_Store b/Easydict/Feature/Utility/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..cb471c59cb04f21f1ca3fdec47753e0bf5faa8ef GIT binary patch literal 6148 zcmeHK%}T>S5T0$TCaBPZLXQhx3)X*%mr(1?gBVfphnkS0!I&*cYY(N6v%Zi|;`2DO zyA@0I;z6X$!0b0WJCkL;gqY;t)9hTSB%IhmcoBDpo$A_=O8Y^ab~Bw2M_mlLxs20D4O?oEM!C-Q&4S}P zZl_usjkfojb-A^7Fs{o{bGuQOyF2^ivFogFY#yF<9+Rh3y% literal 0 HcmV?d00001 diff --git a/Pods/.DS_Store b/Pods/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..91c9796ae7ad2ee958f5070e1186b768e912f9ec GIT binary patch literal 8196 zcmeHMTTc@~6g~q;w`oC4N`en2oA^qQi<%H$+5#F-#IT5omteQ8WntNAwk?$qOrP~X z_!oTjm-t_N((lYHxECNk83{9F=FIM%?_9n)vzsYIB&xl}9MKdJS?DY$3K-65{G5BH z4MlfuLki%Dy3{90A?=fw(Ka^>1BL;^fMLKeU>Nux7{E81n{~l=Uq3aYVZbnOEg9hV zgN@Fz9La%}>eYck9RVOma9cIZaSl)zJCfx{4zyHI*wm*75kWLkiqn$a*|7|1ffXZIpi=rKK~X5#!FP;1qfb=Q|Jba-1; z&}V+BhS?=Jx8G?;xbJS;_d4C#*&kwPc;v=t&dON@>z%VJ`%bsk?RBcP@C{#WN$I<% z^P0QuHTydgr6n13YhKU{6~JpWq4M^X7c^wQDtkerqp*&CVCAj+&cxL5@!W&iX?tOQ z@nqUQUYy7L{=&nPle{%~_uiw;oqhixke^isB%;>|jp^&N@yliT9Xes)%b*1v#^=FI z8-Gh+FaU>53RBE|gI1imo6wb1N3YQ{>d^tYjG{eU*J(eA7I#wUTUad*+D)Kp)PbzP zZ;gC9f_D!VIw=dBP27JmV}av=#T4#m3Rk)aN2{lq>qwGzhM1|i|H+IU#&-}sXW?Vy zJS5*sT2eLmHCBTqdICL3EufeOUWawen3ta7=m1w(m6RP`k+_|k2|F*9e;+Y$9L;nT zYDMB`i`KA?n~0+aL{^{qkL!=oQ`)8tRRvrzA&{JRrg8+YKoYr*+yX@Pf&BnG102^< zs%jMHabym>Fe}VzNJl9?u(!o{jMs5!SID6kibM9r^%lTSCOZO`32Y(4Ix3DhWJVm>6+-A(C&yM*pIvXRt)L~&#yYa{=n(Vsam-;Hmjm~0;P|&x z)J4*Z;x4XTgtkMk;h~KPLU`NN-cmSbFODnGmh#a;TwStZqX!FZ@WHEQt6j=fnc9V1 zl?gj2Qq!&+1H(GvsRHE6#lQbwxx7rkh5^IC-!mXamYwA)^u+}jK5N_P@6oxj-atzQ s!Jv-gkm@)NdG-%O%x$PLrX0zEmbioV&wmIo-~T@+IP?8iHFzC|-=BpCcmMzZ literal 0 HcmV?d00001 diff --git a/Pods/AFNetworking/.DS_Store b/Pods/AFNetworking/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..c10fb1df1809cb8c9ace918fad48be42c5dfb4fe GIT binary patch literal 6148 zcmeHK!D`z;5S?|LSRyU>kU%a4L9ZcolC}_XksZ4bXmW@`duWSmRVEctw856EgE8pb zeoU|ZlKxKnW_J_fxaldB5@ulb&CbqSu}@-GOGK(ONw$faMC8F4Yd)Gk7>~0rSj}aY zfy&HLP)V9bbWZ6)wIu#W1^C@PqBgyvV;a)U_m|VzVWvODnT}DzA4nU%^~)HdzwqL6 zeCc>U;>#=@7p>M$Ra>eruQa@dx9WX}KI<|n2E}CD8I0a>?^Nq7zKRF&n{-(An`;L; zF9vBo92r8I3{mp_ZJH;#?C43Jj14!k1D@~s{pQAWy8WWH8SL)t%{GJS-VWmDyDw)m z-&=qBZ2zQxo?Ybnt62dle7D9PJG_E#2=3J7OEk(eou8qG`3-tahjc(aXc$rNmTKQo zaZ@#)PEgsVE*$~4=z@}YhI(>~fv%V+APR^A_o{%~`@GeAomD0i1w?^|paAa=0h}>( zSXne%2O4t)0M?Nv{dD;7|PO-4_sa7u(D|Bq}=60xhE@k zLs91Gm_IP(q(Y0*iUOj*yaG$M+vM}VclZ5&o+Ld{KoodT3aENF>UOXsceXApj?dZv s{t?c`b(O_y3IcN!qn3~24Y)Dn0}gQMGDsr|{8I&f0~Gdkp#T5? literal 0 HcmV?d00001 From 336fef808abb0476968d43a8e9edf845492b6ded Mon Sep 17 00:00:00 2001 From: tisfeng Date: Thu, 16 Nov 2023 00:11:10 +0800 Subject: [PATCH 03/15] perf: show error message when niutrans error --- Easydict.xcodeproj/project.pbxproj | 10 +- .../Service/Niutrans/EZNiuTransTranslate.m | 162 +++++++++--------- .../Niutrans/EZNiuTransTranslateResponse.h | 49 +++--- .../Niutrans/EZNiuTransTranslateResponse.m | 38 +--- ...ZQueryResult+EZNiuTransTranslateResponse.h | 20 --- ...ZQueryResult+EZNiuTransTranslateResponse.m | 26 --- 6 files changed, 119 insertions(+), 186 deletions(-) delete mode 100644 Easydict/Feature/Service/Niutrans/EZQueryResult+EZNiuTransTranslateResponse.h delete mode 100644 Easydict/Feature/Service/Niutrans/EZQueryResult+EZNiuTransTranslateResponse.m diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index 46ca544cf..b74895582 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -209,7 +209,6 @@ 03F639952AA6CFBB009B9914 /* EZBingConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 03F639942AA6CFBB009B9914 /* EZBingConfig.m */; }; 17FD9A002B01B9F200A528A6 /* EZNiuTransTranslateResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 17FD99FD2B01B9F200A528A6 /* EZNiuTransTranslateResponse.m */; }; 17FD9A012B01B9F200A528A6 /* EZNiuTransTranslate.m in Sources */ = {isa = PBXBuildFile; fileRef = 17FD99FE2B01B9F200A528A6 /* EZNiuTransTranslate.m */; }; - 17FD9A022B01B9F200A528A6 /* EZQueryResult+EZNiuTransTranslateResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 17FD99FF2B01B9F200A528A6 /* EZQueryResult+EZNiuTransTranslateResponse.m */; }; 27B7919E2AEC36A1006E07C6 /* Easydict.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 27B7919C2AEC36A1006E07C6 /* Easydict.xcconfig */; }; 27B7919F2AEC36A1006E07C6 /* Easydict-debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 27B7919D2AEC36A1006E07C6 /* Easydict-debug.xcconfig */; }; 6220AD5B2A82812300BBFB52 /* EZBingService.m in Sources */ = {isa = PBXBuildFile; fileRef = 6220AD5A2A82812300BBFB52 /* EZBingService.m */; }; @@ -634,10 +633,8 @@ 06E15747A7BD34D510ADC6A8 /* Pods-Easydict.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Easydict.debug.xcconfig"; path = "Target Support Files/Pods-Easydict/Pods-Easydict.debug.xcconfig"; sourceTree = ""; }; 17FD99FA2B01B9F200A528A6 /* EZNiuTransTranslateResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZNiuTransTranslateResponse.h; sourceTree = ""; }; 17FD99FB2B01B9F200A528A6 /* EZNiuTransTranslate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZNiuTransTranslate.h; sourceTree = ""; }; - 17FD99FC2B01B9F200A528A6 /* EZQueryResult+EZNiuTransTranslateResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "EZQueryResult+EZNiuTransTranslateResponse.h"; sourceTree = ""; }; 17FD99FD2B01B9F200A528A6 /* EZNiuTransTranslateResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZNiuTransTranslateResponse.m; sourceTree = ""; }; 17FD99FE2B01B9F200A528A6 /* EZNiuTransTranslate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZNiuTransTranslate.m; sourceTree = ""; }; - 17FD99FF2B01B9F200A528A6 /* EZQueryResult+EZNiuTransTranslateResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "EZQueryResult+EZNiuTransTranslateResponse.m"; sourceTree = ""; }; 27B7919C2AEC36A1006E07C6 /* Easydict.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Easydict.xcconfig; sourceTree = ""; }; 27B7919D2AEC36A1006E07C6 /* Easydict-debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Easydict-debug.xcconfig"; sourceTree = ""; }; 27B791A02AEC3A5C006E07C6 /* Easydict-debug.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = "Easydict-debug.entitlements"; sourceTree = ""; }; @@ -1823,12 +1820,10 @@ 17FD99F92B01B9F200A528A6 /* Niutrans */ = { isa = PBXGroup; children = ( - 17FD99FA2B01B9F200A528A6 /* EZNiuTransTranslateResponse.h */, 17FD99FB2B01B9F200A528A6 /* EZNiuTransTranslate.h */, - 17FD99FC2B01B9F200A528A6 /* EZQueryResult+EZNiuTransTranslateResponse.h */, - 17FD99FD2B01B9F200A528A6 /* EZNiuTransTranslateResponse.m */, 17FD99FE2B01B9F200A528A6 /* EZNiuTransTranslate.m */, - 17FD99FF2B01B9F200A528A6 /* EZQueryResult+EZNiuTransTranslateResponse.m */, + 17FD99FA2B01B9F200A528A6 /* EZNiuTransTranslateResponse.h */, + 17FD99FD2B01B9F200A528A6 /* EZNiuTransTranslateResponse.m */, ); path = Niutrans; sourceTree = ""; @@ -2275,7 +2270,6 @@ 0396D611292C932F006A11D9 /* EZSelectLanguageCell.m in Sources */, 036196752A000F5900806370 /* FWEncryptorAES.m in Sources */, 0399C6A829A74E0F00B4AFCC /* EZQueryResult+EZDeepLTranslateResponse.m in Sources */, - 17FD9A022B01B9F200A528A6 /* EZQueryResult+EZNiuTransTranslateResponse.m in Sources */, 039B694F2A9D9F370063709D /* EZWebViewManager.m in Sources */, 03D747432A07FB150006CD77 /* EZError.m in Sources */, 03B0231629231FA6001C7E63 /* SnipFocusView.m in Sources */, diff --git a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m index 8a6417f2b..9ba248906 100644 --- a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m +++ b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m @@ -8,10 +8,9 @@ #import "EZNiuTransTranslate.h" #import "EZWebViewTranslator.h" -#import "EZTranslateError.h" -#import "EZQueryResult+EZNiuTransTranslateResponse.h" +// #import "EZTranslateError.h" #import "NSArray+EZChineseText.h" - +#import "EZNiuTransTranslateResponse.h" static NSString *kNiuTransTranslateURL = @"https://api.niutrans.com/NiuTransServer/translation"; @@ -28,7 +27,6 @@ @implementation EZNiuTransTranslate - (instancetype)init { if (self = [super init]) { - } return self; } @@ -44,15 +42,12 @@ - (EZWebViewTranslator *)webViewTranslator { } - - (NSString *)authKey { NSString *authKey = [[NSUserDefaults standardUserDefaults] stringForKey:EZNiuTransAuthKey] ?: @""; return authKey; } - - #pragma mark - 重写父类方法 - (EZServiceType)serviceType { @@ -68,79 +63,77 @@ - (NSString *)link { } - - // https://niutrans.com/documents/contents/trans_text#accessMode - (nullable NSString *)wordLink:(EZQueryModel *)queryModel { NSString *from = [self languageCodeForLanguage:queryModel.queryFromLanguage]; NSString *to = [self languageCodeForLanguage:queryModel.queryTargetLanguage]; NSString *text = [queryModel.queryText stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; - + NSString *encodedText = [text stringByReplacingOccurrencesOfString:@"/" withString:@"%5C%2F"]; - + if (!from || !to) { return nil; - } + } NSString *url = [NSString stringWithFormat:@"%@#%@/%@/%@", kNiuTransTranslateURL, from, to, encodedText]; - + return url; } // Supported languages: https://niutrans.com/documents/contents/trans_text#languageList - (MMOrderedDictionary *)supportLanguagesDictionary { MMOrderedDictionary *orderedDict = [[MMOrderedDictionary alloc] initWithKeysAndObjects: - EZLanguageAuto, @"auto", - EZLanguageSimplifiedChinese, @"zh", - EZLanguageTraditionalChinese, @"cht", - EZLanguageEnglish, @"en", - EZLanguageJapanese, @"ja", - EZLanguageKorean, @"ko", - EZLanguageFrench, @"fr", - EZLanguageSpanish, @"es", - EZLanguagePortuguese, @"pt", - EZLanguageItalian, @"it", - EZLanguageGerman, @"de", - EZLanguageRussian, @"ru", - EZLanguageArabic, @"ar", - EZLanguageSwedish, @"sv", - EZLanguageRomanian, @"ro", - EZLanguageThai, @"th", - EZLanguageSlovak, @"sk", - EZLanguageDutch, @"nl", - EZLanguageHungarian, @"hu", - EZLanguageGreek, @"el", - EZLanguageDanish, @"da", - EZLanguageFinnish, @"fi", - EZLanguagePolish, @"pl", - EZLanguageCzech, @"cs", - EZLanguageTurkish, @"tr", - EZLanguageLithuanian, @"lt", - EZLanguageLatvian, @"lv", - EZLanguageUkrainian, @"uk", - EZLanguageBulgarian, @"bg", - EZLanguageIndonesian, @"id", - EZLanguageMalay, @"ms", - EZLanguageSlovenian, @"sl", - EZLanguageEstonian, @"et", - EZLanguageVietnamese, @"vi", - EZLanguagePersian, @"fa", - EZLanguageHindi, @"hi", - EZLanguageTelugu, @"te", - EZLanguageTamil, @"ta", - EZLanguageUrdu, @"ur", - EZLanguageFilipino, @"fil", - EZLanguageKhmer, @"km", - EZLanguageLao, @"lo", - EZLanguageBengali, @"bn", - EZLanguageBurmese, @"my", - EZLanguageNorwegian, @"no", - EZLanguageSerbian, @"sr", - EZLanguageCroatian, @"hr", - EZLanguageMongolian, @"mn", - EZLanguageHebrew, @"et", - nil]; + EZLanguageAuto, @"auto", + EZLanguageSimplifiedChinese, @"zh", + EZLanguageTraditionalChinese, @"cht", + EZLanguageEnglish, @"en", + EZLanguageJapanese, @"ja", + EZLanguageKorean, @"ko", + EZLanguageFrench, @"fr", + EZLanguageSpanish, @"es", + EZLanguagePortuguese, @"pt", + EZLanguageItalian, @"it", + EZLanguageGerman, @"de", + EZLanguageRussian, @"ru", + EZLanguageArabic, @"ar", + EZLanguageSwedish, @"sv", + EZLanguageRomanian, @"ro", + EZLanguageThai, @"th", + EZLanguageSlovak, @"sk", + EZLanguageDutch, @"nl", + EZLanguageHungarian, @"hu", + EZLanguageGreek, @"el", + EZLanguageDanish, @"da", + EZLanguageFinnish, @"fi", + EZLanguagePolish, @"pl", + EZLanguageCzech, @"cs", + EZLanguageTurkish, @"tr", + EZLanguageLithuanian, @"lt", + EZLanguageLatvian, @"lv", + EZLanguageUkrainian, @"uk", + EZLanguageBulgarian, @"bg", + EZLanguageIndonesian, @"id", + EZLanguageMalay, @"ms", + EZLanguageSlovenian, @"sl", + EZLanguageEstonian, @"et", + EZLanguageVietnamese, @"vi", + EZLanguagePersian, @"fa", + EZLanguageHindi, @"hi", + EZLanguageTelugu, @"te", + EZLanguageTamil, @"ta", + EZLanguageUrdu, @"ur", + EZLanguageFilipino, @"fil", + EZLanguageKhmer, @"km", + EZLanguageLao, @"lo", + EZLanguageBengali, @"bn", + EZLanguageBurmese, @"my", + EZLanguageNorwegian, @"no", + EZLanguageSerbian, @"sr", + EZLanguageCroatian, @"hr", + EZLanguageMongolian, @"mn", + EZLanguageHebrew, @"et", + nil]; return orderedDict; } @@ -163,7 +156,7 @@ - (void)translate:(NSString *)text from:(EZLanguage)from to:(EZLanguage)to compl self.didFinishBlock(result, error); completion(result, error); }; - + [self niuTransTranslate:text from:from to:to completion:callback]; } @@ -192,44 +185,58 @@ - (NSInteger)getTimeStampWithIcount:(NSInteger)iCount { #pragma mark - NiuTrans API -- (void)niuTransTranslate:(NSString *)text from:(EZLanguage)from to:(EZLanguage)to completion:(void (^)(EZQueryResult *_Nullable, NSError *_Nullable))completion{ - +- (void)niuTransTranslate:(NSString *)text from:(EZLanguage)from to:(EZLanguage)to completion:(void (^)(EZQueryResult *_Nullable, NSError *_Nullable))completion { NSString *souceLangCode = [self languageCodeForLanguage:from]; NSString *targetLangCode = [self languageCodeForLanguage:to]; // NiuTrans api free and NiuTrans pro api use different url host - NSString *host = @"https://api.niutrans.com"; + NSString *host = @"https://api.niutrans.com"; NSString *url = [NSString stringWithFormat:@"%@/NiuTransServer/translation", host]; NSDictionary *params = @{ - @"apikey" : self.authKey , + @"apikey" : self.authKey, @"src_text" : text, @"from" : souceLangCode, @"to" : targetLangCode }; AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; - manager.session.configuration.timeoutIntervalForRequest = EZNetWorkTimeoutInterval; CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent(); - + NSURLSessionTask *task = [manager POST:url parameters:params progress:nil success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) { CFAbsoluteTime endTime = CFAbsoluteTimeGetCurrent(); NSLog(@"NiuTransTranslate cost: %.1f ms", (endTime - startTime) * 1000); - - NSString *tgt_text=[responseObject objectForKey:@"tgt_text"]; - NSArray *results = [tgt_text toParagraphs]; - self.result.translatedResults = results; - self.result.raw = responseObject; - completion(self.result, nil); + + EZNiuTransTranslateResponse *niuTransTranslateResult = [EZNiuTransTranslateResponse mj_objectWithKeyValues:responseObject]; + + NSString *translatedText = niuTransTranslateResult.tgtText; + if (translatedText) { + self.result.translatedResults = [translatedText toParagraphs]; + self.result.raw = responseObject; + completion(self.result, nil); + } else { + NSString *errorCode = niuTransTranslateResult.errorCode; + NSString *errorMsg = niuTransTranslateResult.errorMsg; + if (errorCode.length) { + NSString *message = errorCode; + if (errorMsg) { + message = [NSString stringWithFormat:@"%@, %@", errorCode, errorMsg]; + } + NSError *error = [EZTranslateError errorWithType:EZErrorTypeAPI + message:message + request:task.currentRequest]; + completion(self.result, error); + } + } } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) { NSLog(@"NiuTransTranslate error: %@", error); if ([self.queryModel isServiceStopped:self.serviceType]) { return; } - if (error.code == NSURLErrorCancelled) { + if (error.code == NSURLErrorCancelled) { return; } @@ -244,4 +251,3 @@ - (void)niuTransTranslate:(NSString *)text from:(EZLanguage)from to:(EZLanguage) } @end - diff --git a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslateResponse.h b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslateResponse.h index ddc257d59..275a74feb 100644 --- a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslateResponse.h +++ b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslateResponse.h @@ -12,33 +12,42 @@ NS_ASSUME_NONNULL_BEGIN @class EZNiuTransTranslateResponse; -@class EZNiuTransTranslateResponseResult; -@class EZNiuTransTranslateResponseText; -@class EZNiuTransTranslateResponseAlternative; #pragma mark - Object interfaces +/** + https://niutrans.com/documents/contents/trans_text#languageList + + sccuess: + { + from: "zh", + to: "en", + tgt_text: "Hello" + } + + failure + { + "apikey" : "", + "error_code" : "13002", + "error_msg" : "apikey is empty", + "from" : "en", + "src_text" : "good", + "to" : "zh" + } + */ + @interface EZNiuTransTranslateResponse : NSObject -@property (nonatomic, assign) NSInteger identifier; -@property (nonatomic, copy) NSString *jsonrpc; -@property (nonatomic, strong) EZNiuTransTranslateResponseResult *result; -@end -@interface EZNiuTransTranslateResponseResult : NSObject -@property (nonatomic, copy) NSDictionary *detectedLanguages; -@property (nonatomic, copy) NSString *lang; -@property (nonatomic, assign) BOOL isLangIsConfident; -@property (nonatomic, copy) NSArray *texts; -@end +@property (nonatomic, copy) NSString *from; +@property (nonatomic, copy) NSString *to; -@interface EZNiuTransTranslateResponseText : NSObject -@property (nonatomic, copy) NSArray *alternatives; -@property (nonatomic, copy) NSString *text; -@end +@property (nonatomic, copy, nullable) NSString *tgtText; -@interface EZNiuTransTranslateResponseAlternative : NSObject -@property (nonatomic, copy) NSString *text; -@end +@property (nonatomic, copy, nullable) NSString *srcText; +@property (nonatomic, copy, nullable) NSString *errorMsg; +@property (nonatomic, copy, nullable) NSString *errorCode; +@property (nonatomic, copy, nullable) NSString *apikey; +@end NS_ASSUME_NONNULL_END diff --git a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslateResponse.m b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslateResponse.m index 879f68a53..b254542b9 100644 --- a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslateResponse.m +++ b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslateResponse.m @@ -8,45 +8,15 @@ #import "EZNiuTransTranslateResponse.h" - @implementation EZNiuTransTranslateResponse + (NSDictionary *)mj_replacedKeyFromPropertyName { return @{ - @"identifier" : @"id", - }; -} - -@end - -@implementation EZNiuTransTranslateResponseResult - -+ (NSDictionary *)mj_replacedKeyFromPropertyName { - return @{ - @"isLangIsConfident" : @"lang_is_confident", - }; -} - -+ (NSDictionary *)mj_objectClassInArray { - return @{ - @"texts" : [EZNiuTransTranslateResponseText class], - }; -} - -@end - -@implementation EZNiuTransTranslateResponseText - -+ (NSDictionary *)mj_objectClassInArray { - return @{ - @"alternatives" : [EZNiuTransTranslateResponseAlternative class], + @"srcText" : @"src_text", + @"tgtText" : @"tgt_text", + @"errorMsg" : @"error_msg", + @"errorCode" : @"error_code", }; } - -@end - -@implementation EZNiuTransTranslateResponseAlternative @end - - diff --git a/Easydict/Feature/Service/Niutrans/EZQueryResult+EZNiuTransTranslateResponse.h b/Easydict/Feature/Service/Niutrans/EZQueryResult+EZNiuTransTranslateResponse.h deleted file mode 100644 index 9f3add6de..000000000 --- a/Easydict/Feature/Service/Niutrans/EZQueryResult+EZNiuTransTranslateResponse.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// EZQueryResult+EZNiuTransTranslateResponse.h -// Easydict -// -// Created by tisfeng on 2023/2/23. -// Copyright © 2023 izual. All rights reserved. -// - -#import "EZQueryResult.h" -#import "EZNiuTransTranslateResponse.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface EZQueryResult (EZNiuTransTranslateResponse) - -- (instancetype)setupWithNiuTransTranslateResponse:(EZNiuTransTranslateResponse *)niuTransTranslateResponse; - -@end - -NS_ASSUME_NONNULL_END diff --git a/Easydict/Feature/Service/Niutrans/EZQueryResult+EZNiuTransTranslateResponse.m b/Easydict/Feature/Service/Niutrans/EZQueryResult+EZNiuTransTranslateResponse.m deleted file mode 100644 index 3254af6bb..000000000 --- a/Easydict/Feature/Service/Niutrans/EZQueryResult+EZNiuTransTranslateResponse.m +++ /dev/null @@ -1,26 +0,0 @@ -// -// EZQueryResult+EZNiuTransTranslateResponse.m -// Easydict -// -// Created by tisfeng on 2023/2/23. -// Copyright © 2023 izual. All rights reserved. -// - -#import "EZQueryResult+EZNiuTransTranslateResponse.h" - - -@implementation EZQueryResult (EZNiuTransTranslateResponse) - -- (instancetype)setupWithNiuTransTranslateResponse:(EZNiuTransTranslateResponse *)niuTransTranslateResponse { - NSString *translatedText = niuTransTranslateResponse.result.texts.firstObject.text; - if (translatedText) { - self.translatedResults = [translatedText.trim toParagraphs]; - } - self.raw = niuTransTranslateResponse; - - return self; -} - -@end - - From 1adb594ce4ba13408f456c05c1ac8a28094ec362 Mon Sep 17 00:00:00 2001 From: tisfeng Date: Thu, 16 Nov 2023 00:30:20 +0800 Subject: [PATCH 04/15] perf: remove unused code --- .../Service/Niutrans/EZNiuTransTranslate.m | 80 +------------------ 1 file changed, 2 insertions(+), 78 deletions(-) diff --git a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m index 9ba248906..c7d32eeaf 100644 --- a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m +++ b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m @@ -7,8 +7,6 @@ // #import "EZNiuTransTranslate.h" -#import "EZWebViewTranslator.h" -// #import "EZTranslateError.h" #import "NSArray+EZChineseText.h" #import "EZNiuTransTranslateResponse.h" @@ -17,8 +15,6 @@ @interface EZNiuTransTranslate () -@property (nonatomic, strong) EZWebViewTranslator *webViewTranslator; - @property (nonatomic, copy) NSString *authKey; @end @@ -31,17 +27,6 @@ - (instancetype)init { return self; } -- (EZWebViewTranslator *)webViewTranslator { - if (!_webViewTranslator) { - NSString *selector = @"#target-dummydiv"; - _webViewTranslator = [[EZWebViewTranslator alloc] init]; - _webViewTranslator.querySelector = selector; - _webViewTranslator.queryModel = self.queryModel; - } - return _webViewTranslator; -} - - - (NSString *)authKey { NSString *authKey = [[NSUserDefaults standardUserDefaults] stringForKey:EZNiuTransAuthKey] ?: @""; return authKey; @@ -62,25 +47,6 @@ - (NSString *)link { return kNiuTransTranslateURL; } - -// https://niutrans.com/documents/contents/trans_text#accessMode -- (nullable NSString *)wordLink:(EZQueryModel *)queryModel { - NSString *from = [self languageCodeForLanguage:queryModel.queryFromLanguage]; - NSString *to = [self languageCodeForLanguage:queryModel.queryTargetLanguage]; - NSString *text = [queryModel.queryText stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]; - - - NSString *encodedText = [text stringByReplacingOccurrencesOfString:@"/" withString:@"%5C%2F"]; - - if (!from || !to) { - return nil; - } - - NSString *url = [NSString stringWithFormat:@"%@#%@/%@/%@", kNiuTransTranslateURL, from, to, encodedText]; - - return url; -} - // Supported languages: https://niutrans.com/documents/contents/trans_text#languageList - (MMOrderedDictionary *)supportLanguagesDictionary { MMOrderedDictionary *orderedDict = [[MMOrderedDictionary alloc] initWithKeysAndObjects: @@ -137,52 +103,18 @@ - (nullable NSString *)wordLink:(EZQueryModel *)queryModel { return orderedDict; } -- (void)translate:(NSString *)text from:(EZLanguage)from to:(EZLanguage)to completion:(void (^)(EZQueryResult *_Nullable, NSError *_Nullable))completion { +- (void)translate:(NSString *)text from:(EZLanguage)from to:(EZLanguage)to completion:(void (^)(EZQueryResult *, NSError *_Nullable))completion { if ([self prehandleQueryTextLanguage:text autoConvertChineseText:YES from:from to:to completion:completion]) { return; } - mm_weakify(self); - [self setDidFinishBlock:^(EZQueryResult *result, NSError *error) { - mm_strongify(self); - NSArray *texts = result.translatedResults; - if ([self.queryModel.queryTargetLanguage isEqualToString:EZLanguageTraditionalChinese]) { - texts = [texts toTraditionalChineseTexts]; - } - result.translatedResults = texts; - }]; - - void (^callback)(EZQueryResult *result, NSError *error) = ^(EZQueryResult *result, NSError *error) { - self.didFinishBlock(result, error); - completion(result, error); - }; - - [self niuTransTranslate:text from:from to:to completion:callback]; + [self niuTransTranslate:text from:from to:to completion:completion]; } - (void)ocr:(EZQueryModel *)queryModel completion:(void (^)(EZOCRResult *_Nullable, NSError *_Nullable))completion { NSLog(@"NiuTrans not support ocr"); } -- (NSInteger)getICount:(NSString *)translateText { - return [[translateText componentsSeparatedByString:@"i"] count] - 1; -} - -- (NSInteger)getRandomNumber { - NSInteger rand = arc4random_uniform(89999) + 100000; - return rand * 1000; -} - -- (NSInteger)getTimeStampWithIcount:(NSInteger)iCount { - NSInteger ts = [[NSDate date] timeIntervalSince1970] * 1000; - if (iCount != 0) { - iCount = iCount + 1; - return ts - (ts % iCount) + iCount; - } else { - return ts; - } -} - #pragma mark - NiuTrans API - (void)niuTransTranslate:(NSString *)text from:(EZLanguage)from to:(EZLanguage)to completion:(void (^)(EZQueryResult *_Nullable, NSError *_Nullable))completion { @@ -202,15 +134,8 @@ - (void)niuTransTranslate:(NSString *)text from:(EZLanguage)from to:(EZLanguage) AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; manager.session.configuration.timeoutIntervalForRequest = EZNetWorkTimeoutInterval; - - CFAbsoluteTime startTime = CFAbsoluteTimeGetCurrent(); - NSURLSessionTask *task = [manager POST:url parameters:params progress:nil success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) { - CFAbsoluteTime endTime = CFAbsoluteTimeGetCurrent(); - NSLog(@"NiuTransTranslate cost: %.1f ms", (endTime - startTime) * 1000); - EZNiuTransTranslateResponse *niuTransTranslateResult = [EZNiuTransTranslateResponse mj_objectWithKeyValues:responseObject]; - NSString *translatedText = niuTransTranslateResult.tgtText; if (translatedText) { self.result.translatedResults = [translatedText toParagraphs]; @@ -231,7 +156,6 @@ - (void)niuTransTranslate:(NSString *)text from:(EZLanguage)from to:(EZLanguage) } } } failure:^(NSURLSessionDataTask *_Nullable task, NSError *_Nonnull error) { - NSLog(@"NiuTransTranslate error: %@", error); if ([self.queryModel isServiceStopped:self.serviceType]) { return; } From aa1e861f6559377d05c8f888f34663510a3f0f22 Mon Sep 17 00:00:00 2001 From: tisfeng Date: Thu, 16 Nov 2023 00:38:18 +0800 Subject: [PATCH 05/15] perf: remove extra line break at the end --- Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m index c7d32eeaf..0b14451cd 100644 --- a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m +++ b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m @@ -121,7 +121,7 @@ - (void)niuTransTranslate:(NSString *)text from:(EZLanguage)from to:(EZLanguage) NSString *souceLangCode = [self languageCodeForLanguage:from]; NSString *targetLangCode = [self languageCodeForLanguage:to]; - // NiuTrans api free and NiuTrans pro api use different url host + // NiuTrans API free and NiuTrans pro API use different URL host NSString *host = @"https://api.niutrans.com"; NSString *url = [NSString stringWithFormat:@"%@/NiuTransServer/translation", host]; @@ -137,6 +137,9 @@ - (void)niuTransTranslate:(NSString *)text from:(EZLanguage)from to:(EZLanguage) NSURLSessionTask *task = [manager POST:url parameters:params progress:nil success:^(NSURLSessionDataTask *_Nonnull task, id _Nullable responseObject) { EZNiuTransTranslateResponse *niuTransTranslateResult = [EZNiuTransTranslateResponse mj_objectWithKeyValues:responseObject]; NSString *translatedText = niuTransTranslateResult.tgtText; + // When translated text has multiple paragraphs, it will have an extra line break at the end, which we need to remove. + translatedText = [translatedText stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]]; + if (translatedText) { self.result.translatedResults = [translatedText toParagraphs]; self.result.raw = responseObject; From f76c784a1f6f456cf405f5595755ce0a5b38657b Mon Sep 17 00:00:00 2001 From: tisfeng Date: Thu, 16 Nov 2023 00:46:31 +0800 Subject: [PATCH 06/15] perf: rename EZNiuTransAPIKey --- Easydict/Feature/Service/Model/EZConstKey.h | 2 +- .../Feature/Service/Niutrans/EZNiuTransTranslate.m | 10 +++++----- Easydict/Feature/Utility/EZLinkParser/EZSchemeParser.m | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Easydict/Feature/Service/Model/EZConstKey.h b/Easydict/Feature/Service/Model/EZConstKey.h index b094da26a..4497ffda6 100644 --- a/Easydict/Feature/Service/Model/EZConstKey.h +++ b/Easydict/Feature/Service/Model/EZConstKey.h @@ -28,7 +28,7 @@ static NSString *const EZOpenAIModelKey = @"EZOpenAIModelKey"; static NSString *const EZDeepLAuthKey = @"EZDeepLAuthKey"; -static NSString *const EZNiuTransAuthKey = @"EZNiuTransAuthKey"; +static NSString *const EZNiuTransAPIKey = @"EZNiuTransAPIKey"; static NSString *const EZBingCookieKey = @"EZBingCookieKey"; diff --git a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m index 0b14451cd..588a578ee 100644 --- a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m +++ b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m @@ -15,7 +15,7 @@ @interface EZNiuTransTranslate () -@property (nonatomic, copy) NSString *authKey; +@property (nonatomic, copy) NSString *apiKey; @end @@ -27,9 +27,9 @@ - (instancetype)init { return self; } -- (NSString *)authKey { - NSString *authKey = [[NSUserDefaults standardUserDefaults] stringForKey:EZNiuTransAuthKey] ?: @""; - return authKey; +- (NSString *)apiKey { + NSString *apiKey = [[NSUserDefaults standardUserDefaults] stringForKey:EZNiuTransAPIKey] ?: @""; + return apiKey; } @@ -126,7 +126,7 @@ - (void)niuTransTranslate:(NSString *)text from:(EZLanguage)from to:(EZLanguage) NSString *url = [NSString stringWithFormat:@"%@/NiuTransServer/translation", host]; NSDictionary *params = @{ - @"apikey" : self.authKey, + @"apikey" : self.apiKey, @"src_text" : text, @"from" : souceLangCode, @"to" : targetLangCode diff --git a/Easydict/Feature/Utility/EZLinkParser/EZSchemeParser.m b/Easydict/Feature/Utility/EZLinkParser/EZSchemeParser.m index 68666353c..bd81fce73 100644 --- a/Easydict/Feature/Utility/EZLinkParser/EZSchemeParser.m +++ b/Easydict/Feature/Utility/EZLinkParser/EZSchemeParser.m @@ -207,7 +207,7 @@ - (NSArray *)allowedReadWriteKeys { EZDeepLAuthKey, EZDeepLTranslationAPIKey, - EZNiuTransAuthKey, + EZNiuTransAPIKey, EZIntelligentQueryModeKey, From 55b87e9d4fae4461c92ae11dc9ae76b292517bf5 Mon Sep 17 00:00:00 2001 From: BigGunag <48265638+BigGuang97@users.noreply.github.com> Date: Thu, 16 Nov 2023 15:51:04 +0800 Subject: [PATCH 07/15] Update Localizable.xcstrings --- Easydict/App/Localizable.xcstrings | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index 68495f3bf..815cec8ee 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -1383,8 +1383,8 @@ "localizations" : { "en" : { "stringUnit" : { - "state" : "needs_review", - "value" : "" + "state" : "translated", + "value" : "NiuTrans" } }, "zh-Hans" : { @@ -2238,4 +2238,4 @@ } }, "version" : "1.0" -} \ No newline at end of file +} From 774debc8188e1a5b76f8904d6dde666bd9a72671 Mon Sep 17 00:00:00 2001 From: BigGunag <48265638+BigGuang97@users.noreply.github.com> Date: Thu, 16 Nov 2023 15:52:09 +0800 Subject: [PATCH 08/15] Delete Easydict/.DS_Store --- Easydict/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Easydict/.DS_Store diff --git a/Easydict/.DS_Store b/Easydict/.DS_Store deleted file mode 100644 index 094902c63b2c4bc9ace459c9bb595ab335d5de33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK!D`z;5S@+PSWYPT&_IrYUPEKYZ6NfbxJjVbs-%ZBI8rTIQB`YfIX)PJ&dtZ< znlH)kByV=d5Zmb~r730yX5Z}W%!+xiyBZ==ol&nv)F2`c%2?gN@QCm_>yoUAXC0_` z5B)99bc`8q=fpAK82H~A;ImtyL+VriV>Wkw53%y*&WI^OqT=zeFQ@z_?q}(+Xf|)v zTBZ78z2?=tP47JXp~qnn6{BG%8l3U$v({NWv!nPlO~&2Es}DLaqBKtiCL!%52>JRY z&3k&>(WAUKG`XQ&@akT@+t{8=TJM@WetYj=y5mm{_F%tl?@y<7Z|n8$`%m4U*{@vx zwxlcENk(1@&fp4$RC5^)@=WL7;o;~Solrs%6*Qs&B@2vPBjO<=3(?QcOmiR1v|CSP zW}&JDhCqRn6=6Wmhqt*R^|&$|1CD{e#{l0CK9n&KEG?R=1A}P+fK|ASz&1bsK%X7J zK(Mq34@B8ipiNcMVkqeylugHaAn~O|n@-An8T-hWm2@adS`X!$a8iLqH#!C!1M>`2 z?6kq}|M8#u|M?_0a|}2JR*C^tJqnLHC`sPdrQ-Ol^`RF~7LF?|niLH392 Date: Thu, 16 Nov 2023 15:55:10 +0800 Subject: [PATCH 09/15] Update EZConst.h --- Easydict/App/EZConst.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Easydict/App/EZConst.h b/Easydict/App/EZConst.h index 680fc22b4..3e67abe68 100644 --- a/Easydict/App/EZConst.h +++ b/Easydict/App/EZConst.h @@ -39,7 +39,7 @@ static NSString *const EZUserAgent = @"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 // ???: If value is not 0.2, it seems will block animation, because default animationResizeTime is 0.2 ? static NSTimeInterval const EZUpdateTableViewRowHeightAnimationDuration = 0.2; -static NSTimeInterval const EZNetWorkTimeoutInterval = 150.0; +static NSTimeInterval const EZNetWorkTimeoutInterval = 15.0; // !!!: This floating window level shouldn't be higher than kCGModalPanelWindowLevel, otherwise it will cover system modal alert window. static NSTimeInterval const EZFloatingWindowLevel = kCGModalPanelWindowLevel; From a9eacd5d19d6ecc6fcac1c03892f2872e9fe3400 Mon Sep 17 00:00:00 2001 From: BigGunag <48265638+BigGuang97@users.noreply.github.com> Date: Thu, 16 Nov 2023 16:00:41 +0800 Subject: [PATCH 10/15] Update EZNiuTransTranslate.m --- Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m index 588a578ee..4a3b3cedc 100644 --- a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m +++ b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m @@ -98,7 +98,7 @@ - (NSString *)link { EZLanguageSerbian, @"sr", EZLanguageCroatian, @"hr", EZLanguageMongolian, @"mn", - EZLanguageHebrew, @"et", + EZLanguageHebrew, @"he", nil]; return orderedDict; } From 4f7ef6e19476f5668c441f8687cd297dfbcd658a Mon Sep 17 00:00:00 2001 From: BigGunag <48265638+BigGuang97@users.noreply.github.com> Date: Thu, 16 Nov 2023 16:08:37 +0800 Subject: [PATCH 11/15] Update EZNiuTransTranslate.m --- Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m index 4a3b3cedc..78e8ccc2c 100644 --- a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m +++ b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m @@ -129,7 +129,8 @@ - (void)niuTransTranslate:(NSString *)text from:(EZLanguage)from to:(EZLanguage) @"apikey" : self.apiKey, @"src_text" : text, @"from" : souceLangCode, - @"to" : targetLangCode + @"to" : targetLangCode, + @"source" : @"Easydict" }; AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; From 9be2d0dd6500e57c0e8896efa12ff5c2cd80689e Mon Sep 17 00:00:00 2001 From: BigGunag <48265638+BigGuang97@users.noreply.github.com> Date: Thu, 16 Nov 2023 17:36:09 +0800 Subject: [PATCH 12/15] Delete Easydict/Feature/Service/Niutrans/.DS_Store --- Easydict/Feature/Service/Niutrans/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Easydict/Feature/Service/Niutrans/.DS_Store diff --git a/Easydict/Feature/Service/Niutrans/.DS_Store b/Easydict/Feature/Service/Niutrans/.DS_Store deleted file mode 100644 index ebc3929da95b595e4d8a16f151e1423441eb5e7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKJxc>Y5PcJa1Z~m?Hi7GffdAkONns=SQCVp;sBn5>OksDuKgQo@rEg{yHJ3;f zB&f{5%-h@DnVo&GJGTI&H#y%1+5lQq#pW8#9MN&r8EK@RRiapo365}wQ`}%YGdnth zfneabF`#F60|Ojm4_Ekje&0`W!4rLt5xThCEy}ZDQ4Z;)SH=#t`(nb@cOqTaB0be2 zb-tL>0rMK;7Ny-eb8?iY%#}+_w&4zRcm`~ zT+~+OXUHFCfHhmCweA=;7zhS}fj0*9e#oebdBV!kt_~V|0uY<*Hep+T4Adt}m?x|p zIYJS4CAzDmCx*B?`?EAJPgps+J0v|mB&{szg(9{(<7YM Date: Thu, 16 Nov 2023 17:36:54 +0800 Subject: [PATCH 13/15] Delete Easydict/Feature/Service/DeepL/.DS_Store --- Easydict/Feature/Service/DeepL/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Easydict/Feature/Service/DeepL/.DS_Store diff --git a/Easydict/Feature/Service/DeepL/.DS_Store b/Easydict/Feature/Service/DeepL/.DS_Store deleted file mode 100644 index 9ef9b40ee68872a0d366493f335f0de1a8207788..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~u}T9$5QhKJ6akxHWw}of@C}xj6gCRlSxMAFNIW5=zs|?;5%r&$RXk3?%0m7L zv;W@Q%x>;0Zf*hCVt;=M%m7U3u6XfbY<}N;WCtx`R65t#;}U1M;_qRU{e8e|kFmlH zF7P<0-{Bb@p0MLub8OEy-Q9ZAt(otC_LV+=3*$^C0wN#+A|L`H@LK}jduh|7RE;7a z0wVB9z~2vr?pmAnsqyOI5Jv#&gyAsG<19ff9-!8yeJUd~%Tj8VT03G`mNQ;jUTxZ^ zW;rZ&<~nU>YbO+o-5D>D4y&meML-0G1P=3Z=KX&~|Ka>UEYg(-h`_%hV3Xzba=}Mx zy>;|(-fIi}mi}SPjdTvtimB0xdEu@2b Date: Thu, 16 Nov 2023 17:39:21 +0800 Subject: [PATCH 14/15] Delete Easydict/Feature/.DS_Store --- Easydict/Feature/.DS_Store | Bin 8196 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Easydict/Feature/.DS_Store diff --git a/Easydict/Feature/.DS_Store b/Easydict/Feature/.DS_Store deleted file mode 100644 index 8e185c0bd0cbedcf40143f88e92469c584db9a04..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHML2uJA6n^eHnleB=fYb|8B(4**D@>ZWl&(8WFbPrE4uDG2hAmnaS83V`Rh4>% z|G;11$}i!+aDwmI-jt-9I81^{_(}G2?eB~0?>R}IOGKhI9@L4dMC72buWX>Y#CV*` zk`+u(1zvzp6won^DW)DJOK96+6|f3e1*`&A0jt0&D1di1n{&l`Uys__Dqt1(FBRbD zgNwqxY5YQa_2@vQQULfOx|N~L=>T(F3X@_8O-H|La82VE+G{!q zlY9s>voINoP_yIuu7ZsLNM?Fd3O{<137KUaWohyZbuI|WvAS&RA;mLliH@+*xH$Iy0e`v zv>!LN=kv02@4=&|uezt7#@z%iQRi%98qq%5KAq(_ zyj#+o61@Q~pb#aYPdPO2jWqfW9Rlam)I1#$tU-bsa>TP-wJ$EX_Wchftyu+DU4b?I z1*@F@?_GWVzv|1d-_I&w6}W~1qS)@VTe!ga&(8d{IM;SjKA^BMZlS%Rpi=2Lyh_L6 eFa9t@+Xa+4P2(5ZqX%XW0+bB4vI_iF1%3nDsx;dG From 676a54984bca31c12899aaf6959749642075f447 Mon Sep 17 00:00:00 2001 From: BigGunag <48265638+BigGuang97@users.noreply.github.com> Date: Thu, 16 Nov 2023 17:39:40 +0800 Subject: [PATCH 15/15] Delete Easydict/Feature/Service/.DS_Store --- Easydict/Feature/Service/.DS_Store | Bin 8196 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 Easydict/Feature/Service/.DS_Store diff --git a/Easydict/Feature/Service/.DS_Store b/Easydict/Feature/Service/.DS_Store deleted file mode 100644 index 573ba90141c60e10e72be0099bf2c88d4c4e1025..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHM-D(p-6h4zC&6XlmP>C19g11GJMq7$ENsLIL{$NUrsKnjwnl5g3LVgTV0=d?A z@D;r63-}7Yg3sWUe)E&EKSnQV8^JkY=4@uZGqd}hIWsvMB4Uk^S0O49k%c1k+A6AF zi0Bt3BRSo29h$+O$lnS1p&N2HgEb9?0mFb{z%XDKFbw<~4B*TbV$C`CRj;WH1BQYB zk^!+l*eF8Rw4N$0w+>V?1%S?@SqiR^2S^)R>zdY6rKKsxRM`X5rc9?8OqrwK7I5gA z)>EaGIWc8UOwY`8hQj3Ru(KtcSWRhD8wLymSq4PzUZ6Vl@Cg(7y9lH@%B>$#r0FVJ zM&waIoSp*j(0lT!AItiM)#sE|ff_&tup1?j>_!Ti2Qr|DIw{=8c{q1G=;`+jCvGnc z2E%gsE6XkA3(G~TXsueWT1R}`8al(#pyBjih;MtGhwkj!arXm%++MqKpGQL{i2S}Z z2s|H6dO#nTny_qNE&N#$Kshv^!BtF72JqJqcs1BuOlPhU1cG153OZ#5p`BQ!a z*+$Nlfh9G1N#y?z=D+_x*LyI78wLymi)Dc2o2_O8_b~g3n!X*8YuhNVQG^KGRB35~ zN~Yt`G98CL{lgH~HlV_$ru9^5v_LNWMZoO;N&Nbf`A7VWHRu1u<~`>8moc!2>L-P5 BHrN0F