├── .gitignore ├── Cartfile ├── Cartfile.resolved ├── Carthage └── Checkouts │ └── OGSwitch │ ├── .gitignore │ ├── LICENSE │ ├── OGSwitch-Demo.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ ├── OGSwitch.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ ├── OGSwitch │ ├── OGSwitch.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── OGSwitch.xcscheme │ └── OGSwitch │ │ ├── Info.plist │ │ ├── OGSwitch.h │ │ └── OGSwitch.swift │ ├── OGSwitchDemo │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ ├── Contents.json │ │ └── checkmark.imageset │ │ │ ├── Contents.json │ │ │ ├── checkmark.png │ │ │ └── checkmark@2x.png │ ├── Base.lproj │ │ └── MainMenu.xib │ └── Info.plist │ ├── README.md │ └── screenshot.jpg ├── Common ├── Constants.swift ├── Extensions.swift └── Protocols.swift ├── Extensions ├── Data+Omni.swift └── String+Omni.swift ├── HelperTool ├── HelperTool-Info.plist ├── HelperTool.swift ├── HelperTool │ └── main.swift ├── Launchd.plist ├── XPCServer.swift └── main.swift ├── LICENSE ├── Menus ├── ContentMenuItem.swift ├── DetailMenuItem.swift ├── NetworkMenuItem.swift ├── OmniMainMenu.swift └── OmniMenuItem.swift ├── Models ├── AuthModel.swift ├── DeviceModel.swift ├── DeviceRegisterModel.swift ├── JoinDeviceModel.swift ├── Response.swift ├── ServerModel.swift ├── UserModel.swift └── VirtualNetworkModel.swift ├── Omniedge.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcshareddata │ └── xcschemes │ │ ├── HelperTool.xcscheme │ │ └── Omniedge.xcscheme └── xcuserdata │ └── kidy.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── Omniedge ├── AppDelegate.swift ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ ├── 1024.png │ │ ├── 128.png │ │ ├── 16.png │ │ ├── 256.png │ │ ├── 32.png │ │ ├── 512.png │ │ ├── 64.png │ │ └── Contents.json │ ├── Connected.imageset │ │ ├── 16.png │ │ ├── 32.png │ │ ├── 64.png │ │ └── Contents.json │ ├── Contents.json │ ├── Disconnected.imageset │ │ ├── 16.png │ │ ├── 32.png │ │ ├── 64.png │ │ └── Contents.json │ └── StatusBarIcon.imageset │ │ ├── Contents.json │ │ ├── White.png │ │ └── White@2x.png ├── Base.lproj │ └── Main.storyboard ├── BugsnagReportApplication.swift ├── DeviceInfo.swift ├── GCDWebServers.framework.dSYM │ └── Contents │ │ ├── Info.plist │ │ └── Resources │ │ └── DWARF │ │ └── GCDWebServers ├── Info.plist ├── OAuth2.framework.dSYM │ └── Contents │ │ ├── Info.plist │ │ └── Resources │ │ └── DWARF │ │ └── OAuth2 ├── OGSwitch.framework.dSYM │ └── Contents │ │ ├── Info.plist │ │ └── Resources │ │ └── DWARF │ │ └── OGSwitch ├── Omniedge.entitlements ├── Sparkle.framework.dSYM │ └── Contents │ │ ├── Info.plist │ │ └── Resources │ │ └── DWARF │ │ └── Sparkle ├── SwitchViewController.swift └── success.html ├── README.md ├── SMJobBlessReadMe.txt ├── SMJobBlessUtil.py ├── Services ├── AppService.swift ├── AuthService.swift ├── BaseService.swift ├── CacheService.swift ├── HttpService.swift ├── IService.swift ├── LocatorService.swift ├── OmniService.swift ├── VirtualNetworkService.swift └── XPCService.swift ├── Sparkle.framework ├── Headers ├── Modules ├── PrivateHeaders ├── Resources ├── Sparkle └── Versions │ ├── A │ ├── Headers │ │ ├── SPUDownloadData.h │ │ ├── SPUDownloader.h │ │ ├── SPUDownloaderDelegate.h │ │ ├── SPUDownloaderDeprecated.h │ │ ├── SPUDownloaderProtocol.h │ │ ├── SPUDownloaderSession.h │ │ ├── SPUURLRequest.h │ │ ├── SUAppcast.h │ │ ├── SUAppcastItem.h │ │ ├── SUCodeSigningVerifier.h │ │ ├── SUErrors.h │ │ ├── SUExport.h │ │ ├── SUStandardVersionComparator.h │ │ ├── SUUpdater.h │ │ ├── SUUpdaterDelegate.h │ │ ├── SUVersionComparisonProtocol.h │ │ ├── SUVersionDisplayProtocol.h │ │ └── Sparkle.h │ ├── Modules │ │ └── module.modulemap │ ├── PrivateHeaders │ │ └── SUUnarchiver.h │ ├── Resources │ │ ├── DarkAqua.css │ │ ├── Info.plist │ │ ├── SUModelTranslation.plist │ │ ├── SUStatus.nib │ │ ├── ar.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── ca.lproj │ │ │ └── Sparkle.strings │ │ ├── cs.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── da.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── de.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── el.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── en.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── es.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── fi.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── fr.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── fr_CA.lproj │ │ ├── he.lproj │ │ │ └── Sparkle.strings │ │ ├── hr.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── hu.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── is.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── it.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── ja.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── ko.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── nb.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── nl.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── pl.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── pt.lproj │ │ ├── pt_BR.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── pt_PT.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── ro.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── ru.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── sk.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── sl.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── sv.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── th.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── tr.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── uk.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ ├── zh_CN.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ │ └── zh_TW.lproj │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ ├── SUUpdateAlert.nib │ │ │ ├── SUUpdatePermissionPrompt.nib │ │ │ └── Sparkle.strings │ ├── Sparkle │ └── _CodeSignature │ │ └── CodeResources │ └── Current ├── Utils ├── OmError.swift └── Utils.swift ├── Views ├── BaseView.swift ├── NetworkItemDetailView.swift ├── NetworkItemView.swift ├── OmniButtonCell.swift └── OmniLabel.swift ├── appdmg.json └── uninstall.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/macos,xcode,carthage 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=macos,xcode,carthage 3 | 4 | ### Carthage ### 5 | # Carthage 6 | # 7 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 8 | # Carthage/Checkouts 9 | 10 | Carthage/Build 11 | Carthage/Checkouts 12 | 13 | ### macOS ### 14 | # General 15 | .DS_Store 16 | .AppleDouble 17 | .LSOverride 18 | 19 | # Icon must end with two \r 20 | Icon 21 | 22 | 23 | # Thumbnails 24 | ._* 25 | 26 | # Files that might appear in the root of a volume 27 | .DocumentRevisions-V100 28 | .fseventsd 29 | .Spotlight-V100 30 | .TemporaryItems 31 | .Trashes 32 | .VolumeIcon.icns 33 | .com.apple.timemachine.donotpresent 34 | 35 | # Directories potentially created on remote AFP share 36 | .AppleDB 37 | .AppleDesktop 38 | Network Trash Folder 39 | Temporary Items 40 | .apdisk 41 | 42 | ### Xcode ### 43 | # Xcode 44 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 45 | 46 | ## User settings 47 | */xcuserdata/ 48 | 49 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 50 | *.xcscmblueprint 51 | *.xccheckout 52 | 53 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 54 | build/ 55 | DerivedData/ 56 | *.moved-aside 57 | *.pbxuser 58 | !default.pbxuser 59 | *.mode1v3 60 | !default.mode1v3 61 | *.mode2v3 62 | !default.mode2v3 63 | *.perspectivev3 64 | !default.perspectivev3 65 | 66 | ## Gcc Patch 67 | /*.gcno 68 | 69 | ### Xcode Patch ### 70 | *.xcodeproj/* 71 | !*.xcodeproj/project.pbxproj 72 | !*.xcodeproj/xcshareddata/ 73 | !*.xcworkspace/contents.xcworkspacedata 74 | **/xcshareddata/WorkspaceSettings.xcsettings 75 | 76 | # End of https://www.toptal.com/developers/gitignore/api/macos,xcode,carthage 77 | Carthage 78 | -------------------------------------------------------------------------------- /Cartfile: -------------------------------------------------------------------------------- 1 | github "OskarGroth/OGSwitch" ~> 2.0 2 | github "p2/OAuth2" ~> 4.2 3 | github "swisspol/GCDWebServer" ~> 3.5.4 4 | github "Alamofire/Alamofire" 5 | -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "Alamofire/Alamofire" "5.6.1" 2 | github "OskarGroth/OGSwitch" "2.9.2" 3 | github "p2/OAuth2" "4.2.0" 4 | github "swisspol/GCDWebServer" "3.5.4" 5 | -------------------------------------------------------------------------------- /Carthage/Checkouts/OGSwitch/.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xccheckout 23 | *.xcscmblueprint 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | *.ipa 28 | *.dSYM.zip 29 | *.dSYM 30 | 31 | ## Playgrounds 32 | timeline.xctimeline 33 | playground.xcworkspace 34 | 35 | # Swift Package Manager 36 | # 37 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 38 | # Packages/ 39 | # Package.pins 40 | # Package.resolved 41 | .build/ 42 | 43 | # CocoaPods 44 | # 45 | # We recommend against adding the Pods directory to your .gitignore. However 46 | # you should judge for yourself, the pros and cons are mentioned at: 47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 48 | # 49 | # Pods/ 50 | # 51 | # Add this line if you want to avoid checking in source code from the Xcode workspace 52 | # *.xcworkspace 53 | 54 | # Carthage 55 | # 56 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 57 | # Carthage/Checkouts 58 | 59 | Carthage/Build 60 | 61 | # fastlane 62 | # 63 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 64 | # screenshots whenever they are needed. 65 | # For more information about the recommended setup visit: 66 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 67 | 68 | fastlane/report.xml 69 | fastlane/Preview.html 70 | fastlane/screenshots/**/*.png 71 | fastlane/test_output 72 | -------------------------------------------------------------------------------- /Carthage/Checkouts/OGSwitch/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Oskar Groth 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /Carthage/Checkouts/OGSwitch/OGSwitch-Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Carthage/Checkouts/OGSwitch/OGSwitch-Demo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Carthage/Checkouts/OGSwitch/OGSwitch.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Carthage/Checkouts/OGSwitch/OGSwitch.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Carthage/Checkouts/OGSwitch/OGSwitch/OGSwitch.xcodeproj/xcshareddata/xcschemes/OGSwitch.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Carthage/Checkouts/OGSwitch/OGSwitch/OGSwitch/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSHumanReadableCopyright 22 | Copyright © 2018 Oskar Groth. All rights reserved. 23 | 24 | 25 | -------------------------------------------------------------------------------- /Carthage/Checkouts/OGSwitch/OGSwitch/OGSwitch/OGSwitch.h: -------------------------------------------------------------------------------- 1 | // 2 | // OGSwitch.h 3 | // OGSwitch 4 | // 5 | // Created by Oskar Groth on 2018-07-14. 6 | // Copyright © 2018 Oskar Groth. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for OGSwitch. 12 | FOUNDATION_EXPORT double OGSwitchVersionNumber; 13 | 14 | //! Project version string for OGSwitch. 15 | FOUNDATION_EXPORT const unsigned char OGSwitchVersionString[]; 16 | -------------------------------------------------------------------------------- /Carthage/Checkouts/OGSwitch/OGSwitchDemo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // OGSwitchDemo 4 | // 5 | // Created by Oskar Groth on 2017-02-22. 6 | // Copyright © 2017 Oskar Groth. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import OGSwitch 11 | 12 | @NSApplicationMain 13 | class AppDelegate: NSObject, NSApplicationDelegate { 14 | 15 | @IBOutlet weak var window: NSWindow! 16 | @IBOutlet weak var switchButton: OGSwitch! 17 | 18 | func applicationDidFinishLaunching(_ aNotification: Notification) { 19 | // Insert code here to initialize your application 20 | } 21 | 22 | func applicationWillTerminate(_ aNotification: Notification) { 23 | // Insert code here to tear down your application 24 | } 25 | 26 | @IBAction func switchPress(_ sender: Any) { 27 | NSLog("Switch is now: \((sender as! OGSwitch).isOn)") 28 | // perform(#selector(timer), with: nil, afterDelay: 3) 29 | } 30 | 31 | @objc func timer() { 32 | NSLog("Switch is after timer trigger now: \(switchButton.isOn)") 33 | // switchButton.setOn(isOn: !switchButton.isOn, animated: false) 34 | } 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /Carthage/Checkouts/OGSwitch/OGSwitchDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "mac", 5 | "size" : "16x16", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "mac", 10 | "size" : "16x16", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "mac", 15 | "size" : "32x32", 16 | "scale" : "1x" 17 | }, 18 | { 19 | "idiom" : "mac", 20 | "size" : "32x32", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "idiom" : "mac", 25 | "size" : "128x128", 26 | "scale" : "1x" 27 | }, 28 | { 29 | "idiom" : "mac", 30 | "size" : "128x128", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "idiom" : "mac", 35 | "size" : "256x256", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "mac", 40 | "size" : "256x256", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "mac", 45 | "size" : "512x512", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "mac", 50 | "size" : "512x512", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /Carthage/Checkouts/OGSwitch/OGSwitchDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Carthage/Checkouts/OGSwitch/OGSwitchDemo/Assets.xcassets/checkmark.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "checkmark.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "checkmark@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "version" : 1, 20 | "author" : "xcode" 21 | } 22 | } -------------------------------------------------------------------------------- /Carthage/Checkouts/OGSwitch/OGSwitchDemo/Assets.xcassets/checkmark.imageset/checkmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Carthage/Checkouts/OGSwitch/OGSwitchDemo/Assets.xcassets/checkmark.imageset/checkmark.png -------------------------------------------------------------------------------- /Carthage/Checkouts/OGSwitch/OGSwitchDemo/Assets.xcassets/checkmark.imageset/checkmark@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Carthage/Checkouts/OGSwitch/OGSwitchDemo/Assets.xcassets/checkmark.imageset/checkmark@2x.png -------------------------------------------------------------------------------- /Carthage/Checkouts/OGSwitch/OGSwitchDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleVersion 22 | 1 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | Copyright © 2017 Oskar Groth. All rights reserved. 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /Carthage/Checkouts/OGSwitch/README.md: -------------------------------------------------------------------------------- 1 | OGSwitch 2 | ================== 3 | 4 | Layer based Switch Control for macOS, with Interface Builder styling options. Written in Swift. 5 | 6 | Supports animation, custom aspect ratios, and knob images. 7 | 8 | This is a `NSView` subclass that lets you create beautiful iOS-inspired switches easily. 9 | 10 | ![OGSwitch for macOS](https://s3.amazonaws.com/cindori/images/ogswitch.png "OGSwitch for macOS") 11 | 12 | `OGSwitch` now also supports `IBDesignable` and renders directly in Interface Builder: 13 | 14 | ![IBDesignable](https://i.imgur.com/BKUyWGg.png "IBDesignable") 15 | 16 | 17 | ## Installation (Carthage) 18 | Configure your Cartfile to use `OGSwitch`: 19 | 20 | ```github "OskarGroth/OGSwitch" ~> 2.0``` 21 | 22 | `OGSwitch` requires Swift 4.2. 23 | 24 | ## Usage 25 | 26 | Create a custom `NSView` in Interface Builder and set it's class to `OGSwitch`. 27 | You can now style your switch from the inspector: 28 | 29 | ![OGSwitch for macOS](https://s3.amazonaws.com/cindori/images/inspector-ogswitch.png "OGSwitch for macOS") 30 | 31 | The same values can be accessed from your code. 32 | 33 | ## Credits 34 | 35 | Inspired by ITSwitch by Ilija Tovilo. 36 | 37 | ## License 38 | The MIT License (MIT) 39 | 40 | Copyright (c) 2018 Oskar Groth 41 | 42 | Permission is hereby granted, free of charge, to any person obtaining a copy of 43 | this software and associated documentation files (the "Software"), to deal in 44 | the Software without restriction, including without limitation the rights to 45 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 46 | the Software, and to permit persons to whom the Software is furnished to do so, 47 | subject to the following conditions: 48 | 49 | The above copyright notice and this permission notice shall be included in all 50 | copies or substantial portions of the Software. 51 | 52 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 53 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 54 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 55 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 56 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 57 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 58 | -------------------------------------------------------------------------------- /Carthage/Checkouts/OGSwitch/screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Carthage/Checkouts/OGSwitch/screenshot.jpg -------------------------------------------------------------------------------- /Common/Constants.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Constants.swift 3 | // Omniedge 4 | // 5 | // Created by An Li on 2021/1/17. 6 | // 7 | 8 | import Foundation 9 | import AppKit 10 | 11 | struct XPCConstant { 12 | static let HelperMachLabel = "io.omniedge.mac.Omniedge.HelperTool" 13 | static let HelperToolVersion = "100001" 14 | 15 | } 16 | 17 | let AppBuildIdentifier="io.omniedge.mac.Omniedge" 18 | 19 | struct CryptoConstants{ 20 | static let PrivateStoreKey = "io.omniedge.mac.Omniedge.private" 21 | static let PublicStoreKey = "io.omniedge.mac.Omniedge.public" 22 | 23 | } 24 | 25 | struct UserDefaultKeys{ 26 | 27 | static let AutoLaunch = "io.omniedge.mac.autolaunch" 28 | static let AutoUpdate = "io.omniedge.mac.autoupdate" 29 | static let IDToken = "io.omniedge.mac.id.token" 30 | static let NetworkStatus = "io.omniedge.mac.network.status" 31 | static let DeviceUUID = "io.omniedge.mac.device.UUID" 32 | static let NetworkConfig = "io.omniedge.mac.network.config" 33 | static let PublicKey = "io.omniedge.mac.publickey" 34 | static let Ping = "io.omniedge.mac.ping" 35 | 36 | static let JoinedDevice = "io.omniedge.mac.device.joined" 37 | static let RegisterDevice = "io.omniedge.mac.device.reg" 38 | } 39 | 40 | 41 | struct BackEndConstants{ 42 | 43 | static let ClientID = "274vpj278u5j7njhb9up99ibi8" 44 | static let ClientSecret = "t98n31jmusc3ucci7rql4ojodg7daehjv1nln586p60eu2k4pql" 45 | 46 | static let TokenURL = "https://auth-dev.edgecomputing.network/oauth2/token" 47 | static let LoginURL = "https://auth-dev.edgecomputing.network/login" 48 | static let CallBackURL = "http://localhost:8080/" 49 | static let Scope = "email+openid+phone+profile" 50 | 51 | static let GraphqlEndpoint = "https://nhgt5ptb5fhjzgu6qmwf76hhka.appsync-api.us-east-2.amazonaws.com/graphql" 52 | 53 | // static let RestJoin = "https://3b0loh21sb.execute-api.us-east-2.amazonaws.com/dev" 54 | static let baseApiEndPoint = "https://dev-api.omniedge.io/api/v1/" 55 | static let RestJoin = "https://3b0loh21sb.execute-api.us-east-2.amazonaws.com/dev" 56 | 57 | static let DeviceQuery = """ 58 | {"query":"query { listVirtualNetworks { items { id ipPrefix communityName devices { items { id name virtualIP description } } } }}","variables":{}} 59 | """ 60 | } 61 | 62 | struct ApiEndPoint { 63 | 64 | // // dev 65 | // static let baseApi = "https://dev-api.omniedge.io/api/v1/" 66 | // static let wsEndPoint = "wss://dev-wss.omniedge.io" 67 | 68 | // prod 69 | static let baseApi = "https://api.omniedge.io/api/v1/" 70 | static let wsEndPoint = "wss://wss.omniedge.io" 71 | 72 | static let authSession = "auth/login/session" 73 | static let virtualNetworkList = "virtual-networks/" 74 | static let registerDevice = "devices/register" 75 | } 76 | 77 | let OAuth2AppDidReceiveCallbackNotification = NSNotification.Name(rawValue: "OAuth2AppDidReceiveCallback") 78 | 79 | struct OmniError: Error { 80 | let errorCode: Int 81 | let message: String? 82 | } 83 | 84 | 85 | struct Constants { 86 | struct Colors { 87 | static let textColorInDarkMode = NSColor(red: 0xDA/0xFF, green: 0xDA/0xFF, blue: 0xDA/0xFF, alpha: 1.0) 88 | static let textColorInLightMode = NSColor(red: 0x6C/0xFF, green: 0x6C/0xFF, blue: 0x6C/0xFF, alpha: 1.0) 89 | 90 | static let C_F1F1F1 = NSColor(red: 0xF1/0xFF, green: 0xF1/0xFF, blue: 0xF1/0xFF, alpha: 1.0) 91 | static let C_6C6C6C = NSColor(red: 0x6C/0xFF, green: 0x6C/0xFF, blue: 0x6C/0xFF, alpha: 1.0) 92 | static let C_3D3D3D = NSColor(red: 0x3D/0xFF, green: 0x3D/0xFF, blue: 0x3D/0xFF, alpha: 1.0) 93 | } 94 | 95 | struct Margins { 96 | static let margin5: CGFloat = 5.0 97 | static let margin10: CGFloat = 10.0 98 | static let margin15: CGFloat = 15.0 99 | } 100 | 101 | struct Size { 102 | static let menuItemWidth233: CGFloat = 233 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /Common/Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Extensions.swift 3 | // Omniedge 4 | // 5 | // Created by An Li on 2021/2/4. 6 | // 7 | 8 | import Foundation 9 | import Cocoa 10 | extension URL { 11 | public var queryParameters: [String: String]? { 12 | guard 13 | let components = URLComponents(url: self, resolvingAgainstBaseURL: true), 14 | let queryItems = components.queryItems else { return nil } 15 | return queryItems.reduce(into: [String: String]()) { (result, item) in 16 | result[item.name] = item.value 17 | } 18 | } 19 | } 20 | 21 | 22 | extension NSControl.StateValue{ 23 | 24 | public func toBool() -> Bool{ 25 | return self == .on 26 | } 27 | 28 | public func toggle() -> NSControl.StateValue{ 29 | return self == .on ? .off: .on 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /Common/Protocols.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Protocols.swift 3 | // Omniedge 4 | // 5 | // Created by An Li on 2021/1/17. 6 | // 7 | 8 | 9 | import Foundation 10 | 11 | @objc(HelperTool) 12 | protocol HelperTool { 13 | 14 | func version(completion: @escaping(String) -> Void) // change to check version instead of check alive after first release. 15 | func isConnect(completion: @escaping(Bool) -> Void) 16 | 17 | func connect(_ networkConfig: Data, completion: @escaping (Error?)->Void) 18 | func disconnect() 19 | } 20 | 21 | -------------------------------------------------------------------------------- /Extensions/Data+Omni.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Data+Omni.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 18/7/2022. 6 | // 7 | 8 | import Foundation 9 | 10 | extension Data { 11 | 12 | func printJson() { 13 | do { 14 | let json = try JSONSerialization.jsonObject(with: self, options: []) 15 | let data = try JSONSerialization.data(withJSONObject: json, options: .prettyPrinted) 16 | guard let jsonString = String(data: data, encoding: .utf8) else { 17 | print("Inavlid data") 18 | return 19 | } 20 | print(jsonString) 21 | } catch { 22 | print("Error: \(error.localizedDescription)") 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Extensions/String+Omni.swift: -------------------------------------------------------------------------------- 1 | // 2 | // String+Omni.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 12/8/2022. 6 | // 7 | 8 | import Foundation 9 | extension String { 10 | static let Empty: String = "" 11 | } 12 | -------------------------------------------------------------------------------- /HelperTool/HelperTool-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleExecutable 6 | 7 | CFBundleIdentifier 8 | io.omniedge.mac.Omniedge.HelperTool 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundleName 12 | HelperTool 13 | CFBundleVersion 14 | $(CURRENT_PROJECT_VERSION) 15 | SMAuthorizedClients 16 | 17 | identifier "io.omniedge.mac.Omniedge" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Yanbo Dang (HY4FX274Q4)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */ 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /HelperTool/HelperTool.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HelperTool.swift 3 | // HelperTool 4 | // 5 | // Created by An Li on 2021/1/17. 6 | // 7 | 8 | import Foundation 9 | import n2nMacOS 10 | 11 | var keepRunning: Int32 = 1 12 | var isConnected = false 13 | 14 | class HelperToolImpl: HelperTool{ 15 | 16 | func isConnect(completion: @escaping (Bool) -> Void) { 17 | completion(keepRunning == 1 && isConnected) 18 | } 19 | 20 | func version(completion: @escaping (String) -> Void) { 21 | 22 | let buildNumber = Bundle.main.object(forInfoDictionaryKey: kCFBundleVersionKey as String) as! String 23 | completion(buildNumber) 24 | } 25 | 26 | 27 | private var searchingWorkItem: DispatchWorkItem? 28 | 29 | 30 | let decoder = JSONDecoder() 31 | 32 | func connect(_ networkConfig: Data, completion: @escaping (Error?)->Void){ 33 | NSLog("[SMJBS]: \(#function)") 34 | 35 | 36 | let config = try! decoder.decode(JoinDeviceMode.self, from: networkConfig) 37 | 38 | let deviceName = ProcessInfo.processInfo.hostName 39 | let communityName = config.communityName 40 | let encryptKey = config.secretKey 41 | var deviceMac = "DE:AD:BE:EF:F1:10" 42 | let localIP = config.virtualIp 43 | let superNode = config.server.host 44 | 45 | if let intfIterator = Utils.findEthernetInterfaces() { 46 | if let macAddress = Utils.getMACAddress(intfIterator) { 47 | let macAddressAsString = macAddress.map( { String(format:"%02x", $0) } ) 48 | .joined(separator: ":") 49 | deviceMac = macAddressAsString 50 | } 51 | 52 | IOObjectRelease(intfIterator) 53 | } 54 | 55 | NSLog("[SMJBS]: \(#function)") 56 | 57 | if(!isConnected){ 58 | searchingWorkItem = DispatchWorkItem { 59 | NSLog("[SMJBS]: edge start") 60 | isConnected = true 61 | keepRunning = 1 62 | quick_edge_init(deviceName, communityName, encryptKey, deviceMac, localIP, superNode, &keepRunning) 63 | NSLog("[SMJBS]: edge end") 64 | 65 | } 66 | DispatchQueue.global().async(execute: self.searchingWorkItem!) 67 | } 68 | 69 | completion(nil) 70 | 71 | NSLog("[SMJBS]: \(#function)") 72 | } 73 | func disconnect(){ 74 | NSLog("[SMJBS]: \(#function)") 75 | keepRunning = 0 76 | searchingWorkItem?.cancel() 77 | isConnected = false 78 | 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /HelperTool/HelperTool/main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // main.swift 3 | // HelperTool 4 | // 5 | // Created by An Li on 2021/1/17. 6 | // 7 | 8 | import Foundation 9 | 10 | print("Hello, World!") 11 | 12 | -------------------------------------------------------------------------------- /HelperTool/Launchd.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Label 6 | io.omniedge.mac.Omniedge.HelperTool 7 | MachServices 8 | 9 | io.omniedge.mac.Omniedge.HelperTool 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /HelperTool/XPCServer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // XPCServer.swift 3 | // HelperTool 4 | // 5 | // Created by An Li on 2021/1/17. 6 | // 7 | 8 | import Foundation 9 | 10 | class XPCServer: NSObject { 11 | 12 | internal static let shared = XPCServer() 13 | 14 | private var listener: NSXPCListener? 15 | 16 | internal func start() { 17 | listener = NSXPCListener(machServiceName: XPCConstant.HelperMachLabel) 18 | listener?.delegate = self 19 | listener?.resume() 20 | } 21 | 22 | private func connetionInterruptionHandler() { 23 | NSLog("[SMJBS]: \(#function)") 24 | } 25 | 26 | private func connectionInvalidationHandler() { 27 | NSLog("[SMJBS]: \(#function)") 28 | } 29 | 30 | // private func isValidClient(forConnection connection: NSXPCConnection) -> Bool { 31 | // 32 | // var token = connection.auditToken; 33 | // let tokenData = Data(bytes: &token, count: MemoryLayout.size(ofValue:token)) 34 | // let attributes = [kSecGuestAttributeAudit : tokenData] 35 | // 36 | // // Check which flags you need 37 | // let flags: SecCSFlags = [] 38 | // var code: SecCode? = nil 39 | // var status = SecCodeCopyGuestWithAttributes(nil, attributes as CFDictionary, flags, &code) 40 | // 41 | // if status != errSecSuccess { 42 | // return false 43 | // } 44 | // 45 | // guard let dynamicCode = code else { 46 | // return false 47 | // } 48 | // // in this sample we duplicate the requirements from the Info.plist for simplicity 49 | // // in a commercial application you could want to put the requirements in one place, for example in Active Compilation Conditions (Swift), or in preprocessor definitions (C, Objective-C) 50 | // let entitlements = "identifier \"com.smjobblesssample.uiapplication\" and anchor apple generic and certificate leaf[subject.CN] = \"Mac Developer: mail@example.com (ABCDEFGHIJ)\"" 51 | // var requirement: SecRequirement? 52 | // 53 | // status = SecRequirementCreateWithString(entitlements as CFString, flags, &requirement) 54 | // 55 | // if status != errSecSuccess { 56 | // return false 57 | // } 58 | // 59 | // status = SecCodeCheckValidity(dynamicCode, flags, requirement) 60 | // 61 | // return status == errSecSuccess 62 | // } 63 | } 64 | 65 | extension XPCServer: NSXPCListenerDelegate { 66 | 67 | func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool { 68 | NSLog("[SMJBS]: \(#function)") 69 | 70 | // if (!isValidClient(forConnection: newConnection)) { 71 | // NSLog("[SMJBS]: Client is not valid") 72 | // return false 73 | // } 74 | 75 | NSLog("[SMJBS]: Client is valid") 76 | 77 | let helperTool = HelperToolImpl() 78 | 79 | newConnection.exportedInterface = NSXPCInterface(with: HelperTool.self) 80 | newConnection.exportedObject = helperTool 81 | 82 | newConnection.interruptionHandler = connetionInterruptionHandler 83 | newConnection.invalidationHandler = connectionInvalidationHandler 84 | 85 | newConnection.resume() 86 | 87 | return true 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /HelperTool/main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // main.swift 3 | // HelperTool 4 | // 5 | // Created by An Li on 2021/1/17. 6 | // 7 | 8 | import Foundation 9 | import n2nMacOS 10 | 11 | let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleVersion") as? String 12 | 13 | NSLog("Version:\(version ?? "None")") 14 | XPCServer.shared.start() 15 | RunLoop.current.run() 16 | 17 | -------------------------------------------------------------------------------- /Menus/ContentMenuItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentMenuItem.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 19/7/2022. 6 | // 7 | 8 | import Foundation 9 | import AppKit 10 | 11 | class ContentMenuItem: OmniMenuItem { 12 | 13 | override init() { 14 | super.init() 15 | self.initMenu() 16 | self.initLayout() 17 | } 18 | 19 | private func initMenu() { 20 | self.view = self.contentView 21 | } 22 | 23 | private func initLayout() { 24 | NSLayoutConstraint.activate([ 25 | self.contentView.widthAnchor.constraint(equalToConstant: Constants.Size.menuItemWidth233) 26 | ]) 27 | } 28 | 29 | // lazy loading 30 | lazy var contentView: NSView = { 31 | let view = NSView(frame: .zero) 32 | view.translatesAutoresizingMaskIntoConstraints = false 33 | return view 34 | }() 35 | } 36 | -------------------------------------------------------------------------------- /Menus/DetailMenuItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OmniDetailMenuItem.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 19/7/2022. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | class DetailMenuItem: ContentMenuItem { 12 | 13 | override var title: String { 14 | get { 15 | return self.titleLable.stringValue 16 | } 17 | set { 18 | self.titleLable.stringValue = newValue 19 | } 20 | } 21 | 22 | var detail: String { 23 | get { 24 | return self.detailLabel.stringValue 25 | } 26 | set { 27 | self.detailLabel.stringValue = newValue 28 | } 29 | } 30 | 31 | override init() { 32 | super.init() 33 | self.initMenu() 34 | self.initLayout() 35 | } 36 | 37 | convenience init(title: String) { 38 | self.init() 39 | self.title = title 40 | } 41 | 42 | private func initMenu() { 43 | self.contentView.addSubview(self.titleLable) 44 | self.contentView.addSubview(self.detailLabel) 45 | } 46 | 47 | private func initLayout() { 48 | NSLayoutConstraint.activate([ 49 | self.titleLable.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: Constants.Margins.margin10), 50 | self.titleLable.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: -Constants.Margins.margin10), 51 | self.titleLable.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: Constants.Margins.margin5), 52 | 53 | self.detailLabel.leadingAnchor.constraint(equalTo: self.titleLable.leadingAnchor), 54 | self.detailLabel.trailingAnchor.constraint(equalTo: self.titleLable.trailingAnchor), 55 | self.detailLabel.topAnchor.constraint(equalTo: self.titleLable.bottomAnchor, constant: Constants.Margins.margin5), 56 | self.detailLabel.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: -Constants.Margins.margin5) 57 | ]) 58 | } 59 | 60 | // lazy loading 61 | private lazy var titleLable: OmniLabel = { 62 | let view = OmniLabel() 63 | view.translatesAutoresizingMaskIntoConstraints = false 64 | return view 65 | }() 66 | 67 | private lazy var detailLabel: OmniLabel = { 68 | let view = OmniLabel() 69 | view.translatesAutoresizingMaskIntoConstraints = false 70 | // view.textColor = NSColor.gray 71 | return view 72 | }() 73 | } 74 | -------------------------------------------------------------------------------- /Menus/NetworkMenuItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkMenuItem.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 16/7/2022. 6 | // 7 | 8 | import Foundation 9 | import AppKit 10 | 11 | class NetworkMenuItem: OmniMenuItem { 12 | 13 | var networkService: IVirtualNetworkService? 14 | var cacheService: ICacheService? 15 | 16 | private var model: VirtualNetworkModel 17 | private var detailMenuView: NetworkItemDetailView? 18 | 19 | init(network: VirtualNetworkModel, networkService: IVirtualNetworkService) { 20 | self.model = network 21 | self.networkService = networkService 22 | super.init() 23 | self.initMenu() 24 | } 25 | 26 | 27 | private func initMenu() { 28 | self.title = model.vnName 29 | self.action = #selector(didNetworkSelected) 30 | self.target = self 31 | self.submenu = NSMenu() 32 | self.submenu?.delegate = self 33 | let menuItem = OmniMenuItem() 34 | self.detailMenuView = NetworkItemDetailView(model: self.model, enableConnection: !(self.networkService?.failedRegisteDev ?? false)) 35 | self.detailMenuView?.delegate = self 36 | menuItem.view = self.detailMenuView 37 | self.submenu?.addItem(menuItem) 38 | } 39 | 40 | @objc private func didNetworkSelected() { 41 | return 42 | } 43 | 44 | private func toggleOff() { 45 | DispatchQueue.main.async { 46 | self.detailMenuView?.toggleOff() 47 | } 48 | } 49 | } 50 | 51 | extension NetworkMenuItem: NetworItemDetailViewDelegate { 52 | func didToggled(on: Bool) { 53 | 54 | if !on { 55 | self.networkService?.disconnectNetwork() 56 | return 57 | } 58 | 59 | // join device first 60 | self.networkService?.joinDeviceInNetwork(vnId: self.model.vnId) 61 | 62 | } 63 | } 64 | 65 | extension NetworkMenuItem: NSMenuDelegate { 66 | func menuWillOpen(_ menu: NSMenu) { 67 | guard let curVnId = self.networkService?.curConnectedNetworkId else { 68 | return 69 | } 70 | 71 | if curVnId != self.model.vnId { 72 | self.toggleOff() 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Menus/OmniMenuItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OmniMenuItem.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 15/7/2022. 6 | // 7 | 8 | import Foundation 9 | import AppKit 10 | 11 | class OmniMenuItem: NSMenuItem { 12 | 13 | init() { 14 | super.init(title: String.Empty, action: nil, keyEquivalent: String.Empty) 15 | } 16 | 17 | override init(title string: String, action selector: Selector?, keyEquivalent charCode: String) { 18 | super.init(title: string, action: selector, keyEquivalent: charCode) 19 | } 20 | 21 | @available(*, unavailable) 22 | required init(coder: NSCoder) { 23 | fatalError("init(coder:) has not been implemented") 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Models/AuthModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AuthModel.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 16/7/2022. 6 | // 7 | 8 | import Foundation 9 | 10 | struct AuthModel: Decodable { 11 | 12 | let sessionId: String 13 | let authUrl: String 14 | let expiredDate: Date 15 | 16 | enum CodingKeys: String, CodingKey { 17 | case sessionId = "id" 18 | case authUrl = "auth_url" 19 | case expiredDate = "expired_at" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Models/DeviceModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DeviceModel.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 22/5/2022. 6 | // 7 | 8 | import Foundation 9 | 10 | struct DeviceModel: Codable { 11 | let deviceName: String 12 | let deviceUuid: String 13 | let deviceOS: String 14 | 15 | enum CodingKeys: String, CodingKey { 16 | case deviceName = "name" 17 | case deviceUuid = "hardware_uuid" 18 | case deviceOS = "platform" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Models/DeviceRegisterModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DeviceRegisterModel.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 3/6/2022. 6 | // 7 | 8 | import Foundation 9 | 10 | struct DeviceRegisterModel: Codable { 11 | let deviceId: String 12 | let hardwareId: String 13 | let platform: String 14 | let deviceName: String 15 | let createdOn: Date 16 | let ddbUuid: String? 17 | let virtualIp: String? 18 | 19 | enum CodingKeys: String, CodingKey { 20 | case deviceId = "id" 21 | case hardwareId = "hardware_id" 22 | case platform 23 | case deviceName = "name" 24 | case createdOn = "created_at" 25 | case ddbUuid = "ddb_uuid" 26 | case virtualIp = "virtual_ip" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Models/JoinDeviceModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JoinDeviceModel.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 4/6/2022. 6 | // 7 | 8 | import Foundation 9 | 10 | struct JoinDeviceMode: Codable { 11 | 12 | let communityName: String 13 | let secretKey: String 14 | let virtualIp: String 15 | let subnetMask: String 16 | let server: ServerThumbModel 17 | var vnName: String? 18 | var vnId: String? 19 | 20 | enum CodingKeys: String, CodingKey { 21 | case communityName = "community_name" 22 | case secretKey = "secret_key" 23 | case virtualIp = "virtual_ip" 24 | case subnetMask = "subnet_mask" 25 | case server 26 | case vnName 27 | case vnId 28 | } 29 | 30 | mutating func setVnName(vnName: String) { 31 | self.vnName = vnName 32 | } 33 | 34 | mutating func setVnId(vnId: String) { 35 | self.vnId = vnId 36 | } 37 | } 38 | 39 | struct ServerThumbModel: Codable { 40 | let name: String 41 | let host: String 42 | let country: String 43 | 44 | enum CodingKeys: String, CodingKey { 45 | case name 46 | case host 47 | case country 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Models/Response.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Response.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 16/7/2022. 6 | // 7 | 8 | import Foundation 9 | struct Response: Decodable { 10 | let code: Int 11 | let data: T? 12 | let message: String? 13 | 14 | enum CodingKeys: String, CodingKey { 15 | case code 16 | case data 17 | case message 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Models/ServerModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ServerModel.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 20/5/2022. 6 | // 7 | 8 | import Foundation 9 | 10 | struct ServerModel: Decodable { 11 | let serverId: String 12 | let serverName: String 13 | let hostAddr: String 14 | let countryCode: String? 15 | let type: Int 16 | 17 | enum CodingKeys: String, CodingKey { 18 | case serverId = "id" 19 | case serverName = "name" 20 | case hostAddr = "host" 21 | case countryCode = "country" 22 | case type 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Models/UserModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UserModel.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 20/5/2022. 6 | // 7 | 8 | import Foundation 9 | 10 | struct UserModel: Decodable { 11 | let userId: String 12 | let userName: String 13 | let email: String 14 | let userPicture: String? 15 | let lastLoginIPAddr: String? 16 | let lastLoginOn: Date 17 | let status: Int 18 | let createdOn: Date 19 | let changedOn: Date 20 | let cognitoId: String? 21 | let ddbUuid: String? 22 | let role: Int 23 | let joinedOn: Date 24 | 25 | enum CodingKeys: String, CodingKey { 26 | case userId = "id" 27 | case userName = "name" 28 | case email 29 | case userPicture = "picture" 30 | case lastLoginIPAddr = "last_login_ip" 31 | case lastLoginOn = "last_login_at" 32 | case status 33 | case createdOn = "created_at" 34 | case changedOn = "updated_at" 35 | case cognitoId = "cognito_id" 36 | case ddbUuid = "ddb_uuid" 37 | case role 38 | case joinedOn = "joined_at" 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /Models/VirtualNetworkModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VirtualNetworkModel.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 20/5/2022. 6 | // 7 | 8 | import Foundation 9 | 10 | struct VirtualNetworkModel: Decodable { 11 | let vnId:String 12 | let vnName: String 13 | let ipRange: String 14 | let ddbUuid:String? 15 | let server: ServerModel 16 | let devices: [DeviceRegisterModel]? 17 | let users: [UserModel] 18 | let role: Int 19 | let usersCount: Int 20 | let devicesCount: Int 21 | 22 | enum CodingKeys: String, CodingKey { 23 | case vnId = "id" 24 | case vnName = "name" 25 | case ipRange = "ip_range" 26 | case ddbUuid = "ddb_uuid" 27 | case server 28 | case devices 29 | case users 30 | case role 31 | case usersCount = "users_count" 32 | case devicesCount = "devices_count" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Omniedge.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Omniedge.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Omniedge.xcodeproj/xcshareddata/xcschemes/HelperTool.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Omniedge.xcodeproj/xcshareddata/xcschemes/Omniedge.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Omniedge.xcodeproj/xcuserdata/kidy.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | FileKit (Playground) 1.xcscheme 8 | 9 | isShown 10 | 11 | orderHint 12 | 4 13 | 14 | FileKit (Playground) 2.xcscheme 15 | 16 | isShown 17 | 18 | orderHint 19 | 5 20 | 21 | FileKit (Playground).xcscheme 22 | 23 | isShown 24 | 25 | orderHint 26 | 2 27 | 28 | HelperTool.xcscheme_^#shared#^_ 29 | 30 | orderHint 31 | 3 32 | 33 | Omniedge.xcscheme_^#shared#^_ 34 | 35 | orderHint 36 | 1 37 | 38 | io.omniedge.mac.Omniedge.XPC.xcscheme_^#shared#^_ 39 | 40 | orderHint 41 | 2 42 | 43 | 44 | SuppressBuildableAutocreation 45 | 46 | 0B7575B725B44FF900601DC7 47 | 48 | primary 49 | 50 | 51 | 0BB4142825C6A814005F3C98 52 | 53 | primary 54 | 55 | 56 | 0BBF0F7E25AB52FC001E9B2C 57 | 58 | primary 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /Omniedge/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Omniedge 4 | // 5 | // Created by An Li on 2021/1/10. 6 | // 7 | 8 | import Cocoa 9 | 10 | @available(macOS 10.15, *) 11 | @main 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | private var omniService: IOmniService! 15 | private var statusItem: NSStatusItem! 16 | 17 | func applicationWillFinishLaunching(_ notification: Notification) { 18 | let locatorService = LocatorService.shareInstance() 19 | self.registerServices(locatorService: locatorService) 20 | self.omniService = OmniService(locatorService: locatorService) 21 | self.omniService.initService() 22 | } 23 | 24 | func applicationDidFinishLaunching(_ notification: Notification) { 25 | 26 | self.statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength) 27 | self.statusItem?.button?.image = NSImage(named: "StatusBarIcon") 28 | self.statusItem.menu = OmniMainMenu(omniService: self.omniService) 29 | } 30 | 31 | func applicationWillTerminate(_ notification: Notification) { 32 | self.omniService.terminate() 33 | } 34 | 35 | func didLogin(login: Bool) { 36 | let imageName = login ? "Connected" : "Disconnected" 37 | self.statusItem.button?.image = NSImage(named: imageName) 38 | } 39 | } 40 | 41 | extension AppDelegate { 42 | 43 | private func registerServices(locatorService: ILocatorService){ 44 | locatorService.register(instance: HttpService() as IHttpService) 45 | locatorService.register(instance: XPCService() as IXPCService) 46 | locatorService.register(instance: CacheService() as ICacheService) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/Assets.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/AppIcon.appiconset/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/Assets.xcassets/AppIcon.appiconset/128.png -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/AppIcon.appiconset/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/Assets.xcassets/AppIcon.appiconset/16.png -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/AppIcon.appiconset/256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/Assets.xcassets/AppIcon.appiconset/256.png -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/AppIcon.appiconset/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/Assets.xcassets/AppIcon.appiconset/32.png -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/AppIcon.appiconset/512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/Assets.xcassets/AppIcon.appiconset/512.png -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/AppIcon.appiconset/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/Assets.xcassets/AppIcon.appiconset/64.png -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | {"images":[{"size":"128x128","expected-size":"128","filename":"128.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"256x256","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"128x128","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"256x256","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"512x512","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"16","filename":"16.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"64","filename":"64.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"512x512","expected-size":"1024","filename":"1024.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"}]} -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/Connected.imageset/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/Assets.xcassets/Connected.imageset/16.png -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/Connected.imageset/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/Assets.xcassets/Connected.imageset/32.png -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/Connected.imageset/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/Assets.xcassets/Connected.imageset/64.png -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/Connected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "16.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "32.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "64.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/Disconnected.imageset/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/Assets.xcassets/Disconnected.imageset/16.png -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/Disconnected.imageset/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/Assets.xcassets/Disconnected.imageset/32.png -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/Disconnected.imageset/64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/Assets.xcassets/Disconnected.imageset/64.png -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/Disconnected.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "16.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "32.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "64.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/StatusBarIcon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "White.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "White@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "author" : "xcode", 20 | "version" : 1 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/StatusBarIcon.imageset/White.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/Assets.xcassets/StatusBarIcon.imageset/White.png -------------------------------------------------------------------------------- /Omniedge/Assets.xcassets/StatusBarIcon.imageset/White@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/Assets.xcassets/StatusBarIcon.imageset/White@2x.png -------------------------------------------------------------------------------- /Omniedge/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Omniedge/BugsnagReportApplication.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BugsnagReportNSApplication.swift 3 | // Omniedge 4 | // 5 | // Created by An Li on 2021/3/26. 6 | // 7 | 8 | import Cocoa 9 | 10 | 11 | //@objc(BugsnagReportApplication) 12 | //class BugsnagReportApplication: NSApplication { 13 | // 14 | // func reportException(exception: NSException) { 15 | // Bugsnag.notify(exception) 16 | // super.reportException(exception) 17 | // } 18 | // 19 | //} 20 | -------------------------------------------------------------------------------- /Omniedge/DeviceInfo.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DeviceInfo.swift 3 | // Omniedge 4 | // 5 | // Created by An Li on 2021/2/17. 6 | // 7 | 8 | import Cocoa 9 | 10 | class DeviceInfoView: NSView { 11 | 12 | override func draw(_ dirtyRect: NSRect) { 13 | super.draw(dirtyRect) 14 | 15 | // Drawing code here. 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Omniedge/GCDWebServers.framework.dSYM/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleIdentifier 8 | com.apple.xcode.dsym.net.pol-online.GCDWebServers 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundlePackageType 12 | dSYM 13 | CFBundleSignature 14 | ???? 15 | CFBundleShortVersionString 16 | 3.5.4 17 | CFBundleVersion 18 | 3.5.4 19 | 20 | 21 | -------------------------------------------------------------------------------- /Omniedge/GCDWebServers.framework.dSYM/Contents/Resources/DWARF/GCDWebServers: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/GCDWebServers.framework.dSYM/Contents/Resources/DWARF/GCDWebServers -------------------------------------------------------------------------------- /Omniedge/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | io.omniedge.mac.Omniedge 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleURLTypes 22 | 23 | 24 | CFBundleTypeRole 25 | Editor 26 | CFBundleURLSchemes 27 | 28 | omniedge 29 | 30 | 31 | 32 | 33 | CFBundleVersion 34 | $(CURRENT_PROJECT_VERSION) 35 | LSApplicationCategoryType 36 | public.app-category.utilities 37 | LSMinimumSystemVersion 38 | $(MACOSX_DEPLOYMENT_TARGET) 39 | LSUIElement 40 | 41 | NSAppTransportSecurity 42 | 43 | NSAllowsArbitraryLoads 44 | 45 | 46 | NSMainStoryboardFile 47 | Main 48 | NSPrincipalClass 49 | NSApplication 50 | SMPrivilegedExecutables 51 | 52 | io.omniedge.mac.Omniedge.HelperTool 53 | identifier "io.omniedge.mac.Omniedge.HelperTool" and anchor apple generic and certificate leaf[subject.CN] = "Apple Development: Yanbo Dang (HY4FX274Q4)" and certificate 1[field.1.2.840.113635.100.6.2.1] /* exists */ 54 | 55 | bugsnag 56 | 57 | apiKey 58 | b7dbbb871e775ea83835f6560965cdd2 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /Omniedge/OAuth2.framework.dSYM/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleIdentifier 8 | com.apple.xcode.dsym.com.github.p2.OAuth2 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundlePackageType 12 | dSYM 13 | CFBundleSignature 14 | ???? 15 | CFBundleShortVersionString 16 | 3.0.3 17 | CFBundleVersion 18 | 1 19 | 20 | 21 | -------------------------------------------------------------------------------- /Omniedge/OAuth2.framework.dSYM/Contents/Resources/DWARF/OAuth2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/OAuth2.framework.dSYM/Contents/Resources/DWARF/OAuth2 -------------------------------------------------------------------------------- /Omniedge/OGSwitch.framework.dSYM/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleIdentifier 8 | com.apple.xcode.dsym.org.cindori.OGSwitch 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundlePackageType 12 | dSYM 13 | CFBundleSignature 14 | ???? 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleVersion 18 | 1 19 | 20 | 21 | -------------------------------------------------------------------------------- /Omniedge/OGSwitch.framework.dSYM/Contents/Resources/DWARF/OGSwitch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/OGSwitch.framework.dSYM/Contents/Resources/DWARF/OGSwitch -------------------------------------------------------------------------------- /Omniedge/Omniedge.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Omniedge/Sparkle.framework.dSYM/Contents/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleIdentifier 8 | com.apple.xcode.dsym.org.sparkle-project.Sparkle 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundlePackageType 12 | dSYM 13 | CFBundleSignature 14 | ???? 15 | CFBundleShortVersionString 16 | 1.24.0 17 | CFBundleVersion 18 | 1.24.0 19 | 20 | 21 | -------------------------------------------------------------------------------- /Omniedge/Sparkle.framework.dSYM/Contents/Resources/DWARF/Sparkle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Omniedge/Sparkle.framework.dSYM/Contents/Resources/DWARF/Sparkle -------------------------------------------------------------------------------- /Omniedge/SwitchViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwitchViewController.swift 3 | // Omniedge 4 | // 5 | // Created by An Li on 2021/1/24. 6 | // 7 | 8 | import Foundation 9 | import Cocoa 10 | 11 | class SwitchViewController: NSViewController{ 12 | 13 | } 14 | -------------------------------------------------------------------------------- /Omniedge/success.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | OmniEdge - Connect without concern 18 | 19 | 26 | 27 | 28 |
29 |
30 |
31 | Logo 32 |
33 | 34 |
35 |

lets you connect without concern whether running on any platform, any time, any where.

36 |

37 | Thank you for using Omniedge.
Please check us out on 38 | omniedge.io 39 |

40 | You can close this tab now. 41 |
42 |
43 | image 44 |
45 |
46 |
47 | 48 | 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OmniEdge-macOS 2 | 3 | The OmniEdge GUI version for macOS, API implementation is still understand developemnt. 4 | 5 | >Bring the intranet on the internet 6 | 7 | 8 | [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](http://www.gnu.org/licenses/gpl-3.0) 9 | 10 | [🤝 Website](https://omniedge.io) 11 | [💬 Twitter](https://twitter.com/omniedgeio) 12 | [😇 Discord](https://discord.gg/d4faRPYj) 13 | 14 | A cross-platform private network tool for developers. 15 | 16 | ![MacBook Pro](https://user-images.githubusercontent.com/93888/171177092-48cc58a8-9c7d-4d62-97a3-f471fa950d03.png) 17 | 18 | 19 | 20 | ## Install 21 | 22 | ### Install OmniEdge Cli 23 | 24 | ```bash 25 | curl https://omniedge.io/install/omniedge-install.sh | bash 26 | ``` 27 | 28 | ### Install OmniEdge Gui Client 29 | 30 | - [Android: OmniEdge.apk](https://omniedge.io/install/download/0.2.2/omniedge-release-v0.2.2.apk) 31 | - [macOS cli](https://omniedge.io/install/download/0.2.3/omniedgecli-macos-latest.zip) 32 | - [Windows](https://omniedge.io/install/download/0.2.3/omniedge-setup-0.2.3.exe) 33 | - [Linux Cli](https://github.com/omniedgeio/app-release/releases/tag/v0.2.3) 34 | - [iOS & M1 Mac on App Store](https://apps.apple.com/us/app/omniedgenew/id1603005893) 35 | - [Synology](https://omniedge.io/download/synology) 36 | - [Raspberry Pi, ARM, Nvidia Jetson](https://github.com/omniedgeio/app-release/releases/tag/v0.2.3) 37 | 38 | 39 | ## Cli Command 40 | 41 | ### Login 42 | 43 | - Login By Password 44 | 45 | ```shell 46 | omniedge login -u xxx@xxx.com 47 | ``` 48 | 49 | - Login By Secret-Key 50 | 51 | You can generate secret-key on omniedge web. 52 | 53 | ```shell 54 | omniedge login -s xxxxxx 55 | ``` 56 | 57 | ### Join 58 | 59 | you can just call `omniedge join`, it will automatically prompt 60 | the available network for you to choose. And you can 61 | also add one parameter `-n` to specify the network id manually. 62 | 63 | And then, enjoy the omniedge network. 64 | 65 | ```shell 66 | omniedge join 67 | // or 68 | omniedge join -n "virtual-network-id" 69 | ``` 70 | 71 | ## Protocol 72 | 73 | [n2n](https://github.com/ntop/n2n) 74 | 75 | ## Resources 76 | 77 | - Architecture: https://omniedge.io/docs/article/architecture 78 | - Install: https://omniedge.io/docs/article/install 79 | - Cases: https://omniedge.io/docs/article/cases 80 | - Compare: https://omniedge.io/docs/article/compare 81 | - Performance: https://omniedge.io/docs/article/performance 82 | - Dashboard: https://omniedge.io/docs/article/admin 83 | - [n2n](https://github.com/ntop/n2n) 84 | 85 | 86 | ## Contributing Guildlines 87 | 88 | Check the tempalte into .github folder to report an issue or submit a PR: 89 | 1. ISSUE_TEMPLATE.md 90 | 2. PULL_REQUEST_TEMPLATE.md 91 | 92 | ## How to get started? 93 | 94 | 1. If you only need a convenient connectivity service 95 | Just visit https://omniedge.io/download and download the apps for your platform. 96 | 97 | 2. If you are an experienced programmer 98 | You can prepare your own supernode and build the client to reach your own target accroding to the following `Compiler and debugger` Section. 99 | 100 | ## Compiler and debugger 101 | 102 | Latest version of Xcode, run, 103 | 104 | ```bash 105 | carthage update 106 | carthage update --use-xcframeworks 107 | ``` 108 | 109 | 110 | ## Contributors 111 | 112 | @kidylee @EbenDang 113 | 114 | ## About US 115 | [OmniEdge](https://omniedge.io) is primiary developed by the people at [https://github.com/orgs/omniedgeio/people](https://github.com/orgs/omniedgeio/people). 116 | -------------------------------------------------------------------------------- /Services/AppService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppService.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 16/7/2022. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol IAppService { 11 | 12 | } 13 | 14 | class AppService: IAppService { 15 | 16 | } 17 | -------------------------------------------------------------------------------- /Services/AuthService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AuthService.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 16/7/2022. 6 | // 7 | 8 | import Foundation 9 | import AppKit 10 | 11 | protocol AuthServiceDelegate: AnyObject { 12 | func didLoginCompleted(token: String?) 13 | } 14 | 15 | protocol IAuthService: IService { 16 | var delegate: AuthServiceDelegate? { get set } 17 | func login() 18 | } 19 | 20 | class AuthService: BaseService, IAuthService { 21 | 22 | var token: String? { 23 | get { 24 | return self.authToken 25 | } 26 | } 27 | 28 | weak var delegate: AuthServiceDelegate? 29 | 30 | private var httpService: IHttpService 31 | private var authToken: String? 32 | 33 | init(httpService: IHttpService) { 34 | self.httpService = httpService 35 | super.init() 36 | } 37 | 38 | 39 | override func initService() { 40 | } 41 | 42 | func login() { 43 | 44 | self.httpService.sendGetRequest(url: ApiEndPoint.authSession, completed: { 45 | [weak self] (result: Result, OmError>) in 46 | switch result { 47 | case .success(let response): 48 | if let authModel = response.data { 49 | self?.monitorSessionCodeWSEvent(sessionCode: authModel.sessionId) 50 | self?.onAuthurized(model: authModel) 51 | } else { 52 | self?.handleError(error: .invalidRsp) 53 | } 54 | 55 | case .failure(let error): 56 | self?.handleError(error: error) 57 | } 58 | }) 59 | } 60 | 61 | private func onAuthurized(model: AuthModel) { 62 | guard let url = URL(string: model.authUrl) else { 63 | return 64 | } 65 | 66 | NSWorkspace.shared.open(url) 67 | } 68 | 69 | private func monitorSessionCodeWSEvent(sessionCode: String) { 70 | self.httpService.listenSocket(url: "\(ApiEndPoint.wsEndPoint)/login/session/\(sessionCode)", received: { 71 | [weak self] result in 72 | 73 | switch result { 74 | case .success(let msgData): 75 | self?.didReceivedAuthSocketMessage(message: msgData) 76 | case .failure(let error): 77 | self?.handleError(error: error) 78 | } 79 | }) 80 | } 81 | 82 | private func didReceivedAuthSocketMessage(message: Data?) { 83 | guard let message = message else { 84 | return 85 | } 86 | 87 | do { 88 | let result = try JSONDecoder().decode(Dictionary.self, from: message) 89 | let token = result["token"] 90 | self.delegate?.didLoginCompleted(token: token) 91 | } catch let error { 92 | self.handleError(error: .other(error)) 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Services/BaseService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseService.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 16/7/2022. 6 | // 7 | 8 | import Foundation 9 | 10 | class BaseService { 11 | 12 | init() { 13 | self.initService() 14 | } 15 | 16 | func initService() { 17 | 18 | } 19 | 20 | func handleError(error: OmError){ 21 | print(error) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Services/CacheService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CacheService.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 23/7/2022. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol ICacheService { 11 | func saveValue(value: Any?, key: String) 12 | func getValue(forKey: String) -> Any? 13 | func clearValueForKey(key: String) 14 | } 15 | 16 | class CacheService: BaseService, ICacheService { 17 | 18 | private var userDefault: UserDefaults = UserDefaults.standard 19 | 20 | func saveValue(value: Any?, key: String) { 21 | self.userDefault.setValue(value, forKey: key) 22 | self.userDefault.synchronize() 23 | } 24 | 25 | func getValue(forKey: String) -> Any? { 26 | return self.userDefault.value(forKey: forKey) 27 | } 28 | 29 | func clearValueForKey(key: String) { 30 | self.userDefault.removeObject(forKey: key) 31 | self.userDefault.synchronize() 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Services/HttpService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HttpService.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 15/7/2022. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol IHttpService: IService { 11 | var token: String? { get set } 12 | 13 | func sendGetRequest(url: String, completed: @escaping (Result, OmError>) -> Void) 14 | func sendPostRequest(url: String, payload: S, completed: @escaping (Result, OmError>) -> Void) 15 | 16 | func listenSocket(url: String, received: @escaping (Result) -> Void) 17 | } 18 | 19 | class HttpService: BaseService, IHttpService { 20 | 21 | enum HttpMethodType: String { 22 | case httpGet = "GET" 23 | case httpPost = "POST" 24 | } 25 | 26 | var token: String? 27 | 28 | private var session: URLSession? 29 | private var baseEndPoint = ApiEndPoint.baseApi 30 | private var jsonDecoder: JSONDecoder = JSONDecoder() 31 | 32 | override init() { 33 | super.init() 34 | } 35 | 36 | override func initService() { 37 | self.session = URLSession(configuration: URLSessionConfiguration.default, delegate: nil, delegateQueue: nil) 38 | 39 | let dateFormatter = DateFormatter() 40 | dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" 41 | self.jsonDecoder.dateDecodingStrategy = .formatted(dateFormatter) 42 | } 43 | 44 | func sendGetRequest(url: String, completed: @escaping (Result, OmError>) -> Void) { 45 | 46 | guard let session = self.session, 47 | let request = self.generateRequest(url: url, httpMethodType: .httpGet) else { 48 | completed(.failure(.invalidUrl)) 49 | return 50 | } 51 | 52 | let task = session.dataTask(with: request) { (data, response, error) in 53 | if error != nil { 54 | completed(.failure(.other(error!))) 55 | return 56 | } 57 | 58 | guard let data = data else { 59 | completed(.failure(.invalidRsp)) 60 | return 61 | } 62 | 63 | #if DEBUG 64 | data.printJson() 65 | #endif 66 | 67 | do { 68 | let response = try self.jsonDecoder.decode(Response.self, from: data) 69 | completed(.success(response)) 70 | } catch let error { 71 | completed(.failure(.other(error))) 72 | } 73 | } 74 | 75 | task.resume() 76 | } 77 | 78 | func sendPostRequest(url: String, payload: S, completed: @escaping (Result, OmError>) -> Void) { 79 | guard let session = self.session, 80 | var request = self.generateRequest(url: url, httpMethodType: .httpPost) else { 81 | completed(.failure(.invalidUrl)) 82 | return 83 | } 84 | 85 | do { 86 | let jsonData = try JSONEncoder().encode(payload) 87 | request.httpBody = jsonData 88 | request.setValue("application/json", forHTTPHeaderField: "Content-Type") 89 | } catch let error { 90 | completed(.failure(.other(error))) 91 | return 92 | } 93 | 94 | let task = session.dataTask(with: request) { (data, response, error) in 95 | if error != nil { 96 | completed(.failure(.other(error!))) 97 | return 98 | } 99 | 100 | guard let data = data else { 101 | return 102 | } 103 | 104 | #if DEBUG 105 | data.printJson() 106 | #endif 107 | 108 | do { 109 | 110 | let restReponse = try self.jsonDecoder.decode(Response.self, from: data) 111 | if(restReponse.code == 200) { 112 | completed(.success(restReponse)) 113 | } else { 114 | completed(.failure(.errCode(restReponse.code, restReponse.message ?? String.Empty))) 115 | } 116 | } catch let error { 117 | print(error) 118 | completed(.failure(.other(error))) 119 | } 120 | } 121 | 122 | task.resume() 123 | } 124 | 125 | 126 | 127 | func listenSocket(url: String, received: @escaping (Result) -> Void ) { 128 | let urlSession = URLSession(configuration: URLSessionConfiguration.default) 129 | guard let url = URL(string: url) else { 130 | return 131 | } 132 | 133 | let sokcetTask = urlSession.webSocketTask(with: url) 134 | sokcetTask.resume() 135 | sokcetTask.receive { result in 136 | switch result { 137 | case .success(let message): 138 | self.didReceivedSocketMessage(message: message, completed: received) 139 | case .failure(let error): 140 | self.handleError(error: .other(error)) 141 | } 142 | } 143 | } 144 | 145 | private func didReceivedSocketMessage(message: URLSessionWebSocketTask.Message, completed: (Result) -> Void ) { 146 | switch message { 147 | case .string(let msg): 148 | completed(.success(msg.data(using: .utf8))) 149 | case .data(let data): 150 | completed(.success(data)) 151 | @unknown default: 152 | fatalError() 153 | } 154 | } 155 | 156 | private func generateRequest(url: String, httpMethodType: HttpMethodType) -> URLRequest? { 157 | guard let url = URL(string: ApiEndPoint.baseApi + url) else { 158 | return nil 159 | } 160 | 161 | var request = URLRequest(url: url) 162 | request.httpMethod = httpMethodType.rawValue 163 | guard let token = token else { 164 | return request 165 | } 166 | 167 | request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization") 168 | return request 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /Services/IService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IService.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 16/7/2022. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol IService { 11 | 12 | func initService() 13 | } 14 | -------------------------------------------------------------------------------- /Services/LocatorService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LocatorService.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 16/7/2022. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol ILocatorService { 11 | func register(instance: T) 12 | func register(recipe: @escaping () -> T) 13 | func resolve() -> T 14 | } 15 | 16 | final class LocatorService: ILocatorService { 17 | enum RegistryRec{ 18 | case Instance(Any) 19 | case Recipe(() -> Any) 20 | 21 | func unwap() -> Any{ 22 | switch self{ 23 | case .Instance(let instance): 24 | return instance 25 | case .Recipe(let recipe): 26 | return recipe() 27 | } 28 | } 29 | } 30 | 31 | lazy private var repository: Dictionary = [:] 32 | 33 | private static var instance : LocatorService = { 34 | return LocatorService() 35 | }() 36 | 37 | private init(){ 38 | } 39 | 40 | class func shareInstance() -> LocatorService { 41 | return instance 42 | } 43 | 44 | func register(instance: T) { 45 | let key = typeNmae(some: T.self) 46 | self.repository[key] = .Instance(instance) 47 | } 48 | 49 | func register(recipe: @escaping () -> T) { 50 | let key = typeNmae(some: T.self) 51 | self.repository[key] = .Recipe(recipe) 52 | } 53 | 54 | func resolve() -> T { 55 | let key = self.typeNmae(some: T.self) 56 | var instance : T? = nil 57 | if let record = self.repository[key]{ 58 | instance = record.unwap() as? T 59 | switch record { 60 | case .Recipe: 61 | if let instance = instance { 62 | self.register(instance: instance) 63 | } 64 | default: 65 | break 66 | } 67 | } 68 | 69 | guard let instance = instance else { 70 | fatalError() 71 | } 72 | 73 | return instance 74 | } 75 | 76 | private func typeNmae(some: Any) -> String { 77 | return (some is Any.Type) ? "\(some)" : "\(type(of: some))" 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Services/OmniService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppService.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 15/7/2022. 6 | // 7 | 8 | import Foundation 9 | import AppKit 10 | 11 | protocol OmniServiceDelegate: AnyObject { 12 | func didLoginSuccess() 13 | func didLoginFailed() 14 | func didLogout() 15 | func didNetworksLoaded(networks: [VirtualNetworkModel]) 16 | func didError(error: OmError) 17 | func didDeviceJoined(deviceModel: DeviceRegisterModel?, joinedModel: JoinDeviceMode?, connected: Bool) 18 | func clearRegistedDevice() 19 | } 20 | 21 | protocol IOmniService: IService { 22 | var delegate: OmniServiceDelegate? { get set } 23 | var networkService: IVirtualNetworkService { get } 24 | var hasLoggedIn: Bool { get } 25 | 26 | func login() 27 | func logout() 28 | func getCachedNetworkConfig() -> Data? 29 | 30 | func terminate() 31 | } 32 | 33 | class OmniService: IOmniService { 34 | 35 | var hasLoggedIn: Bool { 36 | get { 37 | return self.token != nil 38 | } 39 | } 40 | 41 | weak var delegate: OmniServiceDelegate? 42 | 43 | var networkService: IVirtualNetworkService { 44 | get { 45 | guard let virtualNetworkService = self.curVirtualNetworkService else { 46 | let networkService: IVirtualNetworkService = self.locatorService.resolve() 47 | self.curVirtualNetworkService = networkService 48 | self.curVirtualNetworkService?.delegate = self 49 | return networkService 50 | } 51 | 52 | return virtualNetworkService 53 | } 54 | } 55 | 56 | private var httpService: IHttpService { 57 | get { 58 | 59 | guard let httpService = self.curHttpService else { 60 | let httpService: IHttpService = self.locatorService.resolve() 61 | self.curHttpService = httpService 62 | return httpService 63 | } 64 | 65 | return httpService 66 | } 67 | } 68 | 69 | private var authService: IAuthService { 70 | get { 71 | guard let authService = self.curAuthService else { 72 | let authService: IAuthService = self.locatorService.resolve() 73 | self.curAuthService = authService 74 | self.curAuthService?.delegate = self 75 | return authService 76 | } 77 | 78 | return authService 79 | } 80 | } 81 | 82 | private var locatorService: ILocatorService 83 | private var curHttpService: IHttpService? 84 | private var curAuthService: IAuthService? 85 | private var curVirtualNetworkService: IVirtualNetworkService? 86 | private var cacheService: ICacheService 87 | 88 | private var token: String? 89 | 90 | init(locatorService: ILocatorService) { 91 | self.locatorService = locatorService 92 | self.cacheService = self.locatorService.resolve() 93 | } 94 | 95 | func initService() { 96 | let xpcService: IXPCService = self.locatorService.resolve() 97 | let authService = AuthService(httpService: self.httpService) 98 | let networkService = VirtualNetworkService(httpService: self.httpService, xpcService: xpcService) 99 | 100 | self.locatorService.register(instance: authService as IAuthService) 101 | self.locatorService.register(instance: networkService as IVirtualNetworkService) 102 | 103 | xpcService.installAndConnectHeperTool() 104 | } 105 | 106 | func login() { 107 | self.authService.login() 108 | } 109 | 110 | func logout() { 111 | self.token = nil 112 | self.delegate?.didLogout() 113 | DispatchQueue.main.async { 114 | (NSApplication.shared.delegate as? AppDelegate)?.didLogin(login: false) 115 | } 116 | } 117 | 118 | func joinLocalDevice(vnId: String) { 119 | self.networkService.joinDeviceInNetwork(vnId: vnId) 120 | } 121 | 122 | func getCachedNetworkConfig() -> Data? { 123 | let cacheService: ICacheService = self.locatorService.resolve() 124 | let networkConfigData = cacheService.getValue(forKey: UserDefaultKeys.NetworkConfig) 125 | return networkConfigData as? Data 126 | } 127 | 128 | func terminate() { 129 | let xpcService: IXPCService = self.locatorService.resolve() 130 | xpcService.disconnect() 131 | } 132 | 133 | private func updateDevice(connected: Bool) { 134 | let registedDeviceData: Data? = self.cacheService.getValue(forKey: UserDefaultKeys.RegisterDevice) as? Data 135 | let joinedDeviceData: Data? = self.cacheService.getValue(forKey: UserDefaultKeys.JoinedDevice) as? Data 136 | 137 | var registerDevice: DeviceRegisterModel? 138 | var joinedDevice: JoinDeviceMode? 139 | 140 | if registedDeviceData != nil { 141 | registerDevice = try? JSONDecoder().decode(DeviceRegisterModel.self, from: registedDeviceData!) 142 | } 143 | 144 | if joinedDeviceData != nil { 145 | joinedDevice = try? JSONDecoder().decode(JoinDeviceMode.self, from: joinedDeviceData!) 146 | } 147 | 148 | self.delegate?.didDeviceJoined(deviceModel: registerDevice, joinedModel: joinedDevice, connected: connected) 149 | } 150 | 151 | // MARK: - Private functions - 152 | private func getRemoteNetworkList() { 153 | self.networkService.loadNetworks() 154 | } 155 | 156 | private func registerLocalDevice() { 157 | self.networkService.registerDevice() 158 | } 159 | } 160 | 161 | extension OmniService: AuthServiceDelegate { 162 | func didLoginCompleted(token: String?) { 163 | self.curHttpService?.token = token 164 | self.token = token 165 | var loggedIn = false 166 | 167 | if token == nil { 168 | self.delegate?.didLoginFailed() 169 | } else { 170 | self.updateDevice(connected: false) 171 | self.delegate?.didLoginSuccess() 172 | self.registerLocalDevice() 173 | self.getRemoteNetworkList() 174 | loggedIn = true 175 | } 176 | 177 | DispatchQueue.main.async { 178 | (NSApplication.shared.delegate as? AppDelegate)?.didLogin(login: loggedIn) 179 | } 180 | } 181 | } 182 | 183 | extension OmniService: VirtualNetworkServiceDelegate { 184 | func didNetworkListLoaded(networks: [VirtualNetworkModel]) { 185 | self.delegate?.didNetworksLoaded(networks: networks) 186 | } 187 | 188 | func didJoinedDevice(model: JoinDeviceMode) { 189 | var data: Data? 190 | do { 191 | data = try JSONEncoder().encode(model) 192 | 193 | } catch let error { 194 | self.delegate?.didError(error: .other(error)) 195 | return 196 | } 197 | 198 | guard let data = data else { 199 | return 200 | } 201 | 202 | // save it 203 | self.cacheService.saveValue(value: data, key: UserDefaultKeys.JoinedDevice) 204 | 205 | self.networkService.connectNetwork(dataOfNetworkConfig: data) { 206 | [weak self] success in 207 | if !success { 208 | Utils.alert(title: "Tuntap not detected", description: "Tuntap is required to enable the network, please install it according the instruction: https://omniedge.io/docs/article/install/macos.", .critical) 209 | } 210 | 211 | self?.updateDevice(connected: success) 212 | } 213 | } 214 | 215 | func didRegisteredDeviceFailed() { 216 | self.cacheService.clearValueForKey(key: UserDefaultKeys.RegisterDevice) 217 | self.updateDevice(connected: false) 218 | self.delegate?.clearRegistedDevice() 219 | } 220 | 221 | func didRegisteredDevice(model: DeviceRegisterModel) { 222 | var data: Data? 223 | do { 224 | data = try JSONEncoder().encode(model) 225 | 226 | } catch let error { 227 | self.delegate?.didError(error: .other(error)) 228 | return 229 | } 230 | 231 | guard let data = data else { 232 | return 233 | } 234 | 235 | // save it 236 | self.cacheService.saveValue(value: data, key: UserDefaultKeys.RegisterDevice) 237 | 238 | self.updateDevice(connected: false) 239 | } 240 | } 241 | -------------------------------------------------------------------------------- /Services/VirtualNetworkService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VirtualNetworkService.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 16/7/2022. 6 | // 7 | 8 | import Foundation 9 | 10 | protocol VirtualNetworkServiceDelegate: AnyObject { 11 | func didNetworkListLoaded(networks: [VirtualNetworkModel]) 12 | func didRegisteredDevice(model: DeviceRegisterModel) 13 | func didJoinedDevice(model: JoinDeviceMode) 14 | func didRegisteredDeviceFailed() 15 | } 16 | 17 | protocol IVirtualNetworkService { 18 | var failedRegisteDev: Bool { get } 19 | 20 | var delegate: VirtualNetworkServiceDelegate? { get set } 21 | var curConnectedNetworkId: String? { get } 22 | func loadNetworks() 23 | func connectNetwork(dataOfNetworkConfig: Data, completed: @escaping (_ successed: Bool) -> Void) 24 | func disconnectNetwork() 25 | func registerDevice() 26 | func joinDeviceInNetwork(vnId: String) 27 | } 28 | 29 | class VirtualNetworkService: BaseService, IVirtualNetworkService { 30 | 31 | weak var delegate: VirtualNetworkServiceDelegate? 32 | 33 | var curConnectedNetworkId: String? { 34 | get { 35 | return self.lastConnectedVNId 36 | } 37 | } 38 | 39 | var failedRegisteDev: Bool { 40 | get { 41 | return self.registerDevFailed 42 | } 43 | } 44 | 45 | private var httpService: IHttpService 46 | private var xpcService: IXPCService 47 | private var deviceRegisterModel: DeviceRegisterModel? 48 | private var deviceJoinedModel: JoinDeviceMode? 49 | private var deviceModel: DeviceModel? 50 | private var lastConnectedVNId: String? 51 | private var networks: [VirtualNetworkModel] = [] 52 | private var registerDevFailed: Bool = false 53 | 54 | init(httpService: IHttpService, xpcService: IXPCService) { 55 | self.httpService = httpService 56 | self.xpcService = xpcService 57 | super.init() 58 | } 59 | 60 | override func initService() { 61 | self.deviceModel = Utils.getDeviceInfo() 62 | } 63 | 64 | func loadNetworks() { 65 | 66 | self.httpService.sendGetRequest(url: ApiEndPoint.virtualNetworkList, completed: { 67 | [weak self] (result: Result, OmError>) in 68 | switch result { 69 | case .success(let response): 70 | if(response.code == 200) { 71 | self?.didLoadNetworkList(networks: response.data) 72 | } else { 73 | self?.handleError(error: .errCode(response.code, response.message ?? String.Empty)) 74 | } 75 | case .failure(let error): 76 | self?.handleError(error: error) 77 | } 78 | }) 79 | } 80 | 81 | func connectNetwork(dataOfNetworkConfig: Data, completed: @escaping (_ successed: Bool) -> Void) { 82 | // check if the tuntapInstalled 83 | if !self.hasTuntapInstalled() { 84 | completed(false) 85 | return 86 | } 87 | 88 | self.terminateActiveTapConnection() 89 | print("Start connection"); 90 | self.xpcService.connect(dataOfNetworkConfig: dataOfNetworkConfig) { (success, error) in 91 | completed(success) 92 | guard let error = error else { 93 | return 94 | } 95 | print(error) 96 | } 97 | } 98 | 99 | func disconnectNetwork() { 100 | self.xpcService.disconnect() 101 | } 102 | 103 | func registerDevice() { 104 | self.httpService.sendPostRequest(url: ApiEndPoint.registerDevice, payload: self.deviceModel) { 105 | [weak self] (result: Result, OmError>) in 106 | switch result { 107 | case .success(let response): 108 | self?.onDeviceRegister(model: response.data) 109 | case .failure(let error): 110 | self?.registerDevFailed = true 111 | self?.delegate?.didRegisteredDeviceFailed() 112 | self?.handleError(error: error) 113 | } 114 | } 115 | } 116 | 117 | func joinDeviceInNetwork(vnId: String) { 118 | if self.lastConnectedVNId != nil && self.lastConnectedVNId! != vnId { 119 | self.disconnectNetwork() 120 | } 121 | 122 | guard let deviceId = self.deviceRegisterModel?.deviceId else { 123 | return 124 | } 125 | let payload: [String: String] = ["deviceId" : deviceId] 126 | let joinUrl = "\(ApiEndPoint.virtualNetworkList)\(vnId)/devices/\(deviceId)/join"; 127 | self.httpService.sendPostRequest(url: joinUrl, payload: payload) { 128 | [weak self] (result: Result< Response, OmError>) in 129 | switch result { 130 | case .success(let response): 131 | self?.onDeviceJoined(model: response.data, virtualNetworkId: vnId) 132 | case .failure(let error): 133 | self?.handleError(error: error) 134 | } 135 | } 136 | } 137 | 138 | // MARK: - Private functions - 139 | private func didLoadNetworkList(networks: [VirtualNetworkModel]?) { 140 | guard let networks = networks else { 141 | return 142 | } 143 | 144 | self.networks.removeAll() 145 | self.networks.append(contentsOf: networks) 146 | self.delegate?.didNetworkListLoaded(networks: networks) 147 | } 148 | 149 | private func hasTuntapInstalled() -> Bool { 150 | return FileManager.default.fileExists(atPath: "/dev/tap0") 151 | } 152 | 153 | private func onDeviceRegister(model: DeviceRegisterModel?) { 154 | guard let model = model else { 155 | return 156 | } 157 | registerDevFailed = false 158 | self.deviceRegisterModel = model 159 | self.delegate?.didRegisteredDevice(model: model) 160 | } 161 | 162 | private func onDeviceJoined(model: JoinDeviceMode?, virtualNetworkId: String) { 163 | guard let model = model else { 164 | return 165 | } 166 | 167 | self.lastConnectedVNId = virtualNetworkId 168 | let vnName = self.networks.first { item in 169 | item.vnId == virtualNetworkId 170 | }?.vnName 171 | self.deviceJoinedModel = model 172 | self.deviceJoinedModel?.setVnId(vnId: virtualNetworkId) 173 | self.deviceJoinedModel?.setVnName(vnName: vnName ?? String.Empty) 174 | 175 | 176 | self.delegate?.didJoinedDevice(model: self.deviceJoinedModel!) 177 | } 178 | 179 | private func terminateActiveTapConnection() { 180 | for _ in 0 ..< 6 { 181 | let output = runShellAndOutput("ifconfig | grep tap0 | head -c 4") 182 | if output?.starts(with: "tap") ?? false { 183 | print("Detected an active tap connection, terminate it"); 184 | self.disconnectNetwork() 185 | sleep(1) 186 | //usleep(useconds_t(5 * 1000) * 100) 187 | print("after 1s delay, check it again"); 188 | } else { 189 | print("No active connection found"); 190 | break 191 | } 192 | } 193 | } 194 | 195 | @discardableResult 196 | // func runShellAndOutput(_ command: String) -> (Int32, String?) { 197 | private func runShellAndOutput(_ command: String) -> String? { 198 | let task = Process() 199 | task.launchPath = "/bin/bash" 200 | task.arguments = ["-c", command] 201 | 202 | let pipe = Pipe() 203 | task.standardOutput = pipe 204 | task.standardError = pipe 205 | 206 | task.launch() 207 | 208 | let data = pipe.fileHandleForReading.readDataToEndOfFile() 209 | let output = String(data: data, encoding: .utf8) 210 | 211 | task.waitUntilExit() 212 | 213 | return output 214 | // return (task.terminationStatus, output) 215 | } 216 | 217 | @discardableResult 218 | func runShellWithArgsAndOutput(_ args: String...) -> (Int32, String?) { 219 | let task = Process() 220 | 221 | task.launchPath = "/usr/bin/env" 222 | task.arguments = args 223 | 224 | let pipe = Pipe() 225 | task.standardOutput = pipe 226 | task.standardError = pipe 227 | 228 | task.launch() 229 | 230 | let data = pipe.fileHandleForReading.readDataToEndOfFile() 231 | let output = String(data: data, encoding: .utf8) 232 | 233 | task.waitUntilExit() 234 | 235 | return (task.terminationStatus, output) 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /Services/XPCService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // XCPService.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 15/7/2022. 6 | // 7 | 8 | import Foundation 9 | import AppKit 10 | 11 | protocol IXPCService: IService { 12 | func installAndConnectHeperTool() 13 | func connect(dataOfNetworkConfig: Data, completed: @escaping (Bool, Error?) -> Void) 14 | func disconnect() 15 | } 16 | 17 | class XPCService: BaseService, IXPCService { 18 | private var XPCConnection: NSXPCConnection? 19 | private var helperTool: HelperTool? 20 | 21 | func installAndConnectHeperTool() { 22 | if !FileManager.default.fileExists(atPath: "/Library/PrivilegedHelperTools/\(XPCConstant.HelperMachLabel)"){ 23 | 24 | self.alertInstall("Omniedge needs to install Helper Tool to complete installation.") 25 | } 26 | 27 | self.connectToXPC() 28 | } 29 | 30 | func disconnect(){ 31 | self.helperTool?.disconnect() 32 | XPCConnection?.invalidationHandler = nil 33 | XPCConnection?.interruptionHandler = nil 34 | self.XPCConnection = nil 35 | } 36 | 37 | func connect(dataOfNetworkConfig: Data, completed: @escaping (Bool, Error?) -> Void) { 38 | self.helperTool?.connect(dataOfNetworkConfig, completion: { err in 39 | completed(err == nil, err) 40 | }) 41 | } 42 | 43 | private func connectToXPC(){ 44 | 45 | self.XPCConnection = NSXPCConnection(machServiceName: XPCConstant.HelperMachLabel, 46 | options: .privileged) 47 | 48 | XPCConnection?.remoteObjectInterface = NSXPCInterface(with: HelperTool.self) 49 | 50 | XPCConnection?.invalidationHandler = connectionInvalidationHandler 51 | XPCConnection?.interruptionHandler = connetionInterruptionHandler 52 | 53 | XPCConnection?.resume() 54 | 55 | self.helperTool = XPCConnection?.remoteObjectProxy as? HelperTool 56 | // self.helperTool?.version(completion: checkHelperVersion) 57 | } 58 | 59 | private func checkHelperVersion(ver: String){ 60 | if ver != XPCConstant.HelperToolVersion{ 61 | DispatchQueue.main.async { 62 | self.alertInstall("Omniedge needs to upgrade Helper Tool.") 63 | } 64 | } 65 | } 66 | 67 | 68 | private func connetionInterruptionHandler() { 69 | NSLog("interrupted Connection") 70 | 71 | } 72 | 73 | private func connectionInvalidationHandler() { 74 | NSLog("Invalid Connection") 75 | } 76 | 77 | private func alertInstall(_ message: String){ 78 | let alert = NSAlert() 79 | alert.alertStyle = .informational 80 | alert.messageText = message 81 | let okButton = alert.addButton(withTitle: "OK") 82 | alert.window.defaultButtonCell = okButton.cell as? NSButtonCell 83 | alert.addButton(withTitle: "Cancel") 84 | let modal = alert.runModal() 85 | 86 | switch modal { 87 | case .OK, .alertFirstButtonReturn: 88 | self.installHelperTool() 89 | default: 90 | self.notAbleToStart(nil) 91 | } 92 | } 93 | 94 | 95 | private func notAbleToStart(_ message: String?){ 96 | let alert = NSAlert() 97 | alert.alertStyle = .critical 98 | alert.messageText = message ?? "Omniedge not able to start." 99 | alert.addButton(withTitle: "Exit") 100 | alert.runModal() 101 | 102 | NSRunningApplication.current.terminate() 103 | } 104 | 105 | 106 | 107 | private func installHelperTool(){ 108 | 109 | self.disconnect() 110 | guard let auth = Utils.askAuthorization() else { 111 | fatalError("Authorization not acquired.") 112 | } 113 | 114 | if(!Utils.blessHelper(label: XPCConstant.HelperMachLabel, authorization: auth)){ 115 | self.notAbleToStart("Install HelperTool failed.") 116 | } 117 | 118 | self.connectToXPC() 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /Sparkle.framework/Headers: -------------------------------------------------------------------------------- 1 | Versions/Current/Headers -------------------------------------------------------------------------------- /Sparkle.framework/Modules: -------------------------------------------------------------------------------- 1 | Versions/Current/Modules -------------------------------------------------------------------------------- /Sparkle.framework/PrivateHeaders: -------------------------------------------------------------------------------- 1 | Versions/Current/PrivateHeaders -------------------------------------------------------------------------------- /Sparkle.framework/Resources: -------------------------------------------------------------------------------- 1 | Versions/Current/Resources -------------------------------------------------------------------------------- /Sparkle.framework/Sparkle: -------------------------------------------------------------------------------- 1 | Versions/Current/Sparkle -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SPUDownloadData.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUDownloadData.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 8/10/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #if __has_feature(modules) 10 | @import Foundation; 11 | #else 12 | #import 13 | #endif 14 | 15 | #import "SUExport.h" 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | /*! 20 | * A class for containing downloaded data along with some information about it. 21 | */ 22 | SU_EXPORT @interface SPUDownloadData : NSObject 23 | 24 | - (instancetype)initWithData:(NSData *)data textEncodingName:(NSString * _Nullable)textEncodingName MIMEType:(NSString * _Nullable)MIMEType; 25 | 26 | /*! 27 | * The raw data that was downloaded. 28 | */ 29 | @property (nonatomic, readonly) NSData *data; 30 | 31 | /*! 32 | * The IANA charset encoding name if available. Eg: "utf-8" 33 | */ 34 | @property (nonatomic, readonly, nullable, copy) NSString *textEncodingName; 35 | 36 | /*! 37 | * The MIME type if available. Eg: "text/plain" 38 | */ 39 | @property (nonatomic, readonly, nullable, copy) NSString *MIMEType; 40 | 41 | @end 42 | 43 | NS_ASSUME_NONNULL_END 44 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SPUDownloader.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUDownloader.h 3 | // Downloader 4 | // 5 | // Created by Mayur Pawashe on 4/1/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #if __has_feature(modules) 10 | @import Foundation; 11 | #else 12 | #import 13 | #endif 14 | #import "SPUDownloaderProtocol.h" 15 | 16 | @protocol SPUDownloaderDelegate; 17 | 18 | // This object implements the protocol which we have defined. It provides the actual behavior for the service. It is 'exported' by the service to make it available to the process hosting the service over an NSXPCConnection. 19 | @interface SPUDownloader : NSObject 20 | 21 | // Due to XPC remote object reasons, this delegate is strongly referenced 22 | // Invoke cleanup when done with this instance 23 | - (instancetype)initWithDelegate:(id )delegate; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SPUDownloaderDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUDownloaderDelegate.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 4/1/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #if __has_feature(modules) 10 | @import Foundation; 11 | #else 12 | #import 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @class SPUDownloadData; 18 | 19 | @protocol SPUDownloaderDelegate 20 | 21 | // This is only invoked for persistent downloads 22 | - (void)downloaderDidSetDestinationName:(NSString *)destinationName temporaryDirectory:(NSString *)temporaryDirectory; 23 | 24 | // Under rare cases, this may be called more than once, in which case the current progress should be reset back to 0 25 | // This is only invoked for persistent downloads 26 | - (void)downloaderDidReceiveExpectedContentLength:(int64_t)expectedContentLength; 27 | 28 | // This is only invoked for persistent downloads 29 | - (void)downloaderDidReceiveDataOfLength:(uint64_t)length; 30 | 31 | // downloadData is nil if this is a persisent download, otherwise it's non-nil if it's a temporary download 32 | - (void)downloaderDidFinishWithTemporaryDownloadData:(SPUDownloadData * _Nullable)downloadData; 33 | 34 | - (void)downloaderDidFailWithError:(NSError *)error; 35 | 36 | @end 37 | 38 | NS_ASSUME_NONNULL_END 39 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SPUDownloaderDeprecated.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUDownloaderDeprecated.h 3 | // Sparkle 4 | // 5 | // Created by Deadpikle on 12/20/17. 6 | // Copyright © 2017 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #import "SPUDownloader.h" 10 | 11 | @interface SPUDownloaderDeprecated : SPUDownloader 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SPUDownloaderProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUDownloaderProtocol.h 3 | // PersistentDownloader 4 | // 5 | // Created by Mayur Pawashe on 4/1/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #if __has_feature(modules) 10 | @import Foundation; 11 | #else 12 | #import 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | @class SPUURLRequest; 18 | 19 | // The protocol that this service will vend as its API. This header file will also need to be visible to the process hosting the service. 20 | @protocol SPUDownloaderProtocol 21 | 22 | - (void)startPersistentDownloadWithRequest:(SPUURLRequest *)request bundleIdentifier:(NSString *)bundleIdentifier desiredFilename:(NSString *)desiredFilename; 23 | 24 | - (void)startTemporaryDownloadWithRequest:(SPUURLRequest *)request; 25 | 26 | - (void)downloadDidFinish; 27 | 28 | - (void)cleanup; 29 | 30 | - (void)cancel; 31 | 32 | @end 33 | 34 | NS_ASSUME_NONNULL_END 35 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SPUDownloaderSession.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUDownloaderSession.h 3 | // Sparkle 4 | // 5 | // Created by Deadpikle on 12/20/17. 6 | // Copyright © 2017 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #if __has_feature(modules) 10 | @import Foundation; 11 | #else 12 | #import 13 | #endif 14 | #import "SPUDownloader.h" 15 | #import "SPUDownloaderProtocol.h" 16 | 17 | NS_CLASS_AVAILABLE(NSURLSESSION_AVAILABLE, 7_0) 18 | @interface SPUDownloaderSession : SPUDownloader 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SPUURLRequest.h: -------------------------------------------------------------------------------- 1 | // 2 | // SPUURLRequest.h 3 | // Sparkle 4 | // 5 | // Created by Mayur Pawashe on 5/19/16. 6 | // Copyright © 2016 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #if __has_feature(modules) 10 | @import Foundation; 11 | #else 12 | #import 13 | #endif 14 | 15 | NS_ASSUME_NONNULL_BEGIN 16 | 17 | // A class that wraps NSURLRequest and implements NSSecureCoding 18 | // This class exists because NSURLRequest did not support NSSecureCoding in macOS 10.8 19 | // I have not verified if NSURLRequest in 10.9 implements NSSecureCoding or not 20 | @interface SPUURLRequest : NSObject 21 | 22 | // Creates a new URL request 23 | // Only these properties are currently tracked: 24 | // * URL 25 | // * Cache policy 26 | // * Timeout interval 27 | // * HTTP header fields 28 | // * networkServiceType 29 | + (instancetype)URLRequestWithRequest:(NSURLRequest *)request; 30 | 31 | @property (nonatomic, readonly) NSURLRequest *request; 32 | 33 | @end 34 | 35 | NS_ASSUME_NONNULL_END 36 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUAppcast.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAppcast.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUAPPCAST_H 10 | #define SUAPPCAST_H 11 | 12 | #if __has_feature(modules) 13 | @import Foundation; 14 | #else 15 | #import 16 | #endif 17 | #import "SUExport.h" 18 | 19 | NS_ASSUME_NONNULL_BEGIN 20 | 21 | @class SUAppcastItem; 22 | SU_EXPORT @interface SUAppcast : NSObject 23 | 24 | @property (copy, nullable) NSString *userAgentString; 25 | @property (copy, nullable) NSDictionary *httpHeaders; 26 | 27 | - (void)fetchAppcastFromURL:(NSURL *)url inBackground:(BOOL)bg completionBlock:(void (^)(NSError *_Nullable))err; 28 | - (SUAppcast *)copyWithoutDeltaUpdates; 29 | 30 | @property (readonly, copy, nullable) NSArray *items; 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUAppcastItem.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUAppcastItem.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/12/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUAPPCASTITEM_H 10 | #define SUAPPCASTITEM_H 11 | 12 | #if __has_feature(modules) 13 | @import Foundation; 14 | #else 15 | #import 16 | #endif 17 | #import "SUExport.h" 18 | @class SUSignatures; 19 | 20 | SU_EXPORT @interface SUAppcastItem : NSObject 21 | @property (copy, readonly) NSString *title; 22 | @property (copy, readonly) NSString *dateString; 23 | @property (copy, readonly) NSDate *date; 24 | @property (copy, readonly) NSString *itemDescription; 25 | @property (strong, readonly) NSURL *releaseNotesURL; 26 | @property (strong, readonly) SUSignatures *signatures; 27 | @property (copy, readonly) NSString *minimumSystemVersion; 28 | @property (copy, readonly) NSString *maximumSystemVersion; 29 | @property (strong, readonly) NSURL *fileURL; 30 | @property (nonatomic, readonly) uint64_t contentLength; 31 | @property (copy, readonly) NSString *versionString; 32 | @property (copy, readonly) NSString *osString; 33 | @property (copy, readonly) NSString *displayVersionString; 34 | @property (copy, readonly) NSDictionary *deltaUpdates; 35 | @property (strong, readonly) NSURL *infoURL; 36 | @property (copy, readonly) NSNumber* phasedRolloutInterval; 37 | 38 | // Initializes with data from a dictionary provided by the RSS class. 39 | - (instancetype)initWithDictionary:(NSDictionary *)dict; 40 | - (instancetype)initWithDictionary:(NSDictionary *)dict failureReason:(NSString **)error; 41 | 42 | @property (getter=isDeltaUpdate, readonly) BOOL deltaUpdate; 43 | @property (getter=isCriticalUpdate, readonly) BOOL criticalUpdate; 44 | @property (getter=isMacOsUpdate, readonly) BOOL macOsUpdate; 45 | @property (getter=isInformationOnlyUpdate, readonly) BOOL informationOnlyUpdate; 46 | 47 | // Returns the dictionary provided in initWithDictionary; this might be useful later for extensions. 48 | @property (readonly, copy) NSDictionary *propertiesDictionary; 49 | 50 | - (NSURL *)infoURL; 51 | 52 | @end 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUCodeSigningVerifier.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUCodeSigningVerifier.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 7/5/12. 6 | // 7 | // 8 | 9 | #ifndef SUCODESIGNINGVERIFIER_H 10 | #define SUCODESIGNINGVERIFIER_H 11 | 12 | #if __has_feature(modules) 13 | @import Foundation; 14 | #else 15 | #import 16 | #endif 17 | #import "SUExport.h" 18 | 19 | SU_EXPORT @interface SUCodeSigningVerifier : NSObject 20 | + (BOOL)codeSignatureAtBundleURL:(NSURL *)oldBundlePath matchesSignatureAtBundleURL:(NSURL *)newBundlePath error:(NSError **)error; 21 | + (BOOL)codeSignatureIsValidAtBundleURL:(NSURL *)bundlePath error:(NSError **)error; 22 | + (BOOL)bundleAtURLIsCodeSigned:(NSURL *)bundlePath; 23 | + (NSDictionary *)codeSignatureInfoAtBundleURL:(NSURL *)bundlePath; 24 | @end 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUErrors.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUErrors.h 3 | // Sparkle 4 | // 5 | // Created by C.W. Betts on 10/13/14. 6 | // Copyright (c) 2014 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SUERRORS_H 10 | #define SUERRORS_H 11 | 12 | #if __has_feature(modules) 13 | @import Foundation; 14 | #else 15 | #import 16 | #endif 17 | #import "SUExport.h" 18 | 19 | /** 20 | * Error domain used by Sparkle 21 | */ 22 | SU_EXPORT extern NSString *const SUSparkleErrorDomain; 23 | 24 | #pragma clang diagnostic push 25 | #pragma clang diagnostic ignored "-Wc++98-compat" 26 | typedef NS_ENUM(OSStatus, SUError) { 27 | // Appcast phase errors. 28 | SUAppcastParseError = 1000, 29 | SUNoUpdateError = 1001, 30 | SUAppcastError = 1002, 31 | SURunningFromDiskImageError = 1003, 32 | SURunningTranslocated = 1004, 33 | 34 | // Download phase errors. 35 | SUTemporaryDirectoryError = 2000, 36 | SUDownloadError = 2001, 37 | 38 | // Extraction phase errors. 39 | SUUnarchivingError = 3000, 40 | SUSignatureError = 3001, 41 | 42 | // Installation phase errors. 43 | SUFileCopyFailure = 4000, 44 | SUAuthenticationFailure = 4001, 45 | SUMissingUpdateError = 4002, 46 | SUMissingInstallerToolError = 4003, 47 | SURelaunchError = 4004, 48 | SUInstallationError = 4005, 49 | SUDowngradeError = 4006, 50 | SUInstallationCancelledError = 4007, 51 | 52 | // System phase errors 53 | SUSystemPowerOffError = 5000 54 | }; 55 | #pragma clang diagnostic pop 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUExport.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUExport.h 3 | // Sparkle 4 | // 5 | // Created by Jake Petroules on 2014-08-23. 6 | // Copyright (c) 2014 Sparkle Project. All rights reserved. 7 | // 8 | 9 | #ifndef SUEXPORT_H 10 | #define SUEXPORT_H 11 | 12 | #ifdef BUILDING_SPARKLE 13 | #define SU_EXPORT __attribute__((visibility("default"))) 14 | #else 15 | #define SU_EXPORT 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUStandardVersionComparator.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUStandardVersionComparator.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 12/21/07. 6 | // Copyright 2007 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUSTANDARDVERSIONCOMPARATOR_H 10 | #define SUSTANDARDVERSIONCOMPARATOR_H 11 | 12 | #if __has_feature(modules) 13 | @import Foundation; 14 | #else 15 | #import 16 | #endif 17 | #import "SUExport.h" 18 | #import "SUVersionComparisonProtocol.h" 19 | 20 | NS_ASSUME_NONNULL_BEGIN 21 | 22 | /*! 23 | Sparkle's default version comparator. 24 | 25 | This comparator is adapted from MacPAD, by Kevin Ballard. 26 | It's "dumb" in that it does essentially string comparison, 27 | in components split by character type. 28 | */ 29 | SU_EXPORT @interface SUStandardVersionComparator : NSObject 30 | 31 | /*! 32 | Initializes a new instance of the standard version comparator. 33 | */ 34 | - (instancetype)init; 35 | 36 | /*! 37 | Returns a singleton instance of the comparator. 38 | 39 | It is usually preferred to alloc/init new a comparator instead. 40 | */ 41 | + (SUStandardVersionComparator *)defaultComparator; 42 | 43 | /*! 44 | Compares version strings through textual analysis. 45 | 46 | See the implementation for more details. 47 | */ 48 | - (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; 49 | @end 50 | 51 | NS_ASSUME_NONNULL_END 52 | #endif 53 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUUpdater.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUpdater.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 1/4/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUUPDATER_H 10 | #define SUUPDATER_H 11 | 12 | #if __has_feature(modules) 13 | @import Cocoa; 14 | #else 15 | #import 16 | #endif 17 | #import "SUExport.h" 18 | #import "SUVersionComparisonProtocol.h" 19 | #import "SUVersionDisplayProtocol.h" 20 | 21 | @class SUAppcastItem, SUAppcast; 22 | 23 | @protocol SUUpdaterDelegate; 24 | 25 | /*! 26 | The main API in Sparkle for controlling the update mechanism. 27 | 28 | This class is used to configure the update paramters as well as manually 29 | and automatically schedule and control checks for updates. 30 | */ 31 | SU_EXPORT @interface SUUpdater : NSObject 32 | 33 | @property (unsafe_unretained) IBOutlet id delegate; 34 | 35 | /*! 36 | The shared updater for the main bundle. 37 | 38 | This is equivalent to passing [NSBundle mainBundle] to SUUpdater::updaterForBundle: 39 | */ 40 | + (SUUpdater *)sharedUpdater; 41 | 42 | /*! 43 | The shared updater for a specified bundle. 44 | 45 | If an updater has already been initialized for the provided bundle, that shared instance will be returned. 46 | */ 47 | + (SUUpdater *)updaterForBundle:(NSBundle *)bundle; 48 | 49 | /*! 50 | Designated initializer for SUUpdater. 51 | 52 | If an updater has already been initialized for the provided bundle, that shared instance will be returned. 53 | */ 54 | - (instancetype)initForBundle:(NSBundle *)bundle; 55 | 56 | /*! 57 | Explicitly checks for updates and displays a progress dialog while doing so. 58 | 59 | This method is meant for a main menu item. 60 | Connect any menu item to this action in Interface Builder, 61 | and Sparkle will check for updates and report back its findings verbosely 62 | when it is invoked. 63 | 64 | This will find updates that the user has opted into skipping. 65 | */ 66 | - (IBAction)checkForUpdates:(id)sender; 67 | 68 | /*! 69 | The menu item validation used for the -checkForUpdates: action 70 | */ 71 | - (BOOL)validateMenuItem:(NSMenuItem *)menuItem; 72 | 73 | /*! 74 | Checks for updates, but does not display any UI unless an update is found. 75 | 76 | This is meant for programmatically initating a check for updates. That is, 77 | it will display no UI unless it actually finds an update, in which case it 78 | proceeds as usual. 79 | 80 | If automatic downloading of updates it turned on and allowed, however, 81 | this will invoke that behavior, and if an update is found, it will be downloaded 82 | in the background silently and will be prepped for installation. 83 | 84 | This will not find updates that the user has opted into skipping. 85 | */ 86 | - (void)checkForUpdatesInBackground; 87 | 88 | /*! 89 | A property indicating whether or not to check for updates automatically. 90 | 91 | Setting this property will persist in the host bundle's user defaults. 92 | The update schedule cycle will be reset in a short delay after the property's new value is set. 93 | This is to allow reverting this property without kicking off a schedule change immediately 94 | */ 95 | @property BOOL automaticallyChecksForUpdates; 96 | 97 | /*! 98 | A property indicating whether or not updates can be automatically downloaded in the background. 99 | 100 | Note that automatic downloading of updates can be disallowed by the developer 101 | or by the user's system if silent updates cannot be done (eg: if they require authentication). 102 | In this case, -automaticallyDownloadsUpdates will return NO regardless of how this property is set. 103 | 104 | Setting this property will persist in the host bundle's user defaults. 105 | */ 106 | @property BOOL automaticallyDownloadsUpdates; 107 | 108 | /*! 109 | A property indicating the current automatic update check interval. 110 | 111 | Setting this property will persist in the host bundle's user defaults. 112 | The update schedule cycle will be reset in a short delay after the property's new value is set. 113 | This is to allow reverting this property without kicking off a schedule change immediately 114 | */ 115 | @property NSTimeInterval updateCheckInterval; 116 | 117 | /*! 118 | Begins a "probing" check for updates which will not actually offer to 119 | update to that version. 120 | 121 | However, the delegate methods 122 | SUUpdaterDelegate::updater:didFindValidUpdate: and 123 | SUUpdaterDelegate::updaterDidNotFindUpdate: will be called, 124 | so you can use that information in your UI. 125 | 126 | Updates that have been skipped by the user will not be found. 127 | */ 128 | - (void)checkForUpdateInformation; 129 | 130 | /*! 131 | The URL of the appcast used to download update information. 132 | 133 | Setting this property will persist in the host bundle's user defaults. 134 | If you don't want persistence, you may want to consider instead implementing 135 | SUUpdaterDelegate::feedURLStringForUpdater: or SUUpdaterDelegate::feedParametersForUpdater:sendingSystemProfile: 136 | 137 | This property must be called on the main thread. 138 | */ 139 | @property (copy) NSURL *feedURL; 140 | 141 | /*! 142 | The host bundle that is being updated. 143 | */ 144 | @property (readonly, strong) NSBundle *hostBundle; 145 | 146 | /*! 147 | The bundle this class (SUUpdater) is loaded into. 148 | */ 149 | @property (strong, readonly) NSBundle *sparkleBundle; 150 | 151 | /*! 152 | The user agent used when checking for updates. 153 | 154 | The default implementation can be overrided. 155 | */ 156 | @property (nonatomic, copy) NSString *userAgentString; 157 | 158 | /*! 159 | The HTTP headers used when checking for updates. 160 | 161 | The keys of this dictionary are HTTP header fields (NSString) and values are corresponding values (NSString) 162 | */ 163 | @property (copy) NSDictionary *httpHeaders; 164 | 165 | /*! 166 | A property indicating whether or not the user's system profile information is sent when checking for updates. 167 | 168 | Setting this property will persist in the host bundle's user defaults. 169 | */ 170 | @property BOOL sendsSystemProfile; 171 | 172 | /*! 173 | A property indicating the decryption password used for extracting updates shipped as Apple Disk Images (dmg) 174 | */ 175 | @property (nonatomic, copy) NSString *decryptionPassword; 176 | 177 | /*! 178 | This function ignores normal update schedule, ignores user preferences, 179 | and interrupts users with an unwanted immediate app update. 180 | 181 | WARNING: this function should not be used in regular apps. This function 182 | is a user-unfriendly hack only for very special cases, like unstable 183 | rapidly-changing beta builds that would not run correctly if they were 184 | even one day out of date. 185 | 186 | Instead of this function you should set `SUAutomaticallyUpdate` to `YES`, 187 | which will gracefully install updates when the app quits. 188 | 189 | For UI-less/daemon apps that aren't usually quit, instead of this function, 190 | you can use the delegate method 191 | SUUpdaterDelegate::updater:willInstallUpdateOnQuit:immediateInstallationInvocation: 192 | or 193 | SUUpdaterDelegate::updater:willInstallUpdateOnQuit:immediateInstallationBlock: 194 | to immediately start installation when an update was found. 195 | 196 | A progress dialog is shown but the user will never be prompted to read the 197 | release notes. 198 | 199 | This function will cause update to be downloaded twice if automatic updates are 200 | enabled. 201 | 202 | You may want to respond to the userDidCancelDownload delegate method in case 203 | the user clicks the "Cancel" button while the update is downloading. 204 | */ 205 | - (void)installUpdatesIfAvailable; 206 | 207 | /*! 208 | Returns the date of last update check. 209 | 210 | \returns \c nil if no check has been performed. 211 | */ 212 | @property (readonly, copy) NSDate *lastUpdateCheckDate; 213 | 214 | /*! 215 | Appropriately schedules or cancels the update checking timer according to 216 | the preferences for time interval and automatic checks. 217 | 218 | This call does not change the date of the next check, 219 | but only the internal NSTimer. 220 | */ 221 | - (void)resetUpdateCycle; 222 | 223 | /*! 224 | A property indicating whether or not an update is in progress. 225 | 226 | Note this property is not indicative of whether or not user initiated updates can be performed. 227 | Use SUUpdater::validateMenuItem: for that instead. 228 | */ 229 | @property (readonly) BOOL updateInProgress; 230 | 231 | @end 232 | 233 | #endif 234 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUVersionComparisonProtocol.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 12/21/07. 6 | // Copyright 2007 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SUVERSIONCOMPARISONPROTOCOL_H 10 | #define SUVERSIONCOMPARISONPROTOCOL_H 11 | 12 | #if __has_feature(modules) 13 | @import Foundation; 14 | #else 15 | #import 16 | #endif 17 | #import "SUExport.h" 18 | 19 | NS_ASSUME_NONNULL_BEGIN 20 | 21 | /*! 22 | Provides version comparison facilities for Sparkle. 23 | */ 24 | @protocol SUVersionComparison 25 | 26 | /*! 27 | An abstract method to compare two version strings. 28 | 29 | Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a, 30 | and NSOrderedSame if they are equivalent. 31 | */ 32 | - (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; // *** MAY BE CALLED ON NON-MAIN THREAD! 33 | 34 | @end 35 | 36 | NS_ASSUME_NONNULL_END 37 | #endif 38 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/SUVersionDisplayProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUVersionDisplayProtocol.h 3 | // EyeTV 4 | // 5 | // Created by Uli Kusterer on 08.12.09. 6 | // Copyright 2009 Elgato Systems GmbH. All rights reserved. 7 | // 8 | 9 | #if __has_feature(modules) 10 | @import Foundation; 11 | #else 12 | #import 13 | #endif 14 | #import "SUExport.h" 15 | 16 | /*! 17 | Applies special display formatting to version numbers. 18 | */ 19 | @protocol SUVersionDisplay 20 | 21 | /*! 22 | Formats two version strings. 23 | 24 | Both versions are provided so that important distinguishing information 25 | can be displayed while also leaving out unnecessary/confusing parts. 26 | */ 27 | - (void)formatVersion:(NSString *_Nonnull*_Nonnull)inOutVersionA andVersion:(NSString *_Nonnull*_Nonnull)inOutVersionB; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Headers/Sparkle.h: -------------------------------------------------------------------------------- 1 | // 2 | // Sparkle.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/16/06. (Modified by CDHW on 23/12/07) 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #ifndef SPARKLE_H 10 | #define SPARKLE_H 11 | 12 | // This list should include the shared headers. It doesn't matter if some of them aren't shared (unless 13 | // there are name-space collisions) so we can list all of them to start with: 14 | 15 | #pragma clang diagnostic push 16 | // Do not use <> style includes since 2.x has two frameworks that need to work: Sparkle and SparkleCore 17 | #pragma clang diagnostic ignored "-Wquoted-include-in-framework-header" 18 | 19 | #import "SUAppcast.h" 20 | #import "SUAppcastItem.h" 21 | #import "SUStandardVersionComparator.h" 22 | #import "SUUpdater.h" 23 | #import "SUUpdaterDelegate.h" 24 | #import "SUVersionComparisonProtocol.h" 25 | #import "SUVersionDisplayProtocol.h" 26 | #import "SUErrors.h" 27 | 28 | #import "SPUDownloader.h" 29 | #import "SPUDownloaderDelegate.h" 30 | #import "SPUDownloaderDeprecated.h" 31 | #import "SPUDownloadData.h" 32 | #import "SPUDownloaderProtocol.h" 33 | #import "SPUDownloaderSession.h" 34 | #import "SPUURLRequest.h" 35 | #import "SUCodeSigningVerifier.h" 36 | 37 | #pragma clang diagnostic pop 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module Sparkle { 2 | umbrella header "Sparkle.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/PrivateHeaders/SUUnarchiver.h: -------------------------------------------------------------------------------- 1 | // 2 | // SUUnarchiver.h 3 | // Sparkle 4 | // 5 | // Created by Andy Matuschak on 3/16/06. 6 | // Copyright 2006 Andy Matuschak. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @protocol SUUnarchiverProtocol; 14 | 15 | @interface SUUnarchiver : NSObject 16 | 17 | + (nullable id )unarchiverForPath:(NSString *)path updatingHostBundlePath:(nullable NSString *)hostPath decryptionPassword:(nullable NSString *)decryptionPassword; 18 | 19 | @end 20 | 21 | NS_ASSUME_NONNULL_END 22 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/DarkAqua.css: -------------------------------------------------------------------------------- 1 | html { 2 | color: #FFFFFFD8; 3 | } 4 | :link { 5 | color: #419CFF; 6 | } 7 | :link:active { 8 | color: #FF1919; 9 | } 10 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildMachineOSBuild 6 | 20B28 7 | CFBundleDevelopmentRegion 8 | en 9 | CFBundleExecutable 10 | Sparkle 11 | CFBundleIdentifier 12 | org.sparkle-project.Sparkle 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | Sparkle 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 1.24.0 a-67-g0e162c98 21 | CFBundleSignature 22 | ???? 23 | CFBundleSupportedPlatforms 24 | 25 | MacOSX 26 | 27 | CFBundleVersion 28 | 1.24.0 29 | DTCompiler 30 | com.apple.compilers.llvm.clang.1_0 31 | DTPlatformBuild 32 | 12C5020f 33 | DTPlatformName 34 | macosx 35 | DTPlatformVersion 36 | 11.1 37 | DTSDKBuild 38 | 20C5048g 39 | DTSDKName 40 | macosx11.1 41 | DTXcode 42 | 1230 43 | DTXcodeBuild 44 | 12C5020f 45 | LSMinimumSystemVersion 46 | 10.7 47 | 48 | 49 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/SUStatus.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/SUStatus.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ar.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ar.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ca.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ca.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/el.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/el.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/el.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/el.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fi.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/fi.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fi.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/fi.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fi.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/fi.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fi.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/fi.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr_CA.lproj: -------------------------------------------------------------------------------- 1 | fr.lproj -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/he.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/he.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/hr.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/hr.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/hr.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/hr.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/hr.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/hr.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/hr.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/hr.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/hu.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/hu.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/hu.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/hu.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/hu.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/hu.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/hu.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/hu.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/is.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/is.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ja.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ja.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ko.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ko.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ko.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ko.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nb.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/nb.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nb.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/nb.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pt.lproj: -------------------------------------------------------------------------------- 1 | pt_BR.lproj -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pt_BR.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/pt_PT.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sk.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/sk.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sk.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/sk.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sl.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/sl.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/th.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/th.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/th.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/th.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/tr.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/tr.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/uk.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/uk.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdateAlert.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdateAlert.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdatePermissionPrompt.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdatePermissionPrompt.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/zh_TW.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Sparkle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/omniedgeio/omniedge-macOS/41bb24888fb1a76eda6396d17dadf024ddcd61cf/Sparkle.framework/Versions/A/Sparkle -------------------------------------------------------------------------------- /Sparkle.framework/Versions/Current: -------------------------------------------------------------------------------- 1 | A -------------------------------------------------------------------------------- /Utils/OmError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OmError.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 12/8/2022. 6 | // 7 | 8 | import Foundation 9 | 10 | enum OmError: Error { 11 | case invalidRsp 12 | case invalidUrl 13 | case errCode(Int, String) 14 | case other(Error) 15 | } 16 | -------------------------------------------------------------------------------- /Utils/Utils.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Utils.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 16/7/2022. 6 | // 7 | 8 | import Foundation 9 | import ServiceManagement 10 | import AppKit 11 | 12 | class Utils { 13 | 14 | static func fromHex(hex: String) -> CGColor? { 15 | var hexSanitized = hex.trimmingCharacters(in: .whitespacesAndNewlines) 16 | hexSanitized = hexSanitized.replacingOccurrences(of: "#", with: "") 17 | 18 | var rgb: UInt64 = 0 19 | 20 | var r: CGFloat = 0.0 21 | var g: CGFloat = 0.0 22 | var b: CGFloat = 0.0 23 | var a: CGFloat = 1.0 24 | 25 | let length = hexSanitized.count 26 | 27 | guard Scanner(string: hexSanitized).scanHexInt64(&rgb) else { return nil } 28 | 29 | if length == 6 { 30 | r = CGFloat((rgb & 0xFF0000) >> 16) / 255.0 31 | g = CGFloat((rgb & 0x00FF00) >> 8) / 255.0 32 | b = CGFloat(rgb & 0x0000FF) / 255.0 33 | 34 | } else if length == 8 { 35 | r = CGFloat((rgb & 0xFF000000) >> 24) / 255.0 36 | g = CGFloat((rgb & 0x00FF0000) >> 16) / 255.0 37 | b = CGFloat((rgb & 0x0000FF00) >> 8) / 255.0 38 | a = CGFloat(rgb & 0x000000FF) / 255.0 39 | 40 | } else { 41 | return nil 42 | } 43 | 44 | return CGColor(red: r, green: g, blue: b, alpha: a) 45 | } 46 | 47 | @discardableResult 48 | static func blessHelper(label: String, authorization: AuthorizationRef) -> Bool { 49 | 50 | var error: Unmanaged? 51 | let blessStatus = SMJobBless(kSMDomainSystemLaunchd, label as CFString, authorization, &error) 52 | 53 | if !blessStatus { 54 | NSLog("[SMJBS]: Helper bless failed with error \(error!.takeUnretainedValue())") 55 | 56 | } 57 | 58 | return blessStatus 59 | } 60 | 61 | static func askAuthorization() -> AuthorizationRef? { 62 | 63 | var auth: AuthorizationRef? 64 | let status: OSStatus = AuthorizationCreate(nil, nil, [], &auth) 65 | if status != errAuthorizationSuccess { 66 | NSLog("[SMJBS]: Authorization failed with status code \(status)") 67 | 68 | return nil 69 | } 70 | 71 | return auth 72 | } 73 | 74 | static func alert(title: String, description: String, _ style: NSAlert.Style) { 75 | DispatchQueue.main.async { 76 | let alert = NSAlert() 77 | alert.messageText = title 78 | alert.informativeText = description 79 | alert.alertStyle = style 80 | alert.addButton(withTitle: "OK") 81 | alert.runModal() 82 | } 83 | } 84 | 85 | static func findEthernetInterfaces() -> io_iterator_t? { 86 | 87 | let matchingDict = IOServiceMatching("IOEthernetInterface") as NSMutableDictionary 88 | matchingDict["IOPropertyMatch"] = [ "IOPrimaryInterface" : true] 89 | 90 | var matchingServices : io_iterator_t = 0 91 | if IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &matchingServices) != KERN_SUCCESS { 92 | return nil 93 | } 94 | 95 | return matchingServices 96 | } 97 | 98 | static func getMACAddress(_ intfIterator : io_iterator_t) -> [UInt8]? { 99 | 100 | var macAddress : [UInt8]? 101 | 102 | var intfService = IOIteratorNext(intfIterator) 103 | while intfService != 0 { 104 | 105 | var controllerService : io_object_t = 0 106 | if IORegistryEntryGetParentEntry(intfService, "IOService", &controllerService) == KERN_SUCCESS { 107 | 108 | let dataUM = IORegistryEntryCreateCFProperty(controllerService, "IOMACAddress" as CFString, kCFAllocatorDefault, 0) 109 | if let data = dataUM?.takeRetainedValue() as? NSData { 110 | macAddress = [0, 0, 0, 0, 0, 0] 111 | data.getBytes(&macAddress!, length: macAddress!.count) 112 | } 113 | IOObjectRelease(controllerService) 114 | } 115 | 116 | IOObjectRelease(intfService) 117 | intfService = IOIteratorNext(intfIterator) 118 | } 119 | 120 | return macAddress 121 | } 122 | 123 | static func getDeviceInfo() -> DeviceModel? { 124 | let deviceName = ProcessInfo.processInfo.hostName 125 | // let osVersion = ProcessInfo.processInfo.operatingSystemVersionString 126 | guard let hardwareUUID = self.getHardwareUUID() else { 127 | return nil 128 | } 129 | 130 | return DeviceModel(deviceName: deviceName, deviceUuid: hardwareUUID, deviceOS: "macOS") 131 | } 132 | 133 | static func getHardwareUUID() -> String? { 134 | let dev = IOServiceMatching("IOPlatformExpertDevice") 135 | let platformExpert: io_service_t = IOServiceGetMatchingService(kIOMasterPortDefault, dev) 136 | let serialNumberAsCFString = IORegistryEntryCreateCFProperty(platformExpert, kIOPlatformUUIDKey as CFString, kCFAllocatorDefault, 0) 137 | IOObjectRelease(platformExpert) 138 | let ser: CFTypeRef? = serialNumberAsCFString?.takeUnretainedValue() 139 | 140 | guard let result = ser as? String else { 141 | return nil 142 | } 143 | 144 | return result 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /Views/BaseView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseView.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 19/7/2022. 6 | // 7 | 8 | import Foundation 9 | import AppKit 10 | 11 | class BaseView: NSView { 12 | 13 | init() { 14 | super.init(frame: .zero) 15 | } 16 | 17 | @available(*, unavailable) 18 | required init?(coder: NSCoder) { 19 | fatalError("init(coder:) has not been implemented") 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Views/NetworkItemDetailView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkItemDetailView.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 20/7/2022. 6 | // 7 | 8 | import Foundation 9 | import OGSwitch 10 | 11 | protocol NetworItemDetailViewDelegate: AnyObject { 12 | func didToggled(on: Bool); 13 | } 14 | 15 | class NetworkItemDetailView: BaseView { 16 | weak public var delegate: NetworItemDetailViewDelegate? 17 | 18 | private var seperatorBottomCopnstraint: NSLayoutConstraint? 19 | private var model: VirtualNetworkModel 20 | private var deviceItemViews: [OmniLabel] = [] 21 | private var enableConnection: Bool = true 22 | 23 | init(model: VirtualNetworkModel, enableConnection: Bool) { 24 | self.model = model 25 | self.enableConnection = enableConnection 26 | super.init() 27 | self.initView() 28 | self.initLayout() 29 | } 30 | 31 | func toggleOff() { 32 | self.connSwitch.setOn(isOn: false, animated: true) 33 | } 34 | 35 | func toggleOn() { 36 | self.connSwitch.setOn(isOn: true, animated: true) 37 | } 38 | 39 | private func initView() { 40 | self.translatesAutoresizingMaskIntoConstraints = false 41 | self.addSubview(self.deviceListTitle) 42 | self.addSubview(self.connSwitch) 43 | self.addSubview(self.seperator) 44 | self.createDeviceItemView() 45 | self.connSwitch.isHidden = !self.enableConnection 46 | } 47 | 48 | private func initLayout() { 49 | NSLayoutConstraint.activate([ 50 | self.connSwitch.topAnchor.constraint(equalTo: self.topAnchor, constant: Constants.Margins.margin5), 51 | self.connSwitch.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: -Constants.Margins.margin5), 52 | self.connSwitch.widthAnchor.constraint(equalToConstant: 40), 53 | self.connSwitch.heightAnchor.constraint(equalToConstant: 20), 54 | 55 | self.deviceListTitle.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: Constants.Margins.margin5), 56 | self.deviceListTitle.topAnchor.constraint(equalTo: self.topAnchor, constant: Constants.Margins.margin5), 57 | self.deviceListTitle.trailingAnchor.constraint(equalTo: self.connSwitch.leadingAnchor, constant: Constants.Margins.margin5), 58 | 59 | self.seperator.leadingAnchor.constraint(equalTo: self.leadingAnchor), 60 | self.seperator.trailingAnchor.constraint(equalTo: self.trailingAnchor), 61 | self.seperator.topAnchor.constraint(equalTo: self.connSwitch.bottomAnchor, constant: Constants.Margins.margin5), 62 | self.seperator.heightAnchor.constraint(equalToConstant: 1.0), 63 | 64 | self.widthAnchor.constraint(equalToConstant: 290) 65 | ]) 66 | 67 | self.layoutDeviceItemViews() 68 | } 69 | 70 | private func createDeviceItemView() { 71 | self.model.devices?.forEach { device in 72 | let view = OmniLabel() 73 | view.translatesAutoresizingMaskIntoConstraints = false 74 | view.stringValue = "\(device.deviceName) \(device.virtualIp ?? String.Empty)" 75 | self.deviceItemViews.append(view) 76 | self.addSubview(view) 77 | } 78 | } 79 | 80 | private func layoutDeviceItemViews() { 81 | if self.deviceItemViews.count == 0 { 82 | self.seperatorBottomCopnstraint = self.seperator.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -10) 83 | self.seperatorBottomCopnstraint?.isActive = true 84 | return 85 | } 86 | 87 | var previousView: NSView = self.seperator 88 | self.deviceItemViews.forEach { itemView in 89 | NSLayoutConstraint.activate([ 90 | itemView.leadingAnchor.constraint(equalTo: self.deviceListTitle.leadingAnchor), 91 | itemView.trailingAnchor.constraint(equalTo: self.deviceListTitle.trailingAnchor), 92 | itemView.topAnchor.constraint(equalTo: previousView.bottomAnchor, constant: Constants.Margins.margin10), 93 | ]) 94 | 95 | previousView = itemView 96 | } 97 | 98 | self.deviceItemViews.last?.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -Constants.Margins.margin10).isActive = true 99 | } 100 | 101 | @objc private func didToggled() { 102 | self.delegate?.didToggled(on: self.connSwitch.isOn) 103 | } 104 | 105 | // Lazy loading 106 | private lazy var deviceListTitle: OmniLabel = { 107 | let view = OmniLabel() 108 | view.stringValue = "Devices of " + model.vnName 109 | view.translatesAutoresizingMaskIntoConstraints = false 110 | return view 111 | }() 112 | 113 | private lazy var connSwitch: OGSwitch = { 114 | let view = OGSwitch() 115 | view.target = self 116 | view.action = #selector(didToggled) 117 | view.translatesAutoresizingMaskIntoConstraints = false 118 | return view 119 | }() 120 | 121 | private lazy var seperator: NSView = { 122 | let view = NSView() 123 | view.wantsLayer = true 124 | view.layer?.backgroundColor = NSColor.lightGray.cgColor 125 | view.translatesAutoresizingMaskIntoConstraints = false 126 | return view 127 | }() 128 | } 129 | -------------------------------------------------------------------------------- /Views/NetworkItemView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkItemView.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 19/7/2022. 6 | // 7 | 8 | import Foundation 9 | import AppKit 10 | 11 | class NetworkItemView: BaseView { 12 | 13 | private var isMouseOver: Bool = false { 14 | didSet { 15 | self.backgroundColor = isMouseOver ? .blue : .clear 16 | } 17 | } 18 | 19 | private var backgroundColor: NSColor? { 20 | didSet { 21 | self.setNeedsDisplay(self.bounds) 22 | } 23 | } 24 | 25 | private var didAddTrackingArea: Bool = false 26 | 27 | override init() { 28 | super.init() 29 | self.initView() 30 | self.initLayout() 31 | } 32 | 33 | convenience init(title: String) { 34 | self.init() 35 | self.titleLabel.stringValue = title 36 | } 37 | 38 | private func initView() { 39 | self.addSubview(self.titleLabel) 40 | self.addSubview(self.detailIndicator) 41 | } 42 | 43 | private func initLayout() { 44 | NSLayoutConstraint.activate([ 45 | self.titleLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor), 46 | self.titleLabel.trailingAnchor.constraint(equalTo: self.detailIndicator.leadingAnchor, constant: -Constants.Margins.margin10), 47 | self.titleLabel.topAnchor.constraint(equalTo: self.topAnchor, constant: Constants.Margins.margin5), 48 | self.titleLabel.bottomAnchor.constraint(equalTo:self.bottomAnchor, constant: -Constants.Margins.margin5), 49 | 50 | self.detailIndicator.trailingAnchor.constraint(equalTo: self.trailingAnchor), 51 | self.detailIndicator.centerYAnchor.constraint(equalTo: self.titleLabel.centerYAnchor), 52 | self.detailIndicator.widthAnchor.constraint(equalTo: self.detailIndicator.heightAnchor) 53 | ]) 54 | 55 | self.detailIndicator.setContentHuggingPriority(.defaultHigh + 1, for: .horizontal) 56 | self.detailIndicator.setContentCompressionResistancePriority(.defaultLow + 1, for: .horizontal) 57 | } 58 | 59 | @objc private func didTitleLabelClicked() { 60 | return 61 | } 62 | 63 | // override func updateTrackingAreas() { 64 | // var trackingAreas = self.trackingAreas 65 | // trackingAreas.removeAll() 66 | // print(self.bounds) 67 | // let hoverArea = NSTrackingArea(rect: self.bounds, options: [.mouseEnteredAndExited, .mouseMoved, .activeInActiveApp, .inVisibleRect, .assumeInside, .cursorUpdate], owner: self, userInfo: nil) 68 | // self.addTrackingArea(hoverArea) 69 | // } 70 | // 71 | // override func mouseEntered(with event: NSEvent) { 72 | // self.isMouseOver = true 73 | // } 74 | // 75 | // override func mouseExited(with event: NSEvent) { 76 | // self.isMouseOver = false 77 | // } 78 | 79 | private lazy var titleLabel: OmniLabel = { 80 | let view = OmniLabel() 81 | view.font = NSFont.systemFont(ofSize: 14) 82 | view.translatesAutoresizingMaskIntoConstraints = false 83 | view.addClick(target: self, action: #selector(didTitleLabelClicked)) 84 | return view 85 | }() 86 | 87 | private lazy var detailIndicator: OmniLabel = { 88 | let view = OmniLabel() 89 | view.translatesAutoresizingMaskIntoConstraints = false 90 | view.stringValue = "〉" 91 | return view 92 | }() 93 | } 94 | -------------------------------------------------------------------------------- /Views/OmniButtonCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OmniButtonCell.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 19/7/2022. 6 | // 7 | 8 | import Foundation 9 | import AppKit 10 | 11 | // https://gist.github.com/marteinn/fa9301ad349b755da2e6 12 | class OmniButtonCell: NSButtonCell { 13 | 14 | // - (NSRect)titleRectForBounds:(NSRect)theRect { 15 | // NSRect titleFrame = [super titleRectForBounds:theRect]; 16 | // NSSize titleSize = [[self attributedStringValue] size]; 17 | // 18 | // titleFrame.origin.y = theRect.origin.y-(theRect.size.height-titleSize.height)*0.5; 19 | // 20 | // return titleFrame; 21 | // } 22 | 23 | override func titleRect(forBounds rect: NSRect) -> NSRect { 24 | var titleFrame = super.titleRect(forBounds: rect) 25 | titleFrame.origin.x = 0 26 | 27 | return titleFrame 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Views/OmniLabel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OmniLabel.swift 3 | // Omniedge 4 | // 5 | // Created by Yanbo Dang on 16/7/2022. 6 | // 7 | 8 | import Foundation 9 | import AppKit 10 | 11 | class OmniLabel: NSTextField { 12 | 13 | private var clickGesture: NSClickGestureRecognizer 14 | 15 | init() { 16 | self.clickGesture = NSClickGestureRecognizer() 17 | super.init(frame: .zero) 18 | self.initLabel() 19 | } 20 | 21 | required init?(coder: NSCoder) { 22 | fatalError("init(coder:) has not been implemented") 23 | } 24 | 25 | func addClick(target: AnyObject, action: Selector) { 26 | self.clickGesture.target = target 27 | self.clickGesture.action = action 28 | } 29 | 30 | private func initLabel() { 31 | self.usesSingleLineMode = false 32 | self.isEditable = false 33 | self.isBezeled = false 34 | self.alignment = .left 35 | self.translatesAutoresizingMaskIntoConstraints = false 36 | self.backgroundColor = .clear 37 | self.addGestureRecognizer(self.clickGesture) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /appdmg.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Omniedge", 3 | "icon": "", 4 | "background": "", 5 | "contents": [ 6 | { "x": 448, "y": 344, "type": "link", "path": "/Applications" }, 7 | { "x": 192, "y": 344, "type": "file", "path": "/Users/yanbodang/Desktop/Omniedge/Products/Applications/Omniedge.app" } 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /uninstall.sh: -------------------------------------------------------------------------------- 1 | PRIVILEGED_HELPER_LABEL=io.omniedge.mac.Omniedge.HelperTool 2 | 3 | sudo rm /Library/PrivilegedHelperTools/$PRIVILEGED_HELPER_LABEL 4 | sudo rm /Library/LaunchDaemons/$PRIVILEGED_HELPER_LABEL.plist 5 | sudo launchctl bootout system/$PRIVILEGED_HELPER_LABEL #'Boot-out failed: 36: Operation now in progress' is OK output 6 | 7 | echo "Querying launchd..." 8 | LAUNCHD_OUTPUT=$(sudo launchctl list | grep $PRIVILEGED_HELPER_LABEL) 9 | 10 | 11 | if [ -z "$LAUNCHD_OUTPUT" ] 12 | then 13 | echo "Finished successfully." 14 | else 15 | echo "WARNING: $PRIVILEGED_HELPER_LABEL is not removed" 16 | fi 17 | --------------------------------------------------------------------------------