diff --git a/.DS_Store b/.DS_Store
deleted file mode 100644
index eba2ac26500b6b4f46cb166942dc112589215d5a..0000000000000000000000000000000000000000
Binary files a/.DS_Store and /dev/null differ
diff --git a/.gitignore b/.gitignore
index e3f5b92725889d9990d684d465d7e48d4e6602b0..6fda9e88f53e238215b76d373ae7d982be4f69e1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,3 +26,12 @@ profiles.clj
 /resources/sample-dataset.db.trace.db
 /deploy/artifacts/*
 /resources/version.properties
+xcuserdata
+xcshareddata
+*.xcworkspacedata
+OSX/Metabase/jre
+OSX/Resources/metabase.jar
+OSX/build
+/osx-artifacts
+OSX/dsa_priv.pem
+bin/config.json
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000000000000000000000000000000000000..d271c26dcc42be6d77d819ebd062bbb63a34ae67
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "OSX/Vendor/INAppStoreWindow"]
+	path = OSX/Vendor/INAppStoreWindow
+	url = git@github.com:indragiek/INAppStoreWindow.git
diff --git a/OSX/Metabase.xcodeproj/project.pbxproj b/OSX/Metabase.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000000000000000000000000000000000..6d8a9f5c4c6b6fb505fe4c1f1dfdb86dd56c21b6
--- /dev/null
+++ b/OSX/Metabase.xcodeproj/project.pbxproj
@@ -0,0 +1,673 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		D105B2241BB378C100A5D850 /* INAppStoreWindowSwizzling.c in Sources */ = {isa = PBXBuildFile; fileRef = D105B1F21BB378C100A5D850 /* INAppStoreWindowSwizzling.c */; };
+		D105B2251BB378C100A5D850 /* INWindowBackgroundView+CoreUIRendering.m in Sources */ = {isa = PBXBuildFile; fileRef = D105B1F51BB378C100A5D850 /* INWindowBackgroundView+CoreUIRendering.m */; };
+		D105B2261BB378C100A5D850 /* NSDocument+INAppStoreWindowFixes.m in Sources */ = {isa = PBXBuildFile; fileRef = D105B1F71BB378C100A5D850 /* NSDocument+INAppStoreWindowFixes.m */; };
+		D105B2271BB378C100A5D850 /* INAppStoreWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = D105B1F91BB378C100A5D850 /* INAppStoreWindow.m */; };
+		D105B2281BB378C100A5D850 /* INWindowButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D105B1FC1BB378C100A5D850 /* INWindowButton.m */; };
+		D105B23C1BB5BE4A00A5D850 /* back_icon@1x.png in Resources */ = {isa = PBXBuildFile; fileRef = D105B2331BB5BE4A00A5D850 /* back_icon@1x.png */; };
+		D105B23D1BB5BE4A00A5D850 /* back_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D105B2341BB5BE4A00A5D850 /* back_icon@2x.png */; };
+		D105B23E1BB5BE4A00A5D850 /* forward_icon@1x.png in Resources */ = {isa = PBXBuildFile; fileRef = D105B2351BB5BE4A00A5D850 /* forward_icon@1x.png */; };
+		D105B23F1BB5BE4A00A5D850 /* forward_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D105B2361BB5BE4A00A5D850 /* forward_icon@2x.png */; };
+		D105B2401BB5BE4A00A5D850 /* link_icon@1x.png in Resources */ = {isa = PBXBuildFile; fileRef = D105B2371BB5BE4A00A5D850 /* link_icon@1x.png */; };
+		D105B2411BB5BE4A00A5D850 /* link_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D105B2381BB5BE4A00A5D850 /* link_icon@2x.png */; };
+		D105B2421BB5BE4A00A5D850 /* Logo_1024.png in Resources */ = {isa = PBXBuildFile; fileRef = D105B2391BB5BE4A00A5D850 /* Logo_1024.png */; };
+		D105B2431BB5BE4A00A5D850 /* refresh_icon@1x.png in Resources */ = {isa = PBXBuildFile; fileRef = D105B23A1BB5BE4A00A5D850 /* refresh_icon@1x.png */; };
+		D105B2441BB5BE4A00A5D850 /* refresh_icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D105B23B1BB5BE4A00A5D850 /* refresh_icon@2x.png */; };
+		D121FD651BC5B2AF002101B0 /* Sparkle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D121FD641BC5B2AF002101B0 /* Sparkle.framework */; };
+		D121FD671BC5B375002101B0 /* Sparkle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = D121FD641BC5B2AF002101B0 /* Sparkle.framework */; };
+		D121FD691BC5B4E7002101B0 /* dsa_pub.pem in Resources */ = {isa = PBXBuildFile; fileRef = D121FD681BC5B4E7002101B0 /* dsa_pub.pem */; };
+		D162C4A81BC87D2B009F678F /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D162C49A1BC87D2B009F678F /* AppDelegate.m */; };
+		D162C4A91BC87D2B009F678F /* MetabaseTask.m in Sources */ = {isa = PBXBuildFile; fileRef = D162C49C1BC87D2B009F678F /* MetabaseTask.m */; };
+		D162C4AA1BC87D2B009F678F /* SettingsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = D162C49E1BC87D2B009F678F /* SettingsManager.m */; };
+		D162C4AB1BC87D2B009F678F /* TaskHealthChecker.m in Sources */ = {isa = PBXBuildFile; fileRef = D162C4A01BC87D2B009F678F /* TaskHealthChecker.m */; };
+		D162C4AE1BC87D2B009F678F /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = D162C4A51BC87D2B009F678F /* MainMenu.xib */; };
+		D162C4AF1BC87D2B009F678F /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D162C4A71BC87D2B009F678F /* MainViewController.m */; };
+		D18853BF1BB0CEC600D89803 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D18853BE1BB0CEC600D89803 /* Cocoa.framework */; };
+		D18853C91BB0CEC600D89803 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D18853C71BB0CEC600D89803 /* InfoPlist.strings */; };
+		D18853CB1BB0CEC600D89803 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D18853CA1BB0CEC600D89803 /* main.m */; };
+		D18853CF1BB0CEC600D89803 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = D18853CD1BB0CEC600D89803 /* Credits.rtf */; };
+		D18853D71BB0CEC600D89803 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D18853D61BB0CEC600D89803 /* Images.xcassets */; };
+		D18853DE1BB0CEC600D89803 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D18853DD1BB0CEC600D89803 /* XCTest.framework */; };
+		D18853DF1BB0CEC600D89803 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D18853BE1BB0CEC600D89803 /* Cocoa.framework */; };
+		D18853F91BB0D37C00D89803 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D18853F81BB0D37B00D89803 /* WebKit.framework */; };
+		D18854041BB0DC2600D89803 /* metabase.jar in Resources */ = {isa = PBXBuildFile; fileRef = D18854021BB0DB6000D89803 /* metabase.jar */; };
+		D18855611BB1C8D700D89803 /* jre in Resources */ = {isa = PBXBuildFile; fileRef = D188555E1BB1C86F00D89803 /* jre */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+		D18853E01BB0CEC600D89803 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = D18853B31BB0CEC600D89803 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = D18853BA1BB0CEC600D89803;
+			remoteInfo = Metabase;
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+		D121FD661BC5B364002101B0 /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 12;
+			dstPath = "";
+			dstSubfolderSpec = 10;
+			files = (
+				D121FD671BC5B375002101B0 /* Sparkle.framework in CopyFiles */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+		D105B1F21BB378C100A5D850 /* INAppStoreWindowSwizzling.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = INAppStoreWindowSwizzling.c; sourceTree = "<group>"; };
+		D105B1F31BB378C100A5D850 /* INAppStoreWindowSwizzling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = INAppStoreWindowSwizzling.h; sourceTree = "<group>"; };
+		D105B1F41BB378C100A5D850 /* INWindowBackgroundView+CoreUIRendering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "INWindowBackgroundView+CoreUIRendering.h"; sourceTree = "<group>"; };
+		D105B1F51BB378C100A5D850 /* INWindowBackgroundView+CoreUIRendering.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "INWindowBackgroundView+CoreUIRendering.m"; sourceTree = "<group>"; };
+		D105B1F61BB378C100A5D850 /* NSDocument+INAppStoreWindowFixes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDocument+INAppStoreWindowFixes.h"; sourceTree = "<group>"; };
+		D105B1F71BB378C100A5D850 /* NSDocument+INAppStoreWindowFixes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDocument+INAppStoreWindowFixes.m"; sourceTree = "<group>"; };
+		D105B1F81BB378C100A5D850 /* INAppStoreWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = INAppStoreWindow.h; sourceTree = "<group>"; };
+		D105B1F91BB378C100A5D850 /* INAppStoreWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = INAppStoreWindow.m; sourceTree = "<group>"; };
+		D105B1FA1BB378C100A5D850 /* INAppStoreWindowCompatibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = INAppStoreWindowCompatibility.h; sourceTree = "<group>"; };
+		D105B1FB1BB378C100A5D850 /* INWindowButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = INWindowButton.h; sourceTree = "<group>"; };
+		D105B1FC1BB378C100A5D850 /* INWindowButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = INWindowButton.m; sourceTree = "<group>"; };
+		D105B2331BB5BE4A00A5D850 /* back_icon@1x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back_icon@1x.png"; sourceTree = "<group>"; };
+		D105B2341BB5BE4A00A5D850 /* back_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "back_icon@2x.png"; sourceTree = "<group>"; };
+		D105B2351BB5BE4A00A5D850 /* forward_icon@1x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "forward_icon@1x.png"; sourceTree = "<group>"; };
+		D105B2361BB5BE4A00A5D850 /* forward_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "forward_icon@2x.png"; sourceTree = "<group>"; };
+		D105B2371BB5BE4A00A5D850 /* link_icon@1x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "link_icon@1x.png"; sourceTree = "<group>"; };
+		D105B2381BB5BE4A00A5D850 /* link_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "link_icon@2x.png"; sourceTree = "<group>"; };
+		D105B2391BB5BE4A00A5D850 /* Logo_1024.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Logo_1024.png; sourceTree = "<group>"; };
+		D105B23A1BB5BE4A00A5D850 /* refresh_icon@1x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "refresh_icon@1x.png"; sourceTree = "<group>"; };
+		D105B23B1BB5BE4A00A5D850 /* refresh_icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "refresh_icon@2x.png"; sourceTree = "<group>"; };
+		D121FD641BC5B2AF002101B0 /* Sparkle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Sparkle.framework; sourceTree = "<group>"; };
+		D121FD681BC5B4E7002101B0 /* dsa_pub.pem */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = dsa_pub.pem; sourceTree = "<group>"; };
+		D162C4991BC87D2B009F678F /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
+		D162C49A1BC87D2B009F678F /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
+		D162C49B1BC87D2B009F678F /* MetabaseTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MetabaseTask.h; sourceTree = "<group>"; };
+		D162C49C1BC87D2B009F678F /* MetabaseTask.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MetabaseTask.m; sourceTree = "<group>"; };
+		D162C49D1BC87D2B009F678F /* SettingsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsManager.h; sourceTree = "<group>"; };
+		D162C49E1BC87D2B009F678F /* SettingsManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsManager.m; sourceTree = "<group>"; };
+		D162C49F1BC87D2B009F678F /* TaskHealthChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TaskHealthChecker.h; sourceTree = "<group>"; };
+		D162C4A01BC87D2B009F678F /* TaskHealthChecker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TaskHealthChecker.m; sourceTree = "<group>"; };
+		D162C4A51BC87D2B009F678F /* MainMenu.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = "<group>"; };
+		D162C4A61BC87D2B009F678F /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = "<group>"; };
+		D162C4A71BC87D2B009F678F /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = "<group>"; };
+		D18853BB1BB0CEC600D89803 /* Metabase.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Metabase.app; sourceTree = BUILT_PRODUCTS_DIR; };
+		D18853BE1BB0CEC600D89803 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
+		D18853C11BB0CEC600D89803 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
+		D18853C21BB0CEC600D89803 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; };
+		D18853C31BB0CEC600D89803 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
+		D18853C61BB0CEC600D89803 /* Metabase-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Metabase-Info.plist"; sourceTree = "<group>"; };
+		D18853C81BB0CEC600D89803 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
+		D18853CA1BB0CEC600D89803 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+		D18853CC1BB0CEC600D89803 /* Metabase-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Metabase-Prefix.pch"; sourceTree = "<group>"; };
+		D18853CE1BB0CEC600D89803 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
+		D18853D61BB0CEC600D89803 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = ../Metabase/Images.xcassets; sourceTree = "<group>"; };
+		D18853DC1BB0CEC600D89803 /* MetabaseTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MetabaseTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+		D18853DD1BB0CEC600D89803 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
+		D18853F81BB0D37B00D89803 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
+		D18854021BB0DB6000D89803 /* metabase.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; path = metabase.jar; sourceTree = "<group>"; };
+		D188555E1BB1C86F00D89803 /* jre */ = {isa = PBXFileReference; lastKnownFileType = folder; name = jre; path = Metabase/jre; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		D18853B81BB0CEC600D89803 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				D18853F91BB0D37C00D89803 /* WebKit.framework in Frameworks */,
+				D121FD651BC5B2AF002101B0 /* Sparkle.framework in Frameworks */,
+				D18853BF1BB0CEC600D89803 /* Cocoa.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		D18853D91BB0CEC600D89803 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				D18853DF1BB0CEC600D89803 /* Cocoa.framework in Frameworks */,
+				D18853DE1BB0CEC600D89803 /* XCTest.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		D105B1BD1BB378C100A5D850 /* Vendor */ = {
+			isa = PBXGroup;
+			children = (
+				D121FD631BC5B2AF002101B0 /* Sparkle-1.11.0 */,
+				D105B1BE1BB378C100A5D850 /* INAppStoreWindow */,
+			);
+			path = Vendor;
+			sourceTree = "<group>";
+		};
+		D105B1BE1BB378C100A5D850 /* INAppStoreWindow */ = {
+			isa = PBXGroup;
+			children = (
+				D105B1F01BB378C100A5D850 /* INAppStoreWindow */,
+			);
+			path = INAppStoreWindow;
+			sourceTree = "<group>";
+		};
+		D105B1F01BB378C100A5D850 /* INAppStoreWindow */ = {
+			isa = PBXGroup;
+			children = (
+				D105B1F11BB378C100A5D850 /* Extensions */,
+				D105B1F81BB378C100A5D850 /* INAppStoreWindow.h */,
+				D105B1F91BB378C100A5D850 /* INAppStoreWindow.m */,
+				D105B1FA1BB378C100A5D850 /* INAppStoreWindowCompatibility.h */,
+				D105B1FB1BB378C100A5D850 /* INWindowButton.h */,
+				D105B1FC1BB378C100A5D850 /* INWindowButton.m */,
+			);
+			path = INAppStoreWindow;
+			sourceTree = "<group>";
+		};
+		D105B1F11BB378C100A5D850 /* Extensions */ = {
+			isa = PBXGroup;
+			children = (
+				D105B1F21BB378C100A5D850 /* INAppStoreWindowSwizzling.c */,
+				D105B1F31BB378C100A5D850 /* INAppStoreWindowSwizzling.h */,
+				D105B1F41BB378C100A5D850 /* INWindowBackgroundView+CoreUIRendering.h */,
+				D105B1F51BB378C100A5D850 /* INWindowBackgroundView+CoreUIRendering.m */,
+				D105B1F61BB378C100A5D850 /* NSDocument+INAppStoreWindowFixes.h */,
+				D105B1F71BB378C100A5D850 /* NSDocument+INAppStoreWindowFixes.m */,
+			);
+			path = Extensions;
+			sourceTree = "<group>";
+		};
+		D105B2321BB5BE4A00A5D850 /* Images */ = {
+			isa = PBXGroup;
+			children = (
+				D105B2331BB5BE4A00A5D850 /* back_icon@1x.png */,
+				D105B2341BB5BE4A00A5D850 /* back_icon@2x.png */,
+				D105B2351BB5BE4A00A5D850 /* forward_icon@1x.png */,
+				D105B2361BB5BE4A00A5D850 /* forward_icon@2x.png */,
+				D105B2371BB5BE4A00A5D850 /* link_icon@1x.png */,
+				D105B2381BB5BE4A00A5D850 /* link_icon@2x.png */,
+				D105B2391BB5BE4A00A5D850 /* Logo_1024.png */,
+				D105B23A1BB5BE4A00A5D850 /* refresh_icon@1x.png */,
+				D105B23B1BB5BE4A00A5D850 /* refresh_icon@2x.png */,
+			);
+			path = Images;
+			sourceTree = "<group>";
+		};
+		D121FD631BC5B2AF002101B0 /* Sparkle-1.11.0 */ = {
+			isa = PBXGroup;
+			children = (
+				D121FD641BC5B2AF002101B0 /* Sparkle.framework */,
+			);
+			path = "Sparkle-1.11.0";
+			sourceTree = "<group>";
+		};
+		D162C4981BC87D2B009F678F /* Backend */ = {
+			isa = PBXGroup;
+			children = (
+				D162C4991BC87D2B009F678F /* AppDelegate.h */,
+				D162C49A1BC87D2B009F678F /* AppDelegate.m */,
+				D162C49B1BC87D2B009F678F /* MetabaseTask.h */,
+				D162C49C1BC87D2B009F678F /* MetabaseTask.m */,
+				D162C49D1BC87D2B009F678F /* SettingsManager.h */,
+				D162C49E1BC87D2B009F678F /* SettingsManager.m */,
+				D162C49F1BC87D2B009F678F /* TaskHealthChecker.h */,
+				D162C4A01BC87D2B009F678F /* TaskHealthChecker.m */,
+			);
+			path = Backend;
+			sourceTree = "<group>";
+		};
+		D162C4A11BC87D2B009F678F /* UI */ = {
+			isa = PBXGroup;
+			children = (
+				D162C4A51BC87D2B009F678F /* MainMenu.xib */,
+				D162C4A61BC87D2B009F678F /* MainViewController.h */,
+				D162C4A71BC87D2B009F678F /* MainViewController.m */,
+			);
+			path = UI;
+			sourceTree = "<group>";
+		};
+		D18853B21BB0CEC600D89803 = {
+			isa = PBXGroup;
+			children = (
+				D188555E1BB1C86F00D89803 /* jre */,
+				D18853C41BB0CEC600D89803 /* Metabase */,
+				D18854011BB0DB6000D89803 /* Resources */,
+				D105B1BD1BB378C100A5D850 /* Vendor */,
+				D18853BD1BB0CEC600D89803 /* Frameworks */,
+				D18853BC1BB0CEC600D89803 /* Products */,
+			);
+			sourceTree = "<group>";
+		};
+		D18853BC1BB0CEC600D89803 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				D18853BB1BB0CEC600D89803 /* Metabase.app */,
+				D18853DC1BB0CEC600D89803 /* MetabaseTests.xctest */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		D18853BD1BB0CEC600D89803 /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				D18853F81BB0D37B00D89803 /* WebKit.framework */,
+				D18853BE1BB0CEC600D89803 /* Cocoa.framework */,
+				D18853DD1BB0CEC600D89803 /* XCTest.framework */,
+				D18853C01BB0CEC600D89803 /* Other Frameworks */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		D18853C01BB0CEC600D89803 /* Other Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				D18853C11BB0CEC600D89803 /* AppKit.framework */,
+				D18853C21BB0CEC600D89803 /* CoreData.framework */,
+				D18853C31BB0CEC600D89803 /* Foundation.framework */,
+			);
+			name = "Other Frameworks";
+			sourceTree = "<group>";
+		};
+		D18853C41BB0CEC600D89803 /* Metabase */ = {
+			isa = PBXGroup;
+			children = (
+				D162C4981BC87D2B009F678F /* Backend */,
+				D162C4A11BC87D2B009F678F /* UI */,
+				D18853C51BB0CEC600D89803 /* Supporting Files */,
+			);
+			path = Metabase;
+			sourceTree = "<group>";
+		};
+		D18853C51BB0CEC600D89803 /* Supporting Files */ = {
+			isa = PBXGroup;
+			children = (
+				D18853C61BB0CEC600D89803 /* Metabase-Info.plist */,
+				D18853C71BB0CEC600D89803 /* InfoPlist.strings */,
+				D18853CA1BB0CEC600D89803 /* main.m */,
+				D18853CC1BB0CEC600D89803 /* Metabase-Prefix.pch */,
+				D18853CD1BB0CEC600D89803 /* Credits.rtf */,
+			);
+			name = "Supporting Files";
+			sourceTree = "<group>";
+		};
+		D18854011BB0DB6000D89803 /* Resources */ = {
+			isa = PBXGroup;
+			children = (
+				D18853D61BB0CEC600D89803 /* Images.xcassets */,
+				D105B2321BB5BE4A00A5D850 /* Images */,
+				D18854021BB0DB6000D89803 /* metabase.jar */,
+				D121FD681BC5B4E7002101B0 /* dsa_pub.pem */,
+			);
+			path = Resources;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		D18853BA1BB0CEC600D89803 /* Metabase */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = D18853EC1BB0CEC600D89803 /* Build configuration list for PBXNativeTarget "Metabase" */;
+			buildPhases = (
+				D18853B71BB0CEC600D89803 /* Sources */,
+				D18853B81BB0CEC600D89803 /* Frameworks */,
+				D18853B91BB0CEC600D89803 /* Resources */,
+				D18854051BB1B90000D89803 /* Kill Existing Processes Listening on Ports 13000 - 14000 */,
+				D121FD661BC5B364002101B0 /* CopyFiles */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = Metabase;
+			productName = Metabase;
+			productReference = D18853BB1BB0CEC600D89803 /* Metabase.app */;
+			productType = "com.apple.product-type.application";
+		};
+		D18853DB1BB0CEC600D89803 /* MetabaseTests */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = D18853EF1BB0CEC600D89803 /* Build configuration list for PBXNativeTarget "MetabaseTests" */;
+			buildPhases = (
+				D18853D81BB0CEC600D89803 /* Sources */,
+				D18853D91BB0CEC600D89803 /* Frameworks */,
+				D18853DA1BB0CEC600D89803 /* Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				D18853E11BB0CEC600D89803 /* PBXTargetDependency */,
+			);
+			name = MetabaseTests;
+			productName = MetabaseTests;
+			productReference = D18853DC1BB0CEC600D89803 /* MetabaseTests.xctest */;
+			productType = "com.apple.product-type.bundle.unit-test";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		D18853B31BB0CEC600D89803 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 0510;
+				ORGANIZATIONNAME = Metabase;
+				TargetAttributes = {
+					D18853BA1BB0CEC600D89803 = {
+						DevelopmentTeam = BR27ZJK7WW;
+					};
+					D18853DB1BB0CEC600D89803 = {
+						TestTargetID = D18853BA1BB0CEC600D89803;
+					};
+				};
+			};
+			buildConfigurationList = D18853B61BB0CEC600D89803 /* Build configuration list for PBXProject "Metabase" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = English;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+				Base,
+			);
+			mainGroup = D18853B21BB0CEC600D89803;
+			productRefGroup = D18853BC1BB0CEC600D89803 /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				D18853BA1BB0CEC600D89803 /* Metabase */,
+				D18853DB1BB0CEC600D89803 /* MetabaseTests */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		D18853B91BB0CEC600D89803 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				D105B23D1BB5BE4A00A5D850 /* back_icon@2x.png in Resources */,
+				D121FD691BC5B4E7002101B0 /* dsa_pub.pem in Resources */,
+				D18855611BB1C8D700D89803 /* jre in Resources */,
+				D162C4AE1BC87D2B009F678F /* MainMenu.xib in Resources */,
+				D105B2401BB5BE4A00A5D850 /* link_icon@1x.png in Resources */,
+				D18854041BB0DC2600D89803 /* metabase.jar in Resources */,
+				D18853C91BB0CEC600D89803 /* InfoPlist.strings in Resources */,
+				D105B2431BB5BE4A00A5D850 /* refresh_icon@1x.png in Resources */,
+				D105B23F1BB5BE4A00A5D850 /* forward_icon@2x.png in Resources */,
+				D18853D71BB0CEC600D89803 /* Images.xcassets in Resources */,
+				D105B23E1BB5BE4A00A5D850 /* forward_icon@1x.png in Resources */,
+				D105B23C1BB5BE4A00A5D850 /* back_icon@1x.png in Resources */,
+				D18853CF1BB0CEC600D89803 /* Credits.rtf in Resources */,
+				D105B2421BB5BE4A00A5D850 /* Logo_1024.png in Resources */,
+				D105B2411BB5BE4A00A5D850 /* link_icon@2x.png in Resources */,
+				D105B2441BB5BE4A00A5D850 /* refresh_icon@2x.png in Resources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		D18853DA1BB0CEC600D89803 /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+		D18854051BB1B90000D89803 /* Kill Existing Processes Listening on Ports 13000 - 14000 */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "Kill Existing Processes Listening on Ports 13000 - 14000";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /usr/bin/perl;
+			shellScript = "foreach(split(/\\n/, `lsof -i :13000-14000`)) {\n    s/^[^\\d]+(\\d+).*$/$1/;\n    m/^\\d+$/ && system('kill', $_);\n}";
+		};
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		D18853B71BB0CEC600D89803 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				D162C4AB1BC87D2B009F678F /* TaskHealthChecker.m in Sources */,
+				D105B2261BB378C100A5D850 /* NSDocument+INAppStoreWindowFixes.m in Sources */,
+				D162C4AA1BC87D2B009F678F /* SettingsManager.m in Sources */,
+				D105B2251BB378C100A5D850 /* INWindowBackgroundView+CoreUIRendering.m in Sources */,
+				D105B2241BB378C100A5D850 /* INAppStoreWindowSwizzling.c in Sources */,
+				D18853CB1BB0CEC600D89803 /* main.m in Sources */,
+				D162C4AF1BC87D2B009F678F /* MainViewController.m in Sources */,
+				D105B2281BB378C100A5D850 /* INWindowButton.m in Sources */,
+				D105B2271BB378C100A5D850 /* INAppStoreWindow.m in Sources */,
+				D162C4A91BC87D2B009F678F /* MetabaseTask.m in Sources */,
+				D162C4A81BC87D2B009F678F /* AppDelegate.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		D18853D81BB0CEC600D89803 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+		D18853E11BB0CEC600D89803 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = D18853BA1BB0CEC600D89803 /* Metabase */;
+			targetProxy = D18853E01BB0CEC600D89803 /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+		D18853C71BB0CEC600D89803 /* InfoPlist.strings */ = {
+			isa = PBXVariantGroup;
+			children = (
+				D18853C81BB0CEC600D89803 /* en */,
+			);
+			name = InfoPlist.strings;
+			sourceTree = "<group>";
+		};
+		D18853CD1BB0CEC600D89803 /* Credits.rtf */ = {
+			isa = PBXVariantGroup;
+			children = (
+				D18853CE1BB0CEC600D89803 /* en */,
+			);
+			name = Credits.rtf;
+			sourceTree = "<group>";
+		};
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+		D18853EA1BB0CEC600D89803 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
+				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = macosx;
+			};
+			name = Debug;
+		};
+		D18853EB1BB0CEC600D89803 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = YES;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_ENABLE_OBJC_EXCEPTIONS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
+				MACOSX_DEPLOYMENT_TARGET = 10.9;
+				SDKROOT = macosx;
+			};
+			name = Release;
+		};
+		D18853ED1BB0CEC600D89803 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				COMBINE_HIDPI_IMAGES = YES;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)/Vendor/Sparkle-1.11.0",
+				);
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "Metabase/Metabase-Prefix.pch";
+				INFOPLIST_FILE = "Metabase/Metabase-Info.plist";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				WRAPPER_EXTENSION = app;
+			};
+			name = Debug;
+		};
+		D18853EE1BB0CEC600D89803 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+				COMBINE_HIDPI_IMAGES = YES;
+				DEAD_CODE_STRIPPING = YES;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(inherited)",
+					"$(PROJECT_DIR)/Vendor/Sparkle-1.11.0",
+				);
+				GCC_OPTIMIZATION_LEVEL = fast;
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "Metabase/Metabase-Prefix.pch";
+				INFOPLIST_FILE = "Metabase/Metabase-Info.plist";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				WRAPPER_EXTENSION = app;
+			};
+			name = Release;
+		};
+		D18853F01BB0CEC600D89803 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Metabase.app/Contents/MacOS/Metabase";
+				COMBINE_HIDPI_IMAGES = YES;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(DEVELOPER_FRAMEWORKS_DIR)",
+					"$(inherited)",
+				);
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "Metabase/Metabase-Prefix.pch";
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = "MetabaseTests/MetabaseTests-Info.plist";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				TEST_HOST = "$(BUNDLE_LOADER)";
+				WRAPPER_EXTENSION = xctest;
+			};
+			name = Debug;
+		};
+		D18853F11BB0CEC600D89803 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Metabase.app/Contents/MacOS/Metabase";
+				COMBINE_HIDPI_IMAGES = YES;
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(DEVELOPER_FRAMEWORKS_DIR)",
+					"$(inherited)",
+				);
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "Metabase/Metabase-Prefix.pch";
+				INFOPLIST_FILE = "MetabaseTests/MetabaseTests-Info.plist";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				TEST_HOST = "$(BUNDLE_LOADER)";
+				WRAPPER_EXTENSION = xctest;
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		D18853B61BB0CEC600D89803 /* Build configuration list for PBXProject "Metabase" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				D18853EA1BB0CEC600D89803 /* Debug */,
+				D18853EB1BB0CEC600D89803 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		D18853EC1BB0CEC600D89803 /* Build configuration list for PBXNativeTarget "Metabase" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				D18853ED1BB0CEC600D89803 /* Debug */,
+				D18853EE1BB0CEC600D89803 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		D18853EF1BB0CEC600D89803 /* Build configuration list for PBXNativeTarget "MetabaseTests" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				D18853F01BB0CEC600D89803 /* Debug */,
+				D18853F11BB0CEC600D89803 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = D18853B31BB0CEC600D89803 /* Project object */;
+}
diff --git a/OSX/Metabase/Backend/AppDelegate.h b/OSX/Metabase/Backend/AppDelegate.h
new file mode 100644
index 0000000000000000000000000000000000000000..6a5a0a3df9451f469dc8994ce25792d8353552bb
--- /dev/null
+++ b/OSX/Metabase/Backend/AppDelegate.h
@@ -0,0 +1,17 @@
+//
+//  AppDelegate.h
+//  Metabase
+//
+//  Created by Cam Saul on 9/21/15.
+//  Copyright (c) 2015 Metabase. All rights reserved.
+//
+
+@import Cocoa;
+
+@interface AppDelegate : NSObject <NSApplicationDelegate>
+
++ (AppDelegate *)instance;
+
+@property (readonly) NSUInteger port;
+
+@end
diff --git a/OSX/Metabase/Backend/AppDelegate.m b/OSX/Metabase/Backend/AppDelegate.m
new file mode 100644
index 0000000000000000000000000000000000000000..44966ed4840954ccd5b018dae52fede398dc6d0c
--- /dev/null
+++ b/OSX/Metabase/Backend/AppDelegate.m
@@ -0,0 +1,102 @@
+//
+//  AppDelegate.m
+//  Metabase
+//
+//  Created by Cam Saul on 9/21/15.
+//  Copyright (c) 2015 Metabase. All rights reserved.
+//
+
+#import <Sparkle/Sparkle.h>
+
+#import "AppDelegate.h"
+#import "MainViewController.h"
+#import "MetabaseTask.h"
+#import "TaskHealthChecker.h"
+
+
+@interface AppDelegate ()
+
+@property (weak) IBOutlet NSWindow *window;
+
+@property (strong, nonatomic) MetabaseTask *task;
+@property (strong, nonatomic) TaskHealthChecker *healthChecker;
+
+@end
+
+
+static AppDelegate *sInstance = nil;
+
+
+@implementation AppDelegate
+
++ (AppDelegate *)instance {
+	return sInstance;
+}
+
+- (id)init {
+	if (self = [super init]) {
+		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskTimedOut:) name:MetabaseTaskTimedOutNotification object:nil];
+	}
+	return self;
+}
+
+- (void)dealloc {
+	[[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+	sInstance = self;
+	
+	[[SUUpdater sharedUpdater] checkForUpdatesInBackground];
+	
+	self.task = [MetabaseTask task];
+	self.healthChecker.port = self.task.port;
+	[self.healthChecker start];
+}
+
+- (void)applicationDidBecomeActive:(NSNotification *)notification {
+	// re-start the health checker if it's not checking like it should be : the HEALTH CHECKER HEALTH CHECKER
+	if (self.healthChecker.lastCheckTime) {
+		const CFTimeInterval timeSinceLastHealthCheck = CFAbsoluteTimeGetCurrent() - self.healthChecker.lastCheckTime;
+		if (timeSinceLastHealthCheck > 5.0f) {
+			NSLog(@"Last health check was %.0f ago, restarting health checker!", timeSinceLastHealthCheck);
+			[self.healthChecker start];
+		}
+	}
+	// (re)start the health checker just to be extra double-safe it's still running
+}
+
+- (void)applicationWillTerminate:(NSNotification *)notification {
+	self.task = nil;
+}
+
+
+#pragma mark - Notifications
+
+- (void)taskTimedOut:(NSNotification *)notification {
+	NSLog(@"Metabase task timed out. Restarting...");
+	[self.healthChecker resetTimeout];
+	self.task = [MetabaseTask task];
+}
+
+
+#pragma mark - Getters / Setters
+
+- (TaskHealthChecker *)healthChecker {
+	if (!_healthChecker) {
+		_healthChecker = [[TaskHealthChecker alloc] init];
+	}
+	return _healthChecker;
+}
+
+- (void)setTask:(MetabaseTask *)task {
+	[_task terminate];
+	_task = task;
+	[task launch];
+}
+
+- (NSUInteger)port {
+	return self.task.port;
+}
+
+@end
diff --git a/OSX/Metabase/Backend/MetabaseTask.h b/OSX/Metabase/Backend/MetabaseTask.h
new file mode 100644
index 0000000000000000000000000000000000000000..fd15ae30fe732858b6b6e66def8f09dfe286a56a
--- /dev/null
+++ b/OSX/Metabase/Backend/MetabaseTask.h
@@ -0,0 +1,19 @@
+//
+//  MetabaseTask.h
+//  Metabase
+//
+//  Created by Cam Saul on 10/9/15.
+//  Copyright (c) 2015 Metabase. All rights reserved.
+//
+
+@interface MetabaseTask : NSObject
+
+/// Create (and launch) a task to run the Metabase backend server.
++ (MetabaseTask *)task;
+
+- (void)launch;
+- (void)terminate;
+
+- (NSUInteger)port;
+
+@end
diff --git a/OSX/Metabase/Backend/MetabaseTask.m b/OSX/Metabase/Backend/MetabaseTask.m
new file mode 100644
index 0000000000000000000000000000000000000000..7d79c0fff83e60be2e1557d5a8397d7bc33265ee
--- /dev/null
+++ b/OSX/Metabase/Backend/MetabaseTask.m
@@ -0,0 +1,229 @@
+//
+//  MetabaseTask.m
+//  Metabase
+//
+//  Created by Cam Saul on 10/9/15.
+//  Copyright (c) 2015 Metabase. All rights reserved.
+//
+
+#import "MetabaseTask.h"
+
+#define ENABLE_JAR_UNPACKING 0
+
+@interface MetabaseTask ()
+@property (strong, nonatomic) NSTask *task;
+@property (strong, nonatomic) NSPipe *pipe;
+@property (strong, nonatomic) NSFileHandle *readHandle;
+
+@property (strong, readonly) NSString *javaPath;
+@property (strong, readonly) NSString *jarPath;
+@property (strong, readonly) NSString *dbPath;
+
+#if ENABLE_JAR_UNPACKING
+	@property (strong, readonly) NSString *unpack200Path;
+#endif
+
+@property (nonatomic) NSUInteger port;
+@end
+
+@implementation MetabaseTask
+
++ (MetabaseTask *)task {
+	return [[MetabaseTask alloc] init];
+}
+
+
+#pragma mark - Lifecycle
+
+- (instancetype)init {
+	if (self = [super init]) {
+		[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(fileHandleCompletedRead:) name:NSFileHandleReadCompletionNotification object:nil];
+	}
+	return self;
+}
+
+- (void)dealloc {
+	[[NSNotificationCenter defaultCenter] removeObserver:self];
+	[self terminate];
+}
+
+
+#pragma mark - Notifications
+
+- (void)fileHandleCompletedRead:(NSNotification *)notification {
+	if (!self.readHandle) return;
+	
+	__weak MetabaseTask *weakSelf = self;
+	dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
+		if (!weakSelf) return;
+		@try {
+			NSString *message = [[NSString alloc] initWithData:weakSelf.readHandle.availableData encoding:NSUTF8StringEncoding];
+			// skip calls to health endpoint
+			if ([message rangeOfString:@"GET /api/health"].location == NSNotFound) {
+				// strip off the timestamp that comes back from the backend so we don't get double-timestamps when NSLog adds its own
+				NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^[\\d-:,\\s]+(.*$)" options:NSRegularExpressionAnchorsMatchLines|NSRegularExpressionAllowCommentsAndWhitespace error:nil];
+				message = [regex stringByReplacingMatchesInString:message options:0 range:NSMakeRange(0, message.length) withTemplate:@"$1"];
+				
+				// remove control codes used to color output
+				regex = [NSRegularExpression regularExpressionWithPattern:@"\\[\\d+m" options:0 error:nil];
+				message = [regex stringByReplacingMatchesInString:message options:0 range:NSMakeRange(0, message.length) withTemplate:@""];
+				
+				NSLog(@"%@", message);
+			}
+		} @catch (NSException *) {}
+		
+		dispatch_async(dispatch_get_main_queue(), ^{
+			[weakSelf.readHandle readInBackgroundAndNotify];
+		});
+	});
+}
+
+
+#pragma mark - Local Methods
+
+#if ENABLE_JAR_UNPACKING
+/// unpack the jars in the BG if needed the first time around
+- (void)unpackJars {
+	[self.packedJarPaths enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSString *packedFilename, NSUInteger idx, BOOL *stop) {
+		NSString *jarName = [packedFilename stringByReplacingOccurrencesOfString:@".pack.gz" withString:@".jar"];
+		
+		if (![[NSFileManager defaultManager] fileExistsAtPath:jarName]) {
+			NSLog(@"Unpacking %@ ->\n\t%@...", packedFilename, jarName);
+			NSTask *task = [[NSTask alloc] init];
+			task.launchPath = self.unpack200Path;
+			task.arguments = @[packedFilename, jarName];
+			[task launch];
+			[task waitUntilExit];
+		}
+	}];
+}
+#endif
+
+- (void)deleteOldDBLockFilesIfNeeded {
+	NSString *lockFile	= [self.dbPath stringByAppendingString:@".lock.db"];
+	NSString *traceFile = [self.dbPath stringByAppendingString:@".trace.db"];
+	
+	for (NSString *file in @[lockFile, traceFile]) {
+		if ([[NSFileManager defaultManager] fileExistsAtPath:file]) {
+			NSLog(@"Deleting %@...", file);
+			
+			NSError *error = nil;
+			[[NSFileManager defaultManager] removeItemAtPath:file error:&error];
+			
+			if (error) {
+				NSLog(@"Error deleting %@: %@", file, error.localizedDescription);
+			}
+		}
+	}
+}
+
+- (void)launch {
+	dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
+		
+		#if ENABLE_JAR_UNPACKING
+			[self unpackJars];
+		#endif
+		
+		[self deleteOldDBLockFilesIfNeeded];
+				
+		NSLog(@"Starting MetabaseTask @ 0x%zx...", (size_t)self);
+		
+		self.task					= [[NSTask alloc] init];
+		self.task.launchPath		= self.javaPath;
+		self.task.environment		= @{@"MB_DB_FILE": self.dbPath,
+										@"MB_JETTY_PORT": @(self.port)};
+		self.task.arguments			= @[@"-jar", self.jarPath];
+		
+		self.pipe					= [NSPipe pipe];
+		self.task.standardOutput	= self.pipe;
+		self.task.standardError		= self.pipe;
+		
+		__weak MetabaseTask *weakSelf = self;
+		self.task.terminationHandler = ^(NSTask *task){
+			NSLog(@"\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Task terminated with exit code %d !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", task.terminationStatus);
+			dispatch_async(dispatch_get_main_queue(), ^{
+				if ([[NSAlert alertWithMessageText:@"Fatal Error" defaultButton:@"Restart" alternateButton:@"Quit" otherButton:nil informativeTextWithFormat:@"The Metabase server terminated unexpectedly."] runModal] == NSAlertDefaultReturn) {
+					[weakSelf launch];
+				} else {
+					exit(task.terminationStatus);
+				}
+			});
+		};
+				
+		self.readHandle = self.pipe.fileHandleForReading;
+		dispatch_async(dispatch_get_main_queue(), ^{
+			[self.readHandle readInBackgroundAndNotify];
+		});
+						
+		NSLog(@"%@ -jar %@", self.javaPath, self.jarPath);
+		[self.task launch];
+	});
+}
+
+- (void)terminate {
+	if (!self.task) return; // already dead
+
+	NSLog(@"Killing MetabaseTask @ 0x%zx...", (size_t)self);
+	self.task = nil;
+	_port = 0;
+}
+
+
+#pragma mark - Getters / Setters
+
+- (void)setTask:(NSTask *)task {
+	self.pipe = nil;
+	[_task terminate];
+	_task = task;
+}
+
+- (void)setPipe:(NSPipe *)pipe {
+	self.readHandle = nil;
+	_pipe = pipe;
+}
+
+- (void)setReadHandle:(NSFileHandle *)readHandle {
+	[_readHandle closeFile];
+	_readHandle = readHandle;
+}
+
+- (NSString *)javaPath {
+	return [[NSBundle mainBundle] pathForResource:@"java" ofType:nil inDirectory:@"jre/bin"];
+}
+
+- (NSString *)jarPath {
+	return [[NSBundle mainBundle] pathForResource:@"metabase" ofType:@"jar"];
+}
+
+- (NSString *)dbPath {
+	NSString *applicationSupportDir = [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES)[0] stringByAppendingPathComponent:@"Metabase"];
+	if (![[NSFileManager defaultManager] fileExistsAtPath:applicationSupportDir]) {
+		NSError *error = nil;
+		[[NSFileManager defaultManager] createDirectoryAtPath:applicationSupportDir withIntermediateDirectories:YES attributes:nil error:&error];
+		if (error) {
+			NSLog(@"Error creating %@: %@", applicationSupportDir, error.localizedDescription);
+		}
+	}
+	return [applicationSupportDir stringByAppendingPathComponent:@"metabase.db"];
+}
+
+- (NSUInteger)port {
+	if (!_port) {
+		srand((unsigned)time(NULL));
+		_port = (rand() % 1000) + 13000;
+		NSLog(@"Using port %lu", _port);
+	}
+	return _port;
+}
+
+#if ENABLE_JAR_UNPACKING
+- (NSArray *)packedJarPaths {
+	return [[NSBundle mainBundle] pathsForResourcesOfType:@"pack.gz" inDirectory:@"jre/lib"];
+}
+
+- (NSString *)unpack200Path {
+	return [[NSBundle mainBundle] pathForResource:@"unpack200" ofType:nil inDirectory:@"jre/bin"];
+}
+#endif
+
+@end
diff --git a/OSX/Metabase/Backend/SettingsManager.h b/OSX/Metabase/Backend/SettingsManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..c21a5bdce24b0da3b324e8269ab526de1db54447
--- /dev/null
+++ b/OSX/Metabase/Backend/SettingsManager.h
@@ -0,0 +1,17 @@
+//
+//  SettingsManager.h
+//  Metabase
+//
+//  Created by Cam Saul on 9/22/15.
+//  Copyright (c) 2015 Metabase. All rights reserved.
+//
+
+NSString *LocalHostBaseURL();
+
+@interface SettingsManager : NSObject
+
++ (instancetype)instance;
+
+@property (copy) NSString *baseURL;
+
+@end
diff --git a/OSX/Metabase/Backend/SettingsManager.m b/OSX/Metabase/Backend/SettingsManager.m
new file mode 100644
index 0000000000000000000000000000000000000000..46b7f18d45be1a2773bdc5e406ef334e3841b3ad
--- /dev/null
+++ b/OSX/Metabase/Backend/SettingsManager.m
@@ -0,0 +1,41 @@
+//
+//  SettingsManager.m
+//  Metabase
+//
+//  Created by Cam Saul on 9/22/15.
+//  Copyright (c) 2015 Metabase. All rights reserved.
+//
+
+#import "AppDelegate.h"
+#import "SettingsManager.h"
+
+static SettingsManager *sSettingsManager = nil;
+
+static NSString * const BaseURLUserDefaultsKey = @"com.metabase.baseURL";
+
+NSString *LocalHostBaseURL() {
+	return [NSString stringWithFormat:@"http://localhost:%lu", [AppDelegate instance].port];
+}
+
+
+@implementation SettingsManager
+
++ (instancetype)instance {
+	@synchronized(self) {
+		if (!sSettingsManager) sSettingsManager = [[SettingsManager alloc] init];
+	}
+	return sSettingsManager;
+}
+
+#pragma mark - Getters / Setters
+
+- (NSString *)baseURL {
+	return [[NSUserDefaults standardUserDefaults] objectForKey:BaseURLUserDefaultsKey];
+}
+
+- (void)setBaseURL:(NSString *)baseURL {
+	[[NSUserDefaults standardUserDefaults] setObject:[baseURL copy] forKey:BaseURLUserDefaultsKey];
+	[[NSUserDefaults standardUserDefaults] synchronize];
+}
+
+@end
diff --git a/OSX/Metabase/Backend/TaskHealthChecker.h b/OSX/Metabase/Backend/TaskHealthChecker.h
new file mode 100644
index 0000000000000000000000000000000000000000..629375d13a45b39fddb90a412a6a35b64709329d
--- /dev/null
+++ b/OSX/Metabase/Backend/TaskHealthChecker.h
@@ -0,0 +1,23 @@
+//
+//  TaskHealthChecker.h
+//  Metabase
+//
+//  Created by Cam Saul on 10/9/15.
+//  Copyright (c) 2015 Metabase. All rights reserved.
+//
+
+static NSString * const MetabaseTaskBecameHealthyNotification	= @"MetabaseTaskBecameHealthyNotification";
+static NSString * const MetabaseTaskBecameUnhealthyNotification = @"MetabaseTaskBecameUnhealthyNotification";
+static NSString * const MetabaseTaskTimedOutNotification		= @"MetabaseTaskTimedOutNotification";
+
+@interface TaskHealthChecker : NSObject
+
+@property () NSUInteger port;
+
+- (void)start;
+- (void)stop;
+- (void)resetTimeout;
+
+- (CFAbsoluteTime)lastCheckTime;
+
+@end
diff --git a/OSX/Metabase/Backend/TaskHealthChecker.m b/OSX/Metabase/Backend/TaskHealthChecker.m
new file mode 100644
index 0000000000000000000000000000000000000000..e1de91bded3d642987562dc3641e690dc31f09fb
--- /dev/null
+++ b/OSX/Metabase/Backend/TaskHealthChecker.m
@@ -0,0 +1,149 @@
+//
+//  TaskHealthChecker.m
+//  Metabase
+//
+//  Created by Cam Saul on 10/9/15.
+//  Copyright (c) 2015 Metabase. All rights reserved.
+//
+
+#import "TaskHealthChecker.h"
+
+/// Check out health every this many seconds
+static const CGFloat HealthCheckIntervalSeconds = 1.2f;
+
+/// This number should be lower than HealthCheckIntervalSeconds so requests don't end up piling up
+static const CGFloat HealthCheckRequestTimeout = 0.25f;
+
+/// After this many seconds of being unhealthy, consider the task timed out so it can be killed
+static const CFTimeInterval TimeoutIntervalSeconds = 10.0f;
+
+@interface TaskHealthChecker ()
+@property (strong, nonatomic) NSOperationQueue *healthCheckOperationQueue;
+@property (strong, nonatomic) NSTimer *healthCheckTimer;
+
+@property (nonatomic) BOOL healthy;
+@property CFAbsoluteTime lastHealthyTime;
+@property CFAbsoluteTime lastCheckTime;
+
+/// Set this to YES after server has started successfully one time
+/// we'll hold of on the whole killing the Metabase server until it launches one time, I guess
+@property (nonatomic) BOOL hasEverBeenHealthy;
+@end
+
+@implementation TaskHealthChecker
+
+- (void)dealloc {
+	[self stop];
+}
+
+
+#pragma mark - Local Methods
+
+- (void)resetTimeout {
+	self.lastHealthyTime = CFAbsoluteTimeGetCurrent();
+}
+
+- (void)start {
+	NSLog(@"(re)starting health checker @ 0x%zx...", (size_t)self);
+	self.healthCheckOperationQueue = [[NSOperationQueue alloc] init];
+	self.healthCheckOperationQueue.maxConcurrentOperationCount = 1;
+	
+	[self resetTimeout];
+	
+	dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+		self.healthCheckTimer = [NSTimer timerWithTimeInterval:HealthCheckIntervalSeconds target:self selector:@selector(checkHealth) userInfo:nil repeats:YES];
+		self.healthCheckTimer.tolerance = HealthCheckIntervalSeconds / 2.0f;
+		[[NSRunLoop mainRunLoop] addTimer:self.healthCheckTimer forMode:NSRunLoopCommonModes];
+
+//		self.healthCheckTimer = [NSTimer scheduledTimerWithTimeInterval:HealthCheckIntervalSeconds target:self selector:@selector(checkHealth) userInfo:nil repeats:YES];
+//		self.healthCheckTimer.tolerance = HealthCheckIntervalSeconds / 2.0f; // the timer doesn't need to fire exactly on the intervals, so give it a loose tolerance which will improve power savings, etc.
+	});}
+
+
+- (void)stop {
+	self.healthCheckTimer = nil;
+	self.healthCheckOperationQueue = nil;
+}
+
+- (void)checkHealth:(void(^)(BOOL healthy))completion {
+	self.lastCheckTime = CFAbsoluteTimeGetCurrent();
+	
+	/// Cancel any pending checks so they don't pile up indefinitely
+	[self.healthCheckOperationQueue cancelAllOperations];
+		
+	NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:%lu/api/health", self.port]] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:HealthCheckRequestTimeout];
+	
+	[NSURLConnection sendAsynchronousRequest:request queue:self.healthCheckOperationQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
+		
+		if (connectionError) {
+			completion(NO);
+			return;
+		}
+		
+		NSError *jsonError = nil;
+		NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError];
+		
+		if (jsonError) {
+			completion(NO);
+			return;
+		}
+		
+		completion([json[@"status"] isEqualToString:@"ok"]);
+	}];
+}
+
+- (void)checkHealth {
+	__weak TaskHealthChecker *weakSelf = self;
+	dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
+		[weakSelf checkHealth:^(BOOL healthy) {
+			if (!healthy) NSLog(@"😷");
+			if (healthy && !weakSelf.healthy) NSLog(@"✅");
+			
+			weakSelf.healthy = healthy;
+		}];
+	});
+}
+
+
+#pragma mark - Getters / Setters
+
+- (void)setHealthCheckTimer:(NSTimer *)healthCheckTimer {
+	[_healthCheckTimer invalidate];
+	_healthCheckTimer = healthCheckTimer;
+}
+
+- (void)setHealthCheckOperationQueue:(NSOperationQueue *)healthCheckOperationQueue {
+	[_healthCheckOperationQueue cancelAllOperations];
+	_healthCheckOperationQueue = healthCheckOperationQueue;
+}
+
+- (void)setHealthy:(BOOL)healthy {
+	if (healthy) {
+		self.lastHealthyTime = CFAbsoluteTimeGetCurrent();
+	} else {
+		const CFTimeInterval timeSinceWasLastHealthy = CFAbsoluteTimeGetCurrent() - self.lastHealthyTime;
+		
+		if (timeSinceWasLastHealthy >= TimeoutIntervalSeconds) {
+			__weak TaskHealthChecker *weakSelf = self;
+			if (!self.hasEverBeenHealthy) {
+				NSLog(@"We've been waiting %.0f seconds, what's going on?", timeSinceWasLastHealthy);
+				return;
+			}
+			[[NSNotificationCenter defaultCenter] postNotificationName:MetabaseTaskTimedOutNotification object:weakSelf];
+		}
+	}
+	
+	if (_healthy == healthy) return;
+	
+	_healthy = healthy;
+	NSLog(@"\n\n"
+		   "+--------------------------------------------------------------------+\n"
+		   "|           Server status has transitioned to: %@           |\n"
+		   "+--------------------------------------------------------------------+\n\n", (healthy ? @"HEALTHY    " : @"NOT HEALTHY"));
+	
+	__weak TaskHealthChecker *weakSelf = self;
+	NSString *notification = healthy ? MetabaseTaskBecameHealthyNotification : MetabaseTaskBecameUnhealthyNotification;
+	[[NSNotificationCenter defaultCenter] postNotificationName:notification object:weakSelf];
+}
+
+@end
diff --git a/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Contents.json b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000000000000000000000000000000000000..5727bad9d72448b6a0a4093c045fd41f8dfb745c
--- /dev/null
+++ b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,68 @@
+{
+  "images" : [
+    {
+      "size" : "16x16",
+      "idiom" : "mac",
+      "filename" : "Logo_16.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "16x16",
+      "idiom" : "mac",
+      "filename" : "Logo_32.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "32x32",
+      "idiom" : "mac",
+      "filename" : "Logo_32.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "32x32",
+      "idiom" : "mac",
+      "filename" : "Logo_64.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "128x128",
+      "idiom" : "mac",
+      "filename" : "Logo_128.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "128x128",
+      "idiom" : "mac",
+      "filename" : "Logo_256.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "256x256",
+      "idiom" : "mac",
+      "filename" : "Logo_256.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "256x256",
+      "idiom" : "mac",
+      "filename" : "Logo_512.png",
+      "scale" : "2x"
+    },
+    {
+      "size" : "512x512",
+      "idiom" : "mac",
+      "filename" : "Logo_512.png",
+      "scale" : "1x"
+    },
+    {
+      "size" : "512x512",
+      "idiom" : "mac",
+      "filename" : "Logo_1024.png",
+      "scale" : "2x"
+    }
+  ],
+  "info" : {
+    "version" : 1,
+    "author" : "xcode"
+  }
+}
\ No newline at end of file
diff --git a/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_1024.png b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_1024.png
new file mode 100644
index 0000000000000000000000000000000000000000..62b59a1be5b7868d73a76ed8fffe2bd1a937a14e
Binary files /dev/null and b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_1024.png differ
diff --git a/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_128.png b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_128.png
new file mode 100644
index 0000000000000000000000000000000000000000..0174f514d2326b21595a916559e1f582d69203c4
Binary files /dev/null and b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_128.png differ
diff --git a/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_16.png b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_16.png
new file mode 100644
index 0000000000000000000000000000000000000000..332be62651f1a42cd44c648737ce38434c2b2596
Binary files /dev/null and b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_16.png differ
diff --git a/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_256.png b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_256.png
new file mode 100644
index 0000000000000000000000000000000000000000..a045c036b365b72da1cf166fdba213aca9a8c2ca
Binary files /dev/null and b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_256.png differ
diff --git a/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_32.png b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_32.png
new file mode 100644
index 0000000000000000000000000000000000000000..52ed2b0079c9c4e76f9ed9c9c2601dc801ee10f8
Binary files /dev/null and b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_32.png differ
diff --git a/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_512.png b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_512.png
new file mode 100644
index 0000000000000000000000000000000000000000..5df5cb0e0ff30b06ae69d0220a5cad023e4c3614
Binary files /dev/null and b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_512.png differ
diff --git a/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_64.png b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_64.png
new file mode 100644
index 0000000000000000000000000000000000000000..d2f5af3699f4e7e81978687cfc55d557f3d6289a
Binary files /dev/null and b/OSX/Metabase/Images.xcassets/AppIcon.appiconset/Logo_64.png differ
diff --git a/OSX/Metabase/Metabase-Info.plist b/OSX/Metabase/Metabase-Info.plist
new file mode 100644
index 0000000000000000000000000000000000000000..407b26d9b6712da50f33ba5a6b1fe0e197aa2a31
--- /dev/null
+++ b/OSX/Metabase/Metabase-Info.plist
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>${EXECUTABLE_NAME}</string>
+	<key>CFBundleIconFile</key>
+	<string></string>
+	<key>CFBundleIdentifier</key>
+	<string>com.metabase.${PRODUCT_NAME:rfc1034identifier}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>${PRODUCT_NAME}</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>0.11.3.14</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+	<string>0.11.3.14</string>
+	<key>LSApplicationCategoryType</key>
+	<string>public.app-category.utilities</string>
+	<key>LSMinimumSystemVersion</key>
+	<string>${MACOSX_DEPLOYMENT_TARGET}</string>
+	<key>NSHumanReadableCopyright</key>
+	<string>Copyright © 2015 Metabase. All rights reserved.</string>
+	<key>NSMainNibFile</key>
+	<string>MainMenu</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+	<key>SUEnableAutomaticChecks</key>
+	<true/>
+	<key>SUFeedURL</key>
+	<string>https://s3-us-west-1.amazonaws.com/metabase-osx-releases/appcast.xml</string>
+	<key>SUPublicDSAKeyFile</key>
+	<string>dsa_pub.pem</string>
+</dict>
+</plist>
diff --git a/OSX/Metabase/Metabase-Prefix.pch b/OSX/Metabase/Metabase-Prefix.pch
new file mode 100644
index 0000000000000000000000000000000000000000..016cfddd1aabdb4debd63ef351b026231281881e
--- /dev/null
+++ b/OSX/Metabase/Metabase-Prefix.pch
@@ -0,0 +1,9 @@
+//
+//  Prefix header
+//
+//  The contents of this file are implicitly included at the beginning of every source file.
+//
+
+#ifdef __OBJC__
+	@import Cocoa;
+#endif
diff --git a/OSX/Metabase/UI/MainMenu.xib b/OSX/Metabase/UI/MainMenu.xib
new file mode 100644
index 0000000000000000000000000000000000000000..14d7df6e1e5d62e91f63ebb21fdf27ebcd3b22db
--- /dev/null
+++ b/OSX/Metabase/UI/MainMenu.xib
@@ -0,0 +1,311 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5053" systemVersion="13A603" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
+    <dependencies>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5053"/>
+        <plugIn identifier="com.apple.WebKitIBPlugin" version="5053"/>
+    </dependencies>
+    <objects>
+        <customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
+            <connections>
+                <outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
+            </connections>
+        </customObject>
+        <customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
+        <customObject id="-3" userLabel="Application"/>
+        <customObject id="SvH-Fm-ua3" customClass="SUUpdater"/>
+        <customObject id="Voe-Tx-rLC" customClass="AppDelegate">
+            <connections>
+                <outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
+            </connections>
+        </customObject>
+        <customObject id="YLy-65-1bz" customClass="NSFontManager"/>
+        <viewController title="MainViewController" nibName="" id="8au-ff-PAw" customClass="MainViewController">
+            <connections>
+                <outlet property="backButtonCell" destination="lEo-fP-VyB" id="Liq-b8-nP9"/>
+                <outlet property="forwardButtonCell" destination="uF3-qn-F0a" id="eR7-ml-w4X"/>
+                <outlet property="linkButtonCell" destination="D9P-hg-lf8" id="G2L-cA-69g"/>
+                <outlet property="loadingView" destination="rgN-Vh-1hF" id="NCM-3X-yhL"/>
+                <outlet property="refreshButtonCell" destination="SSf-hM-lhY" id="xJE-83-OZr"/>
+                <outlet property="titleBarView" destination="Pem-Bq-pDs" id="nGc-wz-YES"/>
+                <outlet property="view" destination="EiT-Mj-1SZ" id="hOv-v9-VQo"/>
+                <outlet property="webView" destination="mhE-X5-FF6" id="MTz-Fg-4Di"/>
+            </connections>
+        </viewController>
+        <menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
+            <items>
+                <menuItem title="Metabase" id="1Xt-HY-uBw">
+                    <modifierMask key="keyEquivalentModifierMask"/>
+                    <menu key="submenu" title="Metabase" systemMenu="apple" id="uQy-DD-JDr">
+                        <items>
+                            <menuItem title="Check for Updates..." id="deG-HF-Nuu">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <connections>
+                                    <action selector="checkForUpdates:" target="SvH-Fm-ua3" id="hKn-lq-Ugp"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem isSeparatorItem="YES" id="45c-9m-ljg"/>
+                            <menuItem title="Hide Metabase" keyEquivalent="h" id="Olw-nP-bQN">
+                                <connections>
+                                    <action selector="hide:" target="-1" id="PnN-Uc-m68"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
+                                <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+                                <connections>
+                                    <action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Show All" id="Kd2-mp-pUS">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <connections>
+                                    <action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
+                            <menuItem title="Quit Metabase" keyEquivalent="q" id="4sb-4s-VLi">
+                                <connections>
+                                    <action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
+                                </connections>
+                            </menuItem>
+                        </items>
+                    </menu>
+                </menuItem>
+                <menuItem title="Edit" id="5QF-Oa-p0T">
+                    <modifierMask key="keyEquivalentModifierMask"/>
+                    <menu key="submenu" title="Edit" id="W48-6f-4Dl">
+                        <items>
+                            <menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
+                                <connections>
+                                    <action selector="undo:" target="-1" id="M6e-cu-g7V"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
+                                <connections>
+                                    <action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
+                            <menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
+                                <connections>
+                                    <action selector="cut:" target="-1" id="YJe-68-I9s"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
+                                <connections>
+                                    <action selector="copy:" target="-1" id="G1f-GL-Joy"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
+                                <connections>
+                                    <action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Delete" id="pa3-QI-u2k">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <connections>
+                                    <action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
+                                </connections>
+                            </menuItem>
+                        </items>
+                    </menu>
+                </menuItem>
+                <menuItem title="Navigate" id="OrU-aO-QrS">
+                    <modifierMask key="keyEquivalentModifierMask"/>
+                    <menu key="submenu" title="Navigate" id="Vm8-vh-NMO">
+                        <items>
+                            <menuItem title="Back" keyEquivalent="" id="1tY-ia-YVu">
+                                <modifierMask key="keyEquivalentModifierMask" option="YES"/>
+                                <connections>
+                                    <action selector="back:" target="8au-ff-PAw" id="E1u-Hv-xOJ"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Forward" keyEquivalent="" id="XMU-vQ-kD4">
+                                <modifierMask key="keyEquivalentModifierMask" option="YES"/>
+                                <connections>
+                                    <action selector="forward:" target="8au-ff-PAw" id="wGg-7M-OEs"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Reload" keyEquivalent="r" id="4nb-4K-Z2y">
+                                <connections>
+                                    <action selector="reload:" target="8au-ff-PAw" id="LU6-rC-mFx"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem isSeparatorItem="YES" id="HRY-1F-Mgz"/>
+                            <menuItem title="Copy Current URL to Clipboard" keyEquivalent="c" id="9UT-kQ-RV6">
+                                <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
+                                <connections>
+                                    <action selector="copyURLToClipboard:" target="8au-ff-PAw" id="grb-Hc-gc4"/>
+                                </connections>
+                            </menuItem>
+                        </items>
+                    </menu>
+                </menuItem>
+                <menuItem title="Window" id="aUF-d1-5bR">
+                    <modifierMask key="keyEquivalentModifierMask"/>
+                    <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
+                        <items>
+                            <menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
+                                <connections>
+                                    <action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
+                                </connections>
+                            </menuItem>
+                            <menuItem title="Bring All to Front" id="LE2-aR-0XJ">
+                                <modifierMask key="keyEquivalentModifierMask"/>
+                                <connections>
+                                    <action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
+                                </connections>
+                            </menuItem>
+                        </items>
+                    </menu>
+                </menuItem>
+                <menuItem title="Help" id="wpr-3q-Mcd">
+                    <modifierMask key="keyEquivalentModifierMask"/>
+                </menuItem>
+            </items>
+        </menu>
+        <window title="Metabase" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g" customClass="INAppStoreWindow">
+            <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
+            <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
+            <rect key="contentRect" x="335" y="390" width="1200" height="900"/>
+            <rect key="screenRect" x="0.0" y="0.0" width="2560" height="1418"/>
+            <value key="minSize" type="size" width="1000" height="800"/>
+            <view key="contentView" canDrawConcurrently="YES" id="EiT-Mj-1SZ">
+                <rect key="frame" x="0.0" y="0.0" width="1200" height="900"/>
+                <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                <subviews>
+                    <webView canDrawConcurrently="YES" translatesAutoresizingMaskIntoConstraints="NO" id="mhE-X5-FF6">
+                        <rect key="frame" x="0.0" y="0.0" width="1200" height="900"/>
+                        <autoresizingMask key="autoresizingMask"/>
+                        <webPreferences key="preferences" defaultFontSize="12" defaultFixedFontSize="12" plugInsEnabled="NO" javaEnabled="NO">
+                            <nil key="identifier"/>
+                        </webPreferences>
+                        <connections>
+                            <outlet property="policyDelegate" destination="8au-ff-PAw" id="Ywf-Ex-Plw"/>
+                            <outlet property="resourceLoadDelegate" destination="8au-ff-PAw" id="Rnd-KA-IRb"/>
+                        </connections>
+                    </webView>
+                    <imageView canDrawConcurrently="YES" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="rgN-Vh-1hF">
+                        <rect key="frame" x="472" y="322" width="256" height="256"/>
+                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+                        <constraints>
+                            <constraint firstAttribute="height" constant="256" id="Wi3-zz-jaD"/>
+                            <constraint firstAttribute="width" constant="256" id="zOt-ub-YPO"/>
+                        </constraints>
+                        <imageCell key="cell" refusesFirstResponder="YES" alignment="left" animates="YES" imageScaling="proportionallyDown" image="Logo_1024" id="wFY-0Y-m5p"/>
+                    </imageView>
+                </subviews>
+                <constraints>
+                    <constraint firstItem="mhE-X5-FF6" firstAttribute="top" secondItem="EiT-Mj-1SZ" secondAttribute="top" id="AbJ-I7-UJl"/>
+                    <constraint firstItem="mhE-X5-FF6" firstAttribute="leading" secondItem="EiT-Mj-1SZ" secondAttribute="leading" id="JBU-I1-v0p"/>
+                    <constraint firstAttribute="bottom" secondItem="mhE-X5-FF6" secondAttribute="bottom" id="OA1-e5-N7X"/>
+                    <constraint firstAttribute="centerY" secondItem="rgN-Vh-1hF" secondAttribute="centerY" id="fMi-CB-Ih4"/>
+                    <constraint firstAttribute="centerX" secondItem="rgN-Vh-1hF" secondAttribute="centerX" id="v6L-mJ-Sh5"/>
+                    <constraint firstAttribute="trailing" secondItem="mhE-X5-FF6" secondAttribute="trailing" id="z4U-O6-LWv"/>
+                </constraints>
+            </view>
+        </window>
+        <customView id="Pem-Bq-pDs" userLabel="titleBarView">
+            <rect key="frame" x="0.0" y="0.0" width="651" height="32"/>
+            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+            <subviews>
+                <customView translatesAutoresizingMaskIntoConstraints="NO" id="V9v-oH-CLo">
+                    <rect key="frame" x="64" y="0.0" width="523" height="32"/>
+                    <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+                    <subviews>
+                        <textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="BVV-jo-b9C">
+                            <rect key="frame" x="229" y="8" width="64" height="17"/>
+                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+                            <textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" enabled="NO" sendsActionOnEndEditing="YES" title="Metabase" id="Vvp-PZ-SY5">
+                                <font key="font" metaFont="system"/>
+                                <color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
+                                <color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
+                            </textFieldCell>
+                        </textField>
+                        <button translatesAutoresizingMaskIntoConstraints="NO" id="dZP-Ul-oSB">
+                            <rect key="frame" x="0.0" y="0.0" width="24" height="32"/>
+                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="24" id="6zn-IR-p7a"/>
+                            </constraints>
+                            <buttonCell key="cell" type="bevel" bezelStyle="rounded" image="back_icon" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="lEo-fP-VyB">
+                                <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                                <font key="font" metaFont="system" size="23"/>
+                            </buttonCell>
+                            <connections>
+                                <action selector="back:" target="8au-ff-PAw" id="MfY-gk-scw"/>
+                            </connections>
+                        </button>
+                        <button translatesAutoresizingMaskIntoConstraints="NO" id="5Bt-VB-Dba">
+                            <rect key="frame" x="24" y="0.0" width="24" height="32"/>
+                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="24" id="cZI-NR-ghh"/>
+                            </constraints>
+                            <buttonCell key="cell" type="bevel" bezelStyle="rounded" image="forward_icon" imagePosition="only" alignment="center" imageScaling="proportionallyDown" inset="2" id="uF3-qn-F0a">
+                                <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                                <font key="font" metaFont="system" size="23"/>
+                            </buttonCell>
+                            <connections>
+                                <action selector="forward:" target="8au-ff-PAw" id="Hwj-Yo-Qtt"/>
+                            </connections>
+                        </button>
+                        <button translatesAutoresizingMaskIntoConstraints="NO" id="HAI-2S-GZQ">
+                            <rect key="frame" x="48" y="0.0" width="24" height="32"/>
+                            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="24" id="Bk3-9A-EeN"/>
+                            </constraints>
+                            <buttonCell key="cell" type="bevel" bezelStyle="rounded" image="refresh_icon" imagePosition="overlaps" alignment="center" imageScaling="proportionallyDown" inset="2" id="SSf-hM-lhY">
+                                <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                                <font key="font" metaFont="system" size="23"/>
+                            </buttonCell>
+                            <connections>
+                                <action selector="reload:" target="8au-ff-PAw" id="y95-m6-iZ1"/>
+                            </connections>
+                        </button>
+                    </subviews>
+                    <constraints>
+                        <constraint firstAttribute="centerY" secondItem="5Bt-VB-Dba" secondAttribute="centerY" id="2iz-ND-ODT"/>
+                        <constraint firstAttribute="centerY" secondItem="HAI-2S-GZQ" secondAttribute="centerY" id="Efu-ly-nfn"/>
+                        <constraint firstAttribute="centerY" secondItem="dZP-Ul-oSB" secondAttribute="centerY" id="FYl-6N-5zd"/>
+                        <constraint firstAttribute="centerX" secondItem="BVV-jo-b9C" secondAttribute="centerX" id="LIX-0H-Hcn"/>
+                        <constraint firstAttribute="centerY" secondItem="BVV-jo-b9C" secondAttribute="centerY" id="NaO-8y-1rD"/>
+                        <constraint firstItem="dZP-Ul-oSB" firstAttribute="leading" secondItem="V9v-oH-CLo" secondAttribute="leading" id="P36-OS-GAI"/>
+                        <constraint firstItem="HAI-2S-GZQ" firstAttribute="leading" secondItem="5Bt-VB-Dba" secondAttribute="trailing" id="cAU-bJ-DfV"/>
+                        <constraint firstItem="5Bt-VB-Dba" firstAttribute="leading" secondItem="dZP-Ul-oSB" secondAttribute="trailing" id="pHA-7b-NC5"/>
+                    </constraints>
+                </customView>
+                <button translatesAutoresizingMaskIntoConstraints="NO" id="XfF-w9-qlO">
+                    <rect key="frame" x="627" y="0.0" width="24" height="32"/>
+                    <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="24" id="O1n-dk-WFr"/>
+                    </constraints>
+                    <buttonCell key="cell" type="bevel" bezelStyle="rounded" image="link_icon" imagePosition="overlaps" alignment="center" imageScaling="proportionallyDown" inset="2" id="D9P-hg-lf8">
+                        <behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
+                        <font key="font" metaFont="system" size="23"/>
+                    </buttonCell>
+                    <connections>
+                        <action selector="copyURLToClipboard:" target="8au-ff-PAw" id="EEq-ZQ-Cwv"/>
+                    </connections>
+                </button>
+            </subviews>
+            <constraints>
+                <constraint firstAttribute="trailing" secondItem="XfF-w9-qlO" secondAttribute="trailing" id="ScP-H6-pcc"/>
+                <constraint firstAttribute="bottom" secondItem="V9v-oH-CLo" secondAttribute="bottom" id="TY7-Sy-rWe"/>
+                <constraint firstItem="V9v-oH-CLo" firstAttribute="top" secondItem="Pem-Bq-pDs" secondAttribute="top" id="YVh-iR-cBq"/>
+                <constraint firstItem="V9v-oH-CLo" firstAttribute="leading" secondItem="Pem-Bq-pDs" secondAttribute="leading" constant="64" id="cEB-9C-Fnb"/>
+                <constraint firstAttribute="trailing" secondItem="V9v-oH-CLo" secondAttribute="trailing" constant="64" id="pcy-tI-xwH"/>
+                <constraint firstItem="XfF-w9-qlO" firstAttribute="top" secondItem="Pem-Bq-pDs" secondAttribute="top" id="rTc-5I-7Vt"/>
+                <constraint firstAttribute="bottom" secondItem="XfF-w9-qlO" secondAttribute="bottom" id="zqj-GW-B55"/>
+            </constraints>
+        </customView>
+    </objects>
+    <resources>
+        <image name="Logo_1024" width="1024" height="1024"/>
+        <image name="back_icon" width="10" height="15"/>
+        <image name="forward_icon" width="10" height="15"/>
+        <image name="link_icon" width="16" height="15"/>
+        <image name="refresh_icon" width="14" height="15"/>
+    </resources>
+</document>
diff --git a/OSX/Metabase/UI/MainViewController.h b/OSX/Metabase/UI/MainViewController.h
new file mode 100644
index 0000000000000000000000000000000000000000..6739314eaf42920ef9b875492421ca5bd92c3ee8
--- /dev/null
+++ b/OSX/Metabase/UI/MainViewController.h
@@ -0,0 +1,13 @@
+//
+//  MainViewController.h
+//  Metabase
+//
+//  Created by Cam Saul on 9/21/15.
+//  Copyright (c) 2015 Metabase. All rights reserved.
+//
+
+@import Cocoa;
+
+@interface MainViewController : NSViewController
+
+@end
diff --git a/OSX/Metabase/UI/MainViewController.m b/OSX/Metabase/UI/MainViewController.m
new file mode 100644
index 0000000000000000000000000000000000000000..8acdcec61e381073104090354d3aa8f4314ed6f9
--- /dev/null
+++ b/OSX/Metabase/UI/MainViewController.m
@@ -0,0 +1,236 @@
+//
+//  MainViewController.m
+//  Metabase
+//
+//  Created by Cam Saul on 9/21/15.
+//  Copyright (c) 2015 Metabase. All rights reserved.
+//
+
+@import JavaScriptCore;
+@import QuartzCore;
+@import WebKit;
+
+#import "INAppStoreWindow.h"
+
+#import "MainViewController.h"
+#import "SettingsManager.h"
+#import "TaskHealthChecker.h"
+
+@interface MainViewController ()
+@property (weak) IBOutlet NSImageView *loadingView;
+@property (weak) IBOutlet WebView *webView;
+@property (strong) IBOutlet NSView *titleBarView;
+
+@property (weak) IBOutlet NSButtonCell *backButtonCell;
+@property (weak) IBOutlet NSButtonCell *forwardButtonCell;
+@property (weak) IBOutlet NSButtonCell *refreshButtonCell;
+@property (weak) IBOutlet NSButtonCell *linkButtonCell;
+
+@property (strong, readonly) NSString *baseURL;
+
+@property (nonatomic) BOOL loading;
+
+@end
+
+@implementation MainViewController
+
+#pragma mark - Lifecycle
+
+- (void)awakeFromNib {
+	INAppStoreWindow *window = (INAppStoreWindow *)self.view.window;
+	window.titleBarHeight = self.titleBarView.bounds.size.height;
+	
+	self.view.wantsLayer = YES;
+	self.view.layer.backgroundColor = [NSColor whiteColor].CGColor;
+	
+	self.titleBarView.frame = window.titleBarView.bounds;
+	self.titleBarView.autoresizingMask = NSViewWidthSizable|NSViewHeightSizable;
+	[window.titleBarView addSubview:self.titleBarView];
+	
+	self.loadingView.wantsLayer = YES;
+	self.loadingView.layer.masksToBounds = NO;
+	
+	self.webView.wantsLayer = YES;
+	
+	self.loadingView.animator.alphaValue = 0.0f;
+	self.webView.animator.alphaValue = 0.0f;
+	
+	dispatch_async(dispatch_get_main_queue(), ^{
+		self.loading = YES;
+	});
+	
+	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskBecameHealthy:) name:MetabaseTaskBecameHealthyNotification object:nil];
+	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskBecameUnhealthy:) name:MetabaseTaskBecameUnhealthyNotification object:nil];
+}
+
+- (void)dealloc {
+	[[NSNotificationCenter defaultCenter] removeObserver:self];
+}
+
+
+#pragma mark - Notifications
+
+- (void)taskBecameHealthy:(NSNotification *)notification {
+	dispatch_async(dispatch_get_main_queue(), ^{
+		[self loadMainPage];
+		dispatch_async(dispatch_get_main_queue(), ^{
+			self.loading = NO;
+		});
+	});
+}
+
+- (void)taskBecameUnhealthy:(NSNotification *)notification {
+	dispatch_async(dispatch_get_main_queue(), ^{
+		self.loading = YES;
+	});
+}
+
+
+#pragma mark - Local Methods
+
+- (void)loadMainPage {
+	NSLog(@"Connecting to Metabase instance at: %@", self.baseURL);
+	
+	NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.baseURL]];
+	request.cachePolicy = NSURLCacheStorageAllowedInMemoryOnly;
+	[self.webView.mainFrame loadRequest:request];
+}
+
+- (void)saveCSV:(NSString *)apiURL {
+	NSSavePanel *savePanel			= [NSSavePanel savePanel];
+	savePanel.allowedFileTypes		= @[@"csv"];
+	savePanel.allowsOtherFileTypes	= NO;
+	savePanel.extensionHidden		= NO;
+	savePanel.showsTagField			= NO;
+	
+	NSString *downloadsDirectory	=  NSSearchPathForDirectoriesInDomains(NSDownloadsDirectory, NSUserDomainMask, YES)[0];
+	savePanel.directoryURL			= [NSURL URLWithString:downloadsDirectory];
+	
+	NSDateFormatter *dateFormatter	= [[NSDateFormatter alloc] init];
+	dateFormatter.locale			= [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
+	dateFormatter.dateFormat		= @"yyyy-MM-dd'T'HH_mm_ss";
+	savePanel.nameFieldStringValue	= [NSString stringWithFormat:@"query_result_%@", [dateFormatter stringFromDate:[NSDate date]]];
+	
+	if ([savePanel runModal] == NSFileHandlingPanelOKButton) {
+		NSLog(@"Will save CSV at: %@", savePanel.URL);
+		
+		NSURL *url = [NSURL URLWithString:apiURL relativeToURL:[NSURL URLWithString:self.baseURL]];
+		NSURLRequest *csvRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0f];
+		[NSURLConnection sendAsynchronousRequest:csvRequest queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
+			NSError *writeError = nil;
+			[data writeToURL:savePanel.URL options:NSDataWritingAtomic error:&writeError];
+			
+			dispatch_async(dispatch_get_main_queue(), ^{
+				if (writeError) {
+					[[NSAlert alertWithError:writeError] runModal];
+				} else {
+					[[NSAlert alertWithMessageText:@"Saved" defaultButton:@"Done" alternateButton:nil otherButton:nil informativeTextWithFormat:@"Your data has been saved."] runModal];
+				}
+			});
+		}];
+	}
+}
+
+- (void)injectJS {
+	JSContext *context = self.webView.mainFrame.javaScriptContext;
+	
+	// replace console.log with a function that calls NSLog so we can see the output
+	context[@"console"][@"log"] = ^(JSValue *message) {
+		NSLog(@"console.log: %@", message);
+	};
+	
+	// custom functions for OS X integration are available to the frontend as properties of window.OSX
+	context[@"OSX"] = @{@"saveCSV": ^(JSValue *apiURL){
+		[self saveCSV:apiURL.description];
+	}};
+}
+
+
+#pragma mark - Getters / Setters
+
+- (NSString *)baseURL {
+	return SettingsManager.instance.baseURL.length ? SettingsManager.instance.baseURL : LocalHostBaseURL();
+}
+
+- (void)setLoading:(BOOL)loading {
+	if (_loading == loading) return;
+	_loading = loading;
+	
+	if (loading) {
+		[self.loadingView.layer removeAllAnimations];
+		
+		self.backButtonCell.enabled = self.forwardButtonCell.enabled = self.linkButtonCell.enabled = NO;
+		
+		self.webView.animator.alphaValue = 0.2f;
+		self.loadingView.animator.alphaValue = 1.0f;
+		
+		static const CGFloat LoadingViewScaleDuration	= 2.5f;
+		static const CGFloat LoadingViewScaleMin		= 0.65f;
+		static const CGFloat LoadingViewScaleMax		= 1.0f;
+		
+		const CATransform3D min = CATransform3DTranslate(CATransform3DMakeScale(LoadingViewScaleMin, LoadingViewScaleMin, 1.0f), self.loadingView.bounds.size.width / 4.0f, self.loadingView.bounds.size.height / 4.0f, 0);
+		const CATransform3D max = CATransform3DMakeScale(LoadingViewScaleMax, LoadingViewScaleMax, 1.0f);
+		
+		CAKeyframeAnimation *scale	= [CAKeyframeAnimation animationWithKeyPath:@"transform"];
+		scale.timingFunction		= [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
+		scale.values				= @[[NSValue valueWithCATransform3D:min],
+										[NSValue valueWithCATransform3D:max],
+										[NSValue valueWithCATransform3D:min]];
+		scale.duration				= LoadingViewScaleDuration;
+		scale.repeatCount			= HUGE_VALF;
+		
+		[self.loadingView.layer addAnimation:scale forKey:@"transform"];
+	} else {
+		self.webView.animator.alphaValue = 1.0f;
+		self.loadingView.animator.alphaValue = 0.0f;
+		
+		dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+			[self.loadingView.layer removeAllAnimations];
+		});
+	}
+}
+
+
+#pragma mark - Actions
+
+- (IBAction)back:(id)sender {
+	[self.webView goBack];
+}
+
+- (IBAction)forward:(id)sender {
+	[self.webView goForward];
+}
+
+- (IBAction)reload:(id)sender {
+	[self.webView.mainFrame reload];
+}
+
+- (IBAction)copyURLToClipboard:(id)sender {
+	[NSPasteboard.generalPasteboard declareTypes:@[NSStringPboardType] owner:nil];
+	[NSPasteboard.generalPasteboard setString:self.webView.mainFrameURL forType:NSStringPboardType];
+	
+	[[NSAlert alertWithMessageText:@"Link Copied" defaultButton:@"Ok" alternateButton:nil otherButton:nil informativeTextWithFormat:@"A link to this page has been copied to your clipboard."] runModal];
+}
+
+
+#pragma mark - WebResourceLoadDelegate
+
+- (void)webView:(WebView *)sender resource:(id)identifier didFinishLoadingFromDataSource:(WebDataSource *)dataSource {
+	[self injectJS];
+	
+	self.linkButtonCell.enabled = YES;
+	self.backButtonCell.enabled = self.webView.canGoBack;
+	self.forwardButtonCell.enabled = self.webView.canGoForward;
+}
+
+
+#pragma mark - WebPolicyDelegate
+
+- (void)webView:(WebView *)webView decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request newFrameName:(NSString *)frameName decisionListener:(id<WebPolicyDecisionListener>)listener {
+	// Tell webkit window to open new links in browser
+	NSURL *url = actionInformation[WebActionOriginalURLKey];
+	[[NSWorkspace sharedWorkspace] openURL:url];
+	[listener ignore];
+}
+
+@end
diff --git a/OSX/Metabase/en.lproj/Credits.rtf b/OSX/Metabase/en.lproj/Credits.rtf
new file mode 100644
index 0000000000000000000000000000000000000000..46576ef211d18155ae1997e26c209a97ff1ec7ec
--- /dev/null
+++ b/OSX/Metabase/en.lproj/Credits.rtf
@@ -0,0 +1,29 @@
+{\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;}
+{\colortbl;\red255\green255\blue255;}
+\paperw9840\paperh8400
+\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
+
+\f0\b\fs24 \cf0 Engineering:
+\b0 \
+	Some people\
+\
+
+\b Human Interface Design:
+\b0 \
+	Some other people\
+\
+
+\b Testing:
+\b0 \
+	Hopefully not nobody\
+\
+
+\b Documentation:
+\b0 \
+	Whoever\
+\
+
+\b With special thanks to:
+\b0 \
+	Mom\
+}
diff --git a/OSX/Metabase/en.lproj/InfoPlist.strings b/OSX/Metabase/en.lproj/InfoPlist.strings
new file mode 100644
index 0000000000000000000000000000000000000000..477b28ff8f86a3158a71c4934fbd3a2456717d7a
--- /dev/null
+++ b/OSX/Metabase/en.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
diff --git a/OSX/Metabase/main.m b/OSX/Metabase/main.m
new file mode 100644
index 0000000000000000000000000000000000000000..91c2e088fd9414fdf89e36160ca7e07bb2e38024
--- /dev/null
+++ b/OSX/Metabase/main.m
@@ -0,0 +1,14 @@
+//
+//  main.m
+//  Metabase
+//
+//  Created by Cam Saul on 9/21/15.
+//  Copyright (c) 2015 Metabase. All rights reserved.
+//
+
+@import Cocoa;
+
+int main(int argc, const char * argv[])
+{
+	return NSApplicationMain(argc, argv);
+}
diff --git a/OSX/Resources/Images/Logo_1024.png b/OSX/Resources/Images/Logo_1024.png
new file mode 100644
index 0000000000000000000000000000000000000000..62b59a1be5b7868d73a76ed8fffe2bd1a937a14e
Binary files /dev/null and b/OSX/Resources/Images/Logo_1024.png differ
diff --git a/OSX/Resources/Images/back_icon@1x.png b/OSX/Resources/Images/back_icon@1x.png
new file mode 100644
index 0000000000000000000000000000000000000000..c29cd709903a3f3958a0df393e878796805c6c12
Binary files /dev/null and b/OSX/Resources/Images/back_icon@1x.png differ
diff --git a/OSX/Resources/Images/back_icon@2x.png b/OSX/Resources/Images/back_icon@2x.png
new file mode 100644
index 0000000000000000000000000000000000000000..769022163ff2c01aa8c3ae57553e466dc2cf28b8
Binary files /dev/null and b/OSX/Resources/Images/back_icon@2x.png differ
diff --git a/OSX/Resources/Images/forward_icon@1x.png b/OSX/Resources/Images/forward_icon@1x.png
new file mode 100644
index 0000000000000000000000000000000000000000..8f565cc6609123891b1b741c7e7a10815d93881b
Binary files /dev/null and b/OSX/Resources/Images/forward_icon@1x.png differ
diff --git a/OSX/Resources/Images/forward_icon@2x.png b/OSX/Resources/Images/forward_icon@2x.png
new file mode 100644
index 0000000000000000000000000000000000000000..6d81433718b36a77155405f4e9c1bdeb8c1390c5
Binary files /dev/null and b/OSX/Resources/Images/forward_icon@2x.png differ
diff --git a/OSX/Resources/Images/link_icon@1x.png b/OSX/Resources/Images/link_icon@1x.png
new file mode 100644
index 0000000000000000000000000000000000000000..3907aede09b85751aa15f14ab2f350c706f97904
Binary files /dev/null and b/OSX/Resources/Images/link_icon@1x.png differ
diff --git a/OSX/Resources/Images/link_icon@2x.png b/OSX/Resources/Images/link_icon@2x.png
new file mode 100644
index 0000000000000000000000000000000000000000..c3945c7b1a529fa13a70660d7b2e24893595d20c
Binary files /dev/null and b/OSX/Resources/Images/link_icon@2x.png differ
diff --git a/OSX/Resources/Images/refresh_icon@1x.png b/OSX/Resources/Images/refresh_icon@1x.png
new file mode 100644
index 0000000000000000000000000000000000000000..3abf33b1f294796ee2a4d06f459455b4c9ebee78
Binary files /dev/null and b/OSX/Resources/Images/refresh_icon@1x.png differ
diff --git a/OSX/Resources/Images/refresh_icon@2x.png b/OSX/Resources/Images/refresh_icon@2x.png
new file mode 100644
index 0000000000000000000000000000000000000000..bbe59ca261023d09ca0126eb5d87be2408ef7f50
Binary files /dev/null and b/OSX/Resources/Images/refresh_icon@2x.png differ
diff --git a/OSX/Resources/dsa_pub.pem b/OSX/Resources/dsa_pub.pem
new file mode 100644
index 0000000000000000000000000000000000000000..15a5b55817abb995eb60a38d91245c6db7b1e67d
--- /dev/null
+++ b/OSX/Resources/dsa_pub.pem
@@ -0,0 +1,36 @@
+-----BEGIN PUBLIC KEY-----
+MIIGOjCCBC0GByqGSM44BAEwggQgAoICAQC7RwleUWvm0dR07ENWdXslkpZEs1e6
+B32itoDF1sm414IMzm2OoHspBqfGf3nQrDcZCW5cngtdLg5eS3x00Ssfdz8j+zHz
+7sH5sMOipdUzxY0LS2qfOW0E5HKeSstLi5qpyE3IDOoQs57KRMeIlk0jPYml8rA7
+z1CTgEe18eSVcNgG2oceamNT9+dE5KleaOmuyV4RuPQF9n76kssMxN4qvP38AMI0
+MjEMKzwF8HsPS4ALPyf4S27ACNJU3Ws/clqDD9UWzsbB7gYtZYkqUjIJKbPqH1sm
+ldGXQV5safL0f/kT4r7r+pSae669BeYEHG2k7JrOccQYfmL0arfhq5ucTYX3nd0v
+XoEFjxmue4ofMpjgFBu/GstVbQl37oxihAwG7jxGbk9uzihGek6HfnKpbkVUAUiH
+LhOvZXUJ6cO+FH4+KCBHsl9HwU0leiBLJ40xnNmWs42moG6LE4Hhs8Uco/9Vpj6R
+0FWtoONiUtvXiAUY3EWQBRpb5uEnqD/r3HYTSpqwYWJkauOR0/DkvvIwmAi0NaO4
+bViiOz+luvn5p/6Le21qOdPopdArRXvQ3bSiopV7P0G6uwnQVtwS+A+rUfDZXSza
+kNZBhK8lOILvk04kp+H4jjdeDGqOe/6HTBrkiVeQsQKla3h0V4ltRkVyBtfbNj6w
+4asW5IsAKiCD2wIVAPy6gMCR+CERLTMkp4qoUYkpMiiXAoICABrhiisnOCqBSqR+
+m+4RRv2aE0pRSJ8XDfA7Kbzvssb31DP8p2AaQH9DZRVlaIEj/PUwO3HHAg6FeV3j
+zLbDBkUHQKAlUb8JsonTthK6i7bC4ZfDge2JndLLvhi345P0dBL7gEZ/91jSYv7p
+QF/bBZQ6FDp4Fpm5cqbg5FXaXJPneaqDd+VqgqZclgfihu92j+HvL6UhWtFdT/DB
+JZTezjIJ4ox299vcEfCfhXXZYiNH6jv+guUt6reAVUobiQOk0QhQhNGXlSdUNs4f
+NQ6ABE4RiB+iRy1PkoAZW4oZtBdBdmEKE8eC0skSqwoLf/XCljv/VySvO0ZO6bBg
+FmZ3yhDgMLEwAzCnjGuaarBl5KxoN7Y7FBQjIugbYlNnr5nxDR5JcDqli+q/NEZT
+qc6c3wf9rqEB9JxMxtkWWcqD7jJBIUiapUG3byieoDaaHi/cvxgnGTGI4nyDPge9
+hpPoP2WBU840wLDjZGxNyNQ78QwUHFIW5v0lPCwdIndZPQJq20z1YZ22lH7azOmB
+NssDVVWSeqn2+DwG275nfK1Qv+V8ww/x0+8wYqOMjaGypMeS0g0MpBBJHZjVQ5Ku
+NH+p9/QjvElk43tLq33cJYnFU/EPVqypE94kbH4bvHpOuysNtrbnvptXLEASO1V3
+sl0OAITKHVDZvvuDsXFPdhXQ9pUVA4ICBQACggIAQ7wfn+Fi2j1Ka5YPgTDf4LLA
+4Z6vvdKcp3+gWnG0oX/X6n5fw//mu7tp2POMCEUm7ANsdTFUqKBfJvcYL15qZCUr
+9D50prWTr4l7A+/NBv5qv/9STDEjccT7Vr5q0pJf6NOkNr/ydGB+0WZEBt/Cpnba
+dAcAKm2BgSrfbb7gIXvOMm7/N+gfYqhYavWKeXv65k8bTfN9UX4odGnz4x0YfUe3
+OOank9ciKwqgDxPCY6mlqe6SuWrfboMimBrZzGUZKMqsAq8CNjH7wwv5XvGyLTMK
+kqysS7fljvhmMf6A1adSxcn3vyckoXP0gHYE/pnn+lrQIpnRzC0x3pbxBYIrV7Qi
+C93YtZAkH5UBIY2q3GL4YmNEIFI6jsJSWLVAxzxqaKbRe3M7FUtkCA2ae3WD+n8e
+XNTCgZmQ0/4syz/3AH8aEaE1ujVE7K9J0Gl4GB8flrXOoKpmMC29zbOg5yuPG+N2
+w5uYmDmmRcOE3dYtSORVzNGObFg9bhvqa3H5zdasC6xCX9/XNFk6Cg693erYpDx3
+KKR6FgQN5qjSrVBBSn/+5JYFntGCs28CIuS3Fd+/Kp9/ZKExBT8AOfU1dXlNNnV3
+Ho77JDPPvJ/mCZwMDERrirU7K794qZ6EdSxzEaaj1VsEkG/nxOEo/3QmSGhr+sJU
+2Rp2O05XdAhgjiObhhg=
+-----END PUBLIC KEY-----
diff --git a/OSX/Vendor/INAppStoreWindow b/OSX/Vendor/INAppStoreWindow
new file mode 160000
index 0000000000000000000000000000000000000000..f91d83f42c159c9f64f4f37bfe1514ca94a651cf
--- /dev/null
+++ b/OSX/Vendor/INAppStoreWindow
@@ -0,0 +1 @@
+Subproject commit f91d83f42c159c9f64f4f37bfe1514ca94a651cf
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Headers b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Headers
new file mode 120000
index 0000000000000000000000000000000000000000..a177d2a6b92600696030834c319f5e1434f9ee6a
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Headers
@@ -0,0 +1 @@
+Versions/Current/Headers
\ No newline at end of file
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Modules b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Modules
new file mode 120000
index 0000000000000000000000000000000000000000..5736f3186e797b8b787748c9979d0fed3b0536c3
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Modules
@@ -0,0 +1 @@
+Versions/Current/Modules
\ No newline at end of file
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/PrivateHeaders b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/PrivateHeaders
new file mode 120000
index 0000000000000000000000000000000000000000..d8e56452691a4645a456259c344667485a974735
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/PrivateHeaders
@@ -0,0 +1 @@
+Versions/Current/PrivateHeaders
\ No newline at end of file
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Resources b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Resources
new file mode 120000
index 0000000000000000000000000000000000000000..953ee36f3bb709faf58a351e0b33c353e337c0a2
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Resources
@@ -0,0 +1 @@
+Versions/Current/Resources
\ No newline at end of file
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Sparkle b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Sparkle
new file mode 120000
index 0000000000000000000000000000000000000000..b2c52731ea3d32dfd46bbd3bed06054190185822
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Sparkle
@@ -0,0 +1 @@
+Versions/Current/Sparkle
\ No newline at end of file
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUAppcast.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUAppcast.h
new file mode 100644
index 0000000000000000000000000000000000000000..8f3efc8e80e140b33081cbcc70f80ef338fb1699
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUAppcast.h
@@ -0,0 +1,26 @@
+//
+//  SUAppcast.h
+//  Sparkle
+//
+//  Created by Andy Matuschak on 3/12/06.
+//  Copyright 2006 Andy Matuschak. All rights reserved.
+//
+
+#ifndef SUAPPCAST_H
+#define SUAPPCAST_H
+
+#import <Foundation/Foundation.h>
+#import "SUExport.h"
+
+@class SUAppcastItem;
+SU_EXPORT @interface SUAppcast : NSObject<NSURLDownloadDelegate>
+
+@property (copy) NSString *userAgentString;
+@property (copy) NSDictionary *httpHeaders;
+
+- (void)fetchAppcastFromURL:(NSURL *)url completionBlock:(void (^)(NSError *))err;
+
+@property (readonly, copy) NSArray *items;
+@end
+
+#endif
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h
new file mode 100644
index 0000000000000000000000000000000000000000..e4c2a06df415794d29dfc7677215374a56182031
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUAppcastItem.h
@@ -0,0 +1,43 @@
+//
+//  SUAppcastItem.h
+//  Sparkle
+//
+//  Created by Andy Matuschak on 3/12/06.
+//  Copyright 2006 Andy Matuschak. All rights reserved.
+//
+
+#ifndef SUAPPCASTITEM_H
+#define SUAPPCASTITEM_H
+
+#import <Foundation/Foundation.h>
+#import "SUExport.h"
+
+SU_EXPORT @interface SUAppcastItem : NSObject
+@property (copy, readonly) NSString *title;
+@property (copy, readonly) NSDate *date;
+@property (copy, readonly) NSString *itemDescription;
+@property (strong, readonly) NSURL *releaseNotesURL;
+@property (copy, readonly) NSString *DSASignature;
+@property (copy, readonly) NSString *minimumSystemVersion;
+@property (copy, readonly) NSString *maximumSystemVersion;
+@property (strong, readonly) NSURL *fileURL;
+@property (copy, readonly) NSString *versionString;
+@property (copy, readonly) NSString *displayVersionString;
+@property (copy, readonly) NSDictionary *deltaUpdates;
+@property (strong, readonly) NSURL *infoURL;
+
+// Initializes with data from a dictionary provided by the RSS class.
+- (instancetype)initWithDictionary:(NSDictionary *)dict;
+- (instancetype)initWithDictionary:(NSDictionary *)dict failureReason:(NSString **)error;
+
+@property (getter=isDeltaUpdate, readonly) BOOL deltaUpdate;
+@property (getter=isCriticalUpdate, readonly) BOOL criticalUpdate;
+
+// Returns the dictionary provided in initWithDictionary; this might be useful later for extensions.
+@property (readonly, copy) NSDictionary *propertiesDictionary;
+
+- (NSURL *)infoURL;
+
+@end
+
+#endif
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUErrors.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUErrors.h
new file mode 100644
index 0000000000000000000000000000000000000000..e624bb056c925a2f859141d2e61a66917113903b
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUErrors.h
@@ -0,0 +1,44 @@
+//
+//  SUErrors.h
+//  Sparkle
+//
+//  Created by C.W. Betts on 10/13/14.
+//  Copyright (c) 2014 Sparkle Project. All rights reserved.
+//
+
+#ifndef SUERRORS_H
+#define SUERRORS_H
+
+#import <Foundation/Foundation.h>
+#import "SUExport.h"
+
+/**
+ * Error domain used by Sparkle
+ */
+SU_EXPORT extern NSString *const SUSparkleErrorDomain;
+
+typedef NS_ENUM(OSStatus, SUError) {
+    // Appcast phase errors.
+    SUAppcastParseError = 1000,
+    SUNoUpdateError = 1001,
+    SUAppcastError = 1002,
+    SURunningFromDiskImageError = 1003,
+    
+    // Downlaod phase errors.
+    SUTemporaryDirectoryError = 2000,
+    
+    // Extraction phase errors.
+    SUUnarchivingError = 3000,
+    SUSignatureError = 3001,
+    
+    // Installation phase errors.
+    SUFileCopyFailure = 4000,
+    SUAuthenticationFailure = 4001,
+    SUMissingUpdateError = 4002,
+    SUMissingInstallerToolError = 4003,
+    SURelaunchError = 4004,
+    SUInstallationError = 4005,
+    SUDowngradeError = 4006
+};
+
+#endif
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUExport.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUExport.h
new file mode 100644
index 0000000000000000000000000000000000000000..3e3f8a1646089b2a7d73f15efe565ffe976be03c
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUExport.h
@@ -0,0 +1,18 @@
+//
+//  SUExport.h
+//  Sparkle
+//
+//  Created by Jake Petroules on 2014-08-23.
+//  Copyright (c) 2014 Sparkle Project. All rights reserved.
+//
+
+#ifndef SUEXPORT_H
+#define SUEXPORT_H
+
+#ifdef BUILDING_SPARKLE
+#define SU_EXPORT __attribute__((visibility("default")))
+#else
+#define SU_EXPORT
+#endif
+
+#endif
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUStandardVersionComparator.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUStandardVersionComparator.h
new file mode 100644
index 0000000000000000000000000000000000000000..d7f2a48cf20ea050dca886b4dd870fe2a21689ad
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUStandardVersionComparator.h
@@ -0,0 +1,38 @@
+//
+//  SUStandardVersionComparator.h
+//  Sparkle
+//
+//  Created by Andy Matuschak on 12/21/07.
+//  Copyright 2007 Andy Matuschak. All rights reserved.
+//
+
+#ifndef SUSTANDARDVERSIONCOMPARATOR_H
+#define SUSTANDARDVERSIONCOMPARATOR_H
+
+#import <Foundation/Foundation.h>
+#import "SUExport.h"
+#import "SUVersionComparisonProtocol.h"
+
+/*!
+    Sparkle's default version comparator.
+
+    This comparator is adapted from MacPAD, by Kevin Ballard.
+    It's "dumb" in that it does essentially string comparison,
+    in components split by character type.
+*/
+SU_EXPORT @interface SUStandardVersionComparator : NSObject <SUVersionComparison>
+
+/*!
+    Returns a singleton instance of the comparator.
+*/
++ (SUStandardVersionComparator *)defaultComparator;
+
+/*!
+    Compares version strings through textual analysis.
+
+    See the implementation for more details.
+*/
+- (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB;
+@end
+
+#endif
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUUpdater.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUUpdater.h
new file mode 100644
index 0000000000000000000000000000000000000000..ce07a142c40f1a65014e6a3622f75a004c3ec4de
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUUpdater.h
@@ -0,0 +1,347 @@
+//
+//  SUUpdater.h
+//  Sparkle
+//
+//  Created by Andy Matuschak on 1/4/06.
+//  Copyright 2006 Andy Matuschak. All rights reserved.
+//
+
+#ifndef SUUPDATER_H
+#define SUUPDATER_H
+
+#import <Foundation/Foundation.h>
+#import "SUExport.h"
+#import "SUVersionComparisonProtocol.h"
+#import "SUVersionDisplayProtocol.h"
+
+@class SUUpdateDriver, SUAppcastItem, SUHost, SUAppcast;
+
+@protocol SUUpdaterDelegate;
+
+/*!
+    The main API in Sparkle for controlling the update mechanism.
+
+    This class is used to configure the update paramters as well as manually
+    and automatically schedule and control checks for updates.
+ */
+SU_EXPORT @interface SUUpdater : NSObject
+
+@property (unsafe_unretained) IBOutlet id<SUUpdaterDelegate> delegate;
+
++ (SUUpdater *)sharedUpdater;
++ (SUUpdater *)updaterForBundle:(NSBundle *)bundle;
+- (instancetype)initForBundle:(NSBundle *)bundle;
+
+@property (readonly, strong) NSBundle *hostBundle;
+@property (strong, readonly) NSBundle *sparkleBundle;
+
+@property BOOL automaticallyChecksForUpdates;
+
+@property NSTimeInterval updateCheckInterval;
+
+/*!
+ * The URL of the appcast used to download update information.
+ *
+ * This property must be called on the main thread.
+ */
+@property (copy) NSURL *feedURL;
+
+@property (nonatomic, copy) NSString *userAgentString;
+
+@property (copy) NSDictionary *httpHeaders;
+
+@property BOOL sendsSystemProfile;
+
+@property BOOL automaticallyDownloadsUpdates;
+
+/*!
+    Explicitly checks for updates and displays a progress dialog while doing so.
+
+    This method is meant for a main menu item.
+    Connect any menu item to this action in Interface Builder,
+    and Sparkle will check for updates and report back its findings verbosely
+    when it is invoked.
+ */
+- (IBAction)checkForUpdates:(id)sender;
+
+/*!
+    Checks for updates, but does not display any UI unless an update is found.
+
+    This is meant for programmatically initating a check for updates. That is,
+    it will display no UI unless it actually finds an update, in which case it
+    proceeds as usual.
+
+    If the fully automated updating is turned on, however, this will invoke that
+    behavior, and if an update is found, it will be downloaded and prepped for
+    installation.
+ */
+- (void)checkForUpdatesInBackground;
+
+/*!
+    Returns the date of last update check.
+
+    \returns \c nil if no check has been performed.
+ */
+@property (readonly, copy) NSDate *lastUpdateCheckDate;
+
+/*!
+    Begins a "probing" check for updates which will not actually offer to
+    update to that version.
+
+    However, the delegate methods
+    SUUpdaterDelegate::updater:didFindValidUpdate: and
+    SUUpdaterDelegate::updaterDidNotFindUpdate: will be called,
+    so you can use that information in your UI.
+ */
+- (void)checkForUpdateInformation;
+
+/*!
+    Appropriately schedules or cancels 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.
+ */
+- (void)resetUpdateCycle;
+
+@property (readonly) BOOL updateInProgress;
+
+@end
+
+// -----------------------------------------------------------------------------
+// SUUpdater Notifications for events that might be interesting to more than just the delegate
+// The updater will be the notification object
+// -----------------------------------------------------------------------------
+SU_EXPORT extern NSString *const SUUpdaterDidFinishLoadingAppCastNotification;
+SU_EXPORT extern NSString *const SUUpdaterDidFindValidUpdateNotification;
+SU_EXPORT extern NSString *const SUUpdaterDidNotFindUpdateNotification;
+SU_EXPORT extern NSString *const SUUpdaterWillRestartNotification;
+#define SUUpdaterWillRelaunchApplicationNotification SUUpdaterWillRestartNotification;
+#define SUUpdaterWillInstallUpdateNotification SUUpdaterWillRestartNotification;
+
+// Key for the SUAppcastItem object in the SUUpdaterDidFindValidUpdateNotification userInfo
+SU_EXPORT extern NSString *const SUUpdaterAppcastItemNotificationKey;
+// Key for the SUAppcast object in the SUUpdaterDidFinishLoadingAppCastNotification userInfo
+SU_EXPORT extern NSString *const SUUpdaterAppcastNotificationKey;
+
+// -----------------------------------------------------------------------------
+//	SUUpdater Delegate:
+// -----------------------------------------------------------------------------
+
+/*!
+    Provides methods to control the behavior of an SUUpdater object.
+ */
+@protocol SUUpdaterDelegate <NSObject>
+@optional
+
+/*!
+    Returns whether to allow Sparkle to pop up.
+
+    For example, this may be used to prevent Sparkle from interrupting a setup assistant.
+
+    \param updater The SUUpdater instance.
+ */
+- (BOOL)updaterMayCheckForUpdates:(SUUpdater *)updater;
+
+/*!
+    Returns additional parameters to append to the appcast URL's query string.
+
+    This is potentially based on whether or not Sparkle will also be sending along the system profile.
+
+    \param updater The SUUpdater instance.
+    \param sendingProfile Whether the system profile will also be sent.
+
+    \return An array of dictionaries with keys: "key", "value", "displayKey", "displayValue", the latter two being specifically for display to the user.
+ */
+- (NSArray *)feedParametersForUpdater:(SUUpdater *)updater sendingSystemProfile:(BOOL)sendingProfile;
+
+/*!
+    Returns a custom appcast URL.
+
+    Override this to dynamically specify the entire URL.
+
+    \param updater The SUUpdater instance.
+ */
+- (NSString *)feedURLStringForUpdater:(SUUpdater *)updater;
+
+/*!
+    Returns whether Sparkle should prompt the user about automatic update checks.
+
+    Use this to override the default behavior.
+
+    \param updater The SUUpdater instance.
+ */
+- (BOOL)updaterShouldPromptForPermissionToCheckForUpdates:(SUUpdater *)updater;
+
+/*!
+    Called after Sparkle has downloaded the appcast from the remote server.
+
+    Implement this if you want to do some special handling with the appcast once it finishes loading.
+
+    \param updater The SUUpdater instance.
+    \param appcast The appcast that was downloaded from the remote server.
+ */
+- (void)updater:(SUUpdater *)updater didFinishLoadingAppcast:(SUAppcast *)appcast;
+
+/*!
+    Returns the item in the appcast corresponding to the update that should be installed.
+
+    If you're using special logic or extensions in your appcast,
+    implement this to use your own logic for finding a valid update, if any,
+    in the given appcast.
+
+    \param appcast The appcast that was downloaded from the remote server.
+    \param updater The SUUpdater instance.
+ */
+- (SUAppcastItem *)bestValidUpdateInAppcast:(SUAppcast *)appcast forUpdater:(SUUpdater *)updater;
+
+/*!
+    Called when a valid update is found by the update driver.
+
+    \param updater The SUUpdater instance.
+    \param item The appcast item corresponding to the update that is proposed to be installed.
+ */
+- (void)updater:(SUUpdater *)updater didFindValidUpdate:(SUAppcastItem *)item;
+
+/*!
+    Called when a valid update is not found.
+
+    \param updater The SUUpdater instance.
+ */
+- (void)updaterDidNotFindUpdate:(SUUpdater *)updater;
+
+/*!
+    Called immediately before downloading the specified update.
+
+    \param updater The SUUpdater instance.
+    \param item The appcast item corresponding to the update that is proposed to be downloaded.
+    \param request The mutable URL request that will be used to download the update.
+ */
+- (void)updater:(SUUpdater *)updater willDownloadUpdate:(SUAppcastItem *)item withRequest:(NSMutableURLRequest *)request;
+
+/*!
+    Called after the specified update failed to download.
+
+    \param updater The SUUpdater instance.
+    \param item The appcast item corresponding to the update that failed to download.
+    \param error The error generated by the failed download.
+ */
+- (void)updater:(SUUpdater *)updater failedToDownloadUpdate:(SUAppcastItem *)item error:(NSError *)error;
+
+/*!
+    Called immediately before installing the specified update.
+
+    \param updater The SUUpdater instance.
+    \param item The appcast item corresponding to the update that is proposed to be installed.
+ */
+- (void)updater:(SUUpdater *)updater willInstallUpdate:(SUAppcastItem *)item;
+
+/*!
+    Returns whether the relaunch should be delayed in order to perform other tasks.
+
+    This is not called if the user didn't relaunch on the previous update,
+    in that case it will immediately restart.
+
+    \param updater The SUUpdater instance.
+    \param item The appcast item corresponding to the update that is proposed to be installed.
+    \param invocation The invocation that must be completed before continuing with the relaunch.
+
+    \return \c YES to delay the relaunch until \p invocation is invoked.
+ */
+- (BOOL)updater:(SUUpdater *)updater shouldPostponeRelaunchForUpdate:(SUAppcastItem *)item untilInvoking:(NSInvocation *)invocation;
+
+/*!
+    Returns whether the application should be relaunched at all.
+
+    Some apps \b cannot be relaunched under certain circumstances.
+    This method can be used to explicitly prevent a relaunch.
+
+    \param updater The SUUpdater instance.
+ */
+- (BOOL)updaterShouldRelaunchApplication:(SUUpdater *)updater;
+
+/*!
+    Called immediately before relaunching.
+
+    \param updater The SUUpdater instance.
+ */
+- (void)updaterWillRelaunchApplication:(SUUpdater *)updater;
+
+/*!
+    Returns an object that compares version numbers to determine their arithmetic relation to each other.
+
+    This method allows you to provide a custom version comparator.
+    If you don't implement this method or return \c nil,
+    the standard version comparator will be used.
+
+    \sa SUStandardVersionComparator
+
+    \param updater The SUUpdater instance.
+ */
+- (id<SUVersionComparison>)versionComparatorForUpdater:(SUUpdater *)updater;
+
+/*!
+    Returns an object that formats version numbers for display to the user.
+
+    If you don't implement this method or return \c nil,
+    the standard version formatter will be used.
+
+    \sa SUUpdateAlert
+
+    \param updater The SUUpdater instance.
+ */
+- (id<SUVersionDisplay>)versionDisplayerForUpdater:(SUUpdater *)updater;
+
+/*!
+    Returns the path which is used to relaunch the client after the update is installed.
+
+    The default is the path of the host bundle.
+
+    \param updater The SUUpdater instance.
+ */
+- (NSString *)pathToRelaunchForUpdater:(SUUpdater *)updater;
+
+/*!
+    Called before an updater shows a modal alert window,
+    to give the host the opportunity to hide attached windows that may get in the way.
+
+    \param updater The SUUpdater instance.
+ */
+- (void)updaterWillShowModalAlert:(SUUpdater *)updater;
+
+/*!
+    Called after an updater shows a modal alert window,
+    to give the host the opportunity to hide attached windows that may get in the way.
+
+    \param updater The SUUpdater instance.
+ */
+- (void)updaterDidShowModalAlert:(SUUpdater *)updater;
+
+/*!
+    Called when an update is scheduled to be silently installed on quit.
+
+    \param updater The SUUpdater instance.
+    \param item The appcast item corresponding to the update that is proposed to be installed.
+    \param invocation Can be used to trigger an immediate silent install and relaunch.
+ */
+- (void)updater:(SUUpdater *)updater willInstallUpdateOnQuit:(SUAppcastItem *)item immediateInstallationInvocation:(NSInvocation *)invocation;
+
+/*!
+    Calls after an update that was scheduled to be silently installed on quit has been canceled.
+
+    \param updater The SUUpdater instance.
+    \param item The appcast item corresponding to the update that was proposed to be installed.
+ */
+- (void)updater:(SUUpdater *)updater didCancelInstallUpdateOnQuit:(SUAppcastItem *)item;
+
+/*!
+    Called after an update is aborted due to an error.
+
+    \param updater The SUUpdater instance.
+    \param error The error that caused the abort
+ */
+- (void)updater:(SUUpdater *)updater didAbortWithError:(NSError *)error;
+
+@end
+
+#endif
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h
new file mode 100644
index 0000000000000000000000000000000000000000..10c4266946bc7d40ce00761204ec41ee4e8cd37b
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUVersionComparisonProtocol.h
@@ -0,0 +1,30 @@
+//
+//  SUVersionComparisonProtocol.h
+//  Sparkle
+//
+//  Created by Andy Matuschak on 12/21/07.
+//  Copyright 2007 Andy Matuschak. All rights reserved.
+//
+
+#ifndef SUVERSIONCOMPARISONPROTOCOL_H
+#define SUVERSIONCOMPARISONPROTOCOL_H
+
+#import <Cocoa/Cocoa.h>
+#import "SUExport.h"
+
+/*!
+    Provides version comparison facilities for Sparkle.
+*/
+@protocol SUVersionComparison
+
+/*!
+    An abstract method to compare two version strings.
+
+    Should return NSOrderedAscending if b > a, NSOrderedDescending if b < a,
+    and NSOrderedSame if they are equivalent.
+*/
+- (NSComparisonResult)compareVersion:(NSString *)versionA toVersion:(NSString *)versionB; // *** MAY BE CALLED ON NON-MAIN THREAD!
+
+@end
+
+#endif
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUVersionDisplayProtocol.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUVersionDisplayProtocol.h
new file mode 100644
index 0000000000000000000000000000000000000000..97fae4c9096aa2b3eed92422a7aff1adde730f9d
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/SUVersionDisplayProtocol.h
@@ -0,0 +1,25 @@
+//
+//  SUVersionDisplayProtocol.h
+//  EyeTV
+//
+//  Created by Uli Kusterer on 08.12.09.
+//  Copyright 2009 Elgato Systems GmbH. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+#import "SUExport.h"
+
+/*!
+    Applies special display formatting to version numbers.
+*/
+@protocol SUVersionDisplay
+
+/*!
+    Formats two version strings.
+
+    Both versions are provided so that important distinguishing information
+    can be displayed while also leaving out unnecessary/confusing parts.
+*/
+- (void)formatVersion:(NSString **)inOutVersionA andVersion:(NSString **)inOutVersionB;
+
+@end
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/Sparkle.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/Sparkle.h
new file mode 100644
index 0000000000000000000000000000000000000000..7b48206441e70dd6e416c2492312893c308d6668
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Headers/Sparkle.h
@@ -0,0 +1,25 @@
+//
+//  Sparkle.h
+//  Sparkle
+//
+//  Created by Andy Matuschak on 3/16/06. (Modified by CDHW on 23/12/07)
+//  Copyright 2006 Andy Matuschak. All rights reserved.
+//
+
+#ifndef SPARKLE_H
+#define SPARKLE_H
+
+#import <Cocoa/Cocoa.h>
+
+// This list should include the shared headers. It doesn't matter if some of them aren't shared (unless
+// there are name-space collisions) so we can list all of them to start with:
+
+#import <Sparkle/SUAppcast.h>
+#import <Sparkle/SUAppcastItem.h>
+#import <Sparkle/SUStandardVersionComparator.h>
+#import <Sparkle/SUUpdater.h>
+#import <Sparkle/SUVersionComparisonProtocol.h>
+#import <Sparkle/SUVersionDisplayProtocol.h>
+#import <Sparkle/SUErrors.h>
+
+#endif
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Modules/module.modulemap b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Modules/module.modulemap
new file mode 100644
index 0000000000000000000000000000000000000000..af3fe6d05057de908fc235c400deeb27f1871472
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Modules/module.modulemap
@@ -0,0 +1,6 @@
+framework module Sparkle {
+  umbrella header "Sparkle.h"
+
+  export *
+  module * { export * }
+}
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/PrivateHeaders/SUUnarchiver.h b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/PrivateHeaders/SUUnarchiver.h
new file mode 100644
index 0000000000000000000000000000000000000000..6397fe71a1371d258b7995117636a48bfdc811a9
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/PrivateHeaders/SUUnarchiver.h
@@ -0,0 +1,35 @@
+//
+//  SUUnarchiver.h
+//  Sparkle
+//
+//  Created by Andy Matuschak on 3/16/06.
+//  Copyright 2006 Andy Matuschak. All rights reserved.
+//
+
+#ifndef SUUNARCHIVER_H
+#define SUUNARCHIVER_H
+
+#import <Foundation/Foundation.h>
+
+@class SUHost;
+@protocol SUUnarchiverDelegate;
+
+@interface SUUnarchiver : NSObject
+
+@property (copy, readonly) NSString *archivePath;
+@property (copy, readonly) NSString *updateHostBundlePath;
+@property (weak) id<SUUnarchiverDelegate> delegate;
+
++ (SUUnarchiver *)unarchiverForPath:(NSString *)path updatingHostBundlePath:(NSString *)host;
+
+- (void)start;
+@end
+
+@protocol SUUnarchiverDelegate <NSObject>
+- (void)unarchiverDidFinish:(SUUnarchiver *)unarchiver;
+- (void)unarchiverDidFail:(SUUnarchiver *)unarchiver;
+@optional
+- (void)unarchiver:(SUUnarchiver *)unarchiver extractedProgress:(double)progress;
+@end
+
+#endif
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Info.plist b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Info.plist
new file mode 100644
index 0000000000000000000000000000000000000000..571db4f58c238399edb21bd4e2cf15be00beef49
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Info.plist
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>BuildMachineOSBuild</key>
+	<string>15A244d</string>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>Autoupdate</string>
+	<key>CFBundleIconFile</key>
+	<string>AppIcon</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.sparkle-project.Sparkle.Autoupdate</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.11.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleSupportedPlatforms</key>
+	<array>
+		<string>MacOSX</string>
+	</array>
+	<key>CFBundleVersion</key>
+	<string>1.11.0</string>
+	<key>DTCompiler</key>
+	<string>com.apple.compilers.llvm.clang.1_0</string>
+	<key>DTPlatformBuild</key>
+	<string>7A176x</string>
+	<key>DTPlatformVersion</key>
+	<string>GM</string>
+	<key>DTSDKBuild</key>
+	<string>15A244e</string>
+	<key>DTSDKName</key>
+	<string>macosx10.11</string>
+	<key>DTXcode</key>
+	<string>0700</string>
+	<key>DTXcodeBuild</key>
+	<string>7A176x</string>
+	<key>LSBackgroundOnly</key>
+	<string>1</string>
+	<key>LSMinimumSystemVersion</key>
+	<string>10.7</string>
+	<key>LSUIElement</key>
+	<string>1</string>
+	<key>NSMainNibFile</key>
+	<string>MainMenu</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+</dict>
+</plist>
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/Autoupdate b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/Autoupdate
new file mode 100755
index 0000000000000000000000000000000000000000..f4bfb8bef6f9df0f9e5997580cd68368c7f37e53
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/MacOS/Autoupdate differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/PkgInfo b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/PkgInfo
new file mode 100644
index 0000000000000000000000000000000000000000..bd04210fb49f6032c3cd79559334dbe735a998ef
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/PkgInfo
@@ -0,0 +1 @@
+APPL????
\ No newline at end of file
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/AppIcon.icns b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/AppIcon.icns
new file mode 100644
index 0000000000000000000000000000000000000000..75c7c379f94c38d64cb160da894f3f41149cc34b
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/AppIcon.icns differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/SUStatus.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/SUStatus.nib
new file mode 100644
index 0000000000000000000000000000000000000000..30f3c2c4d1f6e3a63dd1df160ac5abec8443ced8
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/SUStatus.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ar.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ar.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..28c2c217250892ca0e65bc1b3a11c272d94626a5
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ar.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/cs.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/cs.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..a50d6bf22a8381a741c2e0dbceb1d7d913330728
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/cs.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/da.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/da.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..8c349bd2b6c3302472c4b7c9738901e4eb388c78
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/da.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/de.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/de.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..fe50db5ca4d53df244a939041e8ef0c903b4124b
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/de.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/el.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/el.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..015c213ecf1f8fb449bdde13cae26c1f6bb2082c
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/el.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/en.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/en.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..d3c9f217d6a7b82cafe0579fdd659a1505d54acb
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/en.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/es.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/es.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..ee694079466290bb0a9a2ec01e38d2d8b8bea0e4
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/es.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fr.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fr.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..c7b221b12b2be92af6c5e97c70f754481fbb73e9
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/fr.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/is.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/is.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..68ae6e0ae7b71ed89581d779caaedd8a27c39f3e
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/is.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/it.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/it.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..99955afc5a20cc0ce4ba3e6415334bf307a5cf50
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/it.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ja.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ja.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..faa546c86d66b947157270fe6bab01f99bbde633
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ja.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ko.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ko.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..d5df79da54e5b1a0b5850553a86644c34a5a3fd2
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ko.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nb.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nb.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..05a426d15c2900c117e662f8d7828db5fdde0b88
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nb.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nl.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nl.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..95923ee0bb2689fc1a3808b5394e0b9ea840bbec
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/nl.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pl.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pl.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..d10801f5374464fd452424211f52104398815aaa
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pl.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_BR.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_BR.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..088cde6c2386511460fcf3235e39f340d4712636
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_BR.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_PT.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_PT.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..69853a3f0a90f5e617036231e4d5e808007ec080
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/pt_PT.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ro.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ro.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..3cd694d59dd3db13f47bfbe6088b7aba34852e58
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ro.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ru.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ru.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..349f17fe3f5721bad05c7b7289fea17d4e52b0f8
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/ru.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sk.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sk.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..38bb70dd077a32ecd7c70e465d06efb06b38ef84
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sk.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sl.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sl.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..889a6583e1f7ad676dfdebbb2ba680c97ddd2a70
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sl.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sv.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sv.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..e7e93079a70418c1d16bf1af6aaf208350d3dfa8
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/sv.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/th.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/th.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..323bb70feb0c74f4bf25201586984df03b1491e8
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/th.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/tr.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/tr.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..74e17e44434dfae170ba9bcac2173c92cdaaf4d9
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/tr.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/uk.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/uk.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..bf13d969296e651f021a72bdd8e588952d9b209b
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/uk.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_CN.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_CN.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..49b68ce1e7b697bcefff97f7a62b6ca8365c74a9
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_CN.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_TW.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_TW.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..d9229c96f1bc77843ea6d800e8f4a4f74e986078
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Autoupdate.app/Contents/Resources/zh_TW.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Info.plist b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Info.plist
new file mode 100644
index 0000000000000000000000000000000000000000..076941d5fff571ddd5a51dda5f2fb61756da33da
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/Info.plist
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>BuildMachineOSBuild</key>
+	<string>15A244d</string>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>en</string>
+	<key>CFBundleExecutable</key>
+	<string>Sparkle</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.andymatuschak.Sparkle</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>Sparkle</string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.11.0</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleSupportedPlatforms</key>
+	<array>
+		<string>MacOSX</string>
+	</array>
+	<key>CFBundleVersion</key>
+	<string>1.11.0</string>
+	<key>DTCompiler</key>
+	<string>com.apple.compilers.llvm.clang.1_0</string>
+	<key>DTPlatformBuild</key>
+	<string>7A176x</string>
+	<key>DTPlatformVersion</key>
+	<string>GM</string>
+	<key>DTSDKBuild</key>
+	<string>15A244e</string>
+	<key>DTSDKName</key>
+	<string>macosx10.11</string>
+	<key>DTXcode</key>
+	<string>0700</string>
+	<key>DTXcodeBuild</key>
+	<string>7A176x</string>
+</dict>
+</plist>
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist
new file mode 100644
index 0000000000000000000000000000000000000000..74db0ff07f8633e63dfce24340a89b87f255e489
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/SUModelTranslation.plist
@@ -0,0 +1,228 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>ADP2,1</key>
+	<string>Developer Transition Kit</string>
+	<key>iMac1,1</key>
+	<string>iMac G3 (Rev A-D)</string>
+	<key>iMac4,1</key>
+	<string>iMac (Core Duo)</string>
+	<key>iMac4,2</key>
+	<string>iMac for Education (17 inch, Core Duo)</string>
+	<key>iMac5,1</key>
+	<string>iMac (Core 2 Duo, 17 or 20 inch, SuperDrive)</string>
+	<key>iMac5,2</key>
+	<string>iMac (Core 2 Duo, 17 inch, Combo Drive)</string>
+	<key>iMac6,1</key>
+	<string>iMac (Core 2 Duo, 24 inch, SuperDrive)</string>
+	<key>iMac8,1</key>
+	<string>iMac (Core 2 Duo, 20 or 24 inch, Early 2008 )</string>
+	<key>iMac9,1</key>
+	<string>iMac (Core 2 Duo, 20 or 24 inch, Early or Mid 2009 )</string>
+	<key>iMac10,1</key>
+	<string>iMac (Core 2 Duo, 21.5 or 27 inch, Late 2009 )</string>
+	<key>iMac11,1</key>
+	<string>iMac (Core i5 or i7, 27 inch Late 2009)</string>
+	<key>iMac11,2</key>
+	<string>iMac (Core i3 or i5, 27 inch Mid 2010)</string>
+	<key>iMac11,3</key>
+	<string>iMac (Core i5 or i7, 27 inch Mid 2010)</string>
+	<key>iMac12,1</key>
+	<string>iMac (Core i3 or i5 or i7, 21.5 inch Mid 2010 or Late 2011)</string>
+	<key>iMac12,2</key>
+	<string>iMac (Core i5 or i7, 27 inch Mid 2011)</string>
+	<key>iMac13,1</key>
+	<string>iMac (Core i3 or i5 or i7, 21.5 inch Late 2012 or Early 2013)</string>
+	<key>iMac13,2</key>
+	<string>iMac (Core i5 or i7, 27 inch Late 2012)</string>
+	<key>iMac14,1</key>
+	<string>iMac (Core i5, 21.5 inch Late 2013)</string>
+	<key>iMac14,2</key>
+	<string>iMac (Core i5 or i7, 27 inch Late 2013)</string>
+	<key>iMac14,3</key>
+	<string>iMac (Core i5 or i7, 21.5 inch Late 2013)</string>
+	<key>MacBook1,1</key>
+	<string>MacBook (Core Duo)</string>
+	<key>MacBook2,1</key>
+	<string>MacBook (Core 2 Duo)</string>
+	<key>MacBook4,1</key>
+	<string>MacBook (Core 2 Duo Feb 2008)</string>
+	<key>MacBook5,1</key>
+	<string>MacBook (Core 2 Duo, Late 2008, Unibody)</string>
+	<key>MacBook5,2</key>
+	<string>MacBook (Core 2 Duo, Early 2009, White)</string>
+	<key>MacBook6,1</key>
+	<string>MacBook (Core 2 Duo, Late 2009, Unibody)</string>
+	<key>MacBook7,1</key>
+	<string>MacBook (Core 2 Duo, Mid 2010, White)</string>
+	<key>MacBookAir1,1</key>
+	<string>MacBook Air (Core 2 Duo, 13 inch, Early 2008)</string>
+	<key>MacBookAir2,1</key>
+	<string>MacBook Air (Core 2 Duo, 13 inch, Mid 2009)</string>
+	<key>MacBookAir3,1</key>
+	<string>MacBook Air (Core 2 Duo, 11 inch, Late 2010)</string>
+	<key>MacBookAir3,2</key>
+	<string>MacBook Air (Core 2 Duo, 13 inch, Late 2010)</string>
+	<key>MacBookAir4,1</key>
+	<string>MacBook Air (Core i5 or i7, 11 inch, Mid 2011)</string>
+	<key>MacBookAir4,2</key>
+	<string>MacBook Air (Core i5 or i7, 13 inch, Mid 2011)</string>
+	<key>MacBookAir5,1</key>
+	<string>MacBook Air (Core i5 or i7, 11 inch, Mid 2012)</string>
+	<key>MacBookAir5,2</key>
+	<string>MacBook Air (Core i5 or i7, 13 inch, Mid 2012)</string>
+	<key>MacBookAir6,1</key>
+	<string>MacBook Air (Core i5 or i7, 11 inch, Mid 2013 or Early 2014)</string>
+	<key>MacBookAir6,2</key>
+	<string>MacBook Air (Core i5 or i7, 13 inch, Mid 2013 or Early 2014)</string>
+	<key>MacBookPro1,1</key>
+	<string>MacBook Pro Core Duo (15-inch)</string>
+	<key>MacBookPro1,2</key>
+	<string>MacBook Pro Core Duo (17-inch)</string>
+	<key>MacBookPro2,1</key>
+	<string>MacBook Pro Core 2 Duo (17-inch)</string>
+	<key>MacBookPro2,2</key>
+	<string>MacBook Pro Core 2 Duo (15-inch)</string>
+	<key>MacBookPro3,1</key>
+	<string>MacBook Pro Core 2 Duo (15-inch LED, Core 2 Duo)</string>
+	<key>MacBookPro3,2</key>
+	<string>MacBook Pro Core 2 Duo (17-inch HD, Core 2 Duo)</string>
+	<key>MacBookPro4,1</key>
+	<string>MacBook Pro (Core 2 Duo Feb 2008)</string>
+	<key>Macmini1,1</key>
+	<string>Mac Mini (Core Solo/Duo)</string>
+	<key>MacPro1,1</key>
+	<string>Mac Pro (four-core)</string>
+	<key>MacPro2,1</key>
+	<string>Mac Pro (eight-core)</string>
+	<key>MacPro3,1</key>
+	<string>Mac Pro (January 2008 4- or 8- core &quot;Harpertown&quot;)</string>
+	<key>MacPro4,1</key>
+	<string>Mac Pro (March 2009)</string>
+	<key>MacPro5,1</key>
+	<string>Mac Pro (August 2010)</string>
+	<key>PowerBook1,1</key>
+	<string>PowerBook G3</string>
+	<key>PowerBook2,1</key>
+	<string>iBook G3</string>
+	<key>PowerBook2,2</key>
+	<string>iBook G3 (FireWire)</string>
+	<key>PowerBook2,3</key>
+	<string>iBook G3</string>
+	<key>PowerBook2,4</key>
+	<string>iBook G3</string>
+	<key>PowerBook3,1</key>
+	<string>PowerBook G3 (FireWire)</string>
+	<key>PowerBook3,2</key>
+	<string>PowerBook G4</string>
+	<key>PowerBook3,3</key>
+	<string>PowerBook G4 (Gigabit Ethernet)</string>
+	<key>PowerBook3,4</key>
+	<string>PowerBook G4 (DVI)</string>
+	<key>PowerBook3,5</key>
+	<string>PowerBook G4 (1GHz / 867MHz)</string>
+	<key>PowerBook4,1</key>
+	<string>iBook G3 (Dual USB, Late 2001)</string>
+	<key>PowerBook4,2</key>
+	<string>iBook G3 (16MB VRAM)</string>
+	<key>PowerBook4,3</key>
+	<string>iBook G3 Opaque 16MB VRAM, 32MB VRAM, Early 2003)</string>
+	<key>PowerBook5,1</key>
+	<string>PowerBook G4 (17 inch)</string>
+	<key>PowerBook5,2</key>
+	<string>PowerBook G4 (15 inch FW 800)</string>
+	<key>PowerBook5,3</key>
+	<string>PowerBook G4 (17-inch 1.33GHz)</string>
+	<key>PowerBook5,4</key>
+	<string>PowerBook G4 (15 inch 1.5/1.33GHz)</string>
+	<key>PowerBook5,5</key>
+	<string>PowerBook G4 (17-inch 1.5GHz)</string>
+	<key>PowerBook5,6</key>
+	<string>PowerBook G4 (15 inch 1.67GHz/1.5GHz)</string>
+	<key>PowerBook5,7</key>
+	<string>PowerBook G4 (17-inch 1.67GHz)</string>
+	<key>PowerBook5,8</key>
+	<string>PowerBook G4 (Double layer SD, 15 inch)</string>
+	<key>PowerBook5,9</key>
+	<string>PowerBook G4 (Double layer SD, 17 inch)</string>
+	<key>PowerBook6,1</key>
+	<string>PowerBook G4 (12 inch)</string>
+	<key>PowerBook6,2</key>
+	<string>PowerBook G4 (12 inch, DVI)</string>
+	<key>PowerBook6,3</key>
+	<string>iBook G4</string>
+	<key>PowerBook6,4</key>
+	<string>PowerBook G4 (12 inch 1.33GHz)</string>
+	<key>PowerBook6,5</key>
+	<string>iBook G4 (Early-Late 2004)</string>
+	<key>PowerBook6,7</key>
+	<string>iBook G4 (Mid 2005)</string>
+	<key>PowerBook6,8</key>
+	<string>PowerBook G4 (12 inch 1.5GHz)</string>
+	<key>PowerMac1,1</key>
+	<string>Power Macintosh G3 (Blue &amp; White)</string>
+	<key>PowerMac1,2</key>
+	<string>Power Macintosh G4 (PCI Graphics)</string>
+	<key>PowerMac10,1</key>
+	<string>Mac Mini G4</string>
+	<key>PowerMac10,2</key>
+	<string>Mac Mini (Late 2005)</string>
+	<key>PowerMac11,2</key>
+	<string>Power Macintosh G5 (Late 2005)</string>
+	<key>PowerMac12,1</key>
+	<string>iMac G5 (iSight)</string>
+	<key>PowerMac2,1</key>
+	<string>iMac G3 (Slot-loading CD-ROM)</string>
+	<key>PowerMac2,2</key>
+	<string>iMac G3 (Summer 2000)</string>
+	<key>PowerMac3,1</key>
+	<string>Power Macintosh G4 (AGP Graphics)</string>
+	<key>PowerMac3,2</key>
+	<string>Power Macintosh G4 (AGP Graphics)</string>
+	<key>PowerMac3,3</key>
+	<string>Power Macintosh G4 (Gigabit Ethernet)</string>
+	<key>PowerMac3,4</key>
+	<string>Power Macintosh G4 (Digital Audio)</string>
+	<key>PowerMac3,5</key>
+	<string>Power Macintosh G4 (Quick Silver)</string>
+	<key>PowerMac3,6</key>
+	<string>Power Macintosh G4 (Mirrored Drive Door)</string>
+	<key>PowerMac4,1</key>
+	<string>iMac G3 (Early/Summer 2001)</string>
+	<key>PowerMac4,2</key>
+	<string>iMac G4 (Flat Panel)</string>
+	<key>PowerMac4,4</key>
+	<string>eMac</string>
+	<key>PowerMac4,5</key>
+	<string>iMac G4 (17-inch Flat Panel)</string>
+	<key>PowerMac5,1</key>
+	<string>Power Macintosh G4 Cube</string>
+	<key>PowerMac6,1</key>
+	<string>iMac G4 (USB 2.0)</string>
+	<key>PowerMac6,3</key>
+	<string>iMac G4 (20-inch Flat Panel)</string>
+	<key>PowerMac6,4</key>
+	<string>eMac (USB 2.0, 2005)</string>
+	<key>PowerMac7,2</key>
+	<string>Power Macintosh G5</string>
+	<key>PowerMac7,3</key>
+	<string>Power Macintosh G5</string>
+	<key>PowerMac8,1</key>
+	<string>iMac G5</string>
+	<key>PowerMac8,2</key>
+	<string>iMac G5 (Ambient Light Sensor)</string>
+	<key>PowerMac9,1</key>
+	<string>Power Macintosh G5 (Late 2005)</string>
+	<key>RackMac1,1</key>
+	<string>Xserve G4</string>
+	<key>RackMac1,2</key>
+	<string>Xserve G4 (slot-loading, cluster node)</string>
+	<key>RackMac3,1</key>
+	<string>Xserve G5</string>
+	<key>Xserve1,1</key>
+	<string>Xserve (Intel Xeon)</string>
+	<key>Xserve2,1</key>
+	<string>Xserve (January 2008 quad-core)</string>
+</dict>
+</plist>
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/SUStatus.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/SUStatus.nib
new file mode 100644
index 0000000000000000000000000000000000000000..30f3c2c4d1f6e3a63dd1df160ac5abec8443ced8
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/SUStatus.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..0cf1e265080c12b7bb2389fefec8b0c6a24b88fe
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..e8f0030650d80acf990fb0255fbd427ccf1ba5db
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..108e6874c910e657fe8bdcbcb1340247c5d3aa7c
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..28c2c217250892ca0e65bc1b3a11c272d94626a5
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ar.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..fcc6a46fc9cc82425fead6472d02cf1ab2195680
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..74c8abc63bad07200e4c920a8063880c214fea8a
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..53d7446a68ea650c75ad38bf7e7b2f16a0e98b24
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..a50d6bf22a8381a741c2e0dbceb1d7d913330728
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/cs.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..60949aadf189ac984bbeaf4a37c2630a36c10225
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..f514a4a01a2a9043db1c463cab51aa1d17a780ed
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..a2a56b975989518edf08c9b1f8d7b4ab585e5e32
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..8c349bd2b6c3302472c4b7c9738901e4eb388c78
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/da.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..204098fc18f0926e7960f1d941afae862c171a04
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..c97a4406cf0690212fec612e1ed8dcdf3081902a
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..d62b5720e806a5056f4e8b8ebc7977dfc373083d
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..fe50db5ca4d53df244a939041e8ef0c903b4124b
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/de.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..ed654db41e6ff1182d706205c57bdb8d0b06cc72
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..45c7fde67eb9142223f9ba1cf1e89ecf379ae12c
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..b79f6bedb59c785fe0de33d95af729111725c10b
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..015c213ecf1f8fb449bdde13cae26c1f6bb2082c
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/el.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..df090b491f3131ac3c4653777badcc9b988c4f8a
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..087db77607a6b71cbd20b84f74195ffa359a945e
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..76a955118b2bc4e4ea99059a3223645ce780d535
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..d3c9f217d6a7b82cafe0579fdd659a1505d54acb
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/en.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..6018bc31e1c93456680f4a4ccf24e3ce12d90111
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..c35ca148e48d020cf17d5c978de377ff759695ab
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..e6df30cd7d1d2a3d8f9e1387369af0b9ecce2675
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..ee694079466290bb0a9a2ec01e38d2d8b8bea0e4
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/es.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..5b0007f0bb463ed4c093d305bbe2ce13752e715d
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..7ed6802064ebdeff19d8d7cdb5bedf225bb82024
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..f7f8a502e9ced683e1de838232fccb06b74503f1
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..c7b221b12b2be92af6c5e97c70f754481fbb73e9
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr_CA.lproj b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr_CA.lproj
new file mode 120000
index 0000000000000000000000000000000000000000..f9834a395ef84f59827ee1aea933b0d15ff52b9d
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/fr_CA.lproj
@@ -0,0 +1 @@
+fr.lproj
\ No newline at end of file
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..358d5e11617c3ac25ba9bd31a958601d261816dd
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..8cb4382ddd62810498119622d12b3ccf1a0ed3db
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..c7de27e606431d7d70929bf1832438c46dd301fa
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..68ae6e0ae7b71ed89581d779caaedd8a27c39f3e
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/is.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..d1f21da26c9c6d5a5e71ed65b91272b2757dd743
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..748e39cf661a1a4fa245e3c3a38bd7909ac864d0
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..2423538c9171ce8842f554e6f7fcd5fce3741951
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..99955afc5a20cc0ce4ba3e6415334bf307a5cf50
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/it.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..6cdc3d7a8c7b6f1c054fa0c8f488485c59ff325a
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..a3a92c80c4acca875bacb8445c5e8da8cb62dada
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..f7b43953b5e047ff1aa61e9ee2422485345d377f
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..faa546c86d66b947157270fe6bab01f99bbde633
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ja.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..fc4b0835003b82fb98d56660692ec38e20f30291
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..5ba7d96003075961749b68d5827a417f096c011b
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..6d570e8a6ea349f18c48964037a83361778cff3b
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..d5df79da54e5b1a0b5850553a86644c34a5a3fd2
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ko.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..5cca23d547be972f4235374ed602c36804201a16
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..3ba201625f768df920072dfe7535f397b9ef595e
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..5f5d1e84aa6bd225536fc05cb8e6b1f92add3c5e
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..05a426d15c2900c117e662f8d7828db5fdde0b88
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nb.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..546cc918f037700861a3f1540b531a4bfc1de661
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..3e13b051366ed95c050fca02d8da9288a51e8168
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..8e2e548d874c0364b3f05345a5cb52ac57a22ac3
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..95923ee0bb2689fc1a3808b5394e0b9ea840bbec
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/nl.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..0bd403784257ab43281c77ba283d86053859f658
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..cc0943561b9501c1c499a2f69b79bdd6d541a6da
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..c8afe6d30f9f6fd9f29615d5c557b188290f3baf
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..d10801f5374464fd452424211f52104398815aaa
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pl.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt.lproj b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt.lproj
new file mode 120000
index 0000000000000000000000000000000000000000..3c1c9f6dced30c7e4b955e9cef3ee89121cf4039
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt.lproj
@@ -0,0 +1 @@
+pt_BR.lproj
\ No newline at end of file
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..1b5f6fca03615b64041713c442a753b559c25b86
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..f7c89b10682581875acfa996dced4eac30227604
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..0ce70b351c2f9db0142658393173afa68e56a31b
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..088cde6c2386511460fcf3235e39f340d4712636
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_BR.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..bd666f7a489824747a4a53c5dc10a832b81bb6fd
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..ae56a6a938bf89e3523887b807ccc45a8c514d9c
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..9a85d7c00662755f9a285d9c0fd4a3df474d7d65
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..69853a3f0a90f5e617036231e4d5e808007ec080
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/pt_PT.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..88b32fbab3640fb5027223c9a2d0e6b94de5cbda
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..f43e74488866e9d954c76456f31bae657329f32e
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..461bed272882ea3fe6fe69ed69625491154117c9
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..3cd694d59dd3db13f47bfbe6088b7aba34852e58
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ro.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..e94b704cc26a8bde13b46fce02810c9d2e4724bc
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..97cf27df6664f958e78371322ba45419a8191661
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..f6d7e72be44fca63c8d23d1be52027d6d11dcff3
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..349f17fe3f5721bad05c7b7289fea17d4e52b0f8
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/ru.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..194aaddcc549a76f690fffa0dc4b2c6e24290706
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..75f58b014ea16199e87ef8b5fbc80beaffbb39bc
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..e94310794d29eb036075536b036e085fc02fda19
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..38bb70dd077a32ecd7c70e465d06efb06b38ef84
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sk.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..6be828178ff6e39f56fdcb082c98c2cd26ccfc0c
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..e44ecfc390cc744be496f84887af3d171ff115a6
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..8beb43e905540d297b8ed775b63b3936a41e748c
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..889a6583e1f7ad676dfdebbb2ba680c97ddd2a70
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sl.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..7e45d9c96e048a974e41eb3b8fba9bf02b033113
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..0c65ace7ad08bbbb2666ef7c011e3713e77cc924
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..d702ceeb48dd4d22c96081591c05b051f8b424d0
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..e7e93079a70418c1d16bf1af6aaf208350d3dfa8
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/sv.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..87c65eccde76b7a046260adfa273ddb9d2d8a776
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..416a939a075bb932cd761684cbdc226837d3669e
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..0276fc871fb4810b83b19a4bb7ba61c808f84bc5
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..323bb70feb0c74f4bf25201586984df03b1491e8
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/th.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..ce6d2c5435458fbdbd8c9328962163e5229fc76b
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..cbe48023c4fb06bd09aac499b0150a6b51df6eb1
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..8265ea9903c288a1db24f27728eb95cee526891a
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..74e17e44434dfae170ba9bcac2173c92cdaaf4d9
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/tr.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..2c9a7015b0a3cc2b7bc91a676954a35884484ad3
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..855d4ad77459fc19f747a1444a52f43925131ca5
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..016c70cf9a123040cb81818a2e598a3af30495ff
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..bf13d969296e651f021a72bdd8e588952d9b209b
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/uk.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..501e425d2f5dcf0c9df915d72686736a31608328
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..73a07091e7252975a0045d76a705dc285ec1dd21
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..13cb106377f79b72bcd06272c56661fd79e37e6d
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..49b68ce1e7b697bcefff97f7a62b6ca8365c74a9
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_CN.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..24b24885716d495cd5977cf30d5eac7deaaec3dc
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUAutomaticUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdateAlert.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdateAlert.nib
new file mode 100644
index 0000000000000000000000000000000000000000..c8bc317cbc49148002c40692d876db6afc58fde5
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdateAlert.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdatePermissionPrompt.nib b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdatePermissionPrompt.nib
new file mode 100644
index 0000000000000000000000000000000000000000..e7f8dc9a003f0fa24edb6a570102e1956037c202
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/SUUpdatePermissionPrompt.nib differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/Sparkle.strings b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/Sparkle.strings
new file mode 100644
index 0000000000000000000000000000000000000000..d9229c96f1bc77843ea6d800e8f4a4f74e986078
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Resources/zh_TW.lproj/Sparkle.strings differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Sparkle b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Sparkle
new file mode 100755
index 0000000000000000000000000000000000000000..df9881628edff3be9186c88cc14ea57a43a32d1a
Binary files /dev/null and b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/A/Sparkle differ
diff --git a/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/Current b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/Current
new file mode 120000
index 0000000000000000000000000000000000000000..8c7e5a667f1b771847fe88c01c3de34413a1b220
--- /dev/null
+++ b/OSX/Vendor/Sparkle-1.11.0/Sparkle.framework/Versions/Current
@@ -0,0 +1 @@
+A
\ No newline at end of file
diff --git a/bin/Metabase/Util.pm b/bin/Metabase/Util.pm
new file mode 100644
index 0000000000000000000000000000000000000000..43b57849df7f2f072ed48c99055072c0a77bc294
--- /dev/null
+++ b/bin/Metabase/Util.pm
@@ -0,0 +1,77 @@
+use strict;
+use warnings;
+
+package Metabase::Util;
+
+use Cwd 'getcwd';
+use Exporter;
+use JSON;
+use Term::ANSIColor qw(:constants);
+
+our @ISA = qw(Exporter);
+our @EXPORT = qw(config
+                 announce
+                 print_giant_success_banner
+                 get_file_or_die
+                 plist_buddy_exec
+                 OSX_ARTIFACTS_DIR
+                 artifact);
+
+my $config_file = getcwd() . '/bin/config.json';
+die "Missing config file: $config_file\n" .
+    "Please copy $config_file.template, and edit it as needed before proceeding.\n"
+    unless (-e $config_file);
+my $config = from_json(`cat $config_file`);
+
+sub config {
+    return $config->{ $_[0] };
+}
+
+sub announce {
+    print "\n\n" . GREEN . $_[0] . RESET . "\n\n";
+}
+
+sub print_giant_success_banner {
+    print "\n\n". BLUE .
+        '+----------------------------------------------------------------------+' . "\n" .
+        '|                                                                      |' . "\n" .
+        '|   _______           _______  _______  _______  _______  _______  _   |' . "\n" .
+        '|  (  ____ \|\     /|(  ____ \(  ____ \(  ____ \(  ____ \(  ____ \( )  |' . "\n" .
+        '|  | (    \/| )   ( || (    \/| (    \/| (    \/| (    \/| (    \/| |  |' . "\n" .
+        '|  | (_____ | |   | || |      | |      | (__    | (_____ | (_____ | |  |' . "\n" .
+        '|  (_____  )| |   | || |      | |      |  __)   (_____  )(_____  )| |  |' . "\n" .
+        '|        ) || |   | || |      | |      | (            ) |      ) |(_)  |' . "\n" .
+        '|  /\____) || (___) || (____/\| (____/\| (____/\/\____) |/\____) | _   |' . "\n" .
+        '|  \_______)(_______)(_______/(_______/(_______/\_______)\_______)(_)  |' . "\n" .
+        '|                                                                      |' . "\n" .
+        '|                                                                      |' . "\n" .
+        '+----------------------------------------------------------------------+' . RESET . "\n\n";
+}
+
+# Check if a file exists, or die.
+# If file path is relative, qualify it by prepending the current dir.
+# Return the fully-qualified file path.
+sub get_file_or_die {
+    my ($filename) = @_;
+    $filename = (getcwd() . '/' . $filename) if $filename !~ /^\//;
+
+    die "Error: $filename does not exist.\n" unless -e $filename;
+
+    return $filename;
+}
+
+# Run a PlistBuddy command against Metabase-Info.plist
+sub plist_buddy_exec {
+    my $info_plist = get_file_or_die('OSX/Metabase/Metabase-Info.plist');
+    return `/usr/libexec/PlistBuddy -c '@_' "$info_plist"`;
+}
+
+use constant OSX_ARTIFACTS_DIR => getcwd() . '/osx-artifacts';
+sub artifact {
+    # Make the artifacts directory if needed
+    system('mkdir', OSX_ARTIFACTS_DIR) if ! -d OSX_ARTIFACTS_DIR;
+
+    return OSX_ARTIFACTS_DIR . "/$_[0]";
+}
+
+1;
diff --git a/bin/config.json.template b/bin/config.json.template
new file mode 100644
index 0000000000000000000000000000000000000000..4339e9c78d583f34b16221c859644d73216ef330
--- /dev/null
+++ b/bin/config.json.template
@@ -0,0 +1,7 @@
+{
+    "codesigningIdentity": "Developer ID Application: Metabase, Inc",
+    "slackWebhookURL": "",
+    "awsProfile": "metabase",
+    "awsRegion": "",
+    "awsBucket": ""
+}
diff --git a/bin/lib/sign_update.rb b/bin/lib/sign_update.rb
new file mode 100755
index 0000000000000000000000000000000000000000..6d03e2ef0c26802d0a55b6450d0391130c4448d6
--- /dev/null
+++ b/bin/lib/sign_update.rb
@@ -0,0 +1,7 @@
+#!/usr/bin/ruby
+if ARGV.length < 2
+  puts "Usage: ruby sign_update.rb update_archive private_key"
+  exit
+end
+
+puts `openssl dgst -sha1 -binary < "#{ARGV[0]}" | openssl dgst -dss1 -sign "#{ARGV[1]}" | openssl enc -base64`
\ No newline at end of file
diff --git a/bin/osx-release b/bin/osx-release
new file mode 100755
index 0000000000000000000000000000000000000000..e2a067ce1d216eb2634035715fb09d5bf4cf6b35
--- /dev/null
+++ b/bin/osx-release
@@ -0,0 +1,366 @@
+#! /usr/bin/perl -I./bin
+
+use strict;
+use warnings;
+
+use Cwd 'getcwd';
+use File::Copy 'copy';
+use File::Copy::Recursive 'rcopy'; # CPAN
+use File::Path 'remove_tree';
+use File::stat 'stat';
+use JSON 'encode_json', 'from_json'; # CPAN
+use Readonly;                        # CPAN
+use String::Util 'trim';           # CPAN
+use WWW::Curl::Simple;             # CPAN
+
+use Metabase::Util;
+
+Readonly my $app             => artifact('Metabase.app');
+Readonly my $zipfile         => artifact('Metabase.zip');
+Readonly my $appcast         => artifact('appcast.xml');
+Readonly my $release_notes   => artifact('release-notes.html');
+Readonly my $dmg             => artifact('Metabase.dmg');
+Readonly my @files_to_upload => ($zipfile, $appcast, $release_notes, $dmg);
+
+Readonly my $xcode_project   => get_file_or_die('OSX/Metabase.xcodeproj');
+
+# Get the version saved in the CFBundle, e.g. 0.11.3.1
+sub version {
+    return trim(plist_buddy_exec('Print', 'CFBundleVersion'));
+}
+
+# Next version after version(), e.g. 0.11.3.2
+sub next_version {
+    my ($old_version_tag, $old_version_point_release) = (version() =~ /^(\d+\.\d+\.\d+)\.(\d+)$/);
+
+    # Get the tag saved in version.properties
+    my $tag_from_props_file = '';
+    open(FILE, get_file_or_die('resources/version.properties')) or die $!;
+    while (<FILE>) { m/^tag/ && s/^tag=v(.+)$/$1/ && ($tag_from_props_file = trim($_)); };
+
+    # Now calculate the new version, which is ($tag.$point_release)
+    # Check and see if tag has changed in version.properties; if so, new version is the first "point release" of that tag.
+    return $old_version_tag eq $tag_from_props_file ? ($old_version_tag . '.' . ($old_version_point_release + 1)) : "$tag_from_props_file.0";
+}
+
+sub bump_version {
+    Readonly my $new_version => next_version();
+    announce 'Bumping version: ' . version() . " -> $new_version";
+
+    plist_buddy_exec('Set', ':CFBundleVersion', $new_version);
+    plist_buddy_exec('Set', ':CFBundleShortVersionString', $new_version);
+}
+
+sub clean {
+    system('xcodebuild', 'clean', '-project', $xcode_project) == 0 or die $!;
+    remove_tree(OSX_ARTIFACTS_DIR);
+}
+
+# Build Metabase.app
+sub build {
+    announce "Building $app...";
+
+    Readonly my $xcarchive => artifact('Metabase.xcarchive');
+
+    # remove old artifacts if they exist
+    remove_tree($xcarchive, $app);
+
+    # Build the project and generate Metabase.xcarchive
+    system('xcodebuild',
+           '-project', $xcode_project,
+           '-scheme', 'Metabase',
+           '-configuration', 'Release',
+           '-archivePath', $xcarchive,
+           'archive') == 0 or die $!;
+
+    # Ok, now create the Metabase.app artifact
+    system('xcodebuild',
+           '-exportArchive',
+           '-exportFormat', 'APP',
+           '-archivePath', $xcarchive,
+           '-exportPath', $app) == 0 or die $!;
+
+    # Ok, we can remove the .xcarchive file now
+    remove_tree($xcarchive);
+}
+
+# Codesign Metabase.app
+sub codesign {
+    my $codesigning_cert_name = config('codesigningIdentity') or return;
+
+    announce "Codesigning $app...";
+
+    system('codesign', '--force', '--verify',
+           '--sign', $codesigning_cert_name,
+           '-r=designated => anchor trusted',
+           '--deep', get_file_or_die($app)) == 0 or die "Code signing failed: $!\n";
+}
+
+# Verify that Metabase.app was signed correctly
+sub verify_codesign {
+    return unless config('codesigningIdentity');
+
+    announce "Verifying codesigning for $app...";
+
+    system('codesign', '--verify', '--deep', '--display',
+           '--verbose=4', get_file_or_die($app)) == 0 or die "Code signing verification failed: $!\n";
+
+    # Double-check with System Policy Security tool
+    system('spctl', '--assess', '--verbose=4', get_file_or_die($app)) == 0
+}
+
+
+# ------------------------------------------------------------ PACKAGING FOR SPARKLE ------------------------------------------------------------
+
+# Create ZIP containing Metabase.app
+sub archive {
+    announce "Creating $zipfile...";
+
+    remove_tree($zipfile);
+
+    get_file_or_die($app);
+
+    system('cd ' . OSX_ARTIFACTS_DIR . ' && zip -r Metabase.zip Metabase.app') == 0 or die $!;
+    get_file_or_die($zipfile);
+}
+
+sub generate_signature {
+    Readonly my $private_key_file => getcwd() . '/OSX/dsa_priv.pem';
+
+    unless (-e $private_key_file) {
+        warn "Missing private key file: $private_key_file\n";
+        return;
+    }
+
+    Readonly my $sign_update_script => get_file_or_die('bin/lib/sign_update.rb');
+
+    get_file_or_die($zipfile);
+
+    return trim(`$sign_update_script "$zipfile" "$private_key_file"`);
+}
+
+# Generate the appcast.xml RSS feed file that Sparkle reads to check for updates
+sub generate_appcast {
+    announce "Generating $appcast...";
+
+    remove_tree($appcast);
+
+    my $aws_region  = config('awsRegion')  or return;
+    my $aws_bucket  = config('awsBucket')  or return;
+    my $signature   = generate_signature() or return;
+
+    Readonly my $appcast_template => get_file_or_die('bin/templates/appcast.xml.template');
+    Readonly my $filesize         => stat(get_file_or_die($zipfile))->size;
+    Readonly my $version          => version();
+
+    open(my $in,  '<', $appcast_template) or die "Unable to read $appcast_template: $!";
+    open(my $out, '>', $appcast) or die "Unable to write to $appcast: $!";
+
+    print "SIGNATURE: '$signature'\n";
+
+    while ( <$in> ) {
+        s/{{VERSION}}/$version/;
+        s/{{SIGNATURE}}/$signature/;
+        s/{{LENGTH}}/$filesize/;
+        s/{{S3_REGION}}/$aws_region/;
+        s/{{S3_BUCKET}}/$aws_bucket/;
+        print $out $_;
+    }
+
+    close $out;
+}
+
+sub edit_release_notes {
+    remove_tree($release_notes);
+
+    copy(get_file_or_die('bin/templates/release-notes.html.template'), $release_notes) or die $!;
+    system('emacs', get_file_or_die($release_notes)) == 0 or die $!;
+}
+
+
+# ------------------------------------------------------------ CREATING DMG ------------------------------------------------------------
+
+sub create_dmg_from_source_dir {
+    my ($source_dir, $dmg_filename) = @_;
+    announce "Creating DMG: $dmg_filename from source $source_dir...";
+
+    system('hdiutil', 'create',
+           '-srcfolder', $source_dir,
+           '-volname', 'Metabase',
+           '-fs', 'HFS+',
+           '-fsargs', '-c c=64,a=16,e=16',
+           '-format', 'UDRW',
+           '-size', '144MB',          # it looks like this can be whatever size we want; compression slims it down
+           $dmg_filename) == 0 or die $!;
+}
+
+# Mount the disk image, return the device name
+sub mount_dmg {
+    my ($dmg_filename) = @_;
+    announce "Mounting DMG...";
+
+    my $device = `hdiutil attach -readwrite -noverify -noautoopen $dmg_filename`;
+    # Find the device name: the part of the output looks like /dev/disk11
+    for my $token (split(/\s+/, $device)) {
+        if ($token =~ m|^/dev/|) {
+            $device = $token;
+            last;
+        }
+    }
+
+    announce "Mounted $dmg_filename at $device";
+    return $device;
+}
+
+sub dmg_add_applications_shortcut {
+    announce "Adding shortcut to /Applications...";
+
+    system('osascript', '-e',
+           'tell application "Finder"
+              tell disk "Metabase"
+                open
+                set current view of container window to icon view
+                set toolbar visible of container window to false
+                set statusbar visible of container window to false
+                set the bounds of container window to {400, 100, 885, 430}
+                set theViewOptions to the icon view options of container window
+                set arrangement of theViewOptions to not arranged
+                set icon size of theViewOptions to 72
+                make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
+                set position of item "Metabase.app" of container window to {100, 100}
+                set position of item "Applications" of container window to {375, 100}
+                update without registering applications
+                delay 5
+                close
+              end tell
+           end tell') == 0 or die $!;
+}
+
+sub finalize_dmg {
+    my ($device, $dmg_filename) = @_;
+    announce "Finalizing DMG...";
+
+    # Remove any hidden files that creeped into the DMG
+    remove_tree('/Volumes/Metabase/.Trashes',
+                '/Volumes/Metabase/.fseventsd');
+
+
+    # Set DMG permissions, force completion of pending disk writes
+    system('chmod', '-Rf', 'go-w', '/Volumes/Metabase') == 0 or warn $!; # this might issue warnings about not being able to affect .Trashes
+    system('sync');
+    system('sync');
+
+    # unmount the temp DMG
+    announce "Unmounting $device...";
+    system('hdiutil', 'detach', $device) == 0 or die $!;
+
+    # compress the DMG
+    announce "Compressing DMG...";
+    system('hdiutil', 'convert', $dmg_filename,
+           '-format', 'UDZO',
+           '-imagekey', 'zlib-level-9',
+           '-o', $dmg) == 0 or die $!;
+}
+
+sub create_dmg {
+    announce "Preparing DMG files...";
+
+    # detach any existing Metabase DMGs
+    system('hdiutil', 'detach', '/Volumes/Metabase') if -d '/Volumes/Metabase';
+
+    Readonly my $temp_dmg       => artifact('Metabase.temp.dmg');
+    Readonly my $dmg_source_dir => artifact('dmg');
+
+    # Clean up old artifacts
+    remove_tree($dmg_source_dir, $temp_dmg, $dmg);
+    mkdir $dmg_source_dir or die $!;
+
+    # Copy Metabase.app into the source dir
+    rcopy(get_file_or_die($app), $dmg_source_dir . '/Metabase.app') or die $!;
+
+    # Ok, now proceed with the steps to create the DMG
+    create_dmg_from_source_dir($dmg_source_dir, $temp_dmg);
+
+    Readonly my $device => mount_dmg($temp_dmg);
+
+    dmg_add_applications_shortcut;
+
+    finalize_dmg($device, $temp_dmg);
+
+    announce "DMG created successfully: $dmg";
+
+    # Cleanup: remove temp file & temp dir
+    remove_tree($temp_dmg, $dmg_source_dir);
+}
+
+
+# ------------------------------------------------------------ UPLOADING ------------------------------------------------------------
+
+sub announce_on_slack {
+    Readonly my $slack_url => config('slackWebhookURL') or return;
+    Readonly my $version   => version();
+    Readonly my $awsURL    => 'https://s3-' . config('awsRegion') . 'amazonaws.com/' . config('awsBucket') . '/Metabase.dmg';
+    my $text = "Metabase OS X $version 'Turbulent Toucan' Is Now Available!\n\n" .
+               "Get it here: $awsURL\n\n";
+
+    open(my $file, get_file_or_die($release_notes)) or die $!;
+    while (<$file>) {
+        m/^\s+<li>.*$/ && s|^\s+<li>(.*)</li>$|$1| && ($text .= '*  ' . $_);
+    }
+
+    my $json = encode_json {
+        channel    => '#general',
+        username   => 'OS X Bot',
+        icon_emoji => ':bird:',
+        text       => trim($text)
+    };
+
+    my $curl = WWW::Curl::Simple->new;
+    unless ((my $response = $curl->post($slack_url, $json))->code == 200) {
+        die 'Error posting to slack: ' . $response->code . ' ' . $response->content . "\n";
+    }
+}
+
+# Upload artifacts to AWS
+# Make sure to run `aws configure --profile metabase` first to set up your ~/.aws/config file correctly
+sub upload {
+    my $aws_profile = config('awsProfile') or return;
+    my $aws_region  = config('awsRegion')  or return;
+    my $aws_bucket  = config('awsBucket')  or return;
+
+    for my $file (@files_to_upload) {
+        announce "Uploading $file ...";
+        system('aws',
+               '--profile', $aws_profile,
+               '--region', $aws_region,
+               's3', 'cp', get_file_or_die($file),
+               "s3://$aws_bucket") == 0 or die "Upload failed: $!\n";
+    }
+
+    announce_on_slack;
+
+    announce "Upload finished."
+}
+
+
+# ------------------------------------------------------------ RUN ALL ------------------------------------------------------------
+
+sub all {
+    clean;
+    bump_version;
+    build;
+    codesign;
+    verify_codesign;
+    archive;
+    generate_appcast;
+    edit_release_notes;
+    create_dmg;
+    upload;
+}
+
+# Run all the commands specified in command line args, otherwise default to running 'all'
+@ARGV = ('all') unless @ARGV;
+no strict 'refs';
+map { $_->(); } @ARGV;
+
+print_giant_success_banner();
diff --git a/bin/osx-setup b/bin/osx-setup
new file mode 100755
index 0000000000000000000000000000000000000000..65c7085759ad41a460945d044657666835aae13b
--- /dev/null
+++ b/bin/osx-setup
@@ -0,0 +1,85 @@
+#! /usr/bin/perl -I./bin
+
+use strict;
+use warnings;
+
+use Cwd 'getcwd';
+use File::Copy 'copy';
+use File::Copy::Recursive 'rcopy';
+use File::Find 'find';
+use File::Path 'remove_tree';
+use String::Util 'trim';
+
+use Metabase::Util;
+
+use constant JRE_DEST => getcwd() . '/OSX/Metabase/jre';
+use constant JRE_HOME => trim(`/usr/libexec/java_home`) . '/jre';
+
+use constant UBERJAR_SRC => getcwd() . '/target/uberjar/metabase-standalone.jar';
+use constant UBERJAR_DEST => getcwd() . '/OSX/Resources/metabase.jar';
+
+use constant ENABLE_JAR_PACKING => 0;
+
+sub remove_jre_optional_files {
+    my @optional_files = ('bin/keytool',
+                          'bin/orbd',
+                          'bin/policytool',
+                          'bin/rmid',
+                          'bin/rmiregistry',
+                          'bin/servertool',
+                          'bin/tnameserv',
+                          'lib/cmm/PYCC.pf',
+                          'lib/deploy.jar',
+                          'lib/ext',
+                          'lib/fonts',
+                          'lib/javaws.jar',
+                          'lib/jfr',
+                          'lib/jfr.jar',
+                          'lib/libglass.dylib',
+                          'lib/libglib-lite.dylib',
+                          'lib/libgstreamer-lite.dylib',
+                          'lib/libjavafx_font_t2k.dylib',
+                          'lib/libjfxmedia.dylib',
+                          'lib/libjfxwebkit.dylib',
+                          'lib/libprism_common.dylib',
+                          'lib/libprism_sw.dylib',
+                          'lib/plugin.jar',
+                          'lib/javafx.properties',
+                          'lib/jfxswt.jar'
+        );
+    for my $file (@optional_files) {
+        $file = JRE_DEST . '/' . $file;
+        remove_tree($file) if -e $file;
+    }
+}
+
+# Finds all the .jar files in JRE_DEST and replaces them with packed .pack.gz files.
+sub pack_jre_jars {
+    sub pack_jar {
+        if (/\.jar$/) {
+            s/(^.*)\.jar$/$1/; # stip off extension
+            print "Packing $_.jar...\n";
+            system('pack200', '--gzip', '--strip-debug', '--effort=9', $_ . '.pack.gz', $_ . '.jar') == 0 or die $!;
+            remove_tree($_ . '.jar');
+        }
+    }
+    find(\&pack_jar, JRE_DEST . '/lib');
+}
+
+# Copy the JRE if needed
+(rcopy(JRE_HOME, JRE_DEST) or die $!) unless -d JRE_DEST;
+
+# Remove optional files from JRE dest
+remove_jre_optional_files();
+
+# Pack JARs in JRE if applicable
+pack_jar() if ENABLE_JAR_PACKING;
+
+# Build uberjar if needed
+(system('./bin/build') or die $!) unless -f UBERJAR_SRC;
+
+# Copy uberjar over
+announce 'Copying uberjar ' . UBERJAR_SRC . ' -> ' . UBERJAR_DEST;
+copy(get_file_or_die(UBERJAR_SRC), UBERJAR_DEST) or die $!;
+
+print_giant_success_banner();
diff --git a/bin/templates/appcast.xml.template b/bin/templates/appcast.xml.template
new file mode 100644
index 0000000000000000000000000000000000000000..5c60cb7e38cbee98b8b8ee562d3eb0e22d03e2a3
--- /dev/null
+++ b/bin/templates/appcast.xml.template
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/">
+  <channel>
+    <title>
+      Metabase Changelog
+    </title>
+    <link>
+      https://{{S3_REGION}}.amazonaws.com/{{S3_BUCKET}}/appcast.xml
+    </link>
+    <language>
+      en
+    </language>
+    <item>
+      <title>
+        Version {{VERSION}}
+      </title>
+      <sparkle:releaseNotesLink>
+        https://{{S3_REGION}}.amazonaws.com/{{S3_BUCKET}}/release-notes.html
+      </sparkle:releaseNotesLink>
+      <enclosure url="https://{{S3_REGION}}.amazonaws.com/{{S3_BUCKET}}/Metabase.zip"
+                 sparkle:version="{{VERSION}}"
+                 length="{{LENGTH}}"
+                 type="application/octet-stream"
+                 sparkle:dsaSignature="{{SIGNATURE}}" />
+    </item>
+  </channel>
+</rss>
diff --git a/bin/templates/release-notes.html.template b/bin/templates/release-notes.html.template
new file mode 100644
index 0000000000000000000000000000000000000000..d8360f1278798b8312e4bf01f73b7f425a00d8de
--- /dev/null
+++ b/bin/templates/release-notes.html.template
@@ -0,0 +1,10 @@
+<html>
+  <head>
+    <title>Metabase Release Notes</title>
+  </head>
+  <body>
+    <ul>
+      <li>What's changed in this update? Put notes here.</li>
+    </ul>
+  </body>
+</html>
diff --git a/docs/developers-guide-osx.md b/docs/developers-guide-osx.md
new file mode 100644
index 0000000000000000000000000000000000000000..64f911477f2b40214482de6dff324ee3fdfd0852
--- /dev/null
+++ b/docs/developers-guide-osx.md
@@ -0,0 +1,46 @@
+# Metabase OS X App
+
+## Prereqs
+
+You'll need to run the following commands before building the app:
+
+```bash
+# Fetch and initialize git submodule
+git submodule update --init
+
+# Install Perl modules used by ./setup and ./release
+sudo cpan install File::Copy::Recursive JSON Readonly String::Util WWW::Curl::Simple
+
+# Copy JRE and uberjar
+./bin/osx-setup
+```
+
+`./bin/osx-setup` will build run commands to build the uberjar for you if needed.
+Run `./bin/osx-setup` again at any time in the future to copy the latest version of the uberjar into the project.
+
+
+## Releasing
+
+A handy Perl script called `./bin/osx-release` takes care of all of the details for you. Before you run it for the first time, you'll need to set up a few additional things:
+
+```bash
+# Configure AWS Credentials
+# You'll need credentials that give you permission to write the metabase-osx-releases S3 bucket.
+aws configure --profile metabase
+
+# Copy & Edit Config file
+cp bin/config.json.template bin/config.json
+emacs bin/config.json
+
+# Obtain a copy of the private key used for signing the app (ask Cam)
+# and put a copy of it at ./dsa_priv.pem
+cp /path/to/private/key.pem OSX/dsa_priv.pem
+```
+
+You'll probably also want an Apple Developer ID Application Certificate in your computer's keychain (ask Cam).
+
+After that, you are good to go:
+```bash
+# Bundle entire app, and upload to s3
+./release
+```
diff --git a/docs/developers-guide.md b/docs/developers-guide.md
index 40a8a3ebbc693c1e8d053708a7cf0aea66f06dba..3a55ee0e26b830855c76214629f1ca610943bb32 100644
--- a/docs/developers-guide.md
+++ b/docs/developers-guide.md
@@ -1,9 +1,9 @@
 
-> **This guide will teach you:**  
-> How to compile your own copy of Metabase  
-> How to set up a development environment  
-> How to run the Metabase Server  
-> How to contribute back to the Metabase project  
+> **This guide will teach you:**
+> How to compile your own copy of Metabase
+> How to set up a development environment
+> How to run the Metabase Server
+> How to contribute back to the Metabase project
 
 
 [![Circle CI](https://circleci.com/gh/metabase/metabase-init.svg?style=svg&circle-token=3ccf0aa841028af027f2ac9e8df17ce603e90ef9)](https://circleci.com/gh/metabase/metabase-init)
@@ -25,6 +25,10 @@ The entire Metabase application is compiled and assembled into a single .jar fil
 
 After running the build script simply look in `target/uberjar` for the output .jar file and you are ready to go.
 
+## Building the OS X App
+
+See [this guide](developers-guide-osx.md).
+
 
 # Development Environment
 
@@ -120,7 +124,7 @@ Run unit tests with
 
 or a specific test with
 
-    lein test metabase.api.session-test  
+    lein test metabase.api.session-test
 
 By default, the tests only run against the `h2` dataset (built-in test database). You can specify which datasets/drivers to run tests against with the env var `MB_TEST_DATASETS`: