diff --git a/osx-server-gui/.gitignore b/osx-server-gui/.gitignore
new file mode 100644
index 0000000..14acf59
--- /dev/null
+++ b/osx-server-gui/.gitignore
@@ -0,0 +1,4 @@
+.DS_Store
+build
+*.pbxuser
+*.mode1v3
diff --git a/osx-server-gui/English.lproj/Credits.html b/osx-server-gui/English.lproj/Credits.html
new file mode 100644
index 0000000..916511a
--- /dev/null
+++ b/osx-server-gui/English.lproj/Credits.html
@@ -0,0 +1,43 @@
+
+
+ Foo
+
+
+
+
+ Hop is free software: you can redistribute it and/or modify it
+ under the terms of
+ the GNU General Public
+ License as published by the Free Software Foundation, either
+ version 3 of the License, or (at your option) any later version.
+
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+
+ Developers
+
+ The project is currently hosted on github at http://github.com/tonyg/hop/ .
+ Contact details for the author are here .
+
+
+ Build information
+
+ Build stamp @BUILD_STAMP@
+ @GUI_VERSION@
+ @SERVER_VERSION@
+
+
+
diff --git a/osx-server-gui/English.lproj/InfoPlist.strings b/osx-server-gui/English.lproj/InfoPlist.strings
new file mode 100644
index 0000000..477b28f
--- /dev/null
+++ b/osx-server-gui/English.lproj/InfoPlist.strings
@@ -0,0 +1,2 @@
+/* Localized versions of Info.plist keys */
+
diff --git a/osx-server-gui/English.lproj/MainMenu.xib b/osx-server-gui/English.lproj/MainMenu.xib
new file mode 100644
index 0000000..d5720de
--- /dev/null
+++ b/osx-server-gui/English.lproj/MainMenu.xib
@@ -0,0 +1,1390 @@
+
+
+
+ 1060
+ 10K549
+ 804
+ 1038.36
+ 461.00
+
+ YES
+
+ YES
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.WebKitIBPlugin
+
+
+ YES
+ 804
+ 804
+
+
+
+ YES
+
+
+
+
+ YES
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.WebKitIBPlugin
+
+
+ PluginDependencyRecalculationVersion
+
+
+
+ YES
+
+ NSApplication
+
+
+ FirstResponder
+
+
+ NSApplication
+
+
+
+ 15
+ 2
+ {{85, 208}, {1000, 480}}
+ 1954021376
+ Hop Server
+ NSWindow
+
+ {1.79769e+308, 1.79769e+308}
+
+
+ 256
+
+ YES
+
+
+ 274
+
+ YES
+
+ YES
+ Apple HTML pasteboard type
+ Apple PDF pasteboard type
+ Apple PICT pasteboard type
+ Apple URL pasteboard type
+ Apple Web Archive pasteboard type
+ NSColor pasteboard type
+ NSFilenamesPboardType
+ NSStringPboardType
+ NeXT RTFD pasteboard type
+ NeXT Rich Text Format v1.0 pasteboard type
+ NeXT TIFF v4.0 pasteboard type
+ WebURLsWithTitlesPboardType
+ public.png
+ public.url
+ public.url-name
+
+
+ {1000, 480}
+
+
+
+
+
+ webview
+
+ webviewWebKitJavaEnabled
+
+
+
+ YES
+ YES
+
+
+ {1000, 480}
+
+
+ {{0, 0}, {1366, 746}}
+ {1.79769e+308, 1.79769e+308}
+
+
+ hopOsxAppDelegate
+
+
+ NSFontManager
+
+
+
+
+ YES
+
+
+ performMiniaturize:
+
+
+
+ 37
+
+
+
+ arrangeInFront:
+
+
+
+ 39
+
+
+
+ orderFrontStandardAboutPanel:
+
+
+
+ 142
+
+
+
+ performZoom:
+
+
+
+ 240
+
+
+
+ hide:
+
+
+
+ 367
+
+
+
+ hideOtherApplications:
+
+
+
+ 368
+
+
+
+ unhideAllApplications:
+
+
+
+ 370
+
+
+
+ terminate:
+
+
+
+ 449
+
+
+
+ delegate
+
+
+
+ 495
+
+
+
+ window
+
+
+
+ 532
+
+
+
+ webview
+
+
+
+ 535
+
+
+
+
+ YES
+
+ 0
+
+ YES
+
+
+
+
+
+ -2
+
+
+ File's Owner
+
+
+ -1
+
+
+ First Responder
+
+
+ -3
+
+
+ Application
+
+
+ 29
+
+
+ YES
+
+
+
+
+
+
+ 19
+
+
+ YES
+
+
+
+
+
+ 56
+
+
+ YES
+
+
+
+
+
+ 57
+
+
+ YES
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 58
+
+
+
+
+ 134
+
+
+
+
+ 150
+
+
+
+
+ 136
+
+
+
+
+ 144
+
+
+
+
+ 129
+
+
+
+
+ 143
+
+
+
+
+ 236
+
+
+
+
+ 131
+
+
+ YES
+
+
+
+
+
+ 149
+
+
+
+
+ 145
+
+
+
+
+ 130
+
+
+
+
+ 24
+
+
+ YES
+
+
+
+
+
+
+
+
+ 92
+
+
+
+
+ 5
+
+
+
+
+ 239
+
+
+
+
+ 23
+
+
+
+
+ 371
+
+
+ YES
+
+
+
+
+
+ 372
+
+
+ YES
+
+
+
+
+
+ 420
+
+
+
+
+ 494
+
+
+
+
+ 534
+
+
+
+
+
+
+ YES
+
+ YES
+ -3.IBPluginDependency
+ 129.IBPluginDependency
+ 129.ImportedFromIB2
+ 130.IBEditorWindowLastContentRect
+ 130.IBPluginDependency
+ 130.ImportedFromIB2
+ 130.editorWindowContentRectSynchronizationRect
+ 131.IBPluginDependency
+ 131.ImportedFromIB2
+ 134.IBPluginDependency
+ 134.ImportedFromIB2
+ 136.IBPluginDependency
+ 136.ImportedFromIB2
+ 143.IBPluginDependency
+ 143.ImportedFromIB2
+ 144.IBPluginDependency
+ 144.ImportedFromIB2
+ 145.IBPluginDependency
+ 145.ImportedFromIB2
+ 149.IBPluginDependency
+ 149.ImportedFromIB2
+ 150.IBPluginDependency
+ 150.ImportedFromIB2
+ 19.IBPluginDependency
+ 19.ImportedFromIB2
+ 23.IBPluginDependency
+ 23.ImportedFromIB2
+ 236.IBPluginDependency
+ 236.ImportedFromIB2
+ 239.IBPluginDependency
+ 239.ImportedFromIB2
+ 24.IBEditorWindowLastContentRect
+ 24.IBPluginDependency
+ 24.ImportedFromIB2
+ 24.editorWindowContentRectSynchronizationRect
+ 29.IBEditorWindowLastContentRect
+ 29.IBPluginDependency
+ 29.ImportedFromIB2
+ 29.WindowOrigin
+ 29.editorWindowContentRectSynchronizationRect
+ 371.IBEditorWindowLastContentRect
+ 371.IBPluginDependency
+ 371.IBWindowTemplateEditedContentRect
+ 371.NSWindowTemplate.visibleAtLaunch
+ 371.editorWindowContentRectSynchronizationRect
+ 371.windowTemplate.maxSize
+ 372.IBPluginDependency
+ 494.IBAttributePlaceholdersKey
+ 5.IBPluginDependency
+ 5.ImportedFromIB2
+ 534.IBPluginDependency
+ 534.IBViewBoundsToFrameTransform
+ 56.IBPluginDependency
+ 56.ImportedFromIB2
+ 57.IBEditorWindowLastContentRect
+ 57.IBPluginDependency
+ 57.ImportedFromIB2
+ 57.editorWindowContentRectSynchronizationRect
+ 58.IBPluginDependency
+ 58.ImportedFromIB2
+ 92.IBPluginDependency
+ 92.ImportedFromIB2
+
+
+ YES
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ {{715, 624}, {64, 6}}
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ {{436, 809}, {64, 6}}
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ {{588, 617}, {194, 73}}
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ {{525, 802}, {197, 73}}
+ {{478, 690}, {193, 20}}
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ {74, 862}
+ {{6, 978}, {478, 20}}
+ {{57, 58}, {1000, 480}}
+ com.apple.InterfaceBuilder.CocoaPlugin
+ {{57, 58}, {1000, 480}}
+
+ {{33, 99}, {480, 360}}
+ {3.40282e+38, 3.40282e+38}
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ YES
+
+
+ YES
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.WebKitIBPlugin
+
+ AUK2AADCaAAAA
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ {{490, 507}, {210, 183}}
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ {{23, 794}, {245, 183}}
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+
+ YES
+
+
+ YES
+
+
+
+
+ YES
+
+
+ YES
+
+
+
+ 535
+
+
+
+ YES
+
+ hopOsxAppDelegate
+ NSObject
+
+ YES
+
+ YES
+ webview
+ window
+
+
+ YES
+ WebView
+ NSWindow
+
+
+
+ YES
+
+ YES
+ webview
+ window
+
+
+ YES
+
+ webview
+ WebView
+
+
+ window
+ NSWindow
+
+
+
+
+ IBProjectSource
+ hopOsxAppDelegate.h
+
+
+
+
+ YES
+
+ NSApplication
+ NSResponder
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSApplication.h
+
+
+
+ NSApplication
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSApplicationScripting.h
+
+
+
+ NSApplication
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSColorPanel.h
+
+
+
+ NSApplication
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSHelpManager.h
+
+
+
+ NSApplication
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSPageLayout.h
+
+
+
+ NSApplication
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSUserInterfaceItemSearching.h
+
+
+
+ NSFontManager
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSFontManager.h
+
+
+
+ NSMenu
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSMenu.h
+
+
+
+ NSMenuItem
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSMenuItem.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSAccessibility.h
+
+
+
+ NSObject
+
+
+
+ NSObject
+
+
+
+ NSObject
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSControl.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSDictionaryController.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSDragging.h
+
+
+
+ NSObject
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSFontPanel.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSKeyValueBinding.h
+
+
+
+ NSObject
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSNibLoading.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSOutlineView.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSPasteboard.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSSavePanel.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSTableView.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSToolbarItem.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSView.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSArchiver.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSClassDescription.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSError.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSFileManager.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSKeyValueCoding.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSKeyValueObserving.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSKeyedArchiver.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSObject.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSObjectScripting.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSPortCoder.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSRunLoop.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSScriptClassDescription.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSScriptKeyValueCoding.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSScriptObjectSpecifiers.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSScriptWhoseTests.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSThread.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSURL.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSURLConnection.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ Foundation.framework/Headers/NSURLDownload.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebDownload.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebEditingDelegate.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebFrameLoadDelegate.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebJavaPlugIn.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebPlugin.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebPluginContainer.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebPolicyDelegate.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebResourceLoadDelegate.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebScriptObject.h
+
+
+
+ NSObject
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebUIDelegate.h
+
+
+
+ NSResponder
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSInterfaceStyle.h
+
+
+
+ NSResponder
+ NSObject
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSResponder.h
+
+
+
+ NSView
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSClipView.h
+
+
+
+ NSView
+
+
+
+ NSView
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSRulerView.h
+
+
+
+ NSView
+ NSResponder
+
+
+
+ NSWindow
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSDrawer.h
+
+
+
+ NSWindow
+ NSResponder
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSWindow.h
+
+
+
+ NSWindow
+
+ IBFrameworkSource
+ AppKit.framework/Headers/NSWindowScripting.h
+
+
+
+ WebView
+ NSView
+
+ YES
+
+ YES
+ goBack:
+ goForward:
+ makeTextLarger:
+ makeTextSmaller:
+ makeTextStandardSize:
+ reload:
+ reloadFromOrigin:
+ stopLoading:
+ takeStringURLFrom:
+ toggleContinuousSpellChecking:
+ toggleSmartInsertDelete:
+
+
+ YES
+ id
+ id
+ id
+ id
+ id
+ id
+ id
+ id
+ id
+ id
+ id
+
+
+
+ YES
+
+ YES
+ goBack:
+ goForward:
+ makeTextLarger:
+ makeTextSmaller:
+ makeTextStandardSize:
+ reload:
+ reloadFromOrigin:
+ stopLoading:
+ takeStringURLFrom:
+ toggleContinuousSpellChecking:
+ toggleSmartInsertDelete:
+
+
+ YES
+
+ goBack:
+ id
+
+
+ goForward:
+ id
+
+
+ makeTextLarger:
+ id
+
+
+ makeTextSmaller:
+ id
+
+
+ makeTextStandardSize:
+ id
+
+
+ reload:
+ id
+
+
+ reloadFromOrigin:
+ id
+
+
+ stopLoading:
+ id
+
+
+ takeStringURLFrom:
+ id
+
+
+ toggleContinuousSpellChecking:
+ id
+
+
+ toggleSmartInsertDelete:
+ id
+
+
+
+
+ IBFrameworkSource
+ WebKit.framework/Headers/WebView.h
+
+
+
+
+ 0
+ IBCocoaFramework
+
+ com.apple.InterfaceBuilder.CocoaPlugin.macosx
+
+
+
+ com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3
+
+
+ YES
+ ../hopOsx.xcodeproj
+ 3
+
+ YES
+
+ YES
+ NSMenuCheckmark
+ NSMenuMixedState
+
+
+ YES
+ {9, 8}
+ {7, 2}
+
+
+
+
diff --git a/osx-server-gui/Hop.icns b/osx-server-gui/Hop.icns
new file mode 100644
index 0000000..4d50fa4
Binary files /dev/null and b/osx-server-gui/Hop.icns differ
diff --git a/osx-server-gui/Makefile b/osx-server-gui/Makefile
new file mode 100644
index 0000000..c6b0e5d
--- /dev/null
+++ b/osx-server-gui/Makefile
@@ -0,0 +1,44 @@
+SERVER_PATH=../server
+SERVER_BINARY=hop_server.native
+SERVER_WEB=web
+APP_NAME="Hop Server"
+
+RELEASE_RESOURCES=build/Release/$(APP_NAME).app/Contents/Resources
+DEBUG_RESOURCES=build/Debug/$(APP_NAME).app/Contents/Resources
+
+BUILD_STAMP:=$(shell date +%Y%m%d-%H%M%S)
+GUI_VERSION:=Hop OSX GUI revision git-$(shell git branch -v --abbrev=8 | grep '^\*' | awk '{print $$3}')
+SERVER_VERSION:=Server revision git-$(shell cd $(SERVER_PATH); git branch -v --abbrev=8 | grep '^\*' | awk '{print $$3}')
+
+release: $(SERVER_PATH)/$(SERVER_BINARY)
+ xcodebuild -configuration Release
+ cp $(SERVER_PATH)/$(SERVER_BINARY) $(RELEASE_RESOURCES)/.
+ sh ./fixup_shlibs.sh $(RELEASE_RESOURCES) $(SERVER_BINARY)
+ cp -rp $(SERVER_PATH)/$(SERVER_WEB) $(RELEASE_RESOURCES)/.
+ sed \
+ -e 's:@BUILD_STAMP@:$(BUILD_STAMP):g' \
+ -e 's:@GUI_VERSION@:$(GUI_VERSION):g' \
+ -e 's:@SERVER_VERSION@:$(SERVER_VERSION):g' \
+ $(RELEASE_RESOURCES)/English.lproj/Credits.html \
+ > $(RELEASE_RESOURCES)/English.lproj/Credits.html.tmp
+ mv \
+ $(RELEASE_RESOURCES)/English.lproj/Credits.html.tmp \
+ $(RELEASE_RESOURCES)/English.lproj/Credits.html
+
+# /usr/libexec/PlistBuddy \
+# -c "Set CFBundleShortVersionString $(GUI_VERSION)" \
+# $(RELEASE_RESOURCES)/../Info.plist
+# /usr/libexec/PlistBuddy \
+# -c "Set CFBundleVersion $(SERVER_VERSION)" \
+# $(RELEASE_RESOURCES)/../Info.plist
+
+debug: $(SERVER_PATH)/$(SERVER_BINARY)
+ xcodebuild -configuration Debug
+ ln -sf $(CURDIR)/$(SERVER_PATH)/$(SERVER_BINARY) $(DEBUG_RESOURCES)/
+ ln -sf $(CURDIR)/$(SERVER_PATH)/$(SERVER_WEB) $(DEBUG_RESOURCES)/
+
+$(SERVER_PATH)/$(SERVER_BINARY):
+ make -C $(SERVER_PATH)
+
+clean:
+ rm -rf build
diff --git a/osx-server-gui/fixup_shlibs.sh b/osx-server-gui/fixup_shlibs.sh
new file mode 100755
index 0000000..7335e19
--- /dev/null
+++ b/osx-server-gui/fixup_shlibs.sh
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+RELEASE_RESOURCES="$1"
+SERVER_BINARY="$2"
+
+cd "$RELEASE_RESOURCES"
+
+LIBEV_PATH=$(otool -L "$SERVER_BINARY" | grep 'libev.*dylib' | awk '{print $1}')
+
+if [ ! -f "$LIBEV_PATH" ];
+then
+ echo "Not rewriting LIBEV_PATH $LIBEV_PATH"
+ exit 0
+fi
+
+LIBEV_LOCAL=$(basename "$LIBEV_PATH")
+cp $LIBEV_PATH $LIBEV_LOCAL
+install_name_tool -change "$LIBEV_PATH" @loader_path/"$LIBEV_LOCAL" "$SERVER_BINARY"
+
+otool -L "$SERVER_BINARY"
diff --git a/osx-server-gui/hopOsx-Info.plist b/osx-server-gui/hopOsx-Info.plist
new file mode 100644
index 0000000..b059375
--- /dev/null
+++ b/osx-server-gui/hopOsx-Info.plist
@@ -0,0 +1,34 @@
+
+
+
+
+ NSHumanReadableCopyright
+ Copyright © 2012 Tony Garnock-Jones
+ CFBundleDevelopmentRegion
+ English
+ CFBundleExecutable
+ ${EXECUTABLE_NAME}
+ CFBundleIconFile
+ Hop.icns
+ CFBundleIdentifier
+ org.eighty-twenty.${PRODUCT_NAME:rfc1034identifier}
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ ${PRODUCT_NAME}
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ Hop OSX GUI v0.0.1
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ prealpha
+ LSMinimumSystemVersion
+ ${MACOSX_DEPLOYMENT_TARGET}
+ NSMainNibFile
+ MainMenu
+ NSPrincipalClass
+ NSApplication
+
+
diff --git a/osx-server-gui/hopOsx.xcodeproj/project.pbxproj b/osx-server-gui/hopOsx.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..becb00a
--- /dev/null
+++ b/osx-server-gui/hopOsx.xcodeproj/project.pbxproj
@@ -0,0 +1,312 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 45;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDD58140DA1D0A300B32029 /* MainMenu.xib */; };
+ 256AC3DA0F4B6AC300CF3369 /* hopOsxAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 256AC3D90F4B6AC300CF3369 /* hopOsxAppDelegate.m */; };
+ 8A3AD61B1550596B0083025A /* Hop.icns in Resources */ = {isa = PBXBuildFile; fileRef = 8A3AD61A1550596B0083025A /* Hop.icns */; };
+ 8A78BA7015536F2D0063299E /* Credits.html in Resources */ = {isa = PBXBuildFile; fileRef = 8A78BA6E15536F2D0063299E /* Credits.html */; };
+ 8AC89E371550397E00BACB4E /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AC89E361550397E00BACB4E /* WebKit.framework */; };
+ 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */; };
+ 8D11072D0486CEB800E47090 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; settings = {ATTRIBUTES = (); }; };
+ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 089C165DFE840E0CC02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; };
+ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; };
+ 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; };
+ 1DDD58150DA1D0A300B32029 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/MainMenu.xib; sourceTree = ""; };
+ 256AC3D80F4B6AC300CF3369 /* hopOsxAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hopOsxAppDelegate.h; sourceTree = ""; };
+ 256AC3D90F4B6AC300CF3369 /* hopOsxAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = hopOsxAppDelegate.m; sourceTree = ""; };
+ 256AC3F00F4B6AF500CF3369 /* hopOsx_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hopOsx_Prefix.pch; sourceTree = ""; };
+ 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
+ 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; };
+ 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; };
+ 8A3AD61A1550596B0083025A /* Hop.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Hop.icns; sourceTree = ""; };
+ 8A78BA6F15536F2D0063299E /* English */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = English; path = English.lproj/Credits.html; sourceTree = ""; };
+ 8AC89E361550397E00BACB4E /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = System/Library/Frameworks/WebKit.framework; sourceTree = SDKROOT; };
+ 8D1107310486CEB800E47090 /* hopOsx-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "hopOsx-Info.plist"; sourceTree = ""; };
+ 8D1107320486CEB800E47090 /* Hop Server.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Hop Server.app"; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 8D11072E0486CEB800E47090 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
+ 8AC89E371550397E00BACB4E /* WebKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 080E96DDFE201D6D7F000001 /* Classes */ = {
+ isa = PBXGroup;
+ children = (
+ 256AC3D80F4B6AC300CF3369 /* hopOsxAppDelegate.h */,
+ 256AC3D90F4B6AC300CF3369 /* hopOsxAppDelegate.m */,
+ );
+ name = Classes;
+ sourceTree = "";
+ };
+ 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
+ 8AC89E361550397E00BACB4E /* WebKit.framework */,
+ );
+ name = "Linked Frameworks";
+ sourceTree = "";
+ };
+ 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 29B97324FDCFA39411CA2CEA /* AppKit.framework */,
+ 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */,
+ 29B97325FDCFA39411CA2CEA /* Foundation.framework */,
+ );
+ name = "Other Frameworks";
+ sourceTree = "";
+ };
+ 19C28FACFE9D520D11CA2CBB /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8D1107320486CEB800E47090 /* Hop Server.app */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 29B97314FDCFA39411CA2CEA /* hopOsx */ = {
+ isa = PBXGroup;
+ children = (
+ 080E96DDFE201D6D7F000001 /* Classes */,
+ 29B97315FDCFA39411CA2CEA /* Other Sources */,
+ 29B97317FDCFA39411CA2CEA /* Resources */,
+ 29B97323FDCFA39411CA2CEA /* Frameworks */,
+ 19C28FACFE9D520D11CA2CBB /* Products */,
+ );
+ name = hopOsx;
+ sourceTree = "";
+ };
+ 29B97315FDCFA39411CA2CEA /* Other Sources */ = {
+ isa = PBXGroup;
+ children = (
+ 8A78BA6E15536F2D0063299E /* Credits.html */,
+ 256AC3F00F4B6AF500CF3369 /* hopOsx_Prefix.pch */,
+ 29B97316FDCFA39411CA2CEA /* main.m */,
+ 8A3AD61A1550596B0083025A /* Hop.icns */,
+ );
+ name = "Other Sources";
+ sourceTree = "";
+ };
+ 29B97317FDCFA39411CA2CEA /* Resources */ = {
+ isa = PBXGroup;
+ children = (
+ 8D1107310486CEB800E47090 /* hopOsx-Info.plist */,
+ 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */,
+ 1DDD58140DA1D0A300B32029 /* MainMenu.xib */,
+ );
+ name = Resources;
+ sourceTree = "";
+ };
+ 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */,
+ 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 8D1107260486CEB800E47090 /* Hop Server */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Hop Server" */;
+ buildPhases = (
+ 8D1107290486CEB800E47090 /* Resources */,
+ 8D11072C0486CEB800E47090 /* Sources */,
+ 8D11072E0486CEB800E47090 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = "Hop Server";
+ productInstallPath = "$(HOME)/Applications";
+ productName = "Hop Server";
+ productReference = 8D1107320486CEB800E47090 /* Hop Server.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 29B97313FDCFA39411CA2CEA /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ ORGANIZATIONNAME = "Tony Garnock-Jones";
+ };
+ buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "hopOsx" */;
+ compatibilityVersion = "Xcode 3.1";
+ developmentRegion = English;
+ hasScannedForEncodings = 1;
+ knownRegions = (
+ English,
+ Japanese,
+ French,
+ German,
+ );
+ mainGroup = 29B97314FDCFA39411CA2CEA /* hopOsx */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 8D1107260486CEB800E47090 /* Hop Server */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 8D1107290486CEB800E47090 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D11072B0486CEB800E47090 /* InfoPlist.strings in Resources */,
+ 1DDD58160DA1D0A300B32029 /* MainMenu.xib in Resources */,
+ 8A3AD61B1550596B0083025A /* Hop.icns in Resources */,
+ 8A78BA7015536F2D0063299E /* Credits.html in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 8D11072C0486CEB800E47090 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 8D11072D0486CEB800E47090 /* main.m in Sources */,
+ 256AC3DA0F4B6AC300CF3369 /* hopOsxAppDelegate.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 089C165DFE840E0CC02AAC07 /* English */,
+ );
+ name = InfoPlist.strings;
+ sourceTree = "";
+ };
+ 1DDD58140DA1D0A300B32029 /* MainMenu.xib */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 1DDD58150DA1D0A300B32029 /* English */,
+ );
+ name = MainMenu.xib;
+ sourceTree = "";
+ };
+ 8A78BA6E15536F2D0063299E /* Credits.html */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 8A78BA6F15536F2D0063299E /* English */,
+ );
+ name = Credits.html;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ C01FCF4B08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ COPY_PHASE_STRIP = NO;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_MODEL_TUNING = G5;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = hopOsx_Prefix.pch;
+ INFOPLIST_FILE = "hopOsx-Info.plist";
+ INSTALL_PATH = "$(HOME)/Applications";
+ PRODUCT_NAME = "Hop Server";
+ };
+ name = Debug;
+ };
+ C01FCF4C08A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_MODEL_TUNING = G5;
+ GCC_PRECOMPILE_PREFIX_HEADER = YES;
+ GCC_PREFIX_HEADER = hopOsx_Prefix.pch;
+ INFOPLIST_FILE = "hopOsx-Info.plist";
+ INSTALL_PATH = "$(HOME)/Applications";
+ PRODUCT_NAME = "Hop Server";
+ };
+ name = Release;
+ };
+ C01FCF4F08A954540054247B /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ PREBINDING = NO;
+ SDKROOT = macosx10.6;
+ };
+ name = Debug;
+ };
+ C01FCF5008A954540054247B /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ PREBINDING = NO;
+ SDKROOT = macosx10.6;
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "Hop Server" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4B08A954540054247B /* Debug */,
+ C01FCF4C08A954540054247B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ C01FCF4E08A954540054247B /* Build configuration list for PBXProject "hopOsx" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C01FCF4F08A954540054247B /* Debug */,
+ C01FCF5008A954540054247B /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
+}
diff --git a/osx-server-gui/hopOsxAppDelegate.h b/osx-server-gui/hopOsxAppDelegate.h
new file mode 100644
index 0000000..84b84f4
--- /dev/null
+++ b/osx-server-gui/hopOsxAppDelegate.h
@@ -0,0 +1,32 @@
+// Copyright 2012 Tony Garnock-Jones .
+//
+// This file is part of Hop.
+//
+// Hop is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the
+// Free Software Foundation, either version 3 of the License, or (at your
+// option) any later version.
+//
+// Hop is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Hop. If not, see .
+//
+
+#import
+#import
+
+@interface hopOsxAppDelegate : NSObject {
+ NSWindow *window;
+ WebView *webview;
+
+ NSTask *task;
+}
+
+@property (assign) IBOutlet NSWindow *window;
+@property (assign) IBOutlet WebView *webview;
+
+@end
diff --git a/osx-server-gui/hopOsxAppDelegate.m b/osx-server-gui/hopOsxAppDelegate.m
new file mode 100644
index 0000000..314c76b
--- /dev/null
+++ b/osx-server-gui/hopOsxAppDelegate.m
@@ -0,0 +1,106 @@
+// Copyright 2012 Tony Garnock-Jones .
+//
+// This file is part of Hop.
+//
+// Hop is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the
+// Free Software Foundation, either version 3 of the License, or (at your
+// option) any later version.
+//
+// Hop is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Hop. If not, see .
+//
+
+#import "hopOsxAppDelegate.h"
+#include
+
+#define HOP_STARTUP_DEADLINE_SECONDS 30
+
+@implementation hopOsxAppDelegate
+
+@synthesize window;
+@synthesize webview;
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+ task = [NSTask new];
+
+ [[NSNotificationCenter defaultCenter]
+ addObserver: self
+ selector: @selector(mainWindowClosed:)
+ name: NSWindowWillCloseNotification
+ object: window];
+
+ [[NSNotificationCenter defaultCenter]
+ addObserver: self
+ selector: @selector(taskStatusChanged:)
+ name: NSTaskDidTerminateNotification
+ object: nil];
+
+ NSString *serverBinaryPath = [[NSBundle mainBundle] resourcePath];
+ [task setCurrentDirectoryPath: serverBinaryPath];
+ NSString *serverBinary = [serverBinaryPath stringByAppendingPathComponent: @"hop_server.native"];
+ [task setLaunchPath: serverBinary];
+
+ NSString *readyFile = [NSTemporaryDirectory() stringByAppendingPathComponent: @"hop.ready."];
+ readyFile = [readyFile stringByAppendingFormat: @"%d", getpid()];
+ char const *readyFileUtf8 = [readyFile UTF8String];
+ unlink(readyFileUtf8);
+
+ [task setArguments: [NSArray arrayWithObjects: @"--ready-file", readyFile, nil]];
+
+ @try {
+ [task launch];
+ }
+ @catch (NSException *e) {
+ NSLog(@"Could not launch server %@: %@", serverBinary, [e reason]);
+ [NSApp terminate: self];
+ @throw;
+ }
+
+ int foundReadyFile = 0;
+ time_t startTime = time(NULL);
+ while ([task isRunning] && time(NULL) - startTime < HOP_STARTUP_DEADLINE_SECONDS) {
+ struct stat s;
+ if (lstat(readyFileUtf8, &s) != -1) {
+ foundReadyFile = 1;
+ break;
+ }
+ if (errno != ENOENT) {
+ perror("lstat of readyFileUtf8");
+ exit(EXIT_FAILURE);
+ }
+ usleep(100000);
+ }
+ unlink(readyFileUtf8);
+
+ if (!foundReadyFile) {
+ NSLog(@"Server did not start up within %d seconds.", HOP_STARTUP_DEADLINE_SECONDS);
+ [NSApp terminate: self];
+ return;
+ }
+
+ [[webview mainFrame] loadRequest:
+ [NSURLRequest requestWithURL:
+ [NSURL URLWithString: @"http://localhost:5678/"]]];
+}
+
+- (void) applicationWillTerminate: (NSNotification *) notification {
+ if ([task isRunning]) {
+ [task terminate];
+ }
+}
+
+- (void) taskStatusChanged: (NSNotification *) aNotification {
+ [NSApp terminate: self];
+}
+
+- (void) mainWindowClosed: (NSNotification *) aNotification {
+ [NSApp terminate: self];
+}
+
+@end
diff --git a/osx-server-gui/hopOsx_Prefix.pch b/osx-server-gui/hopOsx_Prefix.pch
new file mode 100644
index 0000000..b3f006f
--- /dev/null
+++ b/osx-server-gui/hopOsx_Prefix.pch
@@ -0,0 +1,7 @@
+//
+// Prefix header for all source files of the 'hopOsx' target in the 'hopOsx' project
+//
+
+#ifdef __OBJC__
+ #import
+#endif
diff --git a/osx-server-gui/icon/Makefile b/osx-server-gui/icon/Makefile
new file mode 100644
index 0000000..7e7caa6
--- /dev/null
+++ b/osx-server-gui/icon/Makefile
@@ -0,0 +1,4 @@
+all: icon.css
+
+%.css: %.less
+ recess --compile $< > $@
diff --git a/osx-server-gui/icon/icon.css b/osx-server-gui/icon/icon.css
new file mode 100644
index 0000000..8549969
--- /dev/null
+++ b/osx-server-gui/icon/icon.css
@@ -0,0 +1,29 @@
+body {
+ background: #004400;
+}
+
+.icon {
+ width: 492px;
+ height: 492px;
+ padding: 0;
+ margin: 0;
+ font-family: "Helvetica Neue";
+ font-size: 240px;
+ line-height: 446px;
+ color: #ffffff;
+ text-align: center;
+ text-shadow: 0 5px 10px black;
+ background-color: #58a258;
+ background-image: linear-gradient(top, #74c474, #2f6f2f);
+ background-image: -ms-linear-gradient(top, #74c474, #2f6f2f);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#74c474), to(#2f6f2f));
+ background-image: -webkit-linear-gradient(top, #74c474, #2f6f2f);
+ background-image: -o-linear-gradient(top, #74c474, #2f6f2f);
+ background-image: -moz-linear-gradient(top, #74c474, #2f6f2f);
+ background-repeat: repeat-x;
+ border: solid #285d28 10px;
+ -webkit-border-radius: 80px;
+ -moz-border-radius: 80px;
+ border-radius: 80px;
+ filter: progid:dximagetransform.microsoft.gradient(startColorstr='#74c474', endColorstr='#2f6f2f', GradientType=0);
+}
diff --git a/osx-server-gui/icon/icon.html b/osx-server-gui/icon/icon.html
new file mode 100644
index 0000000..464d8ea
--- /dev/null
+++ b/osx-server-gui/icon/icon.html
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+ hop
+
+
+
diff --git a/osx-server-gui/icon/icon.less b/osx-server-gui/icon/icon.less
new file mode 100644
index 0000000..f9f8f8a
--- /dev/null
+++ b/osx-server-gui/icon/icon.less
@@ -0,0 +1,49 @@
+// -*- css -*-
+
+@textColor: #fff;
+
+@baseColor: #46a546;
+
+@startColor: lighten(@baseColor, 15%);
+@endColor: darken(@baseColor, 15%);
+
+@borderWidth: 10px;
+@borderColor: darken(@baseColor, 20%);
+
+@transparencyColor: #040;
+
+body {
+ background: @transparencyColor;
+}
+
+.icon {
+ width: 512px - @borderWidth * 2;
+ height: 512px - @borderWidth * 2;
+ padding: 0;
+ margin: 0;
+
+ border: solid @borderColor @borderWidth;
+
+ font-family: "Helvetica Neue";
+ font-size: 240px;
+ line-height: 466px - @borderWidth * 2;
+
+ color: @textColor;
+ text-shadow: 0px 5px 10px black;
+ text-align: center;
+
+ background-color: mix(@startColor, @endColor, 60%);
+ background-image: -moz-linear-gradient(top, @startColor, @endColor); // FF 3.6+
+ background-image: -ms-linear-gradient(top, @startColor, @endColor); // IE10
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(@startColor), to(@endColor)); // Safari 4+, Chrome 2+
+ background-image: -webkit-linear-gradient(top, @startColor, @endColor); // Safari 5.1+, Chrome 10+
+ background-image: -o-linear-gradient(top, @startColor, @endColor); // Opera 11.10
+ background-image: linear-gradient(top, @startColor, @endColor); // The standard
+ background-repeat: repeat-x;
+
+ -webkit-border-radius: 80px;
+ -moz-border-radius: 80px;
+ border-radius: 80px;
+
+ filter: e(%("progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)",@startColor,@endColor)); // IE9 and down
+}
diff --git a/osx-server-gui/main.m b/osx-server-gui/main.m
new file mode 100644
index 0000000..d8e487f
--- /dev/null
+++ b/osx-server-gui/main.m
@@ -0,0 +1,24 @@
+// Copyright 2012 Tony Garnock-Jones .
+//
+// This file is part of Hop.
+//
+// Hop is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the
+// Free Software Foundation, either version 3 of the License, or (at your
+// option) any later version.
+//
+// Hop is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Hop. If not, see .
+//
+
+#import
+
+int main(int argc, char *argv[])
+{
+ return NSApplicationMain(argc, (const char **) argv);
+}