diff --git a/couchpotato/core/_base/_core/main.py b/couchpotato/core/_base/_core/main.py
index 0423e6666803e77e25625d3fec2ec7f81c9975b8..c91140fab3f28a00a1fd430224e18c44b08ae015 100644
--- a/couchpotato/core/_base/_core/main.py
+++ b/couchpotato/core/_base/_core/main.py
@@ -179,7 +179,7 @@ class Core(Plugin):
         if Env.get('daemonized'): return
 
         def signal_handler(signal, frame):
-            fireEvent('app.shutdown')
+            fireEvent('app.shutdown', single = True)
 
         signal.signal(signal.SIGINT, signal_handler)
         signal.signal(signal.SIGTERM, signal_handler)
diff --git a/couchpotato/core/_base/clientscript/main.py b/couchpotato/core/_base/clientscript/main.py
index bb380be64c78ab382bd6eabbb8831470da2b9469..7c95367ae77f14c88e7c36702734442a20c389f7 100644
--- a/couchpotato/core/_base/clientscript/main.py
+++ b/couchpotato/core/_base/clientscript/main.py
@@ -1,15 +1,58 @@
 from couchpotato.core.event import addEvent
+from couchpotato.core.helpers.variable import tryInt
 from couchpotato.core.logger import CPLog
 from couchpotato.core.plugins.base import Plugin
+from couchpotato.environment import Env
+from minify.cssmin import cssmin
+from minify.jsmin import jsmin
+import os
 
 log = CPLog(__name__)
 
 
 class ClientScript(Plugin):
 
-    urls = {
-        'style': {},
-        'script': {},
+    core_static = {
+        'style': [
+            'style/main.css',
+            'style/uniform.generic.css',
+            'style/uniform.css',
+            'style/settings.css',
+        ],
+        'script': [
+            'scripts/library/mootools.js',
+            'scripts/library/mootools_more.js',
+            'scripts/library/prefix_free.js',
+            'scripts/library/uniform.js',
+            'scripts/library/form_replacement/form_check.js',
+            'scripts/library/form_replacement/form_radio.js',
+            'scripts/library/form_replacement/form_dropdown.js',
+            'scripts/library/form_replacement/form_selectoption.js',
+            'scripts/library/question.js',
+            'scripts/library/scrollspy.js',
+            'scripts/library/spin.js',
+            'scripts/couchpotato.js',
+            'scripts/api.js',
+            'scripts/library/history.js',
+            'scripts/page.js',
+            'scripts/block.js',
+            'scripts/block/navigation.js',
+            'scripts/block/footer.js',
+            'scripts/block/menu.js',
+            'scripts/page/wanted.js',
+            'scripts/page/settings.js',
+            'scripts/page/about.js',
+            'scripts/page/manage.js',
+        ],
+    }
+
+
+    urls = {'style': {}, 'script': {}, }
+    minified = {'style': {}, 'script': {}, }
+    paths = {'style': {}, 'script': {}, }
+    comment = {
+       'style': '/*** %s:%d ***/\n',
+       'script': '// %s:%d\n'
     }
 
     html = {
@@ -24,6 +67,66 @@ class ClientScript(Plugin):
         addEvent('clientscript.get_styles', self.getStyles)
         addEvent('clientscript.get_scripts', self.getScripts)
 
+        addEvent('app.load', self.minify)
+
+        self.addCore()
+
+    def addCore(self):
+
+        for static_type in self.core_static:
+            for rel_path in self.core_static.get(static_type):
+                file_path = os.path.join(Env.get('app_dir'), 'couchpotato', 'static', rel_path)
+                core_url = 'api/%s/static/%s?%s' % (Env.setting('api_key'), rel_path, tryInt(os.path.getmtime(file_path)))
+
+                if static_type == 'script':
+                    self.registerScript(core_url, file_path, position = 'front')
+                else:
+                    self.registerStyle(core_url, file_path, position = 'front')
+
+
+    def minify(self):
+
+        for file_type in ['style', 'script']:
+            ext = 'js' if file_type is 'script' else 'css'
+            positions = self.paths.get(file_type, {})
+            for position in positions:
+                files = positions.get(position)
+                self._minify(file_type, files, position, position + '.' + ext)
+
+    def _minify(self, file_type, files, position, out):
+
+        cache = Env.get('cache_dir')
+        out_name = 'minified_' + out
+        out = os.path.join(cache, out_name)
+
+        raw = []
+        for file_path in files:
+            f = open(file_path, 'r').read()
+
+            if file_type == 'script':
+                data = jsmin(f)
+            else:
+                data = cssmin(f)
+                data = data.replace('../images/', '../static/images/')
+
+            raw.append({'file': file_path, 'date': int(os.path.getmtime(file_path)), 'data': data})
+
+        # Combine all files together with some comments
+        data = ''
+        for r in raw:
+            data += self.comment.get(file_type) % (r.get('file'), r.get('date'))
+            data += r.get('data') + '\n\n'
+
+        self.createFile(out, data.strip())
+
+        if not self.minified.get(file_type):
+            self.minified[file_type] = {}
+        if not self.minified[file_type].get(position):
+            self.minified[file_type][position] = []
+
+        minified_url = 'api/%s/file.cache/%s?%s' % (Env.setting('api_key'), out_name, tryInt(os.path.getmtime(out)))
+        self.minified[file_type][position].append(minified_url)
+
     def getStyles(self, *args, **kwargs):
         return self.get('style', *args, **kwargs)
 
@@ -35,22 +138,27 @@ class ClientScript(Plugin):
         data = '' if as_html else []
 
         try:
+            if not Env.get('dev'):
+                return self.minified[type][location]
+
             return self.urls[type][location]
         except Exception, e:
             log.error(e)
 
         return data
 
-    def registerStyle(self, path, position = 'head'):
-        self.register(path, 'style', position)
+    def registerStyle(self, api_path, file_path, position = 'head'):
+        self.register(api_path, file_path, 'style', position)
 
-    def registerScript(self, path, position = 'head'):
-        self.register(path, 'script', position)
+    def registerScript(self, api_path, file_path, position = 'head'):
+        self.register(api_path, file_path, 'script', position)
 
-    def register(self, filepath, type, location):
+    def register(self, api_path, file_path, type, location):
 
         if not self.urls[type].get(location):
             self.urls[type][location] = []
+        self.urls[type][location].append(api_path)
 
-        filePath = filepath
-        self.urls[type][location].append(filePath)
+        if not self.paths[type].get(location):
+            self.paths[type][location] = []
+        self.paths[type][location].append(file_path)
diff --git a/couchpotato/core/notifications/core/static/notification.js b/couchpotato/core/notifications/core/static/notification.js
index db9db843a29f2c54560966eb6b9d5853cfb4ffe5..52062e93d122098f606324eb6095deb0789c4d7d 100644
--- a/couchpotato/core/notifications/core/static/notification.js
+++ b/couchpotato/core/notifications/core/static/notification.js
@@ -178,11 +178,14 @@ var NotificationBase = new Class({
 	},
 
 	addTestButton: function(fieldset, plugin_name){
-		var self = this;
+		var self = this,
+			button_name = self.testButtonName(fieldset);
+
+		if(button_name.contains('Notifications')) return;
 
 		new Element('.ctrlHolder.test_button').adopt(
 			new Element('a.button', {
-				'text': self.testButtonName(fieldset),
+				'text': button_name,
 				'events': {
 					'click': function(){
 						var button = fieldset.getElement('.test_button .button');
@@ -191,7 +194,7 @@ var NotificationBase = new Class({
 						Api.request('notify.'+plugin_name+'.test', {
 							'onComplete': function(json){
 
-								button.set('text', self.testButtonName(fieldset));
+								button.set('text', button_name);
 
 								if(json.success){
 									var message = new Element('span.success', {
diff --git a/couchpotato/core/plugins/base.py b/couchpotato/core/plugins/base.py
index 73a2c306253253a3548e092c0f8dc9821a404893..edecaa943d0ecb0d1754b2c25d99e013987a1c80 100644
--- a/couchpotato/core/plugins/base.py
+++ b/couchpotato/core/plugins/base.py
@@ -64,7 +64,7 @@ class Plugin(object):
             for f in glob.glob(os.path.join(self.plugin_path, 'static', '*')):
                 ext = getExt(f)
                 if ext in ['js', 'css']:
-                    fireEvent('register_%s' % ('script' if ext in 'js' else 'style'), path + os.path.basename(f))
+                    fireEvent('register_%s' % ('script' if ext in 'js' else 'style'), path + os.path.basename(f), f)
 
     def showStatic(self, filename):
         d = os.path.join(self.plugin_path, 'static')
diff --git a/couchpotato/core/plugins/file/main.py b/couchpotato/core/plugins/file/main.py
index a9eab33dfaf7d1e6bf5059cfdeff5a62d4ccfb58..0dc01783406c0b0810051a237a6d3b7d7a98ed72 100644
--- a/couchpotato/core/plugins/file/main.py
+++ b/couchpotato/core/plugins/file/main.py
@@ -71,7 +71,7 @@ class FileManager(Plugin):
             db = get_session()
             for root, dirs, walk_files in os.walk(Env.get('cache_dir')):
                 for filename in walk_files:
-                    if root == python_cache: continue
+                    if root == python_cache or 'minified' in filename: continue
                     file_path = os.path.join(root, filename)
                     f = db.query(File).filter(File.path == toUnicode(file_path)).first()
                     if not f:
diff --git a/couchpotato/core/plugins/movie/main.py b/couchpotato/core/plugins/movie/main.py
index 8b0761c118740849a6b3892d7b8585dc882bbcd5..0e942f09196c2037f25b1c6a968f6778da5d7489 100644
--- a/couchpotato/core/plugins/movie/main.py
+++ b/couchpotato/core/plugins/movie/main.py
@@ -292,9 +292,8 @@ class MoviePlugin(Plugin):
             return False
         else:
             try:
-                url = 'http://thetvdb.com/api/GetSeriesByRemoteID.php?imdbid=%s' % params.get('identifier')
-                tvdb = self.getCache('thetvdb.%s' % params.get('identifier'), url = url, show_error = False)
-                if tvdb and 'series' in tvdb.lower():
+                is_movie = fireEvent('movie.is_movie', identifier = params.get('identifier'), single = True)
+                if not is_movie:
                     msg = 'Can\'t add movie, seems to be a TV show.'
                     log.error(msg)
                     fireEvent('notify.frontend', type = 'movie.is_tvshow', message = msg)
diff --git a/couchpotato/core/plugins/renamer/main.py b/couchpotato/core/plugins/renamer/main.py
index 91dfb339508dfc6d5b7fdd731be95aa9d3c8ea61..62358dde8bc63ada9383cb25f3983da8f3404585 100644
--- a/couchpotato/core/plugins/renamer/main.py
+++ b/couchpotato/core/plugins/renamer/main.py
@@ -468,7 +468,7 @@ class Renamer(Plugin):
 
         except:
             log.error('Couldn\'t move file "%s" to "%s": %s', (old, dest, traceback.format_exc()))
-            raise Exception
+            raise
 
         return True
 
diff --git a/couchpotato/core/plugins/scanner/main.py b/couchpotato/core/plugins/scanner/main.py
index 684f68210f05f4817b052d318df060c5955dde63..b822bc0f9adf9f99a811489226f39a7ad1734a57 100644
--- a/couchpotato/core/plugins/scanner/main.py
+++ b/couchpotato/core/plugins/scanner/main.py
@@ -23,7 +23,7 @@ class Scanner(Plugin):
         'media': 314572800, # 300MB
         'trailer': 1048576, # 1MB
     }
-    ignored_in_path = ['extracting', '_unpack', '_failed_', '_unknown_', '_exists_', '_failed_remove_', '_failed_rename_', '.appledouble', '.appledb', '.appledesktop', os.path.sep + '._', '.ds_store', 'cp.cpnfo'] #unpacking, smb-crap, hidden files
+    ignored_in_path = [os.path.sep + 'extracted' + os.path.sep, 'extracting', '_unpack', '_failed_', '_unknown_', '_exists_', '_failed_remove_', '_failed_rename_', '.appledouble', '.appledb', '.appledesktop', os.path.sep + '._', '.ds_store', 'cp.cpnfo'] #unpacking, smb-crap, hidden files
     ignore_names = ['extract', 'extracting', 'extracted', 'movie', 'movies', 'film', 'films', 'download', 'downloads', 'video_ts', 'audio_ts', 'bdmv', 'certificate']
     extensions = {
         'movie': ['mkv', 'wmv', 'avi', 'mpg', 'mpeg', 'mp4', 'm2ts', 'iso', 'img', 'mdf', 'ts', 'm4v'],
diff --git a/couchpotato/core/providers/movie/couchpotatoapi/main.py b/couchpotato/core/providers/movie/couchpotatoapi/main.py
index 88883d79dbe6567690c9ef2cfe2fa3c13331a47c..87586847e0364f56a8a6d5efa6151d16e02cd7fd 100644
--- a/couchpotato/core/providers/movie/couchpotatoapi/main.py
+++ b/couchpotato/core/providers/movie/couchpotatoapi/main.py
@@ -5,9 +5,7 @@ from couchpotato.core.helpers.request import jsonified, getParams
 from couchpotato.core.logger import CPLog
 from couchpotato.core.providers.movie.base import MovieProvider
 from couchpotato.core.settings.model import Movie
-from flask.helpers import json
 import time
-import traceback
 
 log = CPLog(__name__)
 
@@ -17,6 +15,7 @@ class CouchPotatoApi(MovieProvider):
     urls = {
         'search': 'https://couchpota.to/api/search/%s/',
         'info': 'https://couchpota.to/api/info/%s/',
+        'is_movie': 'https://couchpota.to/api/ismovie/%s/',
         'eta': 'https://couchpota.to/api/eta/%s/',
         'suggest': 'https://couchpota.to/api/suggest/%s/%s/',
     }
@@ -29,58 +28,44 @@ class CouchPotatoApi(MovieProvider):
         addEvent('movie.info', self.getInfo, priority = 1)
         addEvent('movie.search', self.search, priority = 1)
         addEvent('movie.release_date', self.getReleaseDate)
+        addEvent('movie.is_movie', self.isMovie)
 
     def search(self, q, limit = 12):
+        return self.getJsonData(self.urls['search'] % tryUrlencode(q), headers = self.getRequestHeaders())
 
-        cache_key = 'cpapi.cache.%s' % q
-        cached = self.getCache(cache_key, self.urls['search'] % tryUrlencode(q), headers = self.getRequestHeaders())
+    def isMovie(self, identifier = None):
 
-        if cached:
-            try:
-                movies = json.loads(cached)
-                return movies
-            except:
-                log.error('Failed parsing search results: %s', traceback.format_exc())
+        if not identifier:
+            return
 
-        return []
+        data = self.getJsonData(self.urls['is_movie'] % identifier, headers = self.getRequestHeaders())
+        if data:
+            return data.get('is_movie', True)
+
+        return True
 
     def getInfo(self, identifier = None):
 
         if not identifier:
             return
 
-        cache_key = 'cpapi.cache.info.%s' % identifier
-        cached = self.getCache(cache_key, self.urls['info'] % identifier, headers = self.getRequestHeaders())
-
-        if cached:
-            try:
-                movie = json.loads(cached)
-                return movie
-            except:
-                log.error('Failed parsing info results: %s', traceback.format_exc())
+        result = self.getJsonData(self.urls['info'] % identifier, headers = self.getRequestHeaders())
+        if result: return result
 
         return {}
 
     def getReleaseDate(self, identifier = None):
-
         if identifier is None: return {}
-        try:
-            data = self.urlopen(self.urls['eta'] % identifier, headers = self.getRequestHeaders())
-            dates = json.loads(data)
-            log.debug('Found ETA for %s: %s', (identifier, dates))
-            return dates
-        except Exception, e:
-            log.error('Error getting ETA for %s: %s', (identifier, e))
 
-        return {}
+        dates = self.getJsonData(self.urls['eta'] % identifier, headers = self.getRequestHeaders())
+        log.debug('Found ETA for %s: %s', (identifier, dates))
+
+        return dates
 
     def suggest(self, movies = [], ignore = []):
-        try:
-            data = self.urlopen(self.urls['suggest'] % (','.join(movies), ','.join(ignore)))
-            suggestions = json.loads(data)
-            log.info('Found Suggestions for %s', (suggestions))
-        except Exception, e:
-            log.error('Error getting suggestions for %s: %s', (movies, e))
+
+        suggestions = self.getJsonData(self.urls['suggest'] % (','.join(movies), ','.join(ignore)))
+        log.info('Found Suggestions for %s', (suggestions))
 
         return suggestions
 
diff --git a/couchpotato/environment.py b/couchpotato/environment.py
index d8c03c7cc96ff44316d5e95c255f1f23acfdfb28..bd637ad219fdcfd856c57f2e9349c3e9096d2f2a 100644
--- a/couchpotato/environment.py
+++ b/couchpotato/environment.py
@@ -20,7 +20,7 @@ class Env(object):
     _options = None
     _args = None
     _quiet = False
-    _deamonize = False
+    _daemonized = False
     _desktop = None
     _session = None
 
diff --git a/couchpotato/static/scripts/couchpotato.js b/couchpotato/static/scripts/couchpotato.js
index a94f5d4e674af7f437a9e9116db44d9a29caa5df..8f4e665f8413afec3d9ddf2391bef7a13d7c0484 100644
--- a/couchpotato/static/scripts/couchpotato.js
+++ b/couchpotato/static/scripts/couchpotato.js
@@ -24,8 +24,8 @@ var CouchPotato = new Class({
 
 		if(window.location.hash)
 			History.handleInitialState();
-
-		self.openPage(window.location.pathname);
+		else
+			self.openPage(window.location.pathname);
 
 		History.addEvent('change', self.openPage.bind(self));
 		self.c.addEvent('click:relay(a[href^=/]:not([target]))', self.pushState.bind(self));
diff --git a/couchpotato/static/scripts/library/prefix_free.js b/couchpotato/static/scripts/library/prefix_free.js
index 8dd99e2e1881cf118173dad77d906b6499ab1643..b6d9812a0eba7ac704c3a89d6bed6f143367e7de 100644
--- a/couchpotato/static/scripts/library/prefix_free.js
+++ b/couchpotato/static/scripts/library/prefix_free.js
@@ -24,6 +24,9 @@ var self = window.StyleFix = {
 
 		var url = link.href || link.getAttribute('data-href'),
 		    base = url.replace(/[^\/]+$/, ''),
+		    base_scheme = (/^[a-z]{3,10}:/.exec(base) || [''])[0],
+		    base_domain = (/^[a-z]{3,10}:\/\/[^\/]+/.exec(base) || [''])[0],
+		    base_query = /^([^?]*)\??/.exec(url)[1],
 		    parent = link.parentNode,
 		    xhr = new XMLHttpRequest(),
 		    process;
@@ -43,12 +46,23 @@ var self = window.StyleFix = {
 					// Convert relative URLs to absolute, if needed
 					if(base) {
 						css = css.replace(/url\(\s*?((?:"|')?)(.+?)\1\s*?\)/gi, function($0, quote, url) {
-							if(!/^([a-z]{3,10}:|\/|#)/i.test(url)) { // If url not absolute & not a hash
+							if(/^([a-z]{3,10}:|#)/i.test(url)) { // Absolute & or hash-relative
+								return $0;
+							}
+							else if(/^\/\//.test(url)) { // Scheme-relative
 								// May contain sequences like /../ and /./ but those DO work
+								return 'url("' + base_scheme + url + '")';
+							}
+							else if(/^\//.test(url)) { // Domain-relative
+								return 'url("' + base_domain + url + '")';
+							}
+							else if(/^\?/.test(url)) { // Query-relative
+								return 'url("' + base_query + url + '")';
+							}
+							else {
+								// Path-relative
 								return 'url("' + base + url + '")';
 							}
-							
-							return $0;						
 						});
 
 						// behavior URLs shoudn’t be converted (Issue #19)
@@ -470,4 +484,4 @@ root.className += ' ' + self.prefix;
 StyleFix.register(self.prefixCSS);
 
 
-})(document.documentElement);
+})(document.documentElement);
\ No newline at end of file
diff --git a/couchpotato/static/scripts/page/wanted.js b/couchpotato/static/scripts/page/wanted.js
index 3f6e065b57473a9de69ed8f2ed449b19134573a6..a9e0bc71f579432729450a781964a56b840a0e6f 100644
--- a/couchpotato/static/scripts/page/wanted.js
+++ b/couchpotato/static/scripts/page/wanted.js
@@ -52,7 +52,8 @@ Page.Wanted = new Class({
 
 		var start_text = self.manual_search.get('text');
 		self.progress_interval = setInterval(function(){
-			Api.request('searcher.progress', {
+			if(self.search_progress && self.search_progress.running) return;
+			self.search_progress = Api.request('searcher.progress', {
 				'onComplete': function(json){
 					self.search_in_progress = true;
 					if(!json.progress){
@@ -65,7 +66,7 @@ Page.Wanted = new Class({
 						self.manual_search.set('text', 'Searching.. (' + (((progress.total-progress.to_go)/progress.total)*100).round() + '%)');
 					}
 				}
-			})
+			});
 		}, 1000);
 
 	}
diff --git a/couchpotato/static/style/page/settings.css b/couchpotato/static/style/settings.css
similarity index 96%
rename from couchpotato/static/style/page/settings.css
rename to couchpotato/static/style/settings.css
index bcd0b774850d6805924757a22ebcbbf88d1669b8..3af7dba78587ad380cf31465f3d11a11004cc645 100644
--- a/couchpotato/static/style/page/settings.css
+++ b/couchpotato/static/style/settings.css
@@ -118,7 +118,7 @@
 		border: 0;
 	}
 		.page .ctrlHolder.save_success:not(:first-child) {
-			background: url('../../images/icon.check.png') no-repeat 7px center;
+			background: url('../images/icon.check.png') no-repeat 7px center;
 		}
 		.page .ctrlHolder:last-child { border: none; }
 		.page .ctrlHolder:hover { background-color: rgba(255,255,255,0.05); }
@@ -250,7 +250,7 @@
 		padding: 0 4% 0 4px;
 		font-size: 13px;
 		width: 30%;
-		background-image: url('../../images/icon.folder.gif');
+		background-image: url('../images/icon.folder.gif');
 		background-repeat: no-repeat;
 		background-position: 97% center;
 		overflow: hidden;
@@ -298,7 +298,7 @@
 			cursor: pointer;
 			margin: 0 !important;
 			border-top: 1px solid rgba(255,255,255,0.1);
-			background: url('../../images/right.arrow.png') no-repeat 98% center;
+			background: url('../images/right.arrow.png') no-repeat 98% center;
 		}
 		.page .directory_list li:last-child {
 			border-bottom: 1px solid rgba(255,255,255,0.1);
@@ -484,7 +484,7 @@
 				margin: -9px 0 0 -16px;
 				border-radius: 30px 30px 0 0;
 				cursor: pointer;
-				background: url('../../images/icon.delete.png') no-repeat center 2px, -*-linear-gradient(
+				background: url('../images/icon.delete.png') no-repeat center 2px, -*-linear-gradient(
 				   270deg,
 				    #5b9bd1 0%,
 				    #5b9bd1 100%
@@ -558,7 +558,7 @@
 		}
 
 			.page .tab_about .usenet li {
-				background: url('../../images/icon.check.png') no-repeat left center;
+				background: url('../images/icon.check.png') no-repeat left center;
 				padding: 0 0 0 25px;
 			}
 
@@ -646,6 +646,6 @@
 		}
 		
 .active .group_imdb_automation:not(.disabled) {
-	background: url('../../images/imdb_watchlist.png') no-repeat right 50px;
+	background: url('../images/imdb_watchlist.png') no-repeat right 50px;
 	min-height: 210px;
 }
\ No newline at end of file
diff --git a/couchpotato/templates/_desktop.html b/couchpotato/templates/_desktop.html
index 8689b66698cde6715b7ac33e2480f1c48e2701e3..1d618066325bd497a2095c9a90a649f065ab96ef 100644
--- a/couchpotato/templates/_desktop.html
+++ b/couchpotato/templates/_desktop.html
@@ -1,43 +1,14 @@
 <!doctype html>
 <html>
 	<head>
-		<link rel="stylesheet" href="{{ url_for('web.static', filename='style/main.css') }}" type="text/css">
-		<link rel="stylesheet" href="{{ url_for('web.static', filename='style/uniform.generic.css') }}" type="text/css">
-		<link rel="stylesheet" href="{{ url_for('web.static', filename='style/uniform.css') }}" type="text/css">
-
-		<link rel="stylesheet" href="{{ url_for('web.static', filename='style/page/settings.css') }}" type="text/css">
-
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/library/mootools.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/library/mootools_more.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/library/prefix_free.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/library/uniform.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/library/form_replacement/form_check.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/library/form_replacement/form_radio.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/library/form_replacement/form_dropdown.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/library/form_replacement/form_selectoption.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/library/question.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/library/scrollspy.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/library/spin.js') }}"></script>
-
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/couchpotato.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/api.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/library/history.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/page.js') }}"></script>
-
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/block.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/block/navigation.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/block/footer.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/block/menu.js') }}"></script>
-
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/page/wanted.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/page/settings.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/page/about.js') }}"></script>
-		<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/page/manage.js') }}"></script>
-		<!--<script type="text/javascript" src="{{ url_for('web.static', filename='scripts/page/soon.js') }}"></script>-->
-
-		{% for url in fireEvent('clientscript.get_scripts', as_html = True, single = True) %}
+		{% for url in fireEvent('clientscript.get_styles', as_html = True, location = 'front', single = True) %}
+		<link rel="stylesheet" href="{{ url_for('web.index') }}{{ url }}" type="text/css">{% endfor %}
+		{% for url in fireEvent('clientscript.get_scripts', as_html = True, location = 'front', single = True) %}
+		<script type="text/javascript" src="{{ url_for('web.index') }}{{ url }}"></script>{% endfor %}
+
+		{% for url in fireEvent('clientscript.get_scripts', as_html = True, location = 'head', single = True) %}
 		<script type="text/javascript" src="{{ url_for('web.index') }}{{ url }}"></script>{% endfor %}
-		{% for url in fireEvent('clientscript.get_styles', as_html = True, single = True) %}
+		{% for url in fireEvent('clientscript.get_styles', as_html = True, location = 'head', single = True) %}
 		<link rel="stylesheet" href="{{ url_for('web.index') }}{{ url }}" type="text/css">{% endfor %}
 
 		<link href="{{ url_for('web.static', filename='images/favicon.ico') }}" rel="icon" type="image/x-icon" />
diff --git a/libs/daemon.py b/libs/daemon.py
index 0e3d0d63b1ccb27969021d3a8634213fa0264af8..805cfa248050fa354d2321ab5e18b592008d63e2 100644
--- a/libs/daemon.py
+++ b/libs/daemon.py
@@ -92,6 +92,7 @@ class Daemon():
         """
         Stop the daemon
         """
+
         # Get the pid from the pidfile
         try:
             pf = file(self.pidfile, 'r')
@@ -115,7 +116,6 @@ class Daemon():
             if err.find("No such process") > 0:
                 self.delpid()
             else:
-                print str(err)
                 sys.exit(1)
 
     def restart(self):
diff --git a/libs/minify/__init__.py b/libs/minify/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/libs/minify/cssmin.py b/libs/minify/cssmin.py
new file mode 100644
index 0000000000000000000000000000000000000000..c29cb83b7fdc825124bb1b5799d7e55ba0b600b8
--- /dev/null
+++ b/libs/minify/cssmin.py
@@ -0,0 +1,223 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# `cssmin.py` - A Python port of the YUI CSS compressor.
+
+
+from StringIO import StringIO # The pure-Python StringIO supports unicode.
+import re
+
+
+__version__ = '0.1.1'
+
+
+def remove_comments(css):
+    """Remove all CSS comment blocks."""
+
+    iemac = False
+    preserve = False
+    comment_start = css.find("/*")
+    while comment_start >= 0:
+        # Preserve comments that look like `/*!...*/`.
+        # Slicing is used to make sure we don"t get an IndexError.
+        preserve = css[comment_start + 2:comment_start + 3] == "!"
+
+        comment_end = css.find("*/", comment_start + 2)
+        if comment_end < 0:
+            if not preserve:
+                css = css[:comment_start]
+                break
+        elif comment_end >= (comment_start + 2):
+            if css[comment_end - 1] == "\\":
+                # This is an IE Mac-specific comment; leave this one and the
+                # following one alone.
+                comment_start = comment_end + 2
+                iemac = True
+            elif iemac:
+                comment_start = comment_end + 2
+                iemac = False
+            elif not preserve:
+                css = css[:comment_start] + css[comment_end + 2:]
+            else:
+                comment_start = comment_end + 2
+        comment_start = css.find("/*", comment_start)
+
+    return css
+
+
+def remove_unnecessary_whitespace(css):
+    """Remove unnecessary whitespace characters."""
+
+    def pseudoclasscolon(css):
+
+        """
+        Prevents 'p :link' from becoming 'p:link'.
+        
+        Translates 'p :link' into 'p ___PSEUDOCLASSCOLON___link'; this is
+        translated back again later.
+        """
+
+        regex = re.compile(r"(^|\})(([^\{\:])+\:)+([^\{]*\{)")
+        match = regex.search(css)
+        while match:
+            css = ''.join([
+                css[:match.start()],
+                match.group().replace(":", "___PSEUDOCLASSCOLON___"),
+                css[match.end():]])
+            match = regex.search(css)
+        return css
+
+    css = pseudoclasscolon(css)
+    # Remove spaces from before things.
+    css = re.sub(r"\s+([!{};:>+\(\)\],])", r"\1", css)
+
+    # If there is a `@charset`, then only allow one, and move to the beginning.
+    css = re.sub(r"^(.*)(@charset \"[^\"]*\";)", r"\2\1", css)
+    css = re.sub(r"^(\s*@charset [^;]+;\s*)+", r"\1", css)
+
+    # Put the space back in for a few cases, such as `@media screen` and
+    # `(-webkit-min-device-pixel-ratio:0)`.
+    css = re.sub(r"\band\(", "and (", css)
+
+    # Put the colons back.
+    css = css.replace('___PSEUDOCLASSCOLON___', ':')
+
+    # Remove spaces from after things.
+    css = re.sub(r"([!{}:;>+\(\[,])\s+", r"\1", css)
+
+    return css
+
+
+def remove_unnecessary_semicolons(css):
+    """Remove unnecessary semicolons."""
+
+    return re.sub(r";+\}", "}", css)
+
+
+def remove_empty_rules(css):
+    """Remove empty rules."""
+
+    return re.sub(r"[^\}\{]+\{\}", "", css)
+
+
+def normalize_rgb_colors_to_hex(css):
+    """Convert `rgb(51,102,153)` to `#336699`."""
+
+    regex = re.compile(r"rgb\s*\(\s*([0-9,\s]+)\s*\)")
+    match = regex.search(css)
+    while match:
+        colors = match.group(1).split(",")
+        hexcolor = '#%.2x%.2x%.2x' % tuple(map(int, colors))
+        css = css.replace(match.group(), hexcolor)
+        match = regex.search(css)
+    return css
+
+
+def condense_zero_units(css):
+    """Replace `0(px, em, %, etc)` with `0`."""
+
+    return re.sub(r"([\s:])(0)(px|em|%|in|cm|mm|pc|pt|ex)", r"\1\2", css)
+
+
+def condense_multidimensional_zeros(css):
+    """Replace `:0 0 0 0;`, `:0 0 0;` etc. with `:0;`."""
+
+    css = css.replace(":0 0 0 0;", ":0;")
+    css = css.replace(":0 0 0;", ":0;")
+    css = css.replace(":0 0;", ":0;")
+
+    # Revert `background-position:0;` to the valid `background-position:0 0;`.
+    css = css.replace("background-position:0;", "background-position:0 0;")
+
+    return css
+
+
+def condense_floating_points(css):
+    """Replace `0.6` with `.6` where possible."""
+
+    return re.sub(r"(:|\s)0+\.(\d+)", r"\1.\2", css)
+
+
+def condense_hex_colors(css):
+    """Shorten colors from #AABBCC to #ABC where possible."""
+
+    regex = re.compile(r"([^\"'=\s])(\s*)#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])")
+    match = regex.search(css)
+    while match:
+        first = match.group(3) + match.group(5) + match.group(7)
+        second = match.group(4) + match.group(6) + match.group(8)
+        if first.lower() == second.lower():
+            css = css.replace(match.group(), match.group(1) + match.group(2) + '#' + first)
+            match = regex.search(css, match.end() - 3)
+        else:
+            match = regex.search(css, match.end())
+    return css
+
+
+def condense_whitespace(css):
+    """Condense multiple adjacent whitespace characters into one."""
+
+    return re.sub(r"\s+", " ", css)
+
+
+def condense_semicolons(css):
+    """Condense multiple adjacent semicolon characters into one."""
+
+    return re.sub(r";;+", ";", css)
+
+
+def wrap_css_lines(css, line_length):
+    """Wrap the lines of the given CSS to an approximate length."""
+
+    lines = []
+    line_start = 0
+    for i, char in enumerate(css):
+        # It's safe to break after `}` characters.
+        if char == '}' and (i - line_start >= line_length):
+            lines.append(css[line_start:i + 1])
+            line_start = i + 1
+
+    if line_start < len(css):
+        lines.append(css[line_start:])
+    return '\n'.join(lines)
+
+
+def cssmin(css, wrap = None):
+    css = remove_comments(css)
+    css = condense_whitespace(css)
+    # A pseudo class for the Box Model Hack
+    # (see http://tantek.com/CSS/Examples/boxmodelhack.html)
+    css = css.replace('"\\"}\\""', "___PSEUDOCLASSBMH___")
+    #css = remove_unnecessary_whitespace(css)
+    css = remove_unnecessary_semicolons(css)
+    css = condense_zero_units(css)
+    css = condense_multidimensional_zeros(css)
+    css = condense_floating_points(css)
+    css = normalize_rgb_colors_to_hex(css)
+    css = condense_hex_colors(css)
+    if wrap is not None:
+        css = wrap_css_lines(css, wrap)
+    css = css.replace("___PSEUDOCLASSBMH___", '"\\"}\\""')
+    css = condense_semicolons(css)
+    return css.strip()
+
+
+def main():
+    import optparse
+    import sys
+
+    p = optparse.OptionParser(
+        prog = "cssmin", version = __version__,
+        usage = "%prog [--wrap N]",
+        description = """Reads raw CSS from stdin, and writes compressed CSS to stdout.""")
+
+    p.add_option(
+        '-w', '--wrap', type = 'int', default = None, metavar = 'N',
+        help = "Wrap output to approximately N chars per line.")
+
+    options, args = p.parse_args()
+    sys.stdout.write(cssmin(sys.stdin.read(), wrap = options.wrap))
+
+
+if __name__ == '__main__':
+    main()
diff --git a/libs/minify/jsmin.py b/libs/minify/jsmin.py
new file mode 100644
index 0000000000000000000000000000000000000000..a1b81f9ab7a3ae0d4cb683000eb96fbc2289427a
--- /dev/null
+++ b/libs/minify/jsmin.py
@@ -0,0 +1,218 @@
+#!/usr/bin/python
+
+# This code is original from jsmin by Douglas Crockford, it was translated to
+# Python by Baruch Even. The original code had the following copyright and
+# license.
+#
+# /* jsmin.c
+#    2007-05-22
+#
+# Copyright (c) 2002 Douglas Crockford  (www.crockford.com)
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+# of the Software, and to permit persons to whom the Software is furnished to do
+# so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# The Software shall be used for Good, not Evil.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+# */
+
+from StringIO import StringIO
+
+def jsmin(js):
+    ins = StringIO(js)
+    outs = StringIO()
+    JavascriptMinify().minify(ins, outs)
+    str = outs.getvalue()
+    if len(str) > 0 and str[0] == '\n':
+        str = str[1:]
+    return str
+
+def isAlphanum(c):
+    """return true if the character is a letter, digit, underscore,
+           dollar sign, or non-ASCII character.
+    """
+    return ((c >= 'a' and c <= 'z') or (c >= '0' and c <= '9') or
+            (c >= 'A' and c <= 'Z') or c == '_' or c == '$' or c == '\\' or (c is not None and ord(c) > 126));
+
+class UnterminatedComment(Exception):
+    pass
+
+class UnterminatedStringLiteral(Exception):
+    pass
+
+class UnterminatedRegularExpression(Exception):
+    pass
+
+class JavascriptMinify(object):
+
+    def _outA(self):
+        self.outstream.write(self.theA)
+    def _outB(self):
+        self.outstream.write(self.theB)
+
+    def _get(self):
+        """return the next character from stdin. Watch out for lookahead. If
+           the character is a control character, translate it to a space or
+           linefeed.
+        """
+        c = self.theLookahead
+        self.theLookahead = None
+        if c == None:
+            c = self.instream.read(1)
+        if c >= ' ' or c == '\n':
+            return c
+        if c == '': # EOF
+            return '\000'
+        if c == '\r':
+            return '\n'
+        return ' '
+
+    def _peek(self):
+        self.theLookahead = self._get()
+        return self.theLookahead
+
+    def _next(self):
+        """get the next character, excluding comments. peek() is used to see
+           if a '/' is followed by a '/' or '*'.
+        """
+        c = self._get()
+        if c == '/':
+            p = self._peek()
+            if p == '/':
+                c = self._get()
+                while c > '\n':
+                    c = self._get()
+                return c
+            if p == '*':
+                c = self._get()
+                while 1:
+                    c = self._get()
+                    if c == '*':
+                        if self._peek() == '/':
+                            self._get()
+                            return ' '
+                    if c == '\000':
+                        raise UnterminatedComment()
+
+        return c
+
+    def _action(self, action):
+        """do something! What you do is determined by the argument:
+           1   Output A. Copy B to A. Get the next B.
+           2   Copy B to A. Get the next B. (Delete A).
+           3   Get the next B. (Delete B).
+           action treats a string as a single character. Wow!
+           action recognizes a regular expression if it is preceded by ( or , or =.
+        """
+        if action <= 1:
+            self._outA()
+
+        if action <= 2:
+            self.theA = self.theB
+            if self.theA == "'" or self.theA == '"':
+                while 1:
+                    self._outA()
+                    self.theA = self._get()
+                    if self.theA == self.theB:
+                        break
+                    if self.theA <= '\n':
+                        raise UnterminatedStringLiteral()
+                    if self.theA == '\\':
+                        self._outA()
+                        self.theA = self._get()
+
+
+        if action <= 3:
+            self.theB = self._next()
+            if self.theB == '/' and (self.theA == '(' or self.theA == ',' or
+                                     self.theA == '=' or self.theA == ':' or
+                                     self.theA == '[' or self.theA == '?' or
+                                     self.theA == '!' or self.theA == '&' or
+                                     self.theA == '|' or self.theA == ';' or
+                                     self.theA == '{' or self.theA == '}' or
+                                     self.theA == '\n'):
+                self._outA()
+                self._outB()
+                while 1:
+                    self.theA = self._get()
+                    if self.theA == '/':
+                        break
+                    elif self.theA == '\\':
+                        self._outA()
+                        self.theA = self._get()
+                    elif self.theA <= '\n':
+                        raise UnterminatedRegularExpression()
+                    self._outA()
+                self.theB = self._next()
+
+
+    def _jsmin(self):
+        """Copy the input to the output, deleting the characters which are
+           insignificant to JavaScript. Comments will be removed. Tabs will be
+           replaced with spaces. Carriage returns will be replaced with linefeeds.
+           Most spaces and linefeeds will be removed.
+        """
+        self.theA = '\n'
+        self._action(3)
+
+        while self.theA != '\000':
+            if self.theA == ' ':
+                if isAlphanum(self.theB):
+                    self._action(1)
+                else:
+                    self._action(2)
+            elif self.theA == '\n':
+                if self.theB in ['{', '[', '(', '+', '-']:
+                    self._action(1)
+                elif self.theB == ' ':
+                    self._action(3)
+                else:
+                    if isAlphanum(self.theB):
+                        self._action(1)
+                    else:
+                        self._action(2)
+            else:
+                if self.theB == ' ':
+                    if isAlphanum(self.theA):
+                        self._action(1)
+                    else:
+                        self._action(3)
+                elif self.theB == '\n':
+                    if self.theA in ['}', ']', ')', '+', '-', '"', '\'']:
+                        self._action(1)
+                    else:
+                        if isAlphanum(self.theA):
+                            self._action(1)
+                        else:
+                            self._action(3)
+                else:
+                    self._action(1)
+
+    def minify(self, instream, outstream):
+        self.instream = instream
+        self.outstream = outstream
+        self.theA = '\n'
+        self.theB = None
+        self.theLookahead = None
+
+        self._jsmin()
+        self.instream.close()
+
+if __name__ == '__main__':
+    import sys
+    jsm = JavascriptMinify()
+    jsm.minify(sys.stdin, sys.stdout)