├── Sparkle.framework ├── Versions │ ├── Current │ └── A │ │ ├── Sparkle │ │ ├── Resources │ │ ├── relaunch │ │ ├── fr_CA.lproj │ │ ├── de.lproj │ │ │ ├── Sparkle.strings │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ ├── en.lproj │ │ │ ├── Sparkle.strings │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ ├── es.lproj │ │ │ ├── Sparkle.strings │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ ├── fr.lproj │ │ │ ├── Sparkle.strings │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ ├── it.lproj │ │ │ ├── Sparkle.strings │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ ├── nl.lproj │ │ │ ├── Sparkle.strings │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ ├── ru.lproj │ │ │ ├── Sparkle.strings │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ ├── sv.lproj │ │ │ ├── Sparkle.strings │ │ │ ├── SUUpdateAlert.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ │ ├── SUAutomaticUpdateAlert.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ │ └── SUUpdatePermissionPrompt.nib │ │ │ │ ├── keyedobjects.nib │ │ │ │ ├── info.nib │ │ │ │ └── classes.nib │ │ ├── SUStatus.nib │ │ │ ├── keyedobjects.nib │ │ │ ├── info.nib │ │ │ └── classes.nib │ │ ├── Info.plist │ │ ├── License.txt │ │ └── SUModelTranslation.plist │ │ └── Headers │ │ ├── Sparkle.h │ │ ├── SUAppcast.h │ │ ├── SUVersionComparisonProtocol.h │ │ ├── SUAppcastItem.h │ │ └── SUUpdater.h ├── Headers ├── Resources └── Sparkle ├── add.icns ├── red.png ├── Icon.icns ├── green.png ├── lock.icns ├── disabled.png ├── locate.icns ├── message.icns ├── refresh.icns ├── remove.icns ├── English.lproj └── InfoPlist.strings ├── DeviceIcons ├── Device-iPhone-3G.png ├── Device-iPhone-3GS.png ├── Device-iPad-Generic.png ├── Device-iPhone-3G@2x.png ├── Device-iPod-Generic.png ├── Device-Generic-Generic.png ├── Device-iPad-FirstGen.png ├── Device-iPad-Generic@2x.png ├── Device-iPad-SecondGen.png ├── Device-iPhone-3G-mini.png ├── Device-iPhone-3GS-mini.png ├── Device-iPhone-3GS@2x.png ├── Device-iPhone-FirstGen.png ├── Device-iPhone-Generic.png ├── Device-iPod-FirstGen.png ├── Device-iPod-FourthGen.png ├── Device-iPod-Generic@2x.png ├── Device-iPod-SecondGen.png ├── Device-iPod-ThirdGen.png ├── Device-iPad-FirstGen@2x.png ├── Device-iPad-Generic-mini.png ├── Device-iPad-SecondGen@2x.png ├── Device-iPhone-3G-mini@2x.png ├── Device-iPhone-FourthGen.png ├── Device-iPhone-Generic@2x.png ├── Device-iPod-FirstGen@2x.png ├── Device-iPod-FourthGen@2x.png ├── Device-iPod-Generic-mini.png ├── Device-iPod-SecondGen@2x.png ├── Device-iPod-ThirdGen@2x.png ├── Device-Generic-Generic-mini.png ├── Device-Generic-Generic@2x.png ├── Device-iPad-FirstGen-mini.png ├── Device-iPad-Generic-mini@2x.png ├── Device-iPad-SecondGen-mini.png ├── Device-iPhone-3GS-mini@2x.png ├── Device-iPhone-FirstGen-mini.png ├── Device-iPhone-FirstGen@2x.png ├── Device-iPhone-FourthGen@2x.png ├── Device-iPhone-Generic-mini.png ├── Device-iPod-FirstGen-mini.png ├── Device-iPod-FourthGen-mini.png ├── Device-iPod-Generic-mini@2x.png ├── Device-iPod-SecondGen-mini.png ├── Device-iPod-ThirdGen-mini.png ├── Device-iPad-FirstGen-mini@2x.png ├── Device-iPad-SecondGen-mini@2x.png ├── Device-iPhone-FourthGen-mini.png ├── Device-iPhone-Generic-mini@2x.png ├── Device-iPod-FirstGen-mini@2x.png ├── Device-iPod-FourthGen-mini@2x.png ├── Device-iPod-SecondGen-mini@2x.png ├── Device-iPod-ThirdGen-mini@2x.png ├── Device-Generic-Generic-mini@2x.png ├── Device-iPhone-FirstGen-mini@2x.png └── Device-iPhone-FourthGen-mini@2x.png ├── .gitignore ├── Sosumi_Prefix.pch ├── Sosumi.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── thall.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── thall.xcuserdatad │ ├── xcdebugger │ └── Breakpoints.xcbkptlist │ └── xcschemes │ ├── xcschememanagement.plist │ └── Sosumi.xcscheme ├── THGradientBar.h ├── main.m ├── THNetworkActivityManager.h ├── THImageRow.h ├── THNetworkActivityCell.h ├── NetworkSpinner.h ├── deviceIcons.sh ├── Sosumi.sdef ├── THNetworkActivityCell.m ├── NSData+Base64.h ├── dsa_pub.pem ├── SSMAccount.h ├── Sosumi-Info.plist ├── Credits.rtf ├── THImageRow.m ├── SSMDevice.h ├── NetworkSpinner.m ├── SosumiAppDelegate.h ├── THNetworkActivityManager.m ├── map.html ├── JSON ├── NSString+SBJSON.m ├── NSObject+SBJSON.m ├── NSString+SBJSON.h ├── NSObject+SBJSON.h ├── JSON.h ├── SBJsonBase.m ├── SBJsonBase.h ├── SBJsonParser.h ├── SBJsonWriter.h └── SBJsonWriter.m ├── README.markdown ├── THGradientBar.m ├── SSMDevice.m ├── SosumiAPI.plist ├── EMKeychain └── EMKeychainItem.h ├── NSData+Base64.m ├── SSMAccount.m └── SosumiAppDelegate.m /Sparkle.framework/Versions/Current: -------------------------------------------------------------------------------- 1 | A -------------------------------------------------------------------------------- /Sparkle.framework/Headers: -------------------------------------------------------------------------------- 1 | Versions/Current/Headers -------------------------------------------------------------------------------- /Sparkle.framework/Resources: -------------------------------------------------------------------------------- 1 | Versions/Current/Resources -------------------------------------------------------------------------------- /Sparkle.framework/Sparkle: -------------------------------------------------------------------------------- 1 | Versions/Current/Sparkle -------------------------------------------------------------------------------- /add.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/add.icns -------------------------------------------------------------------------------- /red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/red.png -------------------------------------------------------------------------------- /Icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Icon.icns -------------------------------------------------------------------------------- /green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/green.png -------------------------------------------------------------------------------- /lock.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/lock.icns -------------------------------------------------------------------------------- /disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/disabled.png -------------------------------------------------------------------------------- /locate.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/locate.icns -------------------------------------------------------------------------------- /message.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/message.icns -------------------------------------------------------------------------------- /refresh.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/refresh.icns -------------------------------------------------------------------------------- /remove.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/remove.icns -------------------------------------------------------------------------------- /English.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-3G.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-3G.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-3GS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-3GS.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPad-Generic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPad-Generic.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-3G@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-3G@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-Generic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-Generic.png -------------------------------------------------------------------------------- /DeviceIcons/Device-Generic-Generic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-Generic-Generic.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPad-FirstGen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPad-FirstGen.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPad-Generic@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPad-Generic@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPad-SecondGen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPad-SecondGen.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-3G-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-3G-mini.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-3GS-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-3GS-mini.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-3GS@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-3GS@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-FirstGen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-FirstGen.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-Generic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-Generic.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-FirstGen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-FirstGen.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-FourthGen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-FourthGen.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-Generic@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-Generic@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-SecondGen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-SecondGen.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-ThirdGen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-ThirdGen.png -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Sparkle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Sparkle -------------------------------------------------------------------------------- /DeviceIcons/Device-iPad-FirstGen@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPad-FirstGen@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPad-Generic-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPad-Generic-mini.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPad-SecondGen@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPad-SecondGen@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-3G-mini@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-3G-mini@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-FourthGen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-FourthGen.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-Generic@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-Generic@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-FirstGen@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-FirstGen@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-FourthGen@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-FourthGen@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-Generic-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-Generic-mini.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-SecondGen@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-SecondGen@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-ThirdGen@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-ThirdGen@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-Generic-Generic-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-Generic-Generic-mini.png -------------------------------------------------------------------------------- /DeviceIcons/Device-Generic-Generic@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-Generic-Generic@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPad-FirstGen-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPad-FirstGen-mini.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPad-Generic-mini@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPad-Generic-mini@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPad-SecondGen-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPad-SecondGen-mini.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-3GS-mini@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-3GS-mini@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-FirstGen-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-FirstGen-mini.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-FirstGen@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-FirstGen@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-FourthGen@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-FourthGen@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-Generic-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-Generic-mini.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-FirstGen-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-FirstGen-mini.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-FourthGen-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-FourthGen-mini.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-Generic-mini@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-Generic-mini@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-SecondGen-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-SecondGen-mini.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-ThirdGen-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-ThirdGen-mini.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPad-FirstGen-mini@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPad-FirstGen-mini@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPad-SecondGen-mini@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPad-SecondGen-mini@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-FourthGen-mini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-FourthGen-mini.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-Generic-mini@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-Generic-mini@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-FirstGen-mini@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-FirstGen-mini@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-FourthGen-mini@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-FourthGen-mini@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-SecondGen-mini@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-SecondGen-mini@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPod-ThirdGen-mini@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPod-ThirdGen-mini@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-Generic-Generic-mini@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-Generic-Generic-mini@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-FirstGen-mini@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-FirstGen-mini@2x.png -------------------------------------------------------------------------------- /DeviceIcons/Device-iPhone-FourthGen-mini@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/DeviceIcons/Device-iPhone-FourthGen-mini@2x.png -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/relaunch: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/relaunch -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr_CA.lproj: -------------------------------------------------------------------------------- 1 | /Users/andym/Development/Build Products/Release (GC dual-mode; 10.5-only)/Sparkle.framework/Resources/fr.lproj -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.swp 3 | *~.nib 4 | 5 | build 6 | 7 | *.pbxuser 8 | *.perspective 9 | *.perspectivev3 10 | 11 | *.mode1v3 12 | *.mode2v3 13 | 14 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings -------------------------------------------------------------------------------- /Sosumi_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'Sosumi' target in the 'Sosumi' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/SUStatus.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/SUStatus.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sosumi.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Sosumi.xcodeproj/project.xcworkspace/xcuserdata/thall.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tylerhall/MacSosumi/master/Sosumi.xcodeproj/project.xcworkspace/xcuserdata/thall.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /THGradientBar.h: -------------------------------------------------------------------------------- 1 | // 2 | // THHorizontalGradient.h 3 | // Incoming! 4 | // 5 | // Created by Tyler Hall on 7/1/09. 6 | // Copyright 2009 Click On Tyler, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface THGradientBar : NSView { 13 | 14 | } 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Sosumi 4 | // 5 | // Created by Tyler Hall on 11/28/10. 6 | // Copyright 2010 Click On Tyler, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **) argv); 14 | } 15 | -------------------------------------------------------------------------------- /THNetworkActivityManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // SyncActivityManager.h 3 | // Nottingham3 4 | // 5 | // Created by Tyler Hall on 10/10/10. 6 | // Copyright 2010 Click On Tyler, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface THNetworkActivityManager : NSArrayController { 13 | 14 | } 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /THImageRow.h: -------------------------------------------------------------------------------- 1 | // 2 | // THQueryCell.h 3 | // Incoming! 4 | // 5 | // Created by Tyler Hall on 7/4/09. 6 | // Copyright 2009 Click On Tyler, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface THImageRow : NSTextFieldCell { 13 | NSString *imageName; 14 | NSNumber *isShared; 15 | } 16 | 17 | @property (nonatomic, retain) NSString * imageName; 18 | @property (nonatomic, retain) NSNumber * isShared; 19 | 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /Sosumi.xcodeproj/xcuserdata/thall.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /THNetworkActivityCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // THNetworkActivityCell.h 3 | // Nottingham 4 | // 5 | // Created by Tyler Hall on 1/15/11. 6 | // Copyright 2011 Click On Tyler, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface THNetworkActivityCell : NSTextFieldCell { 13 | NSString *title; 14 | NSString *subtitle; 15 | } 16 | 17 | @property (nonatomic, retain) NSString *title; 18 | @property (nonatomic, retain) NSString *subtitle; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /NetworkSpinner.h: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkSpinner.h 3 | // Tennessee Traffic 4 | // 5 | // Created by Tyler Hall on 8/15/10. 6 | // Copyright 2010 Click On Tyler, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface NetworkSpinner : NSObject { 13 | int count; 14 | BOOL hasError; 15 | } 16 | 17 | - (void)realQueue; 18 | - (void)realDequeue; 19 | + (NetworkSpinner *)sharedSpinner; 20 | + (void)queue; 21 | + (void)dequeue; 22 | - (void)realHasError; 23 | + (void)networkError; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /deviceIcons.sh: -------------------------------------------------------------------------------- 1 | # Handy script to un-dereference the symlinks inside Apple's FMIP deviceIcons folder. 2 | # http://serverfault.com/questions/149609/replace-symbolic-link-with-target 3 | find . -type l | while read -r link 4 | do 5 | target=$(readlink "$link") 6 | if [ -e "$target" ] 7 | then 8 | rm "$link" && cp "$target" "$link" || echo "ERROR: Unable to change $link to $target" 9 | else 10 | # remove the ": # " from the following line to enable the error message 11 | : # echo "ERROR: Broken symlink" 12 | fi 13 | done 14 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 629 7 | IBOldestOS 8 | 5 9 | IBOpenObjects 10 | 11 | IBSystem Version 12 | 9E17 13 | targetFramework 14 | IBCocoaFramework 15 | 16 | 17 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 629 7 | IBOldestOS 8 | 5 9 | IBOpenObjects 10 | 11 | IBSystem Version 12 | 9E17 13 | targetFramework 14 | IBCocoaFramework 15 | 16 | 17 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 629 7 | IBOldestOS 8 | 5 9 | IBOpenObjects 10 | 11 | IBSystem Version 12 | 9D34 13 | targetFramework 14 | IBCocoaFramework 15 | 16 | 17 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 629 7 | IBOldestOS 8 | 5 9 | IBOpenObjects 10 | 11 | IBSystem Version 12 | 9E17 13 | targetFramework 14 | IBCocoaFramework 15 | 16 | 17 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 629 7 | IBOldestOS 8 | 5 9 | IBOpenObjects 10 | 11 | IBSystem Version 12 | 9E17 13 | targetFramework 14 | IBCocoaFramework 15 | 16 | 17 | -------------------------------------------------------------------------------- /Sosumi.sdef: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 629 7 | IBOldestOS 8 | 5 9 | IBOpenObjects 10 | 11 | 6 12 | 13 | IBSystem Version 14 | 9D34 15 | targetFramework 16 | IBCocoaFramework 17 | 18 | 19 | -------------------------------------------------------------------------------- /Sosumi.xcodeproj/xcuserdata/thall.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Sosumi.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 8D1107260486CEB800E47090 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /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 | #import 16 | 17 | #import 18 | #import 19 | #import 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 670 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | IBSystem Version 14 | 9E17 15 | targetFramework 16 | IBCocoaFramework 17 | 18 | 19 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/SUStatus.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 670 7 | IBLastKnownRelativeProjectPath 8 | Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 10A96 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 667 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9D34 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 667 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9D34 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 667 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9D34 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 670 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9E17 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBDocumentLocation 6 | 69 14 356 240 0 0 1280 778 7 | IBFramework Version 8 | 489.0 9 | IBLastKnownRelativeProjectPath 10 | ../Sparkle.xcodeproj 11 | IBOldestOS 12 | 5 13 | IBSystem Version 14 | 9D34 15 | targetFramework 16 | IBCocoaFramework 17 | 18 | 19 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 670 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 18 14 | 15 | IBSystem Version 16 | 10A96 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 667 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9D34 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 667 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9D34 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 658 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9C7010 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 667 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9D34 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 667 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9D34 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 667 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 5 14 | 15 | IBSystem Version 16 | 9D34 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 670 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9E17 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 670 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 10A96 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 667 7 | IBLastKnownRelativeProjectPath 8 | ../../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 9D34 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 670 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 15 | IBSystem Version 16 | 10A96 17 | targetFramework 18 | IBCocoaFramework 19 | 20 | 21 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBFramework Version 6 | 670 7 | IBLastKnownRelativeProjectPath 8 | ../Sparkle.xcodeproj 9 | IBOldestOS 10 | 5 11 | IBOpenObjects 12 | 13 | 6 14 | 41 15 | 16 | IBSystem Version 17 | 10A96 18 | targetFramework 19 | IBCocoaFramework 20 | 21 | 22 | -------------------------------------------------------------------------------- /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 | @class SUAppcastItem; 13 | @interface SUAppcast : NSObject { 14 | NSArray *items; 15 | NSString *userAgentString; 16 | id delegate; 17 | NSMutableData *incrementalData; 18 | } 19 | 20 | - (void)fetchAppcastFromURL:(NSURL *)url; 21 | - (void)setDelegate:delegate; 22 | - (void)setUserAgentString:(NSString *)userAgentString; 23 | 24 | - (NSArray *)items; 25 | 26 | @end 27 | 28 | @interface NSObject (SUAppcastDelegate) 29 | - (void)appcastDidFinishLoading:(SUAppcast *)appcast; 30 | - (void)appcast:(SUAppcast *)appcast failedToLoadWithError:(NSError *)error; 31 | @end 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | Sparkle 9 | CFBundleIdentifier 10 | org.andymatuschak.Sparkle 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | Sparkle 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.5 Beta 6 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 313 23 | 24 | 25 | -------------------------------------------------------------------------------- /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 | /*! 13 | @protocol 14 | @abstract Implement this protocol to provide version comparison facilities for Sparkle. 15 | */ 16 | @protocol SUVersionComparison 17 | 18 | /*! 19 | @method 20 | @abstract An abstract method to compare two version strings. 21 | @discussion Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a, and NSOrderedSame if they are equivalent. 22 | */ 23 | - (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; 24 | 25 | @end 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /THNetworkActivityCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // THNetworkActivityCell.m 3 | // Nottingham 4 | // 5 | // Created by Tyler Hall on 1/15/11. 6 | // Copyright 2011 Click On Tyler, LLC. All rights reserved. 7 | // 8 | 9 | #import "THNetworkActivityCell.h" 10 | 11 | 12 | @implementation THNetworkActivityCell 13 | 14 | @synthesize title; 15 | @synthesize subtitle; 16 | 17 | - (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView { 18 | [super drawWithFrame:cellFrame inView:controlView]; 19 | 20 | NSRect rect = cellFrame; 21 | rect.origin.x += 5.0; 22 | rect.origin.y += 15.0; 23 | 24 | NSMutableAttributedString *as = [[NSMutableAttributedString alloc] initWithString:self.subtitle]; 25 | NSFont *font = [NSFont systemFontOfSize:10.0]; 26 | NSDictionary *attrs = @{NSFontAttributeName: font, NSForegroundColorAttributeName: [NSColor blackColor]}; 27 | [as addAttributes:attrs range:NSMakeRange(0, [as length])]; 28 | [as drawInRect:rect]; 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /NSData+Base64.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+Base64.h 3 | // base64 4 | // 5 | // Created by Matt Gallagher on 2009/06/03. 6 | // Copyright 2009 Matt Gallagher. All rights reserved. 7 | // 8 | // Permission is given to use this source code file, free of charge, in any 9 | // project, commercial or otherwise, entirely at your risk, with the condition 10 | // that any redistribution (in part or whole) of source code must retain 11 | // this copyright and permission notice. Attribution in compiled projects is 12 | // appreciated but not required. 13 | // 14 | 15 | #import 16 | 17 | void *NewBase64Decode( 18 | const char *inputBuffer, 19 | size_t length, 20 | size_t *outputLength); 21 | 22 | char *NewBase64Encode( 23 | const void *inputBuffer, 24 | size_t length, 25 | bool separateLines, 26 | size_t *outputLength); 27 | 28 | @interface NSData (Base64) 29 | 30 | + (NSData *)dataFromBase64String:(NSString *)aString; 31 | - (NSString *)base64EncodedString; 32 | 33 | @end 34 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006 Andy Matuschak 2 | 3 | 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: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | 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. -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | { 2 | IBClasses = ( 3 | { 4 | CLASS = FirstResponder; 5 | LANGUAGE = ObjC; 6 | SUPERCLASS = NSObject; 7 | }, 8 | { 9 | CLASS = NSApplication; 10 | LANGUAGE = ObjC; 11 | SUPERCLASS = NSResponder; 12 | }, 13 | { 14 | CLASS = NSObject; 15 | LANGUAGE = ObjC; 16 | }, 17 | { 18 | ACTIONS = { 19 | installUpdate = id; 20 | remindMeLater = id; 21 | skipThisVersion = id; 22 | }; 23 | CLASS = SUUpdateAlert; 24 | LANGUAGE = ObjC; 25 | OUTLETS = { 26 | delegate = id; 27 | description = NSTextField; 28 | releaseNotesView = WebView; 29 | }; 30 | SUPERCLASS = SUWindowController; 31 | }, 32 | { 33 | CLASS = SUWindowController; 34 | LANGUAGE = ObjC; 35 | SUPERCLASS = NSWindowController; 36 | } 37 | ); 38 | IBVersion = 1; 39 | } -------------------------------------------------------------------------------- /dsa_pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIDOjCCAi0GByqGSM44BAEwggIgAoIBAQCMgMkVOyRtc0VdHc6f5txKITDa83UO 3 | ZNBRE5cuwPN8vJOnf9nAh8a42Dp9uoaPSytKOM4ZQYXdSd3Wq/jEqxNKNjFrC44Y 4 | SwMOef1B7dtVltTsmr5M6VzF3dziobKQeY1q2RML1wtwIone24Yt0KrPPZR4668P 5 | uHZt3gOpGqbXnsnBxl4WopNFtKfnw9ebiq/r2p9mH5OLuRChkP/1dT7x610+FviD 6 | 5Sv0h/oJ1C4cvXhKQtirDitP/PQtATU//AaB8Xgi4wSzNkJ4cuEoPpx4xS2BC42F 7 | a8cV/2RMwJKwoF36SEujYdUlC1kCwBJpYwK0WZ017XYr7p88ypeR1vxTAhUAskDA 8 | 8//pD7egggMn4lsjRHPZBnsCggEARaq+U9oWLlgMQcN2G0JvH37k22MWVse4pYg5 9 | Vxo83qO77jNs8mnX67bJp1aFT2MSL049DajUYOM3JKEtkuaT6FcD4dDlrwD1JIRI 10 | 50b/8hDIIgeiGNMHX7saABUzda+u25brfHNPnBNResSC6nux3GdImaxmYO3d0toC 11 | e0XHSZAslxhYi1SKgVBprcb3aPWfaunATjspSFoZmcqsGR94OPjkEye55SPU5vyN 12 | 0JVMhp97kmRuN3tqIShR51LqzOd2bqCqIYRJgAa4QnFphLsK3qSs42i8HHZbljyx 13 | s7+EytHWw1faTDjnznJPxrEXtsm3oyP4chghXVZiHqn2pczHDwOCAQUAAoIBAFPy 14 | gjvNM2mApuKL+g9SvqjgHLMZupphaXsvAl9Y7Ipp2ypnjyHS9dTPpE0uDRbL0HzS 15 | 8NufQNHyAiv/bDjCaLvVIMxhGT3LmCxKSJrbwmkvUa2/0W1YblFfruHSbnvPy3UI 16 | l77jZZnJnD3D6OGkn18CltxOMrzEKz6/KSVpT315u4Wzf2GJDQkteRVEXFICM3rx 17 | PgS0uiwjxEZAeet4auiwxYidC/tAjuSn+uixt+lShHyucSljwAItFxGs5YjPjXTl 18 | WppibFKLOQnk6SEoihxCpq5/U2Uh+Dpi3zGXRKAtGWavB/0C8uowKacrmRKLzUs6 19 | kEme86o47uXaU8uRbCk= 20 | -----END PUBLIC KEY----- 21 | -------------------------------------------------------------------------------- /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 | @interface SUAppcastItem : NSObject { 13 | NSString *title; 14 | NSDate *date; 15 | NSString *itemDescription; 16 | 17 | NSURL *releaseNotesURL; 18 | 19 | NSString *DSASignature; 20 | NSString *minimumSystemVersion; 21 | 22 | NSURL *fileURL; 23 | NSString *versionString; 24 | NSString *displayVersionString; 25 | 26 | NSDictionary *propertiesDictionary; 27 | } 28 | 29 | // Initializes with data from a dictionary provided by the RSS class. 30 | - initWithDictionary:(NSDictionary *)dict; 31 | 32 | - (NSString *)title; 33 | - (NSString *)versionString; 34 | - (NSString *)displayVersionString; 35 | - (NSDate *)date; 36 | - (NSString *)itemDescription; 37 | - (NSURL *)releaseNotesURL; 38 | - (NSURL *)fileURL; 39 | - (NSString *)DSASignature; 40 | - (NSString *)minimumSystemVersion; 41 | 42 | // Returns the dictionary provided in initWithDictionary; this might be useful later for extensions. 43 | - (NSDictionary *)propertiesDictionary; 44 | 45 | @end 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /SSMAccount.h: -------------------------------------------------------------------------------- 1 | // 2 | // SSMAccount.h 3 | // Sosumi 4 | // 5 | // Created by Tyler Hall on 11/28/10. 6 | // Copyright 2010 Click On Tyler, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class GTMHTTPFetcher; 12 | 13 | @interface SSMAccount : NSObject { 14 | NSString *username; 15 | NSString *password; 16 | NSMutableDictionary *devices; 17 | NSString *partition; 18 | BOOL isUpdating; 19 | BOOL isRefreshing; 20 | NSTreeNode *treeNode; 21 | 22 | NSTimer *refreshTimer; 23 | NSTimeInterval refreshTimerInterval; 24 | } 25 | 26 | @property (nonatomic, retain) NSString *username; 27 | @property (nonatomic, retain) NSString *password; 28 | @property (nonatomic, retain) NSMutableDictionary *devices; 29 | @property (nonatomic, retain) NSString *partition; 30 | @property (assign) BOOL isUpdating; 31 | @property (assign) BOOL isRefreshing; 32 | @property (nonatomic, retain) NSTreeNode *treeNode; 33 | 34 | - (NSString *)apiStringsForMethod:(NSString *)method; 35 | 36 | - (void)beginUpdatingDevices; 37 | - (void)stopUpdatingDevices; 38 | 39 | - (void)refresh; 40 | - (void)getPartition; 41 | - (void)sendMessage:(NSString *)message withSubject:(NSString *)subject andAlarm:(BOOL)alarm toDevice:(NSString *)deviceId; 42 | - (void)remoteLockDevice:(NSString *)deviceId withPasscode:(NSString *)passcode; 43 | 44 | - (GTMHTTPFetcher *)getPreparedFetcherWithMethod:(NSString *)method; 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Sosumi-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSAppleScriptEnabled 6 | 7 | OSAScriptingDefinition 8 | Sosumi.sdef 9 | SUPublicDSAKeyFile 10 | dsa_pub.pem 11 | SUFeedURL 12 | http://shine.clickontyler.com/appcast.php?id=10 13 | CFBundleDevelopmentRegion 14 | English 15 | CFBundleExecutable 16 | ${EXECUTABLE_NAME} 17 | CFBundleIconFile 18 | Icon.icns 19 | CFBundleIdentifier 20 | com.clickontyler.macsosumi 21 | CFBundleInfoDictionaryVersion 22 | 6.0 23 | CFBundleName 24 | ${PRODUCT_NAME} 25 | CFBundlePackageType 26 | APPL 27 | CFBundleShortVersionString 28 | 1.3.4 29 | CFBundleSignature 30 | ???? 31 | CFBundleVersion 32 | 1.3.4 33 | LSMinimumSystemVersion 34 | ${MACOSX_DEPLOYMENT_TARGET} 35 | NSMainNibFile 36 | MainMenu 37 | NSPrincipalClass 38 | NSApplication 39 | 40 | 41 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | doNotInstall 19 | id 20 | installLater 21 | id 22 | installNow 23 | id 24 | 25 | CLASS 26 | SUAutomaticUpdateAlert 27 | LANGUAGE 28 | ObjC 29 | SUPERCLASS 30 | SUWindowController 31 | 32 | 33 | CLASS 34 | FirstResponder 35 | LANGUAGE 36 | ObjC 37 | SUPERCLASS 38 | NSObject 39 | 40 | 41 | CLASS 42 | NSObject 43 | LANGUAGE 44 | ObjC 45 | 46 | 47 | IBVersion 48 | 1 49 | 50 | 51 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | doNotInstall 19 | id 20 | installLater 21 | id 22 | installNow 23 | id 24 | 25 | CLASS 26 | SUAutomaticUpdateAlert 27 | LANGUAGE 28 | ObjC 29 | SUPERCLASS 30 | SUWindowController 31 | 32 | 33 | CLASS 34 | FirstResponder 35 | LANGUAGE 36 | ObjC 37 | SUPERCLASS 38 | NSObject 39 | 40 | 41 | CLASS 42 | NSObject 43 | LANGUAGE 44 | ObjC 45 | 46 | 47 | IBVersion 48 | 1 49 | 50 | 51 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | doNotInstall 19 | id 20 | installLater 21 | id 22 | installNow 23 | id 24 | 25 | CLASS 26 | SUAutomaticUpdateAlert 27 | LANGUAGE 28 | ObjC 29 | SUPERCLASS 30 | SUWindowController 31 | 32 | 33 | CLASS 34 | FirstResponder 35 | LANGUAGE 36 | ObjC 37 | SUPERCLASS 38 | NSObject 39 | 40 | 41 | CLASS 42 | NSObject 43 | LANGUAGE 44 | ObjC 45 | 46 | 47 | IBVersion 48 | 1 49 | 50 | 51 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | doNotInstall 19 | id 20 | installLater 21 | id 22 | installNow 23 | id 24 | 25 | CLASS 26 | SUAutomaticUpdateAlert 27 | LANGUAGE 28 | ObjC 29 | SUPERCLASS 30 | SUWindowController 31 | 32 | 33 | CLASS 34 | FirstResponder 35 | LANGUAGE 36 | ObjC 37 | SUPERCLASS 38 | NSObject 39 | 40 | 41 | CLASS 42 | NSObject 43 | LANGUAGE 44 | ObjC 45 | 46 | 47 | IBVersion 48 | 1 49 | 50 | 51 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | doNotInstall 19 | id 20 | installLater 21 | id 22 | installNow 23 | id 24 | 25 | CLASS 26 | SUAutomaticUpdateAlert 27 | LANGUAGE 28 | ObjC 29 | SUPERCLASS 30 | SUWindowController 31 | 32 | 33 | CLASS 34 | FirstResponder 35 | LANGUAGE 36 | ObjC 37 | SUPERCLASS 38 | NSObject 39 | 40 | 41 | CLASS 42 | NSObject 43 | LANGUAGE 44 | ObjC 45 | 46 | 47 | IBVersion 48 | 1 49 | 50 | 51 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | doNotInstall 19 | id 20 | installLater 21 | id 22 | installNow 23 | id 24 | 25 | CLASS 26 | SUAutomaticUpdateAlert 27 | LANGUAGE 28 | ObjC 29 | SUPERCLASS 30 | SUWindowController 31 | 32 | 33 | CLASS 34 | FirstResponder 35 | LANGUAGE 36 | ObjC 37 | SUPERCLASS 38 | NSObject 39 | 40 | 41 | CLASS 42 | NSObject 43 | LANGUAGE 44 | ObjC 45 | 46 | 47 | IBVersion 48 | 1 49 | 50 | 51 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | doNotInstall 19 | id 20 | installLater 21 | id 22 | installNow 23 | id 24 | 25 | CLASS 26 | SUAutomaticUpdateAlert 27 | LANGUAGE 28 | ObjC 29 | SUPERCLASS 30 | SUWindowController 31 | 32 | 33 | CLASS 34 | FirstResponder 35 | LANGUAGE 36 | ObjC 37 | SUPERCLASS 38 | NSObject 39 | 40 | 41 | CLASS 42 | NSObject 43 | LANGUAGE 44 | ObjC 45 | 46 | 47 | IBVersion 48 | 1 49 | 50 | 51 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | doNotInstall 19 | id 20 | installLater 21 | id 22 | installNow 23 | id 24 | 25 | CLASS 26 | SUAutomaticUpdateAlert 27 | LANGUAGE 28 | ObjC 29 | SUPERCLASS 30 | SUWindowController 31 | 32 | 33 | CLASS 34 | FirstResponder 35 | LANGUAGE 36 | ObjC 37 | SUPERCLASS 38 | NSObject 39 | 40 | 41 | CLASS 42 | NSObject 43 | LANGUAGE 44 | ObjC 45 | 46 | 47 | IBVersion 48 | 1 49 | 50 | 51 | -------------------------------------------------------------------------------- /Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252\cocoartf1038\cocoasubrtf350 2 | {\fonttbl\f0\fswiss\fcharset0 Helvetica;} 3 | {\colortbl;\red255\green255\blue255;} 4 | \margl1440\margr1440\vieww9000\viewh8400\viewkind0 5 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 6 | 7 | \f0\b\fs24 \cf0 Sosumi makes use of the following open source software projects and graciously thanks their authors for all the hard work.\ 8 | 9 | \b0 \ 10 | Sparkle by Andy Matuschak\ 11 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 12 | {\field{\*\fldinst{HYPERLINK "http://sparkle.andymatuschak.org/"}}{\fldrslt \cf0 http://sparkle.andymatuschak.org/}}\ 13 | \ 14 | EMKeychain by by Extendmac\ 15 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 16 | {\field{\*\fldinst{HYPERLINK "http://extendmac.com/EMKeychain/"}}{\fldrslt \cf0 http://extendmac.com/EMKeychain/}}\ 17 | \ 18 | gtm-http-fetcher by Google\ 19 | {\field{\*\fldinst{HYPERLINK "http://code.google.com/p/gtm-http-fetcher/"}}{\fldrslt http://code.google.com/p/gtm-http-fetcher/}}\ 20 | \ 21 | Base64 Encoding/Decoding by Matt Gallagher\ 22 | {\field{\*\fldinst{HYPERLINK "http://cocoawithlove.com/"}}{\fldrslt http://cocoawithlove.com/}}\ 23 | \ 24 | JSON Framework by Stig Brautaset\ 25 | {\field{\*\fldinst{HYPERLINK "http://stig.github.com/json-framework/"}}{\fldrslt http://stig.github.com/json-framework/}}\ 26 | } -------------------------------------------------------------------------------- /THImageRow.m: -------------------------------------------------------------------------------- 1 | // 2 | // THQueryCell.m 3 | // Incoming! 4 | // 5 | // Created by Tyler Hall on 7/4/09. 6 | // Copyright 2009 Click On Tyler, LLC. All rights reserved. 7 | // 8 | 9 | #import "THImageRow.h" 10 | 11 | @implementation THImageRow 12 | 13 | @synthesize imageName; 14 | @synthesize isShared; 15 | 16 | - (BOOL)isOpaque 17 | { 18 | return YES; 19 | } 20 | 21 | - (void)drawInteriorWithFrame:(NSRect)aRect inView:(NSView *)controlView 22 | { 23 | NSRect txtRect = aRect; 24 | if(self.imageName == nil) { 25 | txtRect.origin.x += 8; // Account cell 26 | } else { 27 | txtRect.origin.x += 20; // Device cell 28 | } 29 | 30 | 31 | [super drawInteriorWithFrame:txtRect inView:controlView]; 32 | 33 | NSImage *img = [NSImage imageNamed:self.imageName]; 34 | [img setFlipped:YES]; 35 | 36 | NSRect imgRect = aRect; 37 | imgRect.size.width = 16; 38 | imgRect.size.height = 16; 39 | imgRect.origin.x += 2; 40 | imgRect.origin.y += 2; 41 | [img drawInRect:imgRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; 42 | 43 | // if([self.isShared boolValue]) { 44 | // img = [NSImage imageNamed:@"share"]; 45 | // [img setFlipped:YES]; 46 | // 47 | // imgRect = aRect; 48 | // imgRect.origin.x += imgRect.size.width - 16; 49 | // 50 | // imgRect.size.width = 16; 51 | // imgRect.size.height = 16; 52 | // imgRect.origin.x += 2; 53 | // imgRect.origin.y += 2; 54 | // [img drawInRect:imgRect fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0]; 55 | // } 56 | } 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/SUStatus.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | CLASS 17 | NSApplication 18 | LANGUAGE 19 | ObjC 20 | SUPERCLASS 21 | NSResponder 22 | 23 | 24 | CLASS 25 | FirstResponder 26 | LANGUAGE 27 | ObjC 28 | SUPERCLASS 29 | NSObject 30 | 31 | 32 | CLASS 33 | NSObject 34 | LANGUAGE 35 | ObjC 36 | 37 | 38 | CLASS 39 | SUStatusController 40 | LANGUAGE 41 | ObjC 42 | OUTLETS 43 | 44 | actionButton 45 | NSButton 46 | progressBar 47 | NSProgressIndicator 48 | 49 | SUPERCLASS 50 | SUWindowController 51 | 52 | 53 | IBVersion 54 | 1 55 | 56 | 57 | -------------------------------------------------------------------------------- /SSMDevice.h: -------------------------------------------------------------------------------- 1 | // 2 | // SSMDevice.h 3 | // Sosumi 4 | // 5 | // Created by Tyler Hall on 11/28/10. 6 | // Copyright 2010 Click On Tyler, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SSMAccount; 12 | 13 | @interface SSMDevice : NSObject { 14 | BOOL isLocating; 15 | NSDate *locationTimestamp; 16 | NSString *locationType; 17 | NSNumber *horizontalAccuracy; 18 | BOOL locationFinished; 19 | NSNumber *longitude; 20 | NSNumber *latitude; 21 | NSString *deviceModel; 22 | NSString *deviceStatus; 23 | NSString *deviceId; 24 | NSString *name; 25 | NSString *deviceClass; 26 | BOOL isCharging; 27 | NSNumber *batteryLevel; 28 | NSString *statusImage; 29 | SSMAccount *parent; 30 | NSString *imageURL; 31 | } 32 | 33 | @property (assign) BOOL isLocating; 34 | @property (nonatomic, retain) NSDate *locationTimestamp; 35 | @property (nonatomic, retain) NSString *locationType; 36 | @property (nonatomic, retain) NSNumber *horizontalAccuracy; 37 | @property (assign) BOOL locationFinished; 38 | @property (nonatomic, retain) NSNumber *longitude; 39 | @property (nonatomic, retain) NSNumber *latitude; 40 | @property (nonatomic, retain) NSString *deviceModel; 41 | @property (nonatomic, retain) NSString *deviceStatus; 42 | @property (nonatomic, retain) NSString *deviceId; 43 | @property (nonatomic, retain) NSString *name; 44 | @property (nonatomic, retain) NSString *deviceClass; 45 | @property (assign) BOOL isCharging; 46 | @property (nonatomic, retain) NSNumber *batteryLevel; 47 | @property (readonly) NSString *statusImage; 48 | 49 | @property (nonatomic, retain) SSMAccount *parent; 50 | @property (readonly) NSString *imageURL; 51 | 52 | - (NSString *)coords; 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | finishPrompt 19 | id 20 | toggleMoreInfo 21 | id 22 | 23 | CLASS 24 | SUUpdatePermissionPrompt 25 | LANGUAGE 26 | ObjC 27 | OUTLETS 28 | 29 | delegate 30 | id 31 | descriptionTextField 32 | NSTextField 33 | moreInfoButton 34 | NSButton 35 | moreInfoView 36 | NSView 37 | 38 | SUPERCLASS 39 | SUWindowController 40 | 41 | 42 | CLASS 43 | FirstResponder 44 | LANGUAGE 45 | ObjC 46 | SUPERCLASS 47 | NSObject 48 | 49 | 50 | CLASS 51 | NSObject 52 | LANGUAGE 53 | ObjC 54 | 55 | 56 | IBVersion 57 | 1 58 | 59 | 60 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | finishPrompt 19 | id 20 | toggleMoreInfo 21 | id 22 | 23 | CLASS 24 | SUUpdatePermissionPrompt 25 | LANGUAGE 26 | ObjC 27 | OUTLETS 28 | 29 | delegate 30 | id 31 | descriptionTextField 32 | NSTextField 33 | moreInfoButton 34 | NSButton 35 | moreInfoView 36 | NSView 37 | 38 | SUPERCLASS 39 | SUWindowController 40 | 41 | 42 | CLASS 43 | FirstResponder 44 | LANGUAGE 45 | ObjC 46 | SUPERCLASS 47 | NSObject 48 | 49 | 50 | CLASS 51 | NSObject 52 | LANGUAGE 53 | ObjC 54 | 55 | 56 | IBVersion 57 | 1 58 | 59 | 60 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | finishPrompt 19 | id 20 | toggleMoreInfo 21 | id 22 | 23 | CLASS 24 | SUUpdatePermissionPrompt 25 | LANGUAGE 26 | ObjC 27 | OUTLETS 28 | 29 | delegate 30 | id 31 | descriptionTextField 32 | NSTextField 33 | moreInfoButton 34 | NSButton 35 | moreInfoView 36 | NSView 37 | 38 | SUPERCLASS 39 | SUWindowController 40 | 41 | 42 | CLASS 43 | FirstResponder 44 | LANGUAGE 45 | ObjC 46 | SUPERCLASS 47 | NSObject 48 | 49 | 50 | CLASS 51 | NSObject 52 | LANGUAGE 53 | ObjC 54 | 55 | 56 | IBVersion 57 | 1 58 | 59 | 60 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | finishPrompt 19 | id 20 | toggleMoreInfo 21 | id 22 | 23 | CLASS 24 | SUUpdatePermissionPrompt 25 | LANGUAGE 26 | ObjC 27 | OUTLETS 28 | 29 | delegate 30 | id 31 | descriptionTextField 32 | NSTextField 33 | moreInfoButton 34 | NSButton 35 | moreInfoView 36 | NSView 37 | 38 | SUPERCLASS 39 | SUWindowController 40 | 41 | 42 | CLASS 43 | FirstResponder 44 | LANGUAGE 45 | ObjC 46 | SUPERCLASS 47 | NSObject 48 | 49 | 50 | CLASS 51 | NSObject 52 | LANGUAGE 53 | ObjC 54 | 55 | 56 | IBVersion 57 | 1 58 | 59 | 60 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | finishPrompt 19 | id 20 | toggleMoreInfo 21 | id 22 | 23 | CLASS 24 | SUUpdatePermissionPrompt 25 | LANGUAGE 26 | ObjC 27 | OUTLETS 28 | 29 | delegate 30 | id 31 | descriptionTextField 32 | NSTextField 33 | moreInfoButton 34 | NSButton 35 | moreInfoView 36 | NSView 37 | 38 | SUPERCLASS 39 | SUWindowController 40 | 41 | 42 | CLASS 43 | FirstResponder 44 | LANGUAGE 45 | ObjC 46 | SUPERCLASS 47 | NSObject 48 | 49 | 50 | CLASS 51 | NSObject 52 | LANGUAGE 53 | ObjC 54 | 55 | 56 | IBVersion 57 | 1 58 | 59 | 60 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | finishPrompt 19 | id 20 | toggleMoreInfo 21 | id 22 | 23 | CLASS 24 | SUUpdatePermissionPrompt 25 | LANGUAGE 26 | ObjC 27 | OUTLETS 28 | 29 | delegate 30 | id 31 | descriptionTextField 32 | NSTextField 33 | moreInfoButton 34 | NSButton 35 | moreInfoView 36 | NSView 37 | 38 | SUPERCLASS 39 | SUWindowController 40 | 41 | 42 | CLASS 43 | FirstResponder 44 | LANGUAGE 45 | ObjC 46 | SUPERCLASS 47 | NSObject 48 | 49 | 50 | CLASS 51 | NSObject 52 | LANGUAGE 53 | ObjC 54 | 55 | 56 | IBVersion 57 | 1 58 | 59 | 60 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | NSObject 10 | LANGUAGE 11 | ObjC 12 | 13 | 14 | CLASS 15 | SUWindowController 16 | LANGUAGE 17 | ObjC 18 | SUPERCLASS 19 | NSWindowController 20 | 21 | 22 | ACTIONS 23 | 24 | finishPrompt 25 | id 26 | toggleMoreInfo 27 | id 28 | 29 | CLASS 30 | SUUpdatePermissionPrompt 31 | LANGUAGE 32 | ObjC 33 | OUTLETS 34 | 35 | delegate 36 | id 37 | descriptionTextField 38 | NSTextField 39 | moreInfoButton 40 | NSButton 41 | moreInfoView 42 | NSView 43 | 44 | SUPERCLASS 45 | SUWindowController 46 | 47 | 48 | CLASS 49 | FirstResponder 50 | LANGUAGE 51 | ObjC 52 | SUPERCLASS 53 | NSObject 54 | 55 | 56 | IBVersion 57 | 1 58 | 59 | 60 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | ACTIONS 17 | 18 | finishPrompt 19 | id 20 | toggleMoreInfo 21 | id 22 | 23 | CLASS 24 | SUUpdatePermissionPrompt 25 | LANGUAGE 26 | ObjC 27 | OUTLETS 28 | 29 | delegate 30 | id 31 | descriptionTextField 32 | NSTextField 33 | moreInfoButton 34 | NSButton 35 | moreInfoView 36 | NSView 37 | 38 | SUPERCLASS 39 | SUWindowController 40 | 41 | 42 | CLASS 43 | FirstResponder 44 | LANGUAGE 45 | ObjC 46 | SUPERCLASS 47 | NSObject 48 | 49 | 50 | CLASS 51 | NSObject 52 | LANGUAGE 53 | ObjC 54 | 55 | 56 | IBVersion 57 | 1 58 | 59 | 60 | -------------------------------------------------------------------------------- /NetworkSpinner.m: -------------------------------------------------------------------------------- 1 | // 2 | // NetworkSpinner.m 3 | // Tennessee Traffic 4 | // 5 | // Created by Tyler Hall on 8/15/10. 6 | // Copyright 2010 Click On Tyler, LLC. All rights reserved. 7 | // 8 | 9 | #import "NetworkSpinner.h" 10 | 11 | static NetworkSpinner *_me = nil; 12 | 13 | @implementation NetworkSpinner 14 | 15 | - (id)init { 16 | [super init]; 17 | count = 0; 18 | hasError = NO; 19 | return self; 20 | } 21 | 22 | + (NetworkSpinner *)sharedSpinner { 23 | if(_me == nil) { 24 | _me = [[NetworkSpinner alloc] init]; 25 | } 26 | return _me; 27 | } 28 | 29 | - (void)realQueue { 30 | // [[NSNotificationCenter defaultCenter] postNotificationName:@"SHOW_SPINNER" object:self]; 31 | count++; 32 | } 33 | 34 | - (void)realDequeue { 35 | count--; 36 | if(count <= 0) { 37 | count = 0; 38 | // [[NSNotificationCenter defaultCenter] postNotificationName:@"HIDE_SPINNER" object:self]; 39 | } 40 | } 41 | 42 | + (void)queue { 43 | NetworkSpinner *fakeMe = [NetworkSpinner sharedSpinner]; 44 | [fakeMe realQueue]; 45 | } 46 | 47 | + (void)dequeue { 48 | NetworkSpinner *fakeMe = [NetworkSpinner sharedSpinner]; 49 | [fakeMe realDequeue]; 50 | } 51 | 52 | - (void)realHasError { 53 | if(hasError) return; 54 | hasError = YES; 55 | // UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Network Error" message:@"TN Traffic could not connect to the network. Please try again." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil]; 56 | // [alert show]; 57 | // [alert release]; 58 | } 59 | 60 | + (void)networkError { 61 | [[NetworkSpinner sharedSpinner] realHasError]; 62 | } 63 | 64 | //- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { 65 | // hasError = NO; 66 | //} 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /SosumiAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SosumiAppDelegate.h 3 | // Sosumi 4 | // 5 | // Created by Tyler Hall on 11/28/10. 6 | // Copyright 2010 Click On Tyler, LLC. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @class SSMAccount; 13 | 14 | @interface SosumiAppDelegate : NSObject { 15 | NSWindow *window; 16 | IBOutlet NSOutlineView *outlineView; 17 | IBOutlet WebView *map; 18 | IBOutlet NSTreeController *treeController; 19 | IBOutlet NSProgressIndicator *piSpinner; 20 | IBOutlet NSPanel *panelSyncActivity; 21 | 22 | IBOutlet NSPanel *panelAddAccount; 23 | IBOutlet NSTextField *txtUsername; 24 | IBOutlet NSSecureTextField *txtPassword; 25 | 26 | IBOutlet NSPanel *panelSendMessage; 27 | IBOutlet NSTextField *txtSubject; 28 | IBOutlet NSTextField *txtMessage; 29 | IBOutlet NSButton *chkAlarm; 30 | } 31 | 32 | @property (nonatomic, retain) IBOutlet NSWindow *window; 33 | @property (nonatomic, retain) IBOutlet NSPanel *panelSyncActivity; 34 | 35 | - (void)refreshOutline:(NSNotification *)notification; 36 | - (void)refreshMap; 37 | 38 | - (IBAction)addAccountWasClicked:(id)sender; 39 | - (IBAction)removeAccountWasClicked:(id)sender; 40 | - (IBAction)refreshWasClicked:(id)sender; 41 | - (IBAction)viewOnMapWasClicked:(id)sender; 42 | - (IBAction)sendMessageWasClicked:(id)sender; 43 | - (IBAction)lockDeviceWasClicked:(id)sender; 44 | - (IBAction)dismissPanel:(id)sender; 45 | - (IBAction)confirmAddAccount:(id)sender; 46 | - (IBAction)confirmSendMessage:(id)sender; 47 | - (IBAction)copyCoordsWasClicked:(id)sender; 48 | - (IBAction)showSyncActivityPanel:(id)sender; 49 | 50 | - (void)showSpinner:(NSNotification *)notification; 51 | - (void)hideSpinner:(NSNotification *)notification; 52 | 53 | @end 54 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | CLASS 17 | NSApplication 18 | LANGUAGE 19 | ObjC 20 | SUPERCLASS 21 | NSResponder 22 | 23 | 24 | ACTIONS 25 | 26 | installUpdate 27 | id 28 | remindMeLater 29 | id 30 | skipThisVersion 31 | id 32 | 33 | CLASS 34 | SUUpdateAlert 35 | LANGUAGE 36 | ObjC 37 | OUTLETS 38 | 39 | delegate 40 | id 41 | description 42 | NSTextField 43 | releaseNotesView 44 | WebView 45 | 46 | SUPERCLASS 47 | SUWindowController 48 | 49 | 50 | CLASS 51 | FirstResponder 52 | LANGUAGE 53 | ObjC 54 | SUPERCLASS 55 | NSObject 56 | 57 | 58 | CLASS 59 | NSObject 60 | LANGUAGE 61 | ObjC 62 | 63 | 64 | IBVersion 65 | 1 66 | 67 | 68 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | CLASS 17 | NSApplication 18 | LANGUAGE 19 | ObjC 20 | SUPERCLASS 21 | NSResponder 22 | 23 | 24 | ACTIONS 25 | 26 | installUpdate 27 | id 28 | remindMeLater 29 | id 30 | skipThisVersion 31 | id 32 | 33 | CLASS 34 | SUUpdateAlert 35 | LANGUAGE 36 | ObjC 37 | OUTLETS 38 | 39 | delegate 40 | id 41 | description 42 | NSTextField 43 | releaseNotesView 44 | WebView 45 | 46 | SUPERCLASS 47 | SUWindowController 48 | 49 | 50 | CLASS 51 | FirstResponder 52 | LANGUAGE 53 | ObjC 54 | SUPERCLASS 55 | NSObject 56 | 57 | 58 | CLASS 59 | NSObject 60 | LANGUAGE 61 | ObjC 62 | 63 | 64 | IBVersion 65 | 1 66 | 67 | 68 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | CLASS 17 | NSApplication 18 | LANGUAGE 19 | ObjC 20 | SUPERCLASS 21 | NSResponder 22 | 23 | 24 | ACTIONS 25 | 26 | installUpdate 27 | id 28 | remindMeLater 29 | id 30 | skipThisVersion 31 | id 32 | 33 | CLASS 34 | SUUpdateAlert 35 | LANGUAGE 36 | ObjC 37 | OUTLETS 38 | 39 | delegate 40 | id 41 | description 42 | NSTextField 43 | releaseNotesView 44 | WebView 45 | 46 | SUPERCLASS 47 | SUWindowController 48 | 49 | 50 | CLASS 51 | FirstResponder 52 | LANGUAGE 53 | ObjC 54 | SUPERCLASS 55 | NSObject 56 | 57 | 58 | CLASS 59 | NSObject 60 | LANGUAGE 61 | ObjC 62 | 63 | 64 | IBVersion 65 | 1 66 | 67 | 68 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | CLASS 17 | NSApplication 18 | LANGUAGE 19 | ObjC 20 | SUPERCLASS 21 | NSResponder 22 | 23 | 24 | ACTIONS 25 | 26 | installUpdate 27 | id 28 | remindMeLater 29 | id 30 | skipThisVersion 31 | id 32 | 33 | CLASS 34 | SUUpdateAlert 35 | LANGUAGE 36 | ObjC 37 | OUTLETS 38 | 39 | delegate 40 | id 41 | description 42 | NSTextField 43 | releaseNotesView 44 | WebView 45 | 46 | SUPERCLASS 47 | SUWindowController 48 | 49 | 50 | CLASS 51 | FirstResponder 52 | LANGUAGE 53 | ObjC 54 | SUPERCLASS 55 | NSObject 56 | 57 | 58 | CLASS 59 | NSObject 60 | LANGUAGE 61 | ObjC 62 | 63 | 64 | IBVersion 65 | 1 66 | 67 | 68 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | CLASS 17 | NSApplication 18 | LANGUAGE 19 | ObjC 20 | SUPERCLASS 21 | NSResponder 22 | 23 | 24 | ACTIONS 25 | 26 | installUpdate 27 | id 28 | remindMeLater 29 | id 30 | skipThisVersion 31 | id 32 | 33 | CLASS 34 | SUUpdateAlert 35 | LANGUAGE 36 | ObjC 37 | OUTLETS 38 | 39 | delegate 40 | id 41 | description 42 | NSTextField 43 | releaseNotesView 44 | WebView 45 | 46 | SUPERCLASS 47 | SUWindowController 48 | 49 | 50 | CLASS 51 | FirstResponder 52 | LANGUAGE 53 | ObjC 54 | SUPERCLASS 55 | NSObject 56 | 57 | 58 | CLASS 59 | NSObject 60 | LANGUAGE 61 | ObjC 62 | 63 | 64 | IBVersion 65 | 1 66 | 67 | 68 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | CLASS 17 | NSApplication 18 | LANGUAGE 19 | ObjC 20 | SUPERCLASS 21 | NSResponder 22 | 23 | 24 | ACTIONS 25 | 26 | installUpdate 27 | id 28 | remindMeLater 29 | id 30 | skipThisVersion 31 | id 32 | 33 | CLASS 34 | SUUpdateAlert 35 | LANGUAGE 36 | ObjC 37 | OUTLETS 38 | 39 | delegate 40 | id 41 | description 42 | NSTextField 43 | releaseNotesView 44 | WebView 45 | 46 | SUPERCLASS 47 | SUWindowController 48 | 49 | 50 | CLASS 51 | FirstResponder 52 | LANGUAGE 53 | ObjC 54 | SUPERCLASS 55 | NSObject 56 | 57 | 58 | CLASS 59 | NSObject 60 | LANGUAGE 61 | ObjC 62 | 63 | 64 | IBVersion 65 | 1 66 | 67 | 68 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib/classes.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBClasses 6 | 7 | 8 | CLASS 9 | SUWindowController 10 | LANGUAGE 11 | ObjC 12 | SUPERCLASS 13 | NSWindowController 14 | 15 | 16 | CLASS 17 | NSApplication 18 | LANGUAGE 19 | ObjC 20 | SUPERCLASS 21 | NSResponder 22 | 23 | 24 | ACTIONS 25 | 26 | installUpdate 27 | id 28 | remindMeLater 29 | id 30 | skipThisVersion 31 | id 32 | 33 | CLASS 34 | SUUpdateAlert 35 | LANGUAGE 36 | ObjC 37 | OUTLETS 38 | 39 | delegate 40 | id 41 | description 42 | NSTextField 43 | releaseNotesView 44 | WebView 45 | 46 | SUPERCLASS 47 | SUWindowController 48 | 49 | 50 | CLASS 51 | FirstResponder 52 | LANGUAGE 53 | ObjC 54 | SUPERCLASS 55 | NSObject 56 | 57 | 58 | CLASS 59 | NSObject 60 | LANGUAGE 61 | ObjC 62 | 63 | 64 | IBVersion 65 | 1 66 | 67 | 68 | -------------------------------------------------------------------------------- /THNetworkActivityManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // SyncActivityManager.m 3 | // Nottingham3 4 | // 5 | // Created by Tyler Hall on 10/10/10. 6 | // Copyright 2010 Click On Tyler, LLC. All rights reserved. 7 | // 8 | 9 | #import "THNetworkActivityManager.h" 10 | #import "THNetworkActivityCell.h" 11 | #import "GTMHTTPFetcher.h" 12 | 13 | @implementation THNetworkActivityManager 14 | 15 | - (id)initWithCoder:(NSCoder *)aDecoder { 16 | self = [super initWithCoder:aDecoder]; 17 | 18 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(addRequest:) name:@"kGTMHTTPFetcherStartedNotification" object:nil]; 19 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeRequest:) name:@"kGTMHTTPFetcherStoppedNotification" object:nil]; 20 | 21 | return self; 22 | } 23 | 24 | - (void)addRequest:(NSNotification *)notification { 25 | [self addObject:[notification object]]; 26 | [[NSNotificationCenter defaultCenter] postNotificationName:@"SHOW_SPINNER" object:nil]; 27 | } 28 | 29 | - (void)removeRequest:(NSNotification *)notification { 30 | [self removeObject:[notification object]]; 31 | if([[self content] count] == 0) { 32 | [[NSNotificationCenter defaultCenter] postNotificationName:@"HIDE_SPINNER" object:nil]; 33 | } 34 | } 35 | 36 | - (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex { 37 | THNetworkActivityCell *cell = aCell; 38 | 39 | if([aCell isMemberOfClass:[THNetworkActivityCell class]]) { 40 | if(rowIndex < [[self arrangedObjects] count]) { 41 | GTMHTTPFetcher *fetcher = [self arrangedObjects][rowIndex]; 42 | NSDictionary *dict = [fetcher userData]; 43 | 44 | NSString *title = [dict valueForKey:@"title"]; 45 | NSString *subtitle = [dict valueForKey:@"subtitle"]; 46 | cell.title = title; 47 | cell.subtitle = subtitle; 48 | } 49 | } 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 12 | 13 | 14 | 15 |
16 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /JSON/NSString+SBJSON.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2007-2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #import "NSString+SBJSON.h" 31 | #import "SBJsonParser.h" 32 | 33 | @implementation NSString (NSString_SBJSON) 34 | 35 | - (id)JSONValue 36 | { 37 | SBJsonParser *jsonParser = [SBJsonParser new]; 38 | id repr = [jsonParser objectWithString:self]; 39 | if (!repr) 40 | NSLog(@"-JSONValue failed. Error trace is: %@", [jsonParser errorTrace]); 41 | [jsonParser release]; 42 | return repr; 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | MacSosumi 2 | ========= 3 | 4 | A Mac OS X desktop client for Apple's [Find My iPhone service](http://www.apple.com/mobileme/features/find-my-iphone.html). 5 | 6 | MacSosumi was made possible by the work of the original [Sosumi](https://github.com/tylerhall/sosumi) project. 7 | 8 | Much love to the iCloud team for a wonderful service :-) 9 | 10 | ![http://cdn.clickontyler.com/images/sosumi-ss1.png](http://cdn.clickontyler.com/images/sosumi-ss1.png) 11 | 12 | INSTALL 13 | ------- 14 | 15 | MacSosumi requires Mac OS X 10.7 or later. You're welcome to download the source and build (and modify!) it yourself with Xcode. Or, you can download the [latest stable release](http://clickontyler.com/sosumi/download/). 16 | 17 | UPDATES 18 | ------- 19 | 20 | Code is hosted at GitHub: [http://github.com/tylerhall/MacSosumi](http://github.com/tylerhall/MacSosumi) 21 | 22 | LICENSE 23 | ------- 24 | 25 | The MIT License 26 | 27 | Initial code Copyright (c) 2012 Tyler Hall 28 | 29 | Permission is hereby granted, free of charge, to any person obtaining a copy 30 | of this software and associated documentation files (the "Software"), to deal 31 | in the Software without restriction, including without limitation the rights 32 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 33 | copies of the Software, and to permit persons to whom the Software is 34 | furnished to do so, subject to the following conditions: 35 | 36 | The above copyright notice and this permission notice shall be included in 37 | all copies or substantial portions of the Software. 38 | 39 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 40 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 41 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 42 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 43 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 44 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 45 | THE SOFTWARE. -------------------------------------------------------------------------------- /JSON/NSObject+SBJSON.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #import "NSObject+SBJSON.h" 31 | #import "SBJsonWriter.h" 32 | 33 | @implementation NSObject (NSObject_SBJSON) 34 | 35 | - (NSString *)JSONRepresentation { 36 | SBJsonWriter *jsonWriter = [SBJsonWriter new]; 37 | NSString *json = [jsonWriter stringWithObject:self]; 38 | if (!json) 39 | NSLog(@"-JSONRepresentation failed. Error trace is: %@", [jsonWriter errorTrace]); 40 | [jsonWriter release]; 41 | return json; 42 | } 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /THGradientBar.m: -------------------------------------------------------------------------------- 1 | // 2 | // THHorizontalGradient.m 3 | // Incoming! 4 | // 5 | // Created by Tyler Hall on 7/1/09. 6 | // Copyright 2009 Click On Tyler, LLC. All rights reserved. 7 | // 8 | 9 | #import "THGradientBar.h" 10 | 11 | 12 | @implementation THGradientBar 13 | 14 | - (void) drawRect:(NSRect)aRect 15 | { 16 | // Top inset 17 | NSGradient *gradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceRed:0.941 green:0.941 blue:0.941 alpha:1.0] 18 | endingColor:[NSColor colorWithDeviceRed:0.941 green:0.941 blue:0.941 alpha:1.0]]; 19 | [gradient drawInRect:aRect angle:90]; 20 | 21 | 22 | // Top color 23 | gradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceRed:0.851 green:0.851 blue:0.851 alpha:1.0] 24 | endingColor:[NSColor colorWithDeviceRed:0.851 green:0.851 blue:0.851 alpha:1.0]]; 25 | NSRect topRect = aRect; 26 | topRect.size.height -= 2; 27 | [gradient drawInRect:topRect angle:90]; 28 | 29 | // Bottom color 30 | gradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceRed:0.8 green:0.8 blue:0.8 alpha:1.0] 31 | endingColor:[NSColor colorWithDeviceRed:0.8 green:0.8 blue:0.8 alpha:1.0]]; 32 | NSRect bottomRect = aRect; 33 | bottomRect.size.height = bottomRect.size.height / 2; 34 | [gradient drawInRect:bottomRect angle:90]; 35 | 36 | 37 | NSBezierPath *path = [[NSBezierPath alloc] init]; 38 | 39 | // Bottom Border 40 | [[NSColor colorWithDeviceRed:0.612 green:0.612 blue:0.612 alpha:1.0] set]; 41 | [path setLineWidth:1.0]; 42 | [path moveToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y)]; 43 | [path lineToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y)]; 44 | [path stroke]; 45 | 46 | // Top Border 47 | [[NSColor colorWithDeviceRed:0.659 green:0.659 blue:0.659 alpha:1.0] set]; 48 | [path setLineWidth:1.0]; 49 | [path moveToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y + aRect.size.height)]; 50 | [path lineToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y + aRect.size.height)]; 51 | [path stroke]; 52 | } 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /SSMDevice.m: -------------------------------------------------------------------------------- 1 | // 2 | // SSMDevice.m 3 | // Sosumi 4 | // 5 | // Created by Tyler Hall on 11/28/10. 6 | // Copyright 2010 Click On Tyler, LLC. All rights reserved. 7 | // 8 | 9 | #import "SSMDevice.h" 10 | #import "SSMAccount.h" 11 | 12 | #define SINFO(title, subtitle) [NSDictionary dictionaryWithObjectsAndKeys:title, @"title", subtitle, @"subtitle", nil] 13 | 14 | @implementation SSMDevice 15 | 16 | @synthesize isLocating; 17 | @synthesize locationTimestamp; // 18 | @synthesize locationType; // 19 | @synthesize horizontalAccuracy; // 20 | @synthesize locationFinished; 21 | @synthesize longitude; // 22 | @synthesize latitude; // 23 | @synthesize deviceModel; // 24 | @synthesize deviceStatus; // 25 | @synthesize deviceId; 26 | @synthesize name; 27 | @synthesize deviceClass; 28 | @synthesize isCharging; // 29 | @synthesize batteryLevel; // 30 | 31 | @synthesize parent; 32 | 33 | - (NSString *)imageURL 34 | { 35 | // The GitHub URLs are just a workaround since me.com's images have been 404'ing lately... 36 | // NSString *url = [NSString stringWithFormat:@"https://me.com/fmipmobile/deviceImages/Device-%@-%@-mini.png", self.deviceClass, self.deviceModel]; 37 | NSString *url = [NSString stringWithFormat:@"https://github.com/tylerhall/MacSosumi/raw/master/DeviceIcons/Device-Generic-Generic-mini.png"]; //, self.deviceClass, self.deviceModel]; 38 | return url; 39 | } 40 | 41 | - (NSString *)statusImage 42 | { 43 | if(self.latitude == nil || self.longitude == nil) { 44 | return @"red"; 45 | } 46 | 47 | return @"green"; 48 | } 49 | 50 | - (NSString *)coords 51 | { 52 | if(self.latitude == nil || self.longitude == nil) { 53 | return @""; 54 | } else { 55 | return [NSString stringWithFormat:@"%@, %@", self.latitude, self.longitude]; 56 | } 57 | } 58 | 59 | - (NSString *)deviceType 60 | { 61 | return [NSString stringWithFormat:@"%@ %@", self.deviceClass, self.deviceModel]; 62 | } 63 | 64 | - (NSString *)charging 65 | { 66 | return self.isCharging ? @"Yes" : @"No"; 67 | } 68 | 69 | - (NSString *)battery 70 | { 71 | int level = [self.batteryLevel floatValue] * 100; 72 | return [NSString stringWithFormat:@"%d%%", level]; 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /JSON/NSString+SBJSON.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #import 31 | 32 | /** 33 | @brief Adds JSON parsing methods to NSString 34 | 35 | This is a category on NSString that adds methods for parsing the target string. 36 | */ 37 | @interface NSString (NSString_SBJSON) 38 | 39 | /** 40 | @brief Returns the NSDictionary or NSArray represented by the current string's JSON representation. 41 | 42 | Returns the dictionary or array represented in the receiver, or nil on error. 43 | 44 | Returns the NSDictionary or NSArray represented by the current string's JSON representation. 45 | */ 46 | - (id)JSONValue; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /JSON/NSObject+SBJSON.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #import 31 | 32 | 33 | /** 34 | @brief Adds JSON generation to Foundation classes 35 | 36 | This is a category on NSObject that adds methods for returning JSON representations 37 | of standard objects to the objects themselves. This means you can call the 38 | -JSONRepresentation method on an NSArray object and it'll do what you want. 39 | */ 40 | @interface NSObject (NSObject_SBJSON) 41 | 42 | /** 43 | @brief Returns a string containing the receiver encoded in JSON. 44 | 45 | This method is added as a category on NSObject but is only actually 46 | supported for the following objects: 47 | @li NSDictionary 48 | @li NSArray 49 | */ 50 | - (NSString *)JSONRepresentation; 51 | 52 | @end 53 | 54 | -------------------------------------------------------------------------------- /Sosumi.xcodeproj/xcuserdata/thall.xcuserdatad/xcschemes/Sosumi.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 14 | 20 | 21 | 22 | 23 | 24 | 29 | 30 | 31 | 32 | 39 | 40 | 46 | 47 | 48 | 49 | 50 | 51 | 56 | 57 | 63 | 64 | 65 | 66 | 68 | 69 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /JSON/JSON.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009-2010 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | /** 31 | @mainpage A strict JSON parser and generator for Objective-C 32 | 33 | JSON (JavaScript Object Notation) is a lightweight data-interchange 34 | format. This framework provides two apis for parsing and generating 35 | JSON. One standard object-based and a higher level api consisting of 36 | categories added to existing Objective-C classes. 37 | 38 | This framework does its best to be as strict as possible, both in what it accepts and what it generates. For example, it does not support trailing commas in arrays or objects. Nor does it support embedded comments, or anything else not in the JSON specification. This is considered a feature. 39 | 40 | @section Links 41 | 42 | @li Project home page. 43 | @li Online version of the API documentation. 44 | 45 | */ 46 | 47 | 48 | // This setting of 1 is best if you copy the source into your project. 49 | // The build transforms the 1 to a 0 when building the framework and static lib. 50 | 51 | #if 1 52 | 53 | #import "SBJsonParser.h" 54 | #import "SBJsonWriter.h" 55 | #import "NSObject+SBJSON.h" 56 | #import "NSString+SBJSON.h" 57 | 58 | #else 59 | 60 | #import 61 | #import 62 | #import 63 | #import 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /JSON/SBJsonBase.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #import "SBJsonBase.h" 31 | NSString * SBJSONErrorDomain = @"org.brautaset.JSON.ErrorDomain"; 32 | 33 | 34 | @implementation SBJsonBase 35 | 36 | @synthesize errorTrace; 37 | @synthesize maxDepth; 38 | 39 | - (id)init { 40 | self = [super init]; 41 | if (self) 42 | self.maxDepth = 512; 43 | return self; 44 | } 45 | 46 | - (void)dealloc { 47 | [errorTrace release]; 48 | [super dealloc]; 49 | } 50 | 51 | - (void)addErrorWithCode:(NSUInteger)code description:(NSString*)str { 52 | NSDictionary *userInfo; 53 | if (!errorTrace) { 54 | errorTrace = [NSMutableArray new]; 55 | userInfo = [NSDictionary dictionaryWithObject:str forKey:NSLocalizedDescriptionKey]; 56 | 57 | } else { 58 | userInfo = [NSDictionary dictionaryWithObjectsAndKeys: 59 | str, NSLocalizedDescriptionKey, 60 | [errorTrace lastObject], NSUnderlyingErrorKey, 61 | nil]; 62 | } 63 | 64 | NSError *error = [NSError errorWithDomain:SBJSONErrorDomain code:code userInfo:userInfo]; 65 | 66 | [self willChangeValueForKey:@"errorTrace"]; 67 | [errorTrace addObject:error]; 68 | [self didChangeValueForKey:@"errorTrace"]; 69 | } 70 | 71 | - (void)clearErrorTrace { 72 | [self willChangeValueForKey:@"errorTrace"]; 73 | [errorTrace release]; 74 | errorTrace = nil; 75 | [self didChangeValueForKey:@"errorTrace"]; 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /JSON/SBJsonBase.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #import 31 | 32 | extern NSString * SBJSONErrorDomain; 33 | 34 | 35 | enum { 36 | EUNSUPPORTED = 1, 37 | EPARSENUM, 38 | EPARSE, 39 | EFRAGMENT, 40 | ECTRL, 41 | EUNICODE, 42 | EDEPTH, 43 | EESCAPE, 44 | ETRAILCOMMA, 45 | ETRAILGARBAGE, 46 | EEOF, 47 | EINPUT 48 | }; 49 | 50 | /** 51 | @brief Common base class for parsing & writing. 52 | 53 | This class contains the common error-handling code and option between the parser/writer. 54 | */ 55 | @interface SBJsonBase : NSObject { 56 | NSMutableArray *errorTrace; 57 | 58 | @protected 59 | NSUInteger depth, maxDepth; 60 | } 61 | 62 | /** 63 | @brief The maximum recursing depth. 64 | 65 | Defaults to 512. If the input is nested deeper than this the input will be deemed to be 66 | malicious and the parser returns nil, signalling an error. ("Nested too deep".) You can 67 | turn off this security feature by setting the maxDepth value to 0. 68 | */ 69 | @property NSUInteger maxDepth; 70 | 71 | /** 72 | @brief Return an error trace, or nil if there was no errors. 73 | 74 | Note that this method returns the trace of the last method that failed. 75 | You need to check the return value of the call you're making to figure out 76 | if the call actually failed, before you know call this method. 77 | */ 78 | @property(copy,readonly) NSArray* errorTrace; 79 | 80 | /// @internal for use in subclasses to add errors to the stack trace 81 | - (void)addErrorWithCode:(NSUInteger)code description:(NSString*)str; 82 | 83 | /// @internal for use in subclasess to clear the error before a new parsing attempt 84 | - (void)clearErrorTrace; 85 | 86 | @end 87 | -------------------------------------------------------------------------------- /JSON/SBJsonParser.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #import 31 | #import "SBJsonBase.h" 32 | 33 | /** 34 | @brief The JSON parser class. 35 | 36 | JSON is mapped to Objective-C types in the following way: 37 | 38 | @li Null -> NSNull 39 | @li String -> NSMutableString 40 | @li Array -> NSMutableArray 41 | @li Object -> NSMutableDictionary 42 | @li Boolean -> NSNumber (initialised with -initWithBool:) 43 | @li Number -> (NSNumber | NSDecimalNumber) 44 | 45 | Since Objective-C doesn't have a dedicated class for boolean values, these turns into NSNumber 46 | instances. These are initialised with the -initWithBool: method, and 47 | round-trip back to JSON properly. (They won't silently suddenly become 0 or 1; they'll be 48 | represented as 'true' and 'false' again.) 49 | 50 | As an optimisation short JSON integers turn into NSNumber instances, while complex ones turn into NSDecimalNumber instances. 51 | We can thus avoid any loss of precision as JSON allows ridiculously large numbers. 52 | 53 | */ 54 | @interface SBJsonParser : SBJsonBase { 55 | 56 | @private 57 | const char *c; 58 | } 59 | 60 | /** 61 | @brief Return the object represented by the given string 62 | 63 | Returns the object represented by the passed-in string or nil on error. The returned object can be 64 | a string, number, boolean, null, array or dictionary. 65 | 66 | @param repr the json string to parse 67 | */ 68 | - (id)objectWithString:(NSString *)repr; 69 | 70 | /** 71 | @brief Return the object represented by the given string 72 | 73 | Returns the object represented by the passed-in string or nil on error. The returned object can be 74 | a string, number, boolean, null, array or dictionary. 75 | 76 | @param jsonText the json string to parse 77 | @param error pointer to an NSError object to populate on error 78 | */ 79 | 80 | - (id)objectWithString:(NSString*)jsonText 81 | error:(NSError**)error; 82 | 83 | 84 | @end 85 | 86 | 87 | -------------------------------------------------------------------------------- /SosumiAPI.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | remoteLock 6 | {"clientContext":{"appName":"FindMyiPhone","appVersion":"1.4","buildVersion":"145","deviceUDID":"0000000000000000000000000000000000000000","inactiveTime":5911,"osVersion":"3.2","productType":"iPad1,1","selectedDevice":"{{device}}","shouldLocate":false},"device":"{{device}}","oldPasscode":"","passcode":"{{code}}","serverContext":{"callbackIntervalInMS":3000,"clientId":"0000000000000000000000000000000000000000","deviceLoadStatus":"203","hasDevices":true,"lastSessionExtensionTime":null,"maxDeviceLoadTime":60000,"maxLocatingTime":90000,"preferredLanguage":"en","prefsUpdateTime":1276872996660,"sessionLifespan":900000,"timezone":{"currentOffset":-25200000,"previousOffset":-28800000,"previousTransition":1268560799999,"tzCurrentName":"Pacific Daylight Time","tzName":"America/Los_Angeles"},"validRegion":true}} 7 | sendMessage 8 | {"clientContext":{"appName":"FindMyiPhone","appVersion":"1.4","buildVersion":"145","deviceUDID":"0000000000000000000000000000000000000000","inactiveTime":5911,"osVersion":"3.2","productType":"iPad1,1","selectedDevice":"{{device}}","shouldLocate":false},"device":"{{device}}","serverContext":{"callbackIntervalInMS":3000,"clientId":"0000000000000000000000000000000000000000","deviceLoadStatus":"203","hasDevices":true,"lastSessionExtensionTime":null,"maxDeviceLoadTime":60000,"maxLocatingTime":90000,"preferredLanguage":"en","prefsUpdateTime":1276872996660,"sessionLifespan":900000,"timezone":{"currentOffset":-25200000,"previousOffset":-28800000,"previousTransition":1268560799999,"tzCurrentName":"Pacific Daylight Time","tzName":"America/Los_Angeles"},"validRegion":true},"sound":{{alarm}},"subject":"{{subject}}","text":"{{message}}","userText":true} 9 | getPartition 10 | {"clientContext":{"appName":"FindMyiPhone","appVersion":"1.4","buildVersion":"145","deviceUDID":"0000000000000000000000000000000000000000","inactiveTime":2147483647,"osVersion":"4.2.1","personID":0,"productType":"iPad1,1"}} 11 | initClient 12 | {"clientContext":{"appName":"FindMyiPhone","appVersion":"1.4","buildVersion":"145","deviceUDID":"0000000000000000000000000000000000000000","inactiveTime":2147483647,"osVersion":"4.2.1","personID":0,"productType":"iPad1,1"}} 13 | 14 | 15 | -------------------------------------------------------------------------------- /JSON/SBJsonWriter.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #import 31 | #import "SBJsonBase.h" 32 | 33 | /** 34 | @brief The JSON writer class. 35 | 36 | Objective-C types are mapped to JSON types in the following way: 37 | 38 | @li NSNull -> Null 39 | @li NSString -> String 40 | @li NSArray -> Array 41 | @li NSDictionary -> Object 42 | @li NSNumber (-initWithBool:) -> Boolean 43 | @li NSNumber -> Number 44 | 45 | In JSON the keys of an object must be strings. NSDictionary keys need 46 | not be, but attempting to convert an NSDictionary with non-string keys 47 | into JSON will throw an exception. 48 | 49 | NSNumber instances created with the +initWithBool: method are 50 | converted into the JSON boolean "true" and "false" values, and vice 51 | versa. Any other NSNumber instances are converted to a JSON number the 52 | way you would expect. 53 | 54 | */ 55 | @interface SBJsonWriter : SBJsonBase { 56 | 57 | @private 58 | BOOL sortKeys, humanReadable; 59 | } 60 | 61 | /** 62 | @brief Whether we are generating human-readable (multiline) JSON. 63 | 64 | Set whether or not to generate human-readable JSON. The default is NO, which produces 65 | JSON without any whitespace. (Except inside strings.) If set to YES, generates human-readable 66 | JSON with linebreaks after each array value and dictionary key/value pair, indented two 67 | spaces per nesting level. 68 | */ 69 | @property BOOL humanReadable; 70 | 71 | /** 72 | @brief Whether or not to sort the dictionary keys in the output. 73 | 74 | If this is set to YES, the dictionary keys in the JSON output will be in sorted order. 75 | (This is useful if you need to compare two structures, for example.) The default is NO. 76 | */ 77 | @property BOOL sortKeys; 78 | 79 | /** 80 | @brief Return JSON representation (or fragment) for the given object. 81 | 82 | Returns a string containing JSON representation of the passed in value, or nil on error. 83 | If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error. 84 | 85 | @param value any instance that can be represented as a JSON fragment 86 | 87 | */ 88 | - (NSString*)stringWithObject:(id)value; 89 | 90 | /** 91 | @brief Return JSON representation (or fragment) for the given object. 92 | 93 | Returns a string containing JSON representation of the passed in value, or nil on error. 94 | If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error. 95 | 96 | @param value any instance that can be represented as a JSON fragment 97 | @param error pointer to object to be populated with NSError on failure 98 | 99 | */- (NSString*)stringWithObject:(id)value 100 | error:(NSError**)error; 101 | 102 | 103 | @end 104 | 105 | /** 106 | @brief Allows generation of JSON for otherwise unsupported classes. 107 | 108 | If you have a custom class that you want to create a JSON representation for you can implement 109 | this method in your class. It should return a representation of your object defined 110 | in terms of objects that can be translated into JSON. For example, a Person 111 | object might implement it like this: 112 | 113 | @code 114 | - (id)proxyForJson { 115 | return [NSDictionary dictionaryWithObjectsAndKeys: 116 | name, @"name", 117 | phone, @"phone", 118 | email, @"email", 119 | nil]; 120 | } 121 | @endcode 122 | 123 | */ 124 | @interface NSObject (SBProxyForJson) 125 | - (id)proxyForJson; 126 | @end 127 | 128 | -------------------------------------------------------------------------------- /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 | #import 13 | 14 | @class SUUpdateDriver, SUAppcastItem, SUHost, SUAppcast; 15 | @interface SUUpdater : NSObject { 16 | NSTimer *checkTimer; 17 | SUUpdateDriver *driver; 18 | 19 | SUHost *host; 20 | IBOutlet id delegate; 21 | } 22 | 23 | + (SUUpdater *)sharedUpdater; 24 | + (SUUpdater *)updaterForBundle:(NSBundle *)bundle; 25 | - (NSBundle *)hostBundle; 26 | 27 | - (void)setDelegate:(id)delegate; 28 | - delegate; 29 | 30 | - (void)setAutomaticallyChecksForUpdates:(BOOL)automaticallyChecks; 31 | - (BOOL)automaticallyChecksForUpdates; 32 | 33 | - (void)setUpdateCheckInterval:(NSTimeInterval)interval; 34 | - (NSTimeInterval)updateCheckInterval; 35 | 36 | - (void)setFeedURL:(NSURL *)feedURL; 37 | - (NSURL *)feedURL; 38 | 39 | - (void)setSendsSystemProfile:(BOOL)sendsSystemProfile; 40 | - (BOOL)sendsSystemProfile; 41 | 42 | - (void)setAutomaticallyDownloadsUpdates:(BOOL)automaticallyDownloadsUpdates; 43 | - (BOOL)automaticallyDownloadsUpdates; 44 | 45 | // This IBAction is meant for a main menu item. Hook up any menu item to this action, 46 | // and Sparkle will check for updates and report back its findings verbosely. 47 | - (IBAction)checkForUpdates:sender; 48 | 49 | // This kicks off an update meant to be programmatically initiated. That is, it will display no UI unless it actually finds an update, 50 | // in which case it proceeds as usual. If the fully automated updating is turned on, however, this will invoke that behavior, and if an 51 | // update is found, it will be downloaded and prepped for installation. 52 | - (void)checkForUpdatesInBackground; 53 | 54 | // Date of last update check. Returns null if no check has been performed. 55 | - (NSDate*)lastUpdateCheckDate; 56 | 57 | // This begins a "probing" check for updates which will not actually offer to update to that version. The delegate methods, though, 58 | // (up to updater:didFindValidUpdate: and updaterDidNotFindUpdate:), are called, so you can use that information in your UI. 59 | - (void)checkForUpdateInformation; 60 | 61 | // Call this to appropriately schedule or cancel the update checking timer according to the preferences for time interval and automatic checks. This call does not change the date of the next check, but only the internal NSTimer. 62 | - (void)resetUpdateCycle; 63 | 64 | - (BOOL)updateInProgress; 65 | @end 66 | 67 | @interface NSObject (SUUpdaterDelegateInformalProtocol) 68 | // This method allows you to add extra parameters to the appcast URL, potentially based on whether or not Sparkle will also be sending along the system profile. This method should return an array of dictionaries with keys: "key", "value", "displayKey", "displayValue", the latter two being specifically for display to the user. 69 | - (NSArray *)feedParametersForUpdater:(SUUpdater *)updater sendingSystemProfile:(BOOL)sendingProfile; 70 | 71 | // Use this to override the default behavior for Sparkle prompting the user about automatic update checks. 72 | - (BOOL)updaterShouldPromptForPermissionToCheckForUpdates:(SUUpdater *)bundle; 73 | 74 | // Implement this if you want to do some special handling with the appcast once it finishes loading. 75 | - (void)updater:(SUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast; 76 | 77 | // If you're using special logic or extensions in your appcast, implement this to use your own logic for finding 78 | // a valid update, if any, in the given appcast. 79 | - (SUAppcastItem *)bestValidUpdateInAppcast:(SUAppcast *)appcast forUpdater:(SUUpdater *)bundle; 80 | 81 | // Sent when a valid update is found by the update driver. 82 | - (void)updater:(SUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)update; 83 | 84 | // Sent when a valid update is not found. 85 | - (void)updaterDidNotFindUpdate:(SUUpdater *)update; 86 | 87 | // Sent immediately before installing the specified update. 88 | - (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)update; 89 | 90 | // Return YES to delay the relaunch until you do some processing; invoke the given NSInvocation to continue. 91 | - (BOOL)updater:(SUUpdater *)updater shouldPostponeRelaunchForUpdate:(SUAppcastItem *)update untilInvoking:(NSInvocation *)invocation; 92 | 93 | // Called immediately before relaunching. 94 | - (void)updaterWillRelaunchApplication:(SUUpdater *)updater; 95 | 96 | // This method allows you to provide a custom version comparator. 97 | // If you don't implement this method or return nil, the standard version comparator will be used. 98 | - (id )versionComparatorForUpdater:(SUUpdater *)updater; 99 | 100 | // Returns the path which is used to relaunch the client after the update is installed. By default, the path of the host bundle. 101 | - (NSString *)pathToRelaunchForUpdater:(SUUpdater *)updater; 102 | 103 | @end 104 | 105 | // Define some minimum intervals to avoid DOS-like checking attacks. These are in seconds. 106 | #ifdef DEBUG 107 | #define SU_MIN_CHECK_INTERVAL 60 108 | #else 109 | #define SU_MIN_CHECK_INTERVAL 60*60 110 | #endif 111 | 112 | #ifdef DEBUG 113 | #define SU_DEFAULT_CHECK_INTERVAL 60 114 | #else 115 | #define SU_DEFAULT_CHECK_INTERVAL 60*60*24 116 | #endif 117 | 118 | #endif 119 | -------------------------------------------------------------------------------- /Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ADP2,1 6 | Developer Transition Kit 7 | MacBook1,1 8 | MacBook (Core Duo) 9 | MacBook2,1 10 | MacBook (Core 2 Duo) 11 | MacBook4,1 12 | MacBook (Core 2 Duo Feb 2008) 13 | MacBookAir1,1 14 | MacBook Air (January 2008) 15 | MacBookPro1,1 16 | MacBook Pro Core Duo (15-inch) 17 | MacBookPro1,2 18 | MacBook Pro Core Duo (17-inch) 19 | MacBookPro2,1 20 | MacBook Pro Core 2 Duo (17-inch) 21 | MacBookPro2,2 22 | MacBook Pro Core 2 Duo (15-inch) 23 | MacBookPro3,1 24 | MacBook Pro Core 2 Duo (15-inch LED, Core 2 Duo) 25 | MacBookPro3,2 26 | MacBook Pro Core 2 Duo (17-inch HD, Core 2 Duo) 27 | MacBookPro4,1 28 | MacBook Pro (Core 2 Duo Feb 2008) 29 | MacPro1,1 30 | Mac Pro (four-core) 31 | MacPro2,1 32 | Mac Pro (eight-core) 33 | MacPro3,1 34 | Mac Pro (January 2008 4- or 8- core "Harpertown") 35 | Macmini1,1 36 | Mac Mini (Core Solo/Duo) 37 | PowerBook1,1 38 | PowerBook G3 39 | PowerBook2,1 40 | iBook G3 41 | PowerBook2,2 42 | iBook G3 (FireWire) 43 | PowerBook2,3 44 | iBook G3 45 | PowerBook2,4 46 | iBook G3 47 | PowerBook3,1 48 | PowerBook G3 (FireWire) 49 | PowerBook3,2 50 | PowerBook G4 51 | PowerBook3,3 52 | PowerBook G4 (Gigabit Ethernet) 53 | PowerBook3,4 54 | PowerBook G4 (DVI) 55 | PowerBook3,5 56 | PowerBook G4 (1GHz / 867MHz) 57 | PowerBook4,1 58 | iBook G3 (Dual USB, Late 2001) 59 | PowerBook4,2 60 | iBook G3 (16MB VRAM) 61 | PowerBook4,3 62 | iBook G3 Opaque 16MB VRAM, 32MB VRAM, Early 2003) 63 | PowerBook5,1 64 | PowerBook G4 (17 inch) 65 | PowerBook5,2 66 | PowerBook G4 (15 inch FW 800) 67 | PowerBook5,3 68 | PowerBook G4 (17-inch 1.33GHz) 69 | PowerBook5,4 70 | PowerBook G4 (15 inch 1.5/1.33GHz) 71 | PowerBook5,5 72 | PowerBook G4 (17-inch 1.5GHz) 73 | PowerBook5,6 74 | PowerBook G4 (15 inch 1.67GHz/1.5GHz) 75 | PowerBook5,7 76 | PowerBook G4 (17-inch 1.67GHz) 77 | PowerBook5,8 78 | PowerBook G4 (Double layer SD, 15 inch) 79 | PowerBook5,9 80 | PowerBook G4 (Double layer SD, 17 inch) 81 | PowerBook6,1 82 | PowerBook G4 (12 inch) 83 | PowerBook6,2 84 | PowerBook G4 (12 inch, DVI) 85 | PowerBook6,3 86 | iBook G4 87 | PowerBook6,4 88 | PowerBook G4 (12 inch 1.33GHz) 89 | PowerBook6,5 90 | iBook G4 (Early-Late 2004) 91 | PowerBook6,7 92 | iBook G4 (Mid 2005) 93 | PowerBook6,8 94 | PowerBook G4 (12 inch 1.5GHz) 95 | PowerMac1,1 96 | Power Macintosh G3 (Blue & White) 97 | PowerMac1,2 98 | Power Macintosh G4 (PCI Graphics) 99 | PowerMac10,1 100 | Mac Mini G4 101 | PowerMac10,2 102 | Mac Mini (Late 2005) 103 | PowerMac11,2 104 | Power Macintosh G5 (Late 2005) 105 | PowerMac12,1 106 | iMac G5 (iSight) 107 | PowerMac2,1 108 | iMac G3 (Slot-loading CD-ROM) 109 | PowerMac2,2 110 | iMac G3 (Summer 2000) 111 | PowerMac3,1 112 | Power Macintosh G4 (AGP Graphics) 113 | PowerMac3,2 114 | Power Macintosh G4 (AGP Graphics) 115 | PowerMac3,3 116 | Power Macintosh G4 (Gigabit Ethernet) 117 | PowerMac3,4 118 | Power Macintosh G4 (Digital Audio) 119 | PowerMac3,5 120 | Power Macintosh G4 (Quick Silver) 121 | PowerMac3,6 122 | Power Macintosh G4 (Mirrored Drive Door) 123 | PowerMac4,1 124 | iMac G3 (Early/Summer 2001) 125 | PowerMac4,2 126 | iMac G4 (Flat Panel) 127 | PowerMac4,4 128 | eMac 129 | PowerMac4,5 130 | iMac G4 (17-inch Flat Panel) 131 | PowerMac5,1 132 | Power Macintosh G4 Cube 133 | PowerMac6,1 134 | iMac G4 (USB 2.0) 135 | PowerMac6,3 136 | iMac G4 (20-inch Flat Panel) 137 | PowerMac6,4 138 | eMac (USB 2.0, 2005) 139 | PowerMac7,2 140 | Power Macintosh G5 141 | PowerMac7,3 142 | Power Macintosh G5 143 | PowerMac8,1 144 | iMac G5 145 | PowerMac8,2 146 | iMac G5 (Ambient Light Sensor) 147 | PowerMac9,1 148 | Power Macintosh G5 (Late 2005) 149 | RackMac1,1 150 | Xserve G4 151 | RackMac1,2 152 | Xserve G4 (slot-loading, cluster node) 153 | RackMac3,1 154 | Xserve G5 155 | Xserve1,1 156 | Xserve (Intel Xeon) 157 | Xserve2,1 158 | Xserve (January 2008 quad-core) 159 | iMac1,1 160 | iMac G3 (Rev A-D) 161 | iMac4,1 162 | iMac (Core Duo) 163 | iMac4,2 164 | iMac for Education (17-inch, Core Duo) 165 | iMac5,1 166 | iMac (Core 2 Duo, 17 or 20 inch, SuperDrive) 167 | iMac5,2 168 | iMac (Core 2 Duo, 17 inch, Combo Drive) 169 | iMac6,1 170 | iMac (Core 2 Duo, 24 inch, SuperDrive) 171 | iMac8,1 172 | iMac (April 2008) 173 | 174 | 175 | -------------------------------------------------------------------------------- /EMKeychain/EMKeychainItem.h: -------------------------------------------------------------------------------- 1 | /*Copyright (c) 2009 Extendmac, LLC. 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | */ 24 | 25 | //Version 1.0.1, Last Updated February 1st, 2010. 26 | 27 | 28 | #import 29 | #import 30 | #import 31 | 32 | /*! 33 | @abstract EMKeychainItem is a self-contained wrapper class for two-way communication with the keychain. You can add, retrieve, and remove both generic and internet keychain items. 34 | @dicussion All keychain items have a username, password, and optionally a label. 35 | */ 36 | @interface EMKeychainItem : NSObject 37 | { 38 | @private 39 | NSString *mUsername; 40 | NSString *mPassword; 41 | NSString *mLabel; 42 | 43 | @protected 44 | SecKeychainItemRef mCoreKeychainItem; 45 | } 46 | 47 | /*! 48 | @abstract Returns whether or not errors are logged. 49 | @discussion Errors occur whenever a keychain item fails to appropriately update a property, or when a given keychain item cannot be found. 50 | */ 51 | + (BOOL)logsErrors; 52 | 53 | //! @abstracts Sets whether or not errors are logged. 54 | + (void)setLogsErrors:(BOOL)logsErrors; 55 | 56 | //! @abstracts Locks the keychain. 57 | + (void)lockKeychain; 58 | 59 | //! @abstract Unlocks the keychain. 60 | + (void)unlockKeychain; 61 | 62 | //! @abstract The keychain item's username. 63 | @property (readwrite, copy) NSString *username; 64 | 65 | //! @abstract The keychain item's password. 66 | @property (readwrite, copy) NSString *password; 67 | 68 | //! @abstract The keychain item's label. 69 | @property (readwrite, copy) NSString *label; 70 | 71 | /*! 72 | @abstract Removes the receiver from the keychain. 73 | @discussion After calling this method, you should generally discard of the receiver. The receiver cannot be "re-added" to the keychain; invoke either addGenericKeychainItemForServer:... or addInternetKeychainItemForServer:... instead. 74 | */ 75 | - (void)removeFromKeychain; 76 | 77 | @end 78 | 79 | #pragma mark - 80 | 81 | /*! 82 | @abstract An EMGenericKeychainItem wraps the functionality and data-members associated with a generic keychain item. 83 | @discussion Generic keychain items have a service name in addition to the standard keychain item properties. 84 | */ 85 | @interface EMGenericKeychainItem : EMKeychainItem 86 | { 87 | @private 88 | NSString *mServiceName; 89 | } 90 | 91 | //! @abstract The keychain item's service name. 92 | @property (readwrite, copy) NSString *serviceName; 93 | 94 | /*! 95 | @abstract Returns, if possible, a generic keychain item that corresponds to the given service. 96 | @param serviceName The service name. Cannot be nil. 97 | @param username The username. Cannot be nil. 98 | @result An EMGenericKeychainItem if the keychain item can be discovered. Otherwise, nil. 99 | */ 100 | + (EMGenericKeychainItem *)genericKeychainItemForService:(NSString *)serviceName 101 | withUsername:(NSString *)username; 102 | 103 | /*! 104 | @abstract Adds a keychain item for the given service. 105 | @param serviceName The service name. Cannot be nil. 106 | @param username The username. Cannot be nil. 107 | @param password The password to associate with the username and service. Cannot be nil. 108 | @result An EMGenericKeychainItem if the service can be added to the keychain. Otherwise, nil. 109 | */ 110 | + (EMGenericKeychainItem *)addGenericKeychainItemForService:(NSString *)serviceName 111 | withUsername:(NSString *)username 112 | password:(NSString *)password; 113 | @end 114 | 115 | #pragma mark - 116 | 117 | /*! 118 | @abstract An EMInternetKeychainItem wraps the functionality and data-members associated with an internet keychain item. 119 | @discussion Internet keychain items can optionally have a server, path, port, and protocol in addition to the standard keychain item properties. 120 | */ 121 | @interface EMInternetKeychainItem : EMKeychainItem 122 | { 123 | @private 124 | NSString *mServer; 125 | NSString *mPath; 126 | NSInteger mPort; 127 | SecProtocolType mProtocol; 128 | } 129 | 130 | 131 | /*! 132 | @abstract Returns, if possible, an internet keychain item that corresponds to the given server. 133 | @param server The server. Cannot be nil. 134 | @param username The username. Cannot be nil. 135 | @param path The path. 136 | @param port The port. 137 | @param protocol The protocol. 138 | @result An EMInternetKeychainItem if the keychain item can be discovered. Otherwise, nil. 139 | */ 140 | + (EMInternetKeychainItem *)internetKeychainItemForServer:(NSString *)server 141 | withUsername:(NSString *)username 142 | path:(NSString *)path 143 | port:(NSInteger)port 144 | protocol:(SecProtocolType)protocol; 145 | 146 | /*! 147 | @abstract Adds a keychain item for the given server. 148 | @param server The server. Cannot be nil. 149 | @param username The username. Cannot be nil. 150 | @param password The password to associate with the server, username, path, port, and protocol. Cannot be nil. 151 | @param path The path. 152 | @param port The port. 153 | @param protocol The protocol. 154 | @result An EMInternetKeychainItem if the item can be added to the keychain. Otherwise, nil. 155 | */ 156 | + (EMInternetKeychainItem *)addInternetKeychainItemForServer:(NSString *)server 157 | withUsername:(NSString *)username 158 | password:(NSString *)password 159 | path:(NSString *)path 160 | port:(NSInteger)port 161 | protocol:(SecProtocolType)protocol; 162 | 163 | //! @abstract The keychain item's server. 164 | @property (readwrite, copy) NSString *server; 165 | 166 | //! @abstract The keychain item's path. 167 | @property (readwrite, copy) NSString *path; 168 | 169 | //! @abstract The keychain item's port. 170 | @property (readwrite, assign) NSInteger port; 171 | 172 | //! @abstract The keychain item's protocol. 173 | @property (readwrite, assign) SecProtocolType protocol; 174 | 175 | @end -------------------------------------------------------------------------------- /JSON/SBJsonWriter.m: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2009 Stig Brautaset. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of the author nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific 16 | prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | #import "SBJsonWriter.h" 31 | 32 | @interface SBJsonWriter () 33 | 34 | - (BOOL)appendValue:(id)fragment into:(NSMutableString*)json; 35 | - (BOOL)appendArray:(NSArray*)fragment into:(NSMutableString*)json; 36 | - (BOOL)appendDictionary:(NSDictionary*)fragment into:(NSMutableString*)json; 37 | - (BOOL)appendString:(NSString*)fragment into:(NSMutableString*)json; 38 | 39 | - (NSString*)indent; 40 | 41 | @end 42 | 43 | @implementation SBJsonWriter 44 | 45 | @synthesize sortKeys; 46 | @synthesize humanReadable; 47 | 48 | static NSMutableCharacterSet *kEscapeChars; 49 | 50 | + (void)initialize { 51 | kEscapeChars = [[NSMutableCharacterSet characterSetWithRange: NSMakeRange(0,32)] retain]; 52 | [kEscapeChars addCharactersInString: @"\"\\"]; 53 | } 54 | 55 | - (NSString*)stringWithObject:(id)value { 56 | [self clearErrorTrace]; 57 | 58 | if ([value isKindOfClass:[NSDictionary class]] || [value isKindOfClass:[NSArray class]]) { 59 | depth = 0; 60 | NSMutableString *json = [NSMutableString stringWithCapacity:128]; 61 | if ([self appendValue:value into:json]) 62 | return json; 63 | } 64 | 65 | if ([value respondsToSelector:@selector(proxyForJson)]) { 66 | NSString *tmp = [self stringWithObject:[value proxyForJson]]; 67 | if (tmp) 68 | return tmp; 69 | } 70 | 71 | [self addErrorWithCode:EFRAGMENT description:@"Not valid type for JSON"]; 72 | return nil; 73 | } 74 | 75 | - (NSString*)stringWithObject:(id)value error:(NSError**)error { 76 | NSString *tmp = [self stringWithObject:value]; 77 | if (tmp) 78 | return tmp; 79 | 80 | if (error) 81 | *error = [self.errorTrace lastObject]; 82 | return nil; 83 | } 84 | 85 | - (NSString*)indent { 86 | return [@"\n" stringByPaddingToLength:1 + 2 * depth withString:@" " startingAtIndex:0]; 87 | } 88 | 89 | - (BOOL)appendValue:(id)fragment into:(NSMutableString*)json { 90 | if ([fragment isKindOfClass:[NSDictionary class]]) { 91 | if (![self appendDictionary:fragment into:json]) 92 | return NO; 93 | 94 | } else if ([fragment isKindOfClass:[NSArray class]]) { 95 | if (![self appendArray:fragment into:json]) 96 | return NO; 97 | 98 | } else if ([fragment isKindOfClass:[NSString class]]) { 99 | if (![self appendString:fragment into:json]) 100 | return NO; 101 | 102 | } else if ([fragment isKindOfClass:[NSNumber class]]) { 103 | if ('c' == *[fragment objCType]) { 104 | [json appendString:[fragment boolValue] ? @"true" : @"false"]; 105 | } else if ([fragment isEqualToNumber:(NSNumber*)kCFNumberNaN]) { 106 | [self addErrorWithCode:EUNSUPPORTED description:@"NaN is not a valid number in JSON"]; 107 | return NO; 108 | 109 | } else if (isinf([fragment doubleValue])) { 110 | [self addErrorWithCode:EUNSUPPORTED description:@"Infinity is not a valid number in JSON"]; 111 | return NO; 112 | 113 | } else { 114 | [json appendString:[fragment stringValue]]; 115 | } 116 | } else if ([fragment isKindOfClass:[NSNull class]]) { 117 | [json appendString:@"null"]; 118 | } else if ([fragment respondsToSelector:@selector(proxyForJson)]) { 119 | [self appendValue:[fragment proxyForJson] into:json]; 120 | 121 | } else { 122 | [self addErrorWithCode:EUNSUPPORTED description:[NSString stringWithFormat:@"JSON serialisation not supported for %@", [fragment class]]]; 123 | return NO; 124 | } 125 | return YES; 126 | } 127 | 128 | - (BOOL)appendArray:(NSArray*)fragment into:(NSMutableString*)json { 129 | if (maxDepth && ++depth > maxDepth) { 130 | [self addErrorWithCode:EDEPTH description: @"Nested too deep"]; 131 | return NO; 132 | } 133 | [json appendString:@"["]; 134 | 135 | BOOL addComma = NO; 136 | for (id value in fragment) { 137 | if (addComma) 138 | [json appendString:@","]; 139 | else 140 | addComma = YES; 141 | 142 | if ([self humanReadable]) 143 | [json appendString:[self indent]]; 144 | 145 | if (![self appendValue:value into:json]) { 146 | return NO; 147 | } 148 | } 149 | 150 | depth--; 151 | if ([self humanReadable] && [fragment count]) 152 | [json appendString:[self indent]]; 153 | [json appendString:@"]"]; 154 | return YES; 155 | } 156 | 157 | - (BOOL)appendDictionary:(NSDictionary*)fragment into:(NSMutableString*)json { 158 | if (maxDepth && ++depth > maxDepth) { 159 | [self addErrorWithCode:EDEPTH description: @"Nested too deep"]; 160 | return NO; 161 | } 162 | [json appendString:@"{"]; 163 | 164 | NSString *colon = [self humanReadable] ? @" : " : @":"; 165 | BOOL addComma = NO; 166 | NSArray *keys = [fragment allKeys]; 167 | if (self.sortKeys) 168 | keys = [keys sortedArrayUsingSelector:@selector(compare:)]; 169 | 170 | for (id value in keys) { 171 | if (addComma) 172 | [json appendString:@","]; 173 | else 174 | addComma = YES; 175 | 176 | if ([self humanReadable]) 177 | [json appendString:[self indent]]; 178 | 179 | if (![value isKindOfClass:[NSString class]]) { 180 | [self addErrorWithCode:EUNSUPPORTED description: @"JSON object key must be string"]; 181 | return NO; 182 | } 183 | 184 | if (![self appendString:value into:json]) 185 | return NO; 186 | 187 | [json appendString:colon]; 188 | if (![self appendValue:[fragment objectForKey:value] into:json]) { 189 | [self addErrorWithCode:EUNSUPPORTED description:[NSString stringWithFormat:@"Unsupported value for key %@ in object", value]]; 190 | return NO; 191 | } 192 | } 193 | 194 | depth--; 195 | if ([self humanReadable] && [fragment count]) 196 | [json appendString:[self indent]]; 197 | [json appendString:@"}"]; 198 | return YES; 199 | } 200 | 201 | - (BOOL)appendString:(NSString*)fragment into:(NSMutableString*)json { 202 | 203 | [json appendString:@"\""]; 204 | 205 | NSRange esc = [fragment rangeOfCharacterFromSet:kEscapeChars]; 206 | if ( !esc.length ) { 207 | // No special chars -- can just add the raw string: 208 | [json appendString:fragment]; 209 | 210 | } else { 211 | NSUInteger length = [fragment length]; 212 | for (NSUInteger i = 0; i < length; i++) { 213 | unichar uc = [fragment characterAtIndex:i]; 214 | switch (uc) { 215 | case '"': [json appendString:@"\\\""]; break; 216 | case '\\': [json appendString:@"\\\\"]; break; 217 | case '\t': [json appendString:@"\\t"]; break; 218 | case '\n': [json appendString:@"\\n"]; break; 219 | case '\r': [json appendString:@"\\r"]; break; 220 | case '\b': [json appendString:@"\\b"]; break; 221 | case '\f': [json appendString:@"\\f"]; break; 222 | default: 223 | if (uc < 0x20) { 224 | [json appendFormat:@"\\u%04x", uc]; 225 | } else { 226 | CFStringAppendCharacters((CFMutableStringRef)json, &uc, 1); 227 | } 228 | break; 229 | 230 | } 231 | } 232 | } 233 | 234 | [json appendString:@"\""]; 235 | return YES; 236 | } 237 | 238 | 239 | @end 240 | -------------------------------------------------------------------------------- /NSData+Base64.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSData+Base64.m 3 | // base64 4 | // 5 | // Created by Matt Gallagher on 2009/06/03. 6 | // Copyright 2009 Matt Gallagher. All rights reserved. 7 | // 8 | // Permission is given to use this source code file, free of charge, in any 9 | // project, commercial or otherwise, entirely at your risk, with the condition 10 | // that any redistribution (in part or whole) of source code must retain 11 | // this copyright and permission notice. Attribution in compiled projects is 12 | // appreciated but not required. 13 | // 14 | 15 | #import "NSData+Base64.h" 16 | 17 | // 18 | // Mapping from 6 bit pattern to ASCII character. 19 | // 20 | static unsigned char base64EncodeLookup[65] = 21 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 22 | 23 | // 24 | // Definition for "masked-out" areas of the base64DecodeLookup mapping 25 | // 26 | #define xx 65 27 | 28 | // 29 | // Mapping from ASCII character to 6 bit pattern. 30 | // 31 | static unsigned char base64DecodeLookup[256] = 32 | { 33 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 34 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 35 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 62, xx, xx, xx, 63, 36 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, xx, xx, xx, xx, xx, xx, 37 | xx, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 38 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, xx, xx, xx, xx, xx, 39 | xx, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 40 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, xx, xx, xx, xx, xx, 41 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 42 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 43 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 44 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 45 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 46 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 47 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 48 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 49 | }; 50 | 51 | // 52 | // Fundamental sizes of the binary and base64 encode/decode units in bytes 53 | // 54 | #define BINARY_UNIT_SIZE 3 55 | #define BASE64_UNIT_SIZE 4 56 | 57 | // 58 | // NewBase64Decode 59 | // 60 | // Decodes the base64 ASCII string in the inputBuffer to a newly malloced 61 | // output buffer. 62 | // 63 | // inputBuffer - the source ASCII string for the decode 64 | // length - the length of the string or -1 (to specify strlen should be used) 65 | // outputLength - if not-NULL, on output will contain the decoded length 66 | // 67 | // returns the decoded buffer. Must be free'd by caller. Length is given by 68 | // outputLength. 69 | // 70 | void *NewBase64Decode( 71 | const char *inputBuffer, 72 | size_t length, 73 | size_t *outputLength) 74 | { 75 | if (length == -1) 76 | { 77 | length = strlen(inputBuffer); 78 | } 79 | 80 | size_t outputBufferSize = (length / BASE64_UNIT_SIZE) * BINARY_UNIT_SIZE; 81 | unsigned char *outputBuffer = (unsigned char *)malloc(outputBufferSize); 82 | 83 | size_t i = 0; 84 | size_t j = 0; 85 | while (i < length) 86 | { 87 | // 88 | // Accumulate 4 valid characters (ignore everything else) 89 | // 90 | unsigned char accumulated[BASE64_UNIT_SIZE]; 91 | size_t accumulateIndex = 0; 92 | while (i < length) 93 | { 94 | unsigned char decode = base64DecodeLookup[inputBuffer[i++]]; 95 | if (decode != xx) 96 | { 97 | accumulated[accumulateIndex] = decode; 98 | accumulateIndex++; 99 | 100 | if (accumulateIndex == BASE64_UNIT_SIZE) 101 | { 102 | break; 103 | } 104 | } 105 | } 106 | 107 | // 108 | // Store the 6 bits from each of the 4 characters as 3 bytes 109 | // 110 | outputBuffer[j] = (accumulated[0] << 2) | (accumulated[1] >> 4); 111 | outputBuffer[j + 1] = (accumulated[1] << 4) | (accumulated[2] >> 2); 112 | outputBuffer[j + 2] = (accumulated[2] << 6) | accumulated[3]; 113 | j += accumulateIndex - 1; 114 | } 115 | 116 | if (outputLength) 117 | { 118 | *outputLength = j; 119 | } 120 | return outputBuffer; 121 | } 122 | 123 | // 124 | // NewBase64Decode 125 | // 126 | // Encodes the arbitrary data in the inputBuffer as base64 into a newly malloced 127 | // output buffer. 128 | // 129 | // inputBuffer - the source data for the encode 130 | // length - the length of the input in bytes 131 | // separateLines - if zero, no CR/LF characters will be added. Otherwise 132 | // a CR/LF pair will be added every 64 encoded chars. 133 | // outputLength - if not-NULL, on output will contain the encoded length 134 | // (not including terminating 0 char) 135 | // 136 | // returns the encoded buffer. Must be free'd by caller. Length is given by 137 | // outputLength. 138 | // 139 | char *NewBase64Encode( 140 | const void *buffer, 141 | size_t length, 142 | bool separateLines, 143 | size_t *outputLength) 144 | { 145 | const unsigned char *inputBuffer = (const unsigned char *)buffer; 146 | 147 | #define MAX_NUM_PADDING_CHARS 2 148 | #define OUTPUT_LINE_LENGTH 64 149 | #define INPUT_LINE_LENGTH ((OUTPUT_LINE_LENGTH / BASE64_UNIT_SIZE) * BINARY_UNIT_SIZE) 150 | #define CR_LF_SIZE 2 151 | 152 | // 153 | // Byte accurate calculation of final buffer size 154 | // 155 | size_t outputBufferSize = 156 | ((length / BINARY_UNIT_SIZE) 157 | + ((length % BINARY_UNIT_SIZE) ? 1 : 0)) 158 | * BASE64_UNIT_SIZE; 159 | if (separateLines) 160 | { 161 | outputBufferSize += 162 | (outputBufferSize / OUTPUT_LINE_LENGTH) * CR_LF_SIZE; 163 | } 164 | 165 | // 166 | // Include space for a terminating zero 167 | // 168 | outputBufferSize += 1; 169 | 170 | // 171 | // Allocate the output buffer 172 | // 173 | char *outputBuffer = (char *)malloc(outputBufferSize); 174 | if (!outputBuffer) 175 | { 176 | return NULL; 177 | } 178 | 179 | size_t i = 0; 180 | size_t j = 0; 181 | const size_t lineLength = separateLines ? INPUT_LINE_LENGTH : length; 182 | size_t lineEnd = lineLength; 183 | 184 | while (true) 185 | { 186 | if (lineEnd > length) 187 | { 188 | lineEnd = length; 189 | } 190 | 191 | for (; i + BINARY_UNIT_SIZE - 1 < lineEnd; i += BINARY_UNIT_SIZE) 192 | { 193 | // 194 | // Inner loop: turn 48 bytes into 64 base64 characters 195 | // 196 | outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0xFC) >> 2]; 197 | outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i] & 0x03) << 4) 198 | | ((inputBuffer[i + 1] & 0xF0) >> 4)]; 199 | outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i + 1] & 0x0F) << 2) 200 | | ((inputBuffer[i + 2] & 0xC0) >> 6)]; 201 | outputBuffer[j++] = base64EncodeLookup[inputBuffer[i + 2] & 0x3F]; 202 | } 203 | 204 | if (lineEnd == length) 205 | { 206 | break; 207 | } 208 | 209 | // 210 | // Add the newline 211 | // 212 | outputBuffer[j++] = '\r'; 213 | outputBuffer[j++] = '\n'; 214 | lineEnd += lineLength; 215 | } 216 | 217 | if (i + 1 < length) 218 | { 219 | // 220 | // Handle the single '=' case 221 | // 222 | outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0xFC) >> 2]; 223 | outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i] & 0x03) << 4) 224 | | ((inputBuffer[i + 1] & 0xF0) >> 4)]; 225 | outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i + 1] & 0x0F) << 2]; 226 | outputBuffer[j++] = '='; 227 | } 228 | else if (i < length) 229 | { 230 | // 231 | // Handle the double '=' case 232 | // 233 | outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0xFC) >> 2]; 234 | outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0x03) << 4]; 235 | outputBuffer[j++] = '='; 236 | outputBuffer[j++] = '='; 237 | } 238 | outputBuffer[j] = 0; 239 | 240 | // 241 | // Set the output length and return the buffer 242 | // 243 | if (outputLength) 244 | { 245 | *outputLength = j; 246 | } 247 | return outputBuffer; 248 | } 249 | 250 | @implementation NSData (Base64) 251 | 252 | // 253 | // dataFromBase64String: 254 | // 255 | // Creates an NSData object containing the base64 decoded representation of 256 | // the base64 string 'aString' 257 | // 258 | // Parameters: 259 | // aString - the base64 string to decode 260 | // 261 | // returns the autoreleased NSData representation of the base64 string 262 | // 263 | + (NSData *)dataFromBase64String:(NSString *)aString 264 | { 265 | NSData *data = [aString dataUsingEncoding:NSASCIIStringEncoding]; 266 | size_t outputLength; 267 | void *outputBuffer = NewBase64Decode([data bytes], [data length], &outputLength); 268 | NSData *result = [NSData dataWithBytes:outputBuffer length:outputLength]; 269 | free(outputBuffer); 270 | return result; 271 | } 272 | 273 | // 274 | // base64EncodedString 275 | // 276 | // Creates an NSString object that contains the base 64 encoding of the 277 | // receiver's data. Lines are broken at 64 characters long. 278 | // 279 | // returns an autoreleased NSString being the base 64 representation of the 280 | // receiver. 281 | // 282 | - (NSString *)base64EncodedString 283 | { 284 | size_t outputLength; 285 | char *outputBuffer = 286 | NewBase64Encode([self bytes], [self length], true, &outputLength); 287 | 288 | NSString *result = 289 | [[[NSString alloc] 290 | initWithBytes:outputBuffer 291 | length:outputLength 292 | encoding:NSASCIIStringEncoding] 293 | autorelease]; 294 | free(outputBuffer); 295 | return result; 296 | } 297 | 298 | @end 299 | -------------------------------------------------------------------------------- /SSMAccount.m: -------------------------------------------------------------------------------- 1 | // 2 | // SSMAccount.m 3 | // Sosumi 4 | // 5 | // Created by Tyler Hall on 11/28/10. 6 | // Copyright 2010 Click On Tyler, LLC. All rights reserved. 7 | // 8 | 9 | #import "SSMAccount.h" 10 | #import "SSMDevice.h" 11 | #import "GTMHTTPFetcher.h" 12 | #import "NSData+Base64.h" 13 | #import "JSON.h" 14 | #import "NetworkSpinner.h" 15 | 16 | #define SINFO(title, subtitle) [NSDictionary dictionaryWithObjectsAndKeys:title, @"title", subtitle, @"subtitle", nil] 17 | 18 | @implementation SSMAccount 19 | 20 | @synthesize username; 21 | @synthesize password; 22 | @synthesize devices; 23 | @synthesize partition; 24 | @synthesize isUpdating; 25 | @synthesize isRefreshing; 26 | @synthesize treeNode; 27 | 28 | - (id)init 29 | { 30 | self = [super init]; 31 | 32 | self.devices = [[NSMutableDictionary alloc] init]; 33 | refreshTimerInterval = 10.0; 34 | 35 | return self; 36 | } 37 | 38 | - (NSString *)name 39 | { 40 | return self.username; 41 | } 42 | 43 | - (NSString *)apiStringsForMethod:(NSString *)method 44 | { 45 | NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"SosumiAPI" ofType:@"plist"]]; 46 | return [dict valueForKey:method]; 47 | } 48 | 49 | - (void)beginUpdatingDevices 50 | { 51 | self.isUpdating = YES; 52 | refreshTimer = [[NSTimer alloc] initWithFireDate:[NSDate date] interval:refreshTimerInterval target:self selector:@selector(refresh) userInfo:nil repeats:YES]; 53 | [[NSRunLoop mainRunLoop] addTimer:refreshTimer forMode:NSDefaultRunLoopMode]; 54 | } 55 | 56 | - (void)stopUpdatingDevices 57 | { 58 | self.isUpdating = NO; 59 | [refreshTimer invalidate]; 60 | } 61 | 62 | - (void)refresh 63 | { 64 | self.isRefreshing = YES; 65 | [NetworkSpinner queue]; 66 | 67 | if(!self.partition) { 68 | [self getPartition]; 69 | return; 70 | } 71 | 72 | GTMHTTPFetcher *fetcher = [self getPreparedFetcherWithMethod:@"initClient"]; 73 | 74 | NSString *postStr = [self apiStringsForMethod:@"initClient"]; 75 | [fetcher setPostData:[postStr dataUsingEncoding:NSUTF8StringEncoding]]; 76 | 77 | [fetcher beginFetchWithCompletionHandler:^(NSData *retrievedData, NSError *error) { 78 | if(error != nil) { 79 | NSLog(@"%@", error); 80 | self.isRefreshing = NO; 81 | [NetworkSpinner dequeue]; 82 | } 83 | else { 84 | NSDictionary *json = [[[NSString alloc] initWithData:retrievedData encoding:NSUTF8StringEncoding] JSONValue]; 85 | // NSLog(@"%@", json); 86 | 87 | // So we don't get throttled for hammering. 88 | // https://github.com/tylerhall/MacSosumi/issues/8 89 | NSDictionary *serverContext = json[@"serverContext"]; 90 | if(serverContext) { 91 | refreshTimerInterval = [[serverContext valueForKey:@"callbackIntervalInMS"] floatValue] / 1000; 92 | } else { 93 | refreshTimerInterval = 30.0; 94 | } 95 | 96 | NSArray *rawDevices = json[@"content"]; 97 | if(rawDevices) { 98 | for(NSDictionary *rawDevice in rawDevices) { 99 | 100 | SSMDevice *device; 101 | BOOL found = NO; 102 | NSMutableArray *childNodes = [self.treeNode mutableChildNodes]; 103 | for(int i = 0; i < [childNodes count]; i++) { 104 | if([[(SSMDevice *)[childNodes[i] representedObject] deviceId] isEqualToString:rawDevice[@"id"]]) { 105 | found = YES; 106 | device = [childNodes[i] representedObject]; 107 | break; 108 | } 109 | } 110 | 111 | if(!found) { 112 | device = [[SSMDevice alloc] init]; 113 | } 114 | 115 | device.parent = self; 116 | device.isLocating = [rawDevice[@"isLocating"] boolValue]; 117 | device.deviceClass = rawDevice[@"deviceClass"]; 118 | device.deviceModel = rawDevice[@"deviceModel"]; 119 | device.deviceStatus = rawDevice[@"deviceStatus"]; 120 | device.deviceId = rawDevice[@"id"]; 121 | device.name = rawDevice[@"name"]; 122 | device.isCharging = [(NSString *)rawDevice[@"batteryStatus"] isEqualToString:@"Charging"]; 123 | device.batteryLevel = rawDevice[@"batteryLevel"]; 124 | 125 | id location = rawDevice[@"location"]; 126 | if(location != [NSNull null]) { 127 | device.locationTimestamp = [NSDate dateWithTimeIntervalSince1970:[(NSNumber *)[location valueForKey:@"timeStamp"] doubleValue] / 1000]; 128 | device.locationType = location[@"positionType"]; 129 | device.horizontalAccuracy = location[@"horizontalAccuracy"]; 130 | device.locationFinished = [[location valueForKey:@"locationFinished"] boolValue]; 131 | device.longitude = location[@"longitude"]; 132 | device.latitude = location[@"latitude"]; 133 | } 134 | [self.devices setValue:device forKey:device.deviceId]; 135 | 136 | if(!found) { 137 | NSTreeNode *deviceTreeNode = [NSTreeNode treeNodeWithRepresentedObject:device]; 138 | [[self.treeNode mutableChildNodes] addObject:deviceTreeNode]; 139 | } 140 | } 141 | } 142 | self.isRefreshing = NO; 143 | [NetworkSpinner dequeue]; 144 | [[NSNotificationCenter defaultCenter] postNotificationName:@"DEVICES_DID_UPDATE" object:self]; 145 | } 146 | }]; 147 | } 148 | 149 | - (void)getPartition 150 | { 151 | GTMHTTPFetcher *fetcher = [self getPreparedFetcherWithMethod:@"initClient"]; 152 | 153 | NSString *postStr = [self apiStringsForMethod:@"getPartition"]; 154 | [fetcher setPostData:[postStr dataUsingEncoding:NSUTF8StringEncoding]]; 155 | 156 | [fetcher beginFetchWithCompletionHandler:^(NSData *retrievedData, NSError *error) { 157 | if(error != nil) { 158 | if([[fetcher responseHeaders] valueForKey:@"X-Apple-MMe-Host"]) { 159 | self.partition = [[fetcher responseHeaders] valueForKey:@"X-Apple-MMe-Host"]; 160 | [NetworkSpinner dequeue]; 161 | [self refresh]; 162 | } else { 163 | NSLog(@"Could not login to FMIP"); 164 | self.isRefreshing = NO; 165 | [NetworkSpinner dequeue]; 166 | } 167 | 168 | } else { 169 | NSLog(@"Could not login to FMIP"); 170 | self.isRefreshing = NO; 171 | [NetworkSpinner dequeue]; 172 | } 173 | }]; 174 | } 175 | 176 | - (void)sendMessage:(NSString *)message withSubject:(NSString *)subject andAlarm:(BOOL)alarm toDevice:(NSString *)deviceId; 177 | { 178 | GTMHTTPFetcher *fetcher = [self getPreparedFetcherWithMethod:@"sendMessage"]; 179 | 180 | NSMutableString *postStr = [[self apiStringsForMethod:@"sendMessage"] mutableCopy]; 181 | [postStr replaceOccurrencesOfString:@"{{device}}" withString:deviceId options:NSCaseInsensitiveSearch range:NSMakeRange(0, [postStr length])]; 182 | [postStr replaceOccurrencesOfString:@"{{subject}}" withString:subject options:NSCaseInsensitiveSearch range:NSMakeRange(0, [postStr length])]; 183 | [postStr replaceOccurrencesOfString:@"{{message}}" withString:message options:NSCaseInsensitiveSearch range:NSMakeRange(0, [postStr length])]; 184 | [postStr replaceOccurrencesOfString:@"{{alarm}}" withString:(alarm ? @"true" : @"false") options:NSCaseInsensitiveSearch range:NSMakeRange(0, [postStr length])]; 185 | 186 | [fetcher setPostData:[postStr dataUsingEncoding:NSUTF8StringEncoding]]; 187 | 188 | [NetworkSpinner queue]; 189 | [fetcher beginFetchWithCompletionHandler:^(NSData *retrievedData, NSError *error) { 190 | [NetworkSpinner dequeue]; 191 | }]; 192 | } 193 | 194 | - (void)remoteLockDevice:(NSString *)deviceId withPasscode:(NSString *)passcode 195 | { 196 | GTMHTTPFetcher *fetcher = [self getPreparedFetcherWithMethod:@"remoteLock"]; 197 | 198 | NSMutableString *postStr = [[self apiStringsForMethod:@"remoteLock"] mutableCopy]; 199 | [postStr replaceOccurrencesOfString:@"{{device}}" withString:deviceId options:NSCaseInsensitiveSearch range:NSMakeRange(0, [postStr length])]; 200 | [postStr replaceOccurrencesOfString:@"{{code}}" withString:passcode options:NSCaseInsensitiveSearch range:NSMakeRange(0, [postStr length])]; 201 | 202 | [fetcher setPostData:[postStr dataUsingEncoding:NSUTF8StringEncoding]]; 203 | 204 | [NetworkSpinner queue]; 205 | [fetcher beginFetchWithCompletionHandler:^(NSData *retrievedData, NSError *error) { 206 | [NetworkSpinner dequeue]; 207 | }]; 208 | } 209 | 210 | - (GTMHTTPFetcher *)getPreparedFetcherWithMethod:(NSString *)method 211 | { 212 | NSString *urlStr; 213 | 214 | if(!self.partition) 215 | urlStr = [NSString stringWithFormat:@"https://fmipmobile.icloud.com/fmipservice/device/%@/%@", self.username, method]; 216 | else 217 | urlStr = [NSString stringWithFormat:@"https://%@/fmipservice/device/%@/%@", self.partition, self.username, method]; 218 | 219 | NSURL *url = [NSURL URLWithString:urlStr]; 220 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; 221 | [request addValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; 222 | [request addValue:@"2.0" forHTTPHeaderField:@"X-Apple-Find-Api-Ver"]; 223 | [request addValue:@"UserIdGuest" forHTTPHeaderField:@"X-Apple-Authscheme"]; 224 | [request addValue:@"1.2" forHTTPHeaderField:@"X-Apple-Realm-Support"]; 225 | [request addValue:@"Find iPhone/1.1 MeKit (iPad: iPhone OS/4.2.1)" forHTTPHeaderField:@"User-agent"]; 226 | [request addValue:@"iPad" forHTTPHeaderField:@"X-Client-Name"]; 227 | [request addValue:@"0cf3dc501ff812adb0b202baed4f37274b210853" forHTTPHeaderField:@"X-Client-Uuid"]; 228 | [request addValue:@"en-us" forHTTPHeaderField:@"Accept-Language"]; 229 | 230 | NSData *userPwd = [[NSString stringWithFormat:@"%@:%@", self.username, self.password] dataUsingEncoding:NSASCIIStringEncoding]; 231 | [request addValue:[NSString stringWithFormat:@"Basic %@", [userPwd base64EncodedString]] forHTTPHeaderField:@"Authorization"]; 232 | 233 | GTMHTTPFetcher *fetcher = [GTMHTTPFetcher fetcherWithRequest:request]; 234 | [fetcher setUserData:SINFO(method, [[[fetcher mutableRequest] URL] absoluteString])]; 235 | 236 | return fetcher; 237 | } 238 | 239 | @end 240 | -------------------------------------------------------------------------------- /SosumiAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SosumiAppDelegate.m 3 | // Sosumi 4 | // 5 | // Created by Tyler Hall on 11/28/10. 6 | // Copyright 2010 Click On Tyler, LLC. All rights reserved. 7 | // 8 | 9 | #import "SosumiAppDelegate.h" 10 | #import "SSMAccount.h" 11 | #import "SSMDevice.h" 12 | #import "THImageRow.h" 13 | #import "EMKeychainItem.h" 14 | 15 | @implementation SosumiAppDelegate 16 | 17 | @synthesize window; 18 | @synthesize panelSyncActivity; 19 | 20 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 21 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshOutline:) name:@"DEVICES_DID_UPDATE" object:nil]; 22 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showSpinner:) name:@"SHOW_SPINNER" object:nil]; 23 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hideSpinner:) name:@"HIDE_SPINNER" object:nil]; 24 | 25 | NSArray *accounts = [[NSUserDefaults standardUserDefaults] objectForKey:@"accounts"]; 26 | if(accounts == nil) { 27 | [self addAccountWasClicked:self]; 28 | } else { 29 | for(NSDictionary *dict in accounts) { 30 | NSTreeNode *treeNode; 31 | SSMAccount *tmpAccount = [[SSMAccount alloc] init]; 32 | tmpAccount.username = dict[@"username"]; 33 | EMGenericKeychainItem *kcItem = [EMGenericKeychainItem genericKeychainItemForService:@"Sosumi" withUsername:tmpAccount.username]; 34 | tmpAccount.password = kcItem.password; 35 | [tmpAccount beginUpdatingDevices]; 36 | treeNode = [NSTreeNode treeNodeWithRepresentedObject:tmpAccount]; 37 | tmpAccount.treeNode = treeNode; 38 | [treeController insertObject:treeNode atArrangedObjectIndexPath:[NSIndexPath indexPathWithIndex:0]]; 39 | } 40 | } 41 | 42 | // In an old version we were storing the user's password in NSUserDefaults. After we switched to using the Keychain, 43 | // we forgot to erase the old password from disk. This fixes that. 44 | NSMutableArray *fixedAccounts = [NSMutableArray array]; 45 | for(int i = 0; i < [accounts count]; i++) { 46 | NSDictionary *credentials = accounts[i]; 47 | NSDictionary *dict = @{@"username": credentials[@"username"]}; 48 | [fixedAccounts addObject:dict]; 49 | } 50 | [[NSUserDefaults standardUserDefaults] setObject:fixedAccounts forKey:@"accounts"]; 51 | [[NSUserDefaults standardUserDefaults] synchronize]; 52 | 53 | [self refreshOutline:nil]; 54 | 55 | NSString *html = [[NSString alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"map" ofType:@"html"] encoding:NSUTF8StringEncoding error:nil]; 56 | [[map mainFrame] loadHTMLString:html baseURL:[NSURL URLWithString:@"http://maps.google.com"]]; 57 | } 58 | 59 | - (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender 60 | { 61 | [window makeKeyAndOrderFront:self]; 62 | return NO; 63 | } 64 | 65 | #pragma mark - 66 | #pragma mark Outline View Delegates 67 | #pragma mark - 68 | 69 | - (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item 70 | { 71 | id device = [[item representedObject] representedObject]; 72 | if([device isKindOfClass:[SSMDevice class]]) { 73 | [(THImageRow *)cell setImageName:[(SSMDevice *)device statusImage]]; 74 | } else { 75 | [(THImageRow *)cell setImageName:nil]; 76 | } 77 | } 78 | 79 | - (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item 80 | { 81 | return [[[item representedObject] representedObject] isKindOfClass:[SSMAccount class]]; 82 | } 83 | 84 | - (BOOL)outlineView:(NSOutlineView *)outlineView shouldShowOutlineCellForItem:(id)item 85 | { 86 | return NO; 87 | } 88 | 89 | - (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item 90 | { 91 | return ![[[item representedObject] representedObject] isKindOfClass:[SSMAccount class]]; 92 | } 93 | 94 | - (void)refreshOutline:(NSNotification *)notification 95 | { 96 | [outlineView reloadData]; 97 | [outlineView expandItem:nil expandChildren:YES]; 98 | [self refreshMap]; 99 | } 100 | 101 | #pragma mark - 102 | #pragma mark Split View Delegates 103 | #pragma mark - 104 | 105 | - (BOOL)splitView:(NSSplitView *)splitView shouldAdjustSizeOfSubview:(NSView *)subview 106 | { 107 | if(subview == [splitView subviews][0]) { 108 | return NO; 109 | } 110 | 111 | return YES; 112 | } 113 | 114 | - (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)dividerIndex 115 | { 116 | return 150.0; 117 | } 118 | 119 | - (CGFloat)splitView:(NSSplitView *)splitView constrainMaxCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)dividerIndex 120 | { 121 | return 350.0; 122 | } 123 | 124 | #pragma mark - 125 | #pragma mark Webview Delgates 126 | #pragma mark - 127 | 128 | - (void)refreshMap 129 | { 130 | NSArray *args; 131 | 132 | WebScriptObject *ws = [map windowScriptObject]; 133 | 134 | for(NSTreeNode *accountTreeNode in [treeController content]) { 135 | for(NSTreeNode *deviceTreeNode in [accountTreeNode childNodes]) { 136 | SSMDevice *device = [deviceTreeNode representedObject]; 137 | if(device.latitude != nil && device.longitude != nil) { 138 | // NSLog(@"mapped %@ %@ %@", device.name, device.latitude, device.longitude); 139 | args = @[device.deviceId, device.name, device.latitude, device.longitude, device.imageURL]; 140 | [ws callWebScriptMethod:@"createMarker" withArguments:args]; 141 | } 142 | } 143 | } 144 | } 145 | 146 | #pragma mark - 147 | #pragma mark IBActions 148 | #pragma mark - 149 | 150 | - (IBAction)addAccountWasClicked:(id)sender 151 | { 152 | [txtUsername setStringValue:@""]; 153 | [txtPassword setStringValue:@""]; 154 | [NSApp beginSheet:panelAddAccount modalForWindow:self.window modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:NULL]; 155 | } 156 | 157 | - (IBAction)removeAccountWasClicked:(id)sender 158 | { 159 | if([[treeController selectedNodes] count] == 0) { 160 | return; 161 | } 162 | 163 | NSTreeNode *treeNode = [treeController selectedNodes][0]; 164 | SSMAccount *account = [[[treeNode parentNode] representedObject] representedObject]; 165 | 166 | EMGenericKeychainItem *kcItem = [EMGenericKeychainItem genericKeychainItemForService:@"Sosumi" withUsername:account.username]; 167 | if(kcItem) { 168 | [kcItem removeFromKeychain]; 169 | } 170 | 171 | NSMutableArray *accounts = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:@"accounts"]]; 172 | if(accounts) { 173 | for(int i = 0; i < [accounts count]; i++) { 174 | NSDictionary *tmpAccount = accounts[i]; 175 | if([tmpAccount[@"username"] isEqualToString:account.username]) { 176 | [accounts removeObject:tmpAccount]; 177 | } 178 | } 179 | } 180 | 181 | [[NSUserDefaults standardUserDefaults] setObject:accounts forKey:@"accounts"]; 182 | [[NSUserDefaults standardUserDefaults] synchronize]; 183 | 184 | [treeController removeObjectAtArrangedObjectIndexPath:[[treeNode parentNode] indexPath]]; 185 | } 186 | 187 | - (void)sheetDidEnd:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo 188 | { 189 | 190 | } 191 | 192 | - (IBAction)viewOnMapWasClicked:(id)sender 193 | { 194 | if([[treeController selectedNodes] count] == 0) { 195 | return; 196 | } 197 | 198 | NSTreeNode *node = [treeController selectedNodes][0]; 199 | SSMDevice *device = [[node representedObject] representedObject]; 200 | 201 | WebScriptObject *ws = [map windowScriptObject]; 202 | NSArray *args = @[device.deviceId]; 203 | [ws callWebScriptMethod:@"viewOnMap" withArguments:args]; 204 | } 205 | 206 | - (IBAction)refreshWasClicked:(id)sender 207 | { 208 | for(NSTreeNode *accountTreeNode in [treeController content]) { 209 | SSMAccount *account = [accountTreeNode representedObject]; 210 | [account refresh]; 211 | } 212 | } 213 | 214 | - (IBAction)sendMessageWasClicked:(id)sender 215 | { 216 | [txtSubject setStringValue:@""]; 217 | [txtMessage setStringValue:@""]; 218 | [chkAlarm setState:NSOffState]; 219 | [NSApp beginSheet:panelSendMessage modalForWindow:self.window modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:NULL]; 220 | } 221 | 222 | - (IBAction)lockDeviceWasClicked:(id)sender 223 | { 224 | if([[treeController selectedNodes] count] == 0) { 225 | return; 226 | } 227 | 228 | NSTreeNode *node = [treeController selectedNodes][0]; 229 | SSMDevice *device = [[node representedObject] representedObject]; 230 | 231 | SSMAccount *account = [[[node parentNode] representedObject] representedObject]; 232 | [account remoteLockDevice:device.deviceId withPasscode:@"9911"]; 233 | } 234 | 235 | - (IBAction)dismissPanel:(id)sender 236 | { 237 | [NSApp endSheet:panelSendMessage returnCode:NSCancelButton]; 238 | [panelSendMessage orderOut:nil]; 239 | 240 | [NSApp endSheet:panelAddAccount returnCode:NSCancelButton]; 241 | [panelAddAccount orderOut:nil]; 242 | } 243 | 244 | - (IBAction)confirmAddAccount:(id)sender 245 | { 246 | EMGenericKeychainItem *kcItem = [EMGenericKeychainItem genericKeychainItemForService:@"Sosumi" withUsername:[txtUsername stringValue]]; 247 | if(kcItem) { 248 | kcItem.password = [txtPassword stringValue]; 249 | } else { 250 | kcItem = [EMGenericKeychainItem addGenericKeychainItemForService:@"Sosumi" withUsername:[txtUsername stringValue] password:[txtPassword stringValue]]; 251 | } 252 | 253 | NSTreeNode *treeNode; 254 | SSMAccount *tmpAccount = [[SSMAccount alloc] init]; 255 | tmpAccount.username = kcItem.username; 256 | tmpAccount.password = kcItem.password; 257 | treeNode = [NSTreeNode treeNodeWithRepresentedObject:tmpAccount]; 258 | tmpAccount.treeNode = treeNode; 259 | [tmpAccount beginUpdatingDevices]; 260 | 261 | [treeController insertObject:treeNode atArrangedObjectIndexPath:[NSIndexPath indexPathWithIndex:0]]; 262 | 263 | NSMutableArray *accounts = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:@"accounts"]]; 264 | [accounts addObject:[NSDictionary dictionaryWithObjects:@[kcItem.username] forKeys:@[@"username"]]]; 265 | [[NSUserDefaults standardUserDefaults] setObject:accounts forKey:@"accounts"]; 266 | [[NSUserDefaults standardUserDefaults] synchronize]; 267 | 268 | [NSApp endSheet:panelAddAccount returnCode:NSOKButton]; 269 | [panelAddAccount orderOut:nil]; 270 | } 271 | 272 | - (IBAction)confirmSendMessage:(id)sender 273 | { 274 | if([[treeController selectedNodes] count] == 0) { 275 | return; 276 | } 277 | 278 | NSTreeNode *node = [treeController selectedNodes][0]; 279 | SSMDevice *device = [[node representedObject] representedObject]; 280 | SSMAccount *account = [[[node parentNode] representedObject] representedObject]; 281 | [account sendMessage:[txtMessage stringValue] withSubject:[txtSubject stringValue] andAlarm:[chkAlarm state] toDevice:device.deviceId]; 282 | 283 | [NSApp endSheet:panelSendMessage returnCode:NSOKButton]; 284 | [panelSendMessage orderOut:nil]; 285 | } 286 | 287 | - (IBAction)copyCoordsWasClicked:(id)sender 288 | { 289 | if([[treeController selectedNodes] count] == 0) { 290 | return; 291 | } 292 | 293 | NSTreeNode *node = [treeController selectedNodes][0]; 294 | SSMDevice *device = [[node representedObject] representedObject]; 295 | 296 | NSPasteboard *pb = [NSPasteboard generalPasteboard]; 297 | NSArray *types = @[NSStringPboardType]; 298 | [pb declareTypes:types owner:self]; 299 | [pb setString:[device coords] forType:NSStringPboardType]; 300 | } 301 | 302 | - (IBAction)showSyncActivityPanel:(id)sender 303 | { 304 | if([self.panelSyncActivity isVisible]) { 305 | [self.panelSyncActivity close]; 306 | } else { 307 | [self.panelSyncActivity orderFront:nil]; 308 | } 309 | } 310 | 311 | #pragma mark - 312 | #pragma mark Misc 313 | #pragma mark - 314 | 315 | - (void)showSpinner:(NSNotification *)notification 316 | { 317 | [piSpinner startAnimation:self]; 318 | } 319 | 320 | - (void)hideSpinner:(NSNotification *)notification 321 | { 322 | [piSpinner stopAnimation:self]; 323 | } 324 | 325 | @end 326 | --------------------------------------------------------------------------------