Compare commits

..

No commits in common. "a7568e6874b2ab09a992d9f3577a8090ebcb9651" and "b3c8a809dd33192aae5614229e87c33368baa73c" have entirely different histories.

78 changed files with 642 additions and 3800 deletions

View File

@ -18,14 +18,6 @@
6841A8FF53F0AADF96B138C1 /* UIControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6841AFE790F6FC06838B1E2C /* UIControl.swift */; };
6841ABD5E4B126DEF3612BBD /* PNKeyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6841AB0052E9DB6914901EA3 /* PNKeyboard.swift */; };
6841AF924E165F1B3A3B5FB5 /* AuthController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6841ABEA0314E3B4E438C311 /* AuthController.swift */; };
7A024AAE28BD5B450010D3D1 /* RoadNumbers.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7A024AAC28BD5B450010D3D1 /* RoadNumbers.otf */; };
7A024AAF28BD5B450010D3D1 /* RoadNumbers2.0.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7A024AAD28BD5B450010D3D1 /* RoadNumbers2.0.otf */; };
7A0391D6285933EF000EE522 /* AutoCatCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A49F4D727D4064500AEAAE0 /* AutoCatCore.framework */; };
7A0391D7285933EF000EE522 /* AutoCatCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7A49F4D727D4064500AEAAE0 /* AutoCatCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
7A0391DD28593DBC000EE522 /* SidebarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A0391DC28593DBC000EE522 /* SidebarController.swift */; };
7A054FD928C4BE560002C386 /* PlateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A054FD828C4BE560002C386 /* PlateView.swift */; };
7A054FDA28C4C24B0002C386 /* CenterTextLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A24C19E27EE26B900049E7F /* CenterTextLayer.swift */; };
7A163BF128BBE9ED0005A0A4 /* VehiclesListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A163BF028BBE9ED0005A0A4 /* VehiclesListView.swift */; };
7A1D80E027F1F275007BD64F /* DifferenceKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7A1D80DF27F1F275007BD64F /* DifferenceKit */; };
7A1D80E627F20FCB007BD64F /* DifferenceKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7A1D80E527F20FCB007BD64F /* DifferenceKit */; };
7A1D80E827F30399007BD64F /* VModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A1D80E727F30399007BD64F /* VModel.swift */; };
@ -49,21 +41,7 @@
7A36E56027FB5A2F0025AACB /* MockURLProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AAE27FA3CCF001A18EE /* MockURLProtocol.swift */; };
7A36E56127FB5A330025AACB /* ApiMethodMockProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AAF27FA3CCF001A18EE /* ApiMethodMockProtocol.swift */; };
7A36E56327FB5BEB0025AACB /* TestError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A36E56227FB5BEB0025AACB /* TestError.swift */; };
7A39D0772998F25600A6F6FC /* PlaceholderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A39D0762998F25600A6F6FC /* PlaceholderView.swift */; };
7A39D07A2998FF3500A6F6FC /* RealmDecoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A39D0792998FF3500A6F6FC /* RealmDecoding.swift */; };
7A39D07D299904B700A6F6FC /* SidebarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A39D07C299904B700A6F6FC /* SidebarView.swift */; };
7A48B26727D9442A004D1A4B /* PKHUD in Frameworks */ = {isa = PBXBuildFile; productRef = 7A48B26627D9442A004D1A4B /* PKHUD */; };
7A4951B7288D3A6100C644B6 /* AutoCat2SUIApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4951B6288D3A6100C644B6 /* AutoCat2SUIApp.swift */; };
7A4951B9288D3A6100C644B6 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4951B8288D3A6100C644B6 /* RootView.swift */; };
7A4951BB288D3A6300C644B6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7A4951BA288D3A6300C644B6 /* Assets.xcassets */; };
7A4951BF288D3A6300C644B6 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7A4951BE288D3A6300C644B6 /* Preview Assets.xcassets */; };
7A4951C5288D3BCF00C644B6 /* AuthView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4951C4288D3BCF00C644B6 /* AuthView.swift */; };
7A4951C7288D3BDD00C644B6 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4951C6288D3BDD00C644B6 /* MainView.swift */; };
7A4951C8288D3BFA00C644B6 /* AutoCatCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A49F4D727D4064500AEAAE0 /* AutoCatCore.framework */; };
7A4951C9288D3BFA00C644B6 /* AutoCatCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7A49F4D727D4064500AEAAE0 /* AutoCatCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
7A4951D1288D5C4300C644B6 /* ACProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4951D0288D5C4300C644B6 /* ACProgressView.swift */; };
7A4951D3288D5E2800C644B6 /* AuthVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4951D2288D5E2800C644B6 /* AuthVM.swift */; };
7A4951D5288D5ED000C644B6 /* Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4951D4288D5ED000C644B6 /* Alert.swift */; };
7A49F4A327D4061900AEAAE0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F4A227D4061900AEAAE0 /* AppDelegate.swift */; };
7A49F4A527D4061900AEAAE0 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F4A427D4061900AEAAE0 /* SceneDelegate.swift */; };
7A49F4A727D4061900AEAAE0 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F4A627D4061900AEAAE0 /* ViewController.swift */; };
@ -87,38 +65,20 @@
7A49F50D27D406CB00AEAAE0 /* Vehicle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F50627D406CB00AEAAE0 /* Vehicle.swift */; };
7A49F50E27D406CB00AEAAE0 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F50727D406CB00AEAAE0 /* User.swift */; };
7A49F50F27D406CB00AEAAE0 /* Response.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F50827D406CB00AEAAE0 /* Response.swift */; };
7A49F51027D406CB00AEAAE0 /* MainSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F50927D406CB00AEAAE0 /* MainSettings.swift */; };
7A49F51027D406CB00AEAAE0 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F50927D406CB00AEAAE0 /* Settings.swift */; };
7A49F51127D406CB00AEAAE0 /* PlateNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F50A27D406CB00AEAAE0 /* PlateNumber.swift */; };
7A49F51227D406CB00AEAAE0 /* VName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F50B27D406CB00AEAAE0 /* VName.swift */; };
7A49F51527D40C6100AEAAE0 /* AutoCat2.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F51327D40C6100AEAAE0 /* AutoCat2.xcdatamodeld */; };
7A558AB027FA3CCF001A18EE /* SettingsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AA527FA3CCF001A18EE /* SettingsTests.swift */; };
7A558AB127FA3CCF001A18EE /* ApiTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AA627FA3CCF001A18EE /* ApiTests.swift */; };
7A91E8112986DE9C0008A982 /* Realm in Frameworks */ = {isa = PBXBuildFile; productRef = 7A91E8102986DE9C0008A982 /* Realm */; };
7A91E8132986DE9C0008A982 /* RealmSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 7A91E8122986DE9C0008A982 /* RealmSwift */; };
7A9471BD28C52DD80054CB0A /* PlateViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9471BC28C52DD80054CB0A /* PlateViewItem.swift */; };
7A9F2AC327E71531006492A9 /* ACTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9F2AC227E71531006492A9 /* ACTabBarController.swift */; };
7A9FD4072857AF590057ECFA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9FD4062857AF590057ECFA /* AppDelegate.swift */; };
7A9FD4092857AF590057ECFA /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9FD4082857AF590057ECFA /* ViewController.swift */; };
7A9FD40B2857AF5A0057ECFA /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7A9FD40A2857AF5A0057ECFA /* Assets.xcassets */; };
7A9FD40E2857AF5A0057ECFA /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7A9FD40C2857AF5A0057ECFA /* Main.storyboard */; };
7A9FD41A2857AF8D0057ECFA /* DifferenceKit in Frameworks */ = {isa = PBXBuildFile; productRef = 7A9FD4192857AF8D0057ECFA /* DifferenceKit */; };
7ABAB2E427FDF7BC00553691 /* check_success.json in Resources */ = {isa = PBXBuildFile; fileRef = 7ABAB2E327FDF7BC00553691 /* check_success.json */; };
7ABAB2E627FDF83100553691 /* GenericMethodMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ABAB2E527FDF83100553691 /* GenericMethodMock.swift */; };
7AE1943E299C3038009D22DA /* VehiclesListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE1943D299C3038009D22DA /* VehiclesListViewModel.swift */; };
7AE32D6427F05F89004EF6E0 /* VehicleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE32D6327F05F89004EF6E0 /* VehicleCell.swift */; };
7AE32D6627F063A1004EF6E0 /* UIEdgeInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE32D6527F063A1004EF6E0 /* UIEdgeInsets.swift */; };
7AE32D6927F06536004EF6E0 /* CoreDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE32D6827F06536004EF6E0 /* CoreDataSource.swift */; };
7AE32D6E27F06D2D004EF6E0 /* SwiftDate in Frameworks */ = {isa = PBXBuildFile; productRef = 7AE32D6D27F06D2D004EF6E0 /* SwiftDate */; };
7AE32D7127F06DA4004EF6E0 /* DateSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE32D7027F06DA4004EF6E0 /* DateSection.swift */; };
7AE9F20428CDFCC600ABF6DF /* VehicleDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE9F20328CDFCC600ABF6DF /* VehicleDetailView.swift */; };
7AF1D0D828BB577E004E19F7 /* CheckNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF1D0D728BB577E004E19F7 /* CheckNumber.swift */; };
7AF1D0DA28BB5BF5004E19F7 /* View.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF1D0D928BB5BF5004E19F7 /* View.swift */; };
7AFD7AE02871823E00BCCD37 /* SidebarSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AFD7ADF2871823E00BCCD37 /* SidebarSection.swift */; };
7AFD7AE22871826D00BCCD37 /* SidebarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AFD7AE12871826D00BCCD37 /* SidebarItem.swift */; };
7AFD7AE4287182CD00BCCD37 /* SidebarFilterItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AFD7AE3287182CD00BCCD37 /* SidebarFilterItem.swift */; };
7AFD7AE628718BF000BCCD37 /* Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AFD7AE528718BF000BCCD37 /* Filter.swift */; };
7AFD7AE82871B7DA00BCCD37 /* MainSplitController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AFD7AE72871B7DA00BCCD37 /* MainSplitController.swift */; };
7AFD7AEB2872355000BCCD37 /* MainWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AFD7AEA2872355000BCCD37 /* MainWindowController.swift */; };
7AFD7AED2874E49600BCCD37 /* CheckController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AFD7AEC2874E49600BCCD37 /* CheckController.swift */; };
929EDE7F27F89C3000E55F65 /* VEngine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 929EDE7E27F89C3000E55F65 /* VEngine.swift */; };
929EDE8127F8A75E00E55F65 /* VPhoto.swift in Sources */ = {isa = PBXBuildFile; fileRef = 929EDE8027F8A75E00E55F65 /* VPhoto.swift */; };
929EDE8327F8C6C500E55F65 /* VOwnershipPeriod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 929EDE8227F8C6C500E55F65 /* VOwnershipPeriod.swift */; };
@ -131,20 +91,6 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
7A0391D8285933EF000EE522 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 7A49F49727D4061900AEAAE0 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 7A49F4D627D4064500AEAAE0;
remoteInfo = AutoCatCore;
};
7A4951CA288D3BFA00C644B6 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 7A49F49727D4061900AEAAE0 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 7A49F4D627D4064500AEAAE0;
remoteInfo = AutoCatCore;
};
7A49F4B627D4061B00AEAAE0 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 7A49F49727D4061900AEAAE0 /* Project object */;
@ -183,28 +129,6 @@
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
7A0391DA285933EF000EE522 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
7A0391D7285933EF000EE522 /* AutoCatCore.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
7A4951CC288D3BFA00C644B6 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
7A4951C9288D3BFA00C644B6 /* AutoCatCore.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
7A49F4F127D4064500AEAAE0 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@ -230,12 +154,6 @@
6841ADEEC165FA9124C5EF40 /* UITextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITextField.swift; sourceTree = "<group>"; };
6841AFB465BF16E122875D9A /* ACButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ACButton.swift; sourceTree = "<group>"; };
6841AFE790F6FC06838B1E2C /* UIControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIControl.swift; sourceTree = "<group>"; };
7A024AAC28BD5B450010D3D1 /* RoadNumbers.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = RoadNumbers.otf; sourceTree = "<group>"; };
7A024AAD28BD5B450010D3D1 /* RoadNumbers2.0.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = RoadNumbers2.0.otf; sourceTree = "<group>"; };
7A024AB028BD5BB30010D3D1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
7A0391DC28593DBC000EE522 /* SidebarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarController.swift; sourceTree = "<group>"; };
7A054FD828C4BE560002C386 /* PlateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlateView.swift; sourceTree = "<group>"; };
7A163BF028BBE9ED0005A0A4 /* VehiclesListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehiclesListView.swift; sourceTree = "<group>"; };
7A1D80E727F30399007BD64F /* VModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VModel.swift; sourceTree = "<group>"; };
7A24C19527EE212E00049E7F /* RoadNumbers.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = RoadNumbers.otf; sourceTree = "<group>"; };
7A24C19627EE212E00049E7F /* RoadNumbers2.0.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = RoadNumbers2.0.otf; sourceTree = "<group>"; };
@ -251,20 +169,6 @@
7A2B6CD527FCEC8600519F1E /* XCUIApplication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCUIApplication.swift; sourceTree = "<group>"; };
7A36E55B27FB55570025AACB /* Testing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Testing.swift; sourceTree = "<group>"; };
7A36E56227FB5BEB0025AACB /* TestError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestError.swift; sourceTree = "<group>"; };
7A39D0762998F25600A6F6FC /* PlaceholderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaceholderView.swift; sourceTree = "<group>"; };
7A39D0792998FF3500A6F6FC /* RealmDecoding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealmDecoding.swift; sourceTree = "<group>"; };
7A39D07C299904B700A6F6FC /* SidebarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarView.swift; sourceTree = "<group>"; };
7A4951B4288D3A6100C644B6 /* AutoCat2SUI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AutoCat2SUI.app; sourceTree = BUILT_PRODUCTS_DIR; };
7A4951B6288D3A6100C644B6 /* AutoCat2SUIApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoCat2SUIApp.swift; sourceTree = "<group>"; };
7A4951B8288D3A6100C644B6 /* RootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootView.swift; sourceTree = "<group>"; };
7A4951BA288D3A6300C644B6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
7A4951BC288D3A6300C644B6 /* AutoCat2SUI.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AutoCat2SUI.entitlements; sourceTree = "<group>"; };
7A4951BE288D3A6300C644B6 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
7A4951C4288D3BCF00C644B6 /* AuthView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthView.swift; sourceTree = "<group>"; };
7A4951C6288D3BDD00C644B6 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = "<group>"; };
7A4951D0288D5C4300C644B6 /* ACProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACProgressView.swift; sourceTree = "<group>"; };
7A4951D2288D5E2800C644B6 /* AuthVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthVM.swift; sourceTree = "<group>"; };
7A4951D4288D5ED000C644B6 /* Alert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Alert.swift; sourceTree = "<group>"; };
7A49F49F27D4061900AEAAE0 /* AutoCat2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AutoCat2.app; sourceTree = BUILT_PRODUCTS_DIR; };
7A49F4A227D4061900AEAAE0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7A49F4A427D4061900AEAAE0 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
@ -291,9 +195,10 @@
7A49F50627D406CB00AEAAE0 /* Vehicle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Vehicle.swift; sourceTree = "<group>"; };
7A49F50727D406CB00AEAAE0 /* User.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = "<group>"; };
7A49F50827D406CB00AEAAE0 /* Response.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Response.swift; sourceTree = "<group>"; };
7A49F50927D406CB00AEAAE0 /* MainSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainSettings.swift; sourceTree = "<group>"; };
7A49F50927D406CB00AEAAE0 /* Settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = "<group>"; };
7A49F50A27D406CB00AEAAE0 /* PlateNumber.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlateNumber.swift; sourceTree = "<group>"; };
7A49F50B27D406CB00AEAAE0 /* VName.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VName.swift; sourceTree = "<group>"; };
7A49F51427D40C6100AEAAE0 /* Shared.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Shared.xcdatamodel; sourceTree = "<group>"; };
7A558AA527FA3CCF001A18EE /* SettingsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsTests.swift; sourceTree = "<group>"; };
7A558AA627FA3CCF001A18EE /* ApiTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiTests.swift; sourceTree = "<group>"; };
7A558AA927FA3CCF001A18EE /* LoginMethodMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginMethodMock.swift; sourceTree = "<group>"; };
@ -301,31 +206,13 @@
7A558AAC27FA3CCF001A18EE /* login_success.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = login_success.json; sourceTree = "<group>"; };
7A558AAE27FA3CCF001A18EE /* MockURLProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockURLProtocol.swift; sourceTree = "<group>"; };
7A558AAF27FA3CCF001A18EE /* ApiMethodMockProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiMethodMockProtocol.swift; sourceTree = "<group>"; };
7A9471BC28C52DD80054CB0A /* PlateViewItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlateViewItem.swift; sourceTree = "<group>"; };
7A9F2AC227E71531006492A9 /* ACTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACTabBarController.swift; sourceTree = "<group>"; };
7A9FD4042857AF590057ECFA /* AutoCat2Mac.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AutoCat2Mac.app; sourceTree = BUILT_PRODUCTS_DIR; };
7A9FD4062857AF590057ECFA /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7A9FD4082857AF590057ECFA /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
7A9FD40A2857AF5A0057ECFA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
7A9FD40D2857AF5A0057ECFA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
7A9FD40F2857AF5A0057ECFA /* AutoCat2Mac.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AutoCat2Mac.entitlements; sourceTree = "<group>"; };
7ABAB2E327FDF7BC00553691 /* check_success.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = check_success.json; sourceTree = "<group>"; };
7ABAB2E527FDF83100553691 /* GenericMethodMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GenericMethodMock.swift; sourceTree = "<group>"; };
7AE1943D299C3038009D22DA /* VehiclesListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehiclesListViewModel.swift; sourceTree = "<group>"; };
7AE32D6327F05F89004EF6E0 /* VehicleCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleCell.swift; sourceTree = "<group>"; };
7AE32D6527F063A1004EF6E0 /* UIEdgeInsets.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIEdgeInsets.swift; sourceTree = "<group>"; };
7AE32D6827F06536004EF6E0 /* CoreDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreDataSource.swift; sourceTree = "<group>"; };
7AE32D7027F06DA4004EF6E0 /* DateSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateSection.swift; sourceTree = "<group>"; };
7AE9F20328CDFCC600ABF6DF /* VehicleDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehicleDetailView.swift; sourceTree = "<group>"; };
7AF1D0D728BB577E004E19F7 /* CheckNumber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckNumber.swift; sourceTree = "<group>"; };
7AF1D0D928BB5BF5004E19F7 /* View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = View.swift; sourceTree = "<group>"; };
7AFD7ADF2871823E00BCCD37 /* SidebarSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarSection.swift; sourceTree = "<group>"; };
7AFD7AE12871826D00BCCD37 /* SidebarItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarItem.swift; sourceTree = "<group>"; };
7AFD7AE3287182CD00BCCD37 /* SidebarFilterItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarFilterItem.swift; sourceTree = "<group>"; };
7AFD7AE528718BF000BCCD37 /* Filter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Filter.swift; sourceTree = "<group>"; };
7AFD7AE72871B7DA00BCCD37 /* MainSplitController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainSplitController.swift; sourceTree = "<group>"; };
7AFD7AEA2872355000BCCD37 /* MainWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainWindowController.swift; sourceTree = "<group>"; };
7AFD7AEC2874E49600BCCD37 /* CheckController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckController.swift; sourceTree = "<group>"; };
929EDE7E27F89C3000E55F65 /* VEngine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VEngine.swift; sourceTree = "<group>"; };
929EDE8027F8A75E00E55F65 /* VPhoto.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPhoto.swift; sourceTree = "<group>"; };
929EDE8227F8C6C500E55F65 /* VOwnershipPeriod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VOwnershipPeriod.swift; sourceTree = "<group>"; };
@ -338,14 +225,6 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
7A4951B1288D3A6100C644B6 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
7A4951C8288D3BFA00C644B6 /* AutoCatCore.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
7A49F49C27D4061900AEAAE0 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -375,8 +254,6 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
7A91E8132986DE9C0008A982 /* RealmSwift in Frameworks */,
7A91E8112986DE9C0008A982 /* Realm in Frameworks */,
7A1D80E627F20FCB007BD64F /* DifferenceKit in Frameworks */,
7AE32D6E27F06D2D004EF6E0 /* SwiftDate in Frameworks */,
);
@ -390,15 +267,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
7A9FD4012857AF590057ECFA /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
7A9FD41A2857AF8D0057ECFA /* DifferenceKit in Frameworks */,
7A0391D6285933EF000EE522 /* AutoCatCore.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
@ -451,43 +319,6 @@
path = Components;
sourceTree = "<group>";
};
7A024AAB28BD5B450010D3D1 /* Fonts */ = {
isa = PBXGroup;
children = (
7A024AAC28BD5B450010D3D1 /* RoadNumbers.otf */,
7A024AAD28BD5B450010D3D1 /* RoadNumbers2.0.otf */,
);
path = Fonts;
sourceTree = "<group>";
};
7A0391DB28593DAB000EE522 /* Controllers */ = {
isa = PBXGroup;
children = (
7AFD7ADE2871822000BCCD37 /* Sidebar */,
7AFD7AE72871B7DA00BCCD37 /* MainSplitController.swift */,
7AFD7AEC2874E49600BCCD37 /* CheckController.swift */,
);
path = Controllers;
sourceTree = "<group>";
};
7A054FD728C4BB700002C386 /* PlateView */ = {
isa = PBXGroup;
children = (
7A054FD828C4BE560002C386 /* PlateView.swift */,
7A9471BC28C52DD80054CB0A /* PlateViewItem.swift */,
);
path = PlateView;
sourceTree = "<group>";
};
7A163BEF28BBE9DA0005A0A4 /* VehiclesList */ = {
isa = PBXGroup;
children = (
7A163BF028BBE9ED0005A0A4 /* VehiclesListView.swift */,
7AE1943D299C3038009D22DA /* VehiclesListViewModel.swift */,
);
path = VehiclesList;
sourceTree = "<group>";
};
7A24C19427EE212E00049E7F /* Fonts */ = {
isa = PBXGroup;
children = (
@ -534,96 +365,6 @@
path = Testing;
sourceTree = "<group>";
};
7A39D0782998FF1800A6F6FC /* Extensions */ = {
isa = PBXGroup;
children = (
7A39D0792998FF3500A6F6FC /* RealmDecoding.swift */,
);
path = Extensions;
sourceTree = "<group>";
};
7A39D07B2999049F00A6F6FC /* Sidebar */ = {
isa = PBXGroup;
children = (
7A39D07C299904B700A6F6FC /* SidebarView.swift */,
);
path = Sidebar;
sourceTree = "<group>";
};
7A4951B5288D3A6100C644B6 /* AutoCat2SUI */ = {
isa = PBXGroup;
children = (
7A024AB028BD5BB30010D3D1 /* Info.plist */,
7A024AAB28BD5B450010D3D1 /* Fonts */,
7A4951B6288D3A6100C644B6 /* AutoCat2SUIApp.swift */,
7A4951D6288D5EE700C644B6 /* Extensions */,
7A4951CF288D5C2100C644B6 /* Views */,
7A4951C3288D3AF000C644B6 /* Screens */,
7A4951BA288D3A6300C644B6 /* Assets.xcassets */,
7A4951BC288D3A6300C644B6 /* AutoCat2SUI.entitlements */,
7A4951BD288D3A6300C644B6 /* Preview Content */,
);
path = AutoCat2SUI;
sourceTree = "<group>";
};
7A4951BD288D3A6300C644B6 /* Preview Content */ = {
isa = PBXGroup;
children = (
7A4951BE288D3A6300C644B6 /* Preview Assets.xcassets */,
);
path = "Preview Content";
sourceTree = "<group>";
};
7A4951C3288D3AF000C644B6 /* Screens */ = {
isa = PBXGroup;
children = (
7A39D07B2999049F00A6F6FC /* Sidebar */,
7AE9F20228CDFCAB00ABF6DF /* VehicleDetail */,
7A163BEF28BBE9DA0005A0A4 /* VehiclesList */,
7AF1D0D628BB5768004E19F7 /* CheckNumber */,
7A4951CE288D5C1300C644B6 /* Main */,
7A4951CD288D5C0800C644B6 /* Auth */,
);
path = Screens;
sourceTree = "<group>";
};
7A4951CD288D5C0800C644B6 /* Auth */ = {
isa = PBXGroup;
children = (
7A4951C4288D3BCF00C644B6 /* AuthView.swift */,
7A4951D2288D5E2800C644B6 /* AuthVM.swift */,
);
path = Auth;
sourceTree = "<group>";
};
7A4951CE288D5C1300C644B6 /* Main */ = {
isa = PBXGroup;
children = (
7A4951C6288D3BDD00C644B6 /* MainView.swift */,
);
path = Main;
sourceTree = "<group>";
};
7A4951CF288D5C2100C644B6 /* Views */ = {
isa = PBXGroup;
children = (
7A054FD728C4BB700002C386 /* PlateView */,
7A4951B8288D3A6100C644B6 /* RootView.swift */,
7A4951D0288D5C4300C644B6 /* ACProgressView.swift */,
7A39D0762998F25600A6F6FC /* PlaceholderView.swift */,
);
path = Views;
sourceTree = "<group>";
};
7A4951D6288D5EE700C644B6 /* Extensions */ = {
isa = PBXGroup;
children = (
7A4951D4288D5ED000C644B6 /* Alert.swift */,
7AF1D0D928BB5BF5004E19F7 /* View.swift */,
);
path = Extensions;
sourceTree = "<group>";
};
7A49F49627D4061900AEAAE0 = {
isa = PBXGroup;
children = (
@ -632,10 +373,7 @@
7A49F4C227D4061B00AEAAE0 /* AutoCat2UITests */,
7A49F4D827D4064500AEAAE0 /* AutoCatCore */,
7A49F4E627D4064500AEAAE0 /* AutoCatCoreTests */,
7A9FD4052857AF590057ECFA /* AutoCat2Mac */,
7A4951B5288D3A6100C644B6 /* AutoCat2SUI */,
7A49F4A027D4061900AEAAE0 /* Products */,
7A9FD4132857AF860057ECFA /* Frameworks */,
);
sourceTree = "<group>";
};
@ -647,8 +385,6 @@
7A49F4BF27D4061B00AEAAE0 /* AutoCat2UITests.xctest */,
7A49F4D727D4064500AEAAE0 /* AutoCatCore.framework */,
7A49F4E027D4064500AEAAE0 /* AutoCatCoreTests.xctest */,
7A9FD4042857AF590057ECFA /* AutoCat2Mac.app */,
7A4951B4288D3A6100C644B6 /* AutoCat2SUI.app */,
);
name = Products;
sourceTree = "<group>";
@ -692,9 +428,9 @@
7A49F4D827D4064500AEAAE0 /* AutoCatCore */ = {
isa = PBXGroup;
children = (
7A39D0782998FF1800A6F6FC /* Extensions */,
7A36E55A27FB54610025AACB /* Testing */,
7AE32D6F27F06D87004EF6E0 /* DataSource */,
7A49F51327D40C6100AEAAE0 /* AutoCat2.xcdatamodeld */,
7A49F50427D406CB00AEAAE0 /* Models */,
7A49F4FF27D406C300AEAAE0 /* Services */,
7A49F4FC27D406BA00AEAAE0 /* ThirdParty */,
@ -748,9 +484,8 @@
7A49F50627D406CB00AEAAE0 /* Vehicle.swift */,
7A49F50727D406CB00AEAAE0 /* User.swift */,
7A49F50827D406CB00AEAAE0 /* Response.swift */,
7A49F50927D406CB00AEAAE0 /* MainSettings.swift */,
7A49F50927D406CB00AEAAE0 /* Settings.swift */,
7A49F50A27D406CB00AEAAE0 /* PlateNumber.swift */,
7AFD7AE528718BF000BCCD37 /* Filter.swift */,
);
path = Models;
sourceTree = "<group>";
@ -793,27 +528,6 @@
path = Lib;
sourceTree = "<group>";
};
7A9FD4052857AF590057ECFA /* AutoCat2Mac */ = {
isa = PBXGroup;
children = (
7AFD7AE92872353B00BCCD37 /* Window */,
7A0391DB28593DAB000EE522 /* Controllers */,
7A9FD4062857AF590057ECFA /* AppDelegate.swift */,
7A9FD4082857AF590057ECFA /* ViewController.swift */,
7A9FD40A2857AF5A0057ECFA /* Assets.xcassets */,
7A9FD40C2857AF5A0057ECFA /* Main.storyboard */,
7A9FD40F2857AF5A0057ECFA /* AutoCat2Mac.entitlements */,
);
path = AutoCat2Mac;
sourceTree = "<group>";
};
7A9FD4132857AF860057ECFA /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
7AE32D6227F05F5D004EF6E0 /* Cells */ = {
isa = PBXGroup;
children = (
@ -838,41 +552,6 @@
path = DataSource;
sourceTree = "<group>";
};
7AE9F20228CDFCAB00ABF6DF /* VehicleDetail */ = {
isa = PBXGroup;
children = (
7AE9F20328CDFCC600ABF6DF /* VehicleDetailView.swift */,
);
path = VehicleDetail;
sourceTree = "<group>";
};
7AF1D0D628BB5768004E19F7 /* CheckNumber */ = {
isa = PBXGroup;
children = (
7AF1D0D728BB577E004E19F7 /* CheckNumber.swift */,
);
path = CheckNumber;
sourceTree = "<group>";
};
7AFD7ADE2871822000BCCD37 /* Sidebar */ = {
isa = PBXGroup;
children = (
7A0391DC28593DBC000EE522 /* SidebarController.swift */,
7AFD7ADF2871823E00BCCD37 /* SidebarSection.swift */,
7AFD7AE12871826D00BCCD37 /* SidebarItem.swift */,
7AFD7AE3287182CD00BCCD37 /* SidebarFilterItem.swift */,
);
path = Sidebar;
sourceTree = "<group>";
};
7AFD7AE92872353B00BCCD37 /* Window */ = {
isa = PBXGroup;
children = (
7AFD7AEA2872355000BCCD37 /* MainWindowController.swift */,
);
path = Window;
sourceTree = "<group>";
};
929EDE8A27F8E84F00E55F65 /* vmodels */ = {
isa = PBXGroup;
children = (
@ -906,25 +585,6 @@
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
7A4951B3288D3A6100C644B6 /* AutoCat2SUI */ = {
isa = PBXNativeTarget;
buildConfigurationList = 7A4951C0288D3A6300C644B6 /* Build configuration list for PBXNativeTarget "AutoCat2SUI" */;
buildPhases = (
7A4951B0288D3A6100C644B6 /* Sources */,
7A4951B1288D3A6100C644B6 /* Frameworks */,
7A4951B2288D3A6100C644B6 /* Resources */,
7A4951CC288D3BFA00C644B6 /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
7A4951CB288D3BFA00C644B6 /* PBXTargetDependency */,
);
name = AutoCat2SUI;
productName = AutoCat2SUI;
productReference = 7A4951B4288D3A6100C644B6 /* AutoCat2SUI.app */;
productType = "com.apple.product-type.application";
};
7A49F49E27D4061900AEAAE0 /* AutoCat2 */ = {
isa = PBXNativeTarget;
buildConfigurationList = 7A49F4C927D4061B00AEAAE0 /* Build configuration list for PBXNativeTarget "AutoCat2" */;
@ -1002,8 +662,6 @@
packageProductDependencies = (
7AE32D6D27F06D2D004EF6E0 /* SwiftDate */,
7A1D80E527F20FCB007BD64F /* DifferenceKit */,
7A91E8102986DE9C0008A982 /* Realm */,
7A91E8122986DE9C0008A982 /* RealmSwift */,
);
productName = AutoCatCore;
productReference = 7A49F4D727D4064500AEAAE0 /* AutoCatCore.framework */;
@ -1028,28 +686,6 @@
productReference = 7A49F4E027D4064500AEAAE0 /* AutoCatCoreTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
7A9FD4032857AF590057ECFA /* AutoCat2Mac */ = {
isa = PBXNativeTarget;
buildConfigurationList = 7A9FD4122857AF5A0057ECFA /* Build configuration list for PBXNativeTarget "AutoCat2Mac" */;
buildPhases = (
7A9FD4002857AF590057ECFA /* Sources */,
7A9FD4012857AF590057ECFA /* Frameworks */,
7A9FD4022857AF590057ECFA /* Resources */,
7A0391DA285933EF000EE522 /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
7A0391D9285933EF000EE522 /* PBXTargetDependency */,
);
name = AutoCat2Mac;
packageProductDependencies = (
7A9FD4192857AF8D0057ECFA /* DifferenceKit */,
);
productName = AutoCat2Mac;
productReference = 7A9FD4042857AF590057ECFA /* AutoCat2Mac.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@ -1057,12 +693,9 @@
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1400;
LastUpgradeCheck = 1400;
LastSwiftUpdateCheck = 1320;
LastUpgradeCheck = 1320;
TargetAttributes = {
7A4951B3288D3A6100C644B6 = {
CreatedOnToolsVersion = 14.0;
};
7A49F49E27D4061900AEAAE0 = {
CreatedOnToolsVersion = 13.2.1;
};
@ -1081,9 +714,6 @@
CreatedOnToolsVersion = 13.2.1;
TestTargetID = 7A49F49E27D4061900AEAAE0;
};
7A9FD4032857AF590057ECFA = {
CreatedOnToolsVersion = 13.4.1;
};
};
};
buildConfigurationList = 7A49F49A27D4061900AEAAE0 /* Build configuration list for PBXProject "AutoCat2" */;
@ -1101,7 +731,6 @@
7AE32D6C27F06D2D004EF6E0 /* XCRemoteSwiftPackageReference "SwiftDate" */,
7A1D80DE27F1F275007BD64F /* XCRemoteSwiftPackageReference "DifferenceKit" */,
7A1D80E427F20FCB007BD64F /* XCRemoteSwiftPackageReference "DifferenceKit" */,
7A91E80F2986DE9C0008A982 /* XCRemoteSwiftPackageReference "realm-swift" */,
);
productRefGroup = 7A49F4A027D4061900AEAAE0 /* Products */;
projectDirPath = "";
@ -1112,24 +741,11 @@
7A49F4BE27D4061B00AEAAE0 /* AutoCat2UITests */,
7A49F4D627D4064500AEAAE0 /* AutoCatCore */,
7A49F4DF27D4064500AEAAE0 /* AutoCatCoreTests */,
7A9FD4032857AF590057ECFA /* AutoCat2Mac */,
7A4951B3288D3A6100C644B6 /* AutoCat2SUI */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
7A4951B2288D3A6100C644B6 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7A4951BF288D3A6300C644B6 /* Preview Assets.xcassets in Resources */,
7A4951BB288D3A6300C644B6 /* Assets.xcassets in Resources */,
7A024AAE28BD5B450010D3D1 /* RoadNumbers.otf in Resources */,
7A024AAF28BD5B450010D3D1 /* RoadNumbers2.0.otf in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
7A49F49D27D4061900AEAAE0 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@ -1172,42 +788,9 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
7A9FD4022857AF590057ECFA /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7A9FD40B2857AF5A0057ECFA /* Assets.xcassets in Resources */,
7A9FD40E2857AF5A0057ECFA /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
7A4951B0288D3A6100C644B6 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7A4951D3288D5E2800C644B6 /* AuthVM.swift in Sources */,
7A39D07D299904B700A6F6FC /* SidebarView.swift in Sources */,
7AE1943E299C3038009D22DA /* VehiclesListViewModel.swift in Sources */,
7A054FDA28C4C24B0002C386 /* CenterTextLayer.swift in Sources */,
7A163BF128BBE9ED0005A0A4 /* VehiclesListView.swift in Sources */,
7A054FD928C4BE560002C386 /* PlateView.swift in Sources */,
7A4951B9288D3A6100C644B6 /* RootView.swift in Sources */,
7A4951C7288D3BDD00C644B6 /* MainView.swift in Sources */,
7AE9F20428CDFCC600ABF6DF /* VehicleDetailView.swift in Sources */,
7AF1D0D828BB577E004E19F7 /* CheckNumber.swift in Sources */,
7A39D0772998F25600A6F6FC /* PlaceholderView.swift in Sources */,
7A4951B7288D3A6100C644B6 /* AutoCat2SUIApp.swift in Sources */,
7A9471BD28C52DD80054CB0A /* PlateViewItem.swift in Sources */,
7AF1D0DA28BB5BF5004E19F7 /* View.swift in Sources */,
7A4951D1288D5C4300C644B6 /* ACProgressView.swift in Sources */,
7A4951C5288D3BCF00C644B6 /* AuthView.swift in Sources */,
7A4951D5288D5ED000C644B6 /* Alert.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
7A49F49B27D4061900AEAAE0 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -1271,14 +854,13 @@
7A49F50227D406C300AEAAE0 /* StorageService.swift in Sources */,
7A49F4FE27D406BA00AEAAE0 /* AnyEncodable.swift in Sources */,
7ABAB2E627FDF83100553691 /* GenericMethodMock.swift in Sources */,
7AFD7AE628718BF000BCCD37 /* Filter.swift in Sources */,
7A49F51227D406CB00AEAAE0 /* VName.swift in Sources */,
7A1D80E827F30399007BD64F /* VModel.swift in Sources */,
7A49F51127D406CB00AEAAE0 /* PlateNumber.swift in Sources */,
7A36E55E27FB5A260025AACB /* LoginMethodMock.swift in Sources */,
7A49F50C27D406CB00AEAAE0 /* VBrand.swift in Sources */,
7A36E55C27FB55570025AACB /* Testing.swift in Sources */,
7A49F51027D406CB00AEAAE0 /* MainSettings.swift in Sources */,
7A49F51027D406CB00AEAAE0 /* Settings.swift in Sources */,
929EDE9027F8F76300E55F65 /* DebugInfo.swift in Sources */,
7A36E55D27FB5A220025AACB /* ApiMethodMock.swift in Sources */,
929EDE8927F8E65500E55F65 /* VAd.swift in Sources */,
@ -1288,9 +870,9 @@
7A49F50F27D406CB00AEAAE0 /* Response.swift in Sources */,
929EDE8127F8A75E00E55F65 /* VPhoto.swift in Sources */,
7A49F4FB27D406B200AEAAE0 /* Api.swift in Sources */,
7A49F51527D40C6100AEAAE0 /* AutoCat2.xcdatamodeld in Sources */,
929EDE7F27F89C3000E55F65 /* VEngine.swift in Sources */,
929EDE8727F8E11E00E55F65 /* VOsago.swift in Sources */,
7A39D07A2998FF3500A6F6FC /* RealmDecoding.swift in Sources */,
7A2B6CD427FCE93C00519F1E /* TestSettings.swift in Sources */,
7A49F50E27D406CB00AEAAE0 /* User.swift in Sources */,
7A36E56127FB5A330025AACB /* ApiMethodMockProtocol.swift in Sources */,
@ -1309,35 +891,9 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
7A9FD4002857AF590057ECFA /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7A9FD4092857AF590057ECFA /* ViewController.swift in Sources */,
7A0391DD28593DBC000EE522 /* SidebarController.swift in Sources */,
7AFD7AE02871823E00BCCD37 /* SidebarSection.swift in Sources */,
7AFD7AE4287182CD00BCCD37 /* SidebarFilterItem.swift in Sources */,
7AFD7AE82871B7DA00BCCD37 /* MainSplitController.swift in Sources */,
7AFD7AE22871826D00BCCD37 /* SidebarItem.swift in Sources */,
7AFD7AEB2872355000BCCD37 /* MainWindowController.swift in Sources */,
7AFD7AED2874E49600BCCD37 /* CheckController.swift in Sources */,
7A9FD4072857AF590057ECFA /* AppDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
7A0391D9285933EF000EE522 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 7A49F4D627D4064500AEAAE0 /* AutoCatCore */;
targetProxy = 7A0391D8285933EF000EE522 /* PBXContainerItemProxy */;
};
7A4951CB288D3BFA00C644B6 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 7A49F4D627D4064500AEAAE0 /* AutoCatCore */;
targetProxy = 7A4951CA288D3BFA00C644B6 /* PBXContainerItemProxy */;
};
7A49F4B727D4061B00AEAAE0 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 7A49F49E27D4061900AEAAE0 /* AutoCat2 */;
@ -1382,97 +938,9 @@
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
7A9FD40C2857AF5A0057ECFA /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
7A9FD40D2857AF5A0057ECFA /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
7A4951C1288D3A6300C644B6 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = AutoCat2SUI/AutoCat2SUI.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"AutoCat2SUI/Preview Content\"";
DEVELOPMENT_TEAM = 46DTTB8X4S;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = AutoCat2SUI/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = AutoCat2;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity";
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = pro.aliencat.AutoCat2SUI;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = auto;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
7A4951C2288D3A6300C644B6 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CODE_SIGN_ENTITLEMENTS = AutoCat2SUI/AutoCat2SUI.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_ASSET_PATHS = "\"AutoCat2SUI/Preview Content\"";
DEVELOPMENT_TEAM = 46DTTB8X4S;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = AutoCat2SUI/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = AutoCat2;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity";
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES;
"INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES;
"INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = pro.aliencat.AutoCat2SUI;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = auto;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
7A49F4C727D4061B00AEAAE0 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -1728,7 +1196,6 @@
7A49F4EF27D4064500AEAAE0 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
@ -1745,16 +1212,13 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = pro.aliencat.AutoCatCore;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos";
SUPPORTS_MACCATALYST = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2,6";
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
@ -1763,7 +1227,6 @@
7A49F4F027D4064500AEAAE0 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALLOW_TARGET_PLATFORM_SPECIALIZATION = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEFINES_MODULE = YES;
@ -1780,16 +1243,13 @@
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = pro.aliencat.AutoCatCore;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
SKIP_INSTALL = YES;
SUPPORTED_PLATFORMS = "watchsimulator watchos macosx iphonesimulator iphoneos driverkit appletvsimulator appletvos";
SUPPORTS_MACCATALYST = YES;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2,6";
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
@ -1831,86 +1291,9 @@
};
name = Release;
};
7A9FD4102857AF5A0057ECFA /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = AutoCat2Mac/AutoCat2Mac.entitlements;
CODE_SIGN_IDENTITY = "-";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 46DTTB8X4S;
ENABLE_HARDENED_RUNTIME = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = AutoCat2;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INFOPLIST_KEY_NSMainStoryboardFile = Main;
INFOPLIST_KEY_NSPrincipalClass = NSApplication;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = pro.aliencat.AutoCat2Mac;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
7A9FD4112857AF5A0057ECFA /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = AutoCat2Mac/AutoCat2Mac.entitlements;
CODE_SIGN_IDENTITY = "-";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEAD_CODE_STRIPPING = YES;
DEVELOPMENT_TEAM = 46DTTB8X4S;
ENABLE_HARDENED_RUNTIME = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_CFBundleDisplayName = AutoCat2;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
INFOPLIST_KEY_NSHumanReadableCopyright = "";
INFOPLIST_KEY_NSMainStoryboardFile = Main;
INFOPLIST_KEY_NSPrincipalClass = NSApplication;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = pro.aliencat.AutoCat2Mac;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = macosx;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
7A4951C0288D3A6300C644B6 /* Build configuration list for PBXNativeTarget "AutoCat2SUI" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7A4951C1288D3A6300C644B6 /* Debug */,
7A4951C2288D3A6300C644B6 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
7A49F49A27D4061900AEAAE0 /* Build configuration list for PBXProject "AutoCat2" */ = {
isa = XCConfigurationList;
buildConfigurations = (
@ -1965,15 +1348,6 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
7A9FD4122857AF5A0057ECFA /* Build configuration list for PBXNativeTarget "AutoCat2Mac" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7A9FD4102857AF5A0057ECFA /* Debug */,
7A9FD4112857AF5A0057ECFA /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
@ -2009,14 +1383,6 @@
minimumVersion = 5.0.0;
};
};
7A91E80F2986DE9C0008A982 /* XCRemoteSwiftPackageReference "realm-swift" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/realm/realm-swift.git";
requirement = {
branch = master;
kind = branch;
};
};
7AE32D6C27F06D2D004EF6E0 /* XCRemoteSwiftPackageReference "SwiftDate" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/malcommac/SwiftDate";
@ -2048,27 +1414,25 @@
package = 7A48B26527D9442A004D1A4B /* XCRemoteSwiftPackageReference "PKHUD" */;
productName = PKHUD;
};
7A91E8102986DE9C0008A982 /* Realm */ = {
isa = XCSwiftPackageProductDependency;
package = 7A91E80F2986DE9C0008A982 /* XCRemoteSwiftPackageReference "realm-swift" */;
productName = Realm;
};
7A91E8122986DE9C0008A982 /* RealmSwift */ = {
isa = XCSwiftPackageProductDependency;
package = 7A91E80F2986DE9C0008A982 /* XCRemoteSwiftPackageReference "realm-swift" */;
productName = RealmSwift;
};
7A9FD4192857AF8D0057ECFA /* DifferenceKit */ = {
isa = XCSwiftPackageProductDependency;
package = 7A1D80DE27F1F275007BD64F /* XCRemoteSwiftPackageReference "DifferenceKit" */;
productName = DifferenceKit;
};
7AE32D6D27F06D2D004EF6E0 /* SwiftDate */ = {
isa = XCSwiftPackageProductDependency;
package = 7AE32D6C27F06D2D004EF6E0 /* XCRemoteSwiftPackageReference "SwiftDate" */;
productName = SwiftDate;
};
/* End XCSwiftPackageProductDependency section */
/* Begin XCVersionGroup section */
7A49F51327D40C6100AEAAE0 /* AutoCat2.xcdatamodeld */ = {
isa = XCVersionGroup;
children = (
7A49F51427D40C6100AEAAE0 /* Shared.xcdatamodel */,
);
currentVersion = 7A49F51427D40C6100AEAAE0 /* Shared.xcdatamodel */;
path = AutoCat2.xcdatamodeld;
sourceTree = "<group>";
versionGroupType = wrapper.xcdatamodel;
};
/* End XCVersionGroup section */
};
rootObject = 7A49F49727D4061900AEAAE0 /* Project object */;
}

View File

@ -18,24 +18,6 @@
"version" : "5.4.0"
}
},
{
"identity" : "realm-core",
"kind" : "remoteSourceControl",
"location" : "https://github.com/realm/realm-core.git",
"state" : {
"revision" : "b77443ca7fa25407869ca537bf3ae912b1427bff",
"version" : "12.13.0"
}
},
{
"identity" : "realm-swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/realm/realm-swift.git",
"state" : {
"branch" : "master",
"revision" : "f5aaf456ea725ac2f352b0b3decc78a7094adbd8"
}
},
{
"identity" : "swiftdate",
"kind" : "remoteSourceControl",

View File

@ -10,16 +10,6 @@
<integer>0</integer>
</dict>
<key>AutoCat2.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
</dict>
<key>AutoCat2Mac.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>3</integer>
</dict>
<key>AutoCat2SUI.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
@ -41,114 +31,46 @@
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>8</integer>
<integer>3</integer>
</dict>
<key>DifferenceKit (Playground) 2.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>9</integer>
</dict>
<key>DifferenceKit (Playground) 3.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>8</integer>
</dict>
<key>DifferenceKit (Playground) 4.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>9</integer>
</dict>
<key>DifferenceKit (Playground) 5.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>10</integer>
<integer>4</integer>
</dict>
<key>DifferenceKit (Playground).xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>7</integer>
</dict>
<key>GettingStarted (Playground) 1.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>10</integer>
</dict>
<key>GettingStarted (Playground) 2.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>11</integer>
</dict>
<key>GettingStarted (Playground).xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>3</integer>
<integer>2</integer>
</dict>
<key>SwiftDate (Playground) 1.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>5</integer>
<integer>6</integer>
</dict>
<key>SwiftDate (Playground) 2.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>6</integer>
</dict>
<key>SwiftDate (Playground) 3.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>11</integer>
</dict>
<key>SwiftDate (Playground) 4.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>12</integer>
</dict>
<key>SwiftDate (Playground) 5.xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>13</integer>
<integer>7</integer>
</dict>
<key>SwiftDate (Playground).xcscheme</key>
<dict>
<key>isShown</key>
<false/>
<key>orderHint</key>
<integer>4</integer>
<integer>5</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>7A4951B3288D3A6100C644B6</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>7A49F4D627D4064500AEAAE0</key>
<dict>
<key>primary</key>

View File

@ -86,8 +86,12 @@ class VehicleCell: UITableViewCell {
extension VehicleCell: ConfigurableCell {
func configure(with vehicle: Vehicle) {
plateView.number = PlateNumber(vehicle.number)
func configure(with vehicle: CDVehicle) {
guard let number = vehicle.number else {
return
}
plateView.number = PlateNumber(number)
nameLabel.text = vehicle.brand?.name?.original ?? "<Unknown>"
if vehicle.unrecognized {

View File

@ -76,7 +76,7 @@ class AuthController: UIViewController {
do {
HUD.show(.progress)
MainSettings.shared.user = try await Api.shared.login(email: email, password: password)
Settings.shared.user = try await Api.shared.login(email: email, password: password)
view.window?.rootViewController = MainTabController()
HUD.hide()
} catch {
@ -92,7 +92,7 @@ class AuthController: UIViewController {
do {
HUD.show(.progress)
MainSettings.shared.user = try await Api.shared.signup(email: email, password: password)
Settings.shared.user = try await Api.shared.signup(email: email, password: password)
view.window?.rootViewController = MainTabController()
HUD.hide()
} catch {

View File

@ -18,7 +18,7 @@ class HistoryController: UIViewController, UITableViewDelegate {
return table
}()
private var dataSource: CoreDataSource<Vehicle, VehicleCell>?
private var dataSource: CoreDataSource<CDVehicle, VehicleCell>?
override func viewDidLoad() {
super.viewDidLoad()

View File

@ -42,7 +42,7 @@ class MainTabController: UITabBarController, UITabBarControllerDelegate {
func showCheckPuller() {
var attributes = EKAttributes.bottomToast
attributes.displayDuration = .infinity
attributes.entryBackground = .color(color: .init(.secondarySystemBackground)) //.visualEffect(style: .extra) //.color(color: .standardBackground)
attributes.entryBackground = .visualEffect(style: .extra) //.color(color: .standardBackground)
attributes.screenBackground = .color(color: EKColor(UIColor(white: 0, alpha: 0.7)))
attributes.roundCorners = .top(radius: 24)
attributes.screenInteraction = .dismiss

View File

@ -102,9 +102,13 @@ struct ReportItem {
class ReportController: UIViewController, UICollectionViewDataSource {
private let reportTextItemId = String(describing: ReportTextItemCell.self)
private lazy var collectionView: UICollectionView = {
let collection = UICollectionView(frame: .zero, collectionViewLayout: createLayout())
collection.translatesAutoresizingMaskIntoConstraints = false
collection.register(ReportTextItemCell.self,
forCellWithReuseIdentifier: reportTextItemId)
collection.dataSource = self
return collection
}()

View File

@ -21,7 +21,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
self.window = UIWindow(windowScene: scene)
if MainSettings.shared.user.token.isEmpty {
if Settings.shared.user.token.isEmpty {
self.window?.rootViewController = AuthController()
} else {
self.window?.rootViewController = MainTabController()

View File

@ -1,21 +0,0 @@
//
// AppDelegate.swift
// AutoCat2Mac
//
// Created by Selim Mustafaev on 13.06.2022.
//
import Cocoa
@main
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
}
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
true
}
}

View File

@ -1,11 +0,0 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1,58 +0,0 @@
{
"images" : [
{
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1,6 +0,0 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
</dict>
</plist>

View File

@ -1,995 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="21223" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="ANK-bM-ijm">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="21223"/>
<capability name="NSView safe area layout guides" minToolsVersion="12.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Application-->
<scene sceneID="JPo-4y-FX3">
<objects>
<application id="hnw-xV-0zn" sceneMemberID="viewController">
<menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
<items>
<menuItem title="AutoCat2Mac" id="1Xt-HY-uBw">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="AutoCat2Mac" systemMenu="apple" id="uQy-DD-JDr">
<items>
<menuItem title="About AutoCat2Mac" id="5kV-Vb-QxS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
<menuItem title="Services" id="NMo-om-nkz">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
<menuItem title="Hide AutoCat2Mac" keyEquivalent="h" id="Olw-nP-bQN">
<connections>
<action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
</connections>
</menuItem>
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
</connections>
</menuItem>
<menuItem title="Show All" id="Kd2-mp-pUS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
<menuItem title="Quit AutoCat2Mac" keyEquivalent="q" id="4sb-4s-VLi">
<connections>
<action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="File" id="dMs-cI-mzQ">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="File" id="bib-Uj-vzu">
<items>
<menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
<connections>
<action selector="newDocument:" target="Ady-hI-5gd" id="4Si-XN-c54"/>
</connections>
</menuItem>
<menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
<connections>
<action selector="openDocument:" target="Ady-hI-5gd" id="bVn-NM-KNZ"/>
</connections>
</menuItem>
<menuItem title="Open Recent" id="tXI-mr-wws">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
<items>
<menuItem title="Clear Menu" id="vNY-rz-j42">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="clearRecentDocuments:" target="Ady-hI-5gd" id="Daa-9d-B3U"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
<menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
<connections>
<action selector="performClose:" target="Ady-hI-5gd" id="HmO-Ls-i7Q"/>
</connections>
</menuItem>
<menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
<connections>
<action selector="saveDocument:" target="Ady-hI-5gd" id="teZ-XB-qJY"/>
</connections>
</menuItem>
<menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
<connections>
<action selector="saveDocumentAs:" target="Ady-hI-5gd" id="mDf-zr-I0C"/>
</connections>
</menuItem>
<menuItem title="Revert to Saved" keyEquivalent="r" id="KaW-ft-85H">
<connections>
<action selector="revertDocumentToSaved:" target="Ady-hI-5gd" id="iJ3-Pv-kwq"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
<menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="runPageLayout:" target="Ady-hI-5gd" id="Din-rz-gC5"/>
</connections>
</menuItem>
<menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
<connections>
<action selector="print:" target="Ady-hI-5gd" id="qaZ-4w-aoO"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Edit" id="5QF-Oa-p0T">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
<items>
<menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
<connections>
<action selector="undo:" target="Ady-hI-5gd" id="M6e-cu-g7V"/>
</connections>
</menuItem>
<menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
<connections>
<action selector="redo:" target="Ady-hI-5gd" id="oIA-Rs-6OD"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
<menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
<connections>
<action selector="cut:" target="Ady-hI-5gd" id="YJe-68-I9s"/>
</connections>
</menuItem>
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
<connections>
<action selector="copy:" target="Ady-hI-5gd" id="G1f-GL-Joy"/>
</connections>
</menuItem>
<menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
<connections>
<action selector="paste:" target="Ady-hI-5gd" id="UvS-8e-Qdg"/>
</connections>
</menuItem>
<menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteAsPlainText:" target="Ady-hI-5gd" id="cEh-KX-wJQ"/>
</connections>
</menuItem>
<menuItem title="Delete" id="pa3-QI-u2k">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="delete:" target="Ady-hI-5gd" id="0Mk-Ml-PaM"/>
</connections>
</menuItem>
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
<connections>
<action selector="selectAll:" target="Ady-hI-5gd" id="VNm-Mi-diN"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
<menuItem title="Find" id="4EN-yA-p0u">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Find" id="1b7-l0-nxx">
<items>
<menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="cD7-Qs-BN4"/>
</connections>
</menuItem>
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="WD3-Gg-5AJ"/>
</connections>
</menuItem>
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="NDo-RZ-v9R"/>
</connections>
</menuItem>
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="HOh-sY-3ay"/>
</connections>
</menuItem>
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
<connections>
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="U76-nv-p5D"/>
</connections>
</menuItem>
<menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
<connections>
<action selector="centerSelectionInVisibleArea:" target="Ady-hI-5gd" id="IOG-6D-g5B"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
<items>
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
<connections>
<action selector="showGuessPanel:" target="Ady-hI-5gd" id="vFj-Ks-hy3"/>
</connections>
</menuItem>
<menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
<connections>
<action selector="checkSpelling:" target="Ady-hI-5gd" id="fz7-VC-reM"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
<menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleContinuousSpellChecking:" target="Ady-hI-5gd" id="7w6-Qz-0kB"/>
</connections>
</menuItem>
<menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleGrammarChecking:" target="Ady-hI-5gd" id="muD-Qn-j4w"/>
</connections>
</menuItem>
<menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticSpellingCorrection:" target="Ady-hI-5gd" id="2lM-Qi-WAP"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Substitutions" id="9ic-FL-obx">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
<items>
<menuItem title="Show Substitutions" id="z6F-FW-3nz">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontSubstitutionsPanel:" target="Ady-hI-5gd" id="oku-mr-iSq"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
<menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleSmartInsertDelete:" target="Ady-hI-5gd" id="3IJ-Se-DZD"/>
</connections>
</menuItem>
<menuItem title="Smart Quotes" id="hQb-2v-fYv">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticQuoteSubstitution:" target="Ady-hI-5gd" id="ptq-xd-QOA"/>
</connections>
</menuItem>
<menuItem title="Smart Dashes" id="rgM-f4-ycn">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDashSubstitution:" target="Ady-hI-5gd" id="oCt-pO-9gS"/>
</connections>
</menuItem>
<menuItem title="Smart Links" id="cwL-P1-jid">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticLinkDetection:" target="Ady-hI-5gd" id="Gip-E3-Fov"/>
</connections>
</menuItem>
<menuItem title="Data Detectors" id="tRr-pd-1PS">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDataDetection:" target="Ady-hI-5gd" id="R1I-Nq-Kbl"/>
</connections>
</menuItem>
<menuItem title="Text Replacement" id="HFQ-gK-NFA">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticTextReplacement:" target="Ady-hI-5gd" id="DvP-Fe-Py6"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Transformations" id="2oI-Rn-ZJC">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Transformations" id="c8a-y6-VQd">
<items>
<menuItem title="Make Upper Case" id="vmV-6d-7jI">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="uppercaseWord:" target="Ady-hI-5gd" id="sPh-Tk-edu"/>
</connections>
</menuItem>
<menuItem title="Make Lower Case" id="d9M-CD-aMd">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="lowercaseWord:" target="Ady-hI-5gd" id="iUZ-b5-hil"/>
</connections>
</menuItem>
<menuItem title="Capitalize" id="UEZ-Bs-lqG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="capitalizeWord:" target="Ady-hI-5gd" id="26H-TL-nsh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Speech" id="xrE-MZ-jX0">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Speech" id="3rS-ZA-NoH">
<items>
<menuItem title="Start Speaking" id="Ynk-f8-cLZ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="startSpeaking:" target="Ady-hI-5gd" id="654-Ng-kyl"/>
</connections>
</menuItem>
<menuItem title="Stop Speaking" id="Oyz-dy-DGm">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="stopSpeaking:" target="Ady-hI-5gd" id="dX8-6p-jy9"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Format" id="jxT-CU-nIS">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Format" id="GEO-Iw-cKr">
<items>
<menuItem title="Font" id="Gi5-1S-RQB">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
<items>
<menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq">
<connections>
<action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/>
</connections>
</menuItem>
<menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27">
<connections>
<action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/>
</connections>
</menuItem>
<menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq">
<connections>
<action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/>
</connections>
</menuItem>
<menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
<connections>
<action selector="underline:" target="Ady-hI-5gd" id="FYS-2b-JAY"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL">
<connections>
<action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/>
</connections>
</menuItem>
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST">
<connections>
<action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
<menuItem title="Kern" id="jBQ-r6-VK2">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Kern" id="tlD-Oa-oAM">
<items>
<menuItem title="Use Default" id="GUa-eO-cwY">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useStandardKerning:" target="Ady-hI-5gd" id="6dk-9l-Ckg"/>
</connections>
</menuItem>
<menuItem title="Use None" id="cDB-IK-hbR">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="turnOffKerning:" target="Ady-hI-5gd" id="U8a-gz-Maa"/>
</connections>
</menuItem>
<menuItem title="Tighten" id="46P-cB-AYj">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="tightenKerning:" target="Ady-hI-5gd" id="hr7-Nz-8ro"/>
</connections>
</menuItem>
<menuItem title="Loosen" id="ogc-rX-tC1">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="loosenKerning:" target="Ady-hI-5gd" id="8i4-f9-FKE"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Ligatures" id="o6e-r0-MWq">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
<items>
<menuItem title="Use Default" id="agt-UL-0e3">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useStandardLigatures:" target="Ady-hI-5gd" id="7uR-wd-Dx6"/>
</connections>
</menuItem>
<menuItem title="Use None" id="J7y-lM-qPV">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="turnOffLigatures:" target="Ady-hI-5gd" id="iX2-gA-Ilz"/>
</connections>
</menuItem>
<menuItem title="Use All" id="xQD-1f-W4t">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="useAllLigatures:" target="Ady-hI-5gd" id="KcB-kA-TuK"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Baseline" id="OaQ-X3-Vso">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Baseline" id="ijk-EB-dga">
<items>
<menuItem title="Use Default" id="3Om-Ey-2VK">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="unscript:" target="Ady-hI-5gd" id="0vZ-95-Ywn"/>
</connections>
</menuItem>
<menuItem title="Superscript" id="Rqc-34-cIF">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="superscript:" target="Ady-hI-5gd" id="3qV-fo-wpU"/>
</connections>
</menuItem>
<menuItem title="Subscript" id="I0S-gh-46l">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="subscript:" target="Ady-hI-5gd" id="Q6W-4W-IGz"/>
</connections>
</menuItem>
<menuItem title="Raise" id="2h7-ER-AoG">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="raiseBaseline:" target="Ady-hI-5gd" id="4sk-31-7Q9"/>
</connections>
</menuItem>
<menuItem title="Lower" id="1tx-W0-xDw">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="lowerBaseline:" target="Ady-hI-5gd" id="OF1-bc-KW4"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
<menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
<connections>
<action selector="orderFrontColorPanel:" target="Ady-hI-5gd" id="mSX-Xz-DV3"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
<menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="copyFont:" target="Ady-hI-5gd" id="GJO-xA-L4q"/>
</connections>
</menuItem>
<menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="pasteFont:" target="Ady-hI-5gd" id="JfD-CL-leO"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Text" id="Fal-I4-PZk">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Text" id="d9c-me-L2H">
<items>
<menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
<connections>
<action selector="alignLeft:" target="Ady-hI-5gd" id="zUv-R1-uAa"/>
</connections>
</menuItem>
<menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
<connections>
<action selector="alignCenter:" target="Ady-hI-5gd" id="spX-mk-kcS"/>
</connections>
</menuItem>
<menuItem title="Justify" id="J5U-5w-g23">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="alignJustified:" target="Ady-hI-5gd" id="ljL-7U-jND"/>
</connections>
</menuItem>
<menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
<connections>
<action selector="alignRight:" target="Ady-hI-5gd" id="r48-bG-YeY"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
<menuItem title="Writing Direction" id="H1b-Si-o9J">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
<items>
<menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem id="YGs-j5-SAR">
<string key="title"> Default</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeBaseWritingDirectionNatural:" target="Ady-hI-5gd" id="qtV-5e-UBP"/>
</connections>
</menuItem>
<menuItem id="Lbh-J2-qVU">
<string key="title"> Left to Right</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeBaseWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="S0X-9S-QSf"/>
</connections>
</menuItem>
<menuItem id="jFq-tB-4Kx">
<string key="title"> Right to Left</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeBaseWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="5fk-qB-AqJ"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
<menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
<modifierMask key="keyEquivalentModifierMask"/>
</menuItem>
<menuItem id="Nop-cj-93Q">
<string key="title"> Default</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeTextWritingDirectionNatural:" target="Ady-hI-5gd" id="lPI-Se-ZHp"/>
</connections>
</menuItem>
<menuItem id="BgM-ve-c93">
<string key="title"> Left to Right</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeTextWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="caW-Bv-w94"/>
</connections>
</menuItem>
<menuItem id="RB4-Sm-HuC">
<string key="title"> Right to Left</string>
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="makeTextWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="EXD-6r-ZUu"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
<menuItem title="Show Ruler" id="vLm-3I-IUL">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleRuler:" target="Ady-hI-5gd" id="FOx-HJ-KwY"/>
</connections>
</menuItem>
<menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="copyRuler:" target="Ady-hI-5gd" id="71i-fW-3W2"/>
</connections>
</menuItem>
<menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="pasteRuler:" target="Ady-hI-5gd" id="cSh-wd-qM2"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="View" id="H8h-7b-M4v">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="View" id="HyV-fh-RgO">
<items>
<menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="toggleToolbarShown:" target="Ady-hI-5gd" id="BXY-wc-z0C"/>
</connections>
</menuItem>
<menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="runToolbarCustomizationPalette:" target="Ady-hI-5gd" id="pQI-g3-MTW"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="hB3-LF-h0Y"/>
<menuItem title="Show Sidebar" keyEquivalent="s" id="kIP-vf-haE">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="toggleSidebar:" target="Ady-hI-5gd" id="iwa-gc-5KM"/>
</connections>
</menuItem>
<menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
<connections>
<action selector="toggleFullScreen:" target="Ady-hI-5gd" id="dU3-MA-1Rq"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Window" id="aUF-d1-5bR">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
<items>
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
<connections>
<action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/>
</connections>
</menuItem>
<menuItem title="Zoom" id="R4o-n2-Eq4">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Help" id="wpr-3q-Mcd">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
<items>
<menuItem title="AutoCat2Mac Help" keyEquivalent="?" id="FKE-Sm-Kum">
<connections>
<action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
</connections>
</application>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="AutoCat2Mac" customModuleProvider="target"/>
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="76" y="771"/>
</scene>
<!--Window Controller-->
<scene sceneID="WgK-OL-38a">
<objects>
<windowController id="ANK-bM-ijm" customClass="MainWindowController" customModule="AutoCat2Mac" customModuleProvider="target" sceneMemberID="viewController">
<window key="window" title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" frameAutosaveName="MainWindow" animationBehavior="default" id="XfF-RB-9vb">
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" fullSizeContentView="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="425" y="462" width="480" height="270"/>
<rect key="screenRect" x="0.0" y="0.0" width="2560" height="1415"/>
<view key="contentView" id="yWt-lU-Yb9">
<rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
<autoresizingMask key="autoresizingMask"/>
</view>
<toolbar key="toolbar" implicitIdentifier="09D11707-F4A3-4FD5-970E-AC5832E91C2B" autosavesConfiguration="NO" displayMode="iconOnly" sizeMode="regular" id="ERp-ah-8R1">
<allowedToolbarItems>
<toolbarItem implicitItemIdentifier="NSToolbarShowColorsItem" id="Kow-NZ-nnQ"/>
<toolbarItem implicitItemIdentifier="NSToolbarShowFontsItem" id="xeI-Ij-CqS"/>
<toolbarItem implicitItemIdentifier="NSToolbarPrintItem" id="MRQ-nf-EwM"/>
<toolbarItem implicitItemIdentifier="NSToolbarSpaceItem" id="aUV-DI-a5F"/>
<toolbarItem implicitItemIdentifier="NSToolbarFlexibleSpaceItem" id="N2K-bn-QdP"/>
<toolbarItem implicitItemIdentifier="4217B4EF-FB2D-4346-BB51-ED1F699496FE" label="New check" paletteLabel="Check new number" tag="-1" image="plus" catalog="system" sizingBehavior="auto" id="HR9-WR-cxc">
<connections>
<action selector="checkNewNumber:" target="ANK-bM-ijm" id="AhL-Do-AYS"/>
</connections>
</toolbarItem>
</allowedToolbarItems>
<defaultToolbarItems>
<toolbarItem reference="N2K-bn-QdP"/>
<toolbarItem reference="HR9-WR-cxc"/>
<toolbarItem reference="Kow-NZ-nnQ"/>
<toolbarItem reference="xeI-Ij-CqS"/>
<toolbarItem reference="N2K-bn-QdP"/>
<toolbarItem reference="MRQ-nf-EwM"/>
</defaultToolbarItems>
</toolbar>
<connections>
<outlet property="delegate" destination="ANK-bM-ijm" id="ymg-rW-vPr"/>
</connections>
</window>
<connections>
<segue destination="kVc-gr-gzC" kind="relationship" relationship="window.shadowedContentViewController" id="sjI-uM-Wof"/>
</connections>
</windowController>
<customObject id="Rze-wc-UpU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="76" y="1001"/>
</scene>
<!--Check Controller-->
<scene sceneID="HHJ-M8-hIB">
<objects>
<viewController storyboardIdentifier="CheckController" id="XFl-Wx-eYr" customClass="CheckController" customModule="AutoCat2Mac" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" id="qCL-3f-aoO">
<rect key="frame" x="0.0" y="0.0" width="328" height="229"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="93a-kE-ZA0">
<rect key="frame" x="9" y="9" width="154" height="32"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="140" id="aw4-k5-7pa"/>
</constraints>
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="KXn-t5-z1m">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
<string key="keyEquivalent" base64-UTF8="YES">
Gw
</string>
</buttonCell>
<connections>
<action selector="onCancel:" target="XFl-Wx-eYr" id="sQd-Ye-TxD"/>
</connections>
</button>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MTd-tE-Cey">
<rect key="frame" x="18" y="183" width="292" height="26"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="center" title="Check new plate number" id="gQS-6S-oEK">
<font key="font" textStyle="title1" name=".SFNS-Regular"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="PMS-6j-xbV">
<rect key="frame" x="64" y="116" width="200" height="43"/>
<constraints>
<constraint firstAttribute="width" constant="200" id="fdh-Ch-kwi"/>
</constraints>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" drawsBackground="YES" id="8Os-qZ-f33">
<font key="font" metaFont="system" size="32"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<progressIndicator hidden="YES" maxValue="100" indeterminate="YES" controlSize="small" style="spinning" translatesAutoresizingMaskIntoConstraints="NO" id="cWb-uY-s69">
<rect key="frame" x="148" y="60" width="32" height="32"/>
<constraints>
<constraint firstAttribute="width" constant="32" id="GFT-bK-Ak6"/>
<constraint firstAttribute="height" constant="32" id="Gso-V8-5KF"/>
</constraints>
</progressIndicator>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="6Bn-HZ-aid">
<rect key="frame" x="165" y="9" width="154" height="32"/>
<constraints>
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="140" id="Sqt-aL-ILa"/>
</constraints>
<buttonCell key="cell" type="push" title="Check" bezelStyle="rounded" alignment="center" borderStyle="border" inset="2" id="nTE-1c-gSN">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="onCheck:" target="XFl-Wx-eYr" id="LoP-Ss-gjW"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="MTd-tE-Cey" firstAttribute="top" secondItem="qCL-3f-aoO" secondAttribute="top" constant="20" symbolic="YES" id="1hz-As-vMj"/>
<constraint firstAttribute="trailing" secondItem="6Bn-HZ-aid" secondAttribute="trailing" constant="16" id="7gA-CT-ZsC"/>
<constraint firstItem="93a-kE-ZA0" firstAttribute="leading" secondItem="qCL-3f-aoO" secondAttribute="leading" constant="16" id="KwZ-5h-7cw"/>
<constraint firstItem="6Bn-HZ-aid" firstAttribute="top" secondItem="cWb-uY-s69" secondAttribute="bottom" constant="24" id="MMM-F5-rgD"/>
<constraint firstAttribute="bottom" secondItem="6Bn-HZ-aid" secondAttribute="bottom" constant="16" id="TeE-Dj-sRe"/>
<constraint firstItem="PMS-6j-xbV" firstAttribute="top" secondItem="MTd-tE-Cey" secondAttribute="bottom" constant="24" id="b81-2u-K2K"/>
<constraint firstItem="PMS-6j-xbV" firstAttribute="centerX" secondItem="qCL-3f-aoO" secondAttribute="centerX" id="dNS-Q5-yFq"/>
<constraint firstItem="cWb-uY-s69" firstAttribute="top" secondItem="PMS-6j-xbV" secondAttribute="bottom" constant="24" id="djF-Ft-Efx"/>
<constraint firstItem="cWb-uY-s69" firstAttribute="centerX" secondItem="qCL-3f-aoO" secondAttribute="centerX" id="e9q-h1-gr1"/>
<constraint firstAttribute="bottom" secondItem="93a-kE-ZA0" secondAttribute="bottom" constant="16" id="g9K-lY-ds3"/>
<constraint firstItem="6Bn-HZ-aid" firstAttribute="leading" secondItem="93a-kE-ZA0" secondAttribute="trailing" constant="16" id="iiJ-9b-2Jx"/>
<constraint firstItem="MTd-tE-Cey" firstAttribute="leading" secondItem="qCL-3f-aoO" secondAttribute="leading" constant="20" symbolic="YES" id="iwp-bD-Tyz"/>
<constraint firstItem="93a-kE-ZA0" firstAttribute="top" secondItem="cWb-uY-s69" secondAttribute="bottom" constant="24" id="lsA-G2-mW5"/>
<constraint firstItem="93a-kE-ZA0" firstAttribute="width" secondItem="6Bn-HZ-aid" secondAttribute="width" id="rde-Pn-h9P"/>
<constraint firstAttribute="trailing" secondItem="MTd-tE-Cey" secondAttribute="trailing" constant="20" symbolic="YES" id="uEZ-qE-45L"/>
</constraints>
</view>
<connections>
<outlet property="cancelButton" destination="93a-kE-ZA0" id="5bF-Bh-NP8"/>
<outlet property="checkButton" destination="6Bn-HZ-aid" id="peV-8h-Mzp"/>
<outlet property="progress" destination="cWb-uY-s69" id="d4r-Za-9Tc"/>
<outlet property="textField" destination="PMS-6j-xbV" id="hTZ-nV-TIE"/>
</connections>
</viewController>
<customObject id="8Mg-sX-vG1" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="746" y="1503"/>
</scene>
<!--Main Split Controller-->
<scene sceneID="p66-TL-mk9">
<objects>
<splitViewController id="kVc-gr-gzC" customClass="MainSplitController" customModule="AutoCat2Mac" customModuleProvider="target" sceneMemberID="viewController">
<splitViewItems>
<splitViewItem canCollapse="YES" holdingPriority="260" behavior="sidebar" id="rnO-5p-cdV"/>
<splitViewItem id="3Yu-p4-UFu"/>
</splitViewItems>
<splitView key="splitView" identifier="MainSplitViewID" autosaveName="MainSplitView" dividerStyle="thin" vertical="YES" id="Dya-6b-MK1">
<rect key="frame" x="0.0" y="0.0" width="450" height="300"/>
<autoresizingMask key="autoresizingMask"/>
</splitView>
<connections>
<segue destination="8Zn-vq-a7w" kind="relationship" relationship="splitItems" id="V1u-gZ-LZ5"/>
<segue destination="Nua-Uc-G0Y" kind="relationship" relationship="splitItems" id="3Xw-4d-AZI"/>
</connections>
</splitViewController>
<customObject id="vab-lQ-QBd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="768" y="1005"/>
</scene>
<!--Sidebar Controller-->
<scene sceneID="yd4-3O-Y98">
<objects>
<viewController id="8Zn-vq-a7w" customClass="SidebarController" customModule="AutoCat2Mac" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" misplaced="YES" id="V8j-Wf-y5G">
<rect key="frame" x="0.0" y="0.0" width="149" height="541"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<scrollView borderType="none" autohidesScrollers="YES" horizontalLineScroll="27" horizontalPageScroll="10" verticalLineScroll="27" verticalPageScroll="10" usesPredominantAxisScrolling="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zbf-Sa-jlX">
<rect key="frame" x="0.0" y="0.0" width="149" height="1009"/>
<clipView key="contentView" drawsBackground="NO" id="SqE-1u-BH2">
<rect key="frame" x="0.0" y="0.0" width="149" height="1009"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<outlineView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" selectionHighlightStyle="sourceList" multipleSelection="NO" autosaveName="Sidebar" rowHeight="27" rowSizeStyle="automatic" viewBased="YES" floatsGroupRows="NO" indentationPerLevel="13" autosaveExpandedItems="YES" outlineTableColumn="RdD-fI-vom" id="d2l-fY-90X">
<rect key="frame" x="0.0" y="0.0" width="149" height="1009"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<size key="intercellSpacing" width="3" height="0.0"/>
<color key="backgroundColor" name="_sourceListBackgroundColor" catalog="System" colorSpace="catalog"/>
<color key="gridColor" name="gridColor" catalog="System" colorSpace="catalog"/>
<tableColumns>
<tableColumn identifier="AutomaticTableColumnIdentifier.0" width="117" minWidth="16" maxWidth="1000" id="RdD-fI-vom">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border">
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="headerColor" catalog="System" colorSpace="catalog"/>
</tableHeaderCell>
<textFieldCell key="dataCell" lineBreakMode="truncatingTail" selectable="YES" editable="YES" title="Text Cell" id="gLE-0y-PGi">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
<tableColumnResizingMask key="resizingMask" resizeWithTable="YES" userResizable="YES"/>
<prototypeCellViews>
<tableCellView identifier="SidebarHeaderCell" id="k5v-i3-GBI">
<rect key="frame" x="11" y="0.0" width="126" height="17"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="u6m-3a-VB5">
<rect key="frame" x="0.0" y="1" width="126" height="14"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Header Cell" id="UmG-sU-6nm">
<font key="font" metaFont="systemMedium" size="11"/>
<color key="textColor" name="headerColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="u6m-3a-VB5" firstAttribute="top" secondItem="k5v-i3-GBI" secondAttribute="top" constant="2" id="4Sz-3Z-RC7"/>
<constraint firstAttribute="trailing" secondItem="u6m-3a-VB5" secondAttribute="trailing" constant="2" id="tu5-Mn-sgd"/>
<constraint firstItem="u6m-3a-VB5" firstAttribute="leading" secondItem="k5v-i3-GBI" secondAttribute="leading" constant="2" id="xdl-UX-l6G"/>
<constraint firstAttribute="bottom" secondItem="u6m-3a-VB5" secondAttribute="bottom" constant="1" id="y16-PJ-JTS"/>
</constraints>
<connections>
<outlet property="textField" destination="u6m-3a-VB5" id="sZS-wk-2Oc"/>
</connections>
</tableCellView>
<tableCellView identifier="SidebarItemCell" id="eUb-OR-IxL">
<rect key="frame" x="11" y="17" width="126" height="27"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<imageView translatesAutoresizingMaskIntoConstraints="NO" id="qD0-Bm-WN7">
<rect key="frame" x="3" y="5" width="17" height="17"/>
<constraints>
<constraint firstAttribute="height" constant="11" id="PLc-Ox-Ckh"/>
<constraint firstAttribute="width" constant="17" id="XfT-EV-Xms"/>
</constraints>
<imageCell key="cell" refusesFirstResponder="YES" imageScaling="proportionallyDown" image="NSActionTemplate" id="ewq-0M-OAX"/>
</imageView>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="A96-IM-JbT">
<rect key="frame" x="25" y="6" width="96" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="oKl-mJ-ZEi">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="A96-IM-JbT" secondAttribute="trailing" constant="7" id="F0K-EC-Gqs"/>
<constraint firstItem="A96-IM-JbT" firstAttribute="leading" secondItem="qD0-Bm-WN7" secondAttribute="trailing" constant="7" id="GCe-Fp-zhD"/>
<constraint firstItem="qD0-Bm-WN7" firstAttribute="top" secondItem="eUb-OR-IxL" secondAttribute="top" constant="8" id="OAV-Oj-e5b"/>
<constraint firstAttribute="bottom" secondItem="qD0-Bm-WN7" secondAttribute="bottom" constant="8" id="d8y-Ph-SrP"/>
<constraint firstItem="A96-IM-JbT" firstAttribute="leading" secondItem="qD0-Bm-WN7" secondAttribute="trailing" constant="7" id="evl-EN-QSH"/>
<constraint firstItem="A96-IM-JbT" firstAttribute="centerY" secondItem="eUb-OR-IxL" secondAttribute="centerY" id="gdH-E5-hzg"/>
<constraint firstItem="qD0-Bm-WN7" firstAttribute="leading" secondItem="eUb-OR-IxL" secondAttribute="leading" constant="3" id="jDC-Ov-2MF"/>
</constraints>
<connections>
<outlet property="imageView" destination="qD0-Bm-WN7" id="Ixk-H5-gcS"/>
<outlet property="textField" destination="A96-IM-JbT" id="bId-II-VE0"/>
</connections>
</tableCellView>
</prototypeCellViews>
</tableColumn>
</tableColumns>
<connections>
<outlet property="dataSource" destination="8Zn-vq-a7w" id="Yvp-lX-AfJ"/>
<outlet property="delegate" destination="8Zn-vq-a7w" id="qhF-dH-xNY"/>
</connections>
</outlineView>
</subviews>
<nil key="backgroundColor"/>
</clipView>
<scroller key="horizontalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="YES" id="rhX-ct-wPT">
<rect key="frame" x="1" y="119" width="238" height="15"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
<scroller key="verticalScroller" hidden="YES" wantsLayer="YES" verticalHuggingPriority="750" horizontal="NO" id="njn-R9-YRd">
<rect key="frame" x="224" y="17" width="15" height="102"/>
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
</subviews>
<constraints>
<constraint firstItem="zbf-Sa-jlX" firstAttribute="top" secondItem="V8j-Wf-y5G" secondAttribute="top" id="0WG-xL-Z0O"/>
<constraint firstItem="zbf-Sa-jlX" firstAttribute="trailing" secondItem="mm0-rn-2nX" secondAttribute="trailing" id="M9M-tz-rnP"/>
<constraint firstItem="zbf-Sa-jlX" firstAttribute="bottom" secondItem="mm0-rn-2nX" secondAttribute="bottom" id="X2g-Pa-QEZ"/>
<constraint firstItem="zbf-Sa-jlX" firstAttribute="leading" secondItem="V8j-Wf-y5G" secondAttribute="leading" id="syy-IU-YFy"/>
</constraints>
<viewLayoutGuide key="safeArea" id="mm0-rn-2nX"/>
<viewLayoutGuide key="layoutMargins" id="OCA-xY-Jg3"/>
</view>
<connections>
<outlet property="outlineView" destination="d2l-fY-90X" id="sIb-7A-Hxb"/>
</connections>
</viewController>
<customObject id="WOV-sh-nF6" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1287.5" y="819"/>
</scene>
<!--View Controller-->
<scene sceneID="vRJ-Ra-9fw">
<objects>
<viewController id="Nua-Uc-G0Y" sceneMemberID="viewController">
<view key="view" id="GnC-hv-Zpf">
<rect key="frame" x="0.0" y="0.0" width="302" height="300"/>
<autoresizingMask key="autoresizingMask"/>
<viewLayoutGuide key="safeArea" id="6Q2-w7-LA0"/>
<viewLayoutGuide key="layoutMargins" id="DGU-pT-iQU"/>
</view>
</viewController>
<customObject id="fCn-zz-QP5" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1364" y="1289"/>
</scene>
</scenes>
<resources>
<image name="NSActionTemplate" width="15" height="15"/>
<image name="plus" catalog="system" width="14" height="13"/>
</resources>
</document>

View File

@ -1,32 +0,0 @@
//
// CheckController.swift
// AutoCat2Mac
//
// Created by Selim Mustafaev on 06.07.2022.
//
import AppKit
class CheckController: NSViewController {
@IBOutlet weak var checkButton: NSButton!
@IBOutlet weak var cancelButton: NSButton!
@IBOutlet weak var textField: NSTextField!
@IBOutlet weak var progress: NSProgressIndicator!
override func viewDidLoad() {
super.viewDidLoad()
checkButton.controlSize = .large
cancelButton.controlSize = .large
textField.controlSize = .large
}
@IBAction func onCancel(_ sender: NSButton) {
view.window?.close()
}
@IBAction func onCheck(_ sender: NSButton) {
}
}

View File

@ -1,17 +0,0 @@
//
// MainSplitController.swift
// AutoCat2Mac
//
// Created by Selim Mustafaev on 03.07.2022.
//
import AppKit
class MainSplitController: NSSplitViewController {
override func viewDidLoad() {
super.viewDidLoad()
splitView.autosaveName = "MainSplitViewAutosave"
}
}

View File

@ -1,108 +0,0 @@
//
// MainController.swift
// AutoCat2Mac
//
// Created by Selim Mustafaev on 15.06.2022.
//
import AppKit
class SidebarController: NSViewController, NSOutlineViewDataSource, NSOutlineViewDelegate {
@IBOutlet weak var outlineView: NSOutlineView!
var sections: [SidebarSection] = [
.database(items: [
SidebarFilterItem.local,
SidebarFilterItem.remote
])
]
var addItem: NSToolbarItem?
override func viewDidLoad() {
super.viewDidLoad()
outlineView.usesAutomaticRowHeights = true
}
// MARK: - NSOutlineViewDataSource
func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
guard item != nil else {
return sections.count
}
if let section = item as? SidebarSection {
return section.items.count
} else {
return 0
}
}
func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
guard item != nil else {
return sections[index]
}
if let section = item as? SidebarSection {
return section.items[index]
} else {
return sections[index]
}
}
func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
return item is SidebarSection
}
// MARK: - NSOutlineViewDelegate
func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
if let category = item as? SidebarSection {
let cell = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "SidebarHeaderCell"), owner: nil) as? NSTableCellView
cell?.textField?.stringValue = category.name
return cell
} else if let item = item as? SidebarItem {
let cell = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "SidebarItemCell"), owner: nil) as? NSTableCellView
cell?.textField?.stringValue = item.title
cell?.imageView?.image = NSImage(systemSymbolName: item.iconName, accessibilityDescription: item.title)
return cell
}
return nil
}
func outlineView(_ outlineView: NSOutlineView, isGroupItem item: Any) -> Bool {
item is SidebarSection
}
func outlineView(_ outlineView: NSOutlineView, shouldSelectItem item: Any) -> Bool {
outlineView.parent(forItem: item) != nil
}
func outlineView(_ outlineView: NSOutlineView, persistentObjectForItem item: Any?) -> Any? {
guard let section = item as? SidebarSection else {
return nil
}
return section.name
}
func outlineView(_ outlineView: NSOutlineView, itemForPersistentObject object: Any) -> Any? {
guard let name = object as? String else {
return nil
}
return sections.first { $0.name == name }
}
func outlineViewSelectionDidChange(_ notification: Notification) {
let item = self.outlineView.item(atRow: self.outlineView.selectedRow)
if let filter = item as? SidebarFilterItem {
print("Selected filter: ", filter.title)
}
}
}

View File

@ -1,38 +0,0 @@
//
// SidebarFilterItem.swift
// AutoCat2Mac
//
// Created by Selim Mustafaev on 03.07.2022.
//
import AutoCatCore
class SidebarFilterItem: SidebarItem {
var iconName: String
var title: String
var badge: Int?
let filter: Filter
init(iconName: String, title: String, filter: Filter) {
self.iconName = iconName
self.title = title
self.filter = filter
}
static var local: SidebarFilterItem {
SidebarFilterItem(iconName: "internaldrive",
title: "Local history",
filter: Filter.allLocal)
}
static var remote: SidebarFilterItem {
SidebarFilterItem(iconName: "externaldrive.connected.to.line.below",
title: "Remote DB",
filter: Filter.allRemote)
}
}

View File

@ -1,15 +0,0 @@
//
// SidebarItem.swift
// AutoCat2Mac
//
// Created by Selim Mustafaev on 03.07.2022.
//
import Foundation
protocol SidebarItem {
var iconName: String { get }
var title: String { get }
var badge: Int? { get }
}

View File

@ -1,24 +0,0 @@
//
// SidebarSection.swift
// AutoCat2Mac
//
// Created by Selim Mustafaev on 03.07.2022.
//
import Foundation
class SidebarSection {
let name: String
let items: [SidebarItem]
init(name: String, items: [SidebarItem]) {
self.name = name
self.items = items
}
static func database(items: [SidebarItem]) -> SidebarSection {
SidebarSection(name: "Vehicles DB", items: items)
}
}

View File

@ -1,26 +0,0 @@
//
// ViewController.swift
// AutoCat2Mac
//
// Created by Selim Mustafaev on 13.06.2022.
//
import Cocoa
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}

View File

@ -1,35 +0,0 @@
//
// MainWindowController.swift
// AutoCat2Mac
//
// Created by Selim Mustafaev on 03.07.2022.
//
import AppKit
class MainWindowController: NSWindowController {
override func windowDidLoad() {
super.windowDidLoad()
}
override func awakeFromNib() {
super.awakeFromNib()
// First - flexible space item
// Second - new number check item
// Third - sidebar separator item
window?.toolbar?.insertItem(withItemIdentifier: .sidebarTrackingSeparator, at: 2)
}
// MARK: - Toolbar actions
@IBAction func checkNewNumber(_ sender: NSToolbarItem) {
print("Check new number")
let storyboard = NSStoryboard(name: "Main", bundle: nil)
if let controller = storyboard.instantiateController(withIdentifier: "CheckController") as? NSViewController {
contentViewController?.presentAsSheet(controller)
}
}
}

View File

@ -1,11 +0,0 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1,63 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1,6 +0,0 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1,33 +0,0 @@
{
"colors" : [
{
"color" : {
"platform" : "ios",
"reference" : "systemGray2Color"
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.290",
"green" : "0.282",
"red" : "0.282"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1,38 +0,0 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "0.300",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1,38 +0,0 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.152",
"green" : "0.152",
"red" : "0.152"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1,38 +0,0 @@
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.000",
"green" : "0.000",
"red" : "1.000"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.182",
"green" : "0.225",
"red" : "1.000"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1,38 +0,0 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.000",
"green" : "0.000",
"red" : "0.000"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.866",
"green" : "0.866",
"red" : "0.866"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1,6 +0,0 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>

View File

@ -1,63 +0,0 @@
//
// AutoCat2SUIApp.swift
// AutoCat2SUI
//
// Created by Selim Mustafaev on 24.07.2022.
//
import SwiftUI
import AppKit
import AutoCatCore
@main
struct AutoCat2SUIApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
if Testing.isUITesting {
RootView(settings: getTestSettings())
} else {
RootView(settings: getSettings())
}
}
}
func getTestSettings() -> TestSettings {
guard let settings = MainSettings.shared as? TestSettings else {
fatalError("Error getting settings")
}
return settings
}
func getSettings() -> MainSettings {
guard let settings = MainSettings.shared as? MainSettings else {
fatalError("Error getting settings")
}
return settings
}
}
class AppDelegate: NSObject, NSApplicationDelegate {
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
true
}
func applicationDidFinishLaunching(_ notification: Notification) {
NSApp.keyWindow?.toolbar?.insertItem(withItemIdentifier: .sidebarTrackingSeparator, at: 2)
//NSApplication.shared.keyWindow
}
// func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// let configuration = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
// if connectingSceneSession.role == .windowApplication {
// configuration.delegateClass = SceneDelegate.self
// }
// return configuration
// }
}

View File

@ -1,34 +0,0 @@
//
// Alert.swift
// AutoCat2SUI
//
// Created by Selim Mustafaev on 24.07.2022.
//
import SwiftUI
enum AlertMessage: Identifiable {
case info(title: String, body: String)
case error(error: Error)
var id: Int {
switch self {
case .info(let title, let body):
return title.hashValue + body.hashValue
case .error(let error):
return error.localizedDescription.hashValue
}
}
}
extension Alert {
init(_ message: AlertMessage) {
switch message {
case .info(let title, let body):
self.init(title: Text(title), message: Text(body))
case .error(let error):
//let msg = (error as NSError).displayMessage
self.init(title: Text(""), message: Text(error.localizedDescription))
}
}
}

View File

@ -1,14 +0,0 @@
//
// View.swift
// AutoCat2SUI
//
// Created by Selim Mustafaev on 28.08.2022.
//
import SwiftUI
extension View {
func hidden(_ shouldHide: Bool) -> some View {
opacity(shouldHide ? 0 : 1)
}
}

Binary file not shown.

Binary file not shown.

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>ATSApplicationFontsPath</key>
<string>.</string>
<key>UIAppFonts</key>
<array>
<string>RoadNumbers.otf</string>
<string>RoadNumbers2.0.otf</string>
</array>
</dict>
</plist>

View File

@ -1,6 +0,0 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -1,25 +0,0 @@
//
// AuthVM.swift
// AutoCat2SUI
//
// Created by Selim Mustafaev on 24.07.2022.
//
import AutoCatCore
public class AuthVM: ObservableObject {
private let api: ApiProtocol
private var settings: any SettingsProtocol
init(api: ApiProtocol = Api.shared, settings: any SettingsProtocol = MainSettings.shared) {
self.api = api
self.settings = settings
}
@MainActor
public func login(user: String, password: String) async throws {
settings.user = try await api.login(email: user, password: password)
}
}

View File

@ -1,72 +0,0 @@
//
// AuthView.swift
// AutoCat2SUI
//
// Created by Selim Mustafaev on 24.07.2022.
//
import SwiftUI
struct AuthView: View {
enum Field {
case email
case password
}
@ObservedObject var viewModel = AuthVM()
@State private var login: String = ""
@State private var password: String = ""
@State private var showProgress: Bool = false
@State private var alert: AlertMessage? = nil
@FocusState private var focus: Field?
var body: some View {
ZStack {
VStack(alignment: .center, spacing: 16) {
Spacer()
#if os(iOS)
TextField("Login", text: $login)
.focused($focus, equals: .email)
.textContentType(.emailAddress)
.keyboardType(.emailAddress)
#else
TextField("Login", text: $login)
.focused($focus, equals: .email)
#endif
SecureField("Password", text: $password)
.focused($focus, equals: .password)
Button("Login") {
Task.init {
do {
self.focus = nil
self.showProgress = true
try await self.viewModel.login(user: self.login, password: self.password)
self.showProgress = false
} catch {
self.showProgress = false
self.alert = .error(error: error)
}
}
}
.alert(item: $alert, content: Alert.init)
Spacer()
}
.buttonStyle(.bordered)
.controlSize(.large)
.textFieldStyle(.roundedBorder)
.padding(20)
if self.showProgress {
ACProgressView()
}
}
}
}
struct AuthView_Previews: PreviewProvider {
static var previews: some View {
AuthView()
}
}

View File

@ -1,56 +0,0 @@
//
// CheckNumber.swift
// AutoCat2SUI
//
// Created by Selim Mustafaev on 28.08.2022.
//
import SwiftUI
import AutoCatCore
struct CheckNumber: View {
@Environment(\.presentationMode) var presentation
@State var plateNumber: String = ""
@State var showProgress = false
@State private var alert: AlertMessage? = nil
var body: some View {
VStack(alignment: .center, spacing: 8) {
Text("Check new plate number")
TextField("qwe", text: $plateNumber, prompt: Text("Plate number"))
.disabled(showProgress)
ProgressView()
.progressViewStyle(CircularProgressViewStyle())
.hidden(!showProgress)
HStack {
Button("Cancel") {
self.presentation.wrappedValue.dismiss()
}
.disabled(showProgress)
Button("Check") {
Task { @MainActor in
showProgress = true
do {
try await VehicleService.shared.check(plateNumber: plateNumber.uppercased(), force: false)
self.presentation.wrappedValue.dismiss()
} catch {
alert = .error(error: error)
}
showProgress = false
}
}
.alert(item: $alert, content: Alert.init)
.disabled(showProgress)
}
}
.padding()
.frame(minWidth: 300)
}
}
struct CheckNumber_Previews: PreviewProvider {
static var previews: some View {
CheckNumber()
}
}

View File

@ -1,44 +0,0 @@
//
// MainView.swift
// AutoCat2SUI
//
// Created by Selim Mustafaev on 24.07.2022.
//
import SwiftUI
import AutoCatCore
import RealmSwift
struct MainView: View {
@State private var searchText = ""
@State var columnVisibility = NavigationSplitViewVisibility.all
@State var selectedFilter: Filter?
@State var selectedVehicle: Vehicle?
var body: some View {
NavigationSplitView(columnVisibility: $columnVisibility) {
SidebarView(selectedFilter: $selectedFilter)
} content: {
if let filter = selectedFilter {
VehiclesListView(filter: filter, selection: $selectedVehicle)
} else {
EmptyView()
}
} detail: {
if let vehicle = selectedVehicle {
VehicleDetailView(vehicle: vehicle)
.searchable(text: $searchText, placement: .toolbar)
} else {
EmptyView()
}
}
.navigationSplitViewStyle(.balanced)
}
}
struct MainView_Previews: PreviewProvider {
static var previews: some View {
MainView()
}
}

View File

@ -1,74 +0,0 @@
//
// SidebarView.swift
// AutoCat2SUI
//
// Created by Selim Mustafaev on 12.02.2023.
//
import SwiftUI
import AutoCatCore
import RealmSwift
struct SidebarSection: Identifiable {
let name: String
let filters: [Filter]
let id = UUID()
func contains(filter id: UUID) -> Bool {
filters.contains { $0.id == id }
}
}
struct SidebarView: View {
@ObservedResults(Vehicle.self) var vehicles
@Binding var selectedFilter: Filter?
@State private var checkSheetPresented = false
private let sections: [SidebarSection] = [
SidebarSection(name: "History", filters: [
.allLocal,
.unrecognized,
.outdated
]),
SidebarSection(name: "Remote", filters: [
.allRemote
])
]
var body: some View {
List(selection: $selectedFilter) {
ForEach(sections) { section in
Section(section.name) {
ForEach(section.filters, id: \.self) { filter in
Label(filter.name, systemImage: filter.iconName)
.badge(vehicles.filter(filter.match).count)
}
}
}
}
.navigationSplitViewColumnWidth(180)
.toolbar {
ToolbarItemGroup(placement: .primaryAction) {
Spacer()
Button {
checkSheetPresented = true
} label: {
Image(systemName: "plus")
}
.sheet(isPresented: $checkSheetPresented) {
CheckNumber()
}
}
}
}
}
struct SidebarView_Previews: PreviewProvider {
static var previews: some View {
SidebarView(selectedFilter: .constant(nil))
}
}

View File

@ -1,78 +0,0 @@
//
// VehicleDetailView.swift
// AutoCat2SUI
//
// Created by Selim Mustafaev on 11.09.2022.
//
import SwiftUI
import AutoCatCore
struct ReportTextItem: View {
let name: String
let value: String?
var body: some View {
HStack {
Text(name)
Spacer()
Text(value ?? "")
.foregroundColor(.secondary)
}
}
}
struct VehicleDetailView: View {
let vehicle: Vehicle
var body: some View {
Form {
Section(header: Text("General")) {
ReportTextItem(name: "Year", value: String(vehicle.year ?? 0))
ReportTextItem(name: "Color", value: vehicle.color)
ReportTextItem(name: "Category", value: vehicle.category)
ReportTextItem(name: "Steering wheel position", value: vehicle.isRightWheel == true ? "Right": "Left")
ReportTextItem(name: "Japanese", value: vehicle.isJapanese == true ? "Yes" : "No")
}
Section(header: Text("Identifiers")) {
ReportTextItem(name: "Plate number", value: vehicle.number)
ReportTextItem(name: "VIN", value: vehicle.vin1)
ReportTextItem(name: "STS", value: vehicle.sts)
ReportTextItem(name: "PTS", value: vehicle.pts)
}
Section(header: Text("Engine")) {
ReportTextItem(name: "Number", value: vehicle.engine?.number)
ReportTextItem(name: "Fuel type", value: vehicle.engine?.fuelType)
ReportTextItem(name: "Volume (cm2)", value: String(vehicle.engine?.volume ?? 0))
ReportTextItem(name: "Power (HP)", value: String(vehicle.engine?.powerHp ?? 0))
ReportTextItem(name: "Power (kw)", value: String(vehicle.engine?.powerKw ?? 0))
}
}
.formStyle(.grouped)
.toolbar {
ToolbarItem(placement: .automatic) {
Button(action: {}) {
Image(systemName: "square.and.arrow.up")
}
}
}
.navigationTitle(vehicle.brand?.name?.original ?? "")
.navigationSubtitle("\(vehicle.year ?? 0)")
}
}
struct VehicleDetailView_Previews: PreviewProvider {
static var previews: some View {
let test1 = Vehicle(number: "Н282СН61",
brandName: "KIA ОПТИМА",
addedDate: Date().timeIntervalSince1970,
updatedDate: Date().timeIntervalSince1970)
return VehicleDetailView(vehicle: test1)
}
}

View File

@ -1,49 +0,0 @@
//
// VehiclesListView.swift
// AutoCat2SUI
//
// Created by Selim Mustafaev on 28.08.2022.
//
import SwiftUI
import AutoCatCore
import RealmSwift
struct VehiclesListView: View {
var filter: Filter
@Binding var selection: Vehicle?
@ObservedResults(Vehicle.self) var vehicles
var body: some View {
let filtered: [Vehicle] = vehicles.filter(filter.match)
if filtered.isEmpty {
PlaceholderView(imageName: filter.iconName)
} else {
List(selection: $selection) {
ForEach(filtered, id: \.self) { vehicle in
PlateViewItem(vehicle: vehicle)
}
}
.toolbar {
ToolbarItem {
Button(action: {}) {
Image(systemName: "line.3.horizontal.decrease.circle")
}
}
}
.navigationTitle(filter.name)
.navigationSubtitle("\(filtered.count) vehicles")
}
}
}
struct VehiclesListView_Previews: PreviewProvider {
@State var selection: Vehicle?
static var previews: some View {
VehiclesListView(filter: .allLocal, selection: .constant(nil))
}
}

View File

@ -1,29 +0,0 @@
//
// VehiclesListViewModel.swift
// AutoCat2SUI
//
// Created by Selim Mustafaev on 15.02.2023.
//
import SwiftUI
import AutoCatCore
class VehiclesListViewModel: ObservableObject {
@Published var vehicles: [Vehicle] = []
let filter: Filter
init(filter: Filter) {
self.filter = filter
loadVehicles()
}
func loadVehicles() {
switch filter.dataSource {
case .local:
}
}
}

View File

@ -1,76 +0,0 @@
//
// ACProgressView.swift
// AutoCat2SUI
//
// Created by Selim Mustafaev on 24.07.2022.
//
import SwiftUI
struct ACProgressView: View {
@State var isDeterminate: Bool = false
@State var progress: CGFloat = 0
@State var text: String? = nil
@State var isAnimating: Bool = false
var body: some View {
ZStack(alignment: .center) {
Color.black.opacity(0.4)
VStack {
VStack(spacing: 24) {
if self.isDeterminate {
ZStack {
Circle()
.stroke(Color.secondary.opacity(0.2), style: StrokeStyle(lineWidth: 4))
.frame(width: 100, height: 100)
Circle()
.trim(from: 0, to: self.progress)
.stroke(Color.blue, style: StrokeStyle(lineWidth: 4))
.rotationEffect(.degrees(-90))
.frame(width: 100, height: 100)
Text("\(Int(self.progress*100)) %")
}
} else {
let gradient = AngularGradient(
gradient: Gradient(colors: [Color.blue, Color.blue.opacity(0.01)]),
center: .center,
startAngle: .degrees(360),
endAngle: .degrees(0))
Circle()
.stroke(gradient, style: StrokeStyle(lineWidth: 4))
.rotationEffect(Angle(degrees: self.isAnimating ? 360 : 0))
.onAppear {
withAnimation(.linear(duration: 1).repeatForever(autoreverses: false)) {
self.isAnimating = true
}
}
.onDisappear(perform: {
self.isAnimating = false
})
.frame(width: 100, height: 100)
}
if let msg = self.text {
Text(msg)
}
}
.padding(28)
}
//.frame(width: 160, height: 160)
.background(.regularMaterial)
.cornerRadius(20)
}
.edgesIgnoringSafeArea(.all)
}
}
struct ACProgressView_Previews: PreviewProvider {
static var previews: some View {
Group {
ACProgressView()
ACProgressView(isDeterminate: true, progress: 0.3, text: "Loading...")
.preferredColorScheme(.dark)
}
}
}

View File

@ -1,39 +0,0 @@
//
// PlaceholderView.swift
// AutoCat2SUI
//
// Created by Selim Mustafaev on 12.02.2023.
//
import SwiftUI
struct PlaceholderView: View {
let imageName: String
let text: String
var body: some View {
VStack {
Image(systemName: imageName)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 64)
.foregroundColor(.secondary)
Text(text)
.font(.system(size: 18))
.foregroundColor(.secondary)
}
}
init(imageName: String, text: String = "Nothing here") {
self.imageName = imageName
self.text = text
}
}
struct PlaceholderView_Previews: PreviewProvider {
static var previews: some View {
PlaceholderView(imageName: "eye", text: "Nothing here")
}
}

View File

@ -1,232 +0,0 @@
#if os(macOS)
import AppKit
import AutoCatCore
import SwiftUI
extension CGRect {
func inset(by insets: NSEdgeInsets) -> CGRect {
CGRect(origin: CGPoint(x: origin.x + insets.left,
y: origin.y + insets.bottom),
size: CGSize(width: size.width - insets.left - insets.right,
height: size.height - insets.top - insets.bottom))
}
}
extension NSScreen {
static var mainScreenScale: CGFloat {
main?.backingScaleFactor ?? 1
}
}
class FlagLayer: CALayer {
let pixelWidth = 1/NSScreen.mainScreenScale
// Flag colors - https://ru.wikipedia.org/wiki/%D0%A4%D0%BB%D0%B0%D0%B3_%D0%A0%D0%BE%D1%81%D1%81%D0%B8%D0%B8
let blue = NSColor(srgbRed: 0, green: 57/256.0, blue: 166/256.0, alpha: 1)
let red = NSColor(srgbRed: 213/256.0, green: 43/256.0, blue: 30/256.0, alpha: 1)
override func draw(in ctx: CGContext) {
ctx.saveGState()
super.draw(in: ctx)
ctx.setStrokeColor(NSColor.black.cgColor)
ctx.setLineWidth(0)
ctx.setFillColor(NSColor.white.cgColor)
ctx.fill(bounds.inset(by: NSEdgeInsets(top: 0, left: 0, bottom: bounds.height*2/3, right: 0)))
ctx.setFillColor(self.blue.cgColor)
ctx.fill(bounds.insetBy(dx: 0, dy: bounds.height/3))
ctx.setFillColor(self.red.cgColor)
ctx.fill(bounds.inset(by: NSEdgeInsets(top: bounds.height*2/3, left: 0, bottom: 0, right: 0)))
ctx.setLineWidth(pixelWidth)
ctx.stroke(bounds.insetBy(dx: pixelWidth/2, dy: pixelWidth/2))
ctx.restoreGState()
}
}
class PlateView: NSView {
// Some driver plate parameters from "ГОСТ Р 50577-93"
// http://docs.cntd.ru/document/gost-r-50577-93
private static let aspectRatio: CGFloat = 112.0/520.0
private static let fontHeightCoeff: CGFloat = 58.0/76.0
private var bgLayer = CALayer()
private var mainBgLayer = CALayer()
private var regionBgLayer = CALayer()
private var numberLayer = CenterTextLayer(coeff: fontHeightCoeff)
private var regionLayer = CenterTextLayer(coeff: fontHeightCoeff)
private var countryLayer = CenterTextLayer()
private var flagLayer = FlagLayer()
var number: PlateNumber? {
didSet {
self.layout()
self.setAccessibilityLabel(number?.asString())
}
}
var foreground: NSColor? {
didSet {
self.layout()
}
}
var fontSize: CGFloat = 10 {
didSet {
self.layout()
}
}
var onChange: (() -> Void)?
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
func setup() {
self.wantsLayer = true
self.layer?.backgroundColor = NSColor.clear.cgColor
self.bgLayer.cornerRadius = 6 //self.bounds.height/8
self.layer?.addSublayer(self.bgLayer)
self.mainBgLayer.cornerRadius = 4
self.layer?.addSublayer(self.mainBgLayer)
self.regionBgLayer.cornerRadius = 4
self.layer?.addSublayer(self.regionBgLayer)
self.numberLayer.alignmentMode = .center
self.numberLayer.contentsScale = NSScreen.mainScreenScale
self.layer?.addSublayer(self.numberLayer)
self.regionLayer.alignmentMode = .center
self.regionLayer.contentsScale = NSScreen.mainScreenScale
self.layer?.addSublayer(self.regionLayer)
self.countryLayer.contentsScale = NSScreen.mainScreenScale
self.countryLayer.string = "RUS"
self.countryLayer.alignmentMode = .center
self.layer?.addSublayer(self.countryLayer)
self.flagLayer.contentsScale = NSScreen.mainScreenScale
self.layer?.addSublayer(self.flagLayer)
self.setAccessibilityElement(true)
}
private func pathForFlag(in rect: CGRect) -> CGPath {
let path = CGMutablePath()
let rect = CGPath(rect: rect, transform: nil)
path.addPath(rect)
return path
}
override func layout() {
super.layout()
guard let number = self.number else { return }
guard let fgColorMain = NSColor(named: "PlateForeground")?.cgColor else { return }
guard let bgColor = NSColor(named: "PlateBackground")?.cgColor else { return }
let fgColor = self.foreground?.cgColor ?? fgColorMain
self.bgLayer.backgroundColor = fgColor
self.bgLayer.frame = self.bounds
self.mainBgLayer.backgroundColor = bgColor
self.regionBgLayer.backgroundColor = bgColor
self.mainBgLayer.frame = self.bounds.inset(by: NSEdgeInsets(top: 2, left: 2, bottom: 2, right: self.bounds.width*0.27 + 1))
self.regionBgLayer.frame = self.bounds.inset(by: NSEdgeInsets(top: 2, left: self.bounds.width*0.73 + 1, bottom: 2, right: 2))
self.numberLayer.frame = self.mainBgLayer.frame.insetBy(dx: 4, dy: 0)
let font = NSFont(name: "RoadNumbers", size: self.mainBgLayer.frame.height*1.1) ?? NSFont.boldSystemFont(ofSize: 24)
let attributes: [NSAttributedString.Key: Any] = [
.kern: 3,
.font: font,
.foregroundColor: fgColor
]
let attributed = NSAttributedString(string: number.mainPart(), attributes: attributes)
self.numberLayer.string = attributed
let rbgSize = self.regionBgLayer.frame.size
self.regionLayer.frame = self.regionBgLayer.frame.inset(by: NSEdgeInsets(top: 2, left: 2, bottom: rbgSize.height*0.35, right: 2))
let regionFont = NSFont(name: "RoadNumbers", size: rbgSize.height*0.8) ?? NSFont.boldSystemFont(ofSize: 24)
let regionAttrs: [NSAttributedString.Key: Any] = [
.kern: 1,
.font: regionFont,
.foregroundColor: fgColor
]
let attributedRegion = NSAttributedString(string: number.region(), attributes: regionAttrs)
self.regionLayer.string = attributedRegion
self.countryLayer.foregroundColor = fgColor
self.countryLayer.frame = self.regionBgLayer.frame.inset(by: NSEdgeInsets(top: rbgSize.height*0.64,
left: rbgSize.width*0.08,
bottom: rbgSize.height*0.07,
right: rbgSize.width*0.42))
self.countryLayer.fontSize = self.countryLayer.frame.size.height
let top = (self.regionBgLayer.frame.origin.y + rbgSize.height*0.04).rounded(.toNearestOrAwayFromZero)
let left = (self.regionBgLayer.frame.origin.x + rbgSize.width*0.62).rounded(.toNearestOrAwayFromZero)
let w = (rbgSize.width*0.34).rounded(.toNearestOrAwayFromZero)
let h = (rbgSize.height*0.28).rounded(.toNearestOrAwayFromZero)
self.flagLayer.frame = CGRect(x: left, y: top, width: w, height: h)
self.flagLayer.setNeedsDisplay()
}
override var intrinsicContentSize: CGSize {
let height = fontSize/1.1 + 4
let width = height/PlateView.aspectRatio
return CGSize(width: width, height: height)
}
}
struct PlateNumberView: NSViewRepresentable {
var number: PlateNumber
var unrecognized: Bool
var outdated: Bool
var fontSize: CGFloat
func makeNSView(context: Context) -> PlateView {
let view = PlateView(frame: .zero)
view.fontSize = fontSize
return view
}
func updateNSView(_ nsView: PlateView, context: Context) {
nsView.number = number
nsView.setContentHuggingPriority(.defaultHigh, for: .horizontal)
nsView.setContentHuggingPriority(.defaultHigh, for: .vertical)
}
}
struct PlateNumberView_Previews: PreviewProvider {
static var previews: some View {
Group {
PlateNumberView(number: PlateNumber("Е201АМ761"), unrecognized: false, outdated: false, fontSize: 50)
PlateNumberView(number: PlateNumber("Е201АМ761"), unrecognized: true, outdated: false, fontSize: 50)
PlateNumberView(number: PlateNumber("Е201АМ761"), unrecognized: false, outdated: true, fontSize: 50)
}
}
}
#endif

View File

@ -1,46 +0,0 @@
//
// PlateViewItem.swift
// AutoCat2SUI
//
// Created by Selim Mustafaev on 04.09.2022.
//
import SwiftUI
import AutoCatCore
struct PlateViewItem: View {
let vehicle: Vehicle
var body: some View {
VStack(alignment: .leading, spacing: 4) {
Text(vehicle.brand?.name?.original ?? "")
HStack {
PlateNumberView(number: PlateNumber(vehicle.number),
unrecognized: vehicle.unrecognized,
outdated: vehicle.outdated,
fontSize: 30)
VStack {
// if let upDate = vehicle.updatedDate {
//
// }
}
}
}
.padding(.vertical, 2)
}
}
struct PlateViewItem_Previews: PreviewProvider {
static var previews: some View {
let test1 = Vehicle(number: "Н282СН61",
brandName: "KIA ОПТИМА",
addedDate: Date().timeIntervalSince1970,
updatedDate: Date().timeIntervalSince1970)
return PlateViewItem(vehicle: test1)
}
}

View File

@ -1,32 +0,0 @@
//
// ContentView.swift
// AutoCat2SUI
//
// Created by Selim Mustafaev on 24.07.2022.
//
import SwiftUI
import AutoCatCore
struct RootView<T>: View where T: SettingsProtocol {
@ObservedObject var settings: T
init(settings: T) {
self.settings = settings
}
var body: some View {
if settings.user.token.isEmpty {
AuthView()
} else {
MainView()
}
}
}
struct RootView_Previews: PreviewProvider {
static var previews: some View {
RootView(settings: MainSettings())
}
}

View File

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
<dict>
<key>_XCCurrentVersionName</key>
<string>Shared.xcdatamodel</string>
</dict>
</plist>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21513" systemVersion="22D49" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithCloudKit="YES" userDefinedModelVersionIdentifier="">
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="19574" systemVersion="20G80" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithCloudKit="YES" userDefinedModelVersionIdentifier="">
<entity name="DebugInfo" representedClassName=".CDDebugInfo" syncable="YES" codeGenerationType="class">
<relationship name="autocod" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="DebugInfoEntry" inverseName="autocodInfo" inverseEntity="DebugInfoEntry"/>
<relationship name="nomerogram" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="DebugInfoEntry" inverseName="nomerogramInfo" inverseEntity="DebugInfoEntry"/>
@ -131,4 +131,19 @@
<attribute name="url" optional="YES" attributeType="String"/>
<relationship name="vehicle" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Vehicle" inverseName="photos" inverseEntity="Vehicle"/>
</entity>
<elements>
<element name="VBrand" positionX="118.7528686523438" positionY="-209.1094360351562" width="128" height="74"/>
<element name="Vehicle" positionX="-145.9427490234375" positionY="-363.4805297851562" width="128" height="404"/>
<element name="VModel" positionX="-9" positionY="-207" width="128" height="59"/>
<element name="VName" positionX="-54" positionY="9" width="128" height="89"/>
<element name="VEngine" positionX="-9" positionY="-207" width="128" height="119"/>
<element name="VPhoto" positionX="0" positionY="-198" width="128" height="104"/>
<element name="VOwnershipPeriod" positionX="9" positionY="-189" width="128" height="209"/>
<element name="VEvent" positionX="18" positionY="-180" width="128" height="149"/>
<element name="VOsago" positionX="27" positionY="-171" width="128" height="194"/>
<element name="VAd" positionX="36" positionY="-162" width="128" height="179"/>
<element name="VNote" positionX="45" positionY="-153" width="128" height="104"/>
<element name="DebugInfoEntry" positionX="-9" positionY="-207" width="128" height="149"/>
<element name="DebugInfo" positionX="0" positionY="-198" width="128" height="119"/>
</elements>
</model>

View File

@ -1,16 +0,0 @@
//
// RealmDecoding.swift
// AutoCatCore
//
// Created by Selim Mustafaev on 12.02.2023.
//
import RealmSwift
extension KeyedDecodingContainer {
func decode<T: Decodable>(_ type: Persisted<List<T>>.Type, forKey key: Key) throws -> Persisted<List<T>> {
// Use decode if present, falling back to an empty list
try decodeIfPresent(type, forKey: key) ?? Persisted<List<T>>(wrappedValue: List<T>())
}
}

View File

@ -1,103 +0,0 @@
//
// Filter.swift
// AutoCatCore
//
// Created by Selim Mustafaev on 03.07.2022.
//
import Foundation
public enum DataSource: CaseIterable, Identifiable {
case local
case remote
public var id: String {
return name
}
public var name: String {
switch self {
case .local:
return "Local"
case .remote:
return "Remote"
}
}
}
public final class Filter: Hashable, Identifiable {
public let id = UUID()
public let name: String
public let iconName: String
public let dataSource: DataSource
public let unrecognized: Bool
public let outdated: Bool
public init(name: String,
iconName: String,
dataSource: DataSource,
unrecognized: Bool,
outdated: Bool) {
self.name = name
self.iconName = iconName
self.dataSource = dataSource
self.unrecognized = unrecognized
self.outdated = outdated
}
public func match(vehicle: Vehicle) -> Bool {
return unrecognized == vehicle.unrecognized
&& outdated == vehicle.outdated
}
public static func == (lhs: Filter, rhs: Filter) -> Bool {
lhs.dataSource == rhs.dataSource
&& lhs.unrecognized == rhs.unrecognized
&& lhs.outdated == rhs.outdated
}
public func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
// MARK: - Presets
extension Filter {
public static var allLocal: Filter {
Filter(name: "All",
iconName: "car.2",
dataSource: .local,
unrecognized: false,
outdated: false)
}
public static var allRemote: Filter {
Filter(name: "All",
iconName: "car.2",
dataSource: .remote,
unrecognized: false,
outdated: false)
}
public static var unrecognized: Filter {
Filter(name: "Unrecognized",
iconName: "eye.slash",
dataSource: .local,
unrecognized: true,
outdated: false)
}
public static var outdated: Filter {
Filter(name: "Outdated",
iconName: "clock.badge.exclamationmark",
dataSource: .local,
unrecognized: false,
outdated: true)
}
}

View File

@ -1,50 +0,0 @@
import Foundation
public protocol SettingsProtocol: ObservableObject {
var user: User { get set }
var showDebugInfo: Bool { get set }
}
public class MainSettings: SettingsProtocol {
private let defaults: UserDefaults
public static var shared: any SettingsProtocol = Testing.isUITesting ? TestSettings() : MainSettings()
@Published
public var user: User {
didSet {
if let json = try? JSONEncoder().encode(self.user) {
self.defaults.set(json, forKey: "user")
self.defaults.synchronize()
}
}
}
public var showDebugInfo: Bool = false {
didSet {
self.defaults.set(self.showDebugInfo, forKey: "showDebugInfo")
self.defaults.synchronize()
}
}
public init(defaults: UserDefaults = .standard) {
self.defaults = defaults
// if let bundleID = Bundle.main.bundleIdentifier {
// UserDefaults.standard.removePersistentDomain(forName: bundleID)
// }
self.defaults.register(defaults: [
"showDebugInfo": false
])
self.showDebugInfo = self.defaults.bool(forKey: "showDebugInfo")
if let data = self.defaults.data(forKey: "user") {
self.user = (try? JSONDecoder().decode(User.self, from: data)) ?? User()
} else {
self.user = User()
}
}
}

View File

@ -0,0 +1,85 @@
import Foundation
public protocol SettingsProtocol {
var user: User { get set }
var recognizeAlternativeOrder: Bool { get set }
var recognizeShortenedNumbers: Bool { get set }
var defaultRegion: String { get set }
var recordBeep: Bool { get set }
var showDebugInfo: Bool { get set }
}
public class Settings: ObservableObject, SettingsProtocol {
private let defaults: UserDefaults
public static var shared: SettingsProtocol = Testing.isUITesting ? TestSettings() : Settings()
public var user: User {
didSet {
if let json = try? JSONEncoder().encode(self.user) {
self.defaults.set(json, forKey: "user")
self.defaults.synchronize()
}
}
}
public var recognizeAlternativeOrder: Bool = false {
didSet {
self.defaults.set(self.recognizeAlternativeOrder, forKey: "recognizeAlternativeOrder")
self.defaults.synchronize()
}
}
public var recognizeShortenedNumbers: Bool = false {
didSet {
self.defaults.set(self.recognizeShortenedNumbers, forKey: "recognizeShortenedNumbers")
self.defaults.synchronize()
}
}
public var defaultRegion: String = "" {
didSet {
self.defaults.set(self.defaultRegion, forKey: "defaultRegion")
self.defaults.synchronize()
}
}
public var recordBeep: Bool = false {
didSet {
self.defaults.set(self.recordBeep, forKey: "recordBeep")
self.defaults.synchronize()
}
}
public var showDebugInfo: Bool = false {
didSet {
self.defaults.set(self.showDebugInfo, forKey: "showDebugInfo")
self.defaults.synchronize()
}
}
public init(defaults: UserDefaults = .standard) {
self.defaults = defaults
self.defaults.register(defaults: [
"recognizeAlternativeOrder": false,
"recognizeShortenedNumbers": false,
"defaultRegion": "161",
"recordBeep": false,
"showDebugInfo": false
])
self.recognizeAlternativeOrder = self.defaults.bool(forKey: "recognizeAlternativeOrder")
self.recognizeShortenedNumbers = self.defaults.bool(forKey: "recognizeShortenedNumbers")
self.defaultRegion = self.defaults.string(forKey: "defaultRegion") ?? "161"
self.recordBeep = self.defaults.bool(forKey: "recordBeep")
self.showDebugInfo = self.defaults.bool(forKey: "showDebugInfo")
if let data = self.defaults.data(forKey: "user") {
self.user = (try? JSONDecoder().decode(User.self, from: data)) ?? User()
} else {
self.user = User()
}
}
}

View File

@ -1,46 +1,100 @@
import RealmSwift
import Foundation
import CoreData
import DifferenceKit
public final class Vehicle: Object, Decodable {
public struct Vehicle: Decodable {
@Persisted(primaryKey: true) public var number: String
@Persisted public var currentNumber: String?
@Persisted public var brand: VBrand?
@Persisted public var model: VModel?
@Persisted public var addedDate: TimeInterval
@Persisted public var updatedDate: TimeInterval
@Persisted public var color: String?
@Persisted public var year: Int64?
@Persisted public var category: String?
@Persisted public var vin1: String?
@Persisted public var vin2: String?
@Persisted public var sts: String?
@Persisted public var pts: String?
@Persisted public var isRightWheel: Bool?
@Persisted public var isJapanese: Bool?
@Persisted public var addedBy: String?
@Persisted public var engine: VEngine?
@Persisted public var photos: List<VPhoto>
@Persisted public var ownershipPeriods: List<VOwnershipPeriod>
@Persisted public var events: List<VEvent>
@Persisted public var osagoContracts: List<VOsago>
@Persisted public var ads: List<VAd>
@Persisted public var notes: List<VNote>
@Persisted public var debugInfo: DebugInfo?
public let number: String
public let currentNumber: String?
public let brand: VBrand?
public let model: VModel?
public let addedDate: TimeInterval
public let updatedDate: TimeInterval
public let color: String?
public let year: Int64?
public let category: String?
public let vin1: String?
public let vin2: String?
public let sts: String?
public let pts: String?
public let isRightWheel: Bool?
public let isJapanese: Bool?
public let addedBy: String?
public let engine: VEngine?
public let photos: [VPhoto]?
public let ownershipPeriods: [VOwnershipPeriod]?
public let events: [VEvent]?
public let osagoContracts: [VOsago]?
public let ads: [VAd]?
public let notes: [VNote]?
public let debugInfo: DebugInfo?
}
extension CDVehicle: Dated {
public var updatedAt: Date {
Date(timeIntervalSince1970: updatedDate)
}
public var addedAt: Date {
Date(timeIntervalSince1970: addedDate)
}
}
extension CDVehicle: Differentiable {
public convenience init(number: String, brandName: String, addedDate: TimeInterval, updatedDate: TimeInterval) {
self.init()
self.number = number
self.currentNumber = number
self.addedDate = addedDate
self.updatedDate = updatedDate
public var differenceIdentifier: String { number! }
public func isContentEqual(to source: CDVehicle) -> Bool {
return number == source.number &&
addedDate == source.addedDate &&
updatedDate == source.updatedDate
}
}
extension CDVehicle {
convenience init(vehicle: Vehicle, context: NSManagedObjectContext) {
let name = VName()
name.original = brandName
self.init(context: context)
self.number = vehicle.number
self.currentNumber = vehicle.currentNumber
self.addedDate = vehicle.addedDate/1000
self.updatedDate = vehicle.updatedDate/1000
self.color = vehicle.color
self.brand = CDVBrand(vbrand: vehicle.brand, context: context)
self.model = CDVModel(model: vehicle.model, context: context)
self.year = vehicle.year ?? 0
self.category = category
self.vin1 = vehicle.vin1
self.vin2 = vehicle.vin2
self.sts = vehicle.sts
self.pts = vehicle.pts
self.isRightWheel = vehicle.isRightWheel ?? false
self.isJapanese = vehicle.isJapanese ?? false
self.addedBy = vehicle.addedBy
self.synchronized = true
self.engine = CDVEngine(model: vehicle.engine, context: context)
let brand = VBrand()
brand.name = name
self.brand = brand
let photos = vehicle.photos?.map { CDVPhoto(model: $0, context: context) } ?? []
self.photos = NSSet(array: photos)
let ownershipPeriods = vehicle.ownershipPeriods?.map { CDVOwnershipPeriod(model: $0, context: context) } ?? []
self.ownershipPeriods = NSSet(array: ownershipPeriods)
let events = vehicle.events?.map { CDVEvent(model: $0, context: context) } ?? []
self.events = NSSet(array: events)
let osagoContracts = vehicle.osagoContracts?.map { CDVOsago(model: $0, context: context) } ?? []
self.osagoContracts = NSSet(array: osagoContracts)
let ads = vehicle.ads?.map { CDVAd(model: $0, context: context) } ?? []
self.ads = NSSet(array: ads)
let notes = vehicle.notes?.map { CDVNote(model: $0, context: context) } ?? []
self.notes = NSSet(array: notes)
self.debugInfo = CDDebugInfo(model: vehicle.debugInfo, context: context)
}
public var unrecognized: Bool {
@ -54,32 +108,5 @@ public final class Vehicle: Object, Decodable {
return false
}
}
}
extension Vehicle: Dated {
public var updatedAt: Date {
Date(timeIntervalSince1970: updatedDate)
}
public var addedAt: Date {
Date(timeIntervalSince1970: addedDate)
}
}
extension Vehicle: Differentiable {
public var differenceIdentifier: String { number }
public func isContentEqual(to source: Vehicle) -> Bool {
return number == source.number &&
addedDate == source.addedDate &&
updatedDate == source.updatedDate
}
}
extension Vehicle: Identifiable {
public var id: String { number }
}

View File

@ -1,10 +1,31 @@
import RealmSwift
//
// DebugInfo.swift
// AutoCatCore
//
// Created by Selim Mustafaev on 03.04.2022.
//
public final class DebugInfo: Object, Decodable {
import Foundation
import CoreData
public struct DebugInfo: Decodable {
@Persisted var autocod: DebugInfoEntry?
@Persisted var vin01vin: DebugInfoEntry?
@Persisted var vin01base: DebugInfoEntry?
@Persisted var vin01history: DebugInfoEntry?
@Persisted var nomerogram: DebugInfoEntry?
let autocod: DebugInfoEntry?
let vin01vin: DebugInfoEntry?
let vin01base: DebugInfoEntry?
let vin01history: DebugInfoEntry?
let nomerogram: DebugInfoEntry?
}
extension CDDebugInfo {
convenience init(model: DebugInfo?, context: NSManagedObjectContext) {
self.init(context: context)
self.autocod = CDDebugInfoEntry(model: model?.autocod, context: context)
self.vin01vin = CDDebugInfoEntry(model: model?.vin01vin, context: context)
self.vin01base = CDDebugInfoEntry(model: model?.vin01base, context: context)
self.vin01history = CDDebugInfoEntry(model: model?.vin01history, context: context)
self.nomerogram = CDDebugInfoEntry(model: model?.nomerogram, context: context)
}
}

View File

@ -1,15 +1,38 @@
import RealmSwift
//
// DebugInfoEntry.swift
// AutoCatCore
//
// Created by Selim Mustafaev on 03.04.2022.
//
public enum DebugInfoStatus: Int64, Decodable, PersistableEnum {
import Foundation
import CoreData
public enum DebugInfoStatus: Int64 {
case success = 0
case error = 1
case warning = 2
}
public final class DebugInfoEntry: Object, Decodable {
public struct DebugInfoEntry: Decodable {
@Persisted var fields: Int64
@Persisted var error: String?
@Persisted var status: DebugInfoStatus?
let fields: Int64
let error: String?
let status: Int64
}
extension CDDebugInfoEntry {
convenience init(model: DebugInfoEntry?, context: NSManagedObjectContext) {
self.init(context: context)
self.fields = model?.fields ?? 0
self.error = model?.error
self.status = model?.status ?? 0
}
public var statusEnum: DebugInfoStatus {
get { DebugInfoStatus(rawValue: self.status)! }
set { self.status = newValue.rawValue }
}
}

View File

@ -1,15 +1,39 @@
import RealmSwift
//
// VAd.swift
// AutoCatCore
//
// Created by Selim Mustafaev on 02.04.2022.
//
public final class VAd: Object, Decodable {
import Foundation
import CoreData
public struct VAd: Decodable {
@Persisted var id: Int64
@Persisted var url: String?
@Persisted var price: String?
@Persisted var date: Double
@Persisted var mileage: String?
@Persisted var region: String?
@Persisted var city: String?
@Persisted var adDescription: String?
@Persisted var photos: List<String>
let id: Int64
let url: String?
let price: String?
let date: Double
let mileage: String?
let region: String?
let city: String?
let adDescription: String?
let photos: [String]
}
extension CDVAd {
convenience init(model: VAd?, context: NSManagedObjectContext) {
self.init(context: context)
self.id = model?.id ?? 0
self.url = model?.url
self.price = model?.price
self.date = model?.date ?? 0
self.mileage = model?.mileage
self.region = model?.region
self.city = model?.city
self.adDescription = model?.adDescription
self.photos = model?.photos
}
}

View File

@ -1,7 +1,19 @@
import RealmSwift
import Foundation
import CoreData
public final class VBrand: Object, Decodable {
public struct VBrand: Decodable {
let logo: String?
let name: VName?
}
extension CDVBrand {
convenience init(vbrand: VBrand?, context: NSManagedObjectContext) {
self.init(context: context)
self.logo = vbrand?.logo
self.name = CDVName(vname: vbrand?.name, context: context)
}
@Persisted public var logo: String?
@Persisted public var name: VName?
}

View File

@ -1,10 +1,31 @@
import RealmSwift
//
// VEngine.swift
// AutoCatCore
//
// Created by Selim Mustafaev on 02.04.2022.
//
public final class VEngine: Object, Decodable {
import Foundation
import CoreData
public struct VEngine: Decodable {
@Persisted public var number: String?
@Persisted public var volume: Int64?
@Persisted public var powerHp: Float?
@Persisted public var powerKw: Float?
@Persisted public var fuelType: String?
let number: String?
let volume: Int64?
let powerHp: Float?
let powerKw: Float?
let fuelType: String?
}
extension CDVEngine {
convenience init(model: VEngine?, context: NSManagedObjectContext) {
self.init(context: context)
self.number = model?.number
self.volume = model?.volume ?? 0
self.powerHp = model?.powerHp ?? 0
self.powerKw = model?.powerKw ?? 0
self.fuelType = model?.fuelType
}
}

View File

@ -1,10 +1,35 @@
import RealmSwift
//
// VEvent.swift
// AutoCatCore
//
// Created by Selim Mustafaev on 02.04.2022.
//
public final class VEvent: Object, Decodable {
import Foundation
import CoreData
public struct VEvent: Decodable {
@Persisted var id: String
@Persisted var date: Double
@Persisted var latitude: Double
@Persisted var longitude: Double
@Persisted var address: String?
let id: String
let date: Double
let latitude: Double
let longitude: Double
let speed: Double
let direction: Double
let address: String?
}
extension CDVEvent {
convenience init(model: VEvent?, context: NSManagedObjectContext) {
self.init(context: context)
self.id = model?.id
self.date = model?.date ?? 0
self.latitude = model?.latitude ?? 0
self.longitude = model?.longitude ?? 0
self.speed = model?.speed ?? 0
self.direction = model?.direction ?? 0
self.address = model?.address
}
}

View File

@ -1,6 +1,22 @@
import RealmSwift
//
// VModel.swift
// AutoCatCore
//
// Created by Selim Mustafaev on 29.03.2022.
//
public final class VModel: Object, Decodable {
import Foundation
import CoreData
public struct VModel: Decodable {
@Persisted var name: VName?
let name: VName?
}
extension CDVModel {
convenience init(model: VModel?, context: NSManagedObjectContext) {
self.init(context: context)
self.name = CDVName(vname: model?.name, context: context)
}
}

View File

@ -1,7 +1,19 @@
import RealmSwift
import Foundation
import CoreData
public final class VName: Object, Decodable {
public struct VName: Decodable {
let normalized: String?
let original: String?
}
extension CDVName {
convenience init(vname: VName?, context: NSManagedObjectContext) {
self.init(context: context)
self.normalized = vname?.normalized
self.original = vname?.original
}
@Persisted public var normalized: String?
@Persisted public var original: String?
}

View File

@ -1,9 +1,29 @@
import RealmSwift
//
// VNote.swift
// AutoCatCore
//
// Created by Selim Mustafaev on 02.04.2022.
//
public final class VNote: Object, Decodable {
import Foundation
import CoreData
public struct VNote: Decodable {
@Persisted var id: String?
@Persisted var user: String?
@Persisted var date: Double
@Persisted var text: String?
let id: String?
let user: String?
let date: Double
let text: String?
}
extension CDVNote {
convenience init(model: VNote?, context: NSManagedObjectContext) {
self.init(context: context)
self.id = model?.id
self.user = model?.user
self.date = model?.date ?? 0
self.text = model?.text
}
}

View File

@ -1,15 +1,41 @@
import RealmSwift
//
// VOsago.swift
// AutoCatCore
//
// Created by Selim Mustafaev on 02.04.2022.
//
public final class VOsago: Object, Decodable {
import Foundation
import CoreData
public struct VOsago: Decodable {
@Persisted var date: Double
@Persisted var number: String?
@Persisted var vin: String?
@Persisted var plateNumber: String?
@Persisted var name: String?
@Persisted var status: String?
@Persisted var restrictions: String?
@Persisted var insurant: String?
@Persisted var owner: String?
@Persisted var usageRegion: String?
let date: Double
let number: String?
let vin: String?
let plateNumber: String?
let name: String?
let status: String?
let restrictions: String?
let insurant: String?
let owner: String?
let usageRegion: String?
}
extension CDVOsago {
convenience init(model: VOsago?, context: NSManagedObjectContext) {
self.init(context: context)
self.date = model?.date ?? 0
self.number = model?.number
self.vin = model?.vin
self.plateNumber = model?.plateNumber
self.name = model?.name
self.status = model?.status
self.restrictions = model?.restrictions
self.insurant = model?.insurant
self.owner = model?.owner
self.usageRegion = model?.usageRegion
}
}

View File

@ -1,16 +1,43 @@
import RealmSwift
//
// VOwnershipPeriod.swift
// AutoCatCore
//
// Created by Selim Mustafaev on 02.04.2022.
//
public final class VOwnershipPeriod: Object, Decodable {
import Foundation
import CoreData
public struct VOwnershipPeriod: Decodable {
@Persisted var lastOperation: String?
@Persisted var ownerType: String?
@Persisted var from: Int64?
@Persisted var to: Int64?
@Persisted var region: String?
@Persisted var registrationRegion: String?
@Persisted var locality: String?
@Persisted var code: String?
@Persisted var street: String?
@Persisted var building: String?
@Persisted var inn: String?
let lastOperation: String?
let ownerType: String?
let from: Int64?
let to: Int64?
let region: String?
let registrationRegion: String?
let locality: String?
let code: String?
let street: String?
let building: String?
let inn: String?
}
extension CDVOwnershipPeriod {
convenience init(model: VOwnershipPeriod?, context: NSManagedObjectContext) {
self.init(context: context)
self.lastOperation = model?.lastOperation
self.ownerType = model?.ownerType
self.from = model?.from ?? 0
self.to = model?.to ?? 0
self.region = model?.region
self.registrationRegion = model?.registrationRegion
self.locality = model?.locality
self.code = model?.locality
self.street = model?.street
self.building = model?.building
self.inn = model?.inn
}
}

View File

@ -1,9 +1,29 @@
import RealmSwift
//
// VPhoto.swift
// AutoCatCore
//
// Created by Selim Mustafaev on 02.04.2022.
//
public final class VPhoto: Object, Decodable {
import Foundation
import CoreData
public struct VPhoto: Decodable {
@Persisted var brand: String?
@Persisted var model: String?
@Persisted var date: Double
@Persisted var url: String?
let brand: String?
let model: String?
let date: Double
let url: String?
}
extension CDVPhoto {
convenience init(model: VPhoto?, context: NSManagedObjectContext) {
self.init(context: context)
self.brand = model?.brand
self.model = model?.model
self.date = model?.date ?? 0
self.url = model?.url
}
}

View File

@ -1,57 +1,78 @@
import Foundation
import RealmSwift
import CoreData
protocol StorageServiceProtocol {
func store(vehicle: Vehicle) throws
var context: NSManagedObjectContext { get }
func store(vehicle: Vehicle) throws -> CDVehicle
}
public class StorageService: StorageServiceProtocol {
public enum StorageError: String, LocalizedError {
case openDatabaseError = "Ошибка открытия БД"
public var errorDescription: String? {
rawValue
}
}
private static var instance: StorageService?
private let realm: Realm
private let container: NSPersistentCloudKitContainer
public static var shared: StorageService {
get throws {
get async throws {
if let instance = StorageService.instance {
return instance
} else {
if let service = StorageService(inMemory: Testing.isUITesting) {
StorageService.instance = service
return service
} else {
throw StorageError.openDatabaseError
}
let service = StorageService(inMemory: Testing.isUITesting)
try await service.loadPersistentStores()
StorageService.instance = service
return service
}
}
}
init?(inMemory: Bool = false) {
let config = Realm.Configuration(inMemoryIdentifier: inMemory ? "memory" : nil)
init(inMemory: Bool = false) {
guard let realm = try? Realm(configuration: config) else {
return nil
let bundle = Bundle(for: Self.self)
let url = bundle.url(forResource: "AutoCat2", withExtension: "momd")
let mom = NSManagedObjectModel(contentsOf: url!)
container = NSPersistentCloudKitContainer(name: "AutoCat2", managedObjectModel: mom!)
if inMemory {
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
}
}
private func loadPersistentStores() async throws {
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, Error>) in
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
continuation.resume(throwing: error)
} else {
continuation.resume(returning: ())
}
})
}
}
private func save() throws {
guard context.hasChanges else {
return
}
self.realm = realm
do {
try context.save()
} catch {
context.rollback()
throw error
}
}
// MARK: - StorageServiceProtocol
public func store(vehicle: Vehicle) throws {
public var context: NSManagedObjectContext {
container.viewContext
}
public func store(vehicle: Vehicle) throws -> CDVehicle {
try realm.write {
realm.add(vehicle, update: .all)
}
let cdVehicle = CDVehicle(vehicle: vehicle, context: context)
try save()
return cdVehicle
}
}

View File

@ -2,7 +2,7 @@ import Foundation
protocol VehicleServiceProtocol {
func check(plateNumber: String, force: Bool) async throws -> Vehicle
func check(plateNumber: String, force: Bool) async throws -> CDVehicle
}
public class VehicleService: VehicleServiceProtocol {
@ -11,8 +11,8 @@ public class VehicleService: VehicleServiceProtocol {
private let storage: StorageServiceProtocol
public static var shared: VehicleService {
get throws {
let storageService = try StorageService.shared
get async throws {
let storageService = try await StorageService.shared
return VehicleService(api: Api.shared, storage: storageService)
}
}
@ -25,13 +25,11 @@ public class VehicleService: VehicleServiceProtocol {
// MARK: - VehicleServiceProtocol
@MainActor
@discardableResult
public func check(plateNumber: String, force: Bool) async throws -> Vehicle {
public func check(plateNumber: String, force: Bool) async throws -> CDVehicle {
let vehicle = try await api.check(plateNumber: plateNumber, force: force)
try storage.store(vehicle: vehicle)
return vehicle
return try storage.store(vehicle: vehicle)
}
}

View File

@ -10,9 +10,9 @@ import Foundation
public class TestSettings: SettingsProtocol {
public var user: User = User()
public var recognizeAlternativeOrder: Bool = false
public var recognizeShortenedNumbers: Bool = false
public var defaultRegion: String = ""
public var recordBeep: Bool = false
public var showDebugInfo: Bool = false
public init() {
}
}

View File

@ -10,11 +10,11 @@ public protocol ApiProtocol {
public class Api: ApiProtocol {
private let session: URLSession
private let settings: any SettingsProtocol
private let settings: SettingsProtocol
public static let shared = Api()
public init(session: URLSession? = nil, settings: any SettingsProtocol = MainSettings.shared) {
public init(session: URLSession? = nil, settings: SettingsProtocol = Settings.shared) {
self.settings = settings
@ -39,7 +39,7 @@ public class Api: ApiProtocol {
// MARK: - Private wrappres
private func createRequest(api: String, method: String, body: (some Encodable)? = nil, params: [String: some LosslessStringConvertible]? = nil) -> URLRequest? {
private func createRequest<B,P>(api: String, method: String, body: B? = nil, params: [String:P]? = nil) -> URLRequest? where B: Encodable, P: LosslessStringConvertible {
guard var urlComponents = URLComponents(string: Constants.baseUrl + api) else { return nil }
if let params = params, method.uppercased() == "GET" {
@ -63,7 +63,7 @@ public class Api: ApiProtocol {
return request
}
private func makeRequest<T>(api: String, method: String = "GET", body: (some Encodable)?, params: [String: some LosslessStringConvertible]? = nil) async throws -> T where T: Decodable {
private func makeRequest<T,B,P>(api: String, method: String = "GET", body: B?, params: [String:P]? = nil) async throws -> T where T: Decodable, B: Encodable, P: LosslessStringConvertible {
guard let request = self.createRequest(api: api, method: method, body: body, params: params) else {
throw ApiError.message("Error creating request")
}
@ -116,7 +116,7 @@ public class Api: ApiProtocol {
}
}
private func makeGetRequest<T>(api: String, params:[String: some LosslessStringConvertible]? = nil) async throws -> T where T: Decodable {
private func makeGetRequest<T,P>(api: String, params:[String: P]? = nil) async throws -> T where T: Decodable, P: LosslessStringConvertible {
return try await self.makeRequest(api: api, method: "GET", body: nil as Int?, params: params)
}
@ -128,7 +128,7 @@ public class Api: ApiProtocol {
return try await self.makeRequest(api: api, method: method, body: nil as Int?, params: nil as [String:Int]?)
}
private func makeBodyRequest<T>(api: String, body: (some Encodable)?, method: String = "POST") async throws -> T where T: Decodable {
private func makeBodyRequest<T,B>(api: String, body: B?, method: String = "POST") async throws -> T where T: Decodable, B: Encodable {
return try await self.makeRequest(api: api, method: method, body: body, params: nil as [String:Int]?)
}

View File

@ -4,7 +4,7 @@ public struct Constants {
public static var baseUrl: String {
#if DEBUG
return "http://127.0.0.1:3000/"
//return "http://192.168.1.1:3000/"
//return "http://192.168.1.67:3000/"
//return "https://vps.aliencat.pro:8443/"
#else
return "https://vps.aliencat.pro:8443/"

View File

@ -22,7 +22,7 @@ class SettingsTests: XCTestCase {
throw TestError.createDefaultsFailed
}
userDefaults.removePersistentDomain(forName: #file)
self.settings = MainSettings(defaults: userDefaults)
self.settings = Settings(defaults: userDefaults)
}
override func tearDownWithError() throws {